[
  {
    "path": ".agents/skills/changesets/INJECT.md",
    "content": "---\nheading: Changesets\n---\n\n- Any PR that should trigger a package release MUST include a changeset.\n- Identify affected packages by mapping changed files to their nearest `package.json`.\n- Choose the right bump: `patch` for fixes, `minor` for features, `major` for breaking changes.\n- While a project is pre-1.0, `minor` bumps may be treated as breaking.\n- ALWAYS use `npx changeset add --empty` to generate a new changeset file with a random name. NEVER create changeset files manually.\n- No changeset needed for: docs-only changes, CI config, dev dependency updates, test-only changes.\n"
  },
  {
    "path": ".agents/skills/changesets/SKILL.md",
    "content": "---\nname: changesets\ndescription: Generate a changeset file with a changelog entry for package releases. Use when a PR introduces user-facing changes that should trigger a version bump.\nargument-hint: \"[patch|minor|major]\"\nallowed-tools: Bash(npx changeset add --empty)\n---\n\n# Generate Changeset\n\nCreate a new changeset file for the current project using the [changesets CLI](https://github.com/changesets/changesets), then fill it with a proper changelog entry based on recent changes.\n\n## Key Rules\n\n- Any PR that should trigger a package release MUST include a changeset.\n- Identify affected packages by mapping changed files to their nearest `package.json`.\n- Choose the right bump: `patch` for fixes, `minor` for features, `major` for breaking changes.\n- While a project is pre-1.0, `minor` bumps may be treated as breaking.\n- ALWAYS use `npx changeset add --empty` to generate a new changeset file with a random name. NEVER create changeset files manually.\n- No changeset needed for: docs-only changes, CI config, dev dependency updates, test-only changes.\n- Do NOT modify any existing changeset files.\n- Only create one new changeset file per invocation.\n\n## Guidelines\n\n### Changeset Format\n\n```\n---\n'<package-a>': patch\n'<package-b>': patch\n---\n\n<concise changelog entry>\n```\n\n### Changelog Entries\n\n- Write a concise but informative changelog entry (1-3 sentences).\n- Start with a verb — e.g. \"Add\", \"Remove\", \"Replace\", \"Fix\", \"Update\".\n- Focus on what changed from the user's perspective, not implementation details.\n- Mention renamed or removed APIs explicitly.\n\n### Breaking Changes\n\nAdd a `**BREAKING CHANGES**` section (bold paragraph, not a header) after the changelog entry when:\n\n- The bump level is `major`, OR\n- The bump level is `minor` AND the current major version is `0` (i.e. pre-1.0)\n\n...and the changes actually introduce breaking changes.\n\nThe breaking changes section should list each breaking change with a bold title summarizing the change, followed by a brief explanation and a `diff` code block showing the before/after migration when applicable. For example:\n\n```\nReplace the `useGranularImports` boolean option with a new `importStrategy` option.\n\n**BREAKING CHANGES**\n\n**`useGranularImports` replaced with `importStrategy`.** The boolean option has been replaced with a string union for finer control.\n\n\\`\\`\\`diff\n- renderVisitor('./output', { useGranularImports: true });\n+ renderVisitor('./output', { importStrategy: 'granular' });\n\\`\\`\\`\n\n**Default import behavior changed.** The default strategy is now `'preferRoot'`, which falls back to granular packages for symbols not on the root entrypoint.\n\n\\`\\`\\`diff\n- renderVisitor('./output'); // equivalent to useGranularImports: false\n+ renderVisitor('./output'); // equivalent to importStrategy: 'preferRoot'\n\\`\\`\\`\n```\n\nNot every breaking change needs a diff — use them when there's a clear before/after code change to show. For type removals or behavioral changes, a text explanation is sufficient.\n\n## Command Process\n\nWhen invoked as a command, follow these steps:\n\n### Arguments\n\n- `[patch|minor|major]` (optional): Override the bump level for all affected packages.\n\n### Steps\n\n1. **Determine the change source.** Check `git status` for uncommitted changes. If there are meaningful working tree changes, use those. Otherwise, use the latest commit(s) on the current branch (compared to the base branch from `.changeset/config.json`).\n2. **Identify which packages changed.** Look at which files were modified and map them to their nearest `package.json` to determine affected packages. Ignore changes that are not relevant to a changeset — e.g. typo fixes in comments, dependency version bumps in `package.json`, changes to CI config, docs-only changes in non-doc packages, etc. Use your judgement to filter out noise.\n3. **Run `npx changeset add --empty`** to generate a new changeset file with a random name.\n4. **Identify the newly created file** — it will be the most recently created `.md` file in `.changeset/` (excluding `README.md`).\n5. **Write the changeset file** with the proper frontmatter listing each affected package and the bump level, followed by the changelog entry.\n"
  },
  {
    "path": ".agents/skills/shipping-git/INJECT.md",
    "content": "---\nheading: Shipping (Git)\n---\n\n- NEVER commit, push, create branches, or create PRs without explicit user approval.\n- Before any git operation that creates or modifies a commit, present a review block containing: changeset entry (if applicable), commit title, and commit/PR description. ALWAYS wait for approval.\n- Use standard `git add` and `git commit` workflows. Concise title on the first line, blank line, then description body.\n- Use `gh pr create` for pull requests.\n- Write commit and PR descriptions as natural flowing prose. Do NOT insert hard line breaks mid-paragraph.\n"
  },
  {
    "path": ".agents/skills/shipping-git/SKILL.md",
    "content": "---\nname: shipping-git\ndescription: Shipping workflow using standard Git and GitHub CLI. Provides guidance for committing, branching, and creating PRs.\n---\n\n# Ship Code Using Git\n\nGuidance for shipping code using standard Git and the GitHub CLI (`gh`). This skill teaches the agent how to create commits, branches, and pull requests following conventional workflows.\n\n## Key Rules\n\n- NEVER commit, push, create branches, or create PRs without explicit user approval.\n- Before any git operation that creates or modifies a commit, present a review block containing: changeset content (if applicable), commit title, and commit/PR description. ALWAYS wait for approval.\n- Show the proposed changeset entry for review before writing the changeset file.\n- Use standard `git add` and `git commit` workflows. Concise title on the first line, blank line, then description body.\n- Use `gh pr create` for pull requests.\n- Write commit and PR descriptions as natural flowing prose. Do NOT insert hard line breaks mid-paragraph.\n\n## Guidelines\n\n### Creating Commits\n\nFollow conventional commit message format:\n\n```sh\ngit add -A\ngit commit -m \"Commit title\" -m \"Description body explaining what changed and why.\"\n```\n\n- The first `-m` sets the commit title (first line). Keep it concise and descriptive.\n- The second `-m` sets the commit body. Explain what changed and why.\n- Use present tense, imperative mood (e.g. \"Add feature\" not \"Added feature\").\n\n### Creating Branches\n\nCreate a descriptive branch name before committing:\n\n```sh\ngit checkout -b feature/short-description\n```\n\nCommon prefixes: `feature/`, `fix/`, `refactor/`, `docs/`, `chore/`.\n\n### Creating Pull Requests\n\nUse the GitHub CLI to create PRs:\n\n```sh\ngh pr create --title \"PR title\" --body \"Description explaining what changed and why.\"\n```\n\n- If a `.github/PULL_REQUEST_TEMPLATE.md` exists, use it as a guide for structuring the PR description. Fill in sections that are relevant and omit sections that don't apply (e.g. don't add \"Fixes #\" if there's no related issue).\n\n### Pushing Changes\n\nPush the branch and set the upstream:\n\n```sh\ngit push -u origin HEAD\n```\n\n### Review Block Format\n\nBefore any git operation, present this review block and wait for approval:\n\n1. **Changeset entry** (if applicable) — the proposed changelog entry and bump type.\n2. **Commit title** — a concise title for the commit.\n3. **Commit/PR description** — a short description that explains what changed and why.\n"
  },
  {
    "path": ".agents/skills/shipping-graphite/INJECT.md",
    "content": "---\nheading: Shipping (Graphite)\n---\n\n- Check if [Graphite](https://graphite.dev/) is installed (`which gt`). Prefer Graphite when available; fall back to the Git shipping workflow otherwise.\n- NEVER commit, push, create branches, or create PRs without explicit user approval.\n- Before any git operation that creates or modifies a commit, present a review block containing: changeset entry (if applicable), commit title, and commit/PR description. ALWAYS wait for approval.\n- Use `gt create -am \"Title\" -m \"Description body\"` for new PRs. The first `-m` sets the commit title; the second sets the PR description.\n- Use `gt modify -a` to amend the current branch with follow-up changes (NEVER create additional commits on the same branch).\n- ALWAYS escape backticks in commit messages with backslashes for shell compatibility (e.g. `\"Update \\`my-package\\` config\"`).\n- Do NOT run `gt submit` after committing. Only run it when the user explicitly asks to submit or push.\n- Write commit and PR descriptions as natural flowing prose. Do NOT insert hard line breaks mid-paragraph.\n"
  },
  {
    "path": ".agents/skills/shipping-graphite/SKILL.md",
    "content": "---\nname: shipping-graphite\ndescription: Shipping workflow using Graphite CLI. Provides guidance for committing, branching, and creating PRs with Graphite's single-commit-per-branch model.\n---\n\n# Ship Code Using Graphite\n\nGuidance for shipping code using the [Graphite](https://graphite.dev/) CLI (`gt`). This skill teaches the agent how to create commits, branches, and PRs using Graphite's single-commit-per-branch model.\n\n## Key Rules\n\n- NEVER commit, push, create branches, or create PRs without explicit user approval.\n- Before any git operation that creates or modifies a commit, present a review block containing: changeset content (if applicable), commit title, and commit/PR description. ALWAYS wait for approval.\n- Show the proposed changeset entry for review before writing the changeset file.\n- Use `gt create -am \"Title\" -m \"Description body\"` for new PRs. The first `-m` sets the commit title; the second sets the PR description.\n- Use `gt modify -a` to amend the current branch with follow-up changes (NEVER create additional commits on the same branch).\n- ALWAYS escape backticks in commit messages with backslashes for shell compatibility (e.g. `\"Update \\`my-package\\` config\"`).\n- Write commit and PR descriptions as natural flowing prose. Do NOT insert hard line breaks mid-paragraph.\n\n## Guidelines\n\n### Creating a New PR\n\nUse `gt create` to create a new branch with a single commit:\n\n```sh\ngt create -am \"Commit title\" -m \"Description body explaining what changed and why.\"\n```\n\n- The first `-m` flag sets the commit title (first line of the commit message).\n- The second `-m` flag sets the commit body, which Graphite uses as the PR description when the stack is submitted.\n- Write the body as a concise flowing summary. Avoid excessive blank lines.\n- If a `.github/PULL_REQUEST_TEMPLATE.md` exists, use it as a guide for structuring the PR description. Fill in sections that are relevant and omit sections that don't apply (e.g. don't add \"Fixes #\" if there's no related issue).\n\n### Amending an Existing PR\n\nWhen making follow-up changes to the current branch, ALWAYS amend rather than creating new commits:\n\n```sh\ngt modify -a\n```\n\nThis amends the single commit on the current branch. Since Graphite uses a one-commit-per-branch model, ALWAYS use `gt modify -a` for follow-up changes on the same PR.\n\n### Submitting PRs\n\nDo NOT run `gt submit` (or `gt ss`) after creating or modifying branches. The `gt create` and `gt modify` steps are the end of the workflow unless the user explicitly asks to submit or push.\n\nWhen the user asks to submit, first run `gt sync` to ensure the local stack is up-to-date. This will restack branches from the main branch and prompt to delete any stale (merged) branches. If `gt sync` encounters any issues or conflicts, stop immediately and report the problem to the user before proceeding — await their instructions on how to resolve it.\n\nOnly after a clean sync, run `gt submit` to create or update PRs for all branches in the current stack.\n\n### Shell Escaping\n\nWhen commit titles or descriptions contain backticks (e.g. for package names or code references), escape them with a backslash so the shell passes them through literally:\n\n```sh\ngt create -am \"Align \\`kit-plugins\\` infrastructure\" -m \"This PR updates the shared config.\"\n```\n\n### Review Block Format\n\nBefore any git operation, present this review block and wait for approval:\n\n1. **Changeset entry** (if applicable) — the proposed changelog entry and bump type.\n2. **Commit title** — a concise title for the commit.\n3. **Commit/PR description** — a short description that explains what changed and why.\n"
  },
  {
    "path": ".agents/skills/ts-docblocks/INJECT.md",
    "content": "---\nheading: TypeScript Docblocks\n---\n\n- All exported functions, types, interfaces, and constants MUST have JSDoc docblocks.\n- Start with `/**`, use `*` prefix for each line, end with `*/` — each on its own line.\n- Begin with a clear one-to-two line summary. Add a blank line before tags.\n- Include `@param`, `@typeParam`, `@return`, `@throws`, and at least one `@example` when helpful.\n- Use `{@link ...}` to reference related items. Add `@see` tags at the end for related APIs.\n"
  },
  {
    "path": ".agents/skills/ts-docblocks/SKILL.md",
    "content": "---\nname: ts-docblocks\ndescription: Add missing JSDoc docblocks to exported symbols in TypeScript projects. Use when writing new exports or when code is missing documentation.\nargument-hint: \"[path] [--all]\"\n---\n\n# Add Missing Docblocks\n\nScan the specified path (or entire repository if no path given) and add missing docblocks to all exported functions, classes, interfaces, types, and constants.\n\n## Key Rules\n\n- All exported functions, types, interfaces, and constants MUST have JSDoc docblocks.\n- Start with `/**`, use `*` prefix for each line, end with `*/` — each on its own line.\n- Begin with a clear one-to-two line summary. Add a blank line before tags.\n- Include `@param`, `@typeParam`, `@return`, `@throws`, and at least one `@example` when helpful.\n- Use `{@link ...}` to reference related items. Add `@see` tags at the end for related APIs.\n- Do NOT modify real code outside of docblocks. Do NOT modify existing docblocks.\n\n## Guidelines\n\n### Style\n\nUse JSDoc format with the following conventions:\n\n- Start with `/**` on its own line.\n- Use `*` prefix for each line.\n- End with `*/` on its own line.\n- Keep descriptions concise but complete.\n- Start your sentences with a capital letter and end with a period.\n- Limit your usage of em dashes but, when you do use them, use spaces on both sides.\n- Begin with a clear one or two line summary (no `@summary` tag needed).\n- Add a blank line after the summary if adding more details.\n- Include `@param` tags for all parameters.\n- Include `@typeParam` tags for all type parameters. Use `@typeParam`, not `@template`.\n- Include `@return` tag briefly describing the return value.\n- Add `@throws` for functions that may throw errors and list these errors.\n- Include at least one `@example` section whenever usage examples would be helpful. If the file is a TypeScript file, use TypeScript syntax in examples. Try to make the examples realistic but concise and pleasant to read. They must illustrate the concepts clearly at first glance. When more than one example is preferred, use multiple `@example` tags and keep the first one as simple as possible to illustrate the basic usage. Never use `any` type in examples. Display the `import` statements required for the example to work when imports from multiple libraries are required. It is acceptable to use placeholder variable names like `myUser` or even `/* ... */` for parts that are not relevant to the example. When multiple example sections are provided, add a brief description before each code block to quickly explain what the example illustrates.\n- In the rare case where more advanced documentation is also needed for the item, use the `@remarks` tag to add this extra information after any example sections. These remarks can include longer explanations and even additional code blocks if necessary.\n- When an item is deprecated, include a `@deprecated` tag with a brief explanation and, if applicable, suggest an alternative.\n- Use `{@link ...}` tags to reference other items in the codebase when relevant.\n- Add `@see` tags at the very end when applicable to point to other related items or documentation. Use `@see {@link ...}` format when linking to other code items.\n\n### Examples\n\n````ts\n/**\n * Creates a retry wrapper around an async function.\n *\n * Retries the given function up to `maxRetries` times with exponential\n * backoff between attempts.\n *\n * @param fn - The async function to retry.\n * @param maxRetries - Maximum number of retry attempts.\n * @param baseDelay - Base delay in milliseconds between retries.\n * @return A wrapped version of `fn` that retries on failure.\n * @throws Throws the last error if all retry attempts are exhausted.\n *\n * @example\n * ```ts\n * const fetchWithRetry = withRetry(fetchData, 3, 1000);\n * const data = await fetchWithRetry('/api/users');\n * ```\n *\n * @example\n * Custom retry configuration for flaky network calls.\n * ```ts\n * const resilientFetch = withRetry(\n *   () => fetch('https://api.example.com/data'),\n *   5,\n *   500,\n * );\n * ```\n */\nexport function withRetry<T>(\n    fn: (...args: unknown[]) => Promise<T>,\n    maxRetries: number,\n    baseDelay: number,\n): (...args: unknown[]) => Promise<T>;\n````\n\n````ts\n/**\n * Fixes a `Uint8Array` to the specified length.\n *\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n *\n * @param bytes - The byte array to truncate or pad.\n * @param length - The desired length of the byte array.\n * @return The byte array truncated or padded to the desired length.\n *\n * @example\n * Truncates the byte array to the desired length.\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02, 0x03, 0x04]);\n * const fixedBytes = fixBytes(bytes, 2);\n * //    ^ [0x01, 0x02]\n * ```\n *\n * @example\n * Adds zeroes to the end of the byte array to reach the desired length.\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02]);\n * const fixedBytes = fixBytes(bytes, 4);\n * //    ^ [0x01, 0x02, 0x00, 0x00]\n * ```\n */\nexport const fixBytes = (\n    bytes: ReadonlyUint8Array | Uint8Array,\n    length: number,\n): ReadonlyUint8Array | Uint8Array;\n````\n\n````ts\n/**\n * A tree structure representing a set of instructions with execution constraints.\n *\n * Supports parallel execution, sequential execution, and combinations of both\n * through recursive composition of plan nodes.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = parallelPlan([\n *     sequentialPlan([instructionA, instructionB]),\n *     instructionC,\n *     instructionD,\n * ]);\n * ```\n *\n * @see {@link SingleInstructionPlan}\n * @see {@link ParallelInstructionPlan}\n * @see {@link SequentialInstructionPlan}\n */\nexport type InstructionPlan =\n    | ParallelInstructionPlan\n    | SequentialInstructionPlan\n    | SingleInstructionPlan;\n````\n\n## Command Process\n\nWhen invoked as a command, follow these steps:\n\n### Arguments\n\n- `[path]` (optional): Narrow the scan to a specific path (e.g. `src/utils` or `packages/my-lib/src`).\n- `[--all]` (optional): Also scan non-exported items.\n\n### Steps\n\n1. If a path argument is provided, scan only that path; otherwise scan the entire repository.\n2. Look for TypeScript/JavaScript files (`.ts`, `.tsx`, `.js`, `.jsx`).\n3. Identify exported items without docblocks:\n    - `export function`\n    - `export class`\n    - `export interface`\n    - `export type`\n    - `export const` (for constants and arrow functions)\n4. If `--all` is passed, also identify non-exported items.\n5. For each item missing a docblock:\n    - Analyze the code to understand its purpose (this may span multiple files).\n    - Examine parameters, return types, and behavior.\n    - Generate an appropriate docblock following the style guide.\n6. Present all changes clearly, grouped by file. Apply all changes without requiring further approval.\n"
  },
  {
    "path": ".agents/skills/ts-readme/INJECT.md",
    "content": "---\nheading: TypeScript READMEs\n---\n\n- When adding a new public API, add or update the package's README.\n- Structure: brief intro, installation, usage (with code snippet), deep-dive sections.\n- Code snippets must be realistic, concise, and use TypeScript syntax.\n- Focus on the quickest path to success. Developers should feel excited, not overwhelmed.\n"
  },
  {
    "path": ".agents/skills/ts-readme/SKILL.md",
    "content": "---\nname: ts-readme\ndescription: Guidelines for writing developer-friendly READMEs for TypeScript libraries. Use when creating a new package, changing a public API, or updating documentation.\nargument-hint: \"[path]\"\n---\n\n# Create or Update README\n\nCreate a new README or update an existing one for a TypeScript package, library, or project.\n\n## Key Rules\n\n- When adding a new public API, add or update the package's README.\n- Structure: brief intro, installation, usage (with code snippet), deep-dive sections.\n- Code snippets must be realistic, concise, and use TypeScript syntax.\n- Focus on the quickest path to success. Developers should feel excited, not overwhelmed.\n- Do NOT update any real code outside of the README file itself. If you identify errors in the codebase, warn the user but do not fix them.\n\n## Guidelines\n\nA deep understanding of the project is necessary to create an effective README. Analyze the codebase, key features, and typical usage patterns to inform the content. If the project relies on other libraries or frameworks, consider how those influence usage and installation.\n\n### Structure\n\nThe layout of a README will vary from project to project, but they should generally follow these guidelines.\n\n#### 1. Intro Section\n\n- Package/library name as the main heading.\n- Badges for tests, package version, downloads, etc. (npm, GitHub, etc.).\n- **Very brief summary (ELI5)** — A single sentence or short paragraph that anyone can understand at first glance.\n- Only update the intro if you can meaningfully improve the summary; otherwise leave it intact.\n\n#### 2. Installation Section\n\n- Keep it extremely concise (1-2 lines of explanation max if necessary).\n- Show the install command in a code block.\n\n#### 3. Usage Section (Most Critical)\n\n- This is where readers' attention lands first after the intro.\n- Show the **quickest path to success** with this library.\n- **Must include a code snippet** illustrating basic usage.\n- Balance between brevity and clarity to create an \"aha moment.\"\n- Optional: Brief text before/after the snippet if it adds clarity.\n- The code snippet should be realistic, concise, and immediately understandable.\n\n#### 4. Deep Dive Sections\n\n- Structure varies case-by-case based on the project.\n- Document key features, concepts, or use cases.\n- Each section should include **at least one code snippet**. Similar guidelines as the Usage section, that is, realistic and concise (shortest path to \"aha moment\").\n- Organize logically (e.g. by feature, by use case, by complexity).\n- Common patterns:\n    - **Features**: Individual feature documentation with examples.\n    - **API Reference**: Core APIs or functions.\n    - **Advanced Usage**: More complex scenarios.\n    - **Configuration**: Setup and customization options.\n    - **Examples**: Real-world use cases.\n- No need for a \"Requirements\" section for peer dependencies. Just mention them in the \"Installation\" section if necessary to get started.\n\n### Code Snippets\n\n- Use TypeScript syntax for TypeScript projects.\n- Show realistic but concise examples.\n- Include necessary imports when relevant (e.g. when importing from multiple modules).\n- Use descriptive variable names (not `foo`, `bar`).\n- Keep examples focused on one concept at a time when possible.\n- Format for readability (proper indentation, spacing).\n\n### Tone\n\n- Friendly and approachable.\n- Clear and direct.\n- Avoid marketing speak.\n- Focus on practical value.\n- Use active voice.\n- Assume the reader is a developer who wants to get started quickly.\n\n### What to Avoid\n\n- Overly long introductions or preambles.\n- Walls of text without code examples.\n- Complex examples in the Usage section.\n- Unexplained jargon or acronyms.\n- Marketing-heavy language.\n- Duplicating information unnecessarily.\n\n### Monorepo Considerations\n\nWhen working in a monorepo:\n\n- **Package READMEs**: Focus on the specific package — its API, installation, usage, and features. Include an installation note pointing to an umbrella package as an alternative if one exists.\n- **Root README**: Provides an overview of the entire monorepo, links to individual package READMEs for details. Focus on the quick-start experience rather than deep-diving into each package.\n- **Consistency**: When updating a package README, check other package READMEs for structural consistency (heading levels, section order, code example style).\n\n## Command Process\n\nWhen invoked as a command, follow these steps:\n\n### Arguments\n\n- `[path]` (optional): Path to the README file or its parent directory. Defaults to `./README.md`.\n\n### Steps\n\n1. Determine the target README path:\n    - If a path argument is provided and ends with `.md`, use it directly.\n    - If the argument is a directory path, use `<path>/README.md`.\n    - If no argument is provided, use `./README.md`.\n\n2. Check if the README exists:\n    - If it exists, read it to understand the current structure.\n    - If it doesn't exist, prepare to create one from scratch.\n\n3. Analyze the project context:\n    - Examine `package.json` (if exists) for package name, description, dependencies.\n    - Look at the source code to understand what the library does.\n    - Identify key exports, main functions, and typical usage patterns.\n    - Check for existing tests or examples that show usage.\n    - Research any related libraries or frameworks that influence usage.\n    - If in a monorepo, examine other package READMEs to ensure consistency in style and structure.\n\n4. Create or update the README:\n    - **For existing READMEs**: Identify missing sections or areas needing improvement.\n    - **For new READMEs**: Build the full structure following the guidelines.\n    - Preserve the intro unless improvements are clear.\n    - Ensure the Usage section has a strong, clear example.\n    - Add or improve deep dive sections as needed.\n    - Include realistic code snippets throughout.\n\n5. Present the complete README for review before applying changes.\n"
  },
  {
    "path": ".bundlemonrc.json",
    "content": "{\n    \"baseDir\": \"./packages/\",\n    \"files\": [\n        {\n            \"friendlyName\": \"@solana/kit production bundle\",\n            \"path\": \"kit/dist/index.production.min.js\"\n        },\n        {\n            \"path\": \"**/dist/index.*.mjs\"\n        }\n    ],\n    \"includeCommitMessage\": true,\n    \"reportOutput\": [\"github\"]\n}\n"
  },
  {
    "path": ".changeset/bold-drinks-strive.md",
    "content": "---\n'@solana/rpc-spec': minor\n'@solana/kit': minor\n---\n\nAdd a `reactiveStore()` method to `PendingRpcRequest`. It fires the request on construction and synchronously returns a `ReactiveActionStore` that holds the request's `idle`/`running`/`success`/`error` lifecycle state. Compatible with `useSyncExternalStore`, Svelte stores, and other reactive primitives. Call `dispatch()` to re-fire the request (e.g. after an error), or `reset()` to abort the in-flight call and return to idle.\n\n```ts\nconst store = rpc.getAccountInfo(address).reactiveStore();\nconst state = useSyncExternalStore(store.subscribe, store.getState);\nif (state.status === 'error') return <ErrorMessage error={state.error} onRetry={store.dispatch} />;\nif (state.status === 'running' && !state.data) return <Spinner />;\nreturn <View data={state.data!} />;\n```\n"
  },
  {
    "path": ".changeset/brown-candles-relax.md",
    "content": "---\n'@solana/rpc-subscriptions-spec': minor\n'@solana/kit': minor\n---\n\nAdd a `reactiveStore()` method to `PendingRpcSubscriptionsRequest`. Unlike `reactive()`, this variant returns a `ReactiveStore` synchronously and supports `retry()` to reconnect after an error. `reactive()` is now `@deprecated` in favour of `reactiveStore()`.\n\n```ts\nconst store = rpc.accountNotifications(address).reactiveStore({ abortSignal });\nconst state = useSyncExternalStore(store.subscribe, store.getUnifiedState);\nif (state.status === 'error') return <ErrorMessage error={state.error} onRetry={store.retry} />;\n```\n"
  },
  {
    "path": ".changeset/clever-spies-shout.md",
    "content": "---\n'@solana/subscribable': minor\n'@solana/errors': minor\n'@solana/kit': minor\n---\n\nAdd `retry()` and `getUnifiedState()` to `ReactiveStore`. The new `getUnifiedState()` returns a discriminated `{ data, error, status }` snapshot with stable identity, so stores can be passed directly to `useSyncExternalStore` without an intermediate wrapper. `getState()` and `getError()` remain on the type but are now `@deprecated` in favour of the unified snapshot.\n\nA new `createReactiveStoreFromDataPublisherFactory` function is also introduced. It accepts a `createDataPublisher: () => Promise<DataPublisher>` factory rather than a ready-made publisher, which lets the store reconnect via `retry()` after an error. The existing `createReactiveStoreFromDataPublisher` is now `@deprecated`; calling `retry()` on a store it produced throws a new `SolanaError` with code `SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED`.\n\n`createReactiveStoreWithInitialValueAndSlotTracking` (from `@solana/kit`) now supports `retry()`, which re-sends the RPC request and re-subscribes to the subscription with a fresh abort signal while preserving the last known slot and value.\n"
  },
  {
    "path": ".changeset/config.json",
    "content": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config@3.0.0/schema.json\",\n  \"access\": \"public\",\n  \"baseBranch\": \"main\",\n  \"bumpVersionsWithWorkspaceProtocolOnly\": true,\n  \"changelog\": [\n    \"@changesets/changelog-github\",\n    {\n      \"repo\": \"anza-xyz/kit\"\n    }\n  ],\n  \"fixed\": [[\"@solana/!({example-*,*-impl,build-scripts,eslint-config,test-*,tsconfig,web3.js})\"]],\n  \"linked\": [],\n  \"snapshot\": {\n    \"useCalculatedVersion\": true\n  },\n  \"privatePackages\": {\n    \"version\": false,\n    \"tag\": false\n  },\n  \"updateInternalDependencies\": \"patch\"\n}\n"
  },
  {
    "path": ".changeset/some-views-pick.md",
    "content": "---\n'@solana/subscribable': minor\n'@solana/rpc-subscriptions-spec': minor\n'@solana/kit': minor\n'@solana/errors': minor\n---\n\nRename `ReactiveStore<T>` to `ReactiveStreamStore<T>`. The old name remains exported as a deprecated alias and will be removed in a future major release.\n"
  },
  {
    "path": ".changeset/thin-cats-drop.md",
    "content": "---\n'@solana/subscribable': minor\n---\n\nAdded `createReactiveActionStore` — a framework-agnostic state machine that wraps an async function and exposes a `{ dispatch, dispatchAsync, getState, subscribe, reset }` contract compatible with `useSyncExternalStore`, Svelte stores, Vue's `shallowRef`, and similar reactive primitives. `dispatch` is synchronous and fire-and-forget (safe from UI event handlers); `dispatchAsync` returns a promise that resolves to the wrapped function's result and rejects on failure or supersede — use `isAbortError` from `@solana/promises` to filter aborts. Each call creates a fresh `AbortController` and aborts the previous one, so rapid successive dispatches only produce one final state transition — the outcome of the most recent call.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/0_bug.md",
    "content": "---\nname: Report a Bug\nabout: Help us reproduce a bug you've found so that we can fix it\ntitle: ''\nlabels: ['bug']\nassignees: ''\n---\n\n<!-- Please fill in each section completely. Thank you! -->\n\n## Overview\n\n<!-- Say a few words about how you came to discover this bug -->\n\n## Steps to reproduce\n\n<!--\n  List the steps that someone unfamiliar with your problem would\n  have to take to observe this bug.\n\n  Ideally, include a code snippet or link to a repository that\n  someone can run locally to reproduce the problem.\n-->\n\n## Description of bug\n\n<!--\n  Describe what happened that you did not expect, or what did not\n  happen the way you had hoped.\n\n  Include the full text of error messages and logs, if any.\n  Do not upload screenshots of error messages.\n-->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/1_feature.md",
    "content": "---\nname: Suggest a Feature\nabout: Propose an idea for how to make this library better.\ntitle: ''\nlabels: ['enhancement']\nassignees: ''\n---\n\n<!-- Please fill in each section completely. Thank you! -->\n\n## Motivation\n\n<!--\n  Say a few words about what motivated you to propose this enhancement.\n-->\n\n## Example use case\n\n<!--\n  Demonstrate how someone might use this new feature.\n\n  If applicable, write code or pseudocode that would produce the\n  desired result if this feature existed.\n-->\n\n## Details\n\n<!--\n  Go into detail about how this new feature must behave. If you have\n  ideas on how to implement it, go into them here.\n-->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "contact_links:\n  - about: 'Have a question about using this software, or about Solana in general? Post it on the Solana Stack Exchange.'\n    name: Ask a Question\n    url: 'https://solana.stackexchange.com/questions/ask'\n  - about: 'Start or join a discussion on the Solana Tech Discord.'\n    name: Start a Discussion\n    url: 'https://solana.com/discord'\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "#### Problem\n\n\n\n#### Summary of Changes\n\n\n\nFixes #"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: 'npm'\n    directory: '/'\n    schedule:\n      interval: daily\n      time: '01:00'\n      timezone: America/Los_Angeles\n    ignore:\n      - dependency-name: '@radix-ui/react-dropdown-menu'\n    groups:\n      eslint:\n        patterns:\n          - '@eslint/*'\n          - '@typescript-eslint/*'\n          - 'typescript'\n      solana-program-clients:\n        patterns:\n          - '@solana-program/*'\n      react:\n        patterns:\n          - 'react'\n          - 'react-dom'\n      undici:\n        patterns:\n          - 'undici'\n          - 'undici-types'\n  - package-ecosystem: 'npm'\n    directory: '/docs'\n    schedule:\n      interval: daily\n      time: '01:00'\n      timezone: America/Los_Angeles\n    groups:\n      eslint:\n        patterns:\n          - 'eslint*'\n          - 'typescript'\n      solana:\n        patterns:\n          - '@solana/*'\n      solana-program-clients:\n        patterns:\n          - '@solana-program/*'\n      react:\n        patterns:\n          - 'react'\n          - 'react-dom'\n      undici:\n        patterns:\n          - 'undici'\n          - 'undici-types'\n"
  },
  {
    "path": ".github/label-actions.yml",
    "content": "question:\n  issues:\n    # Post a comment, `{issue-author}` is an optional placeholder\n    comment: >\n      Hi @{issue-author},\n\n\n      Thanks for your question!\n\n\n      We want to make sure to keep signal strong in the GitHub issue tracker &ndash; to make sure\n      that it remains the best place to track issues that affect the development of the Solana\n      JavaScript SDK itself.\n\n\n      Questions like yours deserve a purpose-built Q&A forum. Unless there exists evidence that\n      this is a bug with the Solana JavaScript SDK itself, please post your question to the Solana \n      Stack Exchange using this link: https://solana.stackexchange.com/questions/ask\n\n\n      ---\n\n      _This\n      [automated message](https://github.com/anza-xyz/kit/blob/main/.github/label-actions.yml)\n      is a result of having added the &lsquo;question&rsquo; tag_.\n\n    # Close the issue\n    close: true\n"
  },
  {
    "path": ".github/workflows/actions/install-dependencies/action.yml",
    "content": "name: Install Dependencies\ndescription: Sets up Node and its package manager, then installs all dependencies\n\ninputs:\n  version:\n    default: 'lts/*'\n    type: string\n\nruns:\n  using: composite\n  steps:\n    - name: Install package manager\n      uses: pnpm/action-setup@v4\n      with:\n        version: 10.24.0\n\n    - name: Setup Node\n      uses: actions/setup-node@v4\n      with:\n        cache: 'pnpm'\n        node-version: ${{ inputs.version }}\n        registry-url: 'https://registry.npmjs.org'\n\n    - name: Install dependencies\n      shell: bash\n      run: pnpm install\n"
  },
  {
    "path": ".github/workflows/actions/setup-validator/action.yml",
    "content": "name: Install Solana Test Validator\ndescription: Downloads and caches an install of the latest Solana Test Validator\n\noutputs:\n  pid:\n    description: The process id of the running test validator\n    value: ${{ steps.start-validator.outputs.pid }}\n\nruns:\n  using: composite\n  steps:\n    - name: Get Test Validator Latest Release\n      id: get-test-validator-version\n      shell: bash\n      run: echo \"version=$(./scripts/get-latest-validator-release-version.sh)\" >> $GITHUB_OUTPUT\n\n    - name: Cache Test Validator\n      id: cache-test-validator\n      uses: actions/cache@v4\n      with:\n        path: .agave\n        key: ${{ runner.os }}-test-validator-${{ steps.get-test-validator-version.outputs.version }}\n\n    - name: Install Test Validator\n      if: steps.cache-test-validator.outputs.cache-hit != 'true'\n      shell: bash\n      run: ./scripts/setup-test-validator.sh\n\n    - name: Start Test Validator\n      id: start-validator\n      shell: bash\n      run: |\n        ./scripts/start-shared-test-validator.sh &\n        echo \"pid=$!\" >> $GITHUB_OUTPUT\n"
  },
  {
    "path": ".github/workflows/autolock-inactive-threads.yml",
    "content": "name: 'Lock inactive threads'\n\non:\n  # Chosen to be just before London wakes up and way past San Francisco's bedtime.\n  schedule:\n    - cron: '0 8 * * 1-5' # This is in UTC.\n  workflow_dispatch:\n\npermissions:\n  issues: write\n  pull-requests: write\n\nconcurrency:\n  group: lock\n\njobs:\n  autolock-inactive-threads:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771\n        with:\n          github-token: ${{ github.token }}\n          issue-inactive-days: '7'\n          issue-lock-reason: 'resolved'\n          issue-comment: >\n            Because there has been no activity on this issue for 7 days since it was closed, it has \n            been automatically locked. Please open a new issue if it requires a follow up.\n          pr-inactive-days: '14'\n          pr-lock-reason: 'resolved'\n          pr-comment: >\n            Because there has been no activity on this PR for 14 days since it was merged, it has \n            been automatically locked. Please open a new issue if it requires a follow up.\n          process-only: 'issues, prs'\n"
  },
  {
    "path": ".github/workflows/backport.yml",
    "content": "name: Backport\non:\n  pull_request_target:\n    types:\n      - closed\n      - labeled\n\npermissions:\n  contents: write\n  pull-requests: write\n\njobs:\n  backport:\n    name: Backport\n    runs-on: ubuntu-latest\n    # Only react to merged PRs for security reasons.\n    # See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target.\n    if: >\n      github.event.pull_request.merged\n      && (\n        github.event.action == 'closed'\n        || (\n          github.event.action == 'labeled'\n          && contains(github.event.label.name, 'backport')\n        )\n      )\n    steps:\n      - uses: tibdex/backport@9565281eda0731b1d20c4025c43339fb0a23812e\n        with:\n          github_token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/bundlesize.yml",
    "content": "name: Compare bundle size\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n    types: [synchronize, opened, reopened]\n\npermissions:\n  contents: read\n\nenv:\n  # Among other things, opts out of Turborepo telemetry\n  # See https://consoledonottrack.com/\n  DO_NOT_TRACK: '1'\n  # Some tasks slow down considerably on GitHub Actions runners when concurrency is high\n  TURBO_CONCURRENCY: 1\n  # Enables Turborepo Remote Caching.\n  TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}\n  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n  TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n\njobs:\n  measure-bundlesize:\n    permissions:\n      pull-requests: write\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n        with:\n          version: current\n\n      - name: Build\n        run: pnpm turbo compile:js --concurrency=${TURBO_CONCURRENCY:-1}\n\n      - name: BundleMon\n        uses: lironer/bundlemon-action@cadbdd58f86faf1900725ef69d455444124b3748\n        env:\n          # Always compare to the main branch; prevents stacked PRs from being\n          # compared to the wrong mergebase (ie. the PR beneath the current one)\n          CI_TARGET_BRANCH: main\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "content": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# You may wish to alter this file to override the set of languages analyzed,\n# or to provide custom queries or build logic.\n#\n# ******** NOTE ********\n# We have attempted to detect the languages in your repository. Please check\n# the `language` matrix defined below to confirm you have the correct set of\n# supported CodeQL languages.\n#\nname: \"CodeQL Advanced\"\n\non:\n  push:\n    branches:\n      - \"main\"\n  schedule:\n    - cron: \"30 13 * * 0\"\n\njobs:\n  analyze:\n    name: Analyze (${{ matrix.language }})\n    # Runner size impacts CodeQL analysis time. To learn more, please see:\n    #   - https://gh.io/recommended-hardware-resources-for-running-codeql\n    #   - https://gh.io/supported-runners-and-hardware-resources\n    #   - https://gh.io/using-larger-runners (GitHub.com only)\n    # Consider using larger runners or machines with greater resources for possible analysis time improvements.\n    runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}\n    permissions:\n      # required for all workflows\n      security-events: write\n\n      # required to fetch internal or private CodeQL packs\n      packages: read\n\n      # only required for workflows in private repositories\n      actions: read\n      contents: read\n\n    strategy:\n      fail-fast: false\n      matrix:\n        include:\n          - language: actions\n            build-mode: none\n          - language: javascript-typescript\n            build-mode: none\n        # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'\n        # Use `c-cpp` to analyze code written in C, C++ or both\n        # Use 'java-kotlin' to analyze code written in Java, Kotlin or both\n        # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both\n        # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,\n        # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.\n        # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how\n        # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      # Add any setup steps before running the `github/codeql-action/init` action.\n      # This includes steps like installing compilers or runtimes (`actions/setup-node`\n      # or others). This is typically only required for manual builds.\n      # - name: Setup runtime (example)\n      #   uses: actions/setup-example@v1\n\n      # Initializes the CodeQL tools for scanning.\n      - name: Initialize CodeQL\n        uses: github/codeql-action/init@v4\n        with:\n          languages: ${{ matrix.language }}\n          build-mode: ${{ matrix.build-mode }}\n          # If you wish to specify custom queries, you can do so here or in a config file.\n          # By default, queries listed here will override any specified in a config file.\n          # Prefix the list here with \"+\" to use these queries and those in the config file.\n\n          # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs\n          # queries: security-extended,security-and-quality\n\n      # If the analyze step fails for one of the languages you are analyzing with\n      # \"We were unable to automatically build your code\", modify the matrix above\n      # to set the build mode to \"manual\" for that language. Then modify this step\n      # to build your code.\n      # ℹ️ Command-line programs to run using the OS shell.\n      # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun\n      - name: Run manual build steps\n        if: matrix.build-mode == 'manual'\n        shell: bash\n        run: |\n          echo 'If you are using a \"manual\" build mode for one or more of the' \\\n            'languages you are analyzing, replace this with the commands to build' \\\n            'your code, for example:'\n          echo '  make bootstrap'\n          echo '  make release'\n          exit 1\n\n      - name: Perform CodeQL Analysis\n        uses: github/codeql-action/analyze@v4\n        with:\n          category: \"/language:${{matrix.language}}\"\n"
  },
  {
    "path": ".github/workflows/deploy-docs.yml",
    "content": "name: Deploy Documentation\n\non:\n  workflow_dispatch:\n    branches:\n      - main\n  push:\n    branches:\n      - main\n\npermissions:\n  contents: read\n  pull-requests: write\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\nenv:\n  # Among other things, opts out of Turborepo telemetry\n  # See https://consoledonottrack.com/\n  DO_NOT_TRACK: '1'\n  NEXT_TELEMETRY_DISABLED: '1'\n  VERCEL_TELEMETRY_DISABLED: '1'\n  # Enables Turborepo Remote Caching.\n  TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}\n  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n  TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n\njobs:\n  deploy-docs:\n    runs-on: ubuntu-latest\n    name: Deploy Documentation\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n\n      - name: Install Isolated Docs Dependencies\n        working-directory: ./docs/\n        shell: bash\n        run: pnpm install --ignore-workspace\n\n      - name: Install Vercel CLI\n        run: pnpm install -g vercel\n\n      - name: Deploy to Vercel\n        shell: bash\n        env:\n          VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}\n          VERCEL_PROJECT_ID: ${{ secrets.VERCEL_DOCS_PROJECT_ID }}\n          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}\n        run: |\n          vercel pull --token=\"$VERCEL_TOKEN\" --yes --environment=production\n          vercel build --token=\"$VERCEL_TOKEN\" --prod\n          vercel deploy --token=\"$VERCEL_TOKEN\" --archive=tgz --prebuilt --prod\n\n      - name: Synchronize InKeep Search Index\n        uses: inkeep/pr-commenter-action@84ccc7c74b72f628ec7e2b572e0cb7afd5898594 # v10\n        env:\n          GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}\n        with:\n          apiKey: ${{secrets.INKEEP_SEARCH_MANAGEMENT_API_KEY}}\n          sourceId: '${{vars.INKEEP_SEARCH_SOURCE_ID}}'\n"
  },
  {
    "path": ".github/workflows/dismiss-stale-pr-reviews.yml",
    "content": "name: Dismiss Stale PR Reviews\n\non:\n  pull_request_target:\n    types: [opened, synchronize, reopened]\n\npermissions:\n  actions: read\n  contents: read\n  pull-requests: write\n\njobs:\n  dismiss-stale-approvals:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Dismiss Stale PR Reviews\n        if: ${{ !contains('OWNER,MEMBER,COLLABORATOR', github.event.pull_request.author_association) }}\n        uses: withgraphite/dismiss-stale-approvals@15571275d9bf7410e51244e259cd8f9f554879c8\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/label-actions.yml",
    "content": "name: 'Issue Label Actions'\n\non:\n  issues:\n    types: [labeled, unlabeled]\n\npermissions:\n  contents: read\n  issues: write\n\njobs:\n  label:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: dessant/label-actions@102faf474a544be75fbaf4df54e73d3c515a0e65\n"
  },
  {
    "path": ".github/workflows/manage-stale-threads.yml",
    "content": "name: 'Manage stale issues and PRs'\non:\n  # Chosen to be just before London wakes up and way past San Francisco's bedtime.\n  schedule:\n    - cron: '0 8 * * 1-5' # This is in UTC.\n  # Do a dry-run (debug-only: true) whenever this workflow itself is changed.\n  pull_request:\n    paths:\n      - .github/workflows/manage-stale-threads.yml\n    types:\n      - opened\n      - synchronize\n\npermissions:\n  issues: write\n  pull-requests: write\n\njobs:\n  manage-stale-threads:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/stale@v6\n        with:\n          ascending: true # Spend API operations budget on older, more-likely-to-get-closed issues first\n          close-issue-message: '' # Leave no comment when closing\n          close-pr-message: '' # Leave no comment when closing\n          days-before-issue-stale: 365\n          days-before-pr-stale: 14\n          days-before-close: 7\n          debug-only: ${{ github.event_name == 'pull_request' }} # Dry-run when true.\n          exempt-all-milestones: true # Milestones can sometimes last a month, so exempt issues attached to a milestone.\n          exempt-issue-labels: blocked,do-not-close,feature-gate,security\n          exempt-pr-labels: blocked,do-not-close,feature-gate,security\n          # No actual changes get made in debug-only mode, so we can raise the operations ceiling.\n          operations-per-run: ${{ github.event_name == 'pull_request' && 1000 || 900}}\n          stale-issue-label: stale\n          stale-issue-message: '' # Leave no comment when marking as stale\n          stale-pr-label: stale\n          stale-pr-message: '' # Leave no comment when marking as stale\n"
  },
  {
    "path": ".github/workflows/preview-docs.yml",
    "content": "name: Preview Documentation\n\non:\n  pull_request:\n  merge_group:\n\npermissions:\n  contents: read\n\nenv:\n  # Among other things, opts out of Turborepo telemetry\n  # See https://consoledonottrack.com/\n  DO_NOT_TRACK: '1'\n  NEXT_TELEMETRY_DISABLED: '1'\n  VERCEL_TELEMETRY_DISABLED: '1'\n  # Some tasks slow down considerably on GitHub Actions runners when concurrency is high\n  TURBO_CONCURRENCY: 1\n  # Enables Turborepo Remote Caching.\n  TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}\n  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n  TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n\njobs:\n  preview-docs:\n    permissions:\n      pull-requests: write\n    runs-on: ubuntu-latest\n    name: Build Documentation Preview\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n\n      - name: Install Isolated Docs Dependencies\n        working-directory: ./docs/\n        shell: bash\n        run: pnpm install --ignore-workspace\n\n      - name: Install Vercel CLI\n        run: pnpm install -g vercel\n\n      - name: Deploy to Vercel\n        if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'\n        shell: bash\n        id: vercel_deploy\n        env:\n          BRANCH_NAME: ${{ github.head_ref }}\n          PR_NUMBER: ${{ github.event.pull_request.number }}\n          VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}\n          VERCEL_PROJECT_ID: ${{ secrets.VERCEL_DOCS_PROJECT_ID }}\n          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}\n        run: |\n          vercel pull --token=\"$VERCEL_TOKEN\" --yes --environment=preview\n          vercel build --token=\"$VERCEL_TOKEN\" --target=preview\n          DEPLOY_OUTPUT=$(vercel deploy --token=\"$VERCEL_TOKEN\" --archive=tgz --env GITHUB_PR_NUMBER=\"$PR_NUMBER\" --env GITHUB_PR_BRANCH=\"$BRANCH_NAME\" --prebuilt --target=preview 2>&1)\n          DEPLOY_EXIT_CODE=$?\n          if [ $DEPLOY_EXIT_CODE -ne 0 ]; then\n            echo \"Vercel deploy failed:\"\n            echo \"$DEPLOY_OUTPUT\"\n            exit $DEPLOY_EXIT_CODE\n          fi\n          DEPLOY_URL=$(echo \"$DEPLOY_OUTPUT\" | grep -o 'https://[a-zA-Z0-9.-]*\\.vercel\\.app' | tail -1)\n          echo \"preview_url=$DEPLOY_URL\" >> $GITHUB_OUTPUT\n\n      - name: Comment on PR with Preview URL\n        if: steps.vercel_deploy.outcome == 'success'\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          PR_NUMBER: ${{ github.event.pull_request.number }}\n          PREVIEW_URL: '${{ steps.vercel_deploy.outputs.preview_url }}'\n        run: |\n          gh pr comment $PR_NUMBER --body \"Documentation Preview: $PREVIEW_URL\" --create-if-none --edit-last\n"
  },
  {
    "path": ".github/workflows/publish-packages.yml",
    "content": "name: Publish Packages (or Tag Release Manually upon manual dispatch)\n\non:\n  workflow_dispatch:\n    branches:\n      - main\n      - backport/**\n    inputs:\n      version:\n        description: 'Version'\n        required: true\n        type: string\n      tag:\n        description: 'Tag name'\n        required: true\n        type: string\n  push:\n    branches:\n      - main\n      - backport/**\n\npermissions:\n  contents: read\n\nenv:\n  # Among other things, opts out of Turborepo telemetry\n  # See https://consoledonottrack.com/\n  DO_NOT_TRACK: '1'\n  # Enables Turborepo Remote Caching.\n  TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}\n  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n  TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n\njobs:\n  build-and-publish-to-npm:\n    permissions:\n      contents: write\n      id-token: write\n      pull-requests: write\n    runs-on: ubuntu-latest\n    if: github.event_name == 'push'\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n\n      - name: Setup Solana Test Validator\n        id: start-test-validator\n        uses: ./.github/workflows/actions/setup-validator\n\n      - name: Build And Test (bypass cache)\n        run: pnpm build --force\n\n      - name: Create Changesets Pull Request or Publish to NPM\n        id: changesets\n        uses: changesets/action@e0145edc7d9d8679003495b11f87bd8ef63c0cba # v1.5.3\n        with:\n          publish: pnpm changeset:publish\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          PUBLISH_TAG: latest\n          # Some tasks slow down considerably on GitHub Actions runners when concurrency is high\n          TURBO_CONCURRENCY: 1\n\n      - name: Create GitHub Release\n        if: steps.changesets.outputs.published == 'true'\n        run: |\n          cd ./packages/build-scripts/\n          ./create-github-release.ts\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Stop Test Validator\n        if: always() && steps.start-test-validator.outcome == 'success'\n        run: kill ${{ steps.start-test-validator.outputs.pid }}\n\n  build-and-publish-snapshots-to-npm:\n    permissions:\n      id-token: write\n      pull-requests: write\n    runs-on: ubuntu-latest\n    if: github.event_name == 'push' && github.ref == 'refs/heads/main'\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n\n      - name: Setup Solana Test Validator\n        id: start-test-validator\n        uses: ./.github/workflows/actions/setup-validator\n\n      - name: Run Build Step\n        run: pnpm build\n\n      - name: Publish Canary Releases\n        run: |\n          if [ -n \"$(find .changeset -name '*.md')\" ]; then\n            pnpm changeset version --snapshot canary\n            pnpm changeset:publish\n          else\n            echo \"No changesets found, skipping canary publish\"\n          fi\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          PUBLISH_TAG: canary\n\n      - name: Stop Test Validator\n        if: always() && steps.start-test-validator.outcome == 'success'\n        run: kill ${{ steps.start-test-validator.outputs.pid }}\n\n  validate-version-exists:\n    permissions:\n      contents: read\n    runs-on: ubuntu-latest\n    if: github.event_name == 'workflow_dispatch'\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n\n      - name: Validate that a package at the given version has already been published\n        run: |\n          echo '${{ github.event.inputs.version }}' | grep -E \"^([0-9]+\\.){0,2}[0-9]+$\" > /dev/null || echo 'Version must be of the form X.Y.Z'\n          pnpm view '@solana/kit@${{ github.event.inputs.version }}'\n\n  tag-release-manually:\n    permissions:\n      contents: write\n      id-token: write\n    needs: validate-version-exists\n    runs-on: ubuntu-latest\n    if: github.event_name == 'workflow_dispatch'\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n\n      - name: Tag Release Manually\n        run: ./packages/build-scripts/tag-release-manually.ts --version '${{ github.event.inputs.version }}' --tag '${{ github.event.inputs.tag }}'\n"
  },
  {
    "path": ".github/workflows/pull-requests.yml",
    "content": "name: Pull requests\n\non:\n  pull_request:\n  merge_group:\n\npermissions:\n  contents: read\n\nenv:\n  # Among other things, opts out of Turborepo telemetry\n  # See https://consoledonottrack.com/\n  DO_NOT_TRACK: '1'\n  # Some tasks slow down considerably on GitHub Actions runners when concurrency is high\n  TURBO_CONCURRENCY: 1\n  # Enables Turborepo Remote Caching.\n  TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}\n  TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}\n  TURBO_TEAM: ${{ vars.TURBO_TEAM }}\n\njobs:\n  # Needed for grouping check-web3 strategies into one check\n  all-web3-checks:\n    runs-on: ubuntu-latest\n    needs: build-and-test\n    steps:\n      - run: echo \"Done\"\n\n  build-and-test:\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node:\n          - 'current'\n          - 'lts/*'\n\n    name: Build & Test on Node ${{ matrix.node }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n        with:\n          version: ${{ matrix.node }}\n\n      - name: Setup Solana Test Validator\n        id: start-test-validator\n        uses: ./.github/workflows/actions/setup-validator\n\n      - name: Build & Test\n        run: pnpm build # Don't add --concurrency here; it's already baked in\n\n      - name: Stop Test Validator\n        if: always() && steps.start-test-validator.outcome == 'success'\n        run: kill ${{ steps.start-test-validator.outputs.pid }}\n\n  dependabot:\n    runs-on: ubuntu-latest\n    if: github.event_name == 'pull_request' && github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'anza-xyz/kit'\n    needs: [build-and-test]\n    permissions:\n      contents: write\n      pull-requests: write\n    steps:\n      - name: Auto-approve the PR\n        run: gh pr review --approve \"$PR_URL\"\n        env:\n          PR_URL: ${{ github.event.pull_request.html_url }}\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n      - name: Enable auto-merge\n        run: gh pr merge --auto --squash \"$PR_URL\"\n        env:\n          PR_URL: ${{ github.event.pull_request.html_url }}\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/update-docs-lockfile.yml",
    "content": "name: Update Docs Lockfile\n\non:\n  pull_request_target:\n    paths:\n      - 'docs/package.json'\n\npermissions:\n  contents: write\n\njobs:\n  update-lockfile:\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: write\n    if: github.event.pull_request.user.login == 'dependabot[bot]'\n    steps:\n      - uses: actions/create-github-app-token@v2\n        id: app-token\n        with:\n          app-id: ${{ vars.APP_ID }}\n          private-key: ${{ secrets.PRIVATE_KEY }}\n\n      - name: Set git config\n        run: |\n          git config --global user.email \"github-actions@github.com\"\n          git config --global user.name \"github-actions\"\n          git config --global url.\"https://x-access-token:${GITHUB_TOKEN}@github.com/\".insteadOf https://github.com/\n        env:\n          GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}\n\n      - name: Checkout PR branch\n        uses: actions/checkout@v6\n        with:\n          token: ${{ steps.app-token.outputs.token }}\n          ref: ${{ github.event.pull_request.head.ref }}\n          persist-credentials: false\n\n      - name: Install Dependencies\n        uses: ./.github/workflows/actions/install-dependencies\n\n      - name: Update Docs Lockfile\n        working-directory: ./docs/\n        run: pnpm install --ignore-workspace --no-frozen-lockfile --ignore-scripts\n\n      - name: Commit and Push\n        run: |\n          git add docs/pnpm-lock.yaml\n          if git diff --cached --quiet; then\n            echo \"No lockfile changes to commit\"\n          else\n            git commit -m \"Update docs lockfile\"\n            git push\n          fi\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\n.pnp\n.pnp.js\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n.pnpm-debug.log*\n\n# turbo\n.turbo\n\n# Sapling SCM\n.sl\n\n# `solana-test-validator`\n.agave/\ntest-ledger/\n\n# ignore JetBrains IDE\n.idea\n"
  },
  {
    "path": ".npmrc",
    "content": "auto-install-peers=true\nengine-strict=true\nworkspaces-update=false"
  },
  {
    "path": ".prettierignore",
    "content": ".changeset/\n.github/**.md\n\n# These are autogenerated, so leave them alone\n**/CHANGELOG.md\n\ndeclarations/\ndist/\ndoc/\nlib/\n!docs/src/lib\n\npnpm-lock.yaml\npnpm-workspace.yaml\n"
  },
  {
    "path": ".skills-inject.json",
    "content": "{\n  \"targets\": [\n    \"CLAUDE.md\"\n  ],\n  \"skillsDirs\": [\n    \".agents/skills\",\n    \".claude/skills\"\n  ]\n}\n"
  },
  {
    "path": ".vscode/extensions.json",
    "content": "{\n    \"recommendations\": [\n        \"esbenp.prettier-vscode\"\n    ]\n}"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n    \"editor.defaultFormatter\": \"esbenp.prettier-vscode\"\n}\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# Agent Instructions\n\n## Project Overview\n\nKit (`@solana/kit`) is the official JavaScript SDK for building Solana applications, maintained by Anza. The official documentation lives at https://solanakit.com (docs at `/docs`, API reference at `/api`). The GitHub repo is `anza-xyz/kit`.\n\nThis is a pnpm monorepo with ~57 packages under `packages/`, orchestrated by Turborepo. The main `@solana/kit` package is a facade that re-exports ~20 workspace packages (accounts, addresses, codecs, errors, keys, rpc, signers, transactions, etc.) and adds its own convenience helpers like `sendAndConfirmTransaction`, `airdrop`, and `fetchLookupTables`.\n\nThe documentation website supports an `.mdx` suffix on any page (e.g. `https://solanakit.com/docs/concepts/transactions.mdx`) which returns a cleaner markdown representation suitable for LLM consumption. Use this when you need to look up Kit APIs or concepts.\n\nThere is also a companion [`anza-xyz/kit-plugins`](https://github.com/anza-xyz/kit-plugins) monorepo that builds an abstraction layer on top of Kit by offering composable plugins and ready-to-use clients (which are essentially curated sets of plugins). The plugin system relies on the `@solana/plugin-core` and `@solana/plugin-interfaces` packages defined in this repo. Additionally, `@solana/program-client-core` (re-exported from `@solana/kit/program-client-core`) provides the helpers used by the [Codama JS renderer](https://github.com/codama-idl/renderers-js) to generate Kit-compatible program clients.\n\n## Getting Started\n\n```shell\npnpm install                                   # Install dependencies\npnpm test:setup                                # Install the Agave test validator (first time only)\n./scripts/start-shared-test-validator.sh       # Start shared test validator (needed for some tests)\npnpm build                                     # Build + test all packages\n```\n\nFor single-package development:\n\n```shell\ncd packages/<name>\npnpm turbo compile:js compile:typedefs         # Compile the package and its dependencies\npnpm dev                                       # Run tests in watch mode\n```\n\n## Architecture\n\nThe packages form a layered dependency graph. `@solana/errors` is the foundational leaf package with no internal dependencies — nearly every other package depends on it. Core encoding lives in `@solana/codecs-core`, `@solana/codecs-numbers`, `@solana/codecs-strings`, and `@solana/codecs-data-structures`, unified by the `@solana/codecs` facade. `@solana/keys` and `@solana/addresses` build on these codecs and `@solana/nominal-types`. Higher-level packages like `@solana/transactions`, `@solana/rpc`, and `@solana/signers` compose these primitives. `@solana/kit` sits at the top as the consumer-facing umbrella.\n\nFour private \"impl\" packages (`@solana/crypto-impl`, `@solana/text-encoding-impl`, `@solana/ws-impl`, `@solana/event-target-impl`) provide platform-specific implementations and are **inlined at build time** by tsup — they are never published to npm.\n\n## Build System\n\n- **JS compilation**: tsup (esbuild) via configs in `packages/build-scripts/`.\n- **Type declarations**: tsc with per-package `tsconfig.declarations.json`.\n- **Build artifacts per package**: Node CJS + ESM, Browser CJS + ESM, React Native ESM. `@solana/kit` additionally produces IIFE bundles (minified production + development with sourcemaps).\n- **Platform constants** (set at build time): `__BROWSER__`, `__NODEJS__`, `__REACTNATIVE__`, `__VERSION__`. These are mutually exclusive booleans enabling platform-specific code paths to be tree-shaken.\n- **`__DEV__`**: In IIFE builds, statically `true`/`false`. In library builds, replaced with `process.env.NODE_ENV !== 'production'` by the DevFlagPlugin, deferring the decision to the consumer's bundler.\n\n## Testing\n\n- **Framework**: Jest v30 with `@swc/jest` for TypeScript transformation.\n- **Shared config**: `packages/test-config/` (`@solana/test-config`).\n- **File naming**: `*-test.ts` (runs in both environments), `*-test.node.ts` (Node only), `*-test.browser.ts` (browser/jsdom only). Tests live in `src/__tests__/`.\n- **Type tests**: `src/__typetests__/` directories contain compile-time type tests using `satisfies` and `@ts-expect-error`.\n- **Lint/prettier**: Also run through Jest runners (`jest-runner-eslint`, `jest-runner-prettier`).\n- **Commands**: `pnpm test` runs all unit tests. `pnpm lint` runs lint checks. `pnpm style:fix` auto-fixes formatting.\n- **`expect.assertions`**: Only use `expect.assertions(n)` in **async** tests (where you need to guarantee the expected number of assertions ran). Synchronous tests do not need it.\n- **Flushing async state**: When a test needs to wait for queued microtasks or promise chains to settle, prefer `jest.useFakeTimers()` + `await jest.runAllTimersAsync()` over hand-rolled `flushMicrotasks` helpers that `await Promise.resolve()` in a loop. The loop count is fragile and breaks as soon as an extra `.then` is introduced. When enabling fake timers in a scoped `beforeEach` (i.e. not at the top of the file), pair it with an `afterEach(() => { jest.useRealTimers(); })` so subsequent describes don't inherit fake timers.\n- **Placeholder mocks**: When a test mock must satisfy an interface but a particular method shouldn't be called in that test, make the stub throw/reject rather than using a bare `jest.fn()` that silently returns `undefined`. For sync methods use `jest.fn().mockImplementation(() => { throw new Error('not implemented'); })`; for async methods use `jest.fn().mockRejectedValue(new Error('not implemented'))`. An accidental call then fails the test loudly instead of producing `undefined` and a confusing downstream assertion error.\n\n## Error System\n\nAll errors use the `SolanaError` class from `@solana/errors`. Key rules:\n\n- Error codes are numeric constants in `packages/errors/src/codes.ts`, named `SOLANA_ERROR__<DOMAIN>__<DESCRIPTION>` (double-underscore separated).\n- Each domain reserves a dedicated numeric range. Never reuse, remove, or reorder error codes.\n- Human-readable messages live in `packages/errors/src/messages.ts` with `$key` context interpolation.\n- In production builds, messages are stripped. Use `npx @solana/errors decode -- <code>` to decode them.\n- To add a new error: add the constant to `codes.ts`, add it to the `SolanaErrorCode` union, optionally define context in `context.ts`, and add the message to `messages.ts`.\n\n## Coding Conventions\n\n- **TypeScript strict mode**, ESM-first.\n- **Branded/nominal types**: `@solana/nominal-types` provides `Brand<T, Name>` for types like `Address`, `Signature`, `Lamports` — these are branded primitives, not classes.\n- **Functional composition**: Use `pipe()` from `@solana/functional` to compose operations on transaction messages and other data structures.\n- **Platform-specific code**: Use `__BROWSER__`, `__NODEJS__`, `__REACTNATIVE__` guards. The build system will tree-shake unused branches.\n- **Dev-only code**: Guard with `__DEV__` (e.g. verbose error messages, debug assertions).\n- **Formatting**: ESLint via `@solana/eslint-config-solana`, Prettier via `@solana/prettier-config-solana`. Run `pnpm style:fix` to auto-fix.\n- **All publishable packages share a fixed version** (currently in lockstep).\n- **Deferred promises**: Use `Promise.withResolvers<T>()` instead of hand-rolling a `new Promise((resolve, reject) => ...)` with captured externals. Do not reintroduce a `deferred()` helper — `Promise.withResolvers` already returns `{ promise, resolve, reject }`.\n\n## Changesets & Releases\n\n- Use `npx changeset add --empty` to generate changeset files — never create them manually.\n- `patch` for fixes, `minor` for features, `major` for breaking changes (while pre-1.0, `minor` may be treated as breaking).\n- No changeset needed for docs-only changes, CI config, dev dependency updates, or test-only changes.\n- All publishable packages are version-locked via the `fixed` config in `.changeset/config.json`.\n\n## CI\n\n- **PRs**: Build + test on Node `current` and `lts/*`.\n- **Bundle size**: Monitored via BundleMon on every PR.\n- **Publishing**: On merge to `main`, changesets action creates a \"Version Packages\" PR or publishes to npm. Canary snapshots are published on every push to `main`.\n\n<!-- skills-inject:start -->\n\n## Skill Instructions\n\nThe following instructions come from installed skills (autogenerated, do not edit manually) and should always be followed.\n\n### Changesets\n\n- Any PR that should trigger a package release MUST include a changeset.\n- Identify affected packages by mapping changed files to their nearest `package.json`.\n- Choose the right bump: `patch` for fixes, `minor` for features, `major` for breaking changes.\n- While a project is pre-1.0, `minor` bumps may be treated as breaking.\n- ALWAYS use `npx changeset add --empty` to generate a new changeset file with a random name. NEVER create changeset files manually.\n- No changeset needed for: docs-only changes, CI config, dev dependency updates, test-only changes.\n\n### Shipping (Git)\n\n- NEVER commit, push, create branches, or create PRs without explicit user approval.\n- Before any git operation that creates or modifies a commit, present a review block containing: changeset entry (if applicable), commit title, and commit/PR description. ALWAYS wait for approval.\n- Use standard `git add` and `git commit` workflows. Concise title on the first line, blank line, then description body.\n- Use `gh pr create` for pull requests.\n- Write commit and PR descriptions as natural flowing prose. Do NOT insert hard line breaks mid-paragraph.\n\n### Shipping (Graphite)\n\n- Check if [Graphite](https://graphite.dev/) is installed (`which gt`). Prefer Graphite when available; fall back to the Git shipping workflow otherwise.\n- NEVER commit, push, create branches, or create PRs without explicit user approval.\n- Before any git operation that creates or modifies a commit, present a review block containing: changeset entry (if applicable), commit title, and commit/PR description. ALWAYS wait for approval.\n- Use `gt create -am \"Title\" -m \"Description body\"` for new PRs. The first `-m` sets the commit title; the second sets the PR description.\n- Use `gt modify -a` to amend the current branch with follow-up changes (NEVER create additional commits on the same branch).\n- ALWAYS escape backticks in commit messages with backslashes for shell compatibility (e.g. `\"Update \\`my-package\\` config\"`).\n- Do NOT run `gt submit` after committing. Only run it when the user explicitly asks to submit or push.\n- Write commit and PR descriptions as natural flowing prose. Do NOT insert hard line breaks mid-paragraph.\n\n### TypeScript Docblocks\n\n- All exported functions, types, interfaces, and constants MUST have JSDoc docblocks.\n- Start with `/**`, use `*` prefix for each line, end with `*/` — each on its own line.\n- Begin with a clear one-to-two line summary. Add a blank line before tags.\n- Include `@param`, `@typeParam`, `@return`, `@throws`, and at least one `@example` when helpful.\n- Use `{@link ...}` to reference related items. Add `@see` tags at the end for related APIs.\n\n### TypeScript READMEs\n\n- When adding a new public API, add or update the package's README.\n- Structure: brief intro, installation, usage (with code snippet), deep-dive sections.\n- Code snippets must be realistic, concise, and use TypeScript syntax.\n- Focus on the quickest path to success. Developers should feel excited, not overwhelmed.\n\n<!-- skills-inject:end -->\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Kit is developed in public and we encourage and appreciate contributions.\n\n## Getting Started\n\n1. Install dependencies: `pnpm install`\n2. The first time you build Kit, you will need to install the Agave test validator, which is used for some tests. `pnpm test:setup`\n3. Start a test validator before running tests. `./scripts/start-shared-test-validator.sh`\n4. Build + test all packages: `pnpm build`\n\n## Development Environment\n\nKit is developed as a monorepo using [pnpm](https://pnpm.io/) and [turborepo](https://turborepo.com/).\n\nOften your changes will only apply to a single package. You can run tests for a single package and watch for changes:\n\n```shell\ncd packages/accounts\npnpm turbo compile:js compile:typedefs\npnpm dev\n```\n\n## A Note on AI-Generated Code\n\nWe are supportive of using AI tools to _assist_ your development process (e.g., for boilerplate, optimization suggestions, or debugging).\n\nHowever, we do not accept \"vibe-coded\" or purely AI-generated contributions. You must be able to explain, test, and take full ownership of every line of code you submit.\n\nA good rule of thumb is not to use AI to write the PR description. This tends to be less clear and harder to review.\n\n**Pull requests containing code that the author clearly does not understand will be rejected.** You are the developer, not the prompt engineer. All code must be intentional and understood.\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/kit?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/kit?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/kit\n\n# Kit\n\nThis is the JavaScript SDK for building Solana apps for Node, web, and React Native.\n\n> [!NOTE]\n> Did you expect to find `@solana/web3.js` here? You're in the right place! We have renamed the 2.x line of `@solana/web3.js` to `@solana/kit`.\n>\n> The code for the 1.x line of `@solana/web3.js` can be found [here](https://github.com/solana-labs/solana-web3.js/tree/maintenance/v1.x) and the documentation [here](https://solana-foundation.github.io/solana-web3.js/).\n\n# Installation\n\nFor use in a Node.js or web application:\n\n```shell\nnpm install --save @solana/kit\n```\n\nFor use in a browser, without a build system:\n\n```html\n<!-- Development (debug mode, unminified) -->\n<script src=\"https://unpkg.com/@solana/kit/dist/index.development.js\"></script>\n\n<!-- Production (minified) -->\n<script src=\"https://unpkg.com/@solana/kit/dist/index.production.min.js\"></script>\n```\n\n# Quick Start\n\nTo get a feel for the API, run and modify the live examples in the `examples/` directory. There, you will find a series of single-purpose Node scripts that demonstrate a specific feature or use case. You will also find a React application that you can run in a browser, that demonstrates being able to create, sign, and send transactions using browser wallets.\n\nFor a fully baked intro, see: [Getting started with Solana kit](https://www.solanakit.com/docs/getting-started)\n\n# What's New in Kit\n\nKit is a response to many of the pain points you have communicated to us when developing Solana applications with web3.js.\n\n## Tree-Shakability\n\nThe object-oriented design of the web3.js (1.x) API prevents optimizing compilers from being able to ‘tree-shake’ unused code from your production builds. No matter how much of the web3.js API you use in your application, you have until now been forced to package all of it.\n\nRead more about tree-shaking here:\n\n- [Mozilla Developer Docs: Tree Shaking](https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking)\n- [WebPack Docs: Tree Shaking](https://webpack.js.org/guides/tree-shaking/)\n- [Web.Dev Blog Article: Reduce JavaScript Payloads with Tree Shaking](https://web.dev/articles/reduce-javascript-payloads-with-tree-shaking)\n\nOne example of an API that can’t be tree-shaken is the `Connection` class. It has dozens of methods, but because it’s a _class_ you have no choice but to include every method in your application’s final bundle, no matter how many you _actually_ use.\n\nNeedlessly large JavaScript bundles can cause issues with deployments to cloud compute providers like Cloudflare or AWS Lambda. They also impact webapp startup performance because of longer download and JavaScript parse times.\n\nKit is fully tree-shakable and will remain so, enforced by build-time checks. Optimizing compilers can now eliminate those parts of the library that your application does not use.\n\nKit is comprised of several smaller, modular packages under the `@solana` organization, including:\n\n- `@solana/accounts`: For fetching and decoding accounts\n- `@solana/codecs`: For composing data (de)serializers from a set of primitives or building custom ones\n- `@solana/errors`: For identifying and refining coded errors thrown in the `@solana` namespace\n- `@solana/rpc`: For sending RPC requests\n- `@solana/rpc-subscriptions`: For subscribing to RPC notifications\n- `@solana/signers`: For building message and/or transaction signer objects\n- `@solana/sysvars`: For fetching and decoding sysvar accounts\n- `@solana/transaction-messages`: For building and transforming Solana transaction message objects\n- `@solana/transactions`: For compiling and signing transactions for submission to the network\n- And many more!\n\nSome of these packages are themselves composed of smaller packages. For instance, `@solana/rpc` is composed of `@solana/rpc-spec` (for core JSON RPC specification types), `@solana/rpc-api` (for the Solana-specific RPC methods), `@solana/rpc-transport-http` (for the default HTTP transport) and so on.\n\nDevelopers can use the default configurations within the main library (`@solana/kit`) or import any of its subpackages where customization-through-composition is desired.\n\n## Composable Internals\n\nDepending on your use case and your tolerance for certain application behaviours, you may wish to configure your application to make a different set of tradeoffs than another developer. The web3.js (1.x) API imposed a rigid set of common-case defaults on _all_ developers, some of which were impossible to change.\n\nThe inability to customize web3.js up until now has been a source of frustration:\n\n- The Mango team wanted to customize the transaction confirmation strategy, but all of that functionality is hidden away behind `confirmTransaction` – a static method of `Connection`. [Here’s the code for `confirmTransaction` on GitHub](https://github.com/solana-labs/solana-web3.js/blob/69a8ad25ef09f9e6d5bff1ffa8428d9be0bd32ac/packages/library-legacy/src/connection.ts#L3734).\n- Solana developer ‘mPaella’ [wanted us to add a feature in the RPC](https://github.com/solana-labs/solana-web3.js/issues/1143#issuecomment-1435927152) that would failover to a set of backup URLs in case the primary one failed.\n- Solana developer ‘epicfaace’ wanted first-class support for automatic time-windowed batching in the RPC transport. [Here’s their pull request](https://github.com/solana-labs/solana/pull/23628).\n- Multiple folks have expressed the need for custom retry logic for failed requests or transactions. [Here’s a pull request from ‘dafyddd’](https://github.com/solana-labs/solana/pull/11811) and [another from ‘abrkn’](https://github.com/solana-labs/solana-web3.js/issues/1041) attempting to modify retry logic to suit their individual use cases.\n\nKit exposes far more of its internals, particularly where communication with an RPC is concerned, and allows willing developers the ability to compose new implementations from the default ones that manifest a nearly limitless array of customizations.\n\nThe individual modules that make up Kit are assembled in a **default** configuration reminiscent of the legacy library as part of the npm package `@solana/kit`, but those who wish to assemble them in different configurations may do so.\n\nGeneric types are offered in numerous places, allowing you to specify new functionality, to make extensions to each API via composition and supertypes, and to encourage you to create higher-level opinionated abstractions of your own.\n\nIn fact, we expect you to do so, and to open source some of those for use by others with similar needs.\n\n## Modern JavaScript; Zero-Dependency\n\nThe advance of modern JavaScript features presents an opportunity to developers of crypto applications, such as the ability to use native Ed25519 keys and to express large values as native `bigint`.\n\nThe Web Incubator Community Group has advocated for the addition of Ed25519 support to the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API), and support has already landed in _most_ modern JavaScript runtimes.\n\nEngine support for `bigint` values has also become commonplace. The older `number` primitive in JavaScript has a maximum value of 2^53 - 1, whereas Rust’s `u64` can represent values up to 2^64.\n\nKit eliminates userspace implementations of Ed25519 cryptography, large number polyfills, and more, in favour of custom implementations or the use of native JavaScript features, reducing the size of the library. It has no third-party dependencies.\n\n## Functional Architecture\n\nThe object oriented, class-based architecture of web3.js (1.x) causes unnecessary bundle bloat. Your application has no choice but to bundle _all_ of the functionality and dependencies of a class no matter how many methods you actually use at runtime.\n\nClass-based architecture also presents unique risks to developers who trigger the dual-package hazard. This describes a situation you can find yourself in if you build for both CommonJS and ES modules. It arises when two copies of the same class are present in the dependency tree, causing checks like `instanceof` to fail. This introduces aggravating and difficult to debug problems.\n\nRead more about dual-package hazard:\n\n- [NodeJS: Dual Package Hazard](https://nodejs.org/api/packages.html#dual-package-hazard)\n\nKit implements no classes (with the notable exception of the `SolanaError` class) and implements the thinnest possible interfaces at function boundaries.\n\n## Statistics\n\nConsider these statistical comparisons between Kit and the legacy web3.js 1.x.\n\n|                                                                                                        | 1.x (Legacy) | Kit        | +/- % |\n| ------------------------------------------------------------------------------------------------------ | ------------ | ---------- | ----- |\n| Total minified size of library                                                                         | 81 KB        | 57.5 KB    | -29%  |\n| Total minified size of library (when runtime supports Ed25519)                                         | 81 KB        | 53 KB      | -33%  |\n| Bundled size of a web application that executes a transfer of lamports                                 | 111 KB       | 23.9 KB    | -78%  |\n| Bundled size of a web application that executes a transfer of lamports (when runtime supports Ed25519) | 111 KB       | 18.2 KB    | -83%  |\n| Performance of key generation, signing, and verifying signatures (Brave with Experimental API flag)    | 700 ops/s    | 7000 ops/s | +900% |\n| First-load size for Solana Explorer                                                                    | 311 KB       | 228 KB     | -26%  |\n\nThe re-engineered library achieves these speedups and reductions in bundle size in large part through use of modern JavaScript APIs.\n\nTo validate our work, we replaced the legacy 1.x library with Kit on the homepage of the Solana Explorer. Total first-load bundle size dropped by 26% without removing a single feature. [Here’s an X thread](https://twitter.com/callum_codes/status/1679124485218226176) by Callum McIntyre if you would like to dig deeper.\n\n# A Tour of the Kit API\n\nHere’s an overview of how to use the new library to interact with the RPC, configure network transports, work with Ed25519 keys, and to serialize data.\n\n## RPC\n\nKit ships with an implementation of the [JSON RPC specification](https://www.jsonrpc.org/specification) and a type spec for the [Solana JSON RPC](https://solana.com/docs/rpc).\n\nThe main package responsible for managing communication with an RPC is `@solana/rpc`. However, this package makes use of more granular packages to break down the RPC logic into smaller pieces. Namely, these packages are:\n\n- `@solana/rpc`: Contains all logic related to sending Solana RPC calls.\n- `@solana/rpc-api`: Describes all Solana RPC methods using types.\n- `@solana/rpc-transport-http`: Provides a concrete implementation of an RPC transport using HTTP requests.\n- `@solana/rpc-spec`: Defines the JSON RPC spec for sending RPC requests.\n- `@solana/rpc-spec-types`: Shared JSON RPC specifications types and helpers that are used by both `@solana/rpc` and `@solana/rpc-subscriptions` (described in the next section).\n- `@solana/rpc-types`: Shared Solana RPC types and helpers that are used by both `@solana/rpc` and `@solana/rpc-subscriptions`.\n\nThe main `@solana/kit` package re-exports the `@solana/rpc` package so, going forward, we will import RPC types and functions from the library directly.\n\n### RPC Calls\n\nYou can use the `createSolanaRpc` function by providing the URL of a Solana JSON RPC server. This will create a default client for interacting with the Solana JSON RPC API.\n\n```ts\nimport { createSolanaRpc } from '@solana/kit';\n\n// Create an RPC client.\nconst rpc = createSolanaRpc('http://127.0.0.1:8899');\n//    ^? Rpc<SolanaRpcApi>\n\n// Send a request.\nconst slot = await rpc.getSlot().send();\n```\n\n### Custom RPC Transports\n\nThe `createSolanaRpc` function communicates with the RPC server using a default HTTP transport that should satisfy most use cases. You can provide your own transport or wrap an existing one to communicate with RPC servers in any way you see fit. In the example below, we explicitly create a transport and use it to create a new RPC client via the `createSolanaRpcFromTransport` function.\n\n```ts\nimport { createSolanaRpcFromTransport, createDefaultRpcTransport } from '@solana/kit';\n\n// Create an HTTP transport or any custom transport of your choice.\nconst transport = createDefaultRpcTransport({ url: 'https://api.devnet.solana.com' });\n\n// Create an RPC client using that transport.\nconst rpc = createSolanaRpcFromTransport(transport);\n//    ^? Rpc<SolanaRpcApi>\n\n// Send a request.\nconst slot = await rpc.getSlot().send();\n```\n\nA custom transport can implement specialized functionality such as coordinating multiple transports, implementing retries, and more. Let's take a look at some concrete examples.\n\n#### Round Robin\n\nA ‘round robin’ transport is one that distributes requests to a list of endpoints in sequence.\n\n```ts\nimport { createDefaultRpcTransport, createSolanaRpcFromTransport, type RpcTransport } from '@solana/kit';\n\n// Create an HTTP transport for each RPC server.\nconst transports = [\n    createDefaultRpcTransport({ url: 'https://mainnet-beta.my-server-1.com' }),\n    createDefaultRpcTransport({ url: 'https://mainnet-beta.my-server-2.com' }),\n    createDefaultRpcTransport({ url: 'https://mainnet-beta.my-server-3.com' }),\n];\n\n// Set up the round-robin transport.\nlet nextTransport = 0;\nasync function roundRobinTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> {\n    const transport = transports[nextTransport];\n    nextTransport = (nextTransport + 1) % transports.length;\n    return await transport(...args);\n}\n\n// Create an RPC client using the round-robin transport.\nconst rpc = createSolanaRpcFromTransport(roundRobinTransport);\n```\n\n#### Sharding\n\nA sharding transport is a kind of distributing transport that sends requests to a particular server based on something about the request itself. Here’s an example that sends requests to different servers depending on the name of the method:\n\n```ts\nimport { createDefaultRpcTransport, createSolanaRpcFromTransport, type RpcTransport } from '@solana/kit';\n\n// Create multiple transports.\nconst transportA = createDefaultRpcTransport({ url: 'https://mainnet-beta.my-server-1.com' });\nconst transportB = createDefaultRpcTransport({ url: 'https://mainnet-beta.my-server-2.com' });\nconst transportC = createDefaultRpcTransport({ url: 'https://mainnet-beta.my-server-3.com' });\nconst transportD = createDefaultRpcTransport({ url: 'https://mainnet-beta.my-server-4.com' });\n\n// Function to determine which shard to use based on the request method.\nfunction selectShard(method: string): RpcTransport {\n    switch (method) {\n        case 'getAccountInfo':\n        case 'getBalance':\n            return transportA;\n        case 'getLatestBlockhash':\n        case 'getTransaction':\n            return transportB;\n        case 'sendTransaction':\n            return transportC;\n        default:\n            return transportD;\n    }\n}\n\n// Create a transport that selects the correct transport given the request method name.\nasync function shardingTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> {\n    const payload = args[0].payload as { method: string };\n    const selectedTransport = selectShard(payload.method);\n    return (await selectedTransport(...args)) as TResponse;\n}\n\n// Create an RPC client using the sharding transport.\nconst rpc = createSolanaRpcFromTransport(shardingTransport);\n```\n\n#### Retry\n\nA custom transport is a good place to implement global retry logic for every request:\n\n```ts\nimport { createDefaultRpcTransport, createSolanaRpcFromTransport, type RpcTransport } from '@solana/kit';\n\n// Set the maximum number of attempts to retry a request.\nconst MAX_ATTEMPTS = 4;\n\n// Create the default transport.\nconst defaultTransport = createDefaultRpcTransport({ url: 'https://mainnet-beta.my-server-1.com' });\n\n// Sleep function to wait for a given number of milliseconds.\nfunction sleep(ms: number): Promise<void> {\n    return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// Calculate the delay for a given attempt.\nfunction calculateRetryDelay(attempt: number): number {\n    // Exponential backoff with a maximum of 1.5 seconds.\n    return Math.min(100 * Math.pow(2, attempt), 1500);\n}\n\n// A retrying transport that will retry up to MAX_ATTEMPTS times before failing.\nasync function retryingTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> {\n    let requestError;\n    for (let attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {\n        try {\n            return await defaultTransport(...args);\n        } catch (err) {\n            requestError = err;\n            // Only sleep if we have more attempts remaining.\n            if (attempts < MAX_ATTEMPTS - 1) {\n                const retryDelay = calculateRetryDelay(attempts);\n                await sleep(retryDelay);\n            }\n        }\n    }\n    throw requestError;\n}\n\n// Create the RPC client using the retrying transport.\nconst rpc = createSolanaRpcFromTransport(retryingTransport);\n```\n\n#### Failover\n\nSupport for handling network failures can be implemented in the transport itself. Here’s an example of some failover logic integrated into a transport:\n\n```ts\nimport { createDefaultRpcTransport, createSolanaRpcFromTransport, type RpcTransport } from '@solana/kit';\n\n// List of RPC endpoints for failover.\nconst rpcEndpoints = [\n    'https://mainnet-beta.my-server-1.com',\n    'https://mainnet-beta.my-server-2.com',\n    'https://mainnet-beta.my-server-3.com',\n    'https://mainnet-beta.my-server-3.com',\n];\n\n// Create an array of transports from the endpoints.\nconst transports = rpcEndpoints.map(url => createDefaultRpcTransport({ url }));\n\n// A failover transport that switches to the next transport on failure.\nasync function failoverTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> {\n    let lastError;\n    for (const transport of transports) {\n        try {\n            return await transport(...args);\n        } catch (err) {\n            lastError = err;\n            console.warn(`Transport failed: ${err}. Trying next transport...`);\n        }\n    }\n    // If all transports fail, throw the last error.\n    throw lastError;\n}\n\n// Create the RPC client using the failover transport.\nconst rpc = createSolanaRpcFromTransport(failoverTransport);\n```\n\n### Augmenting/Constraining the RPC API\n\nUsing the `createSolanaRpc` or `createSolanaRpcFromTransport` methods, we always get the same API that includes the Solana RPC API methods. Since the RPC API is described using types only, it is possible to augment those types to add your own methods.\n\nWhen constraining the API scope, keep in mind that types don’t affect bundle size. You may still like to constrain the type-spec for a variety of reasons, including reducing TypeScript noise.\n\n#### Constraining by Cluster\n\nIf you're using a specific cluster, you may wrap your RPC URL inside a helper function like `mainnet` or `devnet` to inject that information into the RPC type system.\n\n```ts\nimport { createSolanaRpc, mainnet, devnet } from '@solana/kit';\n\nconst mainnetRpc = createSolanaRpc(mainnet('https://api.mainnet-beta.solana.com'));\n//    ^? RpcMainnet<SolanaRpcApiMainnet>\n\nconst devnetRpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n//    ^? RpcDevnet<SolanaRpcApiDevnet>\n```\n\nIn the example above, `devnetRpc.requestAirdrop(..)` will work, but `mainnetRpc.requestAirdrop(..)` will raise a TypeScript error since `requestAirdrop` is not a valid method of the mainnet cluster.\n\n#### Cherry-Picking API Methods\n\nYou can constrain the API’s type-spec even further so you are left only with the methods you need. The simplest way to do this is to cast the created RPC client to a type that only includes the required methods.\n\n```ts\nimport { createSolanaRpc, type Rpc, type GetAccountInfoApi, type GetMultipleAccountsApi } from '@solana/kit';\n\nconst rpc = createSolanaRpc('http://127.0.0.1:8899') as Rpc<GetAccountInfoApi & GetMultipleAccountsApi>;\n```\n\nAlternatively, you can explicitly create the RPC API using the `createSolanaRpcApi` function. You will need to create your own transport and bind the two together using the `createRpc` function.\n\n```ts\nimport {\n    createDefaultRpcTransport,\n    createRpc,\n    createSolanaRpcApi,\n    DEFAULT_RPC_CONFIG,\n    type GetAccountInfoApi,\n    type GetMultipleAccountsApi,\n} from '@solana/kit';\n\nconst api = createSolanaRpcApi<GetAccountInfoApi & GetMultipleAccountsApi>(DEFAULT_RPC_CONFIG);\nconst transport = createDefaultRpcTransport({ url: 'http://127.0.0.1:8899' });\n\nconst rpc = createRpc({ api, transport });\n```\n\nNote that the `createSolanaRpcApi` function is a wrapper on top of the `createJsonRpcApi` function which adds some Solana-specific transformers such as setting a default commitment on all methods or throwing an error when an integer overflow is detected.\n\n#### Creating Your Own API Methods\n\nThe new library’s RPC specification supports an _infinite_ number of JSON-RPC methods with **zero increase** in bundle size.\n\nThis means the library can support future additions to the official [Solana JSON RPC](https://docs.solana.com/api), or [custom RPC methods](https://docs.helius.dev/compression-and-das-api/digital-asset-standard-das-api/get-asset) defined by some RPC provider.\n\nHere’s an example of how a developer at might build a custom RPC type-spec for an RPC provider's implementation of the Metaplex Digital Asset Standard's `getAsset` method:\n\n```ts\n// Define the method's response payload.\ntype GetAssetApiResponse = Readonly<{\n    interface: DasApiAssetInterface;\n    id: Address;\n    content: Readonly<{\n        files?: readonly {\n            mime?: string;\n            uri?: string;\n            [key: string]: unknown;\n        }[];\n        json_uri: string;\n        links?: readonly {\n            [key: string]: unknown;\n        }[];\n        metadata: DasApiMetadata;\n    }>;\n    /* ...etc... */\n}>;\n\n// Set up a type spec for the request method.\ntype GetAssetApi = {\n    // Define the method's name, parameters and response type\n    getAsset(args: { id: Address }): GetAssetApiResponse;\n};\n\n// Export the type spec for downstream users.\nexport type MetaplexDASApi = GetAssetApi;\n```\n\nHere’s how a developer might use it:\n\n```ts\nimport { createDefaultRpcTransport, createRpc, createJsonRpcApi } from '@solana/kit';\n\n// Create the custom API.\nconst api = createJsonRpcApi<MetaplexDASApi>();\n\n// Set up an HTTP transport to a server that supports the custom API.\nconst transport = createDefaultRpcTransport({\n    url: 'https://mainnet.helius-rpc.com/?api-key=<api_key>',\n});\n\n// Create the RPC client.\nconst metaplexDASRpc = createRpc({ api, transport });\n//    ^? Rpc<MetaplexDASApi>\n```\n\nAs long as a particular JSON RPC method adheres to the [official JSON RPC specification](https://www.jsonrpc.org/specification), it will be supported by Kit.\n\n### Aborting RPC Requests\n\nRPC requests are now abortable with modern `AbortControllers`. When calling an RPC method such as `getSlot`, it will return a `PendingRpcRequest` proxy object that contains a `send` method to send the request to the server.\n\n```ts\nconst pendingRequest: PendingRpcRequest<Slot> = rpc.getSlot();\n\nconst slot: Slot = await pendingRequest.send();\n```\n\nThe arguments of the `getSlot` method are reserved for the request payload, but the `send` method is where additional arguments such as an `AbortSignal` can be accepted in the context of the request.\n\nAborting RPC requests can be useful for a variety of things such as setting a timeout on a request or cancelling a request when a user navigates away from a page.\n\n```ts\nimport { createSolanaRpc } from '@solana/kit';\n\nconst rpc = createSolanaRpc('http://127.0.0.1:8900');\n\n// Create a new AbortController.\nconst abortController = new AbortController();\n\n// Abort the request when the user navigates away from the current page.\nfunction onUserNavigateAway() {\n    abortController.abort();\n}\n\n// The request will be aborted if and only if the user navigates away from the page.\nconst slot = await rpc.getSlot().send({ abortSignal: abortController.signal });\n```\n\nRead more about `AbortController` here:\n\n- [Mozilla Developer Docs: `AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)\n- [Mozilla Developer Docs: `AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)\n- [JavaScript.info: Fetch: Abort](https://javascript.info/fetch-abort)\n\n## RPC Subscriptions\n\nSubscriptions in the legacy library do not allow custom retry logic and do not allow you to recover from potentially missed messages. The new version does away with silent retries, surfaces transport errors to your application, and gives you the opportunity to recover from gap events.\n\nThe main package responsible for managing communication with RPC subscriptions is `@solana/rpc-subscriptions`. However, similarly to `@solana/rpc`, this package also makes use of more granular packages. These packages are:\n\n- `@solana/rpc-subscriptions`: Contains all logic related to subscribing to Solana RPC notifications.\n- `@solana/rpc-subscriptions-api`: Describes all Solana RPC subscriptions using types.\n- `@solana/rpc-subscriptions-channel-websocket`: Provides a concrete implementation of an RPC Subscriptions channel using WebSockets.\n- `@solana/rpc-subscriptions-spec`: Defines the JSON RPC spec for subscribing to RPC notifications.\n- `@solana/rpc-spec-types`: Shared JSON RPC specifications types and helpers that are used by both `@solana/rpc` and `@solana/rpc-subscriptions`.\n- `@solana/rpc-types`: Shared Solana RPC types and helpers that are used by both `@solana/rpc` and `@solana/rpc-subscriptions`.\n\nSince the main `@solana/kit` library also re-exports the `@solana/rpc-subscriptions` package we will import RPC Subscriptions types and functions directly from the main library going forward.\n\n### Getting Started with RPC Subscriptions\n\nTo get started with RPC Subscriptions, you may use the `createSolanaRpcSubscriptions` function by providing the WebSocket URL of a Solana JSON RPC server. This will create a default client for interacting with Solana RPC Subscriptions.\n\n```ts\nimport { createSolanaRpcSubscriptions } from '@solana/kit';\n\n// Create an RPC Subscriptions client.\nconst rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');\n//    ^? RpcSubscriptions<SolanaRpcSubscriptionsApi>\n```\n\n### Subscriptions as `AsyncIterators`\n\nThe new subscriptions API vends subscription notifications as an `AsyncIterator`. The `AsyncIterator` conforms to the [async iterator protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_async_iterator_and_async_iterable_protocols), which allows developers to consume messages using a `for await...of` loop.\n\nHere’s an example of working with a subscription in the new library:\n\n```ts\nimport { address, createSolanaRpcSubscriptions, createDefaultRpcSubscriptionsTransport } from '@solana/kit';\n\n// Create the RPC Subscriptions client.\nconst rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');\n\n// Set up an abort controller.\nconst abortController = new AbortController();\n\n// Subscribe to account notifications.\nconst accountNotifications = await rpcSubscriptions\n    .accountNotifications(address('AxZfZWeqztBCL37Mkjkd4b8Hf6J13WCcfozrBY6vZzv3'), { commitment: 'confirmed' })\n    .subscribe({ abortSignal: abortController.signal });\n\ntry {\n    // Consume messages.\n    for await (const notification of accountNotifications) {\n        console.log('New balance', notification.value.lamports);\n    }\n} catch (e) {\n    // The subscription went down.\n    // Retry it and then recover from potentially having missed\n    // a balance update, here (eg. by making a `getBalance()` call).\n}\n```\n\nYou can read more about `AsyncIterator` at the following links:\n\n- [Mozilla Developer Docs: `AsyncIterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncIterator)\n- [Luciano Mammino (Blog): JavaScript Async Iterators](https://www.nodejsdesignpatterns.com/blog/javascript-async-iterators/)\n\n### Aborting RPC Subscriptions\n\nSimilarly to RPC calls, applications can terminate active subscriptions using an `AbortController` attribute on the `subscribe` method. In fact, this parameter is _required_ for subscriptions to encourage you to clean up subscriptions that your application no longer needs.\n\nLet's take a look at some concrete examples that demonstrate how to abort subscriptions.\n\n#### Subscription Timeout\n\nHere's an example of an `AbortController` used to abort a subscription after a 5-second timeout:\n\n```ts\nimport { createSolanaRpcSubscriptions } from '@solana/kit';\n\nconst rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');\n\n// Subscribe for slot notifications using an AbortSignal that times out after 5 seconds.\nconst slotNotifications = await rpcSubscriptions\n    .slotNotifications()\n    .subscribe({ abortSignal: AbortSignal.timeout(5000) });\n\n// Log slot notifications.\nfor await (const notification of slotNotifications) {\n    console.log('Slot notification', notification);\n}\n\nconsole.log('Done.');\n```\n\nRead more about `AbortController` at the following links:\n\n- [Mozilla Developer Docs: `AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)\n- [Mozilla Developer Docs: `AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal)\n- [JavaScript.info: Fetch: Abort](https://javascript.info/fetch-abort)\n\n#### Cancelling Subscriptions\n\nIt is also possible to abort a subscription inside the `for await...of` loop. This enables us to cancel a subscription based on some condition, such as a change in the state of an account. For instance, the following example cancels a subscription when the owner of an account changes:\n\n```ts\n// Subscribe to account notifications.\nconst accountNotifications = await rpc\n    .accountNotifications(address('AxZfZWeqztBCL37Mkjkd4b8Hf6J13WCcfozrBY6vZzv3'), { commitment: 'confirmed' })\n    .subscribe({ abortSignal });\n\n// Consume messages.\nlet previousOwner = null;\nfor await (const notification of accountNotifications) {\n    const {\n        value: { owner },\n    } = notification;\n    // Check the owner to see if it has changed\n    if (previousOwner && owner !== previousOwner) {\n        // If so, abort the subscription\n        abortController.abort();\n    } else {\n        console.log(notification);\n    }\n    previousOwner = owner;\n}\n```\n\n### Failed vs. Aborted Subscriptions\n\nIt is important to note that a subscription failure behaves differently from a subscription abort. A subscription failure occurs when the subscription goes down and will throw an error that can be intercepted in a `try/catch`. However, an aborted subscription will not throw an error, but will instead exit the `for await...of` loop.\n\n```ts\ntry {\n    for await (const notification of notifications) {\n        // Consume messages.\n    }\n    // [ABORTED] Reaching this line means the subscription was aborted — i.e. unsubscribed.\n} catch (e) {\n    // [FAILED] Reaching this line means the subscription went down.\n    // Retry it, then recover from potential missed messages.\n} finally {\n    // [ABORTED or FAILED] Whether the subscription failed or was aborted, you can run cleanup code here.\n}\n```\n\n### Message Gap Recovery\n\nOne of the most crucial aspects of any subscription API is managing potential missed messages. Missing messages, such as account state updates, could be catastrophic for an application. That’s why the new library provides native support for recovering missed messages using the `AsyncIterator`.\n\nWhen a connection fails unexpectedly, any messages you miss while disconnected can result in your UI falling behind or becoming corrupt. Because subscription failure is now made explicit in the new API, you can implement ‘catch-up’ logic after re-establishing the subscription.\n\nHere’s an example of such logic:\n\n```ts\ntry {\n    for await (const notif of accountNotifications) {\n        updateAccountBalance(notif.lamports);\n    }\n} catch (e) {\n    // The subscription failed.\n    // First, re-establish the subscription.\n    await setupAccountBalanceSubscription(address);\n    // Then make a one-shot request to 'catch up' on any missed balance changes.\n    const { value: lamports } = await rpc.getBalance(address).send();\n    updateAccountBalance(lamports);\n}\n```\n\n### Using Custom RPC Subscriptions Transports\n\nThe `createSolanaRpcSubscriptions` function communicates with the RPC server using a default `WebSocket` channel that should satisfy most use cases. However, you may here as well provide your own channel creator or decorate existing ones to communicate with RPC servers in any way you see fit. In the example below, we supply a custom `WebSocket` channel creator and use it to create a new RPC Subscriptions client via the `createSolanaRpcSubscriptionsFromTransport` function.\n\n```ts\nimport { createDefaultRpcSubscriptionsTransport, createSolanaRpcSubscriptionsFromTransport } from '@solana/kit';\n\n// Create a transport with a custom channel creator of your choice.\nconst transport = createDefaultRpcSubscriptionsTransport({\n    createChannel({ abortSignal }) {\n        return createWebSocketChannel({\n            maxSubscriptionsPerChannel: 100,\n            minChannels: 25,\n            sendBufferHighWatermark: 32_768,\n            signal: abortSignal,\n            url: 'ws://127.0.0.1:8900',\n        });\n    },\n});\n\n// Create an RPC client using that transport.\nconst rpcSubscriptions = createSolanaRpcSubscriptionsFromTransport(transport);\n//    ^? RpcSubscriptions<SolanaRpcSubscriptionsApi>\n```\n\n### Augmenting/Constraining the RPC Subscriptions API\n\nUsing the `createSolanaRpcSubscriptions` or `createSolanaRpcSubscriptionsFromTransport` functions, we always get the same RPC Subscriptions API, including all Solana RPC stable subscriptions. However, since the RPC Subscriptions API is described using types only, it is possible to constrain the API to a specific set of subscriptions or even add your own custom subscriptions.\n\n#### Constraining by Cluster\n\nIf you're using a specific cluster, you may wrap your RPC URL inside a helper function like `mainnet` or `devnet` to inject that information into the RPC type system.\n\n```ts\nimport { createSolanaRpcSubscriptions, mainnet, devnet } from '@solana/kit';\n\nconst mainnetRpc = createSolanaRpcSubscriptions(mainnet('https://api.mainnet-beta.solana.com'));\n//    ^? RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>\n\nconst devnetRpc = createSolanaRpcSubscriptions(devnet('https://api.devnet.solana.com'));\n//    ^? RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>\n```\n\n#### Including Unstable Subscriptions\n\nIf your app needs access to [unstable RPC Subscriptions](https://solana.com/docs/rpc/websocket/blocksubscribe) — e.g. `BlockNotificationsApi` or `SlotsUpdatesNotificationsApi` — and your RPC server supports them, you may use the `createSolanaRpcSubscriptions_UNSTABLE` and `createSolanaRpcSubscriptionsFromTransport_UNSTABLE` functions to create an RPC Subscriptions client that includes those subscriptions.\n\n```ts\nimport {\n    createDefaultSolanaRpcSubscriptionsChannelCreator,\n    createDefaultRpcSubscriptionsTransport,\n    createSolanaRpcSubscriptions_UNSTABLE,\n    createSolanaRpcSubscriptionsFromTransport_UNSTABLE,\n} from '@solana/kit';\n\n// Using the default WebSocket channel.\nconst rpcSubscriptions = createSolanaRpcSubscriptions_UNSTABLE('ws://127.0.0.1:8900');\n//    ^? RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>\n\n// Using a custom transport.\nconst transport = createDefaultRpcSubscriptionsTransport({\n    createChannel: createDefaultSolanaRpcSubscriptionsChannelCreator({\n        url: 'ws://127.0.0.1:8900',\n    }),\n});\nconst rpcSubscriptions = createSolanaRpcSubscriptionsFromTransport_UNSTABLE(transport);\n//    ^? RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>\n```\n\n#### Cherry-Picking API Methods\n\nYou may constrain the scope of the Subscription API even further so you are left only with the subscriptions you need. The simplest way to do this is to cast the created RPC client to a type that only includes the methods you need.\n\n```ts\nimport {\n    createSolanaRpcSubscriptions,\n    type RpcSubscriptions,\n    type AccountNotificationsApi,\n    type SlotNotificationsApi,\n} from '@solana/kit';\n\nconst rpc = createSolanaRpcSubscriptions('ws://127.0.0.1:8900') as RpcSubscriptions<\n    AccountNotificationsApi & SlotNotificationsApi\n>;\n```\n\nAlternatively, you may explicitly create the RPC Subscriptions API using the `createSolanaRpcSubscriptionsApi` function. You will then need to create your own transport explicitly and bind the two together using the `createSubscriptionRpc` function.\n\n```ts\nimport {\n    createDefaultSolanaRpcSubscriptionsChannelCreator,\n    createDefaultRpcSubscriptionsTransport,\n    createSubscriptionRpc,\n    createSolanaRpcSubscriptionsApi,\n    DEFAULT_RPC_CONFIG,\n    type AccountNotificationsApi,\n    type SlotNotificationsApi,\n} from '@solana/kit';\n\nconst api = createSolanaRpcSubscriptionsApi<AccountNotificationsApi & SlotNotificationsApi>(DEFAULT_RPC_CONFIG);\nconst transport = createDefaultRpcSubscriptionsTransport({\n    createChannel: createDefaultSolanaRpcSubscriptionsChannelCreator({\n        url: 'ws://127.0.0.1:8900',\n    }),\n});\nconst rpcSubscriptions = createSubscriptionRpc({ api, transport });\n```\n\nNote that the `createSolanaRpcSubscriptionsApi` function is a wrapper on top of the `createRpcSubscriptionsApi` function which adds some Solana-specific transformers such as setting a default commitment on all methods or throwing an error when an integer overflow is detected.\n\n## Keys\n\nThe new library takes a brand-new approach to Solana key pairs and addresses, which will feel quite different from the classes `PublicKey` and `Keypair` from version 1.x.\n\n### Web Crypto API\n\nAll key operations now use the native Ed25519 implementation in JavaScript’s Web Crypto API.\n\nThe API itself is designed to be a more reliably secure way to manage highly sensitive secret key information, but **developers should still use extreme caution when dealing with secret key bytes in their applications**.\n\nOne thing to note is that many operations from Web Crypto – such as importing, generating, signing, and verifying are now **asynchronous**.\n\nHere’s an example of generating a `CryptoKeyPair` using the Web Crypto API and signing a message:\n\n```ts\nimport { generateKeyPair, signBytes, verifySignature } from '@solana/kit';\n\nconst keyPair: CryptoKeyPair = await generateKeyPair();\n\nconst message = new Uint8Array(8).fill(0);\n\nconst signedMessage = await signBytes(keyPair.privateKey, message);\n//    ^? Signature\n\nconst verified = await verifySignature(keyPair.publicKey, signedMessage, message);\n```\n\n### Web Crypto Polyfill\n\nWherever Ed25519 is not supported, we offer a polyfill for Web Crypto’s Ed25519 API.\n\nThis polyfill can be found at `@solana/webcrypto-ed25519-polyfill` and mimics the functionality of the Web Crypto API for Ed25519 key pairs using the same userspace implementation we used in web3.js 1.x. It does not polyfill other algorithms.\n\nDetermine if your target runtime supports Ed25519, and install the polyfill if it does not:\n\n```ts\nimport { install } from '@solana/webcrypto-ed25519-polyfill';\nimport { generateKeyPair, signBytes, verifySignature } from '@solana/kit';\n\ninstall();\nconst keyPair: CryptoKeyPair = await generateKeyPair();\n\n/* Remaining logic */\n```\n\nYou can see where Ed25519 is currently supported in [this GitHub issue](https://github.com/WICG/webcrypto-secure-curves/issues/20) on the Web Crypto repository. Consider sniffing the user-agent when deciding whether or not to deliver the polyfill to browsers.\n\nOperations on `CryptoKey` objects using the Web Crypto API _or_ the polyfill are mostly handled by the `@solana/keys` package.\n\n### String Addresses\n\nAll addresses are now JavaScript strings. They are represented by the opaque type `Address`, which describes exactly what a Solana address actually is.\n\nConsequently, that means no more `PublicKey`.\n\nHere’s what they look like in development:\n\n```ts\nimport { Address, address, getAddressFromPublicKey, generateKeyPair } from '@solana/kit';\n\n// Coerce a string to an `Address`\nconst myOtherAddress = address('AxZfZWeqztBCL37Mkjkd4b8Hf6J13WCcfozrBY6vZzv3');\n\n// Typecast it instead\nconst myAddress =\n    'AxZfZWeqztBCL37Mkjkd4b8Hf6J13WCcfozrBY6vZzv3' as Address<'AxZfZWeqztBCL37Mkjkd4b8Hf6J13WCcfozrBY6vZzv3'>;\n\n// From CryptoKey\nconst keyPair = await generateKeyPair();\nconst myPublicKeyAsAddress = await getAddressFromPublicKey(keyPair.publicKey);\n```\n\nSome tooling for working with base58-encoded addresses can be found in the `@solana/addresses` package.\n\n## Transactions\n\n### Creating Transaction Messages\n\nLike many other familiar aspects of the 1.0 library, transactions have received a makeover.\n\nFor starters, all transaction messages are now version-aware, so there’s no longer a need to juggle two different types (eg. `Transaction` vs. `VersionedTransaction`).\n\nAddress lookups are now completely described inside transaction message instructions, so you don’t have to materialize `addressTableLookups` anymore.\n\nHere’s a simple example of creating a transaction message &ndash; notice how its type is refined at each step of the process:\n\n```ts\nimport {\n    address,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n    Blockhash,\n} from '@solana/kit';\n\nconst recentBlockhash = {\n    blockhash: '4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY' as Blockhash,\n    lastValidBlockHeight: 196055492n,\n};\nconst feePayer = address('AxZfZWeqztBCL37Mkjkd4b8Hf6J13WCcfozrBY6vZzv3');\n\n// Create a new transaction message\nconst transactionMessage = createTransactionMessage({ version: 0 });\n//    ^? V0TransactionMessage\n\n// Set the fee payer\nconst transactionMessageWithFeePayer = setTransactionMessageFeePayer(feePayer, transactionMessage);\n//    ^? V0TransactionMessage & TransactionMessageWithFeePayer\n\nconst transactionMessageWithFeePayerAndLifetime = setTransactionMessageLifetimeUsingBlockhash(\n    // ^? V0TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithBlockhashLifetime\n    recentBlockhash,\n    transactionMessageWithFeePayer,\n);\n```\n\nAs you can see, each time a transaction message is modified, the type reflects its new shape. If you add a fee payer, you’ll get a type representing a transaction message with a fee payer, and so on.\n\nTransaction message objects are also **frozen by these functions** to prevent them from being mutated in place.\n\n### Signing Transaction Messages\n\nThe `signTransaction(..)` function will raise a type error if your transaction message is not already equipped with a fee payer and a lifetime. This helps you catch errors at author-time instead of runtime.\n\n```ts\nconst feePayer = await generateKeyPair();\nconst feePayerAddress = await getAddressFromPublicKey(feePayer.publicKey);\n\nconst transactionMessage = createTransactionMessage({ version: 'legacy' });\nconst transactionMessageWithFeePayer = setTransactionMessageFeePayer(feePayerAddress, transactionMessage);\n\n// Attempting to sign the transaction message without a lifetime will throw a type error\nconst signedTransaction = await signTransaction([signer], transactionMessageWithFeePayer);\n// => \"Property 'lifetimeConstraint' is missing in type\"\n```\n\n### Calibrating a Transaction Message's Compute Unit Budget\n\nCorrectly budgeting a compute unit limit for your transaction message can increase the probability that your transaction will be accepted for processing. If you don't declare a compute unit limit on your transaction, validators will assume an upper limit of 200K compute units (CU) per instruction.\n\nSince validators have an incentive to pack as many transactions into each block as possible, they may choose to include transactions that they know will fit into the remaining compute budget for the current block over transactions that might not. For this reason, you should set a compute unit limit on each of your transaction messages, whenever possible.\n\nUse these utilities to estimate the actual compute unit cost of a given transaction message and set it on the message.\n\n```ts\nimport { createSolanaRpc, estimateComputeUnitLimitFactory, setTransactionMessageComputeUnitLimit } from '@solana/kit';\n\n// Create an estimator function.\nconst rpc = createSolanaRpc('http://127.0.0.1:8899');\nconst estimateComputeUnitLimit = estimateComputeUnitLimitFactory({ rpc });\n\n// Create your transaction message.\nconst transactionMessage = pipe(\n    createTransactionMessage({ version: 'legacy' }),\n    /* ... */\n);\n\n// Request an estimate of the actual compute units this message will consume.\nconst computeUnitsEstimate = await estimateComputeUnitLimit(transactionMessage);\n\n// Set the transaction message's compute unit budget.\nconst transactionMessageWithComputeUnitLimit = setTransactionMessageComputeUnitLimit(\n    computeUnitsEstimate,\n    transactionMessage,\n);\n```\n\n> [!NOTE]\n> For legacy and v0 transactions, if the transaction message does not already have a `SetComputeUnitLimit` instruction, the estimator will add one before simulation. This ensures that the compute unit consumption of the instruction itself is included in the estimate.\n\nAlternatively, use `estimateAndSetComputeUnitLimitFactory` to estimate and set the compute unit limit in a single step. Pair it with `fillTransactionMessageProvisoryComputeUnitLimit` during transaction construction to reserve space for the limit that will later be estimated.\n\n```ts\nimport {\n    estimateAndSetComputeUnitLimitFactory,\n    estimateComputeUnitLimitFactory,\n    fillTransactionMessageProvisoryComputeUnitLimit,\n} from '@solana/kit';\n\n// During construction, reserve space for the compute unit limit.\nconst messageWithProvisoryLimit = fillTransactionMessageProvisoryComputeUnitLimit(transactionMessage);\n\n// Later, estimate and replace the provisory limit.\nconst estimator = estimateComputeUnitLimitFactory({ rpc });\nconst estimateAndSet = estimateAndSetComputeUnitLimitFactory(estimator);\nconst updatedMessage = await estimateAndSet(messageWithProvisoryLimit);\n```\n\n> [!WARNING]\n> The compute unit estimate is just that &ndash; an estimate. The compute unit consumption of the actual transaction might be higher or lower than what was observed in simulation. Unless you are confident that your particular transaction message will consume the same or fewer compute units as was estimated, you might like to augment the estimate by either a fixed number of CUs or a multiplier.\n\n> [!NOTE]\n> If you are preparing an _unsigned_ transaction, destined to be signed and submitted to the network by a wallet, you might like to leave it up to the wallet to determine the compute unit limit. Consider that the wallet might have a more global view of how many compute units certain types of transactions consume, and might be able to make better estimates of an appropriate compute unit budget.\n\n### Helpers For Building Transaction Messages\n\nBuilding transaction messages in this manner might feel different from what you’re used to. Also, we certainly wouldn’t want you to have to bind transformed transaction messages to a new variable at each step, so we have released a functional programming library dubbed `@solana/functional` that lets you build transaction messages in **pipelines**. Here’s how it can be used:\n\n```ts\nimport { pipe } from '@solana/functional';\nimport {\n    address,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n    Blockhash,\n} from '@solana/kit';\n\n// Use `pipe(..)` to create a pipeline of transaction message transformation operations\nconst transactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    tx => setTransactionMessageFeePayer(feePayer, tx),\n    tx => setTransactionMessageLifetimeUsingBlockhash(recentBlockhash, tx),\n);\n```\n\nNote that `pipe(..)` is general-purpose, so it can be used to pipeline any functional transforms.\n\n## Codecs\n\nWe have taken steps to make it easier to write data (de)serializers, especially as they pertain to Rust datatypes and byte buffers.\n\nSolana’s codecs libraries are broken up into modular components so you only need to import the ones you need. They are:\n\n- `@solana/codecs-core`: The core codecs library for working with codecs serializers and creating custom ones\n- `@solana/codecs-numbers`: Used for serialization of numbers (little-endian and big-endian bytes, etc.)\n- `@solana/codecs-strings`: Used for serialization of strings\n- `@solana/codecs-data-structures`: Codecs and serializers for structs\n- `@solana/options`: Designed to build codecs and serializers for types that mimic Rust’s enums, which can include embedded data within their variants such as values, tuples, and structs\n\nThese packages are included in the main `@solana/kit` library but you may also import them from `@solana/codecs` if you only need the codecs.\n\nHere’s an example of encoding and decoding a custom struct with some strings and numbers:\n\n```ts\nimport { addCodecSizePrefix } from '@solana/codecs-core';\nimport { getStructCodec } from '@solana/codecs-data-structures';\nimport { getU32Codec, getU64Codec, getU8Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\n\n// Equivalent in Rust:\n// struct {\n//     amount: u64,\n//     decimals: u8,\n//     name: String,\n// }\nconst structCodec = getStructCodec([\n    ['amount', getU64Codec()],\n    ['decimals', getU8Codec()],\n    ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n]);\n\nconst myToken = {\n    amount: 1000000000000000n, // `bigint` or `number` is supported\n    decimals: 2,\n    name: 'My Token',\n};\n\nconst myEncodedToken: Uint8Array = structCodec.encode(myToken);\nconst myDecodedToken = structCodec.decode(myEncodedToken);\n\nmyDecodedToken satisfies {\n    amount: bigint;\n    decimals: number;\n    name: string;\n};\n```\n\nYou may only need to encode or decode data, but not both. Importing one or the other allows your optimizing compiler to tree-shake the other implementation away:\n\n```ts\nimport { Codec, combineCodec, Decoder, Encoder, addDecoderSizePrefix, addEncoderSizePrefix } from '@solana/codecs-core';\nimport { getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport {\n    getU8Decoder,\n    getU8Encoder,\n    getU32Decoder,\n    getU32Encoder,\n    getU64Decoder,\n    getU64Encoder,\n} from '@solana/codecs-numbers';\nimport { getUtf8Decoder, getUtf8Encoder } from '@solana/codecs-strings';\n\nexport type MyToken = {\n    amount: bigint;\n    decimals: number;\n    name: string;\n};\n\nexport type MyTokenArgs = {\n    amount: number | bigint;\n    decimals: number;\n    name: string;\n};\n\nexport const getMyTokenEncoder = (): Encoder<MyTokenArgs> =>\n    getStructEncoder([\n        ['amount', getU64Encoder()],\n        ['decimals', getU8Encoder()],\n        ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n    ]);\n\nexport const getMyTokenDecoder = (): Decoder<MyToken> =>\n    getStructDecoder([\n        ['amount', getU64Decoder()],\n        ['decimals', getU8Decoder()],\n        ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n    ]);\n\nexport const getMyTokenCodec = (): Codec<MyTokenArgs, MyToken> =>\n    combineCodec(getMyTokenEncoder(), getMyTokenDecoder());\n```\n\nYou can read more about codecs in [the official Codec documentation](https://github.com/anza-xyz/kit/blob/main/packages/codecs/README.md).\n\n## Type-Safety\n\nThe new library makes use of some advanced TypeScript features, including generic types, conditional types, `Parameters<..>`, `ReturnType<..>` and more.\n\nWe’ve described the RPC API in detail so that TypeScript can determine the _exact_ type of the result you will receive from the server given a particular input. Change the type of the input, and you will see the return type reflect that change.\n\n### RPC Types\n\nThe RPC methods – both HTTP and subscriptions – are built with multiple overloads and conditional types. The expected HTTP response payload or subscription message format will be reflected in the return type of the function you’re working with when you provide the inputs in your code.\n\nHere’s an example of this in action:\n\n```ts\n// Provide one set of parameters, get a certain type\n// These parameters resolve to return type:\n// {\n//     blockhash: Blockhash;\n//     blockHeight: bigint;\n//     blockTime: UnixTimestamp;\n//     parentSlot: bigint;\n//     previousBlockhash: Blockhash;\n// }\nconst blockResponse = await rpc\n    .getBlock(0n, {\n        rewards: false,\n        transactionDetails: 'none',\n    })\n    .send();\n\n// Switch `rewards` to `true`, get `rewards` in the return type\n// {\n//     /* ... Previous response */\n//     rewards: Reward[];\n// }\nconst blockWithRewardsResponse = await rpc\n    .getBlock(0n, {\n        rewards: true,\n        transactionDetails: 'none',\n    })\n    .send();\n\n// Switch `transactionDetails` to `full`, get `transactions` in the return type\n// {\n//     /* ... Previous response */\n//     transactions: TransactionResponse[];\n// }\nconst blockWithRewardsAndTransactionsResponse = await rpc\n    .getBlock(0n, {\n        rewards: true,\n        transactionDetails: 'full',\n    })\n    .send();\n```\n\n### Catching Compile-Time Bugs with TypeScript\n\nAs previously mentioned, the type coverage in Kit allows developers to catch common bugs at compile time, rather than runtime.\n\nIn the example below, a transaction message is created and then attempted to be signed without setting the fee payer. This would result in a runtime error from the RPC, but instead you will see a type error from TypeScript as you type:\n\n```ts\nconst transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n    setTransactionMessageLifetimeUsingBlockhash(recentBlockhash, tx),\n);\nconst signedTransaction = await signTransaction([keyPair], transactionMessage); // ERROR: Property 'feePayer' is missing in type\n```\n\nConsider another example where a developer is attempting to send a transaction that has not been fully signed. Again, the TypeScript compiler will throw a type error:\n\n```ts\nconst transactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    tx => setTransactionMessageFeePayer(feePayerAddress, tx),\n    tx => setTransactionMessageLifetimeUsingBlockhash(recentBlockhash, tx),\n);\n\nconst signedTransaction = await signTransaction([], transactionMessage);\n\n// Asserts the transaction is a `FullySignedTransaction`\n// Throws an error if any signatures are missing!\nassertIsFullySignedTransaction(signedTransaction);\n\nawait sendAndConfirmTransaction(signedTransaction);\n```\n\nAre you building a nonce transaction and forgot to make `AdvanceNonce` the first instruction? That’s a type error:\n\n```ts\nconst feePayer = await generateKeyPair();\nconst feePayerAddress = await getAddressFromPublicKey(feePayer.publicKey);\n\nconst notNonceTransactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n    setTransactionMessageFeePayer(feePayerAddress, tx),\n);\n\nnotNonceTransactionMessage satisfies TransactionMessageWithDurableNonceLifetime;\n// => Property 'lifetimeConstraint' is missing in type\n\nconst nonceConfig = {\n    nonce: 'nonce' as Nonce,\n    nonceAccountAddress: address('5tLU66bxQ35so2bReGcyf3GfMMAAauZdNA1N4uRnKQu4'),\n    nonceAuthorityAddress: address('GDhj8paPg8woUzp9n8fj7eAMocN5P7Ej3A7T9F5gotTX'),\n};\n\nconst stillNotNonceTransactionMessage = {\n    lifetimeConstraint: nonceConfig,\n    ...notNonceTransactionMessage,\n};\n\nstillNotNonceTransactionMessage satisfies TransactionMessageWithDurableNonceLifetime;\n// => 'readonly Instruction<string>[]' is not assignable to type 'readonly [AdvanceNonceAccountInstruction<string, string>, ...Instruction<string>[]]'\n\nconst validNonceTransactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    tx => setTransactionMessageFeePayer(feePayerAddress, tx),\n    tx => setTransactionMessageLifetimeUsingDurableNonce(nonceConfig, tx), // Adds the instruction!\n);\n\nvalidNonceTransactionMessage satisfies TransactionMessageWithDurableNonceLifetime; // OK\n```\n\nThe library’s type-checking can even catch you using lamports instead of SOL for a value:\n\n```ts\nconst airdropAmount = 1n; // SOL\nconst signature = rpc.requestAirdrop(myAddress, airdropAmount).send();\n```\n\nIt will force you to cast the numerical value for your airdrop (or transfer, etc.) amount using `lamports()`, which should be a good reminder!\n\n```ts\nconst airdropAmount = lamports(1000000000n);\nconst signature = rpc.requestAirdrop(myAddress, airdropAmount).send();\n```\n\n## Compatibility Layer\n\nYou will have noticed by now that Kit is a complete and total breaking change from the web3.js 1.x line. We want to provide you with a strategy for interacting with web3.js 1.x APIs while building your application using Kit. You need a tool for converting between web3.js 1.x and Kit data types.\n\nThe `@solana/compat` library allows for interoperability between functions and class objects from the legacy library - such as `VersionedTransaction`, `PublicKey`, and `Keypair` - and functions and types of the new library - such as `Address`, `Transaction`, and `CryptoKeyPair`.\n\nHere’s how you can use `@solana/compat` to convert from a legacy `PublicKey` to an `Address`:\n\n```ts\nimport { fromLegacyPublicKey } from '@solana/compat';\n\nconst publicKey = new PublicKey('B3piXWBQLLRuk56XG5VihxR4oe2PSsDM8nTF6s1DeVF5');\nconst address: Address = fromLegacyPublicKey(publicKey);\n```\n\nHere’s how to convert from a legacy `Keypair` to a `CryptoKeyPair`:\n\n```ts\nimport { fromLegacyKeypair } from '@solana/compat';\n\nconst keypairLegacy = Keypair.generate();\nconst cryptoKeyPair: CryptoKeyPair = fromLegacyKeypair(keypair);\n```\n\nHere’s how to convert legacy transaction objects to the new library’s transaction types:\n\n```ts\n// Note that you can only convert `VersionedTransaction` objects\nconst modernTransaction = fromVersionedTransaction(classicTransaction);\n```\n\nTo see more conversions supported by `@solana/compat`, you can check out the package’s [README on GitHub](https://github.com/anza-xyz/kit/blob/main/packages/compat/README.md).\n\n## Program Clients\n\nWriting JavaScript clients for on-chain programs has been done manually up until now. Without an IDL for some of the native programs, this process has been necessarily manual and has resulted in clients that lag behind the actual capabilities of the programs themselves.\n\nWe think that program clients should be _generated_ rather than written. Developers should be able to write Rust programs, compile the program code, and generate all of the JavaScript client-side code to interact with the program.\n\nWe use [Codama](https://github.com/codama-idl/codama) to represent Solana programs and generate clients for them. This includes a JavaScript client compatible with this library. For instance, here is how you’d construct a transaction message composed of instructions from three different core programs.\n\n```ts\nimport { appendTransactionMessageInstructions, createTransactionMessage, pipe } from '@solana/kit';\nimport { getAddMemoInstruction } from '@solana-program/memo';\nimport { getSetComputeUnitLimitInstruction } from '@solana-program/compute-budget';\nimport { getTransferSolInstruction } from '@solana-program/system';\n\nconst instructions = [\n    getSetComputeUnitLimitInstruction({ units: 600_000 }),\n    getTransferSolInstruction({ source, destination, amount: 1_000_000_000 }),\n    getAddMemoInstruction({ memo: \"I'm transferring some SOL!\" }),\n];\n\n// Creates a V0 transaction message with 3 instructions inside.\nconst transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n    appendTransactionMessageInstructions(instructions, tx),\n);\n```\n\nAs you can see, each program now generates its own library allowing you to cherry-pick your dependencies.\n\nNote that asynchronous versions may be available for some instructions which allows them to resolve more inputs on your behalf — such as PDA derivation. For instance, the `CreateLookupTable` instruction offers an asynchronous builder that derives the `address` account and the `bump` argument for us.\n\n```ts\nconst rpc = createSolanaRpc('http://127.0.0.1:8899');\nconst [authority, recentSlot] = await Promise.all([\n    generateKeyPairSigner(),\n    rpc.getSlot({ commitment: 'finalized' }).send(),\n]);\n\nconst instruction = await getCreateLookupTableInstructionAsync({\n    authority,\n    recentSlot,\n});\n```\n\nAlternatively, you may use the synchronous builder if you already have all the required inputs at hand.\n\n```ts\nconst [address, bump] = await findAddressLookupTablePda({\n    authority: authority.address,\n    recentSlot,\n});\n\nconst instruction = getCreateLookupTableInstruction({\n    address,\n    authority,\n    bump,\n    recentSlot,\n});\n```\n\nOn top of instruction builders, these clients offer a variety of utilities such as:\n\n- Instruction codecs — e.g. `getTransferSolInstructionDataCodec`.\n- Account types — e.g. `AddressLookupTable`.\n- Account codecs — e.g. `getAddressLookupTableAccountDataCodec`.\n- Account helpers — e.g. `fetchAddressLookupTable`.\n- PDA helpers — e.g. `findAddressLookupTablePda`, `fetchAddressLookupTableFromSeeds`.\n- Defined types and their codecs — e.g. `NonceState`, `getNonceStateCodec`.\n- Program helpers — e.g. `SYSTEM_PROGRAM_ADDRESS`, `SystemAccount` enum, `identifySystemInstruction`.\n- And much more!\n\nHere’s another example that fetches an `AddressLookupTable` PDA from its seeds.\n\n```ts\nconst account = await fetchAddressLookupTableFromSeeds(rpc, {\n    authority: authority.address,\n    recentSlot,\n});\n\naccount.address; // Address\naccount.lamports; // Lamports\naccount.data.addresses; // Address[]\naccount.data.authority; // Some<Address>\naccount.data.deactivationSlot; // Slot\naccount.data.lastExtendedSlot; // Slot\naccount.data.lastExtendedSlotStartIndex; // number\n```\n\n### How Does This Work?\n\nAll of this code is 100% auto-generated by Codama from a tree of standardized nodes that represent our programs. It contains obvious nodes such as `AccountNode` but also more specified nodes such as `ConditionalValueNode` that allows us to resolve account or argument default values conditionally.\n\nCodama allows us to hydrate our tree of nodes from IDLs which are typically generated by program frameworks such as [Anchor](https://github.com/coral-xyz/anchor) or [Shank](https://github.com/metaplex-foundation/shank). Additionally, visitors can be used on our nodes to expand the knowledge of our programs since the IDL itself doesn’t yet contain that level of information. Finally, special visitors called ‘renderers’ visit our tree to generate clients such as this JavaScript client.\n\nCurrently, there is one other renderer that generates Rust clients but this is only the beginning. In the future, you can expect renderers for auto-generated Python clients, documentation, CLIs, etc.\n\n## Create Solana Program\n\nWe believe the whole ecosystem could benefit from generated program clients. That’s why we introduced a new NPM binary that allows you to create your Solana program — and generate clients for it — in no time. Simply run the following and follow the prompts to get started.\n\n```sh\npnpm create solana-program\n```\n\nThis [`create-solana-program`](https://github.com/solana-program/create-solana-program) installer will create a new repository including:\n\n- An example program using the framework of your choice (Anchor coming soon).\n- Generated clients for any of the selected clients.\n- A set of scripts that allows you to:\n    - Start a local validator including all programs and accounts you depend on.\n    - Build, lint and test your programs.\n    - Generate IDLs from your programs.\n    - Generate clients from the generated IDLs.\n    - Build and test each of your clients.\n- GitHub Actions pipelines to test your program, test your clients, and even manually publish new packages or crates for your clients. (Coming soon).\n\nWhen selecting the JavaScript client, you will get a fully generated library compatible with Kit much like the `@solana-program` packages showcased above.\n\n## GraphQL\n\nThough not directly related to web3.js, we wanted to hijack your attention to show you something else that we’re working on, of particular interest to frontend developers. It’s a new API for interacting with the RPC: a GraphQL API.\n\nThe `@solana/rpc-graphql` package can be used to make GraphQL queries to Solana RPC endpoints, using the same transports described above (including any customizations).\n\nHere’s an example of retrieving account data with GraphQL:\n\n```ts\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            dataBase58: data(encoding: BASE_58)\n            dataBase64: data(encoding: BASE_64)\n            lamports\n        }\n    }\n`;\n\nconst variableValues = {\n    address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n\nexpect(result).toMatchObject({\n    data: {\n        account: {\n            dataBase58: '2Uw1bpnsXxu3e',\n            dataBase64: 'dGVzdCBkYXRh',\n            lamports: 10290815n,\n        },\n    },\n});\n```\n\nUsing GraphQL allows developers to only specify which fields they _actually_ need, and do away with the rest of the response.\n\nHowever, GraphQL is also extremely powerful for **nesting queries**, which can be particularly useful if you want to, say, get the **sum** of every lamports balance of every **owner of the owner** of each token account, while discarding any mint accounts.\n\n```ts\nconst source = `\n    query getLamportsOfOwnersOfOwnersOfTokenAccounts {\n        programAccounts(programAddress: \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\") {\n            ... on TokenAccount {\n                owner {\n                    ownerProgram {\n                        lamports\n                    }\n                }\n            }\n        }\n    }\n`;\n\nconst result = await rpcGraphQL.query(source);\n\nconst sumOfAllLamportsOfOwnersOfOwnersOfTokenAccounts = result\n    .map(o => o.account.owner.ownerProgram.lamports)\n    .reduce((acc, lamports) => acc + lamports, 0);\n```\n\nThe new GraphQL package supports this same style of nested querying on transactions and blocks.\n\n```ts\nconst source = `\n    query myQuery($signature: String!, $commitment: Commitment) {\n        transaction(signature: $signature, commitment: $commitment) {\n            message {\n                instructions {\n                    ... on CreateAccountInstruction {\n                        lamports\n                        programId\n                        space\n                    }\n                }\n            }\n        }\n    }\n`;\n\nconst variableValues = {\n    signature: '63zkpxATgAwXRGFQZPDESTw2m4uZQ99sX338ibgKtTcgG6v34E3MSS3zckCwJHrimS71cvei6h1Bn1K1De53BNWC',\n    commitment: 'confirmed',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n\nexpect(result).toMatchObject({\n    data: {\n        transaction: {\n            message: {\n                instructions: expect.arrayContaining([\n                    {\n                        lamports: expect.any(BigInt),\n                        programId: '11111111111111111111111111111111',\n                        space: expect.any(BigInt),\n                    },\n                ]),\n            },\n        },\n    },\n});\n```\n\nSee more in the package’s [README on GitHub](https://github.com/anza-xyz/kit/tree/main/packages/rpc-graphql).\n\n## Development\n\nYou can see all development of this library and associated GraphQL tooling in the Kit repository on GitHub.\n\n- https://github.com/anza-xyz/kit\n\nYou can follow along with program client generator development in the `@solana-program` org and the `@codama-idl/codama` repository.\n\n- https://github.com/solana-program/\n- https://github.com/codama-idl/codama\n\nSolana Labs develops these tools in public, as open source. We encourage any and all developers who would like to work on these tools to contribute to the codebase.\n\n## Thank you\n\nWe’re grateful that you have read this far. If you are interested in migrating an existing application to Kit to take advantage of some of the benefits we’ve demonstrated, we want to give you some direct support. Reach out to [@steveluscher](https://t.me/steveluscher/) on Telegram to start a conversation.\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n1. [Reporting security problems](#reporting)\n2. [Incident Response Process](#process)\n\n<a name=\"reporting\"></a>\n\n## Reporting security problems in the Solana JavaScript SDK\n\n**DO NOT CREATE A GITHUB ISSUE** to report a security problem.\n\nInstead please use this [Report a Vulnerability](https://github.com/anza-xyz/kit/security/advisories/new) link. Provide a helpful title, detailed description of the vulnerability and an exploit proof-of-concept. Speculative submissions without proof-of-concept will be closed with no further consideration.\n\nIf you haven't done so already, please **enable two-factor auth** in your GitHub account.\n\n--\n\nIf you do not receive a response in the advisory, send an email to security@anza.xyz with the full URL of the advisory you have created. DO NOT include attachments or provide detail sufficient for exploitation regarding the security issue in this email. **Only provide such details in the advisory**.\n\nIf you do not receive a response from security@anza.xyz please follow up with the team directly. You can do this in the `#js` channel of the [Solana Tech discord server](https://solana.com/discord), by pinging the `Anza` role in the channel and referencing the fact that you submitted a security problem.\n\n<a name=\"process\"></a>\n\n## Incident Response Process\n\nIn case an incident is discovered or reported, the following process will be followed to contain, respond and remediate:\n\n### 1. Accept the new report\n\nIn response to a newly reported security problem, a member of the `anza-xyz/core-contributors` group will accept the report to turn it into a draft advisory. The `anza-xyz/security-incident-response` group should be added to the draft security advisory, and create a private fork of the repository (grey button towards the bottom of the page) if necessary.\n\nIf the advisory is the result of an audit finding, follow the same process as above but add the auditor's github user(s) and begin the title with \"[Audit]\".\n\nIf the report is out of scope, a member of the `anza-xyz/core-contributors` group will comment as such and then close the report.\n\n### 2. Triage\n\nWithin the draft security advisory, discuss and determine the severity of the issue. If necessary, members of the `anza-xyz/security-incident-response` group may add other github users to the advisory to assist. If it is determined that this is not a critical issue then the advisory should be closed and if more follow-up is required a normal Solana public github issue should be created.\n\n### 3. Prepare Fixes\n\nPrepare a fix for the issue and push them to `main` in the private repository associated with the draft security advisory. There is no CI available in the private repository so you must build from source and manually verify fixes. Code review from the reporter is ideal, as well as from multiple members of the core development team.\n\n### 4. Ship the patch\n\nOnce the fix is accepted, a member of the anza-xyz/security-incident-response group should prepare a patch using [`pnpm patch`](https://pnpm.io/cli/patch), [`yarn patch`](https://yarnpkg.com/cli/patch), and [`patch-package`](https://www.npmjs.com/package/patch-package) for developers still using `npm`. Post the patch to an unlisted [GitHub Gist](https://gist.github.com) and disseminate patch instructions privately to as many vulnerable applications as possible.\n\n### 5. Public Disclosure and Release\n\nOnce the fix has been deployed to as large an affected application set as practical, the patches from the security advisory may be merged into the main source repository. A new official release should be shipped, and old affected releases deprecated on NPM using the `npm deprecate` command.\n"
  },
  {
    "path": "docs/.eslintrc.json",
    "content": "{\n    \"extends\": [\"next/core-web-vitals\", \"next/typescript\"]\n}\n"
  },
  {
    "path": "docs/.gitignore",
    "content": "# deps\n/node_modules\n\n# generated content\n.contentlayer\n.content-collections\n.source\n\n# test & build\n/coverage\n/.next/\n/out/\n/build\n*.tsbuildinfo\n\n# misc\n.DS_Store\n*.pem\n/.pnp\n.pnp.js\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# others\n.env*.local\n.vercel\nnext-env.d.ts\n"
  },
  {
    "path": "docs/.npmrc",
    "content": "enable-pre-post-scripts = true\n"
  },
  {
    "path": "docs/.prettierignore",
    "content": "pnpm-lock.yaml\ncontent/api/"
  },
  {
    "path": "docs/README.md",
    "content": "# Kit documentation\n\nDocumentation website for Kit, built with [Fumadocs](https://github.com/fuma-nama/fumadocs).\n\n## Install dependencies\n\nInstall using the `--ignore-workspace` flag to ensure the dependencies of the documentation website are separate from the library dependencies.\n\n```bash\npnpm install --ignore-workspace\n```\n\n## Download necessary environment variables (employees only)\n\n```bash\npnpm vercel link -p kit-docs -S anza-tech --yes\npnpm vercel env pull --environment=development\n```\n\n## Run development server\n\n```bash\npnpm dev\n```\n\nOpen http://localhost:3000 with your browser to see the result.\n\n## Learn more\n\nTo learn more about Next.js and Fumadocs, take a look at the following\nresources:\n\n- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js\n  features and API.\n- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.\n- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs\n"
  },
  {
    "path": "docs/build-api-docs.sh",
    "content": "#!/usr/bin/env bash\nset -euo pipefail\n\ncd ..\npnpm turbo compile:docs --output-logs=hash-only\n\n# Move generated docs.\necho \"➡️ Moving generated TypeDoc files to docs/content/api...\"\nAPI_DIR=\"$(pwd)/docs/content/api\"\nfind $API_DIR -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} +\nmkdir -p \"$API_DIR\"\n\nfor DOC_PATH in packages/*/.docs; do\n    (cd \"$DOC_PATH\" && find . -type f ! -name \"index.mdx\" | while read -r file; do\n        mkdir -p \"$API_DIR/$(dirname \"$file\")\"\n        cp \"$file\" \"$API_DIR/$file\"\n    done)\ndone\n\n# Generate API index.\necho \"📝 Generating API index page from TypeDoc JSON...\"\nnode docs/build-api-index.js\n\n# Regenerate .source to pick up the new index.mdx\necho \"♻️  Regenerating .source files...\"\ncd docs\npnpm fumadocs-mdx\n"
  },
  {
    "path": "docs/build-api-index.js",
    "content": "#!/usr/bin/env node\n\n/**\n * Generate API index page using TypeDoc JSON output\n * This script uses TypeDoc's JSON output to get detailed reflection data\n */\n\nconst fs = require('node:fs/promises');\nconst path = require('node:path');\nconst { execFile } = require('node:child_process');\nconst { promisify } = require('node:util');\n\nconst execFileAsync = promisify(execFile);\n\nasync function exists(path) {\n    try {\n        await fs.access(path);\n        return true;\n    } catch {\n        return false;\n    }\n}\n\nconst ROOT_DIR = path.join(__dirname, '..');\nconst PACKAGES_DIR = path.join(ROOT_DIR, 'packages');\nconst OUTPUT_FILE = path.join(ROOT_DIR, 'docs', 'content', 'api', 'index.mdx');\n\n// TypeDoc reflection kinds (from TypeDoc source)\nconst ReflectionKind = {\n    Project: 1,\n    Module: 2,\n    Namespace: 4,\n    Enum: 8,\n    EnumMember: 16,\n    Variable: 32,\n    Function: 64,\n    Class: 128,\n    Interface: 256,\n    Constructor: 512,\n    Property: 1024,\n    Method: 2048,\n    CallSignature: 4096,\n    IndexSignature: 8192,\n    ConstructorSignature: 16384,\n    Parameter: 32768,\n    TypeLiteral: 65536,\n    TypeParameter: 131072,\n    Accessor: 262144,\n    GetSignature: 524288,\n    SetSignature: 1048576,\n    ObjectLiteral: 2097152,\n    TypeAlias: 4194304,\n    Reference: 8388608,\n};\n\nconst API_GROUP_ORDER = ['Classes', 'Enums', 'Types', 'Functions', 'Variables'];\nconst REFLECTION_KIND_DATA = {\n    [ReflectionKind.Class]: { group: 'Classes', path: 'classes' },\n    [ReflectionKind.Interface]: { group: 'Types', path: 'interfaces' },\n    [ReflectionKind.ObjectLiteral]: { group: 'Types', path: 'type-aliases' },\n    [ReflectionKind.TypeAlias]: { group: 'Types', path: 'type-aliases' },\n    [ReflectionKind.Function]: { group: 'Functions', path: 'functions' },\n    [ReflectionKind.Enum]: { group: 'Enums', path: 'enumerations' },\n    [ReflectionKind.Variable]: { group: 'Variables', path: 'variables' },\n};\n\nasync function findPackageInfos() {\n    const packages = [];\n    const packageDirs = await fs.readdir(PACKAGES_DIR);\n\n    for (const packageName of packageDirs) {\n        const packagePath = path.join(PACKAGES_DIR, packageName);\n        const packageJsonPath = path.join(packagePath, 'package.json');\n        const srcPath = path.join(packagePath, 'src');\n        const indexPath = path.join(srcPath, 'index.ts');\n        const typedocConfigPath = path.join(packagePath, 'typedoc.json');\n\n        // Skip packages without source, package.json, or typedoc config.\n        const artifactsExistence = await Promise.all([\n            exists(packageJsonPath),\n            exists(srcPath),\n            exists(indexPath),\n            exists(typedocConfigPath),\n        ]);\n        if (artifactsExistence.includes(false)) {\n            continue;\n        }\n\n        const pkg = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));\n        packages.push({ name: pkg.name, path: packagePath });\n    }\n\n    return packages.sort((a, b) => a.name.localeCompare(b.name));\n}\n\nasync function generateTypeDocJSON(packageInfo) {\n    const { path: packagePath, name } = packageInfo;\n    const jsonOutputPath = path.join(packagePath, 'typedoc-output.json');\n\n    try {\n        // Generate JSON output only (suppress regular output).\n        await execFileAsync(\n            './node_modules/typedoc/bin/typedoc',\n            [\n                '--json',\n                jsonOutputPath,\n                '--tsconfig',\n                path.join(packagePath, 'tsconfig.json'),\n                '--out',\n                '/dev/null',\n                '--excludePrivate',\n                '--excludeProtected',\n                '--excludeInternal',\n                path.join(packagePath, 'src', 'index.ts'),\n            ],\n            { cwd: ROOT_DIR },\n        );\n\n        if (!(await exists(jsonOutputPath))) {\n            console.warn(`⚠️  No JSON output generated for ${name}`);\n            return null;\n        }\n\n        const typeDocJSON = JSON.parse(await fs.readFile(jsonOutputPath, 'utf8'));\n\n        // Clean up the temp JSON file\n        await fs.unlink(jsonOutputPath);\n\n        return typeDocJSON;\n    } catch (error) {\n        console.error(`❌ Failed to generate JSON for ${name}:`, error.message);\n        return null;\n    }\n}\n\nfunction processTypeDocJSON(packageInfo, typeDocJSON) {\n    const exports = [];\n    const dependencies = new Set([]);\n\n    if (!typeDocJSON || !typeDocJSON.children) {\n        return { ...packageInfo, dependencies, exports };\n    }\n\n    function processChildren(children) {\n        for (const child of children) {\n            // Only include relevant kinds in the exports.\n            if (REFLECTION_KIND_DATA[child.kind]) {\n                const fromPackage = typeDocJSON.symbolIdMap[child.id]?.packageName || typeDocJSON.packageName;\n                const isDependency = fromPackage !== typeDocJSON.packageName;\n                if (isDependency) {\n                    dependencies.add(fromPackage);\n                } else {\n                    exports.push({ name: child.name, kind: child.kind });\n                }\n            }\n\n            // Recursively process nested children.\n            if (child.children) {\n                processChildren(child.children);\n            }\n        }\n    }\n\n    processChildren(typeDocJSON.children);\n    return { ...packageInfo, dependencies, exports };\n}\n\nfunction generateIndexContent(packages) {\n    const totalPackages = packages.length;\n\n    let content = `---\ntitle: API Reference\ndescription: Explore packages, functions, types, and more\n---\n\nWelcome to the Solana Kit API Reference! It covers a total of **${totalPackages} packages** most of which are available via the main \\`@solana/kit\\` package.\n\n\n## Need Help?\n\n- Check out our [Getting Started guide](/docs/getting-started/).\n- Learn about key concepts in our [Advanced Guides](/docs/advanced-guides/).\n\n## All Packages\n\n`;\n\n    // Sort packages by name but with `@solana/kit` first.\n    const sortedPackages = packages.sort((a, b) => {\n        if (a.name === '@solana/kit') return -1;\n        if (b.name === '@solana/kit') return 1;\n        return a.name.localeCompare(b.name);\n    });\n\n    // Generate entries for each package alphabetically.\n    for (const package of sortedPackages) {\n        content += `### \\`${package.name}\\`\\n\\n`;\n\n        // List exported dependencies.\n        if (package.dependencies.size > 0) {\n            const dependencies = [...package.dependencies].sort((a, b) => a.localeCompare(b));\n            const title = `Packages (${dependencies.length})`;\n            content += `${wrapApiGroupTitle(title)}\\n\\n`;\n\n            const links = dependencies.map(dependency => `[${dependency}](#${dependency.replace(/(@|\\/)/g, '')})`);\n            content += `${wrapLinks(links, dependencies)}\\n\\n`;\n        }\n\n        // Sort exports into type groups.\n        const apiGroups = Object.fromEntries(API_GROUP_ORDER.map(group => [group, { title: group, items: [] }]));\n        for (const item of package.exports) {\n            if (item.kind && REFLECTION_KIND_DATA[item.kind]) {\n                const data = REFLECTION_KIND_DATA[item.kind];\n                if (apiGroups[data.group]) {\n                    apiGroups[data.group].items.push({ ...item, path: data.path });\n                }\n            }\n        }\n\n        // Generate sections for each type.\n        for (const group of Object.values(apiGroups)) {\n            if (group.items.length > 0) {\n                const title = `${group.title} (${group.items.length})`;\n                content += `${wrapApiGroupTitle(title)}\\n\\n`;\n\n                // List items with links.\n                const links = group.items\n                    .sort((a, b) => a.name.localeCompare(b.name))\n                    .map(item => `[${item.name}](/api/${item.path}/${item.name})`);\n\n                // Wrap links in columns when possible.\n                const names = group.items.map(item => item.name);\n                content += `${wrapLinks(links, names)}\\n\\n`;\n            }\n        }\n    }\n\n    content += `<Callout title=\"Note\">\n    This documentation is automatically generated from the source code using TypeDoc.\n</Callout>`;\n\n    return content;\n}\n\nfunction wrapApiGroupTitle(content) {\n    return `<p className=\"text-xs tracking-wider uppercase mt-8 -mb-2 text-linen-500 dark:text-linen-400\">${content}</p>`;\n}\n\nfunction wrapLinks(links, names) {\n    const maxNameLength = Math.max(...names.map(name => name.length));\n    let linkWrapper = content => content;\n    if (maxNameLength <= 30) {\n        linkWrapper = content => `<div className=\"*:columns-[12rem] *:gap-8\">\\n\\n${content}\\n\\n</div>`;\n    } else if (maxNameLength <= 60) {\n        linkWrapper = content => `<div className=\"*:columns-[20rem] *:gap-8\">\\n\\n${content}\\n\\n</div>`;\n    }\n\n    return linkWrapper(links.join(' \\\\\\n'));\n}\n\n// Main execution\nasync function main() {\n    const packageInfos = await findPackageInfos();\n\n    const packages = [];\n    await Promise.all(\n        packageInfos.map(async packageInfo => {\n            const typeDocJSON = await generateTypeDocJSON(packageInfo);\n            const package = await processTypeDocJSON(packageInfo, typeDocJSON);\n            packages.push(package);\n        }),\n    );\n\n    const content = generateIndexContent(packages);\n    await fs.writeFile(OUTPUT_FILE, content, 'utf8');\n\n    console.log('✅ API index generated successfully!');\n    console.log(`├─ Packages: ${packages.length}`);\n    console.log(`└─ Output: ${OUTPUT_FILE}`);\n}\n\nif (require.main === module) {\n    main().catch(console.error);\n}\n"
  },
  {
    "path": "docs/cli.json",
    "content": "{\n  \"$schema\": \"node_modules/@fumadocs/cli/dist/schema/src.json\",\n  \"aliases\": {\n    \"uiDir\": \"./components/ui\",\n    \"componentsDir\": \"./components\",\n    \"blockDir\": \"./components\",\n    \"cssDir\": \"./styles\",\n    \"libDir\": \"./lib\"\n  },\n  \"baseDir\": \"src\",\n  \"uiLibrary\": \"radix-ui\",\n  \"commands\": {}\n}"
  },
  {
    "path": "docs/content/.prettierrc",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/prettierrc\",\n    \"tabWidth\": 4,\n    \"singleQuote\": true,\n    \"printWidth\": 100\n}\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/codecs.mdx",
    "content": "---\ntitle: Codecs\ndescription: Encode and decode anything\n---\n\n## Introduction\n\nKit includes a powerful serialisation system called Codecs. Whether you're working with account data, instruction arguments, or custom binary layouts, Codecs give you the tools to transform structured data into bytes — and back again.\n\nCodecs are composable, type-safe, and environment-agnostic. They are designed to provide a flexible and consistent foundation for handling binary data across the Solana stack.\n\n## Installation\n\nCodecs are **included within the `@solana/kit` library** but you may also install them using their standalone package.\n\n```package-install\n@solana/codecs\n```\n\nNote that the `@solana/codecs` package itself is composed of several smaller packages, each providing a different set of codec helpers. Here's the list of all packages containing codecs, should you need to install them individually:\n\n| Package                                                                                          | Description                                                                        |\n| ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |\n| [`@solana/kit`](https://www.npmjs.com/package/@solana/kit)                                       | Includes `@solana/codecs`.                                                         |\n| [`@solana/codecs`](https://www.npmjs.com/package/@solana/codecs)                                 | Includes all codecs packages below.                                                |\n| [`@solana/codecs-core`](https://www.npmjs.com/package/@solana/codecs-core)                       | Core types and utilities for building codecs.                                      |\n| [`@solana/codecs-numbers`](https://www.npmjs.com/package/@solana/codecs-numbers)                 | Codecs for numbers of various sizes and characteristics.                           |\n| [`@solana/codecs-strings`](https://www.npmjs.com/package/@solana/codecs-strings)                 | Codecs for strings of various encodings and size strategies.                       |\n| [`@solana/codecs-data-structures`](https://www.npmjs.com/package/@solana/codecs-data-structures) | Codecs for a variety of data structures such as objects, enums, arrays, maps, etc. |\n| [`@solana/options`](https://www.npmjs.com/package/@solana/options)                               | Codecs for Rust-like `Options` in JavaScript.                                      |\n\n## What is a Codec?\n\nA Codec is an object that knows how to encode a any type into a `Uint8Array` and how to decode a `Uint8Array` back into that value.\n\nNo matter which serialization strategy we use, Codecs abstract away its implementation and offer a simple encode and decode interface. They are also highly composable, allowing us to build complex data structures from simple building blocks.\n\nHere's a quick example that encodes and decodes a simple `Person` type.\n\n```ts twoslash\nimport {\n    Codec,\n    addCodecSizePrefix,\n    getUtf8Codec,\n    getU32Codec,\n    getStructCodec,\n    ReadonlyUint8Array,\n} from '@solana/kit';\n// ---cut-before---\n// Use composable codecs to build complex data structures.\ntype Person = { name: string; age: number };\nconst getPersonCodec = (): Codec<Person> =>\n    getStructCodec([\n        ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n        ['age', getU32Codec()],\n    ]);\n\n// Use your own codecs to encode and decode data.\nconst personCodec = getPersonCodec();\nconst encodedPerson = personCodec.encode({ name: 'John', age: 42 });\nconst decodedPerson = personCodec.decode(encodedPerson);\n```\n\n## Composing codecs\n\nThe easiest way to create your own codecs is to compose the [various codecs](#available-codecs) at your disposal.\n\nFor instance, consider the following codecs available:\n\n- `getStructCodec`: Creates a codec for objects with named fields.\n- `getU32Codec`: Creates a codec for unsigned 32-bit integers.\n- `getUtf8Codec`: Creates a codec for UTF-8 strings.\n- `addCodecSizePrefix`: Creates a codec that prefixes the encoded data with its length.\n- `getBooleanCodec`: Creates a codec for booleans using a single byte.\n\nBy combining them together we can create a custom codec for the following `Person` type.\n\n```ts twoslash\nimport {\n    Codec,\n    addCodecSizePrefix,\n    getUtf8Codec,\n    getU32Codec,\n    getStructCodec,\n    getBooleanCodec,\n} from '@solana/kit';\n// ---cut-before---\ntype Person = {\n    name: string;\n    age: number;\n    verified: boolean;\n};\n\nconst getPersonCodec = (): Codec<Person> =>\n    getStructCodec([\n        ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n        ['age', getU32Codec()],\n        ['verified', getBooleanCodec()],\n    ]);\n```\n\nThis function returns a `Codec` object which contains both an `encode` and `decode` function that can be used to convert a `Person` type to and from a `Uint8Array`.\n\n```ts twoslash\nimport {\n    Codec,\n    addCodecSizePrefix,\n    getUtf8Codec,\n    getU32Codec,\n    getStructCodec,\n    getBooleanCodec,\n} from '@solana/kit';\ntype Person = { name: string; age: number; verified: boolean };\nconst getPersonCodec = (): Codec<Person> =>\n    getStructCodec([\n        ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n        ['age', getU32Codec()],\n        ['verified', getBooleanCodec()],\n    ]);\n// ---cut-before---\nconst personCodec = getPersonCodec();\nconst bytes = personCodec.encode({ name: 'John', age: 42, verified: true });\nconst person = personCodec.decode(bytes);\n```\n\nThere is a significant library of composable codecs at your disposal, enabling you to compose complex types. Check out the [available codecs](#available-codecs) section for more information. If you need a custom codec that cannot be composed from existing ones, you can always create your own as we will see in the [\"Creating custom codecs\"](#creating-custom-codecs) section below.\n\n## Separate encoders and decoders\n\nWhilst Codecs can both encode and decode, it is possible to only focus on encoding or decoding data, enabling the unused logic to be tree-shaken. For instance, here's our previous example using Encoders only to encode a `Person` type.\n\n```ts twoslash\nimport {\n    Encoder,\n    addEncoderSizePrefix,\n    getUtf8Encoder,\n    getU32Encoder,\n    getStructEncoder,\n    getBooleanEncoder,\n} from '@solana/kit';\ntype Person = { name: string; age: number; verified: boolean };\n// ---cut-before---\nconst getPersonEncoder = (): Encoder<Person> =>\n    getStructEncoder([\n        ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n        ['age', getU32Encoder()],\n        ['verified', getBooleanEncoder()],\n    ]);\n\nconst bytes = getPersonEncoder().encode({ name: 'John', age: 42, verified: true });\n```\n\nThe same can be done for decoding the `Person` type by using Decoders like so.\n\n```ts twoslash\nimport {\n    Decoder,\n    addDecoderSizePrefix,\n    getUtf8Decoder,\n    getU32Decoder,\n    getStructDecoder,\n    getBooleanDecoder,\n} from '@solana/kit';\ntype Person = { name: string; age: number; verified: boolean };\nconst bytes = null as unknown as Uint8Array;\n// ---cut-before---\nconst getPersonDecoder = (): Decoder<Person> =>\n    getStructDecoder([\n        ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n        ['age', getU32Decoder()],\n        ['verified', getBooleanDecoder()],\n    ]);\n\nconst person = getPersonDecoder().decode(bytes);\n```\n\n## Combining encoders and decoders\n\nSeparating Codecs into Encoders and Decoders is particularly good practice for library maintainers as it allows their users to tree-shake any of the encoders and/or decoders they don't need. However, we may still want to offer a codec helper for users who need both for convenience.\n\nThat's why this library offers a `combineCodec` helper that creates a `Codec` instance from a matching `Encoder` and `Decoder`.\n\n```ts twoslash\nimport { Codec, Encoder, Decoder, combineCodec } from '@solana/kit';\ntype Person = { name: string; age: number; verified: boolean };\nconst getPersonEncoder = null as unknown as () => Encoder<Person>;\nconst getPersonDecoder = null as unknown as () => Decoder<Person>;\n// ---cut-before---\nconst getPersonCodec = (): Codec<Person> => combineCodec(getPersonEncoder(), getPersonDecoder());\n```\n\nThis means library maintainers can offer Encoders, Decoders and Codecs for all their types whilst staying efficient and tree-shakeable. In summary, we recommend the following pattern when creating codecs for library types.\n\n```ts\ntype MyType = /* ... */;\nconst getMyTypeEncoder = (): Encoder<MyType> => { /* ... */ };\nconst getMyTypeDecoder = (): Decoder<MyType> => { /* ... */ };\nconst getMyTypeCodec = (): Codec<MyType> => combineCodec(\n    getMyTypeEncoder(),\n    getMyTypeDecoder(),\n);\n```\n\n## Different `From` and `To` types\n\nWhen creating codecs, the encoded type is allowed to be looser than the decoded type. A good example of that is the u64 number codec:\n\n```ts twoslash\nimport { Codec, getU64Codec } from '@solana/kit';\n// ---cut-before---\nconst u64Codec: Codec<number | bigint, bigint> = getU64Codec();\n```\n\nAs you can see, the first type parameter is looser since it accepts numbers or big integers, whereas the second type parameter only accepts big integers. That's because when _encoding_ a u64 number, you may provide either a `bigint` or a `number` for convenience. However, when you decode a u64 number, you will always get a `bigint` because not all u64 values can fit in a JavaScript `number` type.\n\n```ts twoslash\nimport { getU64Codec } from '@solana/kit';\nconst u64Codec = getU64Codec();\n// ---cut-before---\nconst bytes = u64Codec.encode(42);\nconst value = u64Codec.decode(bytes); // BigInt(42)\n```\n\nThis relationship between the type we encode “From” and decode “To” can be generalized in TypeScript as `To extends From`.\n\nHere's another example using an object with default values. You can read more about the [transformCodec](#transform-codec) helper below.\n\n```ts twoslash\nimport {\n    Codec,\n    Encoder,\n    Decoder,\n    transformEncoder,\n    getStructEncoder,\n    getStructDecoder,\n    addEncoderSizePrefix,\n    addDecoderSizePrefix,\n    getUtf8Encoder,\n    getUtf8Decoder,\n    getU32Encoder,\n    getU32Decoder,\n    combineCodec,\n} from '@solana/kit';\n// ---cut-before---\ntype Person = { name: string; age: number };\ntype PersonInput = { name: string; age?: number };\n\nconst getPersonEncoder = (): Encoder<PersonInput> =>\n    transformEncoder(\n        getStructEncoder([\n            ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n            ['age', getU32Encoder()],\n        ]),\n        (input) => ({ ...input, age: input.age ?? 42 }),\n    );\n\nconst getPersonDecoder = (): Decoder<Person> =>\n    getStructDecoder([\n        ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n        ['age', getU32Decoder()],\n    ]);\n\nconst getPersonCodec = (): Codec<PersonInput, Person> =>\n    combineCodec(getPersonEncoder(), getPersonDecoder());\n```\n\n## Fixed-size and variable-size codecs\n\nIt is also worth noting that Codecs can either be of fixed size or variable size.\n\n`FixedSizeCodecs` have a `fixedSize` number attribute that tells us exactly how big their encoded data is in bytes.\n\n```ts twoslash\nimport { FixedSizeCodec, getU32Codec } from '@solana/kit';\n// ---cut-before---\nconst myCodec = getU32Codec();\nmyCodec satisfies FixedSizeCodec<number>;\nmyCodec.fixedSize; // 4 bytes.\n```\n\nOn the other hand, `VariableSizeCodecs` do not know the size of their encoded data in advance. Instead, they will grab that information either from the provided encoded data or from the value to encode. For the former, we can simply access the length of the `Uint8Array`. For the latter, it provides a `getSizeFromValue` that tells us the encoded byte size of the provided value.\n\n```ts twoslash\nimport { VariableSizeCodec, getUtf8Codec, getU32Codec, addCodecSizePrefix } from '@solana/kit';\n// ---cut-before---\nconst myCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\nmyCodec satisfies VariableSizeCodec<string>;\nmyCodec.getSizeFromValue('hello world'); // 4 + 11 bytes.\n```\n\nAlso note that, if the `VariableSizeCodec` is bounded by a maximum size, it can be provided as a `maxSize` number attribute.\n\nThe following type guards are available to identify and/or assert the size of codecs: `isFixedSize`, `isVariableSize`, `assertIsFixedSize` and `assertIsVariableSize`.\n\nFinally, note that the same is true for `Encoders` and `Decoders`.\n\n- A `FixedSizeEncoder` has a `fixedSize` number attribute.\n- A `VariableSizeEncoder` has a `getSizeFromValue` function and an optional `maxSize` number attribute.\n- A `FixedSizeDecoder` has a `fixedSize` number attribute.\n- A `VariableSizeDecoder` has an optional `maxSize` number attribute.\n\n## Creating custom codecs\n\nIf composing codecs isn't enough for you, you may implement your own codec logic by using the `createCodec` function. This function requires an object with a `read` and a `write` function telling us how to read from and write to an existing byte array.\n\nThe `read` function accepts the `bytes` to decode from and the `offset` at each we should start reading. It returns an array with two items:\n\n- The first item should be the decoded value.\n- The second item should be the next offset to read from.\n\n```ts twoslash\nimport { createCodec, Offset } from '@solana/kit';\nconst write = null as unknown as Parameters<typeof createCodec<number>>[0]['write'];\nconst fixedSize = null as unknown as 1;\n// ---cut-before---\ncreateCodec({\n    read(bytes, offset) {\n        const value = bytes[offset];\n        return [value, offset + 1];\n    },\n    write,\n    fixedSize,\n});\n```\n\nReciprocally, the `write` function accepts the `value` to encode, the array of `bytes` to write the encoded value to and the `offset` at which it should be written. It should encode the given value, insert it in the byte array, and provide the next offset to write to as the return value.\n\n```ts twoslash\nimport { createCodec } from '@solana/kit';\nconst read = null as unknown as Parameters<typeof createCodec<number>>[0]['read'];\nconst fixedSize = null as unknown as 1;\n// ---cut-before---\ncreateCodec({\n    write(value: number, bytes, offset) {\n        bytes.set([value], offset);\n        return offset + 1;\n    },\n    read,\n    fixedSize,\n});\n```\n\nAdditionally, we must specify the size of the codec. If we are defining a `FixedSizeCodec`, we must simply provide the `fixedSize` number attribute. For `VariableSizeCodecs`, we must provide the `getSizeFromValue` function as described in the previous section.\n\n```ts twoslash\nimport { createCodec } from '@solana/kit';\ntype Config = Parameters<typeof createCodec<string>>[0];\nconst read = null as unknown as Config['read'];\nconst write = null as unknown as Config['write'];\n// ---cut-before---\n// FixedSizeCodec.\ncreateCodec({\n    fixedSize: 1,\n    read,\n    write,\n});\n\n// VariableSizeCodec.\ncreateCodec({\n    getSizeFromValue: (value: string) => value.length,\n    read,\n    write,\n});\n```\n\nHere's a concrete example of a custom codec that encodes any unsigned integer in a single byte. Since a single byte can only store integers from 0 to 255, if any other integer is provided it will take its modulo 256 to ensure it fits in a single byte. Because it always requires a single byte, that codec is a `FixedSizeCodec` of size `1`.\n\n```ts twoslash\nimport { createCodec } from '@solana/kit';\n\nconst getModuloU8Codec = () =>\n    createCodec<number>({\n        fixedSize: 1,\n        read(bytes, offset) {\n            const value = bytes[offset];\n            return [value, offset + 1];\n        },\n        write(value, bytes, offset) {\n            bytes.set([value % 256], offset);\n            return offset + 1;\n        },\n    });\n```\n\nNote that, it is also possible to create custom encoders and decoders separately by using the `createEncoder` and `createDecoder` functions respectively and then use the `combineCodec` function on them just like we were doing with composed codecs.\n\nThis approach is recommended to library maintainers as it allows their users to tree-shake any of the encoders and/or decoders they don't need.\n\nHere's our previous modulo u8 example but split into separate `Encoder`, `Decoder` and `Codec` instances.\n\n```ts twoslash\nimport { createEncoder, createDecoder, combineCodec } from '@solana/kit';\n\nconst getModuloU8Encoder = () =>\n    createEncoder<number>({\n        fixedSize: 1,\n        write(value, bytes, offset) {\n            bytes.set([value % 256], offset);\n            return offset + 1;\n        },\n    });\n\nconst getModuloU8Decoder = () =>\n    createDecoder<number>({\n        fixedSize: 1,\n        read(bytes, offset) {\n            const value = bytes[offset];\n            return [value, offset + 1];\n        },\n    });\n\nconst getModuloU8Codec = () => combineCodec(getModuloU8Encoder(), getModuloU8Decoder());\n```\n\nHere's another example returning a `VariableSizeCodec`. This one transforms a simple string composed of characters from `a` to `z` to a buffer of numbers from `1` to `26` where `0` bytes are spaces.\n\n```ts twoslash\nimport { createEncoder, createDecoder, combineCodec } from '@solana/kit';\n\nconst alphabet = ' abcdefghijklmnopqrstuvwxyz';\n\nconst getCipherEncoder = () =>\n    createEncoder<string>({\n        getSizeFromValue: (value) => value.length,\n        write(value, bytes, offset) {\n            const bytesToAdd = [...value].map((char) => alphabet.indexOf(char));\n            bytes.set(bytesToAdd, offset);\n            return offset + bytesToAdd.length;\n        },\n    });\n\nconst getCipherDecoder = () =>\n    createDecoder<string>({\n        read(bytes, offset) {\n            const value = [...bytes.slice(offset)].map((byte) => alphabet.charAt(byte)).join('');\n            return [value, bytes.length];\n        },\n    });\n\nconst getCipherCodec = () => combineCodec(getCipherEncoder(), getCipherDecoder());\n```\n\n## Available codecs\n\n### Core utilities\n\n<div className=\"*:columns-[12rem] *:gap-8\">\n\n[addCodecSentinel](#add-codec-sentinel) \\\n[addCodecSizePrefix](#add-codec-size-prefix) \\\n[containsBytes](#contains-bytes) \\\n[fixBytes](#fix-bytes) \\\n[fixCodecSize](#fix-codec-size) \\\n[mergeBytes](#merge-bytes) \\\n[offsetCodec](#offset-codec) \\\n[padBytes](#pad-bytes) \\\n[padLeftCodec](#pad-left-codec) \\\n[padRightCodec](#pad-right-codec) \\\n[resizeCodec](#resize-codec) \\\n[reverseCodec](#reverse-codec) \\\n[transformCodec](#transform-codec)\n\n</div>\n\n### Numbers\n\n<div className=\"*:columns-[12rem] *:gap-8\">\n\n[getI8Codec](#get-i8-codec) \\\n[getI16Codec](#get-i16-codec) \\\n[getI32Codec](#get-i32-codec) \\\n[getI64Codec](#get-i64-codec) \\\n[getI128Codec](#get-i128-codec) \\\n[getF32Codec](#get-f32-codec) \\\n[getF64Codec](#get-f64-codec) \\\n[getShortU16Codec](#get-short-u16-codec) \\\n[getU8Codec](#get-u8-codec) \\\n[getU16Codec](#get-u16-codec) \\\n[getU32Codec](#get-u32-codec) \\\n[getU64Codec](#get-u64-codec) \\\n[getU128Codec](#get-u128-codec)\n\n</div>\n\n### Strings\n\n<div className=\"*:columns-[12rem] *:gap-8\">\n\n[getBase10Codec](#get-base10-codec) \\\n[getBase16Codec](#get-base16-codec) \\\n[getBase58Codec](#get-base58-codec) \\\n[getBase64Codec](#get-base64-codec) \\\n[getBaseXCodec](#get-baseX-codec) \\\n[getBaseXResliceCodec](#get-baseX-reslice-codec) \\\n[getUtf8Codec](#get-utf8-codec)\n\n</div>\n\n### Data structures\n\n<div className=\"*:columns-[12rem] *:gap-8\">\n\n[getArrayCodec](#get-array-codec) \\\n[getBitArrayCodec](#get-bit-array-codec) \\\n[getBooleanCodec](#get-boolean-codec) \\\n[getBytesCodec](#get-bytes-codec) \\\n[getConstantCodec](#get-constant-codec) \\\n[getDiscriminatedUnionCodec](#get-discriminated-union-codec) \\\n[getEnumCodec](#get-enum-codec) \\\n[getHiddenPrefixCodec](#get-hidden-prefix-codec) \\\n[getHiddenSuffixCodec](#get-hidden-suffix-codec) \\\n[getLiteralUnionCodec](#get-literal-union-codec) \\\n[getMapCodec](#get-map-codec) \\\n[getNullableCodec](#get-nullable-codec) \\\n[getOptionCodec](#get-option-codec) \\\n[getPatternMatchCodec](#get-pattern-match-codec) \\\n[getPredicateCodec](#get-predicate-codec) \\\n[getSetCodec](#get-set-codec) \\\n[getStructCodec](#get-struct-codec) \\\n[getTupleCodec](#get-tuple-codec) \\\n[getUnionCodec](#get-union-codec) \\\n[getUnitCodec](#get-unit-codec)\n\n</div>\n\n## Core utilities listing [!toc]\n\n### addCodecSentinel [!toc] [#add-codec-sentinel]\n\nOne way of delimiting the size of a codec is to use sentinels. The `addCodecSentinel` function allows us to add a sentinel to the end of the encoded data and to read until that sentinel is found when decoding. It accepts any codec and a `Uint8Array` sentinel responsible for delimiting the encoded data.\n\n```ts twoslash\nimport { addCodecSentinel, getUtf8Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = addCodecSentinel(getUtf8Codec(), new Uint8Array([255, 255]));\ncodec.encode('hello');\n// 0x68656c6c6fffff\n//   |        └-- Our sentinel.\n//   └-- Our encoded string.\n```\n\nNote that the sentinel _must not_ be present in the encoded data and _must_ be present in the decoded data for this to work. If this is not the case, dedicated errors will be thrown.\n\n```ts twoslash\nimport { addCodecSentinel, getUtf8Codec } from '@solana/kit';\n// ---cut-before---\nconst sentinel = new Uint8Array([108, 108]); // 'll'\nconst codec = addCodecSentinel(getUtf8Codec(), sentinel);\n\ncodec.encode('hello'); // Throws: sentinel is in encoded data.\ncodec.decode(new Uint8Array([1, 2, 3])); // Throws: sentinel missing in decoded data.\n```\n\nSeparate `addEncoderSentinel` and `addDecoderSentinel` functions are also available.\n\n```ts twoslash\nimport {\n    addEncoderSentinel,\n    addDecoderSentinel,\n    getUtf8Encoder,\n    getUtf8Decoder,\n} from '@solana/kit';\nconst sentinel = null as unknown as Uint8Array;\n// ---cut-before---\nconst bytes = addEncoderSentinel(getUtf8Encoder(), sentinel).encode('hello');\nconst value = addDecoderSentinel(getUtf8Decoder(), sentinel).decode(bytes);\n```\n\n### addCodecSizePrefix [!toc] [#add-codec-size-prefix]\n\nThe `addCodecSizePrefix` function allows us to store the byte size of any codec as a number prefix, enabling us to contain variable-size codecs to their actual size.\n\nWhen encoding, the size of the encoded data is stored before the encoded data itself. When decoding, the size is read first to know how many bytes to read next.\n\nFor example, say we want to represent a variable-size base-58 string using a `u32` size prefix. Here's how we can use the `addCodecSizePrefix` function to achieve that.\n\n```ts twoslash\nimport { addCodecSizePrefix, getBase58Codec, getU32Codec } from '@solana/kit';\n// ---cut-before---\nconst getU32Base58Codec = () => addCodecSizePrefix(getBase58Codec(), getU32Codec());\n\ngetU32Base58Codec().encode('hello world');\n// 0x0b00000068656c6c6f20776f726c64\n//   |       └-- Our encoded base-58 string.\n//   └-- Our encoded u32 size prefix.\n```\n\nYou may also use the `addEncoderSizePrefix` and `addDecoderSizePrefix` functions to separate your codec logic like so:\n\n```ts twoslash\nimport {\n    addEncoderSizePrefix,\n    addDecoderSizePrefix,\n    getBase58Encoder,\n    getBase58Decoder,\n    getU32Encoder,\n    getU32Decoder,\n    combineCodec,\n} from '@solana/kit';\n// ---cut-before---\nconst getU32Base58Encoder = () => addEncoderSizePrefix(getBase58Encoder(), getU32Encoder());\nconst getU32Base58Decoder = () => addDecoderSizePrefix(getBase58Decoder(), getU32Decoder());\nconst getU32Base58Codec = () => combineCodec(getU32Base58Encoder(), getU32Base58Decoder());\n```\n\n### containsBytes [!toc] [#contains-bytes]\n\nChecks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n\n```ts twoslash\nimport { containsBytes } from '@solana/kit';\n// ---cut-before---\ncontainsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\ncontainsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n```\n\n### fixBytes [!toc] [#fix-bytes]\n\nPads or truncates a `Uint8Array` so it has the specified length.\n\n```ts twoslash\nimport { fixBytes } from '@solana/kit';\n// ---cut-before---\nfixBytes(new Uint8Array([1, 2]), 4); // Uint8Array([1, 2, 0, 0])\nfixBytes(new Uint8Array([1, 2, 3, 4]), 2); // Uint8Array([1, 2])\n```\n\n### fixCodecSize [!toc] [#fix-codec-size]\n\nThe `fixCodecSize` function allows us to bind the size of a given codec to the given fixed size.\n\nFor instance, say we wanted to represent a base-58 string that uses exactly 32 bytes when decoded. Here's how we can use the `fixCodecSize` helper to achieve that.\n\n```ts twoslash\nimport { fixCodecSize, getBase58Codec } from '@solana/kit';\n// ---cut-before---\nconst get32BytesBase58Codec = () => fixCodecSize(getBase58Codec(), 32);\n```\n\nYou may also use the `fixEncoderSize` and `fixDecoderSize` functions to separate your codec logic like so:\n\n```ts twoslash\nimport {\n    fixEncoderSize,\n    fixDecoderSize,\n    getBase58Encoder,\n    getBase58Decoder,\n    combineCodec,\n} from '@solana/kit';\n// ---cut-before---\nconst get32BytesBase58Encoder = () => fixEncoderSize(getBase58Encoder(), 32);\nconst get32BytesBase58Decoder = () => fixDecoderSize(getBase58Decoder(), 32);\nconst get32BytesBase58Codec = () =>\n    combineCodec(get32BytesBase58Encoder(), get32BytesBase58Decoder());\n```\n\n### mergeBytes [!toc] [#merge-bytes]\n\nConcatenates an array of `Uint8Arrays` into a single `Uint8Array`.\n\n```ts twoslash\nimport { mergeBytes } from '@solana/kit';\n// ---cut-before---\nconst bytes1 = new Uint8Array([0x01, 0x02]);\nconst bytes2 = new Uint8Array([]);\nconst bytes3 = new Uint8Array([0x03, 0x04]);\nconst bytes = mergeBytes([bytes1, bytes2, bytes3]);\n//    ^ [0x01, 0x02, 0x03, 0x04]\n```\n\n### offsetCodec [!toc] [#offset-codec]\n\nThe `offsetCodec` function is a powerful codec primitive that allows us to move the offset of a given codec forward or backwards. It accepts one or two functions that takes the current offset and returns a new offset.\n\nTo understand how this works, let's take the following `biggerU32Codec` example which encodes a `u32` number inside an 8-byte buffer by using the [resizeCodec](#resize-codec) helper.\n\n```ts twoslash\nimport { resizeCodec, getU32Codec } from '@solana/kit';\n// ---cut-before---\nconst biggerU32Codec = resizeCodec(getU32Codec(), (size) => size + 4);\nbiggerU32Codec.encode(0xffffffff);\n// 0xffffffff00000000\n//   |       └-- Empty buffer space caused by the resizeCodec function.\n//   └-- Our encoded u32 number.\n```\n\nNow, let's say we want to move the offset of that codec 2 bytes forward so that the encoded number sits in the middle of the buffer. To achieve, this we can use the `offsetCodec` helper and provide a `preOffset` function that moves the \"pre-offset\" of the codec 2 bytes forward.\n\n```ts twoslash\nimport { offsetCodec, resizeCodec, getU32Codec } from '@solana/kit';\nconst biggerU32Codec = resizeCodec(getU32Codec(), (size) => size + 4);\n// ---cut-before---\nconst u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n    preOffset: ({ preOffset }) => preOffset + 2,\n});\nu32InTheMiddleCodec.encode(0xffffffff);\n// 0x0000ffffffff0000\n//       └-- Our encoded u32 number is now in the middle of the buffer.\n```\n\nWe refer to this offset as the \"pre-offset\" because, once the inner codec is encoded or decoded, an additional offset will be returned which we refer to as the \"post-offset\". That \"post-offset\" is important as, unless we are reaching the end of our codec, it will be used by any further codecs to continue encoding or decoding data.\n\nBy default, that \"post-offset\" is simply the addition of the \"pre-offset\" and the size of the encoded or decoded inner data.\n\n```ts twoslash\nimport { offsetCodec, resizeCodec, getU32Codec } from '@solana/kit';\nconst biggerU32Codec = resizeCodec(getU32Codec(), (size) => size + 4);\n// ---cut-before---\nconst u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n    preOffset: ({ preOffset }) => preOffset + 2,\n});\nu32InTheMiddleCodec.encode(0xffffffff);\n// 0x0000ffffffff0000\n//   |   |       └-- Post-offset.\n//   |   └-- New pre-offset: The original pre-offset + 2.\n//   └-- Pre-offset: The original pre-offset before we adjusted it.\n```\n\nHowever, you may also provide a `postOffset` function to adjust the \"post-offset\". For instance, let's push the \"post-offset\" 2 bytes forward as well such that any further codecs will start doing their job at the end of our 8-byte `u32` number.\n\n```ts twoslash\nimport { offsetCodec, resizeCodec, getU32Codec } from '@solana/kit';\nconst biggerU32Codec = resizeCodec(getU32Codec(), (size) => size + 4);\n// ---cut-before---\nconst u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n    preOffset: ({ preOffset }) => preOffset + 2,\n    postOffset: ({ postOffset }) => postOffset + 2,\n});\nu32InTheMiddleCodec.encode(0xffffffff);\n// 0x0000ffffffff0000\n//   |   |       |   └-- New post-offset: The original post-offset + 2.\n//   |   |       └-- Post-offset: The original post-offset before we adjusted it.\n//   |   └-- New pre-offset: The original pre-offset + 2.\n//   └-- Pre-offset: The original pre-offset before we adjusted it.\n```\n\nBoth the `preOffset` and `postOffset` functions offer the following attributes:\n\n- `bytes`: The entire byte array being encoded or decoded.\n- `preOffset`: The original and unaltered pre-offset.\n- `wrapBytes`: A helper function that wraps the given offset around the byte array length. E.g. `wrapBytes(-1)` will refer to the last byte of the byte array.\n\nAdditionally, the post-offset function also provides the following attributes:\n\n- `newPreOffset`: The new pre-offset after the pre-offset function has been applied.\n- `postOffset`: The original and unaltered post-offset.\n\nNote that you may also decide to ignore these attributes to achieve absolute offsets. However, relative offsets are usually recommended as they won't break your codecs when composed with other codecs.\n\n```ts twoslash\nimport { offsetCodec, resizeCodec, getU32Codec } from '@solana/kit';\nconst biggerU32Codec = resizeCodec(getU32Codec(), (size) => size + 4);\n// ---cut-before---\nconst u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n    preOffset: () => 2,\n    postOffset: () => 8,\n});\nu32InTheMiddleCodec.encode(0xffffffff);\n// 0x0000ffffffff0000\n```\n\nAlso note that any negative offset or offset that exceeds the size of the byte array will throw a `SolanaError` of code `SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE`.\n\n```ts twoslash\nimport { offsetCodec, resizeCodec, getU32Codec } from '@solana/kit';\nconst biggerU32Codec = resizeCodec(getU32Codec(), (size) => size + 4);\n// ---cut-before---\nconst u32InTheEndCodec = offsetCodec(biggerU32Codec, { preOffset: () => -4 });\nu32InTheEndCodec.encode(0xffffffff);\n// throws new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE)\n```\n\nTo avoid this, you may use the `wrapBytes` function to wrap the offset around the byte array length. For instance, here's how we can use the `wrapBytes` function to move the pre-offset 4 bytes from the end of the byte array.\n\n```ts twoslash\nimport { offsetCodec, resizeCodec, getU32Codec } from '@solana/kit';\nconst biggerU32Codec = resizeCodec(getU32Codec(), (size) => size + 4);\n// ---cut-before---\nconst u32InTheEndCodec = offsetCodec(biggerU32Codec, {\n    preOffset: ({ wrapBytes }) => wrapBytes(-4),\n});\nu32InTheEndCodec.encode(0xffffffff);\n// 0x00000000ffffffff\n```\n\nAs you can see, the `offsetCodec` helper allows you to jump all over the place with your codecs. This non-linear approach to encoding and decoding data allows you to achieve complex serialization strategies that would otherwise be impossible.\n\nThe `offsetEncoder` and `offsetDecoder` functions can also be used to split your codec logic into tree-shakeable functions.\n\n```ts twoslash\nimport {\n    offsetEncoder,\n    resizeEncoder,\n    getU32Encoder,\n    offsetDecoder,\n    resizeDecoder,\n    getU32Decoder,\n    combineCodec,\n} from '@solana/kit';\nconst biggerU32Encoder = resizeEncoder(getU32Encoder(), (size) => size + 4);\nconst biggerU32Decoder = resizeDecoder(getU32Decoder(), (size) => size + 4);\n// ---cut-before---\nconst getU32InTheMiddleEncoder = () =>\n    offsetEncoder(biggerU32Encoder, { preOffset: ({ preOffset }) => preOffset + 2 });\nconst getU32InTheMiddleDecoder = () =>\n    offsetDecoder(biggerU32Decoder, { preOffset: ({ preOffset }) => preOffset + 2 });\nconst getU32InTheMiddleCodec = () =>\n    combineCodec(getU32InTheMiddleEncoder(), getU32InTheMiddleDecoder());\n```\n\n### padBytes [!toc] [#pad-bytes]\n\nPads a `Uint8Array` with zeroes (to the right) to the specified length.\n\n```ts twoslash\nimport { padBytes } from '@solana/kit';\n// ---cut-before---\npadBytes(new Uint8Array([1, 2]), 4); // Uint8Array([1, 2, 0, 0])\npadBytes(new Uint8Array([1, 2, 3, 4]), 2); // Uint8Array([1, 2, 3, 4])\n```\n\n### padLeftCodec [!toc] [#pad-left-codec]\n\nThe `padLeftCodec` helper can be used to add padding to the left of a given codec. It accepts an `offset` number that tells us how big the padding should be.\n\n```ts twoslash\nimport { padLeftCodec, getU16Codec } from '@solana/kit';\n// ---cut-before---\nconst leftPaddedCodec = padLeftCodec(getU16Codec(), 4);\nleftPaddedCodec.encode(0xffff);\n// 0x00000000ffff\n//   |       └-- Our encoded u16 number.\n//   └-- Our 4-byte padding.\n```\n\nNote that the `padLeftCodec` function is a simple wrapper around the `offsetCodec` and `resizeCodec` functions. For more complex padding strategies, you may want to use the [offsetCodec](#offset-codec) and [resizeCodec](#resize-codec) functions directly instead.\n\nEncoder-only and decoder-only helpers are available for these padding functions.\n\n```ts twoslash\nimport {\n    padLeftEncoder,\n    padLeftDecoder,\n    getU16Encoder,\n    getU16Decoder,\n    combineCodec,\n} from '@solana/kit';\n// ---cut-before---\nconst getMyPaddedEncoder = () => padLeftEncoder(getU16Encoder(), 6);\nconst getMyPaddedDecoder = () => padLeftDecoder(getU16Decoder(), 6);\nconst getMyPaddedCodec = () => combineCodec(getMyPaddedEncoder(), getMyPaddedDecoder());\n```\n\n### padRightCodec [!toc] [#pad-right-codec]\n\nThe `padRightCodec` helper can be used to add padding to the right of a given codec. It accepts an `offset` number that tells us how big the padding should be.\n\n```ts twoslash\nimport { padRightCodec, getU16Codec } from '@solana/kit';\n// ---cut-before---\nconst rightPaddedCodec = padRightCodec(getU16Codec(), 4);\nrightPaddedCodec.encode(0xffff);\n// 0xffff00000000\n//   |   └-- Our 4-byte padding.\n//   └-- Our encoded u16 number.\n```\n\nNote that the `padRightCodec` function is a simple wrapper around the `offsetCodec` and `resizeCodec` functions. For more complex padding strategies, you may want to use the [offsetCodec](#offset-codec) and [resizeCodec](#resize-codec) functions directly instead.\n\nEncoder-only and decoder-only helpers are available for these padding functions.\n\n```ts twoslash\nimport {\n    padRightEncoder,\n    padRightDecoder,\n    getU16Encoder,\n    getU16Decoder,\n    combineCodec,\n} from '@solana/kit';\n// ---cut-before---\nconst getMyPaddedEncoder = () => padRightEncoder(getU16Encoder(), 6);\nconst getMyPaddedDecoder = () => padRightDecoder(getU16Decoder(), 6);\nconst getMyPaddedCodec = () => combineCodec(getMyPaddedEncoder(), getMyPaddedDecoder());\n```\n\n### resizeCodec [!toc] [#resize-codec]\n\nThe `resizeCodec` helper re-defines the size of a given codec by accepting a function that takes the current size of the codec and returns a new size. This works for both fixed-size and variable-size codecs.\n\n```ts twoslash\nimport { resizeCodec, getU32Codec, getUtf8Codec } from '@solana/kit';\n// ---cut-before---\n// Fixed-size codec.\nconst getBiggerU32Codec = () => resizeCodec(getU32Codec(), (size) => size + 4);\ngetBiggerU32Codec().encode(42);\n// 0x2a00000000000000\n//   |       └-- Empty buffer space caused by the resizeCodec function.\n//   └-- Our encoded u32 number.\n\n// Variable-size codec.\nconst getBiggerUtf8Codec = () => resizeCodec(getUtf8Codec(), (size) => size + 4);\ngetBiggerUtf8Codec().encode('ABC');\n// 0x41424300000000\n//   |     └-- Empty buffer space caused by the resizeCodec function.\n//   └-- Our encoded string.\n```\n\nNote that the `resizeCodec` function doesn't change any encoded or decoded bytes, it merely tells the `encode` and `decode` functions how big the `Uint8Array` should be before delegating to their respective `write` and `read` functions. In fact, this is completely bypassed when using the `write` and `read` functions directly. For instance:\n\n```ts twoslash\nimport { resizeCodec, getU32Codec } from '@solana/kit';\n// ---cut-before---\nconst getBiggerU32Codec = () => resizeCodec(getU32Codec(), (size) => size + 4);\n\n// Using the encode function.\ngetBiggerU32Codec().encode(42);\n// 0x2a00000000000000\n\n// Using the lower-level write function.\nconst myCustomBytes = new Uint8Array(4);\ngetBiggerU32Codec().write(42, myCustomBytes, 0);\n// 0x2a000000\n```\n\nSo when would it make sense to use the `resizeCodec` function? This function is particularly useful when combined with the [offsetCodec](#offset-codec) function. Whilst `offsetCodec` may help us push the offset forward — e.g. to skip some padding — it won't change the size of the encoded data which means the last bytes will be truncated by how much we pushed the offset forward. The `resizeCodec` function can be used to fix that. For instance, here's how we can use the `resizeCodec` and the `offsetCodec` functions together to create a struct codec that includes some padding.\n\n```ts twoslash\nimport {\n    getStructCodec,\n    getUtf8Codec,\n    getU32Codec,\n    offsetCodec,\n    resizeCodec,\n    fixCodecSize,\n} from '@solana/kit';\n// ---cut-before---\nconst personCodec = getStructCodec([\n    ['name', fixCodecSize(getUtf8Codec(), 8)],\n    // There is a 4-byte padding between name and age.\n    [\n        'age',\n        offsetCodec(\n            resizeCodec(getU32Codec(), (size) => size + 4),\n            { preOffset: ({ preOffset }) => preOffset + 4 },\n        ),\n    ],\n]);\n\npersonCodec.encode({ name: 'Alice', age: 42 });\n// 0x416c696365000000000000002a000000\n//   |               |       └-- Our encoded u32 (42).\n//   |               └-- The 4-bytes of padding we are skipping.\n//   └-- Our 8-byte encoded string (\"Alice\").\n```\n\nNote that this can be achieved using the [padLeftCodec](#pad-left-codec) helper which is implemented that way.\n\nThe `resizeEncoder` and `resizeDecoder` functions can also be used to split your codec logic into tree-shakeable functions.\n\n```ts twoslash\nimport {\n    resizeEncoder,\n    resizeDecoder,\n    getU32Encoder,\n    getU32Decoder,\n    combineCodec,\n} from '@solana/kit';\n// ---cut-before---\nconst getBiggerU32Encoder = () => resizeEncoder(getU32Encoder(), (size) => size + 4);\nconst getBiggerU32Decoder = () => resizeDecoder(getU32Decoder(), (size) => size + 4);\nconst getBiggerU32Codec = () => combineCodec(getBiggerU32Encoder(), getBiggerU32Decoder());\n```\n\n### reverseCodec [!toc] [#reverse-codec]\n\nThe `reverseCodec` helper reverses the bytes of the provided `FixedSizeCodec`.\n\n```ts twoslash\nimport { reverseCodec, getU64Codec } from '@solana/kit';\n// ---cut-before---\nconst getBigEndianU64Codec = () => reverseCodec(getU64Codec());\n```\n\nNote that number codecs can already do that for you via their `endian` option.\n\n```ts twoslash\nimport { getU64Codec, Endian } from '@solana/kit';\n// ---cut-before---\nconst getBigEndianU64Codec = () => getU64Codec({ endian: Endian.Big });\n```\n\nThe `reverseEncoder` and `reverseDecoder` functions can also be used to achieve that.\n\n```ts twoslash\nimport {\n    reverseEncoder,\n    reverseDecoder,\n    getU64Encoder,\n    getU64Decoder,\n    combineCodec,\n} from '@solana/kit';\n// ---cut-before---\nconst getBigEndianU64Encoder = () => reverseEncoder(getU64Encoder());\nconst getBigEndianU64Decoder = () => reverseDecoder(getU64Decoder());\nconst getBigEndianU64Codec = () => combineCodec(getBigEndianU64Encoder(), getBigEndianU64Decoder());\n```\n\n### transformCodec [!toc] [#transform-codec]\n\nIt is possible to transform a `Codec<T>` to a `Codec<U>` by providing two mapping functions: one that goes from `T` to `U` and one that does the opposite.\n\nFor instance, here's how you would map a `u32` integer into a `string` representation of that number.\n\n```ts twoslash\nimport { transformCodec, getU32Codec } from '@solana/kit';\n// ---cut-before---\nconst getStringU32Codec = () =>\n    transformCodec(\n        getU32Codec(),\n        (integerAsString: string): number => parseInt(integerAsString),\n        (integer: number): string => integer.toString(),\n    );\n\ngetStringU32Codec().encode('42'); // new Uint8Array([42])\ngetStringU32Codec().decode(new Uint8Array([42])); // \"42\"\n```\n\nIf a `Codec` has [different From and To types](#different-from-and-to-types), say `Codec<OldFrom, OldTo>`, and we want to map it to `Codec<NewFrom, NewTo>`, we must provide functions that map from `NewFrom` to `OldFrom` and from `OldTo` to `NewTo`.\n\nTo illustrate that, let's take our previous `getStringU32Codec` example but make it use a `getU64Codec` codec instead as it returns a `Codec<number | bigint, bigint>`. Additionally, let's make it so our `getStringU64Codec` function returns a `Codec<number | string, string>` so that it also accepts numbers when encoding values. Here's what our mapping functions look like:\n\n```ts twoslash\nimport { transformCodec, getU64Codec } from '@solana/kit';\n// ---cut-before---\nconst getStringU64Codec = () =>\n    transformCodec(\n        getU64Codec(),\n        (integerInput: number | string): number | bigint =>\n            typeof integerInput === 'string' ? BigInt(integerInput) : integerInput,\n        (integer: bigint): string => integer.toString(),\n    );\n```\n\nNote that the second function that maps the decoded type is optional. That means, you can omit it to simply update or loosen the type to encode whilst keeping the decoded type the same.\n\nThis is particularly useful to provide default values to object structures. For instance, here's how we can map a `Person` codec to give a default value to its `age` attribute.\n\n```ts twoslash\nimport { transformCodec, getStructCodec, Codec } from '@solana/kit';\n// ---cut-before---\ntype Person = { name: string; age: number };\ntype PersonInput = { name: string; age?: number };\n// ---cut-start---\nconst getPersonCodec = null as unknown as () => Codec<Person>;\n// ---cut-end---\nconst getPersonWithDefaultValueCodec = (): Codec<PersonInput, Person> =>\n    transformCodec(\n        getPersonCodec(),\n        (person: PersonInput): Person => ({ ...person, age: person.age ?? 42 }),\n    );\n```\n\nSimilar helpers exist to map `Encoder` and `Decoder` instances allowing you to separate your codec logic into tree-shakeable functions. Here's our `getStringU32Codec` written that way.\n\n```ts twoslash\nimport {\n    transformEncoder,\n    transformDecoder,\n    getU32Encoder,\n    getU32Decoder,\n    combineCodec,\n} from '@solana/kit';\n// ---cut-before---\nconst getStringU32Encoder = () =>\n    transformEncoder(getU32Encoder(), (integerAsString: string): number =>\n        parseInt(integerAsString),\n    );\nconst getStringU32Decoder = () =>\n    transformDecoder(getU32Decoder(), (integer: number): string => integer.toString());\nconst getStringU32Codec = () => combineCodec(getStringU32Encoder(), getStringU32Decoder());\n```\n\n## Numbers listing [!toc]\n\n### getI8Codec [!toc] [#get-i8-codec]\n\nEncodes and decodes **signed 8-bit integers**. It supports values from -127 (`-2^7`) to 128 (`2^7 - 1`).\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`.\n\n```ts twoslash\nimport { getI8Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getI8Codec();\nconst bytes = codec.encode(-42); // 0xd6\nconst value = codec.decode(bytes); // -42\n```\n\n`getI8Encoder` and `getI8Decoder` functions are also available.\n\n### getI16Codec [!toc] [#get-i16-codec]\n\nEncodes and decodes **signed 16-bit integers**. It supports values from -32,768 (`-2^15`) to 32,767 (`2^15 - 1`).\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getI16Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getI16Codec();\nconst bytes = codec.encode(-42); // 0xd6ff\nconst value = codec.decode(bytes); // -42\n\n// Big-endian.\nconst beCodec = getI16Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(-42); // 0xffd6\nconst beValue = beCodec.decode(bytes); // -42\n```\n\n`getI16Encoder` and `getI16Decoder` functions are also available.\n\n### getI32Codec [!toc] [#get-i32-codec]\n\nEncodes and decodes **signed 32-bit integers**. It supports values from -2,147,483,648 (`-2^31`) to 2,147,483,647 (`2^31 - 1`).\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getI32Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getI32Codec();\nconst bytes = codec.encode(-42); // 0xd6ffffff\nconst value = codec.decode(bytes); // -42\n\n// Big-endian.\nconst beCodec = getI32Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(-42); // 0xffffffd6\nconst beValue = beCodec.decode(bytes); // -42\n```\n\n`getI32Encoder` and `getI32Decoder` functions are also available.\n\n### getI64Codec [!toc] [#get-i64-codec]\n\nEncodes and decodes **signed 64-bit integers**. It supports values from `-2^63` to `2^63 - 1`.\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getI64Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getI64Codec();\nconst bytes = codec.encode(-42); // 0xd6ffffffffffffff\nconst value = codec.decode(bytes); // BigInt(-42)\n\n// Big-endian.\nconst beCodec = getI64Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(-42); // 0xffffffffffffffd6\nconst beValue = beCodec.decode(bytes); // BigInt(-42)\n```\n\n`getI64Encoder` and `getI64Decoder` functions are also available.\n\n### getI128Codec [!toc] [#get-i128-codec]\n\nEncodes and decodes **signed 128-bit integers**. It supports values from `-2^127` to `2^127 - 1`.\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getI128Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getI128Codec();\nconst bytes = codec.encode(-42); // 0xd6ffffffffffffffffffffffffffffff\nconst value = codec.decode(bytes); // BigInt(-42)\n\n// Big-endian.\nconst beCodec = getI128Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(-42); // 0xffffffffffffffffffffffffffffffd6\nconst beValue = beCodec.decode(bytes); // BigInt(-42)\n```\n\n`getI128Encoder` and `getI128Decoder` functions are also available.\n\n### getF32Codec [!toc] [#get-f32-codec]\n\nEncodes and decodes **32-bit floating-point numbers**. Due to the [IEEE 754](https://en.wikipedia.org/wiki/Single-precision_floating-point_format) floating-point representation, some precision loss may occur.\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getF32Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getF32Codec();\nconst bytes = codec.encode(-1.5); // 0x0000c0bf\nconst value = codec.decode(bytes); // -1.5\n\n// Big-endian.\nconst beCodec = getF32Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(-1.5); // 0xbfc00000\nconst beValue = beCodec.decode(bytes); // -1.5\n```\n\n`getF32Encoder` and `getF32Decoder` functions are also available.\n\n### getF64Codec [!toc] [#get-f64-codec]\n\nEncodes and decodes **64-bit floating-point numbers**. Due to the [IEEE 754](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) floating-point representation, some precision loss may occur.\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getF64Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getF64Codec();\nconst bytes = codec.encode(-1.5); // 0x000000000000f8bf\nconst value = codec.decode(bytes); // -1.5\n\n// Big-endian.\nconst beCodec = getF64Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(-1.5); // 0xbff8000000000000\nconst beValue = beCodec.decode(bytes); // -1.5\n```\n\n`getF64Encoder` and `getF64Decoder` functions are also available.\n\n### getShortU16Codec [!toc] [#get-short-u16-codec]\n\nEncodes and decodes **unsigned integer using 1 to 3 bytes** based on the encoded value. It supports values from 0 to 4,194,303 (`2^22 - 1`).\n\nThe larger the value, the more bytes it uses.\n\n- If the value is `<= 0x7f` (127), it is stored in a **single byte** and the first bit is set to `0` to indicate the end of the value.\n- Otherwise, the first bit is set to `1` to indicate that the value continues in the next byte, which follows the same pattern.\n- This process repeats until the value is fully encoded in up to 3 bytes. The third and last byte, if needed, uses all 8 bits to store the remaining value.\n\nIn other words, the encoding scheme follows this structure:\n\n```txt\n0XXXXXXX                   <- Values 0 to 127 (1 byte)\n1XXXXXXX 0XXXXXXX          <- Values 128 to 16,383 (2 bytes)\n1XXXXXXX 1XXXXXXX XXXXXXXX <- Values 16,384 to 4,194,303 (3 bytes)\n```\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`.\n\n```ts twoslash\nimport { getShortU16Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getShortU16Codec();\nconst bytes1 = codec.encode(42); // 0x2a\nconst bytes2 = codec.encode(128); // 0x8001\nconst bytes3 = codec.encode(16384); // 0x808001\n\ncodec.decode(bytes1); // 42\ncodec.decode(bytes2); // 128\ncodec.decode(bytes3); // 16384\n```\n\n`getShortU16Encoder` and `getShortU16Decoder` functions are also available.\n\n### getU8Codec [!toc] [#get-u8-codec]\n\nEncodes and decodes **unsigned 8-bit integers**. It supports values from 0 to 255 (`2^8 - 1`).\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`.\n\n```ts twoslash\nimport { getU8Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getU8Codec();\nconst bytes = codec.encode(42); // 0x2a\nconst value = codec.decode(bytes); // 42\n```\n\n`getU8Encoder` and `getU8Decoder` functions are also available.\n\n### getU16Codec [!toc] [#get-u16-codec]\n\nEncodes and decodes **unsigned 16-bit integers**. It supports values from 0 to 65,535 (`2^16 - 1`).\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getU16Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getU16Codec();\nconst bytes = codec.encode(42); // 0x2a00\nconst value = codec.decode(bytes); // 42\n\n// Big-endian.\nconst beCodec = getU16Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(42); // 0x002a\nconst beValue = beCodec.decode(bytes); // 42\n```\n\n`getU16Encoder` and `getU16Decoder` functions are also available.\n\n### getU32Codec [!toc] [#get-u32-codec]\n\nEncodes and decodes **unsigned 32-bit integers**. It supports values from 0 to 4,294,967,295 (`2^32 - 1`).\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `number`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getU32Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getU32Codec();\nconst bytes = codec.encode(42); // 0x2a000000\nconst value = codec.decode(bytes); // 42\n\n// Big-endian.\nconst beCodec = getU32Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(42); // 0x0000002a\nconst beValue = beCodec.decode(bytes); // 42\n```\n\n`getU32Encoder` and `getU32Decoder` functions are also available.\n\n### getU64Codec [!toc] [#get-u64-codec]\n\nEncodes and decodes **unsigned 64-bit integers**. It supports values from 0 to `2^64 - 1`.\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getU64Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getU64Codec();\nconst bytes = codec.encode(42); // 0x2a00000000000000\nconst value = codec.decode(bytes); // 42\n\n// Big-endian.\nconst beCodec = getU64Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(42); // 0x000000000000002a\nconst beValue = beCodec.decode(bytes); // 42\n```\n\n`getU64Encoder` and `getU64Decoder` functions are also available.\n\n### getU128Codec [!toc] [#get-u128-codec]\n\nEncodes and decodes **unsigned 128-bit integers**. It supports values from 0 to `2^128 - 1`.\n\nValues can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`. Endianness can be specified using the `endian` option. The default is `Endian.Little`.\n\n```ts twoslash\nimport { getU128Codec, Endian } from '@solana/kit';\n// ---cut-before---\n// Little-endian.\nconst codec = getU128Codec();\nconst bytes = codec.encode(42); // 0x2a000000000000000000000000000000\nconst value = codec.decode(bytes); // 42\n\n// Big-endian.\nconst beCodec = getU128Codec({ endian: Endian.Big });\nconst beBytes = beCodec.encode(42); // 0x0000000000000000000000000000002a\nconst beValue = beCodec.decode(bytes); // 42\n```\n\n`getU128Encoder` and `getU128Decoder` functions are also available.\n\n## Strings listing [!toc]\n\n### getBase10Codec [!toc] [#get-base10-codec]\n\nEncodes and decodes **Base 10 strings**.\n\n```ts twoslash\nimport { getBase10Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getBase10Codec();\nconst bytes = codec.encode('1024'); // 0x0400\nconst value = codec.decode(bytes); // \"1024\"\n```\n\nThis codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string. To add size constraints to your codec, you may use utility functions such as [`fixCodecSize`](#fix-codec-size), [`addCodecSizePrefix`](#add-codec-size-prefix) or [`addCodecSentinel`](#add-codec-sentinel).\n\n```ts twoslash\nimport {\n    getBase10Codec,\n    fixCodecSize,\n    addCodecSizePrefix,\n    getU32Codec,\n    addCodecSentinel,\n} from '@solana/kit';\n// ---cut-before---\nfixCodecSize(getBase10Codec(), 4).encode('1024');\n// 0x04000000 (padded to 4 bytes)\n\naddCodecSizePrefix(getBase10Codec(), getU32Codec()).encode('1024');\n// 0x020000000400\n//   |       └-- The 2 bytes of content.\n//   └-- 4-byte prefix telling us to read 2 bytes.\n\naddCodecSentinel(getBase10Codec(), new Uint8Array([0xff, 0xff])).encode('1024');\n// 0x0400ffff\n//   |   └-- The sentinel signaling the end of the content.\n//   └-- The 2 bytes of content.\n```\n\n`getBase10Encoder` and `getBase10Decoder` functions are also available.\n\n### getBase16Codec [!toc] [#get-base16-codec]\n\nEncodes and decodes **Base 16 strings**.\n\n```ts twoslash\nimport { getBase16Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getBase16Codec();\nconst bytes = codec.encode('deadface'); // 0xdeadface\nconst value = codec.decode(bytes); // \"deadface\"\n```\n\nThis codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string. To add size constraints to your codec, you may use utility functions such as [`fixCodecSize`](#fix-codec-size), [`addCodecSizePrefix`](#add-codec-size-prefix) or [`addCodecSentinel`](#add-codec-sentinel).\n\n```ts twoslash\nimport {\n    getBase16Codec,\n    fixCodecSize,\n    addCodecSizePrefix,\n    getU32Codec,\n    addCodecSentinel,\n} from '@solana/kit';\n// ---cut-before---\nfixCodecSize(getBase16Codec(), 2).encode('deadface');\n// 0xdead (truncated to 2 bytes)\n\naddCodecSizePrefix(getBase16Codec(), getU32Codec()).encode('deadface');\n// 0x04000000deadface\n//   |       └-- The 4 bytes of content.\n//   └-- 4-byte prefix telling us to read 4 bytes.\n\naddCodecSentinel(getBase16Codec(), new Uint8Array([0xff, 0xff])).encode('deadface');\n// 0xdeadfaceffff\n//   |       └-- The sentinel signaling the end of the content.\n//   └-- The 4 bytes of content.\n```\n\n`getBase16Encoder` and `getBase16Decoder` functions are also available.\n\n### getBase58Codec [!toc] [#get-base58-codec]\n\nEncodes and decodes **Base 58 strings**.\n\n```ts twoslash\nimport { getBase58Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getBase58Codec();\nconst bytes = codec.encode('heLLo'); // 0x1b6a3070\nconst value = codec.decode(bytes); // \"heLLo\"\n```\n\nThis codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string. To add size constraints to your codec, you may use utility functions such as [`fixCodecSize`](#fix-codec-size), [`addCodecSizePrefix`](#add-codec-size-prefix) or [`addCodecSentinel`](#add-codec-sentinel).\n\n```ts twoslash\nimport {\n    getBase58Codec,\n    fixCodecSize,\n    addCodecSizePrefix,\n    getU32Codec,\n    addCodecSentinel,\n} from '@solana/kit';\n// ---cut-before---\nfixCodecSize(getBase58Codec(), 2).encode('heLLo');\n// 0x1b6a (truncated to 2 bytes)\n\naddCodecSizePrefix(getBase58Codec(), getU32Codec()).encode('heLLo');\n// 0x040000001b6a3070\n//   |       └-- The 4 bytes of content.\n//   └-- 4-byte prefix telling us to read 4 bytes.\n\naddCodecSentinel(getBase58Codec(), new Uint8Array([0xff, 0xff])).encode('heLLo');\n// 0x1b6a3070ffff\n//   |       └-- The sentinel signaling the end of the content.\n//   └-- The 4 bytes of content.\n```\n\n`getBase58Encoder` and `getBase58Decoder` functions are also available.\n\n### getBase64Codec [!toc] [#get-base64-codec]\n\nEncodes and decodes **Base 64 strings**.\n\n```ts twoslash\nimport { getBase64Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getBase64Codec();\nconst bytes = codec.encode('hello+world'); // 0x85e965a3ec28ae57\nconst value = codec.decode(bytes); // \"hello+world\"\n```\n\nThis codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string. To add size constraints to your codec, you may use utility functions such as [`fixCodecSize`](#fix-codec-size), [`addCodecSizePrefix`](#add-codec-size-prefix) or [`addCodecSentinel`](#add-codec-sentinel).\n\n```ts twoslash\nimport {\n    getBase64Codec,\n    fixCodecSize,\n    addCodecSizePrefix,\n    getU32Codec,\n    addCodecSentinel,\n} from '@solana/kit';\n// ---cut-before---\nfixCodecSize(getBase64Codec(), 4).encode('hello+world');\n// 0x85e965a3 (truncated to 4 bytes)\n\naddCodecSizePrefix(getBase64Codec(), getU32Codec()).encode('hello+world');\n// 0x0400000085e965a3ec28ae57\n//   |       └-- The 8 bytes of content.\n//   └-- 4-byte prefix telling us to read 8 bytes.\n\naddCodecSentinel(getBase64Codec(), new Uint8Array([0xff, 0xff])).encode('hello+world');\n// 0x85e965a3ec28ae57ffff\n//   |               └-- The sentinel signaling the end of the content.\n//   └-- The 8 bytes of content.\n```\n\n`getBase64Encoder` and `getBase64Decoder` functions are also available.\n\n### getBaseXCodec [!toc] [#get-baseX-codec]\n\nThe `getBaseXCodec` accepts a custom `alphabet` of `X` characters and **creates a base-X codec using that alphabet**. It does so by iteratively dividing by `X` and handling leading zeros.\n\n```ts twoslash\nimport { getBaseXCodec } from '@solana/kit';\n// ---cut-before---\nconst codec = getBaseXCodec('0ehlo');\nconst bytes = codec.encode('hello'); // 0x05bd\nconst value = codec.decode(bytes); // \"hello\"\n```\n\nThis codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string. To add size constraints to your codec, you may use utility functions such as [`fixCodecSize`](#fix-codec-size), [`addCodecSizePrefix`](#add-codec-size-prefix) or [`addCodecSentinel`](#add-codec-sentinel).\n\n```ts twoslash\nimport {\n    getBaseXCodec,\n    fixCodecSize,\n    addCodecSizePrefix,\n    getU32Codec,\n    addCodecSentinel,\n} from '@solana/kit';\n// ---cut-before---\nconst codec = getBaseXCodec('0ehlo');\n\nfixCodecSize(codec, 4).encode('hello');\n// 0x05bd0000 (padded to 4 bytes)\n\naddCodecSizePrefix(codec, getU32Codec()).encode('hello');\n// 0x0200000005bd\n//   |       └-- The 2 bytes of content.\n//   └-- 4-byte prefix telling us to read 2 bytes.\n\naddCodecSentinel(codec, new Uint8Array([0xff, 0xff])).encode('hello');\n// 0x05bdffff\n//   |   └-- The sentinel signaling the end of the content.\n//   └-- The 2 bytes of content.\n```\n\n`getBaseXEncoder` and `getBaseXDecoder` functions are also available.\n\n### getBaseXResliceCodec [!toc] [#get-baseX-reslice-codec]\n\nThe `getBaseXResliceCodec` accepts a custom `alphabet` of `X` characters and **creates a base-X codec using that alphabet**.\n\nIt does so by re-slicing bytes into custom chunks of bits that are then mapped to the provided `alphabet`. The number of bits per chunk is also provided as the second argument and should typically be set to `log2(alphabet.length)`.\n\nThis is typically used to create codecs whose alphabet's length is a power of 2 such as base-16 or base-64.\n\n```ts twoslash\nimport { getBaseXResliceCodec } from '@solana/kit';\n// ---cut-before---\nconst codec = getBaseXResliceCodec('elho', 2);\nconst bytes = codec.encode('hellolol'); // 0x4aee\nconst value = codec.decode(bytes); // \"hellolol\"\n```\n\nThis codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string. To add size constraints to your codec, you may use utility functions such as [`fixCodecSize`](#fix-codec-size), [`addCodecSizePrefix`](#add-codec-size-prefix) or [`addCodecSentinel`](#add-codec-sentinel).\n\n```ts twoslash\nimport {\n    getBaseXResliceCodec,\n    fixCodecSize,\n    addCodecSizePrefix,\n    getU32Codec,\n    addCodecSentinel,\n} from '@solana/kit';\n// ---cut-before---\nconst codec = getBaseXResliceCodec('elho', 2);\n\nfixCodecSize(codec, 4).encode('hellolol');\n// 0x4aee0000 (padded to 4 bytes)\n\naddCodecSizePrefix(codec, getU32Codec()).encode('hellolol');\n// 0x020000004aee\n//   |       └-- The 2 bytes of content.\n//   └-- 4-byte prefix telling us to read 2 bytes.\n\naddCodecSentinel(codec, new Uint8Array([0xff, 0xff])).encode('hellolol');\n// 0x4aeeffff\n//   |   └-- The sentinel signaling the end of the content.\n//   └-- The 2 bytes of content.\n```\n\n`getBaseXResliceEncoder` and `getBaseXResliceDecoder` functions are also available.\n\n### getUtf8Codec [!toc] [#get-utf8-codec]\n\nEncodes and decodes **UTF-8 strings**.\n\n```ts twoslash\nimport { getUtf8Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getUtf8Codec();\nconst bytes = codec.encode('hello'); // 0x68656c6c6f\nconst value = codec.decode(bytes); // \"hello\"\n```\n\nThis codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string. To add size constraints to your codec, you may use utility functions such as [`fixCodecSize`](#fix-codec-size), [`addCodecSizePrefix`](#add-codec-size-prefix) or [`addCodecSentinel`](#add-codec-sentinel).\n\n```ts twoslash\nimport {\n    getUtf8Codec,\n    fixCodecSize,\n    addCodecSizePrefix,\n    getU32Codec,\n    addCodecSentinel,\n} from '@solana/kit';\n// ---cut-before---\nfixCodecSize(getUtf8Codec(), 4).encode('hello');\n// 0x68656c6c (truncated to 4 bytes)\n\naddCodecSizePrefix(getUtf8Codec(), getU32Codec()).encode('hello');\n// 0x0500000068656c6c6f\n//   |       └-- The 5 bytes of content.\n//   └-- 4-byte prefix telling us to read 5 bytes.\n\naddCodecSentinel(getUtf8Codec(), new Uint8Array([0xff, 0xff])).encode('hello');\n// 0x68656c6c6fffff\n//   |         └-- The sentinel signaling the end of the content.\n//   └-- The 5 bytes of content.\n```\n\n`getUtf8Encoder` and `getUtf8Decoder` functions are also available.\n\n## Data structures listing [!toc]\n\n### getArrayCodec [!toc] [#get-array-codec]\n\nThe `getArrayCodec` function accepts any codec of type `T` and returns a codec of type `Array<T>`.\n\n```ts twoslash\nimport { getArrayCodec, getU8Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getArrayCodec(getU8Codec());\nconst bytes = codec.encode([1, 2, 3]); // 0x03000000010203\nconst array = codec.decode(bytes); // [1, 2, 3]\n```\n\nBy default, the size of the array is stored as a `u32` prefix before encoding the items.\n\n```ts twoslash\nimport { getArrayCodec, getU8Codec } from '@solana/kit';\n// ---cut-before---\ngetArrayCodec(getU8Codec()).encode([1, 2, 3]);\n// 0x03000000010203\n//   |       └-- 3 items of 1 byte each.\n//   └-- 4-byte prefix telling us to read 3 items.\n```\n\nHowever, you may use the `size` option to configure this behaviour. It can be one of the following three strategies:\n\n- `Codec<number>`: When a number codec is provided, that codec will be used to encode and decode the size prefix.\n- `number`: When a number is provided, the codec will expect a fixed number of items in the array. An error will be thrown when trying to encode an array of a different length.\n- `\"remainder\"`: When the string `\"remainder\"` is passed as a size, the codec will use the remainder of the bytes to encode/decode its items. This means the size is not stored or known in advance but simply inferred from the rest of the buffer. For instance, if we have an array of `u16` numbers and 10 bytes remaining, we know there are 5 items in this array.\n\n```ts twoslash\nimport { getArrayCodec, getU8Codec, getU16Codec } from '@solana/kit';\n// ---cut-before---\ngetArrayCodec(getU8Codec(), { size: getU16Codec() }).encode([1, 2, 3]);\n// 0x0300010203\n//   |   └-- 3 items of 1 byte each.\n//   └-- 2-byte prefix telling us to read 3 items.\n\ngetArrayCodec(getU8Codec(), { size: 3 }).encode([1, 2, 3]);\n// 0x010203\n//   └-- 3 items of 1 byte each. There must always be 3 items in the array.\n\ngetArrayCodec(getU8Codec(), { size: 'remainder' }).encode([1, 2, 3]);\n// 0x010203\n//   └-- 3 items of 1 byte each. The size is inferred from the remainder of the bytes.\n```\n\n`getArrayEncoder` and `getArrayDecoder` functions are also available.\n\n### getBitArrayCodec [!toc] [#get-bit-array-codec]\n\nThe `getBitArrayCodec` function returns a codec that encodes and decodes an array of booleans such that each boolean is represented by a single bit. It requires the size of the codec in bytes and an optional `backward` flag that can be used to reverse the order of the bits.\n\n```ts twoslash\nimport { getBitArrayCodec } from '@solana/kit';\n// ---cut-before---\nconst booleans = [true, false, true, false, true, false, true, false];\n\ngetBitArrayCodec(1).encode(booleans);\n// 0xaa or 0b10101010\n\ngetBitArrayCodec(1, { backward: true }).encode(booleans);\n// 0x55 or 0b01010101\n```\n\n`getBitArrayEncoder` and `getBitArrayDecoder` functions are also available.\n\n### getBooleanCodec [!toc] [#get-boolean-codec]\n\nThe `getBooleanCodec` function returns a `Codec<boolean>` that stores the boolean as `0` or `1` using a `u8` number by default.\n\n```ts twoslash\nimport { getBooleanCodec } from '@solana/kit';\n// ---cut-before---\nconst codec = getBooleanCodec();\nconst bytes = codec.encode(true); // 0x01\nconst value = codec.decode(bytes); // true\n```\n\nYou may configure that behaviour by providing an explicit number codec as the `size` option of the `getBooleanCodec` function. That number codec will then be used to encode and decode the values `0` and `1` accordingly.\n\n```ts twoslash\nimport { getBooleanCodec, getU16Codec, getU32Codec } from '@solana/kit';\n// ---cut-before---\ngetBooleanCodec({ size: getU16Codec() }).encode(false); // 0x0000\ngetBooleanCodec({ size: getU16Codec() }).encode(true); // 0x0100\n\ngetBooleanCodec({ size: getU32Codec() }).encode(false); // 0x00000000\ngetBooleanCodec({ size: getU32Codec() }).encode(true); // 0x01000000\n```\n\n`getBooleanEncoder` and `getBooleanDecoder` functions are also available.\n\n### getBytesCodec [!toc] [#get-bytes-codec]\n\nThe `getBytesCodec` function returns a `Codec<Uint8Array>` meaning it converts `Uint8Arrays` to and from… `Uint8Arrays`! Whilst this might seem a bit useless, it can be useful when composed into other codecs. For example, you could use it in a struct codec to say that a particular field should be left unserialised.\n\n```ts twoslash\nimport { getBytesCodec } from '@solana/kit';\n// ---cut-before---\nconst codec = getBytesCodec();\nconst bytes = codec.encode(new Uint8Array([42])); // 0x2a\nconst value = codec.decode(bytes); // 0x2a\n```\n\nThe `getBytesCodec` function will encode and decode `Uint8Arrays` using as many bytes as necessary. If you'd like to restrict the number of bytes used by this codec, you may combine it with utilities such as [`fixCodecSize`](#fix-codec-size), [`addCodecSizePrefix`](#add-codec-size-prefix) or [`addCodecSentinel`](#add-codec-sentinel).\n\n```ts twoslash\nimport {\n    getBytesCodec,\n    fixCodecSize,\n    addCodecSizePrefix,\n    getU32Codec,\n    addCodecSentinel,\n} from '@solana/kit';\n// ---cut-before---\nconst value = new Uint8Array([42, 43]); // 0x2a2b\n\nfixCodecSize(getBytesCodec(), 4).encode(value);\n// 0x2a2b0000 (padded to 4 bytes)\n\naddCodecSizePrefix(getBytesCodec(), getU32Codec()).encode(value);\n// 0x020000002a2b\n//   |       └-- The 2 bytes of content.\n//   └-- 4-byte prefix telling us to read 2 bytes.\n\naddCodecSentinel(getBytesCodec(), new Uint8Array([0xff, 0xff])).encode(value);\n// 0x2a2bffff\n//   |   └-- The sentinel signaling the end of the content.\n//   └-- The 2 bytes of content.\n```\n\n`getBytesEncoder` and `getBytesDecoder` functions are also available.\n\n### getConstantCodec [!toc] [#get-constant-codec]\n\nThe `getConstantCodec` function accepts any `Uint8Array` and returns a `Codec<void>`. When encoding, it will set the provided `Uint8Array` as-is. When decoding, it will assert that the next bytes contain the provided `Uint8Array` and move the offset forward.\n\n```ts twoslash\nimport { getConstantCodec } from '@solana/kit';\n// ---cut-before---\nconst codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n\ncodec.encode(undefined); // 0x010203\ncodec.decode(new Uint8Array([1, 2, 3])); // undefined\ncodec.decode(new Uint8Array([1, 2, 4])); // Throws an error.\n```\n\n`getConstantEncoder` and `getConstantDecoder` functions are also available.\n\n### getDiscriminatedUnionCodec [!toc] [#get-discriminated-union-codec]\n\nIn Rust, enums are powerful data types whose variants can be one of the following:\n\n- An empty variant — e.g. `enum Message { Quit }`.\n- A tuple variant — e.g. `enum Message { Write(String) }`.\n- A struct variant — e.g. `enum Message { Move { x: i32, y: i32 } }`.\n\nWhilst we do not have such powerful enums in JavaScript, we can emulate them in TypeScript using a union of objects such that each object is differentiated by a specific field. **We call this a discriminated union**.\n\nWe use a special field named `__kind` to distinguish between the different variants of a discriminated union. Additionally, since all variants are objects, we can use a `fields` property to wrap the array of tuple variants. Here is an example.\n\n```ts twoslash\ntype Message =\n    | { __kind: 'quit' } // Empty variant.\n    | { __kind: 'write'; fields: [string] } // Tuple variant.\n    | { __kind: 'move'; x: number; y: number }; // Struct variant.\n```\n\nThe `getDiscriminatedUnionCodec` function helps us encode and decode these discriminated unions.\n\nIt requires the discriminator and codec of each variant as a first argument. Similarly to the [getStructCodec](#get-struct-codec), these are defined as an array of variant tuples where the first item is the discriminator of the variant and the second item is its codec. Since empty variants do not have data to encode, they simply use the [getUnitCodec](#get-unit-codec) which does nothing.\n\nHere is how we can create a discriminated union codec for our previous example.\n\n```ts twoslash\nimport {\n    getDiscriminatedUnionCodec,\n    getUnitCodec,\n    getStructCodec,\n    getTupleCodec,\n    getUtf8Codec,\n    getU32Codec,\n    addCodecSizePrefix,\n    getI32Codec,\n} from '@solana/kit';\n// ---cut-before---\nconst messageCodec = getDiscriminatedUnionCodec([\n    // Empty variant.\n    ['quit', getUnitCodec()],\n\n    // Tuple variant.\n    [\n        'write',\n        getStructCodec([\n            ['fields', getTupleCodec([addCodecSizePrefix(getUtf8Codec(), getU32Codec())])],\n        ]),\n    ],\n\n    // Struct variant.\n    [\n        'move',\n        getStructCodec([\n            ['x', getI32Codec()],\n            ['y', getI32Codec()],\n        ]),\n    ],\n]);\n```\n\nAnd here's how we can use such a codec to encode discriminated unions. Notice that by default, they use a `u8` number prefix to distinguish between the different types of variants.\n\n```ts twoslash\nimport {\n    getDiscriminatedUnionCodec,\n    getUnitCodec,\n    getStructCodec,\n    getTupleCodec,\n    getUtf8Codec,\n    getU32Codec,\n    addCodecSizePrefix,\n    getI32Codec,\n} from '@solana/kit';\nconst messageCodec = getDiscriminatedUnionCodec([\n    // Empty variant.\n    ['quit', getUnitCodec()],\n\n    // Tuple variant.\n    [\n        'write',\n        getStructCodec([\n            ['fields', getTupleCodec([addCodecSizePrefix(getUtf8Codec(), getU32Codec())])],\n        ]),\n    ],\n\n    // Struct variant.\n    [\n        'move',\n        getStructCodec([\n            ['x', getI32Codec()],\n            ['y', getI32Codec()],\n        ]),\n    ],\n]);\n// ---cut-before---\nmessageCodec.encode({ __kind: 'quit' });\n// 0x00\n//   └-- 1-byte discriminator (Index 0 — the \"quit\" variant).\n\nmessageCodec.encode({ __kind: 'write', fields: ['Hi'] });\n// 0x01020000004869\n//   | |       └-- utf8 string content (\"Hi\").\n//   | └-- u32 string prefix (2 characters).\n//   └-- 1-byte discriminator (Index 1 — the \"write\" variant).\n\nmessageCodec.encode({ __kind: 'move', x: 5, y: 6 });\n// 0x020500000006000000\n//   | |       └-- Field y (6).\n//   | └-- Field x (5).\n//   └-- 1-byte discriminator (Index 2 — the \"move\" variant).\n```\n\nHowever, you may provide a number codec as the `size` option of the `getDiscriminatedUnionCodec` function to customise that behaviour.\n\n```ts twoslash\nimport {\n    getDiscriminatedUnionCodec,\n    getUnitCodec,\n    getStructCodec,\n    getTupleCodec,\n    getUtf8Codec,\n    getU32Codec,\n    addCodecSizePrefix,\n    getI32Codec,\n} from '@solana/kit';\nconst quitCodec = getUnitCodec();\nconst writeCodec = getStructCodec([\n    ['fields', getTupleCodec([addCodecSizePrefix(getUtf8Codec(), getU32Codec())])],\n]);\nconst moveCodec = getStructCodec([\n    ['x', getI32Codec()],\n    ['y', getI32Codec()],\n]);\n// ---cut-before---\nconst u32MessageCodec = getDiscriminatedUnionCodec(\n    [\n        ['quit', quitCodec],\n        ['write', writeCodec],\n        ['move', moveCodec],\n    ],\n    { size: getU32Codec() },\n);\n\nu32MessageCodec.encode({ __kind: 'quit' });\n// 0x00000000\n//   └------┘ 4-byte discriminator (Index 0).\n\nu32MessageCodec.encode({ __kind: 'write', fields: ['Hi'] });\n// 0x01000000020000004869\n//   └------┘ 4-byte discriminator (Index 1).\n\nu32MessageCodec.encode({ __kind: 'move', x: 5, y: 6 });\n// 0x020000000500000006000000\n//   └------┘ 4-byte discriminator (Index 2).\n```\n\nYou may also customize the discriminator property — which defaults to `__kind` — by providing the desired property name as the `discriminator` option like so:\n\n```ts twoslash\nimport {\n    getDiscriminatedUnionCodec,\n    getUnitCodec,\n    getStructCodec,\n    getTupleCodec,\n    getUtf8Codec,\n    getU32Codec,\n    addCodecSizePrefix,\n    getI32Codec,\n} from '@solana/kit';\nconst quitCodec = getUnitCodec();\nconst writeCodec = getStructCodec([\n    ['fields', getTupleCodec([addCodecSizePrefix(getUtf8Codec(), getU32Codec())])],\n]);\nconst moveCodec = getStructCodec([\n    ['x', getI32Codec()],\n    ['y', getI32Codec()],\n]);\n// ---cut-before---\nconst messageCodec = getDiscriminatedUnionCodec(\n    [\n        ['quit', quitCodec],\n        ['write', writeCodec],\n        ['move', moveCodec],\n    ],\n    { discriminator: 'message' },\n);\n\nmessageCodec.encode({ message: 'quit' });\nmessageCodec.encode({ message: 'write', fields: ['Hi'] });\nmessageCodec.encode({ message: 'move', x: 5, y: 6 });\n```\n\nNote that, the discriminator value of a variant may be any scalar value — such as `number`, `bigint`, `boolean`, a JavaScript `enum`, etc. For instance, the following is also valid:\n\n```ts twoslash\nimport {\n    getDiscriminatedUnionCodec,\n    getUnitCodec,\n    getStructCodec,\n    getTupleCodec,\n    getUtf8Codec,\n    getU32Codec,\n    addCodecSizePrefix,\n    getI32Codec,\n} from '@solana/kit';\nconst quitCodec = getUnitCodec();\nconst writeCodec = getStructCodec([\n    ['fields', getTupleCodec([addCodecSizePrefix(getUtf8Codec(), getU32Codec())])],\n]);\nconst moveCodec = getStructCodec([\n    ['x', getI32Codec()],\n    ['y', getI32Codec()],\n]);\n// ---cut-before---\nenum Message {\n    Quit,\n    Write,\n    Move,\n}\nconst messageCodec = getDiscriminatedUnionCodec([\n    [Message.Quit, quitCodec],\n    [Message.Write, writeCodec],\n    [Message.Move, moveCodec],\n]);\n\nmessageCodec.encode({ __kind: Message.Quit });\nmessageCodec.encode({ __kind: Message.Write, fields: ['Hi'] });\nmessageCodec.encode({ __kind: Message.Move, x: 5, y: 6 });\n```\n\n`getDiscriminatedUnionEncoder` and `getDiscriminatedUnionDecoder` functions are also available.\n\n### getEnumCodec [!toc] [#get-enum-codec]\n\nThe `getEnumCodec` function accepts a JavaScript enum constructor and returns a codec for encoding and decoding values of that enum.\n\n```ts twoslash\nimport { getEnumCodec } from '@solana/kit';\n// ---cut-before---\nenum Direction {\n    Left,\n    Right,\n}\n\nconst codec = getEnumCodec(Direction);\nconst bytes = codec.encode(Direction.Left); // 0x00\nconst direction = codec.decode(bytes); // Direction.Left\n```\n\nWhen encoding an enum, you may either provide the value of the enum variant — e.g. `Direction.Left` — or its key — e.g. `'Left'`.\n\n```ts twoslash\nimport { getEnumCodec } from '@solana/kit';\nenum Direction {\n    Left,\n    Right,\n}\n// ---cut-before---\ngetEnumCodec(Direction).encode(Direction.Left); // 0x00\ngetEnumCodec(Direction).encode(Direction.Right); // 0x01\ngetEnumCodec(Direction).encode('Left'); // 0x00\ngetEnumCodec(Direction).encode('Right'); // 0x01\n```\n\nBy default, a `u8` number is being used to store the enum value. However, a number codec may be passed as the `size` option to configure that behaviour.\n\n```ts twoslash\nimport { getEnumCodec, getU32Codec } from '@solana/kit';\nenum Direction {\n    Left,\n    Right,\n}\n// ---cut-before---\nconst u32DirectionCodec = getEnumCodec(Direction, { size: getU32Codec() });\nu32DirectionCodec.encode(Direction.Left); // 0x00000000\nu32DirectionCodec.encode(Direction.Right); // 0x01000000\n```\n\nThis function also works with lexical enums — e.g. `enum Direction { Left = '←' }` — explicit numerical enums — e.g. `enum Speed { Left = 50 }` — and hybrid enums with a mix of both.\n\n```ts twoslash\nimport { getEnumCodec } from '@solana/kit';\n// ---cut-before---\nenum Numbers {\n    One,\n    Five = 5,\n    Six,\n    Nine = 'nine',\n}\n\ngetEnumCodec(Numbers).encode(Numbers.One); // 0x00\ngetEnumCodec(Numbers).encode(Numbers.Five); // 0x01\ngetEnumCodec(Numbers).encode(Numbers.Six); // 0x02\ngetEnumCodec(Numbers).encode(Numbers.Nine); // 0x03\ngetEnumCodec(Numbers).encode('One'); // 0x00\ngetEnumCodec(Numbers).encode('Five'); // 0x01\ngetEnumCodec(Numbers).encode('Six'); // 0x02\ngetEnumCodec(Numbers).encode('Nine'); // 0x03\n```\n\nNotice how, by default, the index of the enum variant is used to encode the value of the enum. For instance, in the example above, `Numbers.Five` is encoded as `0x01` even though its value is `5`. This is also true for lexical enums.\n\nHowever, when dealing with numerical enums that have explicit values, you may use the `useValuesAsDiscriminators` option to encode the value of the enum variant instead of its index.\n\n```ts twoslash\nimport { getEnumCodec } from '@solana/kit';\n// ---cut-before---\nenum Numbers {\n    One,\n    Five = 5,\n    Six,\n    Nine = 9,\n}\n\nconst codec = getEnumCodec(Numbers, { useValuesAsDiscriminators: true });\ncodec.encode(Numbers.One); // 0x00\ncodec.encode(Numbers.Five); // 0x05\ncodec.encode(Numbers.Six); // 0x06\ncodec.encode(Numbers.Nine); // 0x09\ncodec.encode('One'); // 0x00\ncodec.encode('Five'); // 0x05\ncodec.encode('Six'); // 0x06\ncodec.encode('Nine'); // 0x09\n```\n\nNote that when using the `useValuesAsDiscriminators` option on an enum that contains a lexical value, an error will be thrown.\n\n```ts twoslash\nimport { getEnumCodec } from '@solana/kit';\n// ---cut-before---\nenum Lexical {\n    One,\n    Two = 'two',\n}\ngetEnumCodec(Lexical, { useValuesAsDiscriminators: true }); // Throws an error.\n```\n\n`getEnumEncoder` and `getEnumDecoder` functions are also available.\n\n### getHiddenPrefixCodec [!toc] [#get-hidden-prefix-codec]\n\nThe `getHiddenPrefixCodec` function allow us to prepend a list of hidden `Codec<void>` to a given codec.\n\nWhen encoding, the hidden codecs will be encoded before the main codec and the offset will be moved accordingly. When decoding, the hidden codecs will be decoded but only the result of the main codec will be returned. This is particularly helpful when creating data structures that include constant values that should not be included in the final type.\n\n```ts twoslash\nimport { getHiddenPrefixCodec, getConstantCodec, getU16Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getHiddenPrefixCodec(getU16Codec(), [\n    getConstantCodec(new Uint8Array([1, 2, 3])),\n    getConstantCodec(new Uint8Array([4, 5, 6])),\n]);\n\ncodec.encode(42);\n// 0x0102030405062a00\n//   |     |     └-- Our main u16 codec (value = 42).\n//   |     └-- Our second hidden prefix codec.\n//   └-- Our first hidden prefix codec.\n\ncodec.decode(new Uint8Array([1, 2, 3, 4, 5, 6, 42, 0])); // 42\n```\n\n`getHiddenPrefixEncoder` and `getHiddenPrefixDecoder` functions are also available.\n\n### getHiddenSuffixCodec [!toc] [#get-hidden-suffix-codec]\n\nThe `getHiddenSuffixCodec` function allow us to append a list of hidden `Codec<void>` to a given codec.\n\nWhen encoding, the hidden codecs will be encoded after the main codec and the offset will be moved accordingly. When decoding, the hidden codecs will be decoded but only the result of the main codec will be returned. This is particularly helpful when creating data structures that include constant values that should not be included in the final type.\n\n```ts twoslash\nimport { getHiddenSuffixCodec, getConstantCodec, getU16Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getHiddenSuffixCodec(getU16Codec(), [\n    getConstantCodec(new Uint8Array([1, 2, 3])),\n    getConstantCodec(new Uint8Array([4, 5, 6])),\n]);\n\ncodec.encode(42);\n// 0x2a00010203040506\n//   |   |     └-- Our second hidden suffix codec.\n//   |   └-- Our first hidden suffix codec.\n//   └-- Our main u16 codec (value = 42).\n\ncodec.decode(new Uint8Array([42, 0, 1, 2, 3, 4, 5, 6])); // 42\n```\n\n`getHiddenSuffixEncoder` and `getHiddenSuffixDecoder` functions are also available.\n\n### getLiteralUnionCodec [!toc] [#get-literal-union-codec]\n\nThe `getLiteralUnionCodec` function accepts an array of literal values — such as `string`, `number`, `boolean`, etc. — and returns a codec that encodes and decodes such values by using their index in the array. It uses TypeScript unions to represent all the possible values.\n\n```ts twoslash\nimport { getLiteralUnionCodec, FixedSizeCodec } from '@solana/kit';\n// ---cut-before---\nconst codec = getLiteralUnionCodec(['left', 'right', 'up', 'down']);\ncodec satisfies FixedSizeCodec<'left' | 'right' | 'up' | 'down'>;\n\nconst bytes = codec.encode('left'); // 0x00\nconst value = codec.decode(bytes); // 'left'\n```\n\nIt uses a `u8` number by default to store the index of the value. However, you may provide a number codec as the `size` option of the `getLiteralUnionCodec` function to customise that behaviour.\n\n```ts twoslash\nimport { getLiteralUnionCodec, getU32Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getLiteralUnionCodec(['left', 'right', 'up', 'down'], {\n    size: getU32Codec(),\n});\n\ncodec.encode('left'); // 0x00000000\ncodec.encode('right'); // 0x01000000\ncodec.encode('up'); // 0x02000000\ncodec.encode('down'); // 0x03000000\n```\n\n`getLiteralUnionEncoder` and `getLiteralUnionDecoder` functions are also available.\n\n### getMapCodec [!toc] [#get-map-codec]\n\nThe `getMapCodec` function accepts two codecs of type `K` and `V` and returns a codec of type `Map<K, V>`.\n\n```ts twoslash\nimport { getMapCodec, getU8Codec, getUtf8Codec, fixCodecSize } from '@solana/kit';\n// ---cut-before---\nconst keyCodec = fixCodecSize(getUtf8Codec(), 8);\nconst valueCodec = getU8Codec();\nconst codec = getMapCodec(keyCodec, valueCodec);\n\nconst bytes = codec.encode(new Map([['alice', 42]])); // 0x01000000616c6963650000002a\nconst map = codec.decode(bytes); // new Map([[\"alice\", 42]])\n```\n\nEach entry (key/value pair) is encoded one after the other with the key first and the value next. By default, the size of the map is stored as a `u32` prefix before encoding the entries.\n\n```ts twoslash\nimport { getMapCodec, getU8Codec, getUtf8Codec, fixCodecSize } from '@solana/kit';\n// ---cut-before---\nconst codec = getMapCodec(fixCodecSize(getUtf8Codec(), 8), getU8Codec());\nconst myMap = new Map<string, number>();\nmyMap.set('alice', 42);\nmyMap.set('bob', 5);\n\ncodec.encode(myMap);\n// 0x02000000616c6963650000002a626f62000000000005\n//   |       |               | |               └-- 2nd entry value (5).\n//   |       |               | └-- 2nd entry key (\"bob\").\n//   |       |               └-- 1st entry value (42).\n//   |       └-- 1st entry key (\"alice\").\n//   └-- 4-byte prefix telling us to read 2 map entries.\n```\n\nHowever, you may use the `size` option to configure this behaviour. It can be one of the following three strategies:\n\n- `Codec<number>`: When a number codec is provided, that codec will be used to encode and decode the size prefix.\n- `number`: When a number is provided, the codec will expect a fixed number of entries in the map. An error will be thrown when trying to encode a map of a different length.\n- `\"remainder\"`: When the string `\"remainder\"` is passed as a size, the codec will use the remainder of the bytes to encode/decode its entries. This means the size is not stored or known in advance but simply inferred from the rest of the buffer. For instance, if we have a map of `u16` numbers and 10 bytes remaining, we know there are 5 entries in this map.\n\n```ts twoslash\nimport { getMapCodec, getU8Codec, getU16Codec, fixCodecSize, getUtf8Codec } from '@solana/kit';\n// ---cut-before---\nconst keyCodec = fixCodecSize(getUtf8Codec(), 8);\nconst valueCodec = getU8Codec();\n\nconst myMap = new Map<string, number>();\nmyMap.set('alice', 42);\nmyMap.set('bob', 5);\n\ngetMapCodec(keyCodec, valueCodec, { size: getU16Codec() }).encode(myMap);\n// 0x0200616c6963650000002a626f62000000000005\n//   |   |                 └-- Second entry.\n//   |   └-- First entry.\n//   └-- 2-byte prefix telling us to read 2 entries.\n\ngetMapCodec(keyCodec, valueCodec, { size: 3 }).encode(myMap);\n// 0x616c6963650000002a626f62000000000005\n//   |                 └-- Second entry.\n//   └-- First entry.\n// There must always be 2 entries in the map.\n\ngetMapCodec(keyCodec, valueCodec, { size: 'remainder' }).encode(myMap);\n// 0x616c6963650000002a626f62000000000005\n//   |                 └-- Second entry.\n//   └-- First entry.\n// The size is inferred from the remainder of the bytes.\n```\n\n`getMapEncoder` and `getMapDecoder` functions are also available.\n\n### getNullableCodec [!toc] [#get-nullable-codec]\n\nThe `getNullableCodec` function accepts a codec of type `T` and returns a codec of type `T | null`. It stores whether or not the item exists as a boolean prefix using a `u8` by default.\n\n```ts twoslash\nimport { getNullableCodec, getU32Codec, addCodecSizePrefix, getUtf8Codec } from '@solana/kit';\n// ---cut-before---\nconst stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n\ngetNullableCodec(stringCodec).encode('Hi');\n// 0x01020000004869\n//   | |       └-- utf8 string content (\"Hi\").\n//   | └-- u32 string prefix (2 characters).\n//   └-- 1-byte prefix (true — The item exists).\n\ngetNullableCodec(stringCodec).encode(null);\n// 0x00\n//   └-- 1-byte prefix (false — The item is null).\n```\n\nYou may provide a number codec as the `prefix` option of the `getNullableCodec` function to configure how to store the boolean prefix.\n\n```ts twoslash\nimport { getNullableCodec, getU32Codec, addCodecSizePrefix, getUtf8Codec } from '@solana/kit';\nconst stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n// ---cut-before---\nconst u32NullableStringCodec = getNullableCodec(stringCodec, {\n    prefix: getU32Codec(),\n});\n\nu32NullableStringCodec.encode('Hi');\n// 0x01000000020000004869\n//   └------┘ 4-byte prefix (true).\n\nu32NullableStringCodec.encode(null);\n// 0x00000000\n//   └------┘ 4-byte prefix (false).\n```\n\nAdditionally, if the item is a `FixedSizeCodec`, you may set the `noneValue` option to `\"zeroes\"` to also make the returned nullable codec a `FixedSizeCodec`. To do so, it will pad `null` values with zeroes to match the length of existing values.\n\n```ts twoslash\nimport { getNullableCodec, fixCodecSize, getUtf8Codec } from '@solana/kit';\n// ---cut-before---\nconst fixedNullableStringCodec = getNullableCodec(\n    fixCodecSize(getUtf8Codec(), 8), // Only works with fixed-size items.\n    { noneValue: 'zeroes' },\n);\n\nfixedNullableStringCodec.encode('Hi');\n// 0x014869000000000000\n//   | └-- 8-byte utf8 string content (\"Hi\").\n//   └-- 1-byte prefix (true — The item exists).\n\nfixedNullableStringCodec.encode(null);\n// 0x000000000000000000\n//   | └-- 8-byte of padding to make a fixed-size codec.\n//   └-- 1-byte prefix (false — The item is null).\n```\n\nThe `noneValue` option can also be set to an explicit byte array to use as the padding for `null` values. Note that, in this case, the returned codec will not be a `FixedSizeCodec` as the byte array representing `null` values may be of any length.\n\n```ts twoslash\nimport { getNullableCodec, getUtf8Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getNullableCodec(getUtf8Codec(), {\n    noneValue: new Uint8Array([255]), // 0xff means null.\n});\n\ncodec.encode('Hi');\n// 0x014869\n//   | └-- 2-byte utf8 string content (\"Hi\").\n//   └-- 1-byte prefix (true — The item exists).\n\ncodec.encode(null);\n// 0x00ff\n//   | └-- 1-byte representing null (0xff).\n//   └-- 1-byte prefix (false — The item is null).\n```\n\nThe `prefix` option of the `getNullableCodec` function can also be set to `null`, meaning no prefix will be used to determine whether the item exists. In this case, the codec will rely on the `noneValue` option to determine whether the item is `null`.\n\n```ts twoslash\nimport { getNullableCodec, getU16Codec } from '@solana/kit';\n// ---cut-before---\nconst codecWithZeroNoneValue = getNullableCodec(getU16Codec(), {\n    noneValue: 'zeroes', // 0x0000 means null.\n    prefix: null,\n});\ncodecWithZeroNoneValue.encode(42); // 0x2a00\ncodecWithZeroNoneValue.encode(null); // 0x0000\n\nconst codecWithCustomNoneValue = getNullableCodec(getU16Codec(), {\n    noneValue: new Uint8Array([255]), // 0xff means null.\n    prefix: null,\n});\ncodecWithCustomNoneValue.encode(42); // 0x2a00\ncodecWithCustomNoneValue.encode(null); // 0xff\n```\n\nNote that if `prefix` is set to `null` and no `noneValue` is provided, the codec assumes that the item exists if and only if some remaining bytes are available to decode. This could be useful to describe data structures that may or may not have additional data to the end of the buffer.\n\n```ts\nconst codec = getNullableCodec(getU16Codec(), { prefix: null });\ncodec.encode(42); // 0x2a00\ncodec.encode(null); // Encodes nothing.\ncodec.decode(new Uint8Array([42, 0])); // 42\ncodec.decode(new Uint8Array([])); // null\n```\n\nTo recap, here are all the possible configurations of the `getNullableCodec` function, using a `u16` codec as an example.\n\n| `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n| ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n| `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n| Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n| No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\nNote that you might be interested in the Rust-like alternative version of nullable codecs, available as the [getOptionCodec](#get-option-codec) function.\n\n`getNullableEncoder` and `getNullableDecoder` functions are also available.\n\n### getOptionCodec [!toc] [#get-option-codec]\n\nThe `getOptionCodec` function accepts a codec of type `T` and returns a codec of type `Option<T>` — as defined in the [`@solana/options`](https://github.com/anza-xyz/kit/tree/main/packages/options) package. Note that, when encoding, `T` or `null` may also be provided directly as input and will be interpreted as `Some(T)` or `None` respectively. However, when decoding, the output will always be an `Option<T>` type.\n\nIt stores whether or not the item exists as a boolean prefix using a `u8` by default.\n\n```ts twoslash\nimport {\n    getOptionCodec,\n    getU32Codec,\n    addCodecSizePrefix,\n    getUtf8Codec,\n    some,\n    none,\n} from '@solana/kit';\n// ---cut-before---\nconst stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n\ngetOptionCodec(stringCodec).encode('Hi');\ngetOptionCodec(stringCodec).encode(some('Hi'));\n// 0x01020000004869\n//   | |       └-- utf8 string content (\"Hi\").\n//   | └-- u32 string prefix (2 characters).\n//   └-- 1-byte prefix (Some).\n\ngetOptionCodec(stringCodec).encode(null);\ngetOptionCodec(stringCodec).encode(none());\n// 0x00\n//   └-- 1-byte prefix (None).\n```\n\nYou may provide a number codec as the `prefix` option of the `getOptionCodec` function to configure how to store the boolean prefix.\n\n```ts twoslash\nimport {\n    getOptionCodec,\n    getU32Codec,\n    addCodecSizePrefix,\n    getUtf8Codec,\n    some,\n    none,\n} from '@solana/kit';\nconst stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n// ---cut-before---\nconst u32OptionStringCodec = getOptionCodec(stringCodec, {\n    prefix: getU32Codec(),\n});\n\nu32OptionStringCodec.encode(some('Hi'));\n// 0x01000000020000004869\n//   └------┘ 4-byte prefix (Some).\n\nu32OptionStringCodec.encode(none());\n// 0x00000000\n//   └------┘ 4-byte prefix (None).\n```\n\nAdditionally, if the item is a `FixedSizeCodec`, you may set the `noneValue` option to `\"zeroes\"` to also make the returned Option codec a `FixedSizeCodec`. To do so, it will pad `None` values with zeroes to match the length of existing values.\n\n```ts twoslash\nimport { getOptionCodec, fixCodecSize, getUtf8Codec, some, none } from '@solana/kit';\n// ---cut-before---\nconst codec = getOptionCodec(\n    fixCodecSize(getUtf8Codec(), 8), // Only works with fixed-size items.\n    { noneValue: 'zeroes' },\n);\n\ncodec.encode(some('Hi'));\n// 0x014869000000000000\n//   | └-- 8-byte utf8 string content (\"Hi\").\n//   └-- 1-byte prefix (Some).\n\ncodec.encode(none());\n// 0x000000000000000000\n//   | └-- 8-byte of padding to make a fixed-size codec.\n//   └-- 1-byte prefix (None).\n```\n\nThe `noneValue` option can also be set to an explicit byte array to use as the padding for `None` values. Note that, in this case, the returned codec will not be a `FixedSizeCodec` as the byte array representing `None` values may be of any length.\n\n```ts twoslash\nimport { getOptionCodec, getUtf8Codec, some, none } from '@solana/kit';\n// ---cut-before---\nconst codec = getOptionCodec(getUtf8Codec(), {\n    noneValue: new Uint8Array([255]), // 0xff means None.\n});\n\ncodec.encode(some('Hi'));\n// 0x014869\n//   | └-- 2-byte utf8 string content (\"Hi\").\n//   └-- 1-byte prefix (Some).\n\ncodec.encode(none());\n// 0x00ff\n//   | └-- 1-byte representing None (0xff).\n//   └-- 1-byte prefix (None).\n```\n\nThe `prefix` option of the `getOptionCodec` function can also be set to `null`, meaning no prefix will be used to determine whether the item exists. In this case, the codec will rely on the `noneValue` option to determine whether the item is `None`.\n\n```ts twoslash\nimport { getOptionCodec, getU16Codec, some, none } from '@solana/kit';\n// ---cut-before---\nconst codecWithZeroNoneValue = getOptionCodec(getU16Codec(), {\n    noneValue: 'zeroes', // 0x0000 means None.\n    prefix: null,\n});\ncodecWithZeroNoneValue.encode(some(42)); // 0x2a00\ncodecWithZeroNoneValue.encode(none()); // 0x0000\n\nconst codecWithCustomNoneValue = getOptionCodec(getU16Codec(), {\n    noneValue: new Uint8Array([255]), // 0xff means None.\n    prefix: null,\n});\ncodecWithCustomNoneValue.encode(some(42)); // 0x2a00\ncodecWithCustomNoneValue.encode(none()); // 0xff\n```\n\nNote that if `prefix` is set to `null` and no `noneValue` is provided, the codec assume that the item exists if and only if some remaining bytes are available to decode. This could be useful to describe data structures that may or may not have additional data to the end of the buffer.\n\n```ts twoslash\nimport { getOptionCodec, getU16Codec, some, none } from '@solana/kit';\n// ---cut-before---\nconst codec = getOptionCodec(getU16Codec(), { prefix: null });\ncodec.encode(some(42)); // 0x2a00\ncodec.encode(none()); // Encodes nothing.\ncodec.decode(new Uint8Array([42, 0])); // some(42)\ncodec.decode(new Uint8Array([])); // none()\n```\n\nTo recap, here are all the possible configurations of the `getOptionCodec` function, using a `u16` codec as an example.\n\n| `encode(some(42))` / `encode(none())` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n| ------------------------------------- | ------------------------ | --------------------------- | --------------------------- |\n| `u8` prefix (default)                 | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n| Custom `prefix` (`u16`)               | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n| No `prefix`                           | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n`getOptionEncoder` and `getOptionDecoder` functions are also available.\n\n### getPatternMatchCodec [!toc] [#get-pattern-match-codec]\n\nThe `getPatternMatchCodec` function returns a codec that selects which variant codec to use based on pattern matching. It generalises [`getPredicateCodec`](#get-predicate-codec) from two variants to any number of variants.\n\nIt accepts an array of `[encodePredicate, decodePredicate, codec]` triples, where:\n\n- An encode predicate, that takes the value to encode and returns a boolean\n- A decode predicate, that takes a `ReadonlyUint8Array` and returns a boolean\n- A codec, that will be used when the corresponding predicate returns `true`\n\nPredicates are tested in order and the first match is used. If no predicate matches, a `SolanaError` is thrown.\n\n```ts twoslash\nimport { getPatternMatchCodec, getU8Codec, getU16Codec, getU32Codec, Codec } from '@solana/kit';\n\n// ---cut-before---\n\nconst codec: Codec<number> = getPatternMatchCodec([\n    [\n        (value: number) => value < 256,\n        bytes => bytes.length === 1,\n        getU8Codec(),\n    ],\n    [\n        (value: number) => value < 2 ** 16,\n        bytes => bytes.length === 2,\n        getU16Codec(),\n    ],\n    [\n        (value: number) => value < 2 ** 32,\n        bytes => bytes.length <= 4,\n        getU32Codec(),\n    ],\n]);\n\nconst u8Bytes = codec.encode(42) // 0x2a, encoded as u8\ncodec.decode(u8Bytes) // 42, decoded as u8\n\nconst u16Bytes = codec.encode(1000) // 0xe803, encoded as u16\ncodec.decode(u16Bytes) // 1000, decoded as u16\n\nconst u32Bytes = codec.encode(100_000) // 0xa0860100, encoded as u32\ncodec.decode(u32Bytes) // 100_000, decoded as u32\n```\n\n`getPatternMatchEncoder` and `getPatternMatchDecoder` functions are also available.\n\n### getPredicateCodec [!toc] [#get-predicate-codec]\n\nThe `getPredicateCodec` function returns a codec that switches between two different codecs, based on a predicate.\n\nIt accepts the following arguments:\n\n- An encode predicate, that takes a value of a given type and returns a boolean\n- A decode predicate, that takes a `ReadOnlyUint8Array` and returns a boolean \n- A codec, that will be used to encode if the encode predicate is true and will be used to decode if the decode predicate is true\n- A codec, that will be used to encode if the encode predicate is false and will be used to decode if the decode predicate is false\n\n```ts twoslash\nimport { getPredicateCodec, getU8Codec, getU32Codec, Codec } from '@solana/kit';\n\n// ---cut-before---\n\nconst codec: Codec<number> = getPredicateCodec(\n    (value: number) => value < 256,\n    bytes => bytes.length === 1,\n    getU8Codec(),\n    getU32Codec(),\n);\n\nconst u8Bytes = codec.encode(42) // 0x2a, used u8 codec\ncodec.decode(u8Bytes) // 42, used u8 codec\n\nconst u32Bytes = codec.encode(1000) // 0xE8030000, used u32 codec\ncodec.decode(u32Bytes) // 1000, used u32 codec\n```\n\n`getPredicateEncoder` and `getPredicateDecoder` functions are also available.\n\n### getSetCodec [!toc] [#get-set-codec]\n\nThe `getSetCodec` function accepts any codec of type `T` and returns a codec of type `Set<T>`.\n\n```ts twoslash\nimport { getSetCodec, getU8Codec } from '@solana/kit';\n// ---cut-before---\nconst codec = getSetCodec(getU8Codec());\nconst bytes = codec.encode(new Set([1, 2, 3])); // 0x03000000010203\nconst value = codec.decode(bytes); // new Set([1, 2, 3])\n```\n\nBy default, the size of the set is stored as a `u32` prefix before encoding the items.\n\n```ts twoslash\nimport { getSetCodec, getU8Codec } from '@solana/kit';\n// ---cut-before---\ngetSetCodec(getU8Codec()).encode(new Set([1, 2, 3]));\n// 0x03000000010203\n//   |       └-- 3 items of 1 byte each.\n//   └-- 4-byte prefix telling us to read 3 items.\n```\n\nHowever, you may use the `size` option to configure this behaviour. It can be one of the following three strategies:\n\n- `Codec<number>`: When a number codec is provided, that codec will be used to encode and decode the size prefix.\n- `number`: When a number is provided, the codec will expect a fixed number of items in the set. An error will be thrown when trying to encode a set of a different length.\n- `\"remainder\"`: When the string `\"remainder\"` is passed as a size, the codec will use the remainder of the bytes to encode/decode its items. This means the size is not stored or known in advance but simply inferred from the rest of the buffer. For instance, if we have a set of `u16` numbers and 10 bytes remaining, we know there are 5 items in this set.\n\n```ts twoslash\nimport { getSetCodec, getU8Codec, getU16Codec } from '@solana/kit';\n// ---cut-before---\ngetSetCodec(getU8Codec(), { size: getU16Codec() }).encode(new Set([1, 2, 3]));\n// 0x0300010203\n//   |   └-- 3 items of 1 byte each.\n//   └-- 2-byte prefix telling us to read 3 items.\n\ngetSetCodec(getU8Codec(), { size: 3 }).encode(new Set([1, 2, 3]));\n// 0x010203\n//   └-- 3 items of 1 byte each. There must always be 3 items in the set.\n\ngetSetCodec(getU8Codec(), { size: 'remainder' }).encode(new Set([1, 2, 3]));\n// 0x010203\n//   └-- 3 items of 1 byte each. The size is inferred from the remainder of the bytes.\n```\n\n`getSetEncoder` and `getSetDecoder` functions are also available.\n\n### getStructCodec [!toc] [#get-struct-codec]\n\nThe `getStructCodec` function accepts any number of field codecs and returns a codec for an object containing all these fields. Each provided field is an array such that the first item is the name of the field and the second item is the codec used to encode and decode that field type.\n\n```ts twoslash\nimport {\n    getStructCodec,\n    getU8Codec,\n    getUtf8Codec,\n    addCodecSizePrefix,\n    Codec,\n    getU32Codec,\n} from '@solana/kit';\n// ---cut-before---\ntype Person = { name: string; age: number };\nconst personCodec: Codec<Person> = getStructCodec([\n    ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n    ['age', getU8Codec()],\n]);\n\nconst bytes = personCodec.encode({ name: 'alice', age: 42 });\n// 0x05000000616c6963652a\n//   |                 └-- Age field.\n//   └-- Name field.\n\nconst person = personCodec.decode(bytes);\n// { name: \"alice\", age: 42 }\n```\n\n`getStructEncoder` and `getStructDecoder` functions are also available.\n\n### getTupleCodec [!toc] [#get-tuple-codec]\n\nThe `getTupleCodec` function accepts any number of codecs — `T`, `U`, `V`, etc. — and returns a tuple codec of type `[T, U, V, …]` such that each item is in the order of the provided codecs.\n\n```ts twoslash\nimport {\n    getTupleCodec,\n    getU8Codec,\n    getU64Codec,\n    addCodecSizePrefix,\n    getUtf8Codec,\n    getU32Codec,\n} from '@solana/kit';\n// ---cut-before---\nconst tupleCodec = getTupleCodec([\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()),\n    getU8Codec(),\n    getU64Codec(),\n]);\n\nconst bytes = tupleCodec.encode(['alice', 42, 123]);\n// 0x05000000616c6963652a7b00000000000000\n//   |                 | └-- 3rd item (123).\n//   |                 └-- 2nd item (42).\n//   └-- 1st item (\"alice\").\n\nconst value = tupleCodec.decode(bytes);\n// [\"alice\", 42, 123]\n```\n\n`getTupleEncoder` and `getTupleDecoder` functions are also available.\n\n### getUnionCodec [!toc] [#get-union-codec]\n\nThe `getUnionCodec` is a lower-lever codec helper that can be used to encode/decode any TypeScript union.\n\nIt accepts the following arguments:\n\n- An array of codecs, each defining a variant of the union.\n- A `getIndexFromValue` function which, given a value of the union, returns the index of the codec that should be used to encode that value.\n- A `getIndexFromBytes` function which, given the byte array to decode at a given offset, returns the index of the codec that should be used to decode the next bytes.\n\n```ts twoslash\nimport { getUnionCodec, getU16Codec, getBooleanCodec, Codec } from '@solana/kit';\n// ---cut-before---\nconst codec: Codec<number | boolean> = getUnionCodec(\n    [getU16Codec(), getBooleanCodec()],\n    (value) => (typeof value === 'number' ? 0 : 1),\n    (bytes, offset) => (bytes.slice(offset).length > 1 ? 0 : 1),\n);\n\ncodec.encode(42); // 0x2a00\ncodec.encode(true); // 0x01\n```\n\n`getUnionEncoder` and `getUnionDecoder` functions are also available.\n\n### getUnitCodec [!toc] [#get-unit-codec]\n\nThe `getUnitCodec` function returns a `Codec<void>` that encodes `undefined` into an empty `Uint8Array` and returns `undefined` without consuming any bytes when decoding. This is more of a low-level codec that can be used internally by other codecs. For instance, this is how [getDiscriminatedUnionCodec](#get-discriminated-union-codec) describes the codecs of empty variants.\n\n```ts twoslash\nimport { getUnitCodec } from '@solana/kit';\nconst anyBytes = null as unknown as Uint8Array;\n// ---cut-before---\ngetUnitCodec().encode(undefined); // Empty Uint8Array\ngetUnitCodec().decode(anyBytes); // undefined\n```\n\n`getUnitEncoder` and `getUnitDecoder` functions are also available.\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/errors.mdx",
    "content": "---\ntitle: Errors\ndescription: Recover from errors in development and production\n---\n\n## Introduction\n\nThe ecosystem of packages based on Kit's error system benefit from strongly typed error data, and descriptive error messages. Its error messages get scrubbed from your production bundles, which means that the library of error messages can grow indefinitely without adding a single byte to your app.\n\n## Installation\n\nErrors are **included within the `@solana/kit` library** but you may also install them using their standalone package.\n\n```package-install\n@solana/errors\n```\n\n## What is a `SolanaError`?\n\nA `SolanaError` is a class made of three components:\n\n- An error **code**; found in the union named [`SolanaErrorCode`](/api/type-aliases/SolanaErrorCode)\n- An error **message**\n- Optional error **context**\n\nHere's an example of some code that responds to various errors, taking advantage of the error context offered by each one:\n\n```ts twoslash\nimport {\n    Transaction,\n    TransactionWithBlockhashLifetime,\n    sendAndConfirmTransactionFactory,\n} from '@solana/kit';\nconst sendAndConfirmTransaction = null as unknown as ReturnType<\n    typeof sendAndConfirmTransactionFactory\n>;\nconst transaction = null as unknown as Transaction & TransactionWithBlockhashLifetime;\n// ---cut-before---\nimport {\n    assertIsSendableTransaction,\n    isSolanaError,\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n    SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT,\n} from '@solana/kit';\n\ntry {\n    assertIsSendableTransaction(transaction);\n    await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n        console.error(`Missing signatures for ${e.context.addresses.join(', ')}`);\n    } else if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT)) {\n        console.error(\n            `Transaction exceeds size limit of ${e.context.transactionSizeLimit} bytes. ` +\n                `Actual size: ${e.context.transactionSize}`,\n        );\n    }\n    throw e;\n}\n```\n\n## Catching errors\n\nWhen you encounter an error, you can determine whether it is a `SolanaError` or not using the `isSolanaError()` function:\n\n```ts twoslash\nimport { isSolanaError } from '@solana/kit';\n\ntry {\n    // ...\n} catch (e) {\n    if (isSolanaError(e)) {\n        // A Solana error was thrown\n    } else {\n        // Something else went wrong\n    }\n}\n```\n\nWhen you have a strategy for handling a _particular_ error, you can supply that error's code as the second argument. This will both identify that error by code and refine the type of the `SolanaError` such that the shape of its `context` property becomes known to TypeScript.\n\n```ts twoslash\nimport { SolanaError } from '@solana/kit';\nconst e = null as unknown as SolanaError;\n// ---cut-before---\nimport {\n    isSolanaError,\n    SolanaErrorCode,\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n} from '@solana/kit';\n\ntry {\n    // ...\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n        //               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n        console.error(\n            // Now TypeScript knows the shape of this error's context\n            `Missing signatures for these addresses: [${e.context.addresses.join(', ')}]`,\n            //                                          ^^^^^^^^^\n        );\n    } else {\n        // Something else went wrong\n    }\n}\n```\n\nSome Solana errors have, as their root cause, another Solana error. One such example is during transaction simulation (preflight):\n\n```ts twoslash\nimport { Base64EncodedWireTransaction, Rpc, SendTransactionApi } from '@solana/kit';\nconst rpc = null as unknown as Rpc<SendTransactionApi>;\nconst wireTransaction = null as unknown as Base64EncodedWireTransaction;\n// ---cut-before---\nimport {\n    isSolanaError,\n    SOLANA_ERROR__INSTRUCTION_ERROR__COMPUTATIONAL_BUDGET_EXCEEDED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n} from '@solana/kit';\n\ntry {\n    const result = await rpc.sendTransaction(wireTransaction, {\n        encoding: 'base64',\n        skipPreflight: false,\n    });\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE)) {\n        // Simulation failed, but why?\n        const underlyingError = e.cause;\n        if (\n            isSolanaError(\n                underlyingError,\n                SOLANA_ERROR__INSTRUCTION_ERROR__COMPUTATIONAL_BUDGET_EXCEEDED,\n            )\n        ) {\n            // Now we know the root cause of the simulation failure, and can advise the user\n        }\n    }\n}\n```\n\n## Failed transaction errors\n\nWhen a transaction fails to send, Kit raises one of two high-level error codes that wrap whatever actually went wrong with extra context useful for debugging.\n\n### `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION` [#failed-to-send-transaction]\n\nThis is the error you get back when sending a single transaction fails. The message itself indicates whether the failure happened during preflight or after the transaction was submitted; the context exposes the underlying error, simulation logs, the preflight result when available, and the full `TransactionPlanResult` for deeper inspection.\n\n```ts twoslash\nimport { SolanaError } from '@solana/kit';\nconst error = null as unknown as SolanaError;\n// ---cut-before---\nimport { isSolanaError, SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION } from '@solana/kit';\n\nif (isSolanaError(error, SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION)) {\n    console.error(error.message); // Includes \"(preflight)\" or the transaction signature.\n    console.error('Cause:', error.cause); // The underlying error that triggered the failure.\n    console.error('Logs:', error.context.logs); // Program logs, when available.\n    console.error('Preflight:', error.context.preflightData); // Simulation result, when available.\n}\n```\n\nThe full `TransactionPlanResult` is also attached as `error.context.transactionPlanResult`, but it is non-enumerable so it does not pollute serialized errors. Cast it to [`TransactionPlanResult`](/api/type-aliases/TransactionPlanResult) when you need to walk the tree.\n\n### `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS` [#failed-to-send-transactions]\n\nThe plural variant is raised when sending more than one transaction fails. Its context exposes a `failedTransactions` array — one entry per failure, with the underlying error, its position in the plan, simulation logs, and preflight data — plus the same non-enumerable `transactionPlanResult`.\n\n```ts twoslash\nimport { SolanaError } from '@solana/kit';\nconst error = null as unknown as SolanaError;\n// ---cut-before---\nimport { isSolanaError, SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS } from '@solana/kit';\n\nif (isSolanaError(error, SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS)) {\n    for (const { error: cause, index, logs } of error.context.failedTransactions) {\n        console.error(`Transaction #${index + 1} failed:`, cause.message);\n        if (logs) console.error('Logs:', logs);\n    }\n}\n```\n\nEach individual `error` in the array has already been unwrapped from any preflight wrapper, so you can branch on its code directly the same way you would for a standalone `SolanaError`.\n\n## Walking transaction plan results\n\nBoth failed-transaction errors above expose a `transactionPlanResult` you can inspect, and any successful multi-transaction send returns one directly. A [`TransactionPlanResult`](/api/type-aliases/TransactionPlanResult) is a tree that mirrors the original plan, with one of three statuses at each leaf — `successful`, `failed`, or `canceled`. Kit ships a small set of helpers for working with these trees without writing your own recursion.\n\n[`flattenTransactionPlanResult`](/api/functions/flattenTransactionPlanResult) collapses the tree into an array of leaf results, in the order they appear:\n\n```ts twoslash\nimport { TransactionPlanResult } from '@solana/kit';\nconst result = null as unknown as TransactionPlanResult;\n// ---cut-before---\nimport { flattenTransactionPlanResult } from '@solana/kit';\n\nfor (const single of flattenTransactionPlanResult(result)) {\n    if (single.status === 'successful') {\n        console.log('✅', single.context.signature);\n    } else if (single.status === 'failed') {\n        console.error('❌', single.error.message);\n    } else {\n        console.warn('⏭️', 'canceled');\n    }\n}\n```\n\n[`summarizeTransactionPlanResult`](/api/functions/summarizeTransactionPlanResult) bucketizes the leaves into successful, failed, and canceled arrays, plus a single `successful` boolean for the overall outcome:\n\n```ts twoslash\nimport { TransactionPlanResult } from '@solana/kit';\nconst result = null as unknown as TransactionPlanResult;\n// ---cut-before---\nimport { summarizeTransactionPlanResult } from '@solana/kit';\n\nconst summary = summarizeTransactionPlanResult(result);\nconsole.log(`${summary.successfulTransactions.length} ok`);\nconsole.log(`${summary.failedTransactions.length} failed`);\nconsole.log(`${summary.canceledTransactions.length} canceled`);\n```\n\n[`getFirstFailedSingleTransactionPlanResult`](/api/functions/getFirstFailedSingleTransactionPlanResult) is a convenience for when you only care about the first failure in a tree — useful for surfacing a single root cause in error UI:\n\n```ts twoslash\nimport { TransactionPlanResult } from '@solana/kit';\nconst result = null as unknown as TransactionPlanResult;\n// ---cut-before---\nimport { getFirstFailedSingleTransactionPlanResult } from '@solana/kit';\n\nconst failed = getFirstFailedSingleTransactionPlanResult(result);\nconsole.error('First failure:', failed.error.message);\n```\n\nBy default, executors throw [`SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN`](/api/variables/SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN) on any failure. If you would rather inspect a partial result without a `try`/`catch`, [`passthroughFailedTransactionPlanExecution`](/api/functions/passthroughFailedTransactionPlanExecution) catches that error and returns the embedded `TransactionPlanResult` instead.\n\n```ts twoslash\nimport { TransactionPlanResult } from '@solana/kit';\nconst sendTransactionsPromise = null as unknown as Promise<TransactionPlanResult>;\n// ---cut-before---\nimport { passthroughFailedTransactionPlanExecution } from '@solana/kit';\n\nconst result = await passthroughFailedTransactionPlanExecution(sendTransactionsPromise);\n```\n\n## Program-specific errors\n\nCodama-generated program packages export their own error helpers so you can identify and format program-specific failures. The pattern is consistent across packages: an `isXError(error, transactionMessage)` type guard, a `getXErrorMessage(code)` formatter, and an enum-shaped `XError` for individual codes (where `X` is the program name, e.g. `System` for `@solana-program/system`).\n\n```ts twoslash\nimport { SolanaError, TransactionMessage } from '@solana/kit';\nconst error = null as unknown as SolanaError;\nconst transactionMessage = null as unknown as TransactionMessage;\n// ---cut-before---\nimport { getSystemErrorMessage, isSystemError } from '@solana-program/system';\n\nif (isSystemError(error, transactionMessage)) {\n    console.error(`System program error: ${getSystemErrorMessage(error.context.code)}`);\n    console.error(`Failed instruction index: ${error.context.index}`);\n}\n```\n\nWhen sending a transaction or transaction plan, the program-specific error usually lives a few hops down the chain — typically as the `cause` of `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION` or as one of the `failedTransactions[i].error` entries on the plural variant. Pair the helpers above with the failed-transaction errors documented earlier to surface actionable error messages to your users.\n\n## Error messages\n\n### In development mode\n\nWhen your bundler sets the constant `__DEV__` to `true`, every error message will be included in the bundle. As such, you will be able to read them in plain language wherever they appear.\n\n<Callout type=\"warn\">\n    The size of your JavaScript bundle will increase significantly with the inclusion of every error\n    message in development mode. Be sure to build your bundle with `__DEV__` set to `false` when you\n    go to production.\n</Callout>\n\n### In production mode\n\nWhen your bundler sets the constant `__DEV__` to `false`, error messages will be stripped from the bundle to save space. Only the error code will appear in the message when an error is encountered. Follow the instructions in the error message to convert the error code back to the human-readable error message.\n\nFor instance, to recover the error text for the error with code `7050005`:\n\n<Tabs items={[\"pnpm\", \"npm\", \"yarn\", \"bun\"]}>\n  <Tab value=\"pnpm\">\n      ```shell\n      $ pnpm dlx @solana/errors decode -- 7050005\n\n      [Decoded] Solana error code #7050005\n          - Insufficient funds for fee\n      ```\n\n  </Tab>\n  <Tab value=\"npm\">\n      ```shell\n      $ npx @solana/errors decode -- 7050005\n\n      [Decoded] Solana error code #7050005\n          - Insufficient funds for fee\n      ```\n\n  </Tab>\n  <Tab value=\"yarn\">\n      ```shell\n      $ yarn dlx @solana/errors decode -- 7050005\n\n      [Decoded] Solana error code #7050005\n          - Insufficient funds for fee\n      ```\n\n  </Tab>\n  <Tab value=\"bun\">\n      ```shell\n      $ bunx @solana/errors decode -- 7050005\n\n      [Decoded] Solana error code #7050005\n          - Insufficient funds for fee\n      ```\n\n  </Tab>\n</Tabs>\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/index.mdx",
    "content": "---\ntitle: Advanced Guides\ndescription: Deep dives into Kit's fundamental building blocks\n---\n\nThese guides go deep on the core building blocks Kit is built from — transactions, signers, instruction plans, errors, codecs, keypairs, and more. Each one is a reference you can dip into when you want to understand exactly how something works under the hood.\n\nThe [Guides](/docs/guides) section covers the practical, task-oriented workflows most applications need day to day, and [plugin-based clients](/docs/plugins) take care of much of this automatically. Reach for the Advanced Guides when you are debugging an unexpected behavior, building a custom plugin, working without a client, or simply curious about what is happening underneath.\n\nYou can read these guides in any order — start with the topic that is closest to what you are working on.\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/instruction-plans.mdx",
    "content": "---\ntitle: Instruction Plans\ndescription: Compose instructions into multi-step operations\n---\n\n## Introduction\n\nInstruction plans describe operations that go beyond a single instruction and may even span multiple transactions.\n\nThey define a set of instructions that must be executed following a specific order. For instance, imagine we wanted to create an instruction plan for a simple escrow transfer between Alice and Bob. First, both would need to deposit their assets into a vault. This could happen in any order. Then and only then, the vault can be activated to switch the assets. Alice and Bob can now both withdraw each other's assets (again, in any order). Here's how we could describe an instruction plan for such an operation.\n\n```ts twoslash\nimport { Instruction, sequentialInstructionPlan, parallelInstructionPlan } from '@solana/kit';\nconst depositFromAlice = {} as unknown as Instruction;\nconst depositFromBob = {} as unknown as Instruction;\nconst activateVault = {} as unknown as Instruction;\nconst withdrawToAlice = {} as unknown as Instruction;\nconst withdrawToBob = {} as unknown as Instruction;\n// ---cut-before---\nconst instructionPlan = sequentialInstructionPlan([\n    parallelInstructionPlan([depositFromAlice, depositFromBob]),\n    activateVault,\n    parallelInstructionPlan([withdrawToAlice, withdrawToBob]),\n]);\n```\n\nAs you can see, instruction plans don't concern themselves with:\n\n- Adding structural instructions — e.g. compute budget limits and prices.\n- Building transaction messages from these instructions. That is, planning how many can fit into a single instruction, adding a fee payer, a lifetime, etc.\n- Compiling, signing and sending transactions to the network.\n\nInstead, they solely focus on describing operations and delegate all that to two components introduced in this package:\n\n- **Transaction planner**: builds transaction messages from an instruction plan and returns an appropriate transaction plan.\n- **Transaction plan executor**: compiles, signs and sends transaction plans and returns a detailed result of this operation.\n\n```ts twoslash\nimport { TransactionPlanner, TransactionPlanExecutor, InstructionPlan } from '@solana/kit';\nconst instructionPlan = {} as unknown as InstructionPlan;\nconst transactionPlanner = {} as unknown as TransactionPlanner;\nconst transactionPlanExecutor = {} as unknown as TransactionPlanExecutor;\n// ---cut-before---\n// Plan instructions into transactions.\nconst transactionPlan = await transactionPlanner(instructionPlan);\n\n// Execute transactions.\nconst transactionPlanResult = await transactionPlanExecutor(transactionPlan);\n```\n\nThis separation of concerns not only improves the developer experience but also allows program maintainers to offer helper functions that go beyond a single instruction, while leaving their consumers to decide how they want these operations to materialise.\n\n## Installation\n\nInstruction plans are **included within the `@solana/kit` library** but you may also install them using their standalone package.\n\n```package-install\n@solana/instruction-plans\n```\n\n## Creating instruction plans\n\nThis package offers several helpers to help you compose your own instruction plans. Let's have a look at them.\n\n### Single instructions\n\nThe most trivial way to create an instruction plan is to use the `singleInstructionPlan` helper to create a plan with only one instruction.\n\n```ts twoslash\nimport { singleInstructionPlan, Instruction } from '@solana/kit';\nconst transferSol = {} as unknown as Instruction;\n// ---cut-before---\nconst instructionPlan = singleInstructionPlan(transferSol);\n```\n\n### Sequential plans\n\nThe `sequentialInstructionPlan` helper allows you to create plans from other plans that must be executed sequentially. Therefore, in the example below, we guarantee that Bob will receive assets from Alice before sending them to Carla.\n\n```ts twoslash\nimport { singleInstructionPlan, sequentialInstructionPlan, Instruction } from '@solana/kit';\nconst transferFromAliceToBob = {} as unknown as Instruction;\nconst transferFromBobToCarla = {} as unknown as Instruction;\n// ---cut-before---\nconst instructionPlan = sequentialInstructionPlan([\n    singleInstructionPlan(transferFromAliceToBob),\n    singleInstructionPlan(transferFromBobToCarla),\n]);\n```\n\nNote that the `sequentialInstructionPlan` helper also accept `Instruction` objects directly and automatically wraps them in `singleInstructionPlans`. Therefore the following is equivalent to the previous example.\n\n```ts twoslash\nimport { sequentialInstructionPlan, Instruction } from '@solana/kit';\nconst transferFromAliceToBob = {} as unknown as Instruction;\nconst transferFromBobToCarla = {} as unknown as Instruction;\n// ---cut-before---\nconst instructionPlan = sequentialInstructionPlan([transferFromAliceToBob, transferFromBobToCarla]);\n```\n\nA `nonDivisibleSequentialInstructionPlan` helper is also available to define sequential plans whose inner instructions should all be executed atomically. That is, either in a single transaction or in a transaction bundle when not possible.\n\n```ts twoslash\nimport { nonDivisibleSequentialInstructionPlan, Instruction } from '@solana/kit';\nconst createAccount = {} as unknown as Instruction;\nconst initializeMint = {} as unknown as Instruction;\n// ---cut-before---\nconst instructionPlan = nonDivisibleSequentialInstructionPlan([createAccount, initializeMint]);\n```\n\nIn this example, we know that both instruction will either succeed or fail together.\n\n### Parallel plans\n\nThe `parallelInstructionPlan` function can be used to create plans from other plans that can be executed in parallel. This means direct children of this plan can be executed in separate parallel transactions without consequence. For instance, in the example below, Alice can transfer assets to both Bob and Carla in any order without affecting the final outcome.\n\n```ts twoslash\nimport { singleInstructionPlan, parallelInstructionPlan, Instruction } from '@solana/kit';\nconst transferFromAliceToBob = {} as unknown as Instruction;\nconst transferFromAliceToCarla = {} as unknown as Instruction;\n// ---cut-before---\nconst instructionPlan = parallelInstructionPlan([\n    singleInstructionPlan(transferFromAliceToBob),\n    singleInstructionPlan(transferFromAliceToCarla),\n]);\n```\n\nThe `parallelInstructionPlan` also accepts `Instruction` object directly and therefore the previous example can be simplified as:\n\n```ts twoslash\nimport { parallelInstructionPlan, Instruction } from '@solana/kit';\nconst transferFromAliceToBob = {} as unknown as Instruction;\nconst transferFromAliceToCarla = {} as unknown as Instruction;\n// ---cut-before---\nconst instructionPlan = parallelInstructionPlan([transferFromAliceToBob, transferFromAliceToCarla]);\n```\n\n### Message packer plans\n\nMessage packer plans are a bit special. They can dynamically pack instructions into transaction messages. This is particularly useful when packing instructions whose size will vary based on the available space left on the transaction message being packed.\n\nFor instance, imagine a `write` instruction on a program that gradually write data from instructions into a buffer account. The instruction data used in this case will ideally be as long as the transaction message can fit. Using the `getLinearMessagePackerInstructionPlan` helper, we can create an instruction plan that does just that.\n\n```ts twoslash\nimport { getLinearMessagePackerInstructionPlan, Instruction } from '@solana/kit';\nconst dataToWrite = {} as unknown as Uint8Array;\nconst getWriteInstruction = {} as unknown as (params: {\n    offset: number;\n    data: Uint8Array;\n}) => Instruction;\n// ---cut-before---\nconst instructionPlan = getLinearMessagePackerInstructionPlan({\n    totalLength: dataToWrite.length,\n    getInstruction: (offset, length) =>\n        getWriteInstruction({\n            offset,\n            data: dataToWrite.slice(offset, offset + length),\n        }),\n});\n```\n\nAs you can see, the `getLinearMessagePackerInstructionPlan` helper accepts a `totalLength` attribute representing the total amount of bytes we eventually want to write to the buffer. The purpose of the `getInstruction` function is then to generate these `write` instructions at the provided positions.\n\nThere also exists a `getReallocMessagePackerInstructionPlan` helper that works similarly but whose purpose is to pack multiple realloc instructions to help resize an account.\n\n```ts twoslash\nimport { getReallocMessagePackerInstructionPlan, Instruction } from '@solana/kit';\nconst additionalDataSize = {} as unknown as number;\nconst getExtendInstruction = {} as unknown as (params: { length: number }) => Instruction;\n// ---cut-before---\nconst instructionPlan = getReallocMessagePackerInstructionPlan({\n    totalSize: additionalDataSize,\n    getInstruction: (size) => getExtendInstruction({ length: size }),\n});\n```\n\nWhilst these helpers are fairly situational, you can create any custom message packer as long as you implement the following interfaces.\n\n```ts twoslash\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/kit';\n// ---cut-before---\ntype MessagePackerInstructionPlan = {\n    getMessagePacker: () => MessagePacker;\n    kind: 'messagePacker';\n};\n\ntype MessagePacker = {\n    done: () => boolean;\n    packMessageToCapacity: (\n        transactionMessage: TransactionMessage & TransactionMessageWithFeePayer,\n    ) => TransactionMessage & TransactionMessageWithFeePayer;\n};\n```\n\nMost of your custom logic will live in the `packMessageToCapacity` function whose purpose is to pack the provided message with as many instruction datas as possible or throw when it isn't achievable. The `done` function lets us know if there is any instruction data left to pack. See [`MessagePacker`](/api/type-aliases/MessagePacker) for more information.\n\n### Combining plans\n\nIt is worth noting that more complex operations can be created by combining plans together. For instance, the following plan will:\n\n- Create two accounts in parallel, one Buffer account and one Metadata account.\n    - The Buffer account will be written to via multiple parallel `write` instructions.\n    - The Metadata account will be created and initialized atomically.\n- Once both of these accounts are created, the data in the Buffer account will be used to set the data in the Metadata account before being closed.\n\n```ts twoslash\nimport {\n    sequentialInstructionPlan,\n    nonDivisibleSequentialInstructionPlan,\n    parallelInstructionPlan,\n    Instruction,\n    MessagePackerInstructionPlan,\n} from '@solana/kit';\nconst createAccount1 = {} as unknown as Instruction;\nconst createAccount2 = {} as unknown as Instruction;\nconst initializeBuffer = {} as unknown as Instruction;\nconst initializeMetadata = {} as unknown as Instruction;\nconst setMetadataFromBuffer = {} as unknown as Instruction;\nconst closeBuffer = {} as unknown as Instruction;\nconst writeMessagePacker = {} as unknown as MessagePackerInstructionPlan;\n// ---cut-before---\nconst instructionPlan = sequentialInstructionPlan([\n    parallelInstructionPlan([\n        sequentialInstructionPlan([\n            createAccount1,\n            initializeBuffer,\n            parallelInstructionPlan([writeMessagePacker]),\n        ]),\n        nonDivisibleSequentialInstructionPlan([createAccount2, initializeMetadata]),\n    ]),\n    setMetadataFromBuffer,\n    closeBuffer,\n]);\n```\n\n## Planning instructions\n\nOnce we have an instruction plan, the first step is to build transaction messages from it in the most optimal way whilst satisfying all the constraints defined in the instruction plan. This is the role of **transaction planners**.\n\n### Transaction planners\n\nTransaction planners are defined as simple abortable functions that transform a given instruction plan into a set of built transaction messages called a **transaction plan**.\n\n```ts twoslash\nimport { TransactionPlanner, InstructionPlan } from '@solana/kit';\nconst transactionPlanner = {} as unknown as TransactionPlanner;\nconst instructionPlan = {} as unknown as InstructionPlan;\nconst abortSignal = {} as unknown as AbortSignal;\n// ---cut-before---\nconst transactionPlan = await transactionPlanner(instructionPlan, { abortSignal });\n```\n\n### Creating a transaction planner\n\nTo spin up a transaction planner, you may use the `createTransactionPlanner` helper. This helper requires a `createTransactionMessage` function that tells us how each new transaction message should be created before being packed with instructions.\n\nFor instance, in the example below we create a new planner such that each planned transaction message will be using version 0 and using the `payer` signer as a fee payer.\n\n```ts twoslash\nimport {\n    createTransactionPlanner,\n    pipe,\n    createTransactionMessage,\n    setTransactionMessageFeePayerSigner,\n    TransactionSigner,\n} from '@solana/kit';\nconst payer = {} as unknown as TransactionSigner;\n// ---cut-before---\nconst transactionPlanner = createTransactionPlanner({\n    createTransactionMessage: () =>\n        pipe(\n            createTransactionMessage({ version: 0 }),\n            (message) => setTransactionMessageFeePayerSigner(payer, message),\n            // ...\n        ),\n});\n```\n\nAdditionally, the `onTransactionMessageUpdated` function may be provided to update transaction messages during the planning process. This function will be called whenever a transaction message is updated — e.g. when new instructions are added. It accepts the updated transaction message and must return a transaction message back, even if no changes were made.\n\nIn the example below, we check if the packed transaction contains an instruction that transfers SOL and, if so, add a guard instruction that ensures no more than 1 SOL is transferred.\n\n```ts twoslash\nimport {\n    appendTransactionMessageInstruction,\n    createTransactionPlanner,\n    TransactionMessage,\n    Instruction,\n} from '@solana/kit';\nconst createTransactionMessage = {} as unknown as Parameters<\n    typeof createTransactionPlanner\n>[0]['createTransactionMessage'];\nconst containsTransferSolInstruction = {} as unknown as (message: TransactionMessage) => boolean;\nconst transferSolGuardInstruction = {} as unknown as Instruction;\n// ---cut-before---\nconst transactionPlanner = createTransactionPlanner({\n    createTransactionMessage,\n    onTransactionMessageUpdated: (message) => {\n        if (containsTransferSolInstruction(message)) {\n            return appendTransactionMessageInstruction(\n                transferSolGuardInstruction,\n                message,\n            ) as unknown as typeof message;\n        }\n\n        return message;\n    },\n});\n```\n\nCheck out the [Recipes section](#recipes) at this end of this guide for ideas of what can be achieved with this API.\n\n### Transaction plans\n\nSince transaction planners output transaction plans, it may be useful to see what these look like.\n\nThey work similarly to instruction plans but they wrap transaction messages instead of instructions and do not contain message packers.\n\n- [`singleTransactionPlan`](/api/functions/singleTransactionPlan). Wraps a built transaction message.\n- [`sequentialTransactionPlan`](/api/functions/sequentialTransactionPlan): Wraps other transaction plans that must be executed sequentially.\n- [`nonDivisibleSequentialTransactionPlan `](/api/functions/nonDivisibleSequentialTransactionPlan): Wraps other transaction plans that must be executed sequentially and atomically. Since atomicity is at the transaction level, this suggests transaction bundles should be used if possible. Otherwise, the plan should fail to execute.\n- [`parallelTransactionPlan`](/api/functions/parallelTransactionPlan): Wraps other transaction plans that may be executed in parallel.\n\n```ts twoslash\nimport {\n    singleTransactionPlan,\n    sequentialTransactionPlan,\n    parallelTransactionPlan,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/kit';\nconst messageA = {} as unknown as TransactionMessage & TransactionMessageWithFeePayer;\nconst messageB = {} as unknown as TransactionMessage & TransactionMessageWithFeePayer;\nconst messageC = {} as unknown as TransactionMessage & TransactionMessageWithFeePayer;\n// ---cut-before---\nconst transactionPlan = parallelTransactionPlan([\n    sequentialTransactionPlan([singleTransactionPlan(messageA), singleTransactionPlan(messageB)]),\n    singleTransactionPlan(messageC),\n]);\n```\n\n### Advanced transaction planners\n\nWhilst the `createTransactionPlanner` helper is designed to suit most projects, it may not suit yours. If so, you may create your own by offering a function that satisfy the following signature.\n\n```ts twoslash\nimport { InstructionPlan, TransactionPlan } from '@solana/kit';\n// ---cut-before---\ntype TransactionPlanner = (\n    instructionPlan: InstructionPlan,\n    config?: { abortSignal?: AbortSignal },\n) => Promise<TransactionPlan>;\n```\n\n## Executing transactions\n\nNow that we have obtained a transaction plan from our instruction plan, the next and final step is to send these transactions using a **transaction plan executor**.\n\n### Transaction plan executors\n\nTransaction plan executors are defined as abortable functions that transform a given transaction plan into a mirrored data structure that contains the execution status of each transaction. That data structure is called a **transaction plan result**.\n\n```ts twoslash\nimport { TransactionPlanExecutor, TransactionPlan } from '@solana/kit';\nconst transactionPlanExecutor = {} as unknown as TransactionPlanExecutor;\nconst transactionPlan = {} as unknown as TransactionPlan;\nconst abortSignal = {} as unknown as AbortSignal;\n// ---cut-before---\nconst transactionPlanResult = await transactionPlanExecutor(transactionPlan, { abortSignal });\n```\n\n### Creating a transaction plan executor\n\nTo spin up a transaction plan executor, you may use the `createTransactionPlanExecutor` helper. This helper requires an `executeTransactionMessage` function that tells us how each transaction message should be executed when encountered during the execution process.\n\nThe `executeTransactionMessage` callback receives the following arguments:\n\n- **`context`**: A mutable object for storing data during execution — see the [next section](#the-execution-context) for details.\n- **`message`**: The transaction message to execute.\n- **`config`**: An optional configuration object that may include an `abortSignal`.\n\nThe callback must return either a `Signature` or a full `Transaction` object directly.\n\nFor instance, in the example below we create a new executor such that each transaction message will be assigned the latest blockhash lifetime before being signed and sent to the network using the provided RPC client.\n\n```ts twoslash\nimport {\n    sendAndConfirmTransactionFactory,\n    createTransactionPlanExecutor,\n    Rpc,\n    SolanaRpcApi,\n    RpcSubscriptions,\n    SolanaRpcSubscriptionsApi,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signTransactionMessageWithSigners,\n    assertIsSendableTransaction,\n    assertIsTransactionWithBlockhashLifetime,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/kit';\nconst rpc = {} as unknown as Rpc<SolanaRpcApi>;\nconst rpcSubscriptions = {} as unknown as RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n// ---cut-before---\nconst sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n\nconst transactionPlanExecutor = createTransactionPlanExecutor({\n    executeTransactionMessage: async (context, message) => {\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n        const messageWithBlockhash = setTransactionMessageLifetimeUsingBlockhash(\n            latestBlockhash,\n            message,\n        );\n        context.message = messageWithBlockhash;\n        const transaction = await signTransactionMessageWithSigners(messageWithBlockhash);\n        context.transaction = transaction;\n        assertIsSendableTransaction(transaction);\n        assertIsTransactionWithBlockhashLifetime(transaction);\n        await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n        return transaction;\n    },\n});\n```\n\n### The execution context\n\nThe `context` object passed to the `executeTransactionMessage` callback is a mutable object that you can populate incrementally as execution progresses. This context is preserved in the resulting `SingleTransactionPlanResult` regardless of the outcome — successful, failed, or canceled.\n\nThis is particularly useful for debugging failures or building recovery plans. If an error is thrown at any point in the callback, any attributes you've already saved to the context will still be available in the `FailedSingleTransactionPlanResult`.\n\nThe context object supports three optional base properties that have semantic meaning:\n\n- **`message`**: The transaction message after any modifications (e.g., after setting a lifetime).\n- **`transaction`**: The signed transaction ready to be sent.\n- **`signature`**: The transaction signature. Note that this is automatically populated when you set the `transaction` property on the context and/or return a `Transaction`.\n\nYou can also add any custom properties you need:\n\n```ts twoslash\nimport {\n    createTransactionPlanExecutor,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signTransactionMessageWithSigners,\n    sendAndConfirmTransactionFactory,\n    assertIsSendableTransaction,\n    assertIsTransactionWithBlockhashLifetime,\n    Rpc,\n    SolanaRpcApi,\n    RpcSubscriptions,\n    SolanaRpcSubscriptionsApi,\n} from '@solana/kit';\nconst rpc = {} as unknown as Rpc<SolanaRpcApi>;\nconst rpcSubscriptions = {} as unknown as RpcSubscriptions<SolanaRpcSubscriptionsApi>;\nconst sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n// ---cut-before---\nconst transactionPlanExecutor = createTransactionPlanExecutor({\n    executeTransactionMessage: async (context, message) => {\n        // Store the start time (custom context).\n        context.startedAt = Date.now();\n\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n        const messageWithBlockhash = setTransactionMessageLifetimeUsingBlockhash(\n            latestBlockhash,\n            message,\n        );\n\n        // Store the message about to be signed.\n        context.message = messageWithBlockhash;\n\n        const transaction = await signTransactionMessageWithSigners(messageWithBlockhash);\n\n        // Store the transaction about to be sent.\n        context.transaction = transaction;\n\n        assertIsSendableTransaction(transaction);\n        assertIsTransactionWithBlockhashLifetime(transaction);\n        await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n\n        // Store the confirmation time (custom context).\n        context.confirmedAt = Date.now();\n\n        return transaction;\n    },\n});\n```\n\nWhen accessing the context from a result, you can retrieve both the base properties and your custom properties:\n\n```ts twoslash\nimport {\n    SingleTransactionPlanResult,\n    isSuccessfulSingleTransactionPlanResult,\n    isFailedSingleTransactionPlanResult,\n} from '@solana/kit';\nconst result = {} as unknown as SingleTransactionPlanResult<{ startedAt: number }>;\n// ---cut-before---\nif (isSuccessfulSingleTransactionPlanResult(result)) {\n    console.log(result.context.signature); // Always available for successful results.\n    console.log(result.context.transaction); // Available if you stored it.\n    console.log(result.context.startedAt); // Custom context property.\n}\n\nif (isFailedSingleTransactionPlanResult(result)) {\n    console.log(result.error); // The error that caused the failure.\n    console.log(result.context.message); // Available if stored before the failure.\n    console.log(result.context.transaction); // Available if stored before the failure.\n    console.log(result.context.startedAt); // Custom context property.\n}\n```\n\nCheck out the [Recipes section](#recipes) at this end of this guide for ideas of what can be achieved with this API.\n\n### Transaction plan results\n\nWhen you execute a transaction plan, you get back a `TransactionPlanResult` that tells you what happened during execution. This result object has the same tree structure as your original transaction plan, but includes execution information for each transaction message.\n\nEach transaction message in your plan can have one of three execution outcomes:\n\n- **Successful** - The transaction was sent and confirmed. You get the original planned message, a context object containing the signature (and optionally the transaction), plus any custom context data.\n- **Failed** - The transaction encountered an error. You get the original planned message, the error that caused the failure, and a context object with any data accumulated before the failure.\n- **Canceled** - The transaction was skipped because an earlier transaction failed or the operation was aborted. You get the original planned message with any context data accumulated before cancellation.\n\nThe result structure mirrors your transaction plan structure:\n\n- Single transaction messages become `SingleTransactionPlanResult` with the original `plannedMessage` plus execution status\n- Sequential plans become `SequentialTransactionPlanResult` containing child results\n- Parallel plans become `ParallelTransactionPlanResult` containing child results\n\nEach `SingleTransactionPlanResult` has a `status` property that is a string literal (`'successful'`, `'failed'`, or `'canceled'`), and properties like `context`, `error` live at the top level of each variant.\n\n```ts twoslash\nimport {\n    parallelTransactionPlan,\n    singleTransactionPlan,\n    parallelTransactionPlanResult,\n    successfulSingleTransactionPlanResultFromTransaction,\n    failedSingleTransactionPlanResult,\n    isSuccessfulSingleTransactionPlanResult,\n    isFailedSingleTransactionPlanResult,\n    SolanaError,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    Transaction,\n} from '@solana/kit';\nconst messageA = {} as unknown as TransactionMessage & TransactionMessageWithFeePayer;\nconst messageB = {} as unknown as TransactionMessage & TransactionMessageWithFeePayer;\nconst transactionA = {} as unknown as Transaction;\nconst error = {} as unknown as SolanaError;\n// ---cut-before---\n// If your transaction plan looked like this:\nconst plan = parallelTransactionPlan([\n    singleTransactionPlan(messageA),\n    singleTransactionPlan(messageB),\n]);\n\n// Your result may look like this:\nconst result = parallelTransactionPlanResult([\n    successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n    failedSingleTransactionPlanResult(messageB, error),\n]);\n\n// Access the signature from a successful result:\nif (isSuccessfulSingleTransactionPlanResult(result.plans[0])) {\n    console.log(result.plans[0].context.signature);\n    console.log(result.plans[0].context.transaction); // If available\n}\n\n// Access the error from a failed result:\nif (isFailedSingleTransactionPlanResult(result.plans[1])) {\n    console.log(result.plans[1].error);\n    console.log(result.plans[1].context.signature); // If available\n    console.log(result.plans[1].context.transaction); // If available\n}\n```\n\n### Failed transaction executions\n\nWhen a transaction plan executor — created via the `createTransactionPlanExecutor` helper — encounters a failed transaction, it will cancel all remaining transactions in the plan. The executor will then throw a `SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN` error code.\n\nThis error contains a `transactionPlanResult` property (accessible as a non-enumerable property) that provides detailed information about which transactions succeeded, failed, or were canceled.\n\n```ts twoslash\nimport {\n    TransactionPlan,\n    TransactionPlanExecutor,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n    isSolanaError,\n    TransactionPlanResult,\n} from '@solana/kit';\nconst transactionPlan = {} as unknown as TransactionPlan;\nconst transactionPlanExecutor = {} as unknown as TransactionPlanExecutor;\n// ---cut-before---\ntry {\n    const result = await transactionPlanExecutor(transactionPlan);\n} catch (error) {\n    if (isSolanaError(error, SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN)) {\n        // Access the failed `TransactionPlanResult` to understand what happened.\n        const result = error.context.transactionPlanResult as TransactionPlanResult;\n    }\n}\n```\n\n### Advanced transaction plan executors\n\nWhilst the `createTransactionPlanExecutor` helper is designed to suit most projects, it may not suit yours. If so, you may create your own by offering a function that satisfies the following signature.\n\n```ts twoslash\nimport { TransactionPlan, TransactionPlanResult } from '@solana/kit';\n// ---cut-before---\ntype TransactionPlanExecutor = (\n    transactionPlan: TransactionPlan,\n    config?: { abortSignal?: AbortSignal },\n) => Promise<TransactionPlanResult>;\n```\n\nThis allows you to implement custom execution strategies, such as using transaction bundles for atomic execution or adding custom transaction prioritization.\n\n<Callout type=\"info\">\n    Bundled clients such as `solanaRpc` and `litesvm` install ready-to-use planner and executor\n    implementations on the client. See [Available plugins](/docs/plugins/available-plugins) for the\n    full list, and [Sending multiple transactions](/docs/guides/sending-multiple-transactions) for\n    the consumer-facing API they expose.\n</Callout>\n\n## Recipes\n\nHere are some common patterns and recipes for using instruction plans effectively.\n\n### Setting priority fees\n\nYou can set priority fees by using the [`setTransactionMessageComputeUnitPrice`](/api/functions/setTransactionMessageComputeUnitPrice) helper from `@solana/kit` in your `createTransactionMessage` function. See [Configuring compute and priority fees](/docs/advanced-guides/transactions#configuring-priority-fees) for the full set of fee setters, including the v1 [`setTransactionMessagePriorityFeeLamports`](/api/functions/setTransactionMessagePriorityFeeLamports) variant.\n\n```ts twoslash\nimport {\n    createTransactionPlanner,\n    pipe,\n    createTransactionMessage,\n    setTransactionMessageFeePayerSigner,\n    TransactionSigner,\n} from '@solana/kit';\nconst payer = {} as unknown as TransactionSigner;\n// ---cut-before---\nimport { setTransactionMessageComputeUnitPrice } from '@solana/kit'; // [!code ++]\n\nconst transactionPlanner = createTransactionPlanner({\n    createTransactionMessage: () =>\n        pipe(\n            createTransactionMessage({ version: 0 }),\n            (message) => setTransactionMessageFeePayerSigner(payer, message),\n            // [!code ++:2]\n            // Set priority fees to 0.01 lamports per compute unit.\n            (message) => setTransactionMessageComputeUnitPrice(10_000n, message),\n        ),\n});\n```\n\n### Estimating compute units\n\nYou can estimate and set compute unit limits dynamically by using a two-step process:\n\n- First, add a provisory compute unit limit (if missing) in your transaction planner.\n- Then, estimate and update it right before sending the transaction.\n\nThe [`fillTransactionMessageProvisoryComputeUnitLimit`](/api/functions/fillTransactionMessageProvisoryComputeUnitLimit) helper from `@solana/kit` reserves the limit by setting it to a provisory value of `0`, so the planner can account for the resulting compute budget instruction when packing transaction messages. See [Estimating the compute unit limit](/docs/advanced-guides/transactions#configuring-compute-unit-limit-estimation) for the full estimator API.\n\n```ts twoslash\nimport {\n    createTransactionPlanner,\n    pipe,\n    createTransactionMessage,\n    setTransactionMessageFeePayerSigner,\n    TransactionSigner,\n} from '@solana/kit';\nconst payer = {} as unknown as TransactionSigner;\n// ---cut-before---\nimport { fillTransactionMessageProvisoryComputeUnitLimit } from '@solana/kit'; // [!code ++]\n\nconst transactionPlanner = createTransactionPlanner({\n    createTransactionMessage: () =>\n        pipe(\n            createTransactionMessage({ version: 0 }),\n            (message) => setTransactionMessageFeePayerSigner(payer, message),\n            (message) => fillTransactionMessageProvisoryComputeUnitLimit(message), // [!code ++]\n        ),\n});\n```\n\nThen, pair [`estimateComputeUnitLimitFactory`](/api/functions/estimateComputeUnitLimitFactory) with [`estimateAndSetComputeUnitLimitFactory`](/api/functions/estimateAndSetComputeUnitLimitFactory) in your transaction plan executor to estimate the compute units right before sending the transaction.\n\n```ts twoslash\nimport {\n    sendAndConfirmTransactionFactory,\n    createTransactionPlanExecutor,\n    Rpc,\n    SolanaRpcApi,\n    RpcSubscriptions,\n    SolanaRpcSubscriptionsApi,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signTransactionMessageWithSigners,\n    assertIsSendableTransaction,\n    assertIsTransactionWithBlockhashLifetime,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/kit';\nconst rpc = {} as unknown as Rpc<SolanaRpcApi>;\nconst rpcSubscriptions = {} as unknown as RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n// ---cut-before---\n// [!code ++:4]\nimport {\n    estimateAndSetComputeUnitLimitFactory,\n    estimateComputeUnitLimitFactory,\n} from '@solana/kit';\n\nconst sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n// [!code ++:2]\nconst estimateCULimit = estimateComputeUnitLimitFactory({ rpc });\nconst estimateAndSetCULimit = estimateAndSetComputeUnitLimitFactory(estimateCULimit);\n\nconst transactionPlanExecutor = createTransactionPlanExecutor({\n    executeTransactionMessage: async (context, message) => {\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n        const messageWithBlockhash = setTransactionMessageLifetimeUsingBlockhash(\n            latestBlockhash,\n            message,\n        );\n        context.message = messageWithBlockhash;\n        const estimatedMessage = await estimateAndSetCULimit(messageWithBlockhash); // [!code ++]\n        context.message = estimatedMessage; // [!code ++]\n        const transaction = await signTransactionMessageWithSigners(estimatedMessage);\n        context.transaction = transaction;\n        assertIsSendableTransaction(transaction);\n        assertIsTransactionWithBlockhashLifetime(transaction);\n        await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n        return transaction;\n    },\n});\n```\n\n### Durable nonce executor\n\nYou may create transaction plans that use durable nonces for offline transaction signing by using the `setTransactionMessageLifetimeUsingDurableNonce` helper in your transaction planner.\n\n```ts twoslash\nimport {\n    createTransactionPlanner,\n    pipe,\n    createTransactionMessage,\n    setTransactionMessageFeePayerSigner,\n    TransactionSigner,\n} from '@solana/kit';\nconst payer = {} as unknown as TransactionSigner;\nconst config = {} as unknown as Parameters<\n    typeof setTransactionMessageLifetimeUsingDurableNonce\n>['0'];\nconst nonce = config.nonce;\nconst nonceAccountAddress = config.nonceAccountAddress;\nconst nonceAuthorityAddress = config.nonceAuthorityAddress;\n// ---cut-before---\nimport { setTransactionMessageLifetimeUsingDurableNonce } from '@solana/kit'; // [!code ++]\n\nconst transactionPlanner = createTransactionPlanner({\n    createTransactionMessage: () => {\n        return pipe(\n            createTransactionMessage({ version: 0 }),\n            (message) => setTransactionMessageFeePayerSigner(payer, message),\n            // [!code ++:5]\n            (message) =>\n                setTransactionMessageLifetimeUsingDurableNonce(\n                    { nonce, nonceAccountAddress, nonceAuthorityAddress },\n                    message,\n                ),\n        );\n    },\n});\n```\n\nThen, make sure to use the `sendAndConfirmDurableNonceTransactionFactory` helper in your transaction plan executor in order to use the appropriate confirmation strategy for your transactions.\n\n```ts twoslash\nimport {\n    createTransactionPlanExecutor,\n    Rpc,\n    SolanaRpcApi,\n    RpcSubscriptions,\n    SolanaRpcSubscriptionsApi,\n    signTransactionMessageWithSigners,\n    assertIsSendableTransaction,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    assertIsTransactionWithDurableNonceLifetime,\n} from '@solana/kit';\nconst rpc = {} as unknown as Rpc<SolanaRpcApi>;\nconst rpcSubscriptions = {} as unknown as RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n// ---cut-before---\n// [!code ++:4]\nimport {\n    assertIsTransactionMessageWithDurableNonceLifetime,\n    sendAndConfirmDurableNonceTransactionFactory,\n} from '@solana/kit';\n\n// [!code ++:4]\nconst sendAndConfirmDurableNonceTransaction = sendAndConfirmDurableNonceTransactionFactory({\n    rpc,\n    rpcSubscriptions,\n});\n\nconst transactionPlanExecutor = createTransactionPlanExecutor({\n    executeTransactionMessage: async (context, message) => {\n        assertIsTransactionMessageWithDurableNonceLifetime(message); // [!code ++]\n        context.message = message;\n        const transaction = await signTransactionMessageWithSigners(message);\n        context.transaction = transaction;\n        assertIsSendableTransaction(transaction);\n        assertIsTransactionWithDurableNonceLifetime(transaction);\n        await sendAndConfirmDurableNonceTransaction(transaction, { commitment: 'confirmed' }); // [!code ++]\n        return transaction;\n    },\n});\n```\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/keypairs.mdx",
    "content": "---\ntitle: Key pairs\ndescription: Sign and verify messages and transactions using Ed25519 keys\n---\n\n## Introduction\n\nKit uses the primitives built-in to JavaScript’s Web Crypto API to perform cryptography. This keeps your applications small, and confers to them the security and performance characteristics of the runtime's native cryptography functions.\n\nEd25519 keys created or imported using the native APIs are compatible with all of Kit's cryptographic features. Kit also offers several helpers to generate, import, and transform key material.\n\n<Callout title=\"Looking for Signers instead?\">\n    Keys are a low-level primitive. While it's important to know how they work, in a Solana\n    application it's often more appropriate to deal with key material in terms of the accounts and\n    wallets that sign a transaction or message. The [Signers](/docs/advanced-guides/signers) API\n    offers an ergonomic way to build and sign transactions using accounts and their associated keys.\n</Callout>\n\n## Installation\n\nKey management functions are **included within the `@solana/kit` library** but you may also install them using their standalone package.\n\n```package-install\n@solana/keys\n```\n\n<Callout title=\"Not all runtimes support the cryptography required by Solana\" type=\"warn\">\n    When deploying your application to a JavaScript runtime that lacks support for the Ed25519\n    digital signature algorithm, [import our polyfill](#polyfill) before invoking any operations\n    that create or make use of `CryptoKey` objects.\n</Callout>\n\n## What is a key pair?\n\nA key pair is a data type composed of 256-bits of random data (the private key) and a Cartesian point (the public key) on the curve that is used to cryptographically sign and verify Solana transactions. The interface definition of `CryptoKeyPair` is:\n\n```ts\ninterface CryptoKeyPair {\n    privateKey: CryptoKey;\n    publicKey: CryptoKey;\n}\n```\n\nTogether, these keys represent an address on Solana and its owner. The 256-bit address is derived from the coordinates of the public key itself.\n\n## What is a key?\n\nA key is an object native to the JavaScript runtime that supports the [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) interface. You can use a `CryptoKey` with the native [`SubtleCrypto` API](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) to sign messages and to verify signatures. Kit builds on these capabilities to enable the use of `CryptoKey` objects to sign and verify Solana transactions and off-chain messages.\n\n## Managing keys\n\n### Generating new keys\n\nYou can use the native [`SubtleCrypto#generateKey`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey) API, or the [`generateKeyPair()`](/api/functions/generateKeyPair) helper to create a new random key pair.\n\n<Tabs items={[\"SubtleCrypto API\", \"Kit\"]}>\n  <Tab value=\"SubtleCrypto API\">\n      ```ts twoslash\n      const keyPair = await crypto.subtle.generateKey(\n        /* algorithm */ { name: 'Ed25519' },\n        /* extractable */ false,\n        /* usages */ ['sign', 'verify'],\n      );\n      ```\n  </Tab>\n  <Tab value=\"Kit\">\n    ```ts twoslash\n    import { generateKeyPair } from '@solana/kit';\n    const keyPair = await generateKeyPair();\n    ```\n  </Tab>\n</Tabs>\n\nThis is useful in cases where you need to sign for the creation of a new account with a random address, using an ephemeral key pair that can be discarded after the account is created and assigned to a program.\n\n### Importing a key\n\nYou can create a `CryptoKeyPair` using the 64 bytes of a pre-generated key. This is possible to do with the native [`SubtleCrypto#importKey`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey) API, but it is more convenient to use the helpers in Kit.\n\n```ts twoslash\nimport { createKeyPairFromBytes } from '@solana/kit';\nconst keyPair = await createKeyPairFromBytes(\n    new Uint8Array([\n        /* 32 bytes representing the private key */\n        /* 32 bytes representing the public key */\n    ]),\n);\n```\n\nIn cases where you have only the 32 bytes representing the private key but not its associated public key, you can use a different function that will automatically derive the public key from the private key.\n\n```ts twoslash\nimport { createKeyPairFromPrivateKeyBytes } from '@solana/kit';\nconst keyPair = await createKeyPairFromPrivateKeyBytes(\n    new Uint8Array([\n        /* 32 bytes representing the private key */\n    ]),\n);\n```\n\n### Storing keys\n\n`CryptoKey` objects can be stored locally by runtimes that support the [IndexedDB API](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API).\n\nGiven an instance of an `IDBDatabase` with an object store called `'MyKeyPairStore'`:\n\n```ts twoslash\nconst db = await new Promise<IDBDatabase>((resolve, reject) => {\n    const request = indexedDB.open('MyDatabase', 1);\n    request.onupgradeneeded = (e) => {\n        const db = (e.target as IDBOpenDBRequest).result;\n        db.createObjectStore('MyKeyPairStore');\n    };\n    request.onsuccess = (e) => {\n        resolve((e.target as IDBOpenDBRequest).result);\n    };\n    request.onerror = (e) => {\n        reject((e.target as IDBOpenDBRequest).error);\n    };\n});\n```\n\nYou can store a key pair like this:\n\n```ts twoslash\nconst db = null as unknown as IDBDatabase;\nconst keyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\nconst transaction = db.transaction('MyKeyPairStore', 'readwrite');\nconst store = transaction.objectStore('MyKeyPairStore');\nawait new Promise<void>((resolve, reject) => {\n    const request = store.put(keyPair, 'myStoredKey');\n    request.onsuccess = () => resolve();\n    request.onerror = () => reject(request.error);\n});\n```\n\nAnd then later retrieve it like this:\n\n```ts twoslash\nconst db = null as unknown as IDBDatabase;\n// ---cut-before---\nconst transaction = db.transaction('MyKeyPairStore', 'readonly');\nconst store = transaction.objectStore('MyKeyPairStore');\nconst loadedKeyPair = await new Promise<CryptoKeyPair>((resolve, reject) => {\n    const request = store.get('myStoredKey');\n    request.onsuccess = () => {\n        if (request.result) {\n            resolve(request.result);\n        } else {\n            reject(new Error('Key not found'));\n        }\n    };\n    request.onerror = () => reject(request.error);\n});\n```\n\n<Callout type=\"warn\">\n    Keys stored in IndexedDB are local to the host, are subject to its [storage limits and eviction\n    criteria](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API#storage_limits_and_eviction_criteria),\n    and can not be accessed from a domain other than the one that stored them when the host is a web\n    browser. Keys that are evicted from storage or erased by the user can generally not be\n    recovered.\n</Callout>\n\n### Exporting a key\n\nYou can obtain the 32 bytes of any public key like this:\n\n```ts twoslash\nconst keyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\nconst publicKeyBytes = new Uint8Array(await crypto.subtle.exportKey('raw', keyPair.publicKey));\n```\n\nExporting private key material requires a specially constructed `CryptoKey` with its extractable property set to `true`.\n\n```ts twoslash\nconst keyPair = await crypto.subtle.generateKey(\n    /* algorithm */ { name: 'Ed25519' },\n    /* extractable */ true,\n    //                ^^^^\n    /* usages */ ['sign', 'verify'],\n);\n```\n\nYou can then use that `CryptoKey` with the [`SubtleCrypto#exportKey`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey) API. The last 32 bytes of a PKCS#8 export of the key are the private key bytes.\n\n```ts twoslash\nconst keyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\nconst exportedPrivateKey = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey);\nconst privateKeyBytes = new Uint8Array(exportedPrivateKey, exportedPrivateKey.byteLength - 32, 32);\n```\n\n<Callout title=\"Security warning\" type=\"warn\">\n    Exporting private key material in JavaScript is not recommended, and you should take extreme\n    care when doing so. Private key bytes exported through these APIs are vulnerable to theft (eg.\n    by code running in your JavaScript sandbox) and accidental logging (eg. to the console or to a\n    third-party logger).\n</Callout>\n\n## Using private keys\n\nA private key is a `CryptoKey` whose `type` property is set to `'private'` and whose `usages` property includes `'sign'`.\n\nPrivate keys can be used by their owner to produce a digital signature of a specific message. You can think of a signature as representing the key owner's approval of, agreement to, or endorsement of the message. Private key owners must never share the key with anyone.\n\n### Signing messages\n\nAny data that you can serialize as a `Uint8Array` can be signed with a `CryptoKey`.\n\n```ts twoslash\nimport { ReadonlyUint8Array } from '@solana/kit';\n// ---cut-before---\nimport { getU32Encoder, getUtf8Encoder } from '@solana/kit';\nconst messageFromText = getUtf8Encoder().encode('🎉');\nconst messageFromU32 = getU32Encoder().encode(0xdeadbeef);\nconst messageOfBytes = new Uint8Array([1, 2, 3]);\n```\n\nSupply a message and a private key to the [`signBytes()`](/api/functions/signBytes) function to obtain a 64-byte digital signature.\n\n```ts twoslash\nconst bobsKeyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\nimport { getUtf8Encoder, signBytes } from '@solana/kit';\nconst message = getUtf8Encoder().encode('The meeting is at 6:00pm');\nconst bobsSignature = await signBytes(bobsKeyPair.privateKey, message);\nconsole.log(bobsSignature);\n// @log: Uint8Array(64) [79, 43, 140, 65, 177, 35, 169, 61, 62, 228, 190, 202, 205, 143, 4, 35, 83, 228, 47, 76, 68, 62, 125, 140, 21, 102, 182, 105, 24, 238, 67, 40, 179, 255, 247, 136, 95, 119, 46, 244, 44, 224, 100, 111, 68, 110, 189, 224, 159, 144, 197, 181, 210, 132, 101, 226, 120, 200, 0, 102, 104, 65, 216, 3]\n```\n\n<Callout type=\"info\">\n    The same message and private key might produce a different signature every time you call this\n    function. Some runtimes produce randomized signatures as per\n    [draft-irtf-cfrg-det-sigs-with-noise](https://datatracker.ietf.org/doc/draft-irtf-cfrg-det-sigs-with-noise/)\n    while others produce deterministic signatures as per [RFC\n    8032](https://www.rfc-editor.org/rfc/rfc8032).\n</Callout>\n\n### Signing transactions\n\nIn Kit, private keys are used to digitally sign transactions on behalf of account owners, to approve spending, transfers, and modifications to account data on the blockchain.\n\n```ts twoslash\nimport { Transaction, TransactionWithLifetime } from '@solana/kit';\nconst transaction = null as unknown as Transaction & TransactionWithLifetime;\nconst bobsKeyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\nimport { signTransaction } from '@solana/kit';\nconst signedTransaction = await signTransaction([bobsKeyPair], transaction);\n```\n\nIn practice, it's rare to sign transactions like this. Typically, you create a transaction message in your application, specify which accounts are required to sign it using the [Signers API](/docs/advanced-guides/signers), and then call [`signTransactionMessageWithSigners`](/api/functions/signTransactionMessageWithSigners) to turn it into a signed `Transaction`.\n\n## Using public keys\n\nA public key is a `CryptoKey` whose `type` property is set to `'public'` and whose `usages` property includes `'verify'`.\n\nSolana uses public keys to verify that modifications to account data and balances through transactions are approved of by those who hold the private keys required to authorize such modifications. Kit generally only uses public keys to derive the address of their associated accounts, but it can also use public keys to enable your programs to verify arbitrary messages.\n\n### Verifying signatures\n\nThe public key associated with a given private key can be used by anyone to verify that a message was signed by the holder of the associated private key, as described above. The verification function requires the original message, a digital signature, and the public key associated with the owner who is believed to have produced that signature. Successful verification implies that the contents of the message signed by the owner are identical to the contents of the message that was given to the verification function. Key owners are free to share their public key with anyone they would like to grant the ability to verify their digital signatures.\n\nIf someone sends us a message and signature that they claim to be from the example above, we could use Bob's public key to verify that the signature was in fact the one produced by Bob and that the message was not modified in transit.\n\n```ts twoslash\nimport { SignatureBytes } from '@solana/kit';\nconst bobsPublicKey = null as unknown as CryptoKey;\nconst supposedlyBobsSignature = null as unknown as SignatureBytes;\n// ---cut-before---\nimport { getUtf8Encoder, verifySignature } from '@solana/kit';\nconst verificationSucceeded = await verifySignature(\n    bobsPublicKey,\n    supposedlyBobsSignature,\n    getUtf8Encoder().encode('The meeting is at 6:00pm'),\n);\nif (!verificationSucceeded) {\n    throw new Error(\n        'Either the message was modified, the signature was not produced by Bob, or both',\n    );\n}\n```\n\nVerification protects equally against false claims of who produced the signature as it does against false claims about what message was signed. Both of these will return `false`;\n\n{/* prettier-ignore */}\n```ts twoslash\nimport { SignatureBytes } from '@solana/kit';\nconst bobsPublicKey = null as unknown as CryptoKey;\nconst bobsSignature = null as unknown as SignatureBytes;\nconst mallorysSignature = null as unknown as SignatureBytes;\nconst signature = null as unknown as SignatureBytes;\n// ---cut-before---\nimport { getUtf8Encoder, verifySignature } from '@solana/kit';\n// False claim that Bob signed the message when it was in fact Mallory\nawait verifySignature(\n    bobsPublicKey,\n    mallorysSignature,\n  //^^^^^^^^^^^^^^^^^\n    getUtf8Encoder().encode('The meeting is at 6:00pm'),\n);\n// False claim about the contents of the message\nawait verifySignature(\n    bobsPublicKey,\n    bobsSignature,\n    getUtf8Encoder().encode('The meeting is at 6:00am'),\n    //                                         ^^^^^^\n);\n```\n\n### Deriving addresses\n\nThe Solana address associated with any public key can be derived using the [`getAddressFromPublicKey()`](/api/functions/getAddressFromPublicKey) function.\n\n```ts twoslash\nconst keyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\nimport { getAddressFromPublicKey } from '@solana/kit';\nconst address = await getAddressFromPublicKey(keyPair.publicKey);\n```\n\n## Signatures\n\nThe [`SignatureBytes`](/api/type-aliases/SignatureBytes) type represents a 64-byte Ed25519 signature, and the [`Signature`](/api/type-aliases/Signature) type represents such a signature as a base58-encoded string.\n\nWhen you acquire a string that you expect to be a base58-encoded signature (eg. of a transaction) from an untrusted network API or user input you can assert it is in fact a base58-encoded byte array of sufficient length using the [`assertIsSignature()`](/api/functions/assertIsSignature) function.\n\n```ts twoslash\n// @noErrors: 1308\nimport { GetSignatureStatusesApi, Rpc } from '@solana/kit';\nconst rpc = null as unknown as Rpc<GetSignatureStatusesApi>;\nconst signatureInput = null as unknown as HTMLInputElement;\n// ---cut-before---\nimport { assertIsSignature } from '@solana/kit';\n\n// Imagine a function that asserts whether a user-supplied signature is valid or not.\nfunction handleSubmit() {\n    // We know only that what the user typed conforms to the `string` type.\n    const signature: string = signatureInput.value;\n    try {\n        // If this type assertion function doesn't throw, then\n        // Typescript will upcast `signature` to `Signature`.\n        assertIsSignature(signature);\n        // At this point, `signature` is a `Signature` that can be used with the RPC.\n        const {\n            value: [status],\n        } = await rpc.getSignatureStatuses([signature]).send();\n    } catch (e) {\n        // `signature` turned out not to be a base58-encoded signature\n    }\n}\n```\n\nSimilarly, you can use the [`isSignature()`](/api/functions/isSignature) type guard. It will return `true` if the input string conforms to the `Signature` type and will refine the type for use in your program from that point onward. This method does not throw in the opposite case.\n\n```ts twoslash\nimport { GetSignatureStatusesApi, Rpc } from '@solana/kit';\nconst rpc = null as unknown as Rpc<GetSignatureStatusesApi>;\nconst signature = '';\nfunction setError(s: string) {}\nfunction setSignatureStatus(\n    s: ReturnType<GetSignatureStatusesApi['getSignatureStatuses']>['value'][number],\n) {}\n// ---cut-before---\nimport { isSignature } from '@solana/kit';\n\nif (isSignature(signature)) {\n    // At this point, `signature` has been refined to a\n    // `Signature` that can be used with the RPC.\n    const {\n        value: [status],\n    } = await rpc.getSignatureStatuses([signature]).send();\n    setSignatureStatus(status);\n} else {\n    setError(`${signature} is not a transaction signature`);\n}\n```\n\nThe [`signature()`](/api/functions/signature) helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the `Signature` type. It's best used with untrusted input.\n\n```ts\nimport { signature } from '@solana/kit';\n\nconst signature = signature(userSuppliedSignature);\nconst {\n    value: [status],\n} = await rpc.getSignatureStatuses([signature]).send();\n```\n\n## Runtime Support\n\nAll major JavaScript runtimes support the Ed25519 digital signature algorithm required by Solana.\n\n|                      | Runtime              | Min version   | Since    |\n| -------------------: | -------------------- | ------------- | -------- |\n| **Desktop browsers** | Chrome               | v137          | May 2025 |\n|                      | Edge                 | v137          | May 2025 |\n|                      | Firefox              | v130          | Sep 2024 |\n|                      | Safari               | v17           | Sep 2023 |\n|  **Mobile browsers** | Android browser      | v137          | May 2025 |\n|                      | Firefox for Android  | v139          | May 2025 |\n|                      | Mobile Safari        | iOS 17        | Sep 2023 |\n|  **Server runtimes** | Bun                  | v1.2.6        | Mar 2025 |\n|                      | Cloudflare `workerd` | v1.20230419.0 | Apr 2023 |\n|                      | Deno                 | v1.26.1       | Oct 2022 |\n|                      | Node.js              | v18.4.0       | Jun 2022 |\n|                      | Vercel Edge          | v2.3.0        | May 2023 |\n\nFor additional up-to-date details on runtimes' implementation status, visit https://github.com/WICG/webcrypto-secure-curves/issues/20.\n\n### Ed25519 Polyfill [#polyfill]\n\nTo use keys in a runtime without Ed25519 digital signature algorithm support, install the following polyfill.\n\n```package-install\n@solana/webcrypto-ed25519-polyfill\n```\n\nThen import and install it before invoking any operations that create or make use of `CryptoKey` objects.\n\n```ts twoslash\nimport { install } from '@solana/webcrypto-ed25519-polyfill';\n\n// Calling this will shim methods on `SubtleCrypto`, adding Ed25519 support.\ninstall();\n\n// Now you can do this, in environments that do not otherwise support Ed25519.\nconst keyPair = await crypto.subtle.generateKey({ name: 'Ed25519' }, false, ['sign']);\n```\n\nWherever you call `install()`, make sure the call is made only once, and before any key operation requiring Ed25519 support is performed.\n\n<Callout title=\"Security warning\" type=\"warn\">\n    Because the polyfill's implementation of Ed25519 key generation exists in userspace, it can't\n    guarantee that the keys you generate with it are non-exportable. Untrusted code running in your\n    JavaScript context may still be able to gain access to and/or exfiltrate secret key material.\n</Callout>\n\n<Callout title=\"Storing polyfilled keys in IndexedDB\" type=\"warn\">\n    Native `CryptoKeys` can be stored in IndexedDB, but the keys created by this polyfill can not.\n    This is because, unlike native `CryptoKeys`, our polyfilled key objects can not implement the\n    [structured clone algorithm](https://www.w3.org/TR/WebCryptoAPI/#cryptokey-interface-clone).\n</Callout>\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/kit-without-a-client.mdx",
    "content": "---\ntitle: Kit without a client\ndescription: Use Kit's full power without the client abstraction\n---\n\nThis guide shows how to achieve the same capabilities a [Kit client](/docs/plugins) gives you, but using Kit's primitives directly. The page is organized as a reference: each section takes one piece of what a fully composed client offers and shows the manual equivalent, so you can pick and choose the exact bits you need.\n\n## When to skip the client\n\nGoing client-less is the right choice when you want the smallest possible bundles, full control over every step of the transaction lifecycle, or when you are writing library code that should not assume a Kit client. The cost is a little more boilerplate and a less prescriptive structure. The client model, on the other hand, gives you consistent ergonomics and a curated set of plugin interfaces other plugins can build on.\n\nIf you need ergonomics on top of a curated set of primitives, consider [creating a custom plugin bundle](/docs/plugins/creating-custom-plugins) instead. A bundle plugin is just a regular plugin that composes several smaller ones, so you keep the client model while owning exactly which primitives are wired up.\n\n## Set up RPC\n\nKit ships two factories for talking to a Solana RPC node: `createSolanaRpc` for HTTP requests and `createSolanaRpcSubscriptions` for the WebSocket channel. Both return typed proxies with the full Solana JSON-RPC API surface available on them.\n\n```ts twoslash\nimport { createSolanaRpc, createSolanaRpcSubscriptions } from '@solana/kit';\n\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\nconst rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.devnet.solana.com');\n```\n\nThe objects returned by these factories are exactly what `client.rpc` and `client.rpcSubscriptions` expose under the hood, so any code that takes an `Rpc` or `RpcSubscriptions` works in either setup. See [RPC requests](/docs/guides/rpc) and [RPC subscriptions](/docs/guides/rpc-subscriptions) for the user-facing API.\n\n## Create a signer\n\nThe most common way to create a signer is to generate a fresh in-memory keypair with `generateKeyPairSigner`. The returned object is a `KeyPairSigner` that satisfies both the `TransactionSigner` and `MessageSigner` interfaces.\n\n```ts twoslash\nimport { generateKeyPairSigner } from '@solana/kit';\n\nconst signer = await generateKeyPairSigner();\n```\n\nIf you already have a keypair stored as a JSON byte array — for example, a Solana CLI keypair file — you can rebuild a signer from it with `createKeyPairSignerFromBytes`. See [Setting up signers](/docs/guides/setting-up-signers) for the broader signer setup story and [Advanced guides — Signers](/docs/advanced-guides/signers) for the underlying signer interfaces.\n\n```ts twoslash\nimport { createKeyPairSignerFromBytes } from '@solana/kit';\nimport { readFileSync } from 'node:fs';\n\nconst bytes = JSON.parse(readFileSync('keypair.json', 'utf-8')) as number[];\nconst signer = await createKeyPairSignerFromBytes(new Uint8Array(bytes));\n```\n\n## Build a transaction message\n\nKit transaction messages are immutable: each helper returns a new object with a narrower type, so TypeScript can enforce that required fields are set before the message is signed or sent. The `pipe` helper threads a value through a sequence of transformations and lets the type narrow at each step.\n\n```ts twoslash\nimport {\n    appendTransactionMessageInstructions,\n    createTransactionMessage,\n    Instruction,\n    pipe,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n} from '@solana/kit';\n// ---cut-start---\nimport { createSolanaRpc, generateKeyPairSigner } from '@solana/kit';\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\nconst signer = await generateKeyPairSigner();\nconst instructionA = {} as Instruction;\nconst instructionB = {} as Instruction;\n// ---cut-end---\nconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n\nconst transactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    (tx) => setTransactionMessageFeePayerSigner(signer, tx),\n    (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n    (tx) => appendTransactionMessageInstructions([instructionA, instructionB], tx),\n);\n```\n\nThis is the same composition the bundled clients use internally. See [Advanced guides — Transactions](/docs/advanced-guides/transactions) for the full transaction message API, including durable-nonce lifetimes and other configuration helpers.\n\n## Estimate compute units\n\nSetting an explicit compute unit limit close to what your transaction actually consumes increases the chance of inclusion, packs more transactions per block, and reduces priority fees. Kit ships everything you need for this without leaving `@solana/kit`: `estimateComputeUnitLimitFactory` simulates the message to estimate the cost, and `estimateAndSetComputeUnitLimitFactory` wraps that estimator to write the result back onto the message in one step.\n\n```ts twoslash\nimport {\n    estimateAndSetComputeUnitLimitFactory,\n    estimateComputeUnitLimitFactory,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/kit';\n// ---cut-start---\nimport { createSolanaRpc } from '@solana/kit';\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\nconst transactionMessage = {} as TransactionMessage & TransactionMessageWithFeePayer;\n// ---cut-end---\nconst estimateComputeUnitLimit = estimateComputeUnitLimitFactory({ rpc });\nconst estimateAndSetComputeUnitLimit =\n    estimateAndSetComputeUnitLimitFactory(estimateComputeUnitLimit);\n\nconst transactionMessageWithLimit = await estimateAndSetComputeUnitLimit(transactionMessage);\n```\n\nBundled clients such as `solanaRpc` and `litesvm` already do this for you when sending transactions.\n\n## Sign the transaction\n\nOnce a transaction message is fully configured, `signTransactionMessageWithSigners` extracts every signer attached to it (the fee payer plus any signer-typed instruction inputs) and produces a signed `Transaction`.\n\n```ts twoslash\nimport {\n    signTransactionMessageWithSigners,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/kit';\n// ---cut-start---\nconst transactionMessage = {} as TransactionMessage & TransactionMessageWithFeePayer;\n// ---cut-end---\nconst signedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n```\n\nTwo assertions are typically useful at this point: `assertIsSendableTransaction` verifies the transaction has every required signature and fits within the size limit, and `assertIsTransactionWithBlockhashLifetime` narrows the lifetime so it can be passed to `sendAndConfirmTransactionFactory` below. The transaction identifier on Solana is the fee payer's signature, which is fully determined as soon as the fee payer signs — `getSignatureFromTransaction(signedTransaction)` returns that identifier directly, without needing to send the transaction first.\n\n## Send and confirm a transaction\n\n`sendAndConfirmTransactionFactory` builds a function that sends a signed transaction and waits for the configured commitment. It needs both an `rpc` and an `rpcSubscriptions` because confirmation listens to slot and signature notifications.\n\n```ts twoslash\nimport {\n    SendableTransaction,\n    sendAndConfirmTransactionFactory,\n    Transaction,\n    TransactionWithBlockhashLifetime,\n} from '@solana/kit';\n// ---cut-start---\nimport { createSolanaRpc, createSolanaRpcSubscriptions } from '@solana/kit';\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\nconst rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.devnet.solana.com');\nconst signedTransaction = {} as Transaction &\n    SendableTransaction &\n    TransactionWithBlockhashLifetime;\n// ---cut-end---\nconst sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\nawait sendAndConfirmTransaction(signedTransaction, { commitment: 'confirmed' });\n```\n\nFor durable-nonce transactions, use `sendAndConfirmDurableNonceTransactionFactory` instead, which knows how to confirm against a nonce account instead of a recent blockhash. If you don't need confirmation at all, `sendTransactionWithoutConfirmingFactory` returns a fire-and-forget sender. All three return `Promise<void>`; pair them with `getSignatureFromTransaction` to obtain the signature for logging or display.\n\n## Fetch and decode accounts\n\nTo read onchain state, `fetchEncodedAccount` wraps `getAccountInfo` and returns a `MaybeEncodedAccount` whose shape is consistent regardless of whether the account exists. `assertAccountExists` narrows the result so the rest of your code can rely on a fully populated account.\n\n```ts twoslash\nimport { address, assertAccountExists, fetchEncodedAccount } from '@solana/kit';\n// ---cut-start---\nimport { createSolanaRpc } from '@solana/kit';\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\n// ---cut-end---\nconst account = await fetchEncodedAccount(\n    rpc,\n    address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ'),\n);\nassertAccountExists(account);\n\naccount.data satisfies Uint8Array;\n```\n\nFor typed reads, the `@solana-program/*` packages export `fetchX` and `decodeX` standalone helpers that take any `Rpc` and return decoded `Account<T>` values without needing a Kit client. See [Fetching accounts](/docs/guides/fetching-accounts) for the full helper line-up and [Codecs](/docs/advanced-guides/codecs) for decoding raw bytes when no helper is available.\n\n## Next steps\n\n- [Plugins](/docs/plugins) — opt back in to the client model when you want it.\n- [Plugins — Creating custom plugins](/docs/plugins/creating-custom-plugins) — wrap a curated set of primitives into a reusable bundle.\n- [Advanced guides — Transactions](/docs/advanced-guides/transactions) — the full transaction message API.\n- [Advanced guides — Signers](/docs/advanced-guides/signers) — the signer interfaces in depth.\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/meta.json",
    "content": "{\n    \"title\": \"Advanced Guides\",\n    \"defaultOpen\": true,\n    \"pages\": [\"kit-without-a-client\", \"...\"]\n}\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/offchain-messages.mdx",
    "content": "---\ntitle: Offchain messages\ndescription: Build, compile, sign, and verify messages offchain\n---\n\n## Introduction\n\nAny time you want one or more parties to approve of something that is not governed by an onchain program, you can prepare a message for them to sign offchain. Such messages can contain arbitrary contents, like the text of a plain-language contract, or some data encoded as text. Each offchain message contains a list of one or more signers that must provide a signature over that encoded message. Only when all of the required signers provide an authentic signature over the message are its contents considered to be ratified. You can use Kit to create, sign, verify, encode, and decode offchain messages.\n\n## Installation\n\nOffchain message utilities are **included within the `@solana/kit` library** but you may also install them using their standalone packages.\n\nTo install the offchain message utilities:\n\n```package-install\n@solana/offchain-messages\n```\n\n## What is an offchain message?\n\nAn offchain message consists of some UTF-8 message text, and a list of one or more required signers. The message is considered ratified when all of the signers provide a signature over the encoded message.\n\nHere is an example of a contract being proposed by one person as an offchain message, and ratified by another.\n\n<Tabs items={[\"Proposing a message\", \"Ratifying a message\", \"Verifying a message\"]}>\n  <Tab value=\"Proposing a message\">\n    ```ts twoslash\n    const ursulaKeypair = null as unknown as CryptoKeyPair;\n    // ---cut-before---\n    import {\n        Address,\n        createSignerFromKeyPair,\n        getOffchainMessageEnvelopeEncoder,\n        OffchainMessage,\n        partiallySignOffchainMessageWithSigners,\n    } from '@solana/kit';\n\n    // Ursula creates the contract as an offchain message.\n    const ursulaSigner = await createSignerFromKeyPair(ursulaKeypair);\n    const offchainMessage: OffchainMessage = {\n        content:\n            \"Ursula grants Ariel three days as a human, in exchange for Ariel's voice, on the \" +\n            'condition that Ariel secures a kiss of true love from Prince Eric before the third ' +\n            'sunset to remain human permanently. If Ariel fails, she reverts to a mermaid and ' +\n            \"becomes Ursula's property.\",\n        requiredSignatories: [\n            ursulaSigner,\n            { address: 'ARiEL3q7uXvN9yZK8s2a5GfpHmQdR7cBv' as Address },\n        ],\n        version: 1,\n    };\n\n    // Ursula partially signs the message, producing an offchain message envelope.\n    const offchainMessageEnvelope =\n        await partiallySignOffchainMessageWithSigners(offchainMessage);\n\n    // Ursula encodes the offchain message envelope to share with Ariel.\n    const offchainMessageEnvelopeBytes =\n        getOffchainMessageEnvelopeEncoder().encode(offchainMessageEnvelope);\n    ```\n    </Tab>\n    <Tab value=\"Ratifying a message\">\n        ```ts twoslash\n        import { ReadonlyUint8Array } from '@solana/kit';\n        const arielKeypair = null as unknown as CryptoKeyPair;\n        const offchainMessageEnvelopeBytes = null as unknown as ReadonlyUint8Array;\n        // ---cut-before---\n        import { getOffchainMessageEnvelopeCodec, signOffchainMessageEnvelope } from '@solana/kit';\n\n        // Ariel decodes the offchain message envelope received from Ursula.\n        const offchainMessageEnvelope =\n            getOffchainMessageEnvelopeCodec().decode(offchainMessageEnvelopeBytes);\n\n        // To ratify the contract, she signs the message.\n        const fullySignedOffchainMessageEnvelope =\n            await signOffchainMessageEnvelope([arielKeypair], offchainMessageEnvelope);\n\n        // Ariel encodes the fully signed offchain message envelope to share with Ursula.\n        const fullySignedOffchainMessageEnvelopeBytes =\n            getOffchainMessageEnvelopeCodec().encode(fullySignedOffchainMessageEnvelope);\n        ```\n    </Tab>\n\n    <Tab value=\"Verifying a message\">\n        ```ts twoslash\n        import { ReadonlyUint8Array, OffchainMessageEnvelope } from '@solana/kit';\n        const offchainMessageEnvelope = null as unknown as OffchainMessageEnvelope;\n        const receivedOffchainMessageEnvelopeBytes = null as unknown as ReadonlyUint8Array;\n        // ---cut-before---\n        import {\n            bytesEqual,\n            getOffchainMessageEnvelopeDecoder,\n            isSolanaError,\n            verifyOffchainMessageEnvelope,\n            SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE,\n        } from '@solana/kit';\n\n        // Upon receipt of the signed message envelope bytes from Ariel, Ursula decodes them.\n        const receivedOffchainMessageEnvelope =\n            getOffchainMessageEnvelopeDecoder().decode(receivedOffchainMessageEnvelopeBytes);\n\n        // For good measure, Ursula verifies that the message bytes are the exact ones she sent.\n        if (!bytesEqual(receivedOffchainMessageEnvelope.content, offchainMessageEnvelope.content)) {\n            throw new Error('I do not accept this modified contract');\n        }\n\n        // Ursula then verifies the signatures on the envelope.\n        try {\n            await verifyOffchainMessageEnvelope(receivedOffchainMessageEnvelope);\n            console.log('We have a deal!');\n        } catch(e) {\n            if (isSolanaError(e, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE)) {\n                console.error('We do not have a deal!');\n            } else {\n                throw e;\n            }\n        }\n        ```\n    </Tab>\n\n</Tabs>\n\n## Building offchain messages\n\nUse the [`OffchainMessage`](/api/type-aliases/OffchainMessage) type to help you create an offchain message.\n\n### Specifying the version\n\nSpecify the `version` property to select the schema and capabilities of the message. The latest version is version `1` which corresponds to the specification found in [sRFC 3](https://github.com/solana-foundation/SRFCs/discussions/3).\n\n```ts twoslash\n// @noErrors: 2322\nimport { address, OffchainMessage } from '@solana/kit';\n\nconst offchainMessage: OffchainMessage = {\n    // [!code ++:1]\n    version: 1,\n    /* ... */\n};\n```\n\n<Callout type=\"info\">\n    The format and construction of v0 messages is beyond the scope of this guide. You can read the\n    v0 specification [here](https://docs.solanalabs.com/proposals/off-chain-message-signing).\n</Callout>\n\n### Required signatories\n\nEach message must specify a list of addresses belonging to accounts that must sign the message in order for it to be considered valid.\n\n#### Using a signer [!toc]\n\nYou can declare one or more required signatories using a [`MessageSigner`](/api/interfaces/MessageSigner).\n\n```ts twoslash\nconst myKeyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\n// @noErrors: 2322\nimport { createSignerFromKeyPair, OffchainMessage } from '@solana/kit';\n\nconst messageSigner = await createSignerFromKeyPair(myKeyPair);\nconst offchainMessage: OffchainMessage = {\n    version: 1,\n    // [!code ++:1]\n    requiredSignatories: [messageSigner],\n    /* ... */\n};\n```\n\nWhen you do so, the message will have the capability to self-sign using the [`signOffchainMessageWithSigners`](/api/functions/signOffchainMessageWithSigners) method. Follow the [instructions for signing offchain message envelopes with `CryptoKeyPairs`](#signing-offchain-message-envelopes) to sign it.\n\n#### Using an address [!toc]\n\nYou can declare one or more required signatories for whom you don't control the private key using the addresses of their accounts.\n\n```ts twoslash\nconst myKeyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\n// @noErrors: 2322\nimport { address, OffchainMessage } from '@solana/kit';\n\nconst offchainMessage: OffchainMessage = {\n    version: 1,\n    // [!code ++:1]\n    requiredSignatories: [{ address: address('EkMpZ4tPqt7LgNCWjbNQ4WhuzFuitdwp8JPxSbCWXy9x') }],\n    /* ... */\n};\n```\n\n### Defining the message content\n\nEach message must contain some non-empty UTF-8 text the signatories must agree upon.\n\n#### Using text [!toc]\n\nThe content can be a string of UTF-8 text.\n\n```ts twoslash\nconst myKeyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\nimport { address, createSignerFromKeyPair, OffchainMessage } from '@solana/kit';\n\nconst messageSigner = await createSignerFromKeyPair(myKeyPair);\nconst offchainMessage: OffchainMessage = {\n    version: 1,\n    requiredSignatories: [\n        messageSigner,\n        { address: address('r5FsobNdd53imrHH4rrdAt1MNkkJUjNPBTNqvKe9igR') },\n    ],\n    // [!code ++:1]\n    content: '🥓 Crispy bacon is better than floppy bacon.',\n};\n```\n\n#### Using data [!toc]\n\nYou can also encode arbitrary data as text using an encoding such as base-64.\n\n```ts twoslash\nimport { ReadonlyUint8Array } from '@solana/kit';\nconst bytes = null as unknown as ReadonlyUint8Array;\nconst myKeyPair = null as unknown as CryptoKeyPair;\n// ---cut-before---\nimport { address, createSignerFromKeyPair, getBase64Decoder, OffchainMessage } from '@solana/kit';\n\nconst messageSigner = await createSignerFromKeyPair(myKeyPair);\nconst offchainMessage: OffchainMessage = {\n    version: 1,\n    requiredSignatories: [\n        messageSigner,\n        { address: address('r5FsobNdd53imrHH4rrdAt1MNkkJUjNPBTNqvKe9igR') },\n    ],\n    // [!code ++:1]\n    content: getBase64Decoder().decode(bytes),\n};\n```\n\n## Signing offchain messages\n\nIn order to be considered ratified an offchain message must be signed by all of the private keys belonging to accounts that are required signatories of the message.\n\n- [`FullySignedOffchainMessageEnvelope`](/api/type-aliases/FullySignedOffchainMessageEnvelope): An offchain message that is signed by all of its required signatories.\n- [`OffchainMessageEnvelope`](/api/interfaces/OffchainMessageEnvelope): A compiled offchain message encoded as bytes, paired with a map between its required signatory addresses and their provided signatures, if any.\n\nOffchain messages whose signers are specified using `MessageSigner` objects have the ability to self-sign. This is because signers encapsulate both the address of the signing account as well as an implementation of the signing algorithm for the private key associated with that account.\n\nThe [`signOffchainMessageWithSigners`](/api/functions/signOffchainMessageWithSigners) method will return a new signed offchain message envelope of type `FullySignedOffchainMessageEnvelope`.\n\n```ts twoslash\nimport { OffchainMessage } from '@solana/kit';\nconst offchainMessage = null as unknown as OffchainMessage;\n// ---cut-before---\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING,\n    isSolanaError,\n    signOffchainMessageWithSigners,\n} from '@solana/kit';\n\ntry {\n    const fullySignedOffchainMessageEnvelope =\n        await signOffchainMessageWithSigners(offchainMessage);\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING)) {\n        console.error('Missing signers for the following addresses:', e.context.addresses);\n    } else {\n        throw e;\n    }\n}\n```\n\n<Callout type=\"warn\">\n    This function will throw if the offchain message does not carry a `MessageSigner` implementation\n    for every required signer. To partially sign a message that you know to carry a strict subset of\n    the required `MessageSigners`, use the\n    [`partiallySignOffchainMessageWithSigners`](/api/functions/partiallySignOffchainMessageWithSigners)\n    method.\n</Callout>\n\nBuilding offchain messages using `MessageSigners` is the recommended way to create self-signable offchain messages. To sign with a `CryptoKey` directly, you first have to compile the offchain message.\n\n```ts twoslash\nimport { OffchainMessage } from '@solana/kit';\nconst offchainMessage = null as unknown as OffchainMessage;\n// ---cut-before---\nimport { compileOffchainMessageEnvelope } from '@solana/kit';\n\nconst offchainMessageEnvelope = compileOffchainMessageEnvelope(offchainMessage);\n```\n\nThis produces an unsigned offchain message envelope. Follow the [instructions for signing offchain message envelopes with `CryptoKeyPairs`](#signing-offchain-message-envelopes) to sign it.\n\n<Callout type=\"info\">\n    If the version of the offchain message is known, use the compile function specific to that\n    version, such as\n    [`compileOffchainMessageV1Envelope`](/api/functions/compileOffchainMessageV1Envelope). This will\n    prevent you from bundling compilers you don't need, saving space in your JavaScript bundle.\n</Callout>\n\n## Signing offchain message envelopes\n\nWherever you have a `OffchainMessageEnvelope` instead of an `OffchainMessage` you can add or replace a signature using the `signOffchainMessageEnvelope` method and one or more `CryptoKeyPairs`.\n\n```ts twoslash\nimport { OffchainMessageEnvelope } from '@solana/kit';\nconst keyPair = null as unknown as CryptoKeyPair;\nconst offchainMessageEnvelope = null as unknown as OffchainMessageEnvelope;\n// ---cut-before---\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING,\n    isSolanaError,\n    signOffchainMessageEnvelope,\n} from '@solana/kit';\n\ntry {\n    const fullySignedOffchainMessageEnvelope = await signOffchainMessageEnvelope(\n        [keyPair],\n        offchainMessageEnvelope,\n    );\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING)) {\n        console.error('Missing signers for the following addresses:', e.context.addresses);\n    } else {\n        throw e;\n    }\n}\n```\n\n<Callout type=\"warn\">\n    This function will throw if the resultant offchain message envelope is missing a signature for\n    one of the offchain message's required signers. To partially sign an offchain message envelope,\n    use the\n    [`partiallySignOffchainMessageEnvelope`](/api/functions/partiallySignOffchainMessageEnvelope)\n    method.\n</Callout>\n\n## Verifying an offchain message\n\nGiven an offchain message envelope, you can verify that it has been signed by all of its required signatories using the [`verifyOffchainMessageEnvelope`](/api/functions/verifyOffchainMessageEnvelope) method.\n\n```ts twoslash\nimport { OffchainMessageEnvelope } from '@solana/kit';\nconst receivedOffchainMessageEnvelope = null as unknown as OffchainMessageEnvelope;\n// ---cut-before---\nimport {\n    isSolanaError,\n    verifyOffchainMessageEnvelope,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE,\n} from '@solana/kit';\n\ntry {\n    await verifyOffchainMessageEnvelope(receivedOffchainMessageEnvelope);\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE)) {\n        if (e.context.signatoriesWithInvalidSignatures.length) {\n            console.error(\n                'The signatures for the following addresses are invalid',\n                e.context.signatoriesWithInvalidSignatures,\n            );\n        }\n        if (e.context.signatoriesWithMissingSignatures.length) {\n            console.error(\n                'The following required signatories have not signed this message',\n                e.context.signatoriesWithMissingSignatures,\n            );\n        }\n    } else {\n        throw e;\n    }\n}\n```\n\n<Callout type=\"warn\">\n    Verifying an offchain message will tell you if its content has been signed by all required\n    signatories, but it will _not_ ensure that the content of the message nor its list of required\n    signatories is what you expect it to be. Take special care to inspect the content of the message\n    before accepting it. If you have the original bytes of the message, you can compare them to the\n    `content` of the envelope you are verifying. Otherwise, see [deserializing offchain\n    messages](#deserializing-offchain-messages) for instructions on how to decode the envelope's\n    `content` for inspection.\n</Callout>\n\n## Serializing offchain messages\n\nIf you would like to share an offchain message envelope with someone, you can serialize it to bytes using an encoder.\n\n```ts twoslash\nimport { OffchainMessageEnvelope } from '@solana/kit';\nconst offchainMessageEnvelope = null as unknown as OffchainMessageEnvelope;\n// ---cut-before---\nimport { getOffchainMessageEnvelopeEncoder } from '@solana/kit';\n\nconst offchainMessageEnvelopeBytes =\n    getOffchainMessageEnvelopeEncoder().encode(offchainMessageEnvelope);\n```\n\n## Deserializing offchain messages\n\nDecoding the bytes of an encoded offchain message envelope yields an `OffchainMessageEnvelope` object. This takes the form of a compiled offchain message encoded as [`OffchainMessageBytes`](/api/type-aliases/OffchainMessageBytes), paired with a map between its required signatory addresses and their provided signatures, if any.\n\n```ts twoslash\nimport { ReadonlyUint8Array } from '@solana/kit';\nconst offchainMessageEnvelopeBytes = null as unknown as ReadonlyUint8Array;\n// ---cut-before---\nimport { getOffchainMessageEnvelopeDecoder } from '@solana/kit';\nconst offchainMessageEnvelope = getOffchainMessageEnvelopeDecoder().decode(\n    offchainMessageEnvelopeBytes,\n);\n```\n\nDecoding the bytes of the offchain message envelope will yield an object containing an offchain message in its **compiled** form – a message in a form suitable for signing and transmitting over a network. Decompiling a compiled message will yield an `OffchainMessage` object. This is the most common form of offchain message that you will encounter when using Kit to build an application.\n\n```ts twoslash\nimport { OffchainMessageEnvelope } from '@solana/kit';\nconst offchainMessageEnvelope = null as unknown as OffchainMessageEnvelope;\n// ---cut-before---\nimport { getOffchainMessageDecoder } from '@solana/kit';\nconst offchainMessage = getOffchainMessageDecoder().decode(offchainMessageEnvelope.content);\n```\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/signers.mdx",
    "content": "---\ntitle: Signers\ndescription: Accounts with signing capabilities\n---\n\n## Introduction\n\nSigners are an abstraction that combines an account with an implementation that computes signatures on behalf of that account. No matter what actually computes the signature – a wallet app, a network API, the `SubtleCrypto` API, or a userspace implementation – so long as it implements the correct signer interface for your intended purpose, you can use it with all of Kit's signer-aware functions.\n\nSigners are designed to make it easier to build, sign, and send transactions by taking the guesswork out of which accounts' key pairs need to sign a transaction. Signer-aware APIs allow you to associate signer objects with each transaction instruction that requires them, enabling Kit's transaction planning, signing, and sending functions to automatically collect and invoke them.\n\n## Installation\n\nSigners are **included within the `@solana/kit` library** but you may also install them using their standalone package.\n\n```package-install\n@solana/signers\n```\n\n## What is a signer?\n\nAll signers are wrappers around an [`Address`](/api/type-aliases/Address). This means that most APIs that require an `Address` can be made to accept a signer. Each specific type of signer adds one or more capabilities, such as the ability to sign a message or a transaction on behalf of the account with that address. Some even add the ability to sign _and_ send a transaction, which is common for wallets that you use in your browser or on your phone.\n\n```ts twoslash\n// @noErrors: 2769\nimport {\n    createSignableMessage,\n    createTransactionMessage,\n    generateKeyPairSigner,\n    pipe,\n    setTransactionMessageFeePayerSigner,\n    signTransactionMessageWithSigners,\n} from '@solana/kit';\n\n// Generate a key pair signer.\nconst mySigner = await generateKeyPairSigner();\nmySigner.address; // The address of the account\n\n// Sign one or multiple messages.\nconst myMessage = createSignableMessage('Hello world!');\nconst [messageSignatures] = await mySigner.signMessages([myMessage]);\n//                                ^^^^^^^^\n\n// Sign to pay fees for a transaction message\nconst myTransactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    (m) => setTransactionMessageFeePayerSigner(mySigner, m),\n    //                                         ^^^^^^^^\n    // Add instructions, lifetime, etc.\n);\nconst signedTransaction = await signTransactionMessageWithSigners(myTransactionMessage);\n```\n\nAs you can see, this provides a consistent API regardless of how things are being signed behind the scenes. If tomorrow we need to use a browser wallet instead, we'd simply need to swap the `generateKeyPairSigner()` function with the signer factory of our choice.\n\n## Types of signers\n\nThis package offers a total of five different types of signers that may be used in combination when applicable. Three of them allow us to sign transactions whereas the other two are used for regular message signing.\n\nThey are separated into three categories:\n\n- **Partial signers**: Given a message or transaction, provide one or more signatures for it. These signers are not able to modify the given data which allows us to run many of them in parallel.\n- **Modifying signers**: Can choose to modify a message or transaction before signing it with zero or more private keys. Because modifying a message or transaction invalidates any pre-existing signatures over it, modifying signers must do their work before any other signer.\n- **Sending signers**: Given a transaction, signs it and sends it immediately to the blockchain. When applicable, the signer may also decide to modify the provided transaction before signing it. This interface accommodates wallets that simply cannot sign a transaction without sending it at the same time. This category of signers does not apply to regular messages.\n\nThus, we end up with the following interfaces.\n\n|                                                            | Partial signers                                                          | Modifying signers                                                            | Sending signers                                                          |\n| ---------------------------------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------ |\n| [`TransactionSigner`](/api/type-aliases/TransactionSigner) | [`TransactionPartialSigner`](/api/type-aliases/TransactionPartialSigner) | [`TransactionModifyingSigner`](/api/type-aliases/TransactionModifyingSigner) | [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner) |\n| [`MessageSigner`](/api/type-aliases/MessageSigner)         | [`MessagePartialSigner`](/api/type-aliases/MessagePartialSigner)         | [`MessageModifyingSigner`](/api/type-aliases/MessageModifyingSigner)         | N/A                                                                      |\n\nWe will go through each of these five signer interfaces and their respective characteristics in the documentation below.\n\n## Signing transactions\n\n### Partial signers [#transaction-partial-signers]\n\n[`TransactionPartialSigner`](/api/type-aliases/TransactionPartialSigner) is an interface that signs an array of [`Transactions`](/api/type-aliases/Transaction) without modifying their content. It defines a `signTransactions` function that returns a [`SignatureDictionary`](/api/type-aliases/SignatureDictionary) for each provided transaction. Such signature dictionaries are expected to be merged with the existing ones if any.\n\n```ts twoslash\n// @noErrors: 2355\nimport { address, SignatureDictionary, Transaction, TransactionPartialSigner } from '@solana/kit';\n// ---cut-before---\nconst myTransactionPartialSigner: TransactionPartialSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    signTransactions: async (transactions): Promise<SignatureDictionary[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Parallel**. It returns a signature dictionary for each provided transaction without modifying them, making it possible for multiple partial signers to sign the same transaction in parallel.\n- **Flexible order**. The order in which we use these signers for a given transaction doesn’t matter.\n\n### Modifying signers\n\n[`TransactionModifyingSigner`](/api/type-aliases/TransactionModifyingSigner) is an interface that potentially modifies the provided [`Transactions`](/api/type-aliases/Transaction) before signing them. E.g. this enables wallets to inject additional instructions into the transaction before signing them. For each transaction, instead of returning a [`SignatureDictionary`](/api/type-aliases/SignatureDictionary), its `modifyAndSignTransactions` function returns an updated [`Transaction`](/api/type-aliases/Transaction) with a potentially modified set of instructions and signature dictionary.\n\n```ts twoslash\n// @noErrors: 2355\nimport {\n    address,\n    Transaction,\n    TransactionModifyingSigner,\n    TransactionWithinSizeLimit,\n    TransactionWithLifetime,\n} from '@solana/kit';\n// ---cut-before---\nconst myTransactionModifyingSigner: TransactionModifyingSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    modifyAndSignTransactions: async (\n        transactions: readonly Transaction[],\n    ): Promise<readonly (Transaction & TransactionWithinSizeLimit & TransactionWithLifetime)[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Sequential**. Contrary to partial signers, these cannot be executed in parallel as each call can modify the provided transactions.\n- **First signers**. For a given transaction, a modifying signer must always be used before a partial signer as the former will likely modify the transaction and thus impact the outcome of the latter.\n- **Potential conflicts**. If more than one modifying signer is provided, the second signer may invalidate the signature of the first one. However, modifying signers may decide not to modify a transaction based on the existence of signatures for that transaction.\n\n### Sending signers\n\n[`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner) is an interface that signs one or multiple transactions before sending them immediately to the blockchain. It defines a `signAndSendTransactions` function that returns the transaction signature (i.e. its identifier) for each provided [`Transaction`](/api/type-aliases/Transaction). This interface is required for PDA wallets and other types of wallets that don't provide an interface for signing transactions without sending them.\n\nNote that it is also possible for such signers to modify the provided transactions before signing and sending them. This enables use cases where the modified transactions cannot be shared with the app and thus must be sent directly.\n\n```ts twoslash\n// @noErrors: 2355\nimport { address, SignatureBytes, Transaction, TransactionSendingSigner } from '@solana/kit';\n// ---cut-before---\nconst myTransactionSendingSigner: TransactionSendingSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    signAndSendTransactions: async (transactions: Transaction[]): Promise<SignatureBytes[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Single signer**. Since this signer also sends the provided transactions, we can only use a single [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner) for a given set of transactions.\n- **Last signer**. Trivially, that signer must also be the last one used.\n- **Potential conflicts**. Since signers may decide to modify the given transactions before sending them, they may invalidate previous signatures. However, signers may decide not to modify a transaction based on the existence of signatures for that transaction.\n- **Potential confirmation**. Whilst this is not required by this interface, it is also worth noting that most wallets will also wait for the transaction to be confirmed (typically with a `confirmed` commitment) before notifying the app that they are done.\n\n## Signing messages\n\n### Signable messages\n\n[`SignableMessage`](/api/type-aliases/SignableMessage) defines a message with any of the signatures that might have already been provided by other signers. This interface allows modifying signers to decide on whether or not they should modify the provided message depending on whether or not signatures already exist for such message. It also helps create a more consistent API by providing a structure analogous to transactions which also keep track of their signature dictionary.\n\n```ts twoslash\nimport { SignatureDictionary } from '@solana/kit';\n// ---cut-before---\ntype SignableMessage = {\n    content: Uint8Array;\n    signatures: SignatureDictionary; // Record<Address, SignatureBytes>\n};\n```\n\nYou can use the [`createSignableMessage`](/api/functions/createSignableMessage) function to create a [`SignableMessage`](/api/type-aliases/SignableMessage) from a `Uint8Array` or UTF-8 string. It optionally accepts a signature dictionary if the message already contains signatures.\n\n```ts twoslash\nimport { address, createSignableMessage, SignatureBytes } from '@solana/kit';\n// ---cut-before--\nconst myMessage = createSignableMessage(new Uint8Array([1, 2, 3]));\nconst myMessageFromText = createSignableMessage('Hello world!');\nconst myMessageWithSignatures = createSignableMessage('Hello world!', {\n    [address('1234..5678')]: new Uint8Array([1, 2, 3]) as SignatureBytes,\n});\n```\n\n### Partial signers\n\n[`MessagePartialSigner`](/api/type-aliases/MessagePartialSigner) is an interface that signs an array of [`SignableMessages`](/api/type-aliases/SignableMessage) without modifying their content. It defines a `signMessages` function that returns a [`SignatureDictionary`](/api/type-aliases/SignatureDictionary) for each provided message. Such signature dictionaries are expected to be merged with the existing ones if any.\n\n```ts twoslash\n// @noErrors: 2355\nimport { address, MessagePartialSigner, SignableMessage, SignatureDictionary } from '@solana/kit';\n// ---cut-before---\nconst myMessagePartialSigner: MessagePartialSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    signMessages: async (messages: SignableMessage[]): Promise<SignatureDictionary[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Parallel**. When multiple signers sign the same message, we can perform this operation in parallel to obtain all their signatures.\n- **Flexible order**. The order in which we use these signers for a given message doesn’t matter.\n\n### Modifying signers\n\n[`MessageModifyingSigner`](/api/type-aliases/MessageModifyingSigner) is an interface that potentially modifies the content of the provided [`SignableMessages`](/api/type-aliases/SignableMessage) before signing them. E.g. this enables wallets to prefix or suffix nonces to the messages they sign. For each message, instead of returning a [`SignatureDictionary`](/api/type-aliases/SignatureDictionary), its `modifyAndSignMessages` function returns its updated [`SignableMessage`](/api/type-aliases/SignableMessage) with a potentially modified content and signature dictionary.\n\n```ts twoslash\n// @noErrors: 2355\nimport { address, MessageModifyingSigner, SignableMessage } from '@solana/kit';\n// ---cut-before---\nconst myMessageModifyingSigner: MessageModifyingSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    modifyAndSignMessages: async (messages: SignableMessage[]): Promise<SignableMessage[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Sequential**. Contrary to partial signers, these cannot be executed in parallel as each call can modify the content of the message.\n- **First signers**. For a given message, a modifying signer must always be used before a partial signer as the former will likely modify the message and thus impact the outcome of the latter.\n- **Potential conflicts**. If more than one modifying signer is provided, the second signer may invalidate the signature of the first one. However, modifying signers may decide not to modify a message based on the existence of signatures for that message.\n\n## Available signers\n\n### No-op signers\n\nFor a given address, a <abbr title=\"no-operation\">no-op</abbr> signer can be created to offer an implementation of both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces such that they do not sign anything. Namely, signing a transaction or a message with a `NoopSigner` will return an empty `SignatureDictionary`.\n\nThis signer may be useful:\n\n- For testing purposes.\n- For indicating that a given account is a signer and taking the responsibility to provide the signature for that account ourselves. For instance, if we need to send the transaction to a server that will sign it and send it for us.\n\n```ts twoslash\nimport {\n    address,\n    SignableMessage,\n    Transaction,\n    TransactionWithinSizeLimit,\n    TransactionWithLifetime,\n} from '@solana/kit';\nconst myMessage = null as unknown as SignableMessage;\nconst myTransaction = null as unknown as Transaction &\n    TransactionWithinSizeLimit &\n    TransactionWithLifetime;\n// ---cut-before---\nimport { createNoopSigner } from '@solana/kit';\n\nconst myNoopSigner = createNoopSigner(address('1234..5678'));\nconst [myMessageSignatures] = await myNoopSigner.signMessages([myMessage]); // <- Empty signature dictionary.\nconst [myTransactionSignatures] = await myNoopSigner.signTransactions([myTransaction]); // <- Empty signature dictionary.\n```\n\n### Key pair signers\n\nA key pair signer uses a `CryptoKeyPair` to sign messages and transactions. It implements both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces and keeps track of the `CryptoKeyPair` instance used to sign messages and transactions.\n\n<div className=\"*:columns-5xs *:gap-8\">\n\n[createSignerFromKeyPair](#create-signer-from-key-pair)\n[generateKeyPairSigner](#generate-key-pair-signer)\n[createKeyPairSignerFromBytes](#create-key-pair-signer-from-bytes)\n[createKeyPairSignerFromPrivateKeyBytes](#create-key-pair-signer-from-private-key-bytes)\n\n</div>\n\n#### createSignerFromKeyPair [!toc] [#create-signer-from-key-pair]\n\nCreates a `KeyPairSigner` from a provided Crypto KeyPair. The `signMessages` and `signTransactions` functions of the returned signer will use the private key of the provided key pair to sign messages and transactions. Note that both the `signMessages` and `signTransactions` implementations are parallelized, meaning that they will sign all provided messages and transactions in parallel.\n\n```ts twoslash\nimport { createSignerFromKeyPair, generateKeyPair, KeyPairSigner } from '@solana/kit';\n\nconst myKeyPair: CryptoKeyPair = await generateKeyPair();\nconst myKeyPairSigner: KeyPairSigner = await createSignerFromKeyPair(myKeyPair);\n```\n\n#### generateKeyPairSigner [!toc] [#generate-key-pair-signer]\n\nA convenience function that generates a new Crypto KeyPair and immediately creates a `KeyPairSigner` from it.\n\n```ts twoslash\nimport { generateKeyPairSigner } from '@solana/kit';\n\nconst myKeyPairSigner = await generateKeyPairSigner();\n```\n\n#### createKeyPairSignerFromBytes [!toc] [#create-key-pair-signer-from-bytes]\n\nA convenience function that creates a new KeyPair from a 64-bytes `Uint8Array` secret key and immediately creates a `KeyPairSigner` from it.\n\n```ts twoslash\nimport fs from 'fs';\nimport { createKeyPairSignerFromBytes } from '@solana/kit';\n\n// Get bytes from local keypair file.\nconst keypairFile = fs.readFileSync('~/.config/solana/id.json');\nconst keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n\n// Create a KeyPairSigner from the bytes.\nconst signer = await createKeyPairSignerFromBytes(keypairBytes);\n```\n\n#### createKeyPairSignerFromPrivateKeyBytes [!toc] [#create-key-pair-signer-from-private-key-bytes]\n\nA convenience function that creates a new KeyPair from a 32-bytes `Uint8Array` private key and immediately creates a `KeyPairSigner` from it.\n\n```ts twoslash\nimport { createKeyPairSignerFromPrivateKeyBytes, getUtf8Encoder } from '@solana/kit';\n\nconst message = getUtf8Encoder().encode('Hello, World!');\nconst seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n\nconst derivedSigner = await createKeyPairSignerFromPrivateKeyBytes(seed);\n```\n\n### Wallet account signers\n\nWallet account signers bridge between [Wallet Standard](https://github.com/wallet-standard/wallet-standard) accounts and Kit's signer interfaces. They live in the [`@solana/wallet-account-signer`](https://www.npmjs.com/package/@solana/wallet-account-signer) package and let any wallet that exposes the standard Solana features participate in signing transactions and messages.\n\n```package-install\n@solana/wallet-account-signer\n```\n\n<div className=\"*:columns-5xs *:gap-8\">\n\n[createSignerFromWalletAccount](#create-signer-from-wallet-account)\n[createTransactionSignerFromWalletAccount](#create-transaction-signer-from-wallet-account)\n[createTransactionSendingSignerFromWalletAccount](#create-transaction-sending-signer-from-wallet-account)\n[createMessageSignerFromWalletAccount](#create-message-signer-from-wallet-account)\n\n</div>\n\n#### createSignerFromWalletAccount [!toc] [#create-signer-from-wallet-account]\n\nInspects the wallet account's available features and returns a single signer object combining whichever capabilities the wallet supports — `modifyAndSignTransactions`, `signAndSendTransactions`, and/or `modifyAndSignMessages`. Use this when you do not know in advance which features a wallet exposes.\n\n```ts twoslash\nimport { UiWalletAccount } from '@wallet-standard/ui';\nconst walletAccount = null as unknown as UiWalletAccount;\n// ---cut-before---\nimport { createSignerFromWalletAccount } from '@solana/wallet-account-signer';\n\nconst signer = createSignerFromWalletAccount(walletAccount, 'solana:devnet');\n```\n\n#### createTransactionSignerFromWalletAccount [!toc] [#create-transaction-signer-from-wallet-account]\n\nReturns a [`TransactionModifyingSigner`](/api/type-aliases/TransactionModifyingSigner) that signs transactions with the wallet via the `solana:signTransaction` feature. The signer is allowed to modify the transaction before signing, which lets the wallet inject guard instructions or priority fees if it wants to.\n\n```ts twoslash\nimport { UiWalletAccount } from '@wallet-standard/ui';\nconst walletAccount = null as unknown as UiWalletAccount;\n// ---cut-before---\nimport { createTransactionSignerFromWalletAccount } from '@solana/wallet-account-signer';\n\nconst signer = createTransactionSignerFromWalletAccount(walletAccount, 'solana:devnet');\n```\n\n#### createTransactionSendingSignerFromWalletAccount [!toc] [#create-transaction-sending-signer-from-wallet-account]\n\nReturns a [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner) that uses the `solana:signAndSendTransaction` feature to sign and immediately submit the transaction to the network. This is the right shape for wallets that do not let the dapp inspect or relay the signed transaction itself.\n\n```ts twoslash\nimport { UiWalletAccount } from '@wallet-standard/ui';\nconst walletAccount = null as unknown as UiWalletAccount;\n// ---cut-before---\nimport { createTransactionSendingSignerFromWalletAccount } from '@solana/wallet-account-signer';\n\nconst signer = createTransactionSendingSignerFromWalletAccount(walletAccount, 'solana:devnet');\n```\n\n#### createMessageSignerFromWalletAccount [!toc] [#create-message-signer-from-wallet-account]\n\nReturns a [`MessageModifyingSigner`](/api/type-aliases/MessageModifyingSigner) that signs arbitrary messages via the `solana:signMessage` feature. This is the wallet-backed counterpart to a key pair signer's message-signing capability.\n\n```ts twoslash\nimport { UiWalletAccount } from '@wallet-standard/ui';\nconst walletAccount = null as unknown as UiWalletAccount;\n// ---cut-before---\nimport { createMessageSignerFromWalletAccount } from '@solana/wallet-account-signer';\n\nconst signer = createMessageSignerFromWalletAccount(walletAccount);\n```\n\n## Signing with signers\n\nKit provides helper functions that use [`TransactionSigner`](/api/type-aliases/TransactionSigner) objects to sign and optionally send transactions. There are two families of signing functions:\n\n- **Transaction message functions** extract signers from the transaction message — either from the fee payer or from account metas — and handle compilation and signing automatically.\n- **Transaction functions** accept an explicit array of signers alongside a compiled [`Transaction`](/api/type-aliases/Transaction), giving you full control over which signers are used.\n\n### Signing transaction messages\n\nThe following functions extract [`TransactionSigners`](/api/type-aliases/TransactionSigner) from a transaction message's account metas, compile the message into a [`Transaction`](/api/type-aliases/Transaction), and use those signers to sign it.\n\n#### partiallySignTransactionMessageWithSigners [!toc] [#partially-sign-transaction-message-with-signers]\n\nSigns a transaction message without requiring all signatures to be present. This is useful when you know the message only carries a subset of the required signers and you plan to add more signatures later.\n\n```ts twoslash\nimport {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithSigners,\n} from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage &\n    TransactionMessageWithFeePayer &\n    TransactionMessageWithSigners;\n// ---cut-before---\nimport { partiallySignTransactionMessageWithSigners } from '@solana/kit';\n\nconst signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n```\n\n<Callout type=\"info\">\n    This function ignores any\n    [`TransactionSendingSigners`](/api/type-aliases/TransactionSendingSigner) in the message since\n    it does not send the transaction. Use\n    [`signAndSendTransactionMessageWithSigners`](#sign-and-send-transaction-message-with-signers) if\n    you need to sign and send in a single step.\n</Callout>\n\n#### signTransactionMessageWithSigners [!toc] [#sign-transaction-message-with-signers]\n\nSigns a transaction message and asserts that all required signatures are present. The returned transaction satisfies the [`FullySignedTransaction`](/api/type-aliases/FullySignedTransaction) type.\n\n```ts twoslash\nimport {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithSigners,\n} from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage &\n    TransactionMessageWithFeePayer &\n    TransactionMessageWithSigners;\n// ---cut-before---\nimport { signTransactionMessageWithSigners } from '@solana/kit';\n\nconst fullySignedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n```\n\n<Callout type=\"warn\">\n    This function will throw if the transaction message does not carry a\n    [`TransactionSigner`](/api/type-aliases/TransactionSigner) implementation for every required\n    signer. To partially sign a message that you know to carry a strict subset of the required\n    signers, use\n    [`partiallySignTransactionMessageWithSigners`](#partially-sign-transaction-message-with-signers).\n</Callout>\n\n#### signAndSendTransactionMessageWithSigners [!toc] [#sign-and-send-transaction-message-with-signers]\n\nSigns a transaction message and sends it to the network via the [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner) found in the message's account metas. Returns the transaction signature as [`SignatureBytes`](/api/type-aliases/SignatureBytes).\n\n```ts twoslash\nimport {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithSigners,\n    TransactionMessageWithSingleSendingSigner,\n} from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage &\n    TransactionMessageWithFeePayer &\n    TransactionMessageWithSigners &\n    TransactionMessageWithSingleSendingSigner;\n// ---cut-before---\nimport { signAndSendTransactionMessageWithSigners } from '@solana/kit';\n\nconst signature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n```\n\nThe message must contain exactly one resolvable [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner). You can check this ahead of time using [`isTransactionMessageWithSingleSendingSigner`](/api/functions/isTransactionMessageWithSingleSendingSigner) to provide a fallback strategy:\n\n```ts twoslash\n// @noErrors: 2345\nimport {\n    Rpc,\n    RpcSubscriptions,\n    SolanaRpcApi,\n    SolanaRpcSubscriptionsApi,\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithSigners,\n} from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage &\n    TransactionMessageWithBlockhashLifetime &\n    TransactionMessageWithFeePayer &\n    TransactionMessageWithSigners;\nconst rpc = null as unknown as Rpc<SolanaRpcApi>;\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n// ---cut-before---\nimport {\n    isTransactionMessageWithSingleSendingSigner,\n    sendAndConfirmTransactionFactory,\n    signAndSendTransactionMessageWithSigners,\n    signTransactionMessageWithSigners,\n} from '@solana/kit';\n\nif (isTransactionMessageWithSingleSendingSigner(transactionMessage)) {\n    // A sending signer is available — sign and send in one step.\n    const signature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n} else {\n    // No sending signer — sign locally and use sendAndConfirmTransaction.\n    const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n    const sendAndConfirm = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n    await sendAndConfirm(signedTransaction, { commitment: 'confirmed' });\n}\n```\n\n### Signing compiled transactions\n\nWhen you already have a compiled [`Transaction`](/api/type-aliases/Transaction) and an explicit set of signers — for example, when signers are not embedded in the transaction message or when working with an externally provided transaction — you can use the following lower-level functions.\n\n#### partiallySignTransactionWithSigners [!toc] [#partially-sign-transaction-with-signers]\n\nSigns a compiled transaction using the provided [`TransactionModifyingSigners`](/api/type-aliases/TransactionModifyingSigner) and [`TransactionPartialSigners`](/api/type-aliases/TransactionPartialSigner) without requiring all signatures to be present.\n\n```ts twoslash\nimport {\n    Transaction,\n    TransactionWithLifetime,\n    TransactionPartialSigner,\n    TransactionModifyingSigner,\n} from '@solana/kit';\nconst compiledTransaction = null as unknown as Transaction & TransactionWithLifetime;\nconst signerA = null as unknown as TransactionPartialSigner;\nconst signerB = null as unknown as TransactionPartialSigner;\n// ---cut-before---\nimport { partiallySignTransactionWithSigners } from '@solana/kit';\n\nconst signedTransaction = await partiallySignTransactionWithSigners(\n    [signerA, signerB],\n    compiledTransaction,\n);\n```\n\n<Callout type=\"info\">\n    This function ignores any\n    [`TransactionSendingSigners`](/api/type-aliases/TransactionSendingSigner) in the provided array.\n    Use [`signAndSendTransactionWithSigners`](#sign-and-send-transaction-with-signers) if you need\n    to sign and send.\n</Callout>\n\n#### signTransactionWithSigners [!toc] [#sign-transaction-with-signers]\n\nSigns a compiled transaction using the provided signers and asserts that all required signatures are present. The returned transaction satisfies the [`FullySignedTransaction`](/api/type-aliases/FullySignedTransaction) type.\n\n```ts twoslash\nimport { Transaction, TransactionWithLifetime, TransactionPartialSigner } from '@solana/kit';\nconst compiledTransaction = null as unknown as Transaction & TransactionWithLifetime;\nconst signerA = null as unknown as TransactionPartialSigner;\nconst signerB = null as unknown as TransactionPartialSigner;\n// ---cut-before---\nimport { signTransactionWithSigners } from '@solana/kit';\n\nconst fullySignedTransaction = await signTransactionWithSigners(\n    [signerA, signerB],\n    compiledTransaction,\n);\n```\n\n<Callout type=\"warn\">\n    This function will throw if the resultant transaction is missing a signature for one of its\n    required signers. To partially sign, use\n    [`partiallySignTransactionWithSigners`](#partially-sign-transaction-with-signers).\n</Callout>\n\n#### signAndSendTransactionWithSigners [!toc] [#sign-and-send-transaction-with-signers]\n\nSigns a compiled transaction using the provided signers and sends it to the network via the [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner) found in the array. Returns the transaction signature as [`SignatureBytes`](/api/type-aliases/SignatureBytes).\n\n```ts twoslash\nimport {\n    Transaction,\n    TransactionWithLifetime,\n    TransactionPartialSigner,\n    TransactionSendingSigner,\n} from '@solana/kit';\nconst compiledTransaction = null as unknown as Transaction & TransactionWithLifetime;\nconst partialSigner = null as unknown as TransactionPartialSigner;\nconst sendingSigner = null as unknown as TransactionSendingSigner;\n// ---cut-before---\nimport { signAndSendTransactionWithSigners } from '@solana/kit';\n\nconst signature = await signAndSendTransactionWithSigners(\n    [partialSigner, sendingSigner],\n    compiledTransaction,\n);\n```\n\nThe provided signers must contain exactly one resolvable [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner). You can validate this ahead of time using [`assertContainsResolvableTransactionSendingSigner`](#assert-contains-resolvable-transaction-sending-signer).\n\n#### assertContainsResolvableTransactionSendingSigner [!toc] [#assert-contains-resolvable-transaction-sending-signer]\n\nAsserts that an array of signers contains at least one [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner) that can be unambiguously resolved. This is useful for validating your signers before calling [`signAndSendTransactionWithSigners`](#sign-and-send-transaction-with-signers).\n\n```ts twoslash\nimport { TransactionSigner } from '@solana/kit';\nconst mySigners = null as unknown as TransactionSigner[];\n// ---cut-before---\nimport { assertContainsResolvableTransactionSendingSigner } from '@solana/kit';\n\n// Throws if no resolvable sending signer is found or if\n// multiple sending-only signers conflict with each other.\nassertContainsResolvableTransactionSendingSigner(mySigners);\n```\n\n### How composite signers are resolved\n\nWhen a signer implements multiple interfaces (e.g. both [`TransactionPartialSigner`](/api/type-aliases/TransactionPartialSigner) and [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner)), the signing functions automatically resolve it to the most appropriate role:\n\n1. **[`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner)** — Used if no other signer exclusively implements the sending interface. Only one sending signer can be active.\n2. **[`TransactionModifyingSigner`](/api/type-aliases/TransactionModifyingSigner)** — Used if no other signer exclusively implements the modifying interface. Modifying signers run sequentially before all others.\n3. **[`TransactionPartialSigner`](/api/type-aliases/TransactionPartialSigner)** — The fallback. Partial signers run in parallel after all modifying signers have finished.\n\nThis means a composite signer is always demoted to the least powerful interface that avoids conflicts with other signers.\n"
  },
  {
    "path": "docs/content/docs/advanced-guides/transactions.mdx",
    "content": "---\ntitle: Transactions\ndescription: Build and compile transaction messages\n---\n\n## Introduction\n\nTo take an action on Solana, whether to place an order, transfer an asset, or more generally to modify data on the blockchain, you need to prepare a transaction and sign to pay for it to be executed on the network. You can use Kit to create, sign, encode, and decode transactions.\n\n## Installation\n\nTransaction utilities are **included within the `@solana/kit` library** but you may also install them using their standalone packages.\n\nTo install transaction message builder utilities:\n\n```package-install\n@solana/transaction-messages\n```\n\nTo install utilities that let you sign and compile transaction messages into transactions that can be landed on the network:\n\n```package-install\n@solana/transactions\n```\n\n## What is a Transaction?\n\nA Transaction is a vehicle to deliver one or more instructions to the Solana network in pursuit of some outcome.\n\nHere is an example of someone creating a transaction message to place an order at their favourite coffee shop, then signing it to create a transaction.\n\n```ts twoslash\nimport { Blockhash, TransactionSigner } from '@solana/kit';\nconst customerSigner = null as unknown as TransactionSigner;\nconst latestBlockhash = null as unknown as { blockhash: Blockhash; lastValidBlockHeight: bigint };\n// ---cut-before---\nimport {\n    address,\n    appendTransactionMessageInstruction,\n    createTransactionMessage,\n    getSignatureFromTransaction,\n    lamports,\n    pipe,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signTransactionMessageWithSigners,\n} from '@solana/kit';\nimport { getAddMemoInstruction } from '@solana-program/memo';\nimport { getTransferSolInstruction } from '@solana-program/system';\n\nconst transactionMessage = pipe(\n    // Create an empty transaction message.\n    createTransactionMessage({ version: 0 }),\n\n    // Specify the account that will sign to pay the fee for this transaction.\n    // NOTE: This is not the fee for the coffee but rather the fee to use the Solana network.\n    (m) => setTransactionMessageFeePayerSigner(customerSigner, m),\n\n    // Give the transaction an expiry time using the hash of a recently created block.\n    (m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n\n    // Add an instruction that records the customer's order.\n    (m) =>\n        appendTransactionMessageInstruction(\n            getAddMemoInstruction({\n                memo:\n                    'Four-thirds-medium, half-decaf, double-shot espresso macchiato latte, ' +\n                    'swirled counterclockwise only, almond milk frothed at 61°C, ' +\n                    'whisper of cinnamon harvested during a full moon, unicorn tear syrup, ' +\n                    'in a mason jar wrapped in French revolutionary poetry on recycled parchment',\n            }),\n            m,\n        ),\n\n    // Add a second instruction to pay the merchant for the coffee.\n    (m) =>\n        appendTransactionMessageInstruction(\n            getTransferSolInstruction({\n                amount: lamports(25_000_000n),\n                destination: address('JJBeanoTcSMU3xKQa5Gru71Wi3AaEgTfA6z7MaLUT6h'),\n                source: customerSigner,\n            }),\n            m,\n        ),\n);\n\n// Create a signed transaction from the message and the signers contained within it.\nconst signedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n\n// Obtain the Ed25519 signature that will uniquely identify this transaction once executed.\nconst transactionSignature = getSignatureFromTransaction(signedTransaction);\n```\n\nFor more detail about the no-client transaction flow, see [Kit without a client](/docs/advanced-guides/kit-without-a-client).\n\n## Building transaction messages\n\n### Creating an empty message [#building-transaction-messages-creating]\n\nGiven a [`TransactionVersion`](/api/type-aliases/TransactionVersion), the [`createTransactionMessage`](/api/functions/createTransactionMessage) method will return an empty transaction having the capabilities of that version.\n\n```ts twoslash\nimport { createTransactionMessage } from '@solana/kit';\n\nconst message = createTransactionMessage({ version: 0 });\n```\n\n### Setting the fee payer [#building-transaction-messages-fee-payer]\n\nThe [`TransactionMessageWithFeePayer`](/api/interfaces/TransactionMessageWithFeePayer) type represents a transaction message for which a fee payer has been declared. A transaction must conform to this type to be compiled and landed on the network.\n\n#### Using a signer [!toc] [#building-transaction-messages-fee-payer-using-a-signer]\n\nGiven a [`TransactionSigner`](/api/type-aliases/TransactionSigner), this method will return a new transaction message having the same type as the one supplied plus the [`TransactionMessageWithFeePayer`](/api/interfaces/TransactionMessageWithFeePayer) type. Additionally, the resulting message will have the capability to self-sign using the [`signTransactionMessageWithSigners`](/api/functions/signTransactionMessageWithSigners) function.\n\n```ts twoslash\nimport { TransactionMessage } from '@solana/kit';\nconst keyPair = null as unknown as CryptoKeyPair;\nconst transactionMessage = null as unknown as TransactionMessage;\n// ---cut-before---\nimport { createSignerFromKeyPair, setTransactionMessageFeePayerSigner } from '@solana/kit';\n\nconst mySigner = await createSignerFromKeyPair(keyPair);\nconst transactionMessagePaidByMe = setTransactionMessageFeePayerSigner(\n    mySigner,\n    transactionMessage,\n);\n```\n\n#### Using an address [!toc] [#building-transaction-messages-fee-payer-using-an-address]\n\nGiven a base58-encoded address of a system account, this method will return a new transaction message having the same type as the one supplied plus the [`TransactionMessageWithFeePayer`](/api/interfaces/TransactionMessageWithFeePayer) type.\n\n```ts twoslash\nimport { TransactionMessage } from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage;\n// ---cut-before---\nimport { address, setTransactionMessageFeePayer } from '@solana/kit';\n\nconst myAddress = address('mpngsFd4tmbUfzDYJayjKZwZcaR7aWb2793J6grLsGu');\nconst transactionMessagePaidByMe = setTransactionMessageFeePayer(myAddress, transactionMessage);\n```\n\n### Defining the lifetime [#building-transaction-messages-lifetime]\n\nA signed transaction can be only be landed on the network if certain conditions are met:\n\n- It includes the hash of a recent block\n- Or it includes the value of an unused nonce known to the network\n\nThese conditions define a transaction's lifetime, after which it can no longer be landed, even if signed. The lifetime must be added to the transaction message before it is compiled to be sent.\n\n#### Using a recent blockhash [!toc] [#building-transaction-messages-lifetime-using-a-recent-blockhash]\n\nThe [`TransactionMessageWithBlockhashLifetime`](/api/interfaces/TransactionMessageWithBlockhashLifetime) type represents a transaction message whose expiry is tied to the age of a block. Such a transaction can only be landed on the network if the current block height of the network is less than or equal to the value of `TransactionMessageWithBlockhashLifetime.lifetimeConstraint.lastValidBlockHeight`.\n\nGiven a blockhash and the last block height at which that blockhash is considered usable to land transactions, the [`setTransactionMessageLifetimeUsingBlockhash`](/api/functions/setTransactionMessageLifetimeUsingBlockhash) method will return a new transaction message having the same type as the one supplied plus the [`TransactionMessageWithBlockhashLifetime`](/api/interfaces/TransactionMessageWithBlockhashLifetime) type.\n\n```ts twoslash\nimport { Rpc, GetLatestBlockhashApi, TransactionMessage } from '@solana/kit';\nconst rpc = null as unknown as Rpc<GetLatestBlockhashApi>;\nconst transactionMessage = null as unknown as TransactionMessage;\n// ---cut-before---\nimport { setTransactionMessageLifetimeUsingBlockhash } from '@solana/kit';\n\nconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\nconst txMessageWithBlockhashLifetime = setTransactionMessageLifetimeUsingBlockhash(\n    latestBlockhash,\n    transactionMessage,\n);\n```\n\n#### Using a durable nonce [!toc] [#building-transaction-messages-lifetime-using-a-durable-nonce]\n\nThe [`TransactionMessageWithDurableNonceLifetime`](/api/interfaces/TransactionMessageWithDurableNonceLifetime) type represents a transaction message whose lifetime is defined by the value of a nonce account onchain. Such a transaction can only be landed on the network if the nonce value in the transaction message matches the one in the nonce account at the time the transaction executes.\n\nGiven a nonce, the account where the value of the nonce is stored, and the address of the account authorized to consume that nonce, this method will return a new transaction having the same type as the one supplied plus the [`TransactionMessageWithDurableNonceLifetime`](/api/interfaces/TransactionMessageWithDurableNonceLifetime) type.\n\n```ts twoslash\nimport { TransactionMessage, address, Rpc, GetAccountInfoApi } from '@solana/kit';\nconst rpc = null as unknown as Rpc<GetAccountInfoApi>;\nconst transactionMessage = null as unknown as TransactionMessage;\n// ---cut-before---\nimport { Nonce, setTransactionMessageLifetimeUsingDurableNonce } from '@solana/kit';\nimport { fetchNonce } from '@solana-program/system';\n\nconst nonceAccountAddress = address('EGtMh4yvXswwHhwVhyPxGrVV2TkLTgUqGodbATEPvojZ');\nconst nonceAuthorityAddress = address('4KD1Rdrd89NG7XbzW3xsX9Aqnx2EExJvExiNme6g9iAT');\n\nconst {\n    data: { blockhash },\n} = await fetchNonce(rpc, nonceAccountAddress);\nconst nonce = blockhash as string as Nonce;\n\nconst durableNonceTransactionMessage = setTransactionMessageLifetimeUsingDurableNonce(\n    { nonce, nonceAccountAddress, nonceAuthorityAddress },\n    transactionMessage,\n);\n```\n\nIn particular, this method _prepends_ an instruction to the transaction message designed to consume (or &lsquo;advance&rsquo;) the nonce in the same transaction whose lifetime is defined by it.\n\n```ts twoslash\nimport { TransactionMessageWithDurableNonceLifetime } from '@solana/kit';\nconst durableNonceTransactionMessage =\n    null as unknown as TransactionMessageWithDurableNonceLifetime<\n        'EGtMh4yvXswwHhwVhyPxGrVV2TkLTgUqGodbATEPvojZ',\n        '4KD1Rdrd89NG7XbzW3xsX9Aqnx2EExJvExiNme6g9iAT'\n    >;\n// ---cut-before---\nconst [\n    // An 'advance nonce' instruction gets prepended to the instruction list\n    advanceNonceInstruction,\n    ...otherInstructions\n] = durableNonceTransactionMessage.instructions;\n```\n\n### Adding instructions [#building-transaction-messages-instructions]\n\nThere are three types that correspond to the different parts of an instruction. Any given instruction may conform to one or more of these types, but must conform in every case to the `Instruction` type.\n\n- [`Instruction`](/api/interfaces/Instruction): An instruction having a `programAddress` property that is the base58-encoded address of the program to invoke.\n- [`InstructionWithAccounts`](/api/interfaces/InstructionWithAccounts): An instruction that specifies a list of accounts that a program may read from, write to, or require be signers of the transaction itself. Objects that conform to this type have an `accounts` property that is an array of `AccountMeta | AccountLookupMeta` in the order the instruction requires.\n- [`InstructionWithData`](/api/interfaces/InstructionWithData): An instruction that supplies some data as input to the program. Objects that conform to this type have a `data` property that can be any type of `Uint8Array`.\n\nGiven an instruction, the [`appendTransactionMessageInstruction`](/api/functions/appendTransactionMessageInstruction) method will return a new transaction message with that instruction having been added to the end of the list of existing instructions.\n\n```ts twoslash\nimport { TransactionMessage } from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage;\n// ---cut-before---\nimport { address, appendTransactionMessageInstruction, getUtf8Encoder } from '@solana/kit';\nimport { getAddMemoInstruction } from '@solana-program/memo';\n\nconst memoTransactionMessage = appendTransactionMessageInstruction(\n    getAddMemoInstruction({ memo: 'Hello world!' }),\n    transactionMessage,\n);\n```\n\nTo add an instruction to the beginning of the list instead, see [`prependTransactionMessageInstruction`](/api/functions/prependTransactionMessageInstruction)\n\nTo add an array of instructions to a transaction message, see [`appendTransactionMessageInstructions`](/api/functions/appendTransactionMessageInstructions) and [`prependTransactionMessageInstructions`](/api/functions/prependTransactionMessageInstructions).\n\n## Configuring compute and priority fees\n\nEvery transaction has a compute budget — a maximum number of compute units (CUs) it is allowed to consume. The Solana network also lets you attach a priority fee to influence inclusion ordering. Kit exposes these as first-class configuration setters on the transaction message, so you do not need to add or update Compute Budget program instructions yourself.\n\n### Setting the compute unit limit [#configuring-compute-unit-limit]\n\nThe compute unit limit caps how many CUs the transaction may consume. Setting it close to what your transaction actually uses increases the chance of inclusion, packs more transactions per block, and reduces the amount of priority fees you pay.\n\n```ts twoslash\nimport { TransactionMessage } from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage;\n// ---cut-before---\nimport { setTransactionMessageComputeUnitLimit } from '@solana/kit';\n\nconst transactionMessageWithLimit = setTransactionMessageComputeUnitLimit(\n    50_000,\n    transactionMessage,\n);\n```\n\nTo remove the limit, pass `undefined` as the first argument. The matching reader [`getTransactionMessageComputeUnitLimit`](/api/functions/getTransactionMessageComputeUnitLimit) returns the limit currently set on a message, or `undefined` if none is set.\n\n### Estimating the compute unit limit [#configuring-compute-unit-limit-estimation]\n\nA good way to size the compute unit limit is to simulate the transaction and use the result. Kit ships [`estimateComputeUnitLimitFactory`](/api/functions/estimateComputeUnitLimitFactory) for the simulation step and [`estimateAndSetComputeUnitLimitFactory`](/api/functions/estimateAndSetComputeUnitLimitFactory) for the common case of estimating and writing the result back onto the message in one call.\n\n```ts twoslash\nimport {\n    Rpc,\n    SimulateTransactionApi,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/kit';\nconst rpc = null as unknown as Rpc<SimulateTransactionApi>;\nconst transactionMessage = null as unknown as TransactionMessage & TransactionMessageWithFeePayer;\n// ---cut-before---\nimport {\n    estimateAndSetComputeUnitLimitFactory,\n    estimateComputeUnitLimitFactory,\n} from '@solana/kit';\n\nconst estimateComputeUnitLimit = estimateComputeUnitLimitFactory({ rpc });\nconst estimateAndSetComputeUnitLimit =\n    estimateAndSetComputeUnitLimitFactory(estimateComputeUnitLimit);\n\nconst transactionMessageWithLimit = await estimateAndSetComputeUnitLimit(transactionMessage);\n```\n\nThe estimator simulates the transaction with the maximum allowed limit so the simulation itself never runs out of budget; the returned value is the compute unit count actually consumed. `estimateAndSetComputeUnitLimitFactory` only updates the message if no explicit limit is already set or if the existing limit is the provisory `0` value, leaving messages with manually configured limits untouched.\n\nWhen constructing a message that you intend to estimate later, [`fillTransactionMessageProvisoryComputeUnitLimit`](/api/functions/fillTransactionMessageProvisoryComputeUnitLimit) reserves space for the limit by setting it to a provisory value of `0`.\n\n### Setting the priority fee [#configuring-priority-fees]\n\nPriority fees boost the chance that your transaction is included sooner. The exact knob depends on the transaction version: legacy and v0 transactions express priority fees as a price per compute unit, while v1 transactions express them as a single total amount in lamports.\n\n```ts twoslash\nimport { TransactionMessage } from '@solana/kit';\nconst v0TransactionMessage = null as unknown as TransactionMessage & { version: 0 };\nconst v1TransactionMessage = null as unknown as TransactionMessage & { version: 1 };\n// ---cut-before---\nimport {\n    setTransactionMessageComputeUnitPrice,\n    setTransactionMessagePriorityFeeLamports,\n} from '@solana/kit';\n\n// Legacy or v0: 10,000 micro-lamports per compute unit.\nconst v0WithPriorityFee = setTransactionMessageComputeUnitPrice(10_000n, v0TransactionMessage);\n\n// v1: 50,000 lamports total, regardless of compute unit usage.\nconst v1WithPriorityFee = setTransactionMessagePriorityFeeLamports(50_000n, v1TransactionMessage);\n```\n\nBoth setters accept `undefined` to clear the configuration. The matching readers [`getTransactionMessageComputeUnitPrice`](/api/functions/getTransactionMessageComputeUnitPrice) and [`getTransactionMessagePriorityFeeLamports`](/api/functions/getTransactionMessagePriorityFeeLamports) return the current value or `undefined` when none is set.\n\n<Callout type=\"info\">\n    Bundled clients such as `solanaRpc` and `litesvm` estimate the compute unit limit when sending\n    transactions for you. Reach for the setters above when you build messages by hand or when you\n    want to override what a client would do automatically.\n</Callout>\n\n## Compressing transaction messages\n\nEvery transaction message must include a reference to the account addresses it will read from and write to. One alternative to storing these addresses in the message itself is to store them in an onchain account called an **address lookup table**. This lets you save space in the message by replacing many 32-byte account addresses with one or more 32-byte address lookup table account addresses then a 1-byte index into those tables for each address.\n\n<Callout type=\"warn\">\n    Addresses that are required signers of a transaction message can not be looked up in an address\n    lookup table; they must be encoded in the message in the conventional way.\n</Callout>\n\nGiven a transaction message and a mapping of lookup tables to the ordered addresses stored in them, the [`compressTransactionMessageUsingAddressLookupTables`](/api/functions/compressTransactionMessageUsingAddressLookupTables) function will return a new transaction message with the same instructions but with all non-signer accounts that are found in the given lookup tables represented by an [`AccountLookupMeta`](/api/interfaces/AccountLookupMeta) instead of an [`AccountMeta`](/api/interfaces/AccountMeta).\n\n```ts twoslash\nimport {\n    AddressesByLookupTableAddress,\n    Rpc,\n    GetAccountInfoApi,\n    TransactionMessage,\n} from '@solana/kit';\nconst rpc = null as unknown as Rpc<GetAccountInfoApi>;\nconst transactionMessage = null as unknown as Extract<TransactionMessage, { version: 0 }>;\n// ---cut-before---\nimport { address, compressTransactionMessageUsingAddressLookupTables } from '@solana/kit';\nimport { fetchAddressLookupTable } from '@solana-program/address-lookup-table';\n\nconst lookupTableAddress = address('4QwSwNriKPrz8DLW4ju5uxC2TN5cksJx6tPUPj7DGLAW');\nconst {\n    data: { addresses },\n} = await fetchAddressLookupTable(rpc, lookupTableAddress);\nconst addressesByAddressLookupTable: AddressesByLookupTableAddress = {\n    [lookupTableAddress]: addresses,\n};\n\nconst compressedTransactionMessage = compressTransactionMessageUsingAddressLookupTables(\n    transactionMessage,\n    addressesByAddressLookupTable,\n);\n```\n\nConsider how compressing transaction messages creates more space for instructions. This might enable you to prepare more complex transactions, or to execute the same number of instructions over fewer transactions thereby saving on network fees.\n\n<Callout type=\"warn\">\n    This technique can not be applied to transaction messages having the version `'legacy'`.\n</Callout>\n\n## Signing transaction messages\n\nIn order to be executed a transaction message must be signed by all of the private keys belonging to accounts that are required signers of the transaction, and must not exceed the size allowable by the network. You may encounter these types when using functions that send transactions.\n\n- [`FullySignedTransaction`](/api/type-aliases/FullySignedTransaction): A transaction that is signed by all of its required signers.\n- [`TransactionWithinSizeLimit`](/api/type-aliases/TransactionWithinSizeLimit): A transaction that is under or equal to the maximum size limit for transactions on the Solana network.\n- [`SendableTransaction`](/api/type-aliases/SendableTransaction): A union of `FullySignedTransaction` and `TransactionWithinSizeLimit`\n\nTransaction messages whose signers are specified using `TransactionSigner` objects have the ability to self-sign. This is because signers encapsulate both the address of the signing account as well as an implementation of the signing algorithm for the private key associated with that account.\n\nThe [`signTransactionMessageWithSigners`](/api/functions/signTransactionMessageWithSigners) method will return a new signed transaction of type `FullySignedTransaction`.\n\n```ts twoslash\nimport {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithSigners,\n} from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage &\n    TransactionMessageWithFeePayer &\n    TransactionMessageWithSigners;\n// ---cut-before---\nimport {\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n    isSolanaError,\n    signTransactionMessageWithSigners,\n} from '@solana/kit';\n\ntry {\n    const fullySignedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n        console.error('Missing signers for the following addresses:', e.context.addresses);\n    } else {\n        throw e;\n    }\n}\n```\n\n<Callout type=\"warn\">\n    This function will throw if the transaction message does not carry a `TransactionSigner`\n    implementation for every required signer. To partially sign a message that you know to carry a\n    strict subset of the required `TransactionSigners`, use the\n    [`partiallySignTransactionMessageWithSigners`](/api/functions/partiallySignTransactionMessageWithSigners)\n    method.\n</Callout>\n\n<Callout type=\"info\">\n    If exactly one of the `TransactionSigners` in the message is a\n    [`TransactionSendingSigner`](/api/type-aliases/TransactionSendingSigner) then you can use the\n    [`signAndSendTransactionMessageWithSigners`](/api/functions/signAndSendTransactionMessageWithSigners)\n    method to sign and send the transaction in a single step.\n</Callout>\n\nFor a comprehensive guide on all signing functions — including the lower-level [`partiallySignTransactionWithSigners`](/api/functions/partiallySignTransactionWithSigners), [`signTransactionWithSigners`](/api/functions/signTransactionWithSigners), and [`signAndSendTransactionWithSigners`](/api/functions/signAndSendTransactionWithSigners) functions that accept an explicit array of signers and a compiled transaction — see the [Signing with signers](/docs/advanced-guides/signers#signing-with-signers) section.\n\nBuilding transaction messages using `TransactionSigners` is the recommended way to create self-signable transaction messages. To sign with a `CryptoKey` directly, you first have to compile the transaction message.\n\n```ts twoslash\nimport {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithSigners,\n} from '@solana/kit';\nconst transactionMessage = null as unknown as TransactionMessage &\n    TransactionMessageWithFeePayer &\n    TransactionMessageWithSigners;\n// ---cut-before---\nimport { compileTransaction } from '@solana/kit';\n\nconst transaction = compileTransaction(transactionMessage);\n```\n\nThis produces an unsigned transaction. Follow the [instructions for signing transactions with `CryptoKeyPairs`](#signing-transactions) to sign it.\n\n## Signing transactions\n\nWherever you have a `Transaction` instead of a `TransactionMessage` you can add or replace a signature using the [`signTransaction`](/api/functions/signTransaction) method and one or more `CryptoKeyPairs`.\n\n```ts twoslash\nimport { Transaction, TransactionWithLifetime } from '@solana/kit';\nconst keyPair = null as unknown as CryptoKeyPair;\nconst transaction = null as unknown as Transaction & TransactionWithLifetime;\n// ---cut-before---\nimport {\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n    isSolanaError,\n    signTransaction,\n} from '@solana/kit';\n\ntry {\n    const fullySignedTransaction = await signTransaction([keyPair], transaction);\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n        console.error('Missing signers for the following addresses:', e.context.addresses);\n    } else {\n        throw e;\n    }\n}\n```\n\n<Callout type=\"warn\">\n    This function will throw if the resultant transaction is missing a signature for one of the\n    transaction's required signers. To partially sign a transaction, use the\n    [`partiallySignTransaction`](/api/functions/partiallySignTransaction) method.\n</Callout>\n\n<Callout type=\"info\">\n    If you have [`TransactionSigner`](/api/type-aliases/TransactionSigner) objects rather than raw\n    `CryptoKeyPairs`, you can use\n    [`signTransactionWithSigners`](/api/functions/signTransactionWithSigners) and\n    [`partiallySignTransactionWithSigners`](/api/functions/partiallySignTransactionWithSigners)\n    instead. See the [Signing with\n    signers](/docs/advanced-guides/signers#signing-compiled-transactions) section for details.\n</Callout>\n\n## Serializing transactions\n\nIf you would like to send a transaction to the network manually, you must first serialize it in a particular way. The [`Base64EncodedWireTransaction`](/api/type-aliases/Base64EncodedWireTransaction) represents the wire format of a transaction as a base64-encoded string.\n\nGiven a transaction, the [`getBase64EncodedWireTransaction`](/api/functions/getBase64EncodedWireTransaction) method returns the transaction as a string that conforms to the `Base64EncodedWireTransaction` type.\n\n```ts twoslash\nimport { Transaction, Rpc, SendTransactionApi } from '@solana/kit';\nconst rpc = null as unknown as Rpc<SendTransactionApi>;\nconst signedTransaction = null as unknown as Transaction;\n// ---cut-before---\nimport { getBase64EncodedWireTransaction, signTransaction } from '@solana/kit';\n\nconst serializedTransaction = getBase64EncodedWireTransaction(signedTransaction);\nconst signature = await rpc.sendTransaction(serializedTransaction, { encoding: 'base64' }).send();\n```\n\n<Callout type=\"info\">\n    Typically you would not serialize and send transactions to the network manually. See [Kit\n    without a client](/docs/advanced-guides/kit-without-a-client) for the full no-client transaction\n    flow.\n</Callout>\n\n## Deserializing transactions\n\nYou can fetch the raw bytes of a transaction from the network using an RPC server.\n\n```ts twoslash\nimport { createSolanaRpc, getBase64Encoder, Signature } from '@solana/kit';\nconst rpc = createSolanaRpc('...');\n// ---cut-before---\nconst response = await rpc\n    .getTransaction(\n        '3atZVDiLEjXmddxLbH2AWHtFdXmHRocnA4vNyvkPRcd7WnzCtoVshFCvGtxfGYWs9C6ptucY6Jd84BerDnzQpJEH' as Signature,\n        { encoding: 'base64' },\n    )\n    .send();\nif (!response) {\n    throw new Error('Could not find transaction');\n}\nconst {\n    transaction: [base64EncodedTransaction],\n} = response;\nconst transactionBytes = getBase64Encoder().encode(base64EncodedTransaction);\n```\n\nDecoding the wire transaction bytes yields a `Transaction` object. This takes the form of a transaction message encoded as a byte array, and a list of signatures of those bytes created by those who must authorize the message and pay for it to be executed on Solana.\n\n```ts twoslash\nimport { ReadonlyUint8Array } from '@solana/kit';\nconst transactionBytes = new Uint8Array() as ReadonlyUint8Array;\n// ---cut-before---\nimport { getTransactionDecoder } from '@solana/kit';\nconst transaction = getTransactionDecoder().decode(transactionBytes);\n```\n\nDecoding the network wire format bytes of the message will yield a transaction message in its **compiled** form – a message in a form suitable for execution on the network. Encountering a compiled message in your application is rare, but it's important to know that they exist.\n\n```ts twoslash\nimport { Transaction } from '@solana/kit';\nconst transaction = null as unknown as Transaction;\n// ---cut-before---\nimport { getCompiledTransactionMessageDecoder } from '@solana/kit';\nconst compiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(\n    transaction.messageBytes,\n);\n```\n\nFinally, decompiling a compiled message will yield a `TransactionMessage` object. This is the most common form of transaction message that you will encounter when using Kit to build an application.\n\n```ts twoslash\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '@solana/kit';\nconst compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n    CompiledTransactionMessageWithLifetime;\n// ---cut-before---\nimport { decompileTransactionMessage } from '@solana/kit';\nconst transactionMessage = decompileTransactionMessage(compiledTransactionMessage);\n```\n\n<Callout type=\"warn\">\n    You can not fully reconstruct a source message from a compiled message without extra\n    information. In particular, supporting details about the lifetime constraint and the concrete\n    addresses of accounts sourced from account lookup tables are lost to compilation, but can be\n    supplied in the `config` argument of the `decompileTransactionMessage` or\n    `decompileTransactionMessageFetchingLookupTables` methods.\n</Callout>\n"
  },
  {
    "path": "docs/content/docs/getting-started.mdx",
    "content": "---\ntitle: Getting started\ndescription: Build your first Solana app with Kit\n---\n\nIn this tutorial, we'll build a small Solana app with Kit. We'll create a devnet signer, fund it with devnet SOL, create a token mint, and read its data back — all with a plugin-composed Kit client.\n\n## Install dependencies\n\nFirst, let's install Kit and the plugins for connecting to Solana via RPC and loading a signer.\n\n```package-install\n@solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer\n```\n\nThen install the program plugins for the Solana programs you want to interact with. For this tutorial, we'll use the Token program to create and read a token mint.\n\n```package-install\n@solana-program/token\n```\n\n## Create a devnet signer\n\nBefore we start, let's create a signer that we can reuse across this tutorial. This one-time setup script grinds a small vanity address, makes the keypair extractable, and writes it to a local file in the same JSON format used by Solana CLI keypairs.\n\n```ts twoslash title=\"create-signer.ts\"\nimport { grindKeyPairSigner, writeKeyPairSigner } from '@solana/kit';\n\nconst signer = await grindKeyPairSigner({\n    extractable: true,\n    matches: /^kit/i,\n});\n\nawait writeKeyPairSigner(signer, './kit-getting-started-keypair.json');\n\nconsole.log(`✨ Created devnet signer ${signer.address}`);\nconsole.log('🔐 Wrote ./kit-getting-started-keypair.json');\nconsole.log('✅ Add this file to .gitignore before committing your project.');\n```\n\nRun this script once, then remove it from your project. We'll keep the generated `kit-getting-started-keypair.json` file locally for the rest of this tutorial. Be sure to add it to `.gitignore` if you are planning on committing these changes.\n\n<Callout>\n    Already have a Solana CLI keypair? You can skip this script and use\n    `signerFromFile('~/.config/solana/id.json')` instead. See [Setting Up\n    Signers](/docs/guides/setting-up-signers) for more signer options.\n</Callout>\n\n## Create a client\n\nNow let's create a client connected to devnet and load the signer from the file we just wrote.\n\n```ts twoslash\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\n\nconst client = await createClient()\n    .use(signerFromFile('./kit-getting-started-keypair.json'))\n    .use(solanaDevnetRpc())\n    .use(tokenProgram());\n```\n\nHere's what each piece does:\n\n- `createClient()` creates an empty Kit client that can be extended with plugins.\n- `.use(signerFromFile(...))` loads our keypair file and sets it as both the client's payer (who pays fees) and identity (who owns assets).\n- `.use(solanaDevnetRpc())` connects to devnet and adds RPC, subscriptions, airdrops, minimum balance helpers, and transaction sending.\n- `.use(tokenProgram())` adds typed access to the Token program's instructions and accounts.\n\nBecause we just created a fresh devnet signer, it won't have any SOL yet. Let's fund it with a devnet airdrop before moving on. If you're reusing a signer that already has devnet SOL, you can skip this step.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(signerFromFile('./kit-getting-started-keypair.json'))\n    .use(solanaDevnetRpc())\n    .use(tokenProgram());\n// ---cut-before---\nconst airdropSignature = await client.airdrop(client.payer.address, lamports(1_000_000_000n));\n\nconsole.log(`💸 Funded ${client.payer.address} with 1 SOL`);\nif (airdropSignature) {\n    console.log(`🔎 https://explorer.solana.com/tx/${airdropSignature}?cluster=devnet`);\n}\n```\n\n<Callout>\n    Airdrops are only available on test networks like devnet and localhost. Run the airdrop once,\n    then remove or comment out those lines before continuing so we do not hit devnet faucet rate\n    limits. If the airdrop fails, wait a moment and try again, or request devnet SOL from the\n    [Solana Faucet](https://faucet.solana.com).\n</Callout>\n\n## Send a transaction\n\nLet's create a token mint onchain. In Solana, every transaction contains one or more instructions: small commands that tell programs what to do. Some tasks, like creating a mint, require multiple instructions that should stay together. Kit represents that kind of multi-step operation as an **instruction plan**.\n\nThe Token program plugin gives us one of these plans via `client.token.instructions.createMint(...)`. Under the hood, it creates a new account for the provided mint address with enough lamports to be rent-exempt (system program's `createAccount` instruction) and initializes it as a Token program mint (token program's `initializeMint` instruction). We pass the new mint as a signer (since we initialize a new account), choose `9` decimals, and set our client identity as the mint authority.\n\n```ts twoslash\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(signerFromFile('./kit-getting-started-keypair.json'))\n    .use(solanaDevnetRpc())\n    .use(tokenProgram());\n// ---cut-before---\nconst mint = await generateKeyPairSigner();\n\nconst createMintPlan = client.token.instructions.createMint({\n    newMint: mint,\n    decimals: 9,\n    mintAuthority: client.identity.address,\n});\n\nconst createMintResult = await client.sendTransaction([createMintPlan]);\nconst createMintSignature = createMintResult.context.signature;\n\nconsole.log(`🎉 Created token mint ${mint.address}`);\nconsole.log(`🔎 https://explorer.solana.com/tx/${createMintSignature}?cluster=devnet`);\n```\n\n`client.sendTransaction([...])` accepts an array of instructions and instruction plans and sends them as a single transaction. If one part fails, the whole transaction fails. This is the most common way to send transactions with a client, especially when we want to combine several instructions or plans.\n\nFor simple one-off operations, program instruction helpers also include a `.sendTransaction()` shortcut. The following sends the same `createMint` instruction plan as a single transaction without explicitly calling `client.sendTransaction([...])`.\n\n```ts twoslash\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(signerFromFile('./kit-getting-started-keypair.json'))\n    .use(solanaDevnetRpc())\n    .use(tokenProgram());\nconst mint = await generateKeyPairSigner();\n// ---cut-before---\nconst createMintResult = await client.token.instructions\n    .createMint({\n        newMint: mint,\n        decimals: 9,\n        mintAuthority: client.identity.address,\n    })\n    .sendTransaction();\n```\n\nFor error handling, priority fees, and more advanced patterns, see the [Sending Transactions](/docs/guides/sending-transactions) guide.\n\n## Fetch an account\n\nNow let's read the mint account we just created.\n\nProgram plugins provide typed fetch helpers that decode account data automatically. The `mintAccount.data` object gives us the full `Mint` structure with fields like `decimals`, `mintAuthority`, `supply`, and `freezeAuthority`.\n\n```ts twoslash\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(signerFromFile('./kit-getting-started-keypair.json'))\n    .use(solanaDevnetRpc())\n    .use(tokenProgram());\nconst mint = await generateKeyPairSigner();\n// ---cut-before---\nconst mintAccount = await client.token.accounts.mint.fetch(mint.address);\n\nconsole.log('✅ Mint account decoded');\nconsole.log(`   Address: ${mint.address}`);\nconsole.log(`   Decimals: ${mintAccount.data.decimals}`);\nconsole.log('   Mint authority:', mintAccount.data.mintAuthority);\nconsole.log(`   Supply: ${mintAccount.data.supply}`);\n```\n\nFor raw account fetching and manual decoding, see the [Fetching Accounts](/docs/guides/fetching-accounts) guide.\n\n## Full example\n\nHere's the complete script you can copy and run after creating `kit-getting-started-keypair.json`.\n\n```ts twoslash\nimport { createClient, generateKeyPairSigner, lamports } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\n\nconst client = await createClient()\n    .use(signerFromFile('./kit-getting-started-keypair.json'))\n    .use(solanaDevnetRpc())\n    .use(tokenProgram());\n\n// Run this once, then remove or comment it out to avoid devnet faucet rate limits.\nconst airdropSignature = await client.airdrop(client.payer.address, lamports(1_000_000_000n));\nconsole.log(`💸 Funded ${client.payer.address} with 1 SOL`);\nif (airdropSignature) {\n    console.log(`🔎 https://explorer.solana.com/tx/${airdropSignature}?cluster=devnet`);\n}\n\nconst mint = await generateKeyPairSigner();\nconst createMintPlan = client.token.instructions.createMint({\n    newMint: mint,\n    decimals: 9,\n    mintAuthority: client.identity.address,\n});\n\nconst createMintResult = await client.sendTransaction([createMintPlan]);\nconst createMintSignature = createMintResult.context.signature;\n\nconsole.log(`🎉 Created token mint ${mint.address}`);\nconsole.log(`🔎 https://explorer.solana.com/tx/${createMintSignature}?cluster=devnet`);\n\nconst mintAccount = await client.token.accounts.mint.fetch(mint.address);\n\nconsole.log('✅ Mint account decoded');\nconsole.log(`   Address: ${mint.address}`);\nconsole.log(`   Decimals: ${mintAccount.data.decimals}`);\nconsole.log('   Mint authority:', mintAccount.data.mintAuthority);\nconsole.log(`   Supply: ${mintAccount.data.supply}`);\n```\n\n## Next steps\n\nWe've connected to devnet, funded a signer, created a token mint, and read its data. Here's where to go next:\n\n- [Setting Up Signers](/docs/guides/setting-up-signers) — load signers from keypair files, wallet standard, and more.\n- [Sending Transactions](/docs/guides/sending-transactions) — error handling, priority fees, and instruction plans.\n- [Fetching Accounts](/docs/guides/fetching-accounts) — program plugin fetch helpers, batch fetching, and decoding.\n- [Using Program Plugins](/docs/guides/using-program-plugins) — typed access to any Solana program.\n- [Plugins](/docs/plugins) — understand and extend the plugin system.\n"
  },
  {
    "path": "docs/content/docs/guides/fetching-accounts.mdx",
    "content": "---\ntitle: Fetching accounts\ndescription: Read and decode onchain account data\n---\n\nReading data from Solana usually means fetching one or more accounts and decoding their data into something your application can use. This guide walks through the helpers Kit provides at each step, from the raw RPC call all the way to typed account objects.\n\n## Fetch raw account data\n\nThe `fetchEncodedAccount` helper wraps the `getAccountInfo` RPC method and returns a `MaybeEncodedAccount`. The result always has the same shape regardless of whether the account exists, which makes it easier to handle than the raw RPC response.\n\n```ts twoslash\nimport { address, fetchEncodedAccount } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst account = await fetchEncodedAccount(client.rpc, wallet);\n```\n\nWhen the account exists, you get back its address, lamports, owner program, and a `data` field containing the raw bytes as a `Uint8Array`. When it does not, the same object is returned with `exists: false` and just the address.\n\n## Handle missing accounts\n\nA `MaybeEncodedAccount` is a discriminated union: TypeScript narrows the type once you check `account.exists`. You can branch on that flag, or use `assertAccountExists` when you would rather throw if the account is not present.\n\n```ts twoslash\nimport { address, assertAccountExists, fetchEncodedAccount } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst account = await fetchEncodedAccount(client.rpc, wallet);\nassertAccountExists(account);\n\n// `account` is now `EncodedAccount`, with `data` typed as `Uint8Array`.\naccount.data satisfies Uint8Array;\n```\n\nAsserting up front lets the rest of your function rely on a fully populated account, which is convenient for scripts and tests. In application code, branching on `account.exists` is usually a better fit so you can show a sensible empty state. When working with several accounts at once, `assertAccountsExist(accounts)` performs the same check across an entire array in one call.\n\n## Fetch multiple accounts\n\nWhen you need several accounts at once, `fetchEncodedAccounts` batches them into a single `getMultipleAccounts` RPC request and returns a parallel array of `MaybeEncodedAccount` values.\n\n```ts twoslash\nimport { address, fetchEncodedAccounts } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst accounts = await fetchEncodedAccounts(client.rpc, [\n    address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ'),\n    address('Ay1zdJ3VDbhrAtkRiqBUJgKLHYbgFZN5BXk7svtMowif'),\n]);\n```\n\nEach returned account already carries its own address, so you do not need to zip arrays together to figure out which result belongs to which input. The same `exists` flag works on every entry, and `assertAccountsExist(accounts)` is the multi-account counterpart of `assertAccountExists`.\n\n## Decode accounts manually\n\nOnce you have an encoded account, the `decodeAccount` helper turns it into a typed `Account` (or `MaybeAccount`) by running its `data` through any `Decoder`. The [Codecs guide](/docs/advanced-guides/codecs) covers how to build these decoders.\n\n```ts twoslash\nimport { address, decodeAccount, fetchEncodedAccount } from '@solana/kit';\nimport {\n    addDecoderSizePrefix,\n    Decoder,\n    getStructDecoder,\n    getU32Decoder,\n    getU8Decoder,\n    getUtf8Decoder,\n} from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\n\ntype Person = { name: string; age: number };\nconst personDecoder: Decoder<Person> = getStructDecoder([\n    ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n    ['age', getU8Decoder()],\n]);\n\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst encodedAccount = await fetchEncodedAccount(client.rpc, wallet);\nconst decodedAccount = decodeAccount(encodedAccount, personDecoder);\n```\n\n`decodeAccount` preserves the `MaybeAccount` shape: a missing account stays missing, and a present account gets its `data` swapped from raw bytes to your decoded type. This means you can keep narrowing with `account.exists` exactly like before.\n\n## Decode using program helpers\n\nFor most popular Solana programs you will not need to write a decoder yourself. The `@solana-program/*` packages include generated helpers that handle decoding for every account they define, exposed as `decodeX`, `fetchX`, and `fetchMaybeX` functions where `X` is the account name.\n\n```ts twoslash\nimport { address } from '@solana/kit';\nimport { fetchMint } from '@solana-program/token';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst mint = await fetchMint(client.rpc, address('So11111111111111111111111111111111111111112'));\nmint.data.decimals; // typed as `number`\n```\n\nEach program package follows the same naming convention: `fetchMint` and `fetchMaybeMint` for the `Mint` account, `fetchToken` and `fetchMaybeToken` for the `Token` account, and so on. The standalone `decodeMint` and `decodeToken` helpers work on encoded accounts you have already fetched. If you would rather access these through a typed `client.token.accounts.*` namespace, see the [Using program plugins](/docs/guides/using-program-plugins) guide.\n\n## Subscribe to account changes\n\nIf you need live updates rather than a one-off read, pair an account fetch with an account subscription. The subscription notifies you whenever the account's data changes onchain, and the same address is used in both calls.\n\n```ts twoslash\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst accountNotifications = await client.rpcSubscriptions\n    .accountNotifications(wallet, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: AbortSignal.timeout(60_000) });\n\nfor await (const notification of accountNotifications) {\n    console.log('Account changed:', notification.value);\n}\n```\n\nSee the [RPC subscriptions](/docs/guides/rpc-subscriptions) guide for more on cancellation, error handling, and the async iterator model.\n\n## Choose the right fetch helper\n\nEach helper trades a different amount of structure and convenience. The table below summarizes when each one shines.\n\n| Helper                                | Returns                           | Best for                               |\n| ------------------------------------- | --------------------------------- | -------------------------------------- |\n| `client.rpc.getAccountInfo(...)`      | raw RPC response                  | one-off reads with custom encoding     |\n| `client.rpc.getMultipleAccounts(...)` | raw RPC response                  | bulk reads with custom encoding        |\n| `fetchEncodedAccount(...)`            | `MaybeEncodedAccount`             | unified handling of single accounts    |\n| `fetchEncodedAccounts(...)`           | `MaybeEncodedAccount[]`           | unified batch reads                    |\n| `decodeAccount(...)`                  | `Account<T>` / `MaybeAccount<T>`  | turning raw bytes into typed data      |\n| `fetchMint`, `fetchToken`, ...        | `Account<T>` / `MaybeAccount<T>`  | typed reads for known program accounts |\n| `accountNotifications(...)`           | async iterator of account updates | live updates instead of one-off reads  |\n\nIn practice you can pick any of them in isolation, or combine them to match the access pattern you need.\n\n## Next steps\n\n- [Codecs](/docs/advanced-guides/codecs) — learn how to build custom decoders.\n- [RPC requests](/docs/guides/rpc) — explore the rest of the RPC API.\n- [Using program plugins](/docs/guides/using-program-plugins) — read typed accounts through `client.token.accounts.mint.fetch(...)` and friends.\n"
  },
  {
    "path": "docs/content/docs/guides/index.mdx",
    "content": "---\ntitle: Guides\ndescription: Practical guides for common tasks with Kit\n---\n\nThe pages in this section cover the most common tasks you will run into when building Solana applications with Kit. Each guide focuses on a single topic and can be read independently, so you can dip in when a specific question comes up rather than reading them in order.\n\n## How to use these guides\n\nIf you are completely new to Kit, start with the [Getting started](/docs/getting-started) tutorial. It walks through a small end-to-end project so the rest of the documentation has something concrete to reference.\n\nOnce you have shipped your first transaction, the guides below are designed to be your day-to-day companion. They focus on practical workflows — composing a client, sending transactions, fetching accounts, testing locally, and so on — and link to the [Advanced guides](/docs/advanced-guides) when you want to learn what is happening under the hood.\n"
  },
  {
    "path": "docs/content/docs/guides/meta.json",
    "content": "{\n    \"title\": \"Guides\",\n    \"defaultOpen\": true,\n    \"pages\": [\n        \"setting-up-signers\",\n        \"rpc\",\n        \"rpc-subscriptions\",\n        \"sending-transactions\",\n        \"sending-multiple-transactions\",\n        \"fetching-accounts\",\n        \"using-program-plugins\",\n        \"testing-and-local-development\"\n    ]\n}\n"
  },
  {
    "path": "docs/content/docs/guides/rpc-subscriptions.mdx",
    "content": "---\ntitle: RPC subscriptions\ndescription: Get notified of changes to the blockchain\n---\n\nRPC subscriptions let your application receive live updates from the network instead of polling for them. They are delivered over a WebSocket endpoint and surface as async iterators in Kit, which fit naturally into modern JavaScript control flow.\n\nKit aims to support every method documented in the [Solana RPC WebSocket methods](https://solana.com/docs/rpc/websocket) docs. As with HTTP RPC, you can either browse the methods in the official documentation or rely on TypeScript autocompletion in your editor.\n\n## Installation\n\nYou will typically install Kit alongside the RPC plugin package, which provides both HTTP and WebSocket connectivity.\n\n```package-install\n@solana/kit @solana/kit-plugin-rpc\n```\n\nIf you only need subscriptions and prefer not to use a Kit client, the lower-level `createSolanaRpcSubscriptions` function is available directly from `@solana/kit`.\n\n## Create a subscriptions client\n\nThe bundle plugins from `@solana/kit-plugin-rpc` install both `client.rpc` and `client.rpcSubscriptions` in one step. You do not need to manage two separate transports.\n\n```ts twoslash\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n```\n\nBy default, the WebSocket endpoint is derived from the HTTP endpoint by swapping `http`/`https` for `ws`/`wss`. If your provider hosts the two endpoints at different URLs, pass `rpcSubscriptionsUrl` explicitly in the plugin configuration.\n\n## Subscribe to slot notifications\n\nSubscriptions return an async iterator. The most idiomatic way to consume one is a `for await` loop, which keeps reading notifications until the underlying subscription ends.\n\n```ts twoslash\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst slotNotifications = await client.rpcSubscriptions\n    .slotNotifications()\n    .subscribe({ abortSignal: AbortSignal.timeout(10_000) });\n\nfor await (const notification of slotNotifications) {\n    console.log('The network advanced to slot', notification.slot);\n}\n```\n\nThe `.subscribe({ abortSignal })` step is mandatory because every subscription must be tied to an `AbortSignal`. This forces you to think up front about when the subscription should end and prevents leaks.\n\n## Cancel subscriptions\n\nYou may want to cancel a subscription before it ends naturally — for example, when a component unmounts in a UI. Pass an `AbortController` so that calling `.abort()` from anywhere in your code stops the iterator gracefully.\n\n```ts twoslash\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst abortController = new AbortController();\nconst slotNotifications = await client.rpcSubscriptions\n    .slotNotifications()\n    .subscribe({ abortSignal: abortController.signal });\n\n// Stop receiving notifications after the user navigates away.\nabortController.abort();\n```\n\n`AbortSignal.timeout(ms)` is a convenient shortcut when you simply want a fixed duration. For one-off subscriptions, that single line is often all you need.\n\n## Subscribe to account changes\n\nAccount subscriptions notify you whenever an account's data changes onchain. The shape of the notification mirrors the response of `getAccountInfo`, so the same encoding and commitment options apply.\n\n```ts twoslash\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst accountNotifications = await client.rpcSubscriptions\n    .accountNotifications(wallet, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: AbortSignal.timeout(60_000) });\n\nfor await (const notification of accountNotifications) {\n    console.log('Account changed:', notification.value);\n}\n```\n\nIf you only need a one-off read of an account, [`fetchEncodedAccount`](/docs/guides/fetching-accounts) is usually a better fit. Use subscriptions for live, ongoing updates.\n\n## Handle disconnects and errors\n\nLong-lived subscriptions can disconnect for many reasons — flaky networks, server restarts, or connection limits — and errors can be raised at any point during iteration. Wrap the iteration in a `try`/`catch` so your application can react gracefully.\n\n```ts twoslash\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst accountNotifications = await client.rpcSubscriptions\n    .accountNotifications(wallet, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: AbortSignal.timeout(60_000) });\n\ntry {\n    for await (const notification of accountNotifications) {\n        console.log('Account changed:', notification.value);\n    }\n} catch (error) {\n    // Reconnect, log, surface a UI error, etc.\n}\n```\n\nDepending on your application, you may want to recreate the subscription with a fresh `AbortSignal` after a disconnect, possibly using a small backoff to avoid thrashing the server.\n\n## Use subscriptions without a client\n\nIf you do not need a Kit client, you can build an `RpcSubscriptions` object directly with `createSolanaRpcSubscriptions`. This is the lower-level building block the plugins use under the hood.\n\n```ts twoslash\nimport { createSolanaRpcSubscriptions, mainnet } from '@solana/kit';\n\nconst rpcSubscriptions = createSolanaRpcSubscriptions(mainnet('wss://api.mainnet-beta.solana.com'));\nconst slotNotifications = await rpcSubscriptions\n    .slotNotifications()\n    .subscribe({ abortSignal: AbortSignal.timeout(10_000) });\n```\n\nThis is useful when you want maximum tree-shaking, when you are writing a library that should not assume a client, or when you only need a tiny subset of the subscriptions API.\n\n## Choose a WebSocket endpoint\n\nFor light development or personal use, the public WebSocket endpoints maintained by the Solana Foundation work the same way as their HTTP counterparts.\n\n- `wss://api.mainnet-beta.solana.com`\n- `wss://api.testnet.solana.com`\n- `wss://api.devnet.solana.com`\n\nIn production, your HTTP and WebSocket endpoints should match — both clusters and providers — to avoid subtle mismatches between the data each transport returns. Most RPC providers offer paired endpoints; consult their documentation for the exact URLs they expect you to use.\n\n## Next steps\n\n- [RPC requests](/docs/guides/rpc) — read state and submit one-off requests over HTTP.\n- [Fetching accounts](/docs/guides/fetching-accounts) — pair subscriptions with a baseline read.\n- [Sending transactions](/docs/guides/sending-transactions) — submit work to the network.\n"
  },
  {
    "path": "docs/content/docs/guides/rpc.mdx",
    "content": "---\ntitle: RPC requests\ndescription: Read and write data to the blockchain\n---\n\nSolana applications interact with the network through a JSON-RPC server. RPC requests are how your code reads onchain state, simulates transactions, and submits transactions to be processed. Kit ships a fully typed RPC client and exposes it on Kit clients via plugins, so the same RPC API is available whether you compose a client or use the lower-level building blocks directly.\n\nKit aims to support every method documented in the [Solana RPC HTTP methods](https://solana.com/docs/rpc/http) docs. You can either browse the methods in the official documentation or rely on TypeScript autocompletion in your editor.\n\n## Installation\n\nYou will typically install Kit alongside the RPC plugin package.\n\n```package-install\n@solana/kit @solana/kit-plugin-rpc\n```\n\nThe `@solana/kit-plugin-rpc` package contains the plugins that install RPC connectivity on a client. The `@solana/kit` package contains the lower-level RPC primitives those plugins are built on top of, so you can also use it standalone if you prefer not to use a client.\n\n## Create an RPC client\n\nThe most convenient way to make RPC requests is to compose a Kit client with one of the bundle plugins, which install both `client.rpc` and `client.rpcSubscriptions` in one call.\n\n```ts twoslash\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n```\n\nThe bundle plugins also wire up minimum balance computation, transaction planning, and transaction sending, which you will use in the other guides. If you only need to make read-only RPC requests, you can drop the signer plugin and use `solanaRpcConnection(...)` instead, which only installs `client.rpc` and `client.rpcSubscriptions`.\n\n## Send your first RPC request\n\nOnce you have an RPC client, you build a request by calling the corresponding method on `client.rpc` and finalize it with `.send()`. Most RPC responses come back wrapped in a `{ context, value }` object, so destructuring `value` is a common pattern.\n\n```ts twoslash\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\n\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst { value: balance } = await client.rpc.getBalance(wallet).send();\n```\n\nAlthough `client.rpc` looks like a regular object, it is actually a [`Proxy`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) that constructs RPC requests on demand. TypeScript provides type safety for every method based on the API installed by your plugin, which makes the available methods discoverable from your editor while keeping the bundle small.\n\n## Use cluster-specific RPC bundles\n\nThe `@solana/kit-plugin-rpc` package ships several bundle plugins, each tailored to a specific use case. The cluster-typed variants type the RPC API to match what is available on that cluster, which prevents accidents like calling `airdrop` against mainnet at compile time.\n\n| Plugin                  | Default endpoint                | Adds to the client                                          |\n| ----------------------- | ------------------------------- | ----------------------------------------------------------- |\n| `solanaRpc(config)`     | provided via `rpcUrl`           | RPC, subscriptions, planning, sending                       |\n| `solanaMainnetRpc(...)` | provided via `rpcUrl`           | mainnet-typed RPC, subscriptions, planning, sending         |\n| `solanaDevnetRpc(...)`  | `https://api.devnet.solana.com` | devnet-typed RPC, subscriptions, planning, sending, airdrop |\n| `solanaLocalRpc(...)`   | `http://127.0.0.1:8899`         | localnet RPC, subscriptions, planning, sending, airdrop     |\n\nIf you need to talk to a custom RPC provider, pass its URL through `solanaRpc({ rpcUrl: '...' })` or `solanaMainnetRpc({ rpcUrl: '...' })`. The other settings on `SolanaRpcConfig` cover advanced options such as transport configuration and transaction planner overrides.\n\n## Pass request options\n\nMost RPC methods accept a configuration object as their final argument. This is where you control things like the requested commitment level, encoding, or pagination, depending on the method.\n\n```ts twoslash\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n// ---cut-end---\n\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst { value: balance } = await client.rpc.getBalance(wallet, { commitment: 'confirmed' }).send();\n```\n\nThe `.send(...)` call itself accepts an optional `abortSignal` that lets you cancel the request in flight.\n\n## Use RPC without a client\n\nIf you do not need a Kit client, you can build an `Rpc` object directly with `createSolanaRpc`. This is useful when you want maximum tree-shaking, when you are writing a library that should not assume a client, or when you simply want to keep your dependency surface small.\n\n```ts twoslash\nimport { address, createSolanaRpc } from '@solana/kit';\n\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\nconst wallet = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst { value: balance } = await rpc.getBalance(wallet).send();\n```\n\nThe standalone `Rpc` object exposes the exact same API as `client.rpc`, so any code that takes an `Rpc` will work in either setup. See the [Kit without a client](/docs/advanced-guides/kit-without-a-client) guide for more on this approach.\n\n## Choose an RPC endpoint\n\nFor light development or personal use, the public RPC endpoints maintained by the Solana Foundation are a fine starting point.\n\n- `https://api.mainnet-beta.solana.com`\n- `https://api.testnet.solana.com`\n- `https://api.devnet.solana.com`\n\nThese endpoints are heavily rate-limited and should not be used for anything close to production traffic. When you ship to production, lease an RPC node from a provider or [run your own](https://docs.anza.xyz/operations/setup-an-rpc-node). Some RPC providers also expose extra methods on top of the standard JSON-RPC API; many of them ship a Kit-compatible SDK that you can layer on top of `createSolanaRpc(...)` to merge their additional methods into the typed RPC object.\n\n## Next steps\n\n- [RPC subscriptions](/docs/guides/rpc-subscriptions) — receive live updates from a WebSocket endpoint.\n- [Fetching accounts](/docs/guides/fetching-accounts) — go from raw account bytes to typed data.\n- [Sending transactions](/docs/guides/sending-transactions) — submit transactions through your client.\n"
  },
  {
    "path": "docs/content/docs/guides/sending-multiple-transactions.mdx",
    "content": "---\ntitle: Sending multiple transactions\ndescription: Plan and execute work across several transactions\n---\n\nWhen an operation cannot fit in a single transaction — too many instructions, too much data, or work that should run in parallel — you need to split it across several transactions. Kit clients support this through the same `client.sendTransactions(...)` and `client.planTransactions(...)` methods you used in [Sending transactions](/docs/guides/sending-transactions), but plural.\n\n## Prerequisites\n\nThis guide assumes a transaction-ready client, like the one set up in [Sending transactions](/docs/guides/sending-transactions). The same bundle plugins from `@solana/kit-plugin-rpc` and `@solana/kit-plugin-litesvm` install everything `client.sendTransactions(...)` needs out of the box.\n\n## Instruction plans\n\nAn instruction plan describes an operation made of several instructions together with constraints on how they can run — some steps must happen sequentially, others may run in parallel, and some must stay atomic. Kit represents this as a tree, so simple operations stay simple while more complex flows can nest sequential and parallel branches inside each other. The plan is then handed to a [transaction planner](/docs/advanced-guides/instruction-plans) that decides how to pack it into transaction messages, and then to a [transaction plan executor](/docs/advanced-guides/instruction-plans) that sends those transactions.\n\nKit's planners can divide work, batch it into transactions, and even pack variable-sized data into the available space. For most cases you only need to know about three building blocks: `singleInstructionPlan`, `sequentialInstructionPlan`, and `parallelInstructionPlan`. The [Instruction plans](/docs/advanced-guides/instruction-plans) advanced guide goes much deeper.\n\n## Run work sequentially\n\nUse `sequentialInstructionPlan(...)` when each step depends on the previous one — for example, creating an account before initializing it.\n\n```ts twoslash\nimport { Instruction, sequentialInstructionPlan } from '@solana/kit';\nconst createAccount = {} as Instruction;\nconst initializeAccount = {} as Instruction;\n// ---cut-before---\nconst instructionPlan = sequentialInstructionPlan([createAccount, initializeAccount]);\n```\n\nSequential plans accept either raw instructions or other instruction plans, so you can compose larger flows from smaller ones. A `nonDivisibleSequentialInstructionPlan(...)` variant also exists for steps that must run atomically inside a single transaction (or transaction bundle when not possible).\n\n## Run work in parallel\n\nUse `parallelInstructionPlan(...)` when independent steps can run in any order. The planner is then free to pack them into separate transactions and send them concurrently.\n\n```ts twoslash\nimport { Instruction, parallelInstructionPlan } from '@solana/kit';\nconst transferToBob = {} as Instruction;\nconst transferToCarla = {} as Instruction;\n// ---cut-before---\nconst instructionPlan = parallelInstructionPlan([transferToBob, transferToCarla]);\n```\n\nThe two helpers compose freely: a sequential plan can contain parallel children and vice versa. This is how you describe operations like \"set up these two accounts in parallel, then run the operation that depends on both of them\".\n\n## Plan multiple transactions\n\nWhen you only want to inspect or persist the planned transactions, `client.planTransactions(plan)` runs the planner without executing anything and returns the resulting `TransactionPlan` tree.\n\n```ts twoslash\nimport { lamports, parallelInstructionPlan } from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\n// ---cut-start---\nimport { address } from '@solana/kit';\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(10_000_000_000n)));\nconst bob = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst carla = address('Ay1zdJ3VDbhrAtkRiqBUJgKLHYbgFZN5BXk7svtMowif');\n// ---cut-end---\nconst instructionPlan = parallelInstructionPlan([\n    getTransferSolInstruction({\n        source: client.payer,\n        destination: bob,\n        amount: lamports(500_000n),\n    }),\n    getTransferSolInstruction({\n        source: client.payer,\n        destination: carla,\n        amount: lamports(500_000n),\n    }),\n]);\n\nconst transactionPlan = await client.planTransactions(instructionPlan);\n```\n\nThe returned `TransactionPlan` keeps the same sequential and parallel structure as the original instruction plan, but its leaves are the concrete transaction messages the planner chose to pack the work into. This is useful for dry runs, debugging, or feeding a custom executor.\n\n## Send multiple transactions\n\nTo plan and send in one call, use `client.sendTransactions(plan)`. The result is a `TransactionPlanResult` tree that mirrors the original plan, with one leaf per transaction.\n\n```ts twoslash\nimport { lamports, parallelInstructionPlan } from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\n// ---cut-start---\nimport { address } from '@solana/kit';\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(10_000_000_000n)));\nconst bob = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\nconst carla = address('Ay1zdJ3VDbhrAtkRiqBUJgKLHYbgFZN5BXk7svtMowif');\n// ---cut-end---\nconst instructionPlan = parallelInstructionPlan([\n    getTransferSolInstruction({\n        source: client.payer,\n        destination: bob,\n        amount: lamports(500_000n),\n    }),\n    getTransferSolInstruction({\n        source: client.payer,\n        destination: carla,\n        amount: lamports(500_000n),\n    }),\n]);\n\nconst result = await client.sendTransactions(instructionPlan);\n```\n\n`client.sendTransactions(...)` is the multi-transaction counterpart of `client.sendTransaction(...)`. The single-transaction version asserts that the plan resolves to exactly one transaction and unwraps its result — a convenience for the common case. The plural version preserves the full tree, which you can walk to see what happened.\n\n## Understand transaction plan results\n\nEvery leaf in the result tree is a `SingleTransactionPlanResult` with one of three statuses:\n\n- `successful` — the transaction was sent and confirmed; `context.signature` is always present.\n- `failed` — the transaction was attempted but failed during preflight, simulation, or execution. `error` carries the underlying error.\n- `canceled` — the transaction was never attempted, typically because a prior transaction in a sequential branch failed first.\n\n```ts twoslash\nimport { TransactionPlanResult } from '@solana/kit';\nconst result = {} as TransactionPlanResult;\n// ---cut-before---\nif (result.kind === 'single') {\n    if (result.status === 'successful') {\n        console.log('Signature:', result.context.signature);\n    } else if (result.status === 'failed') {\n        console.error('Failed:', result.error);\n    } else {\n        console.warn('Canceled before being sent');\n    }\n}\n```\n\nBranch nodes use `kind: 'parallel'` or `kind: 'sequential'`, with their child results in `plans`. You usually do not need to walk the tree by hand — the helpers in the next sections cover the common cases.\n\n## Summarize results\n\n`summarizeTransactionPlanResult(...)` flattens the tree and bucketizes the results so you can quickly check whether everything succeeded.\n\n```ts twoslash\nimport { summarizeTransactionPlanResult, TransactionPlanResult } from '@solana/kit';\nconst result = {} as TransactionPlanResult;\n// ---cut-before---\nconst summary = summarizeTransactionPlanResult(result);\n\nif (summary.successful) {\n    console.log(`✅ ${summary.successfulTransactions.length} transactions confirmed`);\n} else {\n    console.warn(\n        `${summary.successfulTransactions.length} ok, ` +\n            `${summary.failedTransactions.length} failed, ` +\n            `${summary.canceledTransactions.length} canceled`,\n    );\n}\n```\n\nThis is usually the first thing to reach for after `client.sendTransactions(...)` — it gives you a quick health check without writing any tree-walking code.\n\n## Continue after failures\n\nBy default, `client.sendTransactions(...)` throws as soon as any transaction in the plan fails. That behaviour is convenient for small operations, but counterproductive when you are running a large batch and want to inspect partial results. The `passthroughFailedTransactionPlanExecution(...)` helper turns that thrown error back into a `TransactionPlanResult`.\n\n```ts twoslash\nimport { InstructionPlan, passthroughFailedTransactionPlanExecution } from '@solana/kit';\nconst instructionPlan = {} as InstructionPlan;\n// ---cut-start---\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(10_000_000_000n)));\n// ---cut-end---\nconst result = await passthroughFailedTransactionPlanExecution(\n    client.sendTransactions(instructionPlan),\n);\n```\n\nAfter this call, `result` is the same tree you would have received on full success — but with `failed` and `canceled` leaves where the issues occurred. You can then summarize it, walk it, or react however you need.\n\n## Handle partial success\n\nWhen you want to react to each transaction individually, `flattenTransactionPlanResult(...)` collapses the tree into an array of leaf results in the order they appear.\n\n```ts twoslash\nimport { flattenTransactionPlanResult, TransactionPlanResult } from '@solana/kit';\nconst result = {} as TransactionPlanResult;\n// ---cut-before---\nfor (const single of flattenTransactionPlanResult(result)) {\n    if (single.status === 'successful') {\n        console.log('✅', single.context.signature);\n    } else if (single.status === 'failed') {\n        console.error('❌', single.error.message);\n    } else {\n        console.warn('⏭️', 'canceled');\n    }\n}\n```\n\nCombined with `passthroughFailedTransactionPlanExecution(...)`, this is enough to drive a UI that shows per-transaction status, retry buttons, or detailed error messages for a long-running multi-transaction operation.\n\n## Next steps\n\n- [Sending transactions](/docs/guides/sending-transactions) — single-transaction basics.\n- [Advanced guides — Instruction plans](/docs/advanced-guides/instruction-plans) — the full instruction plan API.\n- [Advanced guides — Errors](/docs/advanced-guides/errors) — recover from `SolanaError` failures.\n"
  },
  {
    "path": "docs/content/docs/guides/sending-transactions.mdx",
    "content": "---\ntitle: Sending transactions\ndescription: Send single transactions with a Kit client\n---\n\nA Kit client can take a list of instructions and turn it into a fully signed, sent, and confirmed transaction in a single call. This guide covers the basics of sending one transaction at a time. When an operation needs to span multiple transactions, see [Sending multiple transactions](/docs/guides/sending-multiple-transactions).\n\n## Create a transaction-ready client\n\nSending transactions requires a client that exposes a `sendTransaction` method. At the lowest level, this means installing the [`planAndSendTransactions`](/docs/plugins/available-plugins) plugin from `@solana/kit-plugin-instruction-plan` on top of a custom `transactionPlanner` and `transactionPlanExecutor`. In practice, you almost always pick a higher-level bundle that does this for you.\n\n```ts twoslash\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient().use(generatedSigner()).use(solanaLocalRpc());\n```\n\nThe bundle plugins from `@solana/kit-plugin-rpc` (`solanaRpc`, `solanaMainnetRpc`, `solanaDevnetRpc`, `solanaLocalRpc`) and the `litesvm` plugin from `@solana/kit-plugin-litesvm` all install a working planner and executor out of the box. Community plugins that target other backends should follow the same pattern, so the rest of this guide works the same way regardless of where transactions are actually sent.\n\nThe signer plugin must be installed before the bundle, because the bundle's transaction planner needs a `payer` on the client to plan transactions. See [Setting up signers](/docs/guides/setting-up-signers) for the full set of signer options.\n\n## Send instructions\n\nOnce your client is ready, `client.sendTransaction([...])` accepts an array of instructions and turns them into a single transaction. The client takes care of fetching a recent blockhash, estimating compute units when applicable, setting the fee payer, signing with all attached signers, sending the transaction, and waiting for confirmation.\n\n```ts twoslash\nimport { address, lamports } from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)));\n// ---cut-end---\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n\nconst result = await client.sendTransaction([\n    getTransferSolInstruction({\n        source: client.payer,\n        destination: recipient,\n        amount: lamports(500_000n),\n    }),\n    getTransferSolInstruction({\n        source: client.payer,\n        destination: recipient,\n        amount: lamports(500_000n),\n    }),\n]);\n```\n\nA single `client.sendTransaction([...])` call always produces exactly one transaction onchain, which means every instruction succeeds together or fails together. If you have so many instructions that they cannot fit in one transaction, use [`client.sendTransactions(...)`](/docs/guides/sending-multiple-transactions) instead.\n\n## Plan before sending\n\nSometimes you do not want to send the transaction immediately. You may want to inspect the planned message before signing, log it for debugging, or take over the rest of the lifecycle yourself. The `client.planTransaction([...])` method returns the planned transaction message and stops there, leaving signing and sending to you.\n\n```ts twoslash\nimport { address, lamports } from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)));\n// ---cut-end---\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n\nconst transactionMessage = await client.planTransaction([\n    getTransferSolInstruction({\n        source: client.payer,\n        destination: recipient,\n        amount: lamports(500_000n),\n    }),\n]);\n```\n\nThis gives you full control over what happens next: you can sign the message with [`signTransactionMessageWithSigners`](/docs/advanced-guides/signers), encode it for transmission to another service, or pass it to a custom executor. Note that the executor used by `client.sendTransaction([...])` may further mutate the planned message before sending — for example by attaching a fresh blockhash or refreshing the compute unit limit — so the message you inspect here is not guaranteed to be byte-identical to what would land onchain. The [Kit without a client](/docs/advanced-guides/kit-without-a-client) guide goes deeper into building and sending transactions step by step.\n\n## Handle transaction errors\n\nWhen a transaction fails, `client.sendTransaction(...)` throws a [`SolanaError`](/docs/advanced-guides/errors) with the `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION` code. The error message identifies whether the failure happened in preflight or onchain, and the `cause` carries the underlying error you can branch on.\n\n```ts twoslash\nimport {\n    address,\n    isSolanaError,\n    lamports,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION,\n} from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)));\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n// ---cut-end---\ntry {\n    await client.sendTransaction([\n        getTransferSolInstruction({\n            source: client.payer,\n            destination: recipient,\n            amount: lamports(500_000n),\n        }),\n    ]);\n} catch (error) {\n    if (isSolanaError(error, SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION)) {\n        console.error(error.message);\n        console.error('Logs:', error.context.logs);\n    } else {\n        throw error;\n    }\n}\n```\n\nThe same `error.context` object also exposes the underlying `transactionPlanResult`, which is particularly useful when you want to inspect the failed transaction message or its signature. Program-specific errors (such as System program or SPL Token program errors) live deeper inside `error.cause`. The [Errors](/docs/advanced-guides/errors) guide covers how to identify and handle them.\n\n## Inspect transaction signatures\n\nA successful `client.sendTransaction(...)` resolves with a result object whose `context` carries the transaction `signature` and the original transaction message. You can use the signature to log a link to a block explorer or store it for later reference.\n\n```ts twoslash\nimport { address, lamports } from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)));\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n// ---cut-end---\nconst result = await client.sendTransaction([\n    getTransferSolInstruction({\n        source: client.payer,\n        destination: recipient,\n        amount: lamports(500_000n),\n    }),\n]);\n\nconsole.log(`✅ ${result.context.signature}`);\n```\n\nTransaction signatures are deterministic, so the signature is known as soon as the fee payer signs the transaction — you do not need to wait for confirmation to learn what it will be. If you build and sign your own transactions, the [`getSignatureFromTransaction`](/docs/advanced-guides/transactions) helper exposes the same value.\n\n## Next steps\n\n- [Sending multiple transactions](/docs/guides/sending-multiple-transactions) — plan and execute work that does not fit in a single transaction.\n- [Using program plugins](/docs/guides/using-program-plugins) — discover the `.sendTransaction()` shortcut on typed program helpers.\n- [Advanced guides — Transactions](/docs/advanced-guides/transactions) — learn the full transaction lifecycle.\n- [Advanced guides — Errors](/docs/advanced-guides/errors) — handle failures with `SolanaError`.\n"
  },
  {
    "path": "docs/content/docs/guides/setting-up-signers.mdx",
    "content": "---\ntitle: Setting up signers\ndescription: Authorize transactions, pay fees, and own onchain assets\n---\n\nMost Kit applications need at least one signer. Signers represent the accounts that authorize transactions, pay fees, and own onchain assets such as tokens or program authorities. This guide covers the different ways you can attach signers to a Kit client and the situations each one is best suited for.\n\n## Installation\n\nYou will need Kit and the signer plugin package.\n\n```package-install\n@solana/kit @solana/kit-plugin-signer\n```\n\nSome examples below also use `@solana/kit-plugin-rpc` or `@solana/kit-plugin-litesvm` to fund signers in local environments.\n\n## What is a signer?\n\nA signer is an object that carries an `Address` and knows how to produce a signature for that address. Where the underlying private key actually lives — in memory, in a keypair file, in a browser wallet, on a hardware device, or behind a remote signing service — is an implementation detail. As long as the signer implements one of Kit's signer interfaces, it can be plugged into the same APIs.\n\nThis means you can swap a generated keypair for a wallet-backed signer without changing the rest of your code. The [Advanced guides — Signers](/docs/advanced-guides/signers) page goes into the different signer interfaces and when each one applies.\n\n## Payer and identity\n\nKit clients hold two distinct signer roles:\n\n- **`payer`** — the signer that pays transaction fees and storage costs (the rent reserved when creating new accounts).\n- **`identity`** — the signer that represents the wallet your application acts on behalf of, typically the authority over accounts, tokens, or other onchain assets.\n\nIn most apps these roles are filled by the same signer, but they can be separated when you want a sponsored fee payer, a custodial backend, or any setup where authority and fee payment do not belong to the same key.\n\n## Install signers on your client\n\nThe most common way to install a signer is to use the `signer(...)` plugin, which sets the same signer as both the `payer` and the `identity` of the client.\n\n```ts twoslash\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { signer } from '@solana/kit-plugin-signer';\n\nconst mySigner = await generateKeyPairSigner();\nconst client = createClient().use(signer(mySigner));\n```\n\nThe `signer(...)` plugin accepts any object that implements the `TransactionSigner` interface, so a signer obtained from somewhere else in your code — a library, a hook, a custom factory — can be passed in directly without any wrapping.\n\nIf your application needs a sponsored fee payer or otherwise wants to set the two roles independently, you may use the `payer(...)` and `identity(...)` plugins instead. They have the exact same shape as `signer(...)` but install only one role each.\n\n```ts twoslash\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { identity, payer } from '@solana/kit-plugin-signer';\n\nconst feePayer = await generateKeyPairSigner();\nconst owner = await generateKeyPairSigner();\n\nconst client = createClient().use(payer(feePayer)).use(identity(owner));\n```\n\n## Load a signer from a file\n\nMost Solana CLI keypairs are stored as a JSON byte array on disk. The `signerFromFile(...)` plugin reads such a file and installs the resulting signer on both the `payer` and `identity` roles.\n\n```ts twoslash\nimport { createClient } from '@solana/kit';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\n\nconst client = await createClient().use(signerFromFile('~/.config/solana/id.json'));\n```\n\nThis is convenient for command-line tools, scripts, and backend services that already use a Solana CLI keypair. As with the in-memory plugins above, `payerFromFile(path)` and `identityFromFile(path)` are available if you only want to install a single role.\n\n<Callout title=\"Node.js only\" type=\"warn\">\n    The file-based signer plugins read from the local filesystem and therefore only work in Node.js\n    environments. They throw an error in browsers and React Native. Make sure your keypair files are\n    excluded from version control and from any production build artifact.\n</Callout>\n\n## Use a browser wallet signer\n\nA dedicated wallet signer plugin is on its way and will be documented here once it lands. It will use the [Wallet Standard](https://github.com/wallet-standard/wallet-standard) under the hood and expose a framework-agnostic reactive layer, so it can be used from any UI framework — not just React.\n\nUntil then, the [`@solana/react`](/api) hooks can produce a `TransactionSigner` from a connected wallet account, and you can install that signer on a Kit client with the `signer(...)`, `payer(...)`, or `identity(...)` plugins shown above.\n\n## Generate signers for tests\n\nWhen writing tests, generating a fresh signer per run keeps each scenario isolated and avoids leaking state between tests. The `generatedSigner()` plugin creates a brand new keypair signer and installs it on both roles.\n\n```ts twoslash\nimport { createClient } from '@solana/kit';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient().use(generatedSigner());\n```\n\n`generatedPayer()` and `generatedIdentity()` follow the same pattern when you only want to generate one of the two roles. Generated signers are great for tests but should not be used as long-lived production identities, since the keypair only exists for the lifetime of the client.\n\n## Fund signers in local environments\n\nGenerated signers start with no SOL, so they can not pay fees or rent until they have been funded. The typical local pattern is to install a generated signer first, then install a local environment that ships an `airdrop` capability — either `solanaLocalRpc()` or `litesvm()` — and finally airdrop SOL to the signer with the `airdropSigner(...)` plugin.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)));\n```\n\nThe order matters: the signer must exist before the RPC bundle is added (so the bundle can wire the signer into transaction planning), and the airdrop function must be available before `airdropSigner(...)` runs (which `solanaLocalRpc()` and `litesvm()` both provide). `airdropPayer(...)` and `airdropIdentity(...)` are available if you split roles between two different signers.\n\n<Callout type=\"warn\">\n    Airdrops only work on test clusters such as devnet, testnet, and local validators. Mainnet does\n    not have a faucet, and `solanaMainnetRpc(...)` will refuse to type-check an `airdrop` call.\n</Callout>\n\n## Next steps\n\n- [Sending transactions](/docs/guides/sending-transactions) — use your client to send and confirm transactions.\n- [Testing and local development](/docs/guides/testing-and-local-development) — set up local validators or LiteSVM for testing.\n- [Advanced guides — Signers](/docs/advanced-guides/signers) — learn the signer interfaces in depth.\n"
  },
  {
    "path": "docs/content/docs/guides/testing-and-local-development.mdx",
    "content": "---\ntitle: Testing & local development\ndescription: Test your Solana applications locally\n---\n\nLocal development and testing benefit hugely from Kit's plugin system: the same application code can run against devnet, a local validator, or an in-process [LiteSVM](https://github.com/litesvm/litesvm) instance, depending on which bundle plugin you install. This guide walks through the three options and the small patterns that make tests easy to write and maintain.\n\n## Choose a local environment\n\nEach environment shines in a different situation. The table below summarizes when to reach for each.\n\n| Environment     | Best for                                             | Tradeoffs                                                 |\n| --------------- | ---------------------------------------------------- | --------------------------------------------------------- |\n| Devnet          | shared/manual testing                                | faucet limits, network latency, shared state across tests |\n| Local validator | integration testing, full RPC API                    | requires a separate process, shared state across tests    |\n| LiteSVM         | fast unit tests, manipulating account state per test | Node.js only, RPC subset, in-memory only state            |\n\nYou do not have to commit to one environment for the whole project. It is common to use LiteSVM for fast unit tests, a local validator for integration tests, and devnet for manual exploration.\n\n## Use devnet for shared testing\n\nDevnet is the easiest way to share a Solana environment with your team. The `solanaDevnetRpc()` plugin defaults to the public devnet endpoint and bundles an `airdrop` capability for funding accounts.\n\n```ts twoslash\nimport { address, createClient, lamports } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\n\nconst client = await createClient()\n    .use(signerFromFile('~/.config/solana/id.json'))\n    .use(solanaDevnetRpc());\n\nawait client.airdrop(client.payer.address, lamports(1_000_000_000n));\n```\n\nDevnet is great for one-off scripts and manual exploration, but the public faucet has tight rate limits. For automated tests, prefer one of the local options.\n\n## Use a local validator\n\nA local validator runs the same software as mainnet but on your own machine. You can install the `solana-test-validator` binary by following the [Anza installation guide](https://docs.anza.xyz/cli/install) and start it with a single command.\n\n```shell\nsolana-test-validator\n```\n\nOnce the validator is running, the `solanaLocalRpc()` plugin connects to its default endpoints (`http://127.0.0.1:8899` and `ws://127.0.0.1:8900`) and ships the same `airdrop` capability as devnet — without any rate limits.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)));\n```\n\nUse this setup for integration tests that need the full Solana RPC API or to load deployed programs the way a real validator would. Make sure the validator is running before your tests start; otherwise, the first RPC call will fail with a connection error.\n\n## Use LiteSVM for fast tests\n\nLiteSVM runs the Solana virtual machine in-process, with no validator and no network. It is significantly faster than a local validator and is ideal for unit tests. The `litesvm()` plugin from `@solana/kit-plugin-litesvm` installs a LiteSVM-backed client that exposes the same `client.rpc`, `client.airdrop`, `client.sendTransaction`, and `client.sendTransactions` APIs as the RPC bundles.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { litesvm } from '@solana/kit-plugin-litesvm';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(litesvm())\n    .use(airdropSigner(lamports(1_000_000_000n)));\n```\n\nEach LiteSVM-backed client owns its own in-memory SVM instance, so every test can have a completely isolated state. This is particularly useful for unit tests where one test should never affect the state observed by another.\n\n<Callout title=\"Node.js only\" type=\"warn\">\n    LiteSVM runs natively in Node.js. It will throw if you try to use it in a browser or in React\n    Native. The exposed RPC also covers a subset of the full API — enough for most tests, but worth\n    double-checking against the [`@solana/kit-plugin-litesvm`\n    README](https://github.com/anza-xyz/kit-plugins/tree/main/packages/kit-plugin-litesvm#readme)\n    for the methods you rely on.\n</Callout>\n\n## Create a funded test client\n\nFor most tests you want a fresh, funded signer for every run. The pattern is the same regardless of the chosen environment: install a generated signer, install the environment, and airdrop SOL.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { litesvm } from '@solana/kit-plugin-litesvm';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(litesvm())\n    .use(airdropSigner(lamports(10_000_000_000n)));\n```\n\nSwapping `litesvm()` for `solanaLocalRpc()` is a one-line change and the rest of your test code stays the same. This is one of the main benefits of the plugin model: the surface your tests interact with is a `client`, not a particular environment.\n\n## Reuse setup across tests\n\nWrap the client creation in a small factory so every test starts from a clean state. Adding any program plugins or extra setup to the factory keeps tests focused on what they are actually testing.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { litesvm } from '@solana/kit-plugin-litesvm';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nimport { tokenProgram } from '@solana-program/token';\n\nasync function createTestClient() {\n    return await createClient()\n        .use(generatedSigner())\n        .use(litesvm())\n        .use(airdropSigner(lamports(10_000_000_000n)))\n        .use(systemProgram())\n        .use(tokenProgram());\n}\n```\n\nBecause Kit clients are immutable, you do not need to worry about leaking state between tests as long as you do not share a single client instance across them.\n\n## Seed accounts and programs\n\nLiteSVM exposes the underlying SVM through `client.svm`, which lets you preload accounts and programs before your test code runs. This is the quickest way to set up a specific scenario without chaining a series of transactions.\n\n```ts twoslash\nimport { address, EncodedAccount, lamports } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { litesvm } from '@solana/kit-plugin-litesvm';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nconst client = await createClient().use(generatedSigner()).use(litesvm());\n// ---cut-end---\nconst myAccount: EncodedAccount = {\n    address: address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ'),\n    data: new Uint8Array([1, 2, 3]),\n    executable: false,\n    lamports: lamports(1_000_000_000n),\n    programAddress: address('11111111111111111111111111111111'),\n    space: 3n,\n};\nclient.svm.setAccount(myAccount);\n\nclient.svm.addProgramFromFile(\n    address('MyProgram111111111111111111111111111111111'),\n    './my_program.so',\n);\n```\n\nA local validator supports similar workflows through its CLI flags (`--account`, `--bpf-program`, etc.), which you can pass when starting `solana-test-validator`. See [`@solana/kit-plugin-litesvm`](/docs/plugins/available-plugins) and the [Anza CLI documentation](https://docs.anza.xyz/cli/) for the exact APIs.\n\n## Troubleshooting\n\nA few issues come up often when wiring up local environments:\n\n- **Faucet rate limits on devnet** — switch to `solanaLocalRpc()` or `litesvm()` for repeated runs, or top up your devnet signer manually from the [Solana Faucet](https://faucet.solana.com).\n- **Validator not running** — `solana-test-validator` must be running before tests start; check the process and the default port (`8899`).\n- **WebSocket endpoint mismatch** — when overriding `rpcUrl`, also set `rpcSubscriptionsUrl` if your provider uses a different URL for WebSocket traffic.\n- **`litesvm()` errors in browser tests** — LiteSVM is Node.js only; run those tests in a Node.js environment or pick a different bundle.\n\n## Next steps\n\n- [Sending transactions](/docs/guides/sending-transactions) — exercise your client end-to-end.\n- [Using program plugins](/docs/guides/using-program-plugins) — add typed program access to your tests.\n- [Available plugins](/docs/plugins/available-plugins) — explore the LiteSVM and RPC plugin packages.\n"
  },
  {
    "path": "docs/content/docs/guides/using-program-plugins.mdx",
    "content": "---\ntitle: Using program plugins\ndescription: Add typed program APIs to your client\n---\n\nProgram plugins are how Kit clients gain typed access to a specific Solana program. They install a typed namespace under the client — `client.system`, `client.token`, and so on — and expose the program's accounts and instructions through it. This guide walks through adding program plugins to a client and using them, alongside the standalone helpers that the same packages also expose.\n\n## Installation\n\nMost popular Solana programs ship a Codama-generated package that doubles as a Kit program plugin. Install one for each program you want to interact with.\n\n```package-install\n@solana-program/system @solana-program/token\n```\n\nThe [Available plugins](/docs/plugins/available-plugins) page lists the program plugins available today. Once installed, apply each plugin with `.use(...)` after your signer and bundle plugins, and the client gains a new typed namespace named after the program.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nimport { tokenProgram } from '@solana-program/token';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(10_000_000_000n)))\n    .use(systemProgram())\n    .use(tokenProgram());\n```\n\n`client.system` and `client.token` now expose `accounts` and `instructions` namespaces typed against the System and Token programs. Multiple program plugins compose freely — installing more of them simply adds more namespaces to the client.\n\n## What is a program plugin?\n\nA program plugin is a function from a Codama-generated package that adds a typed namespace for one program's accounts and instructions to a Kit client. The same package also exports standalone helpers — `getXInstruction`, `fetchX`, `decodeX`, and so on, where `X` is the instruction or account name — for cases where you do not want a client.\n\n```ts twoslash\nimport { systemProgram } from '@solana-program/system';\nimport { tokenProgram } from '@solana-program/token';\n```\n\nYou can think of a program plugin as a typed adapter on top of these standalone helpers. The plugin handles the wiring — passing the client's RPC and payer where needed — so your code can focus on what the program does. This is great for developer experience and program discoverability, but the tradeoff is tree-shakability: pulling an entire program namespace into your client tends to produce a larger bundle than importing only the standalone helpers you actually use.\n\n## Fetch typed accounts\n\nEach `accounts` namespace exposes one entry per account type defined by the program, with `fetch`, `fetchMaybe`, `fetchAll`, and `fetchAllMaybe` methods that already know the codec to use.\n\n```ts twoslash\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(10_000_000_000n)))\n    .use(tokenProgram());\n// ---cut-end---\nconst mint = await client.token.accounts.mint.fetch(\n    address('So11111111111111111111111111111111111111112'),\n);\nmint.data.decimals; // typed as `number`\n```\n\nBecause the account namespace is generated from the program's IDL, every field on `mint.data` is fully typed — autocompletion and refactors flow through naturally. See [Fetching accounts](/docs/guides/fetching-accounts) for raw account fetching that doesn't depend on a program plugin.\n\n## Create typed instructions\n\nThe matching `instructions` namespace exposes one builder per instruction the program defines. The builders accept a typed input and return an instruction ready to be sent.\n\n```ts twoslash\nimport { address, lamports } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(10_000_000_000n)))\n    .use(systemProgram());\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n// ---cut-end---\nconst transferSol = client.system.instructions.transferSol({\n    source: client.payer,\n    destination: recipient,\n    amount: lamports(500_000n),\n});\n```\n\n## Use the `.sendTransaction()` shortcut\n\nEach typed instruction returned by a program plugin also exposes a `.sendTransaction()` method that wraps `client.sendTransaction([instruction])`. This is the most concise way to send a one-off transaction.\n\n```ts twoslash\nimport { address, lamports } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(10_000_000_000n)))\n    .use(systemProgram());\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n// ---cut-end---\nconst result = await client.system.instructions\n    .transferSol({\n        source: client.payer,\n        destination: recipient,\n        amount: lamports(500_000n),\n    })\n    .sendTransaction();\n```\n\nThe same returned object also exposes `.sendTransactions()`, `.planTransaction()`, and `.planTransactions()` shortcuts that wrap the matching client methods. The shortcut shines for single-instruction operations where the rest of the transaction would just be ceremony. When you want to combine several instructions into one transaction or compose larger operations, [`client.sendTransaction([...])`](/docs/guides/sending-transactions) is the more flexible primitive.\n\n## Use instruction plans from program plugins\n\nSome operations naturally span more than one instruction — creating and initializing a token mint is a classic example. Program plugins expose these as instruction plans rather than raw instructions, which means they can also be combined into larger plans.\n\n```ts twoslash\nimport { generateKeyPairSigner } from '@solana/kit';\n// ---cut-start---\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(10_000_000_000n)))\n    .use(tokenProgram());\n// ---cut-end---\nconst newMint = await generateKeyPairSigner();\nconst createMintPlan = client.token.instructions.createMint({\n    newMint,\n    decimals: 9,\n    mintAuthority: client.identity.address,\n});\n```\n\nThe returned plan can be sent on its own with `.sendTransaction()` or `.sendTransactions()`, fed into [`client.sendTransaction([...])`](/docs/guides/sending-transactions) alongside other work, or combined with [`sequentialInstructionPlan(...)`](/docs/guides/sending-multiple-transactions) and [`parallelInstructionPlan(...)`](/docs/guides/sending-multiple-transactions) helpers when building larger operations.\n\n## Use program libraries without a client\n\nEvery program package also exports standalone helpers that work on a plain `Rpc` object or with raw `Instruction`s. This is useful for libraries that should not assume a Kit client, or when you want maximum tree-shaking.\n\n```ts twoslash\nimport { address, createSolanaRpc, generateKeyPairSigner, lamports } from '@solana/kit';\nimport { fetchMint } from '@solana-program/token';\nimport { getTransferSolInstruction } from '@solana-program/system';\n\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\n\nconst mint = await fetchMint(rpc, address('So11111111111111111111111111111111111111112'));\n\nconst source = await generateKeyPairSigner();\nconst transferSol = getTransferSolInstruction({\n    source,\n    destination: address('Ay1zdJ3VDbhrAtkRiqBUJgKLHYbgFZN5BXk7svtMowif'),\n    amount: lamports(500_000n),\n});\n```\n\nBecause the standalone helpers and the plugin-based namespaces are generated from the same IDL, the input shapes match exactly. You can move from one style to the other without rewriting the data your application passes around.\n\n## Generate plugins for your own programs\n\nAny program with a Codama IDL can be turned into a Kit-compatible package, with both standalone helpers and a program plugin, using the [Codama JS renderer](https://github.com/codama-idl/renderers-js). The renderer reads the IDL, emits TypeScript bindings, and wires them up through the same `@solana/program-client-core` primitives the `@solana-program/*` packages use.\n\nIf your program is built with Anchor, you can convert its Anchor IDL to a Codama IDL first, which means program plugin generation works for Anchor programs as well. See [Generating program plugins](/docs/plugins/generating-program-plugins) for a step-by-step walkthrough.\n\n## Next steps\n\n- [Available plugins](/docs/plugins/available-plugins) — browse the program plugins available today.\n- [Generating program plugins](/docs/plugins/generating-program-plugins) — generate a plugin for your own program.\n- [Fetching accounts](/docs/guides/fetching-accounts) — combine typed accounts with raw RPC reads.\n- [Sending transactions](/docs/guides/sending-transactions) — use typed instructions with `client.sendTransaction([...])`.\n"
  },
  {
    "path": "docs/content/docs/index.mdx",
    "content": "---\ntitle: Installation\ndescription: Get started with Kit\n---\n\nKit is a JavaScript SDK for building Solana apps across environments like Node, the web, and React Native. It provides a comprehensive set of data types and helper functions, forming the foundation for interacting with Solana in JavaScript.\n\n<Callout title=\"Coming from Web3.js?\">\n    Check out our [Upgrade guide](/docs/upgrade-guide) to see how Kit compares to Web3.js.\n</Callout>\n\n## Quick start\n\nChoose the client setup that fits your environment:\n\n<CardTabs groupId=\"client-type\" persist cards={[\n    { title: \"RPC Client\", description: \"For production apps on mainnet, devnet, or testnet.\", icon: \"globe\" },\n    { title: \"Local RPC Client\", description: \"For local development with a test validator.\", icon: \"laptop\" },\n    { title: \"LiteSVM Client\", description: \"For fast unit testing. Node.js only.\", icon: \"flask-conical\" },\n    { title: \"No Client\", description: \"Maximum treeshakability. Import only what you need.\", icon: \"puzzle\" },\n]}>\n<CardTab>\n\n<Steps>\n<Step>\n\n### Install packages\n\nInstall Kit and the plugins for RPC connectivity and signer management.\n\n```package-install\n@solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer\n```\n\n</Step>\n<Step>\n\n### Install program plugins\n\nInstall plugins for any Solana program you want to interact with. You can find a full list on the [Available Plugins](/docs/plugins/available-plugins) page.\n\n```package-install\n@solana-program/system @solana-program/token\n```\n\n</Step>\n<Step>\n\n### Create your client\n\n```ts twoslash\nimport { createClient } from '@solana/kit';\nimport { solanaMainnetRpc } from '@solana/kit-plugin-rpc';\nimport { signerFromFile } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nimport { tokenProgram } from '@solana-program/token';\n\nconst client = await createClient()\n    .use(signerFromFile('~/.config/solana/id.json'))\n    .use(solanaMainnetRpc({ rpcUrl: 'https://api.mainnet-beta.solana.com' }))\n    .use(systemProgram())\n    .use(tokenProgram());\n\n// Here are some of the things you can do with your client:\n// client.rpc.getBalance(address).send();\n// client.system.instructions.transferSol({...}).sendTransaction();\n// client.token.accounts.mint.fetch(address);\n// client.sendTransaction(instructions);\n// And more...\n```\n\nThis example loads the default Solana CLI keypair. See [Setting Up Signers](/docs/guides/setting-up-signers) for other production signer options such as using a wallet.\n\n</Step>\n</Steps>\n\n</CardTab>\n<CardTab>\n\n<Steps>\n<Step>\n\n### Install packages\n\nInstall Kit and the plugins for local RPC connectivity and signer management.\n\n```package-install\n@solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer\n```\n\n</Step>\n<Step>\n\n### Install program plugins\n\nInstall plugins for any Solana program you want to interact with. You can find a full list on the [Available Plugins](/docs/plugins/available-plugins) page.\n\n```package-install\n@solana-program/system @solana-program/token\n```\n\n</Step>\n<Step>\n\n### Start a test validator\n\nMake sure you have a local Solana validator running before using your client.\n\n```shell\nsolana-test-validator\n```\n\n</Step>\n<Step>\n\n### Create your client\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nimport { tokenProgram } from '@solana-program/token';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(100_000_000_000n)))\n    .use(systemProgram())\n    .use(tokenProgram());\n\n// Signer is auto-generated and funded with SOL.\n// Here are some of the things you can do with your client:\n// client.rpc.getBalance(address).send();\n// client.system.instructions.transferSol({...}).sendTransaction();\n// client.token.accounts.mint.fetch(address);\n// client.sendTransaction(instructions);\n// And more...\n```\n\n</Step>\n</Steps>\n\n</CardTab>\n<CardTab>\n\n<Steps>\n<Step>\n\n### Install packages\n\nInstall Kit and the plugins for LiteSVM and signer management.\n\n```package-install\n@solana/kit @solana/kit-plugin-litesvm @solana/kit-plugin-signer\n```\n\n</Step>\n<Step>\n\n### Install program plugins\n\nInstall plugins for any Solana program you want to interact with. You can find a full list on the [Available Plugins](/docs/plugins/available-plugins) page.\n\n```package-install\n@solana-program/system @solana-program/token\n```\n\n</Step>\n<Step>\n\n### Create your client\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { litesvm } from '@solana/kit-plugin-litesvm';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nimport { tokenProgram } from '@solana-program/token';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(litesvm())\n    .use(airdropSigner(lamports(100_000_000_000n)))\n    .use(systemProgram())\n    .use(tokenProgram());\n\n// Here are some of the things you can do with your client:\n// client.rpc.getBalance(address).send();\n// client.system.instructions.transferSol({...}).sendTransaction();\n// client.token.accounts.mint.fetch(address);\n// client.sendTransaction(instructions);\n// And more...\n```\n\n</Step>\n</Steps>\n\n</CardTab>\n<CardTab>\n\n<Steps>\n<Step>\n\n### Install Kit\n\n```package-install\n@solana/kit\n```\n\n</Step>\n<Step>\n\n### Install program libraries\n\nInstall Kit-compatible libraries for any program you want to interact with. For example, to interact with the System program, install the `@solana-program/system` package. You can find a [list of available program plugins here](/docs/plugins/available-plugins).\n\n```package-install\n@solana-program/system @solana-program/token\n```\n\n</Step>\n<Step>\n\n### Set up your project\n\n```ts twoslash\nimport { address, createSolanaRpc } from '@solana/kit';\n\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\nconst { value: balance } = await rpc\n    .getBalance(address('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'))\n    .send();\nconsole.log(`Balance: ${balance} lamports`);\n```\n\nSee [Kit Without a Client](/docs/advanced-guides/kit-without-a-client) for the full guide on sending transactions, signing, and more without a client.\n\n</Step>\n</Steps>\n\n</CardTab>\n</CardTabs>\n\nReady to build? Check out the [Getting Started](/docs/getting-started) tutorial to build your first app, or explore the [Guides](/docs/guides) for specific topics.\n"
  },
  {
    "path": "docs/content/docs/meta.json",
    "content": "{\n    \"title\": \"Documentation\",\n    \"defaultOpen\": true,\n    \"root\": true,\n    \"pages\": [\n        \"index\",\n        \"getting-started\",\n        \"upgrade-guide\",\n        \"...\",\n        \"guides\",\n        \"plugins\",\n        \"advanced-guides\"\n    ]\n}\n"
  },
  {
    "path": "docs/content/docs/plugins/available-plugins.mdx",
    "content": "---\ntitle: Available plugins\ndescription: Directory of plugins for Kit clients\n---\n\nThis page lists the Kit plugins published today. Anyone can author and publish a plugin; if you have one you'd like added here, open a PR against [`anza-xyz/kit`](https://github.com/anza-xyz/kit) to be listed alongside the others.\n\nThe tables below group plugins by category. Within each category, generic plugins from Anza are listed first because they target the broadest range of use cases, followed by community plugins in alphabetical order. When a single package contains plugins with materially different purposes, those plugins are split across multiple rows so each description stays targeted.\n\n## Signer plugins\n\nSigner plugins install a `TransactionSigner` on the client as the `payer`, the `identity`, or both. See [Setting up signers](/docs/guides/setting-up-signers) for an overview of when each variant fits.\n\n| Maintainer                    | Package                                                                                | Plugins                                                                       | Description                                                      |\n| ----------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------- |\n| [Anza](https://www.anza.xyz/) | [`@solana/kit-plugin-signer`](https://www.npmjs.com/package/@solana/kit-plugin-signer) | `signer`, `payer`, `identity`                                                 | Install an existing `TransactionSigner` on the client.           |\n| [Anza](https://www.anza.xyz/) | [`@solana/kit-plugin-signer`](https://www.npmjs.com/package/@solana/kit-plugin-signer) | `signerFromFile`, `payerFromFile`, `identityFromFile`                         | Load a Solana CLI keypair from a JSON file (Node.js only).       |\n| [Anza](https://www.anza.xyz/) | [`@solana/kit-plugin-signer`](https://www.npmjs.com/package/@solana/kit-plugin-signer) | `generatedSigner`, `generatedPayer`, `generatedIdentity`                      | Generate a fresh in-memory keypair, useful for tests.            |\n| [Anza](https://www.anza.xyz/) | [`@solana/kit-plugin-signer`](https://www.npmjs.com/package/@solana/kit-plugin-signer) | `generatedSignerWithSol`, `generatedPayerWithSol`, `generatedIdentityWithSol` | Generate a signer and airdrop SOL to it in one step.             |\n| [Anza](https://www.anza.xyz/) | [`@solana/kit-plugin-signer`](https://www.npmjs.com/package/@solana/kit-plugin-signer) | `airdropSigner`, `airdropPayer`, `airdropIdentity`                            | Airdrop SOL to a signer that is already installed on the client. |\n\n## RPC plugins\n\nRPC plugins install Solana RPC connectivity on the client. LiteSVM is included here because it implements a subset of the same RPC API in-process, with no network involved.\n\n| Maintainer                         | Package                                                                                                   | Plugins                                                              | Description                                                                            |\n| ---------------------------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-rpc`](https://www.npmjs.com/package/@solana/kit-plugin-rpc)                          | `solanaRpc`, `solanaMainnetRpc`, `solanaDevnetRpc`, `solanaLocalRpc` | Bundle plugins that wire up RPC, subscriptions, planning, and sending in one step.     |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-rpc`](https://www.npmjs.com/package/@solana/kit-plugin-rpc)                          | `solanaRpcConnection`                                                | Install `client.rpc` and `client.rpcSubscriptions` from a cluster URL.                 |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-rpc`](https://www.npmjs.com/package/@solana/kit-plugin-rpc)                          | `rpcAirdrop`                                                         | Add `client.airdrop` for devnet, testnet, and local validators.                        |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-rpc`](https://www.npmjs.com/package/@solana/kit-plugin-rpc)                          | `rpcGetMinimumBalance`                                               | Add `client.getMinimumBalance` using the matching RPC method.                          |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-litesvm`](https://www.npmjs.com/package/@solana/kit-plugin-litesvm)                  | `litesvm`                                                            | Bundle plugin that runs an in-process Solana VM with full transaction sending support. |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-litesvm`](https://www.npmjs.com/package/@solana/kit-plugin-litesvm)                  | `litesvmConnection`                                                  | Install `client.svm` and a subset of `client.rpc` backed by an in-process VM.          |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-litesvm`](https://www.npmjs.com/package/@solana/kit-plugin-litesvm)                  | `litesvmAirdrop`                                                     | Add `client.airdrop` against the in-process VM.                                        |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-litesvm`](https://www.npmjs.com/package/@solana/kit-plugin-litesvm)                  | `litesvmGetMinimumBalance`                                           | Add `client.getMinimumBalance` against the in-process VM.                              |\n| [@amilz](https://github.com/amilz) | [`local-validator`](https://github.com/amilz/kit-helpers/tree/main/plugins/local-validator) (unpublished) | `localValidatorPlugin`                                               | Manage the lifecycle of a local `solana-test-validator` (start, stop, restart).        |\n\n## Instruction plan plugins\n\nInstruction plan plugins install transaction planning and sending capabilities on the client. The RPC and LiteSVM packages are listed here too because they ship default planner and executor implementations on top of their respective backends — including the bundle plugins, which install everything needed to call `client.planTransaction(s)` and `client.sendTransaction(s)` in one step.\n\n| Maintainer                         | Package                                                                                                           | Plugins                                                              | Description                                                                                                 |\n| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-instruction-plan`](https://www.npmjs.com/package/@solana/kit-plugin-instruction-plan)        | `transactionPlanner`                                                 | Install a custom transaction planner on the client.                                                         |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-instruction-plan`](https://www.npmjs.com/package/@solana/kit-plugin-instruction-plan)        | `transactionPlanExecutor`                                            | Install a custom transaction plan executor on the client.                                                   |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-instruction-plan`](https://www.npmjs.com/package/@solana/kit-plugin-instruction-plan)        | `planAndSendTransactions`                                            | Add `client.planTransaction(s)` and `client.sendTransaction(s)` on top of an existing planner and executor. |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-rpc`](https://www.npmjs.com/package/@solana/kit-plugin-rpc)                                  | `solanaRpc`, `solanaMainnetRpc`, `solanaDevnetRpc`, `solanaLocalRpc` | Bundle plugins that wire up RPC, subscriptions, planning, and sending in one step.                          |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-rpc`](https://www.npmjs.com/package/@solana/kit-plugin-rpc)                                  | `rpcTransactionPlanner`, `rpcTransactionPlanExecutor`                | Default transaction planner and executor backed by RPC.                                                     |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-litesvm`](https://www.npmjs.com/package/@solana/kit-plugin-litesvm)                          | `litesvm`                                                            | Bundle plugin that runs an in-process Solana VM with full transaction sending support.                      |\n| [Anza](https://www.anza.xyz/)      | [`@solana/kit-plugin-litesvm`](https://www.npmjs.com/package/@solana/kit-plugin-litesvm)                          | `litesvmTransactionPlanner`, `litesvmTransactionPlanExecutor`        | Default transaction planner and executor backed by LiteSVM.                                                 |\n| [@amilz](https://github.com/amilz) | [`transaction-builder`](https://github.com/amilz/kit-helpers/tree/main/plugins/transaction-builder) (unpublished) | `transactionBuilderPlugin`                                           | Helpers for constructing, signing, and sending transactions.                                                |\n\n## Program plugins\n\nProgram plugins are generated from program IDLs and install a typed `client.<program>` namespace with `accounts` and `instructions` helpers. See [Using program plugins](/docs/guides/using-program-plugins) for usage and [Generating program plugins](/docs/plugins/generating-program-plugins) for authoring new ones.\n\n| Maintainer                         | Package                                                                                                      | Plugins                           | Description                                                                   |\n| ---------------------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------- | ----------------------------------------------------------------------------- |\n| [Anza](https://www.anza.xyz/)      | [`@solana-program/address-lookup-table`](https://www.npmjs.com/package/@solana-program/address-lookup-table) | _Plugin coming soon_              | Address Lookup Table program.                                                 |\n| [Anza](https://www.anza.xyz/)      | [`@solana-program/compute-budget`](https://www.npmjs.com/package/@solana-program/compute-budget)             | _Plugin coming soon_              | Compute Budget program: priority fees and compute unit limits.                |\n| [Anza](https://www.anza.xyz/)      | [`@solana-program/memo`](https://www.npmjs.com/package/@solana-program/memo)                                 | _Plugin coming soon_              | Memo program.                                                                 |\n| [Anza](https://www.anza.xyz/)      | [`@solana-program/stake`](https://www.npmjs.com/package/@solana-program/stake)                               | _Plugin coming soon_              | Stake program.                                                                |\n| [Anza](https://www.anza.xyz/)      | [`@solana-program/system`](https://www.npmjs.com/package/@solana-program/system)                             | `systemProgram`                   | Native System program: account creation, transfers, nonce accounts, and more. |\n| [Anza](https://www.anza.xyz/)      | [`@solana-program/token`](https://www.npmjs.com/package/@solana-program/token)                               | `tokenProgram`                    | SPL Token program: mints, token accounts, and ATAs.                           |\n| [Anza](https://www.anza.xyz/)      | [`@solana-program/token-2022`](https://www.npmjs.com/package/@solana-program/token-2022)                     | _Plugin coming soon_              | SPL Token Extension program (Token-2022).                                     |\n| [@amilz](https://github.com/amilz) | [`airdrop-token`](https://github.com/amilz/kit-helpers/tree/main/plugins/airdrop-token) (unpublished)        | `airdropToken`, `testTokenPlugin` | Helpers for creating mints, ATAs, and minting tokens for tests.               |\n\n## Other plugins\n\nPlugins that don't fit into the categories above land here. Nothing has been listed yet — open a PR against [`anza-xyz/kit`](https://github.com/anza-xyz/kit) to add yours.\n\n## Next steps\n\n- [Creating custom plugins](/docs/plugins/creating-custom-plugins) — write your own plugin and publish it.\n- [Generating program plugins](/docs/plugins/generating-program-plugins) — generate a typed plugin for a Solana program.\n- [Using program plugins](/docs/guides/using-program-plugins) — consume program plugins from a Kit client.\n"
  },
  {
    "path": "docs/content/docs/plugins/creating-custom-plugins.mdx",
    "content": "---\ntitle: Creating custom plugins\ndescription: Write your own plugins to extend Kit clients\n---\n\nPlugins are small, focused functions that extend a Kit client with new capabilities. This page walks through writing a plugin from scratch, declaring its prerequisites, handling asynchronous setup, registering cleanup logic, and composing several plugins into a higher-level bundle.\n\n## The `ClientPlugin` shape\n\nA plugin is a function that takes a client and returns a new client object. The recommended way to add properties is the `extendClient(client, additions)` helper from `@solana/kit`, which preserves property descriptors (getters, symbol-keyed properties) that a plain object spread would flatten.\n\n```ts twoslash\nimport { createClient, extendClient } from '@solana/kit';\n\nfunction apple() {\n    return <T extends object>(client: T) => extendClient(client, { fruit: 'apple' as const });\n}\n\nconst client = createClient().use(apple());\nclient.fruit; // 'apple'\n```\n\nWrapping the plugin in a small factory function (`apple()` rather than `apple`) is the convention across Kit plugins. It gives you somewhere to accept configuration without changing the shape of the function returned to `.use(...)`.\n\n## Add prerequisites with TypeScript generics\n\nPlugins can require capabilities from the input client by constraining the input type. If a consumer applies your plugin in the wrong order, TypeScript reports a compile-time error rather than letting it fail at runtime.\n\n```ts twoslash\n// @errors: 2345\nimport { createClient, extendClient } from '@solana/kit';\n\nfunction appleTart() {\n    return <T extends { fruit: 'apple' }>(client: T) =>\n        extendClient(client, { dessert: 'appleTart' as const });\n}\n\ncreateClient().use(appleTart()); // ❌ Missing `fruit: 'apple'`.\n```\n\nThe same mechanism is what makes the official plugins compose so cleanly: `airdropPayer()` requires `ClientWithPayer & ClientWithAirdrop`, `solanaRpc(...)` requires `ClientWithPayer`, and so on. Adopting the same pattern in your own plugins keeps users honest about the order of operations.\n\n## Use the standard interfaces\n\nWhenever possible, declare your prerequisites and additions using the standard interfaces from `@solana/plugin-interfaces` (re-exported from `@solana/kit`). This lets your plugin compose with any other plugin that targets the same shape, regardless of its package.\n\nThe most common interfaces are:\n\n- `ClientWithPayer` and `ClientWithIdentity` for signer roles.\n- `ClientWithRpc<TApi>` and `ClientWithRpcSubscriptions<TApi>` for transports.\n- `ClientWithAirdrop` and `ClientWithGetMinimumBalance` for funding helpers.\n- `ClientWithTransactionPlanning` and `ClientWithTransactionSending` for the transaction lifecycle.\n\nIf your plugin's capability does not match any existing interface, define your own type and export it. If you think the capability is generally useful and there is a gap in the standard interfaces, consider opening a PR against [`anza-xyz/kit`](https://github.com/anza-xyz/kit) so other plugins can adopt it too. Treating capabilities as named interfaces makes them addressable from other code without naming the specific plugin that installed them.\n\n## Asynchronous plugins\n\nPlugins can return a `Promise<Client>` instead of a `Client`. The `.use(...)` chain awaits async plugins automatically, so you only need a single `await` at the end of the chain.\n\n```ts twoslash\nimport {\n    createClient,\n    createKeyPairSignerFromBytes,\n    extendClient,\n    KeyPairSigner,\n} from '@solana/kit';\nimport { readFile } from 'node:fs/promises';\n\nfunction signerFromBytesFile(path: string) {\n    return async <T extends object>(client: T) => {\n        const bytes = JSON.parse(await readFile(path, 'utf-8')) as number[];\n        const signer: KeyPairSigner = await createKeyPairSignerFromBytes(new Uint8Array(bytes));\n        return extendClient(client, { payer: signer, identity: signer });\n    };\n}\n\nconst client = await createClient().use(signerFromBytesFile('./keypair.json'));\n```\n\nAsync and sync plugins can be mixed freely in the same chain. Once any async plugin is involved, the `.use(...)` chain returns an `AsyncClient` that you await once at the end.\n\n## Release resources on disposal\n\nPlugins that hold disposable resources — WebSocket connections, intervals, file handles — can register a cleanup function with `withCleanup(...)`. The returned client implements `Disposable`, so a `using` declaration runs the cleanup when the client goes out of scope.\n\n```ts twoslash\nimport { extendClient, withCleanup } from '@solana/kit';\n\nfunction liveFeed(url: string) {\n    return <T extends object>(client: T) => {\n        const socket = new WebSocket(url);\n        return withCleanup(extendClient(client, { socket }), () => socket.close());\n    };\n}\n```\n\n`withCleanup` chains existing dispose logic, so you can call it more than once across plugins without overriding earlier cleanup. Reach for it whenever your plugin owns a resource the user would otherwise have to remember to release manually.\n\n## Compose smaller plugins into a bundle\n\nA bundle plugin is just a regular plugin that applies several smaller plugins one after another. The `pipe(...)` helper from `@solana/kit` makes the composition concise and the resulting type predictable.\n\n```ts twoslash\n// @noErrors\nimport { ClientWithPayer, pipe } from '@solana/kit';\nimport {\n    rpcAirdrop,\n    rpcGetMinimumBalance,\n    solanaRpcConnection,\n    SolanaRpcConnectionConfig,\n} from '@solana/kit-plugin-rpc';\n\nfunction myDevnetBundle(config: SolanaRpcConnectionConfig) {\n    return <T extends ClientWithPayer>(client: T) =>\n        pipe(client, solanaRpcConnection(config), rpcGetMinimumBalance(), rpcAirdrop());\n}\n```\n\nThe bundle accepts an existing client rather than calling `createClient()` itself. That keeps your bundle composable: callers stay in control of their own client and can apply additional plugins before or after yours. It is also what lets the official `solanaRpc`, `solanaDevnetRpc`, `solanaLocalRpc`, and `litesvm` bundles drop into any client the same way a single plugin would.\n\n## Publish your plugin\n\nA few small conventions go a long way once a plugin lands on npm:\n\n- Name the factory function after the capability it installs (e.g. `signer`, `rpcAirdrop`, `tokenProgram`) rather than the package, and make sure it reads well at the call site — `use(tokenProgram())` should sound like the sentence you would write to describe what it does.\n- Document the standard interfaces your plugin requires and provides; this is what other plugin authors will read first.\n- Keep the public surface minimal — one factory function per concept — and prefer composition over bigger plugins that try to do everything.\n\nOnce your plugin is published, open a PR against [`anza-xyz/kit`](https://github.com/anza-xyz/kit) to be listed on the [Available plugins](/docs/plugins/available-plugins) page so other developers can find it.\n\n## Next steps\n\n- [Plugins](/docs/plugins) — revisit the client model and standard interfaces.\n- [Available plugins](/docs/plugins/available-plugins) — see how published plugins describe themselves.\n- [Generating program plugins](/docs/plugins/generating-program-plugins) — let Codama write a program plugin for you.\n"
  },
  {
    "path": "docs/content/docs/plugins/generating-program-plugins.mdx",
    "content": "---\ntitle: Generating program plugins\ndescription: Generate typed plugins for your Solana programs using Codama\n---\n\nProgram plugins are generated from program IDLs by [Codama](https://github.com/codama-idl/codama). Codama's CLI is the quickest path to a working plugin: two commands set up a configuration file in your repo and emit a Kit-compatible package containing both standalone helpers and a typed program plugin.\n\nThis page focuses on how the generated output fits into the Kit ecosystem. Codama itself has comprehensive docs that go much deeper into IDLs, visitors, and renderer configuration.\n\n## What Codama generates\n\nFor every program, the JavaScript renderer emits two things side by side: standalone helpers for use without a client, and a program plugin that installs a typed namespace on a Kit client.\n\n```ts\n// Standalone helpers, one per instruction and account defined in the IDL.\nimport { decodeMyAccount, fetchMyAccount, getMyInstruction } from '@your-scope/your-program';\n\n// Program plugin — installs `client.yourProgram.accounts` and `client.yourProgram.instructions`.\nimport { yourProgram } from '@your-scope/your-program';\n```\n\nBoth forms are generated automatically from your IDL. The standalone helpers tree-shake well and keeps JS bundles small, while the program plugin is the most ergonomic way to use the program from a Kit client.\n\n## Set up Codama with `codama init`\n\nInstall Codama as a dev dependency and run `codama init`. The CLI prompts you for the path to your IDL and writes a `codama.json` configuration file at the root of your project. Make sure to select the JS client option to generate a Kit-compatible program library.\n\n```sh\npnpm install codama\ncodama init\n```\n\nThe CLI auto-detects Anchor IDLs and configures the conversion step for you, so this same flow works for both native programs (with a Codama IDL) and Anchor programs (with an Anchor IDL).\n\n## Generate the plugin with `codama run js`\n\nOnce the configuration file exists, generating the JavaScript client is a single command. Codama installs the renderer the first time it runs and writes the generated files to the path declared in the configuration.\n\n```sh\ncodama run js\n```\n\nThe output includes the standalone helpers, the program plugin, and the supporting types. Importing it from a Kit client looks the same as any other program plugin:\n\n```ts twoslash\n// @noErrors\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\nimport { yourProgram } from '@your-scope/your-program';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaDevnetRpc())\n    .use(yourProgram());\n```\n\n## Configure the renderer\n\nThe `codama.json` file generated by `codama init` controls where the output lands and which visitors run before the renderer. You can edit it to rename accounts, add custom transformations, or change the output directory. See the [Codama JS renderer docs](https://github.com/codama-idl/renderers-js) for the full list of configuration options.\n\nIf you need more than one client (for example, both JavaScript and Rust), additional renderers can be added to the same configuration file and run with `codama run --all`.\n\n## Publish your generated plugin\n\nOnce your plugin is generating cleanly, publishing it follows the same pattern as the official `@solana-program/*` packages. A few conventions worth keeping in mind:\n\n- Use a `@<scope>/<program-name>` package layout, with a single entry point that re-exports both the standalone helpers and the `programName()` plugin.\n- Once published, open a PR against [`anza-xyz/kit`](https://github.com/anza-xyz/kit) to list your plugin on the [Available plugins](/docs/plugins/available-plugins) page so other developers can find it.\n\n## Next steps\n\n- [Using program plugins](/docs/guides/using-program-plugins) — consume program plugins from a Kit client.\n- [Available plugins](/docs/plugins/available-plugins) — browse program plugins published today.\n- [Creating custom plugins](/docs/plugins/creating-custom-plugins) — write a plugin that is not generated from an IDL.\n"
  },
  {
    "path": "docs/content/docs/plugins/index.mdx",
    "content": "---\ntitle: Plugins\ndescription: Understand Kit's plugin ecosystem\n---\n\nPlugins are how Kit clients gain capabilities. Everything from RPC connectivity, wallet signers, transaction sending, and even typed access to Solana programs is delivered as a plugin you opt into. This page explains the underlying client model and the conventions plugins follow.\n\n## What is a Kit client?\n\nA Kit client is a frozen, typed JavaScript object created with `createClient()` from `@solana/kit` and extended by chaining `.use(plugin())` calls. Each call applies a plugin, and the returned client is a brand new immutable object — the previous one is left untouched.\n\n```ts twoslash\nimport { createClient } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { generatedSigner } from '@solana/kit-plugin-signer';\n\nconst client = await createClient().use(generatedSigner()).use(solanaDevnetRpc());\n```\n\nBecause the client is immutable, you cannot accidentally mutate it from somewhere else in your application: `client` always reflects the exact set of plugins you applied at creation time.\n\n## What is a plugin?\n\nA plugin is a function that takes a client object and returns either a new client object or a promise resolving to one. The shape is captured by the `ClientPlugin<TInput, TOutput>` type.\n\n```ts twoslash\nimport { ClientPlugin, extendClient } from '@solana/kit';\n\nconst apple = (): ClientPlugin<object, { fruit: 'apple' }> => (client) =>\n    extendClient(client, { fruit: 'apple' as const });\n```\n\nMost plugins follow the same convention: they are exported as small factory functions (so you can pass configuration to them) that return the actual `ClientPlugin` function. Asynchronous plugins are supported too; the `.use(...)` chain awaits them automatically, so you only need a single `await` at the end.\n\n## Plugin requirements and ordering\n\nPlugins can require capabilities from the input client by constraining the input type. This means installing them in the wrong order produces a TypeScript error rather than a runtime surprise.\n\n```ts twoslash\n// @errors: 2345\nimport { ClientWithPayer, createClient, extendClient } from '@solana/kit';\n\nfunction airdropPayer() {\n    return <T extends ClientWithPayer>(client: T) => extendClient(client, { airdropped: true });\n}\n\n// Requires a `payer` to be installed first; this fails at compile time.\nconst client = createClient().use(airdropPayer());\n```\n\nAdding `payer(...)` (or any other plugin that satisfies `ClientWithPayer`) before `airdropPayer()` makes the chain type-check. The TypeScript compiler walks the whole chain and verifies that each plugin's input requirements are met by the time it is applied.\n\n## Standard plugin interfaces\n\nKit ships a small set of standard interfaces in `@solana/plugin-interfaces` (re-exported from `@solana/kit`) so plugins from different packages can interoperate. A plugin that installs `client.rpc` declares it provides `ClientWithRpc<...>`; a plugin that needs a payer constrains its input with `ClientWithPayer`. The most common interfaces are:\n\n- `ClientWithPayer` — installs `client.payer`.\n- `ClientWithIdentity` — installs `client.identity`.\n- `ClientWithRpc<TApi>` — installs `client.rpc`.\n- `ClientWithRpcSubscriptions<TApi>` — installs `client.rpcSubscriptions`.\n- `ClientWithAirdrop` — installs `client.airdrop`.\n- `ClientWithGetMinimumBalance` — installs `client.getMinimumBalance`.\n- `ClientWithTransactionPlanning` — installs `client.planTransaction(s)`.\n- `ClientWithTransactionSending` — installs `client.sendTransaction(s)`.\n\nSticking to these interfaces lets plugins from any source compose freely with each other — and lets your application code take a `ClientWithRpc` rather than caring which specific plugin produced the RPC capability.\n\n## Next steps\n\n- [Available plugins](/docs/plugins/available-plugins) — browse the plugins published today.\n- [Creating custom plugins](/docs/plugins/creating-custom-plugins) — write your own plugin.\n- [Generating program plugins](/docs/plugins/generating-program-plugins) — generate a typed plugin for a Solana program.\n"
  },
  {
    "path": "docs/content/docs/plugins/meta.json",
    "content": "{\n    \"title\": \"Plugins\",\n    \"defaultOpen\": true,\n    \"pages\": [\"available-plugins\", \"creating-custom-plugins\", \"generating-program-plugins\"]\n}\n"
  },
  {
    "path": "docs/content/docs/tree-shaking.tsx",
    "content": "import { ImageZoom } from 'fumadocs-ui/components/image-zoom';\n\nexport default function TreeShaking() {\n    return (\n        <figure>\n            <ImageZoom alt=\"Tree-shaking illustration; The left side shows a bunch of imports from Web3.js all being bundled despite only a couple being used. The right side shows an equivalent set of imports for Kit but only the used functions are bundled\">\n                <svg\n                    className=\"w-full h-auto cursor-zoom-in\"\n                    width=\"1203\"\n                    height=\"511\"\n                    viewBox=\"0 0 1203 511\"\n                    fill=\"none\"\n                    xmlns=\"http://www.w3.org/2000/svg\"\n                    role=\"img\"\n                    aria-label=\"Tree-shaking illustration. The left side shows a bunch of imports from Web3.js all being bundled despite only a couple being used. The right side shows an equivalent set of imports for Kit but only the used functions are bundled.\"\n                >\n                    <title>Tree-shaking illustration</title>\n                    <desc>\n                        The left side shows a bunch of imports from Web3.js all being bundled\n                        despite only a couple being used. The right side shows an equivalent set of\n                        imports for Kit but only the used functions are bundled.\n                    </desc>\n                    <line\n                        x1=\"759\"\n                        y1=\"151\"\n                        x2=\"858\"\n                        y2=\"151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M858 59L818 59C812.477 59 808 63.4772 808 69L808 141C808 146.523 803.523 151 798 151L758 151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M858 105L818 105C812.477 105 808 109.477 808 115L808 141C808 146.523 803.523 151 798 151L758 151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M858 243L818 243C812.477 243 808 238.523 808 233L808 161C808 155.477 803.523 151 798 151L758 151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M858 197L818 197C812.477 197 808 192.523 808 187L808 161C808 155.477 803.523 151 798 151L758 151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <line\n                        x1=\"759\"\n                        y1=\"381\"\n                        x2=\"858\"\n                        y2=\"381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M858 289L818 289C812.477 289 808 293.477 808 299L808 371C808 376.523 803.523 381 798 381L758 381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M858 335L818 335C812.477 335 808 339.477 808 345L808 371C808 376.523 803.523 381 798 381L758 381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M858 473L818 473C812.477 473 808 468.523 808 463L808 391C808 385.477 803.523 381 798 381L758 381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M858 427L818 427C812.477 427 808 422.523 808 417L808 391C808 385.477 803.523 381 798 381L758 381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <rect\n                        x=\"646\"\n                        y=\"138\"\n                        width=\"113\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-coral-400 dark:fill-coral-500\"\n                    />\n                    <path\n                        d=\"M659.99 146.144C663.49 146.144 664.274 148.86 664.274 151.954C664.274 155.482 663.882 157.288 662.16 157.288C661.026 157.288 660.536 156.14 660.494 155.314H660.438C660.158 155.986 659.584 156.658 658.506 156.658C656.924 156.658 656.336 155.286 656.336 153.452C656.336 151.072 657.33 149.784 659.178 149.784C659.85 149.784 660.508 149.924 661.292 150.344V154.502C661.292 155.832 661.628 156.182 662.118 156.182C662.86 156.182 662.874 154.6 662.874 152.01C662.874 149.238 662.398 147.306 659.962 147.306C659.01 147.306 657.974 147.586 656.826 148.594L656.07 147.712C657.33 146.606 658.646 146.144 659.99 146.144ZM659.192 150.848C658.114 150.848 657.792 151.646 657.792 153.452C657.792 154.782 658.016 155.58 658.744 155.58C659.584 155.58 659.822 154.852 659.948 154.446V151.03C659.696 150.904 659.472 150.848 659.192 150.848ZM668.329 154.992C669.309 154.992 669.925 154.614 669.925 153.998C669.925 153.396 669.687 153.116 668.161 152.724C666.691 152.346 665.725 151.828 665.725 150.54C665.725 149.266 666.859 148.412 668.679 148.412C669.925 148.412 670.821 148.776 671.493 149.266L670.821 150.26C670.247 149.882 669.589 149.602 668.721 149.602C667.713 149.602 667.321 149.924 667.321 150.414C667.321 150.974 667.727 151.184 669.197 151.59C670.639 151.982 671.591 152.486 671.591 153.886C671.591 155.496 670.023 156.182 668.329 156.182C666.957 156.182 665.977 155.734 665.291 155.146L666.117 154.194C666.691 154.656 667.461 154.992 668.329 154.992ZM677.003 148.412C679.159 148.412 680.335 149.938 680.335 152.29C680.335 154.642 679.131 156.182 676.989 156.182C674.833 156.182 673.643 154.698 673.643 152.304C673.643 149.994 674.847 148.412 677.003 148.412ZM677.003 149.63C675.869 149.63 675.295 150.47 675.295 152.304C675.295 154.138 675.855 154.978 676.989 154.978C678.123 154.978 678.683 154.138 678.683 152.29C678.683 150.47 678.123 149.63 677.003 149.63ZM685.678 145.64V153.984C685.678 154.67 686.14 154.922 686.798 154.922C687.218 154.922 687.596 154.824 687.974 154.67L688.366 155.762C687.932 156 687.288 156.182 686.462 156.182C684.978 156.182 684.11 155.3 684.11 153.844V146.788H681.884V145.64H685.678ZM696.48 154.194C696.48 154.768 696.648 154.992 697.04 155.118L696.676 156.182C695.962 156.098 695.416 155.804 695.15 155.16C694.604 155.846 693.736 156.182 692.798 156.182C691.286 156.182 690.362 155.258 690.362 153.886C690.362 152.346 691.622 151.464 693.876 151.464H694.926V150.988C694.926 150.022 694.324 149.644 693.288 149.644C692.798 149.644 692.07 149.756 691.328 150.022L690.936 148.916C691.86 148.566 692.77 148.412 693.526 148.412C695.514 148.412 696.48 149.336 696.48 150.89V154.194ZM693.26 155.034C693.904 155.034 694.562 154.684 694.926 154.082V152.444H694.058C692.588 152.444 692.014 152.962 692.014 153.83C692.014 154.614 692.434 155.034 693.26 155.034ZM699.219 156V148.608H700.577L700.689 149.574C701.305 148.818 702.187 148.412 703.083 148.412C704.455 148.412 705.141 149.224 705.141 150.61V156H703.573V151.394C703.573 150.106 703.419 149.616 702.523 149.616C701.795 149.616 701.179 150.134 700.787 150.694V156H699.219ZM713.269 154.194C713.269 154.768 713.437 154.992 713.829 155.118L713.465 156.182C712.751 156.098 712.205 155.804 711.939 155.16C711.393 155.846 710.525 156.182 709.587 156.182C708.075 156.182 707.151 155.258 707.151 153.886C707.151 152.346 708.411 151.464 710.665 151.464H711.715V150.988C711.715 150.022 711.113 149.644 710.077 149.644C709.587 149.644 708.859 149.756 708.117 150.022L707.725 148.916C708.649 148.566 709.559 148.412 710.315 148.412C712.303 148.412 713.269 149.336 713.269 150.89V154.194ZM710.049 155.034C710.693 155.034 711.351 154.684 711.715 154.082V152.444H710.847C709.377 152.444 708.803 152.962 708.803 153.83C708.803 154.614 709.223 155.034 710.049 155.034ZM716.624 157.484L715.378 156.924L721.314 144.632L722.546 145.206L716.624 157.484ZM726.012 145.458V156H724.444V145.64L726.012 145.458ZM730.912 148.608L727.93 151.912L731.22 156H729.302L726.124 151.954L729.092 148.608H730.912ZM735.751 144.982C736.353 144.982 736.773 145.416 736.773 145.976C736.773 146.536 736.353 146.956 735.751 146.956C735.135 146.956 734.729 146.536 734.729 145.976C734.729 145.416 735.135 144.982 735.751 144.982ZM736.829 148.608V154.852H738.845V156H733.063V154.852H735.261V149.756H733.133V148.608H736.829ZM747.365 155.608C746.819 155.958 746.035 156.182 745.209 156.182C743.487 156.182 742.577 155.216 742.577 153.76V149.756H740.939V148.608H742.577V146.956L744.145 146.774V148.608H746.651L746.469 149.756H744.145V153.746C744.145 154.544 744.523 154.922 745.433 154.922C745.965 154.922 746.427 154.782 746.805 154.572L747.365 155.608Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"554\"\n                        y=\"368\"\n                        width=\"205\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-coral-400 dark:fill-coral-500\"\n                    />\n                    <path\n                        d=\"M567.99 376.144C571.49 376.144 572.274 378.86 572.274 381.954C572.274 385.482 571.882 387.288 570.16 387.288C569.026 387.288 568.536 386.14 568.494 385.314H568.438C568.158 385.986 567.584 386.658 566.506 386.658C564.924 386.658 564.336 385.286 564.336 383.452C564.336 381.072 565.33 379.784 567.178 379.784C567.85 379.784 568.508 379.924 569.292 380.344V384.502C569.292 385.832 569.628 386.182 570.118 386.182C570.86 386.182 570.874 384.6 570.874 382.01C570.874 379.238 570.398 377.306 567.962 377.306C567.01 377.306 565.974 377.586 564.826 378.594L564.07 377.712C565.33 376.606 566.646 376.144 567.99 376.144ZM567.192 380.848C566.114 380.848 565.792 381.646 565.792 383.452C565.792 384.782 566.016 385.58 566.744 385.58C567.584 385.58 567.822 384.852 567.948 384.446V381.03C567.696 380.904 567.472 380.848 567.192 380.848ZM576.329 384.992C577.309 384.992 577.925 384.614 577.925 383.998C577.925 383.396 577.687 383.116 576.161 382.724C574.691 382.346 573.725 381.828 573.725 380.54C573.725 379.266 574.859 378.412 576.679 378.412C577.925 378.412 578.821 378.776 579.493 379.266L578.821 380.26C578.247 379.882 577.589 379.602 576.721 379.602C575.713 379.602 575.321 379.924 575.321 380.414C575.321 380.974 575.727 381.184 577.197 381.59C578.639 381.982 579.591 382.486 579.591 383.886C579.591 385.496 578.023 386.182 576.329 386.182C574.957 386.182 573.977 385.734 573.291 385.146L574.117 384.194C574.691 384.656 575.461 384.992 576.329 384.992ZM585.003 378.412C587.159 378.412 588.335 379.938 588.335 382.29C588.335 384.642 587.131 386.182 584.989 386.182C582.833 386.182 581.643 384.698 581.643 382.304C581.643 379.994 582.847 378.412 585.003 378.412ZM585.003 379.63C583.869 379.63 583.295 380.47 583.295 382.304C583.295 384.138 583.855 384.978 584.989 384.978C586.123 384.978 586.683 384.138 586.683 382.29C586.683 380.47 586.123 379.63 585.003 379.63ZM593.678 375.64V383.984C593.678 384.67 594.14 384.922 594.798 384.922C595.218 384.922 595.596 384.824 595.974 384.67L596.366 385.762C595.932 386 595.288 386.182 594.462 386.182C592.978 386.182 592.11 385.3 592.11 383.844V376.788H589.884V375.64H593.678ZM604.48 384.194C604.48 384.768 604.648 384.992 605.04 385.118L604.676 386.182C603.962 386.098 603.416 385.804 603.15 385.16C602.604 385.846 601.736 386.182 600.798 386.182C599.286 386.182 598.362 385.258 598.362 383.886C598.362 382.346 599.622 381.464 601.876 381.464H602.926V380.988C602.926 380.022 602.324 379.644 601.288 379.644C600.798 379.644 600.07 379.756 599.328 380.022L598.936 378.916C599.86 378.566 600.77 378.412 601.526 378.412C603.514 378.412 604.48 379.336 604.48 380.89V384.194ZM601.26 385.034C601.904 385.034 602.562 384.684 602.926 384.082V382.444H602.058C600.588 382.444 600.014 382.962 600.014 383.83C600.014 384.614 600.434 385.034 601.26 385.034ZM607.219 386V378.608H608.577L608.689 379.574C609.305 378.818 610.187 378.412 611.083 378.412C612.455 378.412 613.141 379.224 613.141 380.61V386H611.573V381.394C611.573 380.106 611.419 379.616 610.523 379.616C609.795 379.616 609.179 380.134 608.787 380.694V386H607.219ZM621.269 384.194C621.269 384.768 621.437 384.992 621.829 385.118L621.465 386.182C620.751 386.098 620.205 385.804 619.939 385.16C619.393 385.846 618.525 386.182 617.587 386.182C616.075 386.182 615.151 385.258 615.151 383.886C615.151 382.346 616.411 381.464 618.665 381.464H619.715V380.988C619.715 380.022 619.113 379.644 618.077 379.644C617.587 379.644 616.859 379.756 616.117 380.022L615.725 378.916C616.649 378.566 617.559 378.412 618.315 378.412C620.303 378.412 621.269 379.336 621.269 380.89V384.194ZM618.049 385.034C618.693 385.034 619.351 384.684 619.715 384.082V382.444H618.847C617.377 382.444 616.803 382.962 616.803 383.83C616.803 384.614 617.223 385.034 618.049 385.034ZM624.428 382.822V381.534H629.496V382.822H624.428ZM636.014 378.412C637.96 378.412 638.702 379.938 638.702 382.29C638.702 384.544 637.722 386.182 635.846 386.182C635.076 386.182 634.446 385.916 633.97 385.37V388.842L632.402 389.024V378.608H633.76L633.858 379.56C634.418 378.804 635.188 378.412 636.014 378.412ZM635.58 379.616C634.88 379.616 634.334 380.106 633.97 380.68V384.138C634.32 384.67 634.824 384.964 635.426 384.964C636.49 384.964 637.05 384.152 637.05 382.304C637.05 380.4 636.56 379.616 635.58 379.616ZM646.033 378.426C646.481 378.426 646.817 378.496 647.153 378.608L646.887 381.338H645.767V379.826C644.717 379.854 643.961 380.694 643.527 382.136V384.88H645.011V386H640.867V384.88H641.959V379.728H640.867V378.608H643.149L643.429 380.316C643.989 379.084 644.759 378.426 646.033 378.426ZM652.159 378.412C654.315 378.412 655.491 379.938 655.491 382.29C655.491 384.642 654.287 386.182 652.145 386.182C649.989 386.182 648.799 384.698 648.799 382.304C648.799 379.994 650.003 378.412 652.159 378.412ZM652.159 379.63C651.025 379.63 650.451 380.47 650.451 382.304C650.451 384.138 651.011 384.978 652.145 384.978C653.279 384.978 653.839 384.138 653.839 382.29C653.839 380.47 653.279 379.63 652.159 379.63ZM663.816 377.67L664.222 378.972C663.648 379.168 662.948 379.21 662.08 379.21C662.962 379.616 663.424 380.204 663.424 381.1C663.424 382.542 662.318 383.592 660.498 383.592C660.078 383.592 659.784 383.564 659.49 383.466C659.294 383.606 659.168 383.844 659.168 384.082C659.168 384.376 659.336 384.642 660.078 384.642H661.366C662.948 384.642 664.068 385.51 664.068 386.7C664.068 388.17 662.766 389.024 660.372 389.024C657.824 389.024 657.082 388.226 657.082 386.728H658.482C658.482 387.512 658.832 387.876 660.386 387.876C661.926 387.876 662.486 387.484 662.486 386.798C662.486 386.196 661.926 385.86 661.058 385.86H659.784C658.384 385.86 657.768 385.202 657.768 384.432C657.768 383.942 658.048 383.452 658.58 383.102C657.698 382.64 657.32 381.996 657.32 381.03C657.32 379.476 658.58 378.412 660.4 378.412C662.178 378.426 662.934 378.104 663.816 377.67ZM660.414 379.504C659.406 379.504 658.916 380.12 658.916 381.03C658.916 381.954 659.42 382.57 660.428 382.57C661.366 382.57 661.856 382.01 661.856 381.002C661.856 380.008 661.38 379.504 660.414 379.504ZM671.216 378.426C671.664 378.426 672 378.496 672.336 378.608L672.07 381.338H670.95V379.826C669.9 379.854 669.144 380.694 668.71 382.136V384.88H670.194V386H666.05V384.88H667.142V379.728H666.05V378.608H668.332L668.612 380.316C669.172 379.084 669.942 378.426 671.216 378.426ZM680.031 384.194C680.031 384.768 680.199 384.992 680.591 385.118L680.227 386.182C679.513 386.098 678.967 385.804 678.701 385.16C678.155 385.846 677.287 386.182 676.349 386.182C674.837 386.182 673.913 385.258 673.913 383.886C673.913 382.346 675.173 381.464 677.427 381.464H678.477V380.988C678.477 380.022 677.875 379.644 676.839 379.644C676.349 379.644 675.621 379.756 674.879 380.022L674.487 378.916C675.411 378.566 676.321 378.412 677.077 378.412C679.065 378.412 680.031 379.336 680.031 380.89V384.194ZM676.811 385.034C677.455 385.034 678.113 384.684 678.477 384.082V382.444H677.609C676.139 382.444 675.565 382.962 675.565 383.83C675.565 384.614 675.985 385.034 676.811 385.034ZM687.865 378.412C688.705 378.412 689.335 378.874 689.335 380.512V386H687.949V380.722C687.949 379.952 687.893 379.63 687.459 379.63C687.095 379.63 686.731 379.84 686.367 380.372V386H685.093V380.722C685.093 379.952 685.037 379.63 684.603 379.63C684.225 379.63 683.875 379.84 683.511 380.372V386H682.111V378.608H683.287L683.399 379.406C683.819 378.818 684.267 378.412 684.981 378.412C685.541 378.412 686.031 378.65 686.241 379.35C686.661 378.79 687.151 378.412 687.865 378.412ZM691.78 387.484L690.534 386.924L696.47 374.632L697.702 375.206L691.78 387.484ZM702.247 384.992C703.227 384.992 703.843 384.614 703.843 383.998C703.843 383.396 703.605 383.116 702.079 382.724C700.609 382.346 699.643 381.828 699.643 380.54C699.643 379.266 700.777 378.412 702.597 378.412C703.843 378.412 704.739 378.776 705.411 379.266L704.739 380.26C704.165 379.882 703.507 379.602 702.639 379.602C701.631 379.602 701.239 379.924 701.239 380.414C701.239 380.974 701.645 381.184 703.115 381.59C704.557 381.982 705.508 382.486 705.508 383.886C705.508 385.496 703.941 386.182 702.247 386.182C700.875 386.182 699.895 385.734 699.209 385.146L700.035 384.194C700.609 384.656 701.379 384.992 702.247 384.992ZM714.421 378.608L711.873 386.028C711.313 387.708 710.319 388.842 708.247 389.024L708.051 387.848C709.549 387.61 710.025 387.064 710.417 386H709.885L707.393 378.608H709.059L710.921 384.908L712.811 378.608H714.421ZM719.036 384.992C720.016 384.992 720.632 384.614 720.632 383.998C720.632 383.396 720.394 383.116 718.868 382.724C717.398 382.346 716.432 381.828 716.432 380.54C716.432 379.266 717.566 378.412 719.386 378.412C720.632 378.412 721.528 378.776 722.2 379.266L721.528 380.26C720.954 379.882 720.296 379.602 719.428 379.602C718.42 379.602 718.028 379.924 718.028 380.414C718.028 380.974 718.434 381.184 719.904 381.59C721.346 381.982 722.298 382.486 722.298 383.886C722.298 385.496 720.73 386.182 719.036 386.182C717.664 386.182 716.684 385.734 715.998 385.146L716.824 384.194C717.398 384.656 718.168 384.992 719.036 384.992ZM730.916 385.608C730.37 385.958 729.586 386.182 728.76 386.182C727.038 386.182 726.128 385.216 726.128 383.76V379.756H724.49V378.608H726.128V376.956L727.696 376.774V378.608H730.202L730.02 379.756H727.696V383.746C727.696 384.544 728.074 384.922 728.984 384.922C729.516 384.922 729.978 384.782 730.356 384.572L730.916 385.608ZM734.439 382.808C734.537 384.32 735.391 384.964 736.455 384.964C737.169 384.964 737.771 384.74 738.401 384.32L739.073 385.272C738.387 385.832 737.421 386.182 736.385 386.182C734.075 386.182 732.815 384.614 732.815 382.304C732.815 380.092 734.089 378.412 736.189 378.412C738.149 378.412 739.381 379.812 739.381 382.108C739.381 382.36 739.367 382.626 739.339 382.808H734.439ZM736.203 379.574C735.223 379.574 734.523 380.26 734.425 381.744H737.855C737.827 380.344 737.253 379.574 736.203 379.574ZM746.627 378.412C747.467 378.412 748.097 378.874 748.097 380.512V386H746.711V380.722C746.711 379.952 746.655 379.63 746.221 379.63C745.857 379.63 745.493 379.84 745.129 380.372V386H743.855V380.722C743.855 379.952 743.799 379.63 743.365 379.63C742.987 379.63 742.637 379.84 742.273 380.372V386H740.873V378.608H742.049L742.161 379.406C742.581 378.818 743.029 378.412 743.743 378.412C744.303 378.412 744.793 378.65 745.003 379.35C745.423 378.79 745.913 378.412 746.627 378.412Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"46\"\n                        width=\"146\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-coral-400 dark:fill-coral-500\"\n                    />\n                    <path\n                        d=\"M873.816 62.894C874.502 62.894 875.09 62.628 875.636 62.264L876.35 63.272C875.706 63.818 874.74 64.182 873.76 64.182C871.478 64.182 870.162 62.656 870.162 60.346C870.162 58.092 871.506 56.412 873.788 56.412C874.796 56.412 875.636 56.72 876.35 57.308L875.622 58.288C875.048 57.896 874.446 57.672 873.816 57.672C872.64 57.672 871.828 58.498 871.828 60.346C871.828 62.194 872.668 62.894 873.816 62.894ZM883.877 56.426C884.325 56.426 884.661 56.496 884.997 56.608L884.731 59.338H883.611V57.826C882.561 57.854 881.805 58.694 881.371 60.136V62.88H882.855V64H878.711V62.88H879.803V57.728H878.711V56.608H880.993L881.273 58.316C881.833 57.084 882.603 56.426 883.877 56.426ZM888.337 60.808C888.435 62.32 889.289 62.964 890.353 62.964C891.067 62.964 891.669 62.74 892.299 62.32L892.971 63.272C892.285 63.832 891.319 64.182 890.283 64.182C887.973 64.182 886.713 62.614 886.713 60.304C886.713 58.092 887.987 56.412 890.087 56.412C892.047 56.412 893.279 57.812 893.279 60.108C893.279 60.36 893.265 60.626 893.237 60.808H888.337ZM890.101 57.574C889.121 57.574 888.421 58.26 888.323 59.744H891.753C891.725 58.344 891.151 57.574 890.101 57.574ZM901.086 62.194C901.086 62.768 901.254 62.992 901.646 63.118L901.282 64.182C900.568 64.098 900.022 63.804 899.756 63.16C899.21 63.846 898.342 64.182 897.404 64.182C895.892 64.182 894.968 63.258 894.968 61.886C894.968 60.346 896.228 59.464 898.482 59.464H899.532V58.988C899.532 58.022 898.93 57.644 897.894 57.644C897.404 57.644 896.676 57.756 895.934 58.022L895.542 56.916C896.466 56.566 897.376 56.412 898.132 56.412C900.12 56.412 901.086 57.336 901.086 58.89V62.194ZM897.866 63.034C898.51 63.034 899.168 62.684 899.532 62.082V60.444H898.664C897.194 60.444 896.62 60.962 896.62 61.83C896.62 62.614 897.04 63.034 897.866 63.034ZM909.998 63.608C909.452 63.958 908.668 64.182 907.842 64.182C906.12 64.182 905.21 63.216 905.21 61.76V57.756H903.572V56.608H905.21V54.956L906.778 54.774V56.608H909.284L909.102 57.756H906.778V61.746C906.778 62.544 907.156 62.922 908.066 62.922C908.598 62.922 909.06 62.782 909.438 62.572L909.998 63.608ZM913.521 60.808C913.619 62.32 914.473 62.964 915.537 62.964C916.251 62.964 916.853 62.74 917.483 62.32L918.155 63.272C917.469 63.832 916.503 64.182 915.467 64.182C913.157 64.182 911.897 62.614 911.897 60.304C911.897 58.092 913.171 56.412 915.271 56.412C917.231 56.412 918.463 57.812 918.463 60.108C918.463 60.36 918.449 60.626 918.421 60.808H913.521ZM915.285 57.574C914.305 57.574 913.605 58.26 913.507 59.744H916.937C916.909 58.344 916.335 57.574 915.285 57.574ZM927.053 61.27C927.053 62.992 925.695 64.182 923.357 64.182C921.789 64.182 920.613 63.692 919.801 62.894L920.697 61.9C921.383 62.53 922.223 62.908 923.357 62.908C924.449 62.908 925.359 62.39 925.359 61.354C925.359 60.5 924.925 60.094 923.385 59.632C921.327 59.03 920.263 58.26 920.263 56.762C920.263 55.18 921.677 54.144 923.581 54.144C924.967 54.144 925.989 54.564 926.815 55.306L925.961 56.272C925.275 55.684 924.477 55.418 923.679 55.418C922.685 55.418 921.929 55.824 921.929 56.664C921.929 57.42 922.461 57.77 924.183 58.274C925.821 58.764 927.053 59.45 927.053 61.27ZM931.976 56.412C934.132 56.412 935.308 57.938 935.308 60.29C935.308 62.642 934.104 64.182 931.962 64.182C929.806 64.182 928.616 62.698 928.616 60.304C928.616 57.994 929.82 56.412 931.976 56.412ZM931.976 57.63C930.842 57.63 930.268 58.47 930.268 60.304C930.268 62.138 930.828 62.978 931.962 62.978C933.096 62.978 933.656 62.138 933.656 60.29C933.656 58.47 933.096 57.63 931.976 57.63ZM940.65 53.64V61.984C940.65 62.67 941.112 62.922 941.77 62.922C942.19 62.922 942.568 62.824 942.946 62.67L943.338 63.762C942.904 64 942.26 64.182 941.434 64.182C939.95 64.182 939.082 63.3 939.082 61.844V54.788H936.856V53.64H940.65ZM951.453 62.194C951.453 62.768 951.621 62.992 952.013 63.118L951.649 64.182C950.935 64.098 950.389 63.804 950.123 63.16C949.577 63.846 948.709 64.182 947.771 64.182C946.259 64.182 945.335 63.258 945.335 61.886C945.335 60.346 946.595 59.464 948.849 59.464H949.899V58.988C949.899 58.022 949.297 57.644 948.261 57.644C947.771 57.644 947.043 57.756 946.301 58.022L945.909 56.916C946.833 56.566 947.743 56.412 948.499 56.412C950.487 56.412 951.453 57.336 951.453 58.89V62.194ZM948.233 63.034C948.877 63.034 949.535 62.684 949.899 62.082V60.444H949.031C947.561 60.444 946.987 60.962 946.987 61.83C946.987 62.614 947.407 63.034 948.233 63.034ZM954.191 64V56.608H955.549L955.661 57.574C956.277 56.818 957.159 56.412 958.055 56.412C959.427 56.412 960.113 57.224 960.113 58.61V64H958.545V59.394C958.545 58.106 958.391 57.616 957.495 57.616C956.767 57.616 956.151 58.134 955.759 58.694V64H954.191ZM968.242 62.194C968.242 62.768 968.41 62.992 968.802 63.118L968.438 64.182C967.724 64.098 967.178 63.804 966.912 63.16C966.366 63.846 965.498 64.182 964.56 64.182C963.048 64.182 962.124 63.258 962.124 61.886C962.124 60.346 963.384 59.464 965.638 59.464H966.688V58.988C966.688 58.022 966.086 57.644 965.05 57.644C964.56 57.644 963.832 57.756 963.09 58.022L962.698 56.916C963.622 56.566 964.532 56.412 965.288 56.412C967.276 56.412 968.242 57.336 968.242 58.89V62.194ZM965.022 63.034C965.666 63.034 966.324 62.684 966.688 62.082V60.444H965.82C964.35 60.444 963.776 60.962 963.776 61.83C963.776 62.614 964.196 63.034 965.022 63.034ZM977.378 57.14C977.378 58.554 976.426 59.422 975.18 59.8L977.924 64H976.034L973.598 60.024H972.548V64H970.924V54.34H973.612C976.09 54.34 977.378 55.264 977.378 57.14ZM975.684 57.14C975.684 56.006 975.04 55.544 973.71 55.544H972.548V58.834H973.752C974.984 58.834 975.684 58.358 975.684 57.14ZM982.987 56.412C984.933 56.412 985.675 57.938 985.675 60.29C985.675 62.544 984.695 64.182 982.819 64.182C982.049 64.182 981.419 63.916 980.943 63.37V66.842L979.375 67.024V56.608H980.733L980.831 57.56C981.391 56.804 982.161 56.412 982.987 56.412ZM982.553 57.616C981.853 57.616 981.307 58.106 980.943 58.68V62.138C981.293 62.67 981.797 62.964 982.399 62.964C983.463 62.964 984.023 62.152 984.023 60.304C984.023 58.4 983.533 57.616 982.553 57.616ZM991.339 62.894C992.025 62.894 992.613 62.628 993.159 62.264L993.873 63.272C993.229 63.818 992.263 64.182 991.283 64.182C989.001 64.182 987.685 62.656 987.685 60.346C987.685 58.092 989.029 56.412 991.311 56.412C992.319 56.412 993.159 56.72 993.873 57.308L993.145 58.288C992.571 57.896 991.969 57.672 991.339 57.672C990.163 57.672 989.351 58.498 989.351 60.346C989.351 62.194 990.191 62.894 991.339 62.894Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"276\"\n                        width=\"205\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M876.476 285.67L876.882 286.972C876.308 287.168 875.608 287.21 874.74 287.21C875.622 287.616 876.084 288.204 876.084 289.1C876.084 290.542 874.978 291.592 873.158 291.592C872.738 291.592 872.444 291.564 872.15 291.466C871.954 291.606 871.828 291.844 871.828 292.082C871.828 292.376 871.996 292.642 872.738 292.642H874.026C875.608 292.642 876.728 293.51 876.728 294.7C876.728 296.17 875.426 297.024 873.032 297.024C870.484 297.024 869.742 296.226 869.742 294.728H871.142C871.142 295.512 871.492 295.876 873.046 295.876C874.586 295.876 875.146 295.484 875.146 294.798C875.146 294.196 874.586 293.86 873.718 293.86H872.444C871.044 293.86 870.428 293.202 870.428 292.432C870.428 291.942 870.708 291.452 871.24 291.102C870.358 290.64 869.98 289.996 869.98 289.03C869.98 287.476 871.24 286.412 873.06 286.412C874.838 286.426 875.594 286.104 876.476 285.67ZM873.074 287.504C872.066 287.504 871.576 288.12 871.576 289.03C871.576 289.954 872.08 290.57 873.088 290.57C874.026 290.57 874.516 290.01 874.516 289.002C874.516 288.008 874.04 287.504 873.074 287.504ZM879.943 290.808C880.041 292.32 880.895 292.964 881.959 292.964C882.673 292.964 883.275 292.74 883.905 292.32L884.577 293.272C883.891 293.832 882.925 294.182 881.889 294.182C879.579 294.182 878.319 292.614 878.319 290.304C878.319 288.092 879.593 286.412 881.693 286.412C883.653 286.412 884.885 287.812 884.885 290.108C884.885 290.36 884.871 290.626 884.843 290.808H879.943ZM881.707 287.574C880.727 287.574 880.027 288.26 879.929 289.744H883.359C883.331 288.344 882.757 287.574 881.707 287.574ZM893.209 293.608C892.663 293.958 891.879 294.182 891.053 294.182C889.331 294.182 888.421 293.216 888.421 291.76V287.756H886.783V286.608H888.421V284.956L889.989 284.774V286.608H892.495L892.313 287.756H889.989V291.746C889.989 292.544 890.367 292.922 891.277 292.922C891.809 292.922 892.271 292.782 892.649 292.572L893.209 293.608ZM900.078 291.676H896.634L895.962 294H894.296L897.376 284.34H899.392L902.472 294H900.75L900.078 291.676ZM896.97 290.416H899.742L898.356 285.6L896.97 290.416ZM907.072 283.64V291.984C907.072 292.67 907.534 292.922 908.192 292.922C908.612 292.922 908.99 292.824 909.368 292.67L909.76 293.762C909.326 294 908.682 294.182 907.856 294.182C906.372 294.182 905.504 293.3 905.504 291.844V284.788H903.278V283.64H907.072ZM915.467 283.64V291.984C915.467 292.67 915.929 292.922 916.587 292.922C917.007 292.922 917.385 292.824 917.763 292.67L918.155 293.762C917.721 294 917.077 294.182 916.251 294.182C914.767 294.182 913.899 293.3 913.899 291.844V284.788H911.673V283.64H915.467ZM923.581 286.412C925.737 286.412 926.913 287.938 926.913 290.29C926.913 292.642 925.709 294.182 923.567 294.182C921.411 294.182 920.221 292.698 920.221 290.304C920.221 287.994 921.425 286.412 923.581 286.412ZM923.581 287.63C922.447 287.63 921.873 288.47 921.873 290.304C921.873 292.138 922.433 292.978 923.567 292.978C924.701 292.978 925.261 292.138 925.261 290.29C925.261 288.47 924.701 287.63 923.581 287.63ZM932.578 292.894C933.264 292.894 933.852 292.628 934.398 292.264L935.112 293.272C934.468 293.818 933.502 294.182 932.522 294.182C930.24 294.182 928.924 292.656 928.924 290.346C928.924 288.092 930.268 286.412 932.55 286.412C933.558 286.412 934.398 286.72 935.112 287.308L934.384 288.288C933.81 287.896 933.208 287.672 932.578 287.672C931.402 287.672 930.59 288.498 930.59 290.346C930.59 292.194 931.43 292.894 932.578 292.894ZM943.058 292.194C943.058 292.768 943.226 292.992 943.618 293.118L943.254 294.182C942.54 294.098 941.994 293.804 941.728 293.16C941.182 293.846 940.314 294.182 939.376 294.182C937.864 294.182 936.94 293.258 936.94 291.886C936.94 290.346 938.2 289.464 940.454 289.464H941.504V288.988C941.504 288.022 940.902 287.644 939.866 287.644C939.376 287.644 938.648 287.756 937.906 288.022L937.514 286.916C938.438 286.566 939.348 286.412 940.104 286.412C942.092 286.412 943.058 287.336 943.058 288.89V292.194ZM939.838 293.034C940.482 293.034 941.14 292.684 941.504 292.082V290.444H940.636C939.166 290.444 938.592 290.962 938.592 291.83C938.592 292.614 939.012 293.034 939.838 293.034ZM951.971 293.608C951.425 293.958 950.641 294.182 949.815 294.182C948.093 294.182 947.183 293.216 947.183 291.76V287.756H945.545V286.608H947.183V284.956L948.751 284.774V286.608H951.257L951.075 287.756H948.751V291.746C948.751 292.544 949.129 292.922 950.039 292.922C950.571 292.922 951.033 292.782 951.411 292.572L951.971 293.608ZM955.493 290.808C955.591 292.32 956.445 292.964 957.509 292.964C958.223 292.964 958.825 292.74 959.455 292.32L960.127 293.272C959.441 293.832 958.475 294.182 957.439 294.182C955.129 294.182 953.869 292.614 953.869 290.304C953.869 288.092 955.143 286.412 957.243 286.412C959.203 286.412 960.435 287.812 960.435 290.108C960.435 290.36 960.421 290.626 960.393 290.808H955.493ZM957.257 287.574C956.277 287.574 955.577 288.26 955.479 289.744H958.909C958.881 288.344 958.307 287.574 957.257 287.574ZM968.452 284.34V285.572H966.352V292.754H968.452V294H962.628V292.754H964.728V285.572H962.628V284.34H968.452ZM970.98 294V286.608H972.338L972.45 287.574C973.066 286.818 973.948 286.412 974.844 286.412C976.216 286.412 976.902 287.224 976.902 288.61V294H975.334V289.394C975.334 288.106 975.18 287.616 974.284 287.616C973.556 287.616 972.94 288.134 972.548 288.694V294H970.98ZM982.063 292.992C983.043 292.992 983.659 292.614 983.659 291.998C983.659 291.396 983.421 291.116 981.895 290.724C980.425 290.346 979.459 289.828 979.459 288.54C979.459 287.266 980.593 286.412 982.413 286.412C983.659 286.412 984.555 286.776 985.227 287.266L984.555 288.26C983.981 287.882 983.323 287.602 982.455 287.602C981.447 287.602 981.055 287.924 981.055 288.414C981.055 288.974 981.461 289.184 982.931 289.59C984.373 289.982 985.325 290.486 985.325 291.886C985.325 293.496 983.757 294.182 982.063 294.182C980.691 294.182 979.711 293.734 979.025 293.146L979.851 292.194C980.425 292.656 981.195 292.992 982.063 292.992ZM993.943 293.608C993.397 293.958 992.613 294.182 991.787 294.182C990.065 294.182 989.155 293.216 989.155 291.76V287.756H987.517V286.608H989.155V284.956L990.723 284.774V286.608H993.229L993.047 287.756H990.723V291.746C990.723 292.544 991.101 292.922 992.011 292.922C992.543 292.922 993.005 292.782 993.383 292.572L993.943 293.608ZM1001.4 286.426C1001.85 286.426 1002.18 286.496 1002.52 286.608L1002.25 289.338H1001.13V287.826C1000.08 287.854 999.328 288.694 998.894 290.136V292.88H1000.38V294H996.234V292.88H997.326V287.728H996.234V286.608H998.516L998.796 288.316C999.356 287.084 1000.13 286.426 1001.4 286.426ZM1006.13 286.608V291.774C1006.13 292.642 1006.48 292.992 1007.18 292.992C1007.86 292.992 1008.53 292.53 1008.9 291.956V286.608H1010.47V294H1009.11L1009.01 293.048C1008.46 293.79 1007.55 294.182 1006.69 294.182C1005.24 294.182 1004.56 293.356 1004.56 291.97V286.608H1006.13ZM1016.52 292.894C1017.21 292.894 1017.8 292.628 1018.34 292.264L1019.06 293.272C1018.41 293.818 1017.45 294.182 1016.47 294.182C1014.19 294.182 1012.87 292.656 1012.87 290.346C1012.87 288.092 1014.21 286.412 1016.5 286.412C1017.5 286.412 1018.34 286.72 1019.06 287.308L1018.33 288.288C1017.76 287.896 1017.15 287.672 1016.52 287.672C1015.35 287.672 1014.54 288.498 1014.54 290.346C1014.54 292.194 1015.38 292.894 1016.52 292.894ZM1027.52 293.608C1026.98 293.958 1026.19 294.182 1025.37 294.182C1023.64 294.182 1022.73 293.216 1022.73 291.76V287.756H1021.1V286.608H1022.73V284.956L1024.3 284.774V286.608H1026.81L1026.63 287.756H1024.3V291.746C1024.3 292.544 1024.68 292.922 1025.59 292.922C1026.12 292.922 1026.58 292.782 1026.96 292.572L1027.52 293.608ZM1032.7 282.982C1033.3 282.982 1033.72 283.416 1033.72 283.976C1033.72 284.536 1033.3 284.956 1032.7 284.956C1032.08 284.956 1031.67 284.536 1031.67 283.976C1031.67 283.416 1032.08 282.982 1032.7 282.982ZM1033.77 286.608V292.852H1035.79V294H1030.01V292.852H1032.21V287.756H1030.08V286.608H1033.77ZM1041.1 286.412C1043.26 286.412 1044.44 287.938 1044.44 290.29C1044.44 292.642 1043.23 294.182 1041.09 294.182C1038.93 294.182 1037.74 292.698 1037.74 290.304C1037.74 287.994 1038.95 286.412 1041.1 286.412ZM1041.1 287.63C1039.97 287.63 1039.4 288.47 1039.4 290.304C1039.4 292.138 1039.96 292.978 1041.09 292.978C1042.22 292.978 1042.78 292.138 1042.78 290.29C1042.78 288.47 1042.22 287.63 1041.1 287.63ZM1046.53 294V286.608H1047.89L1048 287.574C1048.62 286.818 1049.5 286.412 1050.4 286.412C1051.77 286.412 1052.45 287.224 1052.45 288.61V294H1050.89V289.394C1050.89 288.106 1050.73 287.616 1049.84 287.616C1049.11 287.616 1048.49 288.134 1048.1 288.694V294H1046.53Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"322\"\n                        width=\"188\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M876.476 331.67L876.882 332.972C876.308 333.168 875.608 333.21 874.74 333.21C875.622 333.616 876.084 334.204 876.084 335.1C876.084 336.542 874.978 337.592 873.158 337.592C872.738 337.592 872.444 337.564 872.15 337.466C871.954 337.606 871.828 337.844 871.828 338.082C871.828 338.376 871.996 338.642 872.738 338.642H874.026C875.608 338.642 876.728 339.51 876.728 340.7C876.728 342.17 875.426 343.024 873.032 343.024C870.484 343.024 869.742 342.226 869.742 340.728H871.142C871.142 341.512 871.492 341.876 873.046 341.876C874.586 341.876 875.146 341.484 875.146 340.798C875.146 340.196 874.586 339.86 873.718 339.86H872.444C871.044 339.86 870.428 339.202 870.428 338.432C870.428 337.942 870.708 337.452 871.24 337.102C870.358 336.64 869.98 335.996 869.98 335.03C869.98 333.476 871.24 332.412 873.06 332.412C874.838 332.426 875.594 332.104 876.476 331.67ZM873.074 333.504C872.066 333.504 871.576 334.12 871.576 335.03C871.576 335.954 872.08 336.57 873.088 336.57C874.026 336.57 874.516 336.01 874.516 335.002C874.516 334.008 874.04 333.504 873.074 333.504ZM879.943 336.808C880.041 338.32 880.895 338.964 881.959 338.964C882.673 338.964 883.275 338.74 883.905 338.32L884.577 339.272C883.891 339.832 882.925 340.182 881.889 340.182C879.579 340.182 878.319 338.614 878.319 336.304C878.319 334.092 879.593 332.412 881.693 332.412C883.653 332.412 884.885 333.812 884.885 336.108C884.885 336.36 884.871 336.626 884.843 336.808H879.943ZM881.707 333.574C880.727 333.574 880.027 334.26 879.929 335.744H883.359C883.331 334.344 882.757 333.574 881.707 333.574ZM893.209 339.608C892.663 339.958 891.879 340.182 891.053 340.182C889.331 340.182 888.421 339.216 888.421 337.76V333.756H886.783V332.608H888.421V330.956L889.989 330.774V332.608H892.495L892.313 333.756H889.989V337.746C889.989 338.544 890.367 338.922 891.277 338.922C891.809 338.922 892.271 338.782 892.649 338.572L893.209 339.608ZM900.078 337.676H896.634L895.962 340H894.296L897.376 330.34H899.392L902.472 340H900.75L900.078 337.676ZM896.97 336.416H899.742L898.356 331.6L896.97 336.416ZM906.512 338.992C907.492 338.992 908.108 338.614 908.108 337.998C908.108 337.396 907.87 337.116 906.344 336.724C904.874 336.346 903.908 335.828 903.908 334.54C903.908 333.266 905.042 332.412 906.862 332.412C908.108 332.412 909.004 332.776 909.676 333.266L909.004 334.26C908.43 333.882 907.772 333.602 906.904 333.602C905.896 333.602 905.504 333.924 905.504 334.414C905.504 334.974 905.91 335.184 907.38 335.59C908.822 335.982 909.774 336.486 909.774 337.886C909.774 339.496 908.206 340.182 906.512 340.182C905.14 340.182 904.16 339.734 903.474 339.146L904.3 338.194C904.874 338.656 905.644 338.992 906.512 338.992ZM914.907 338.992C915.887 338.992 916.503 338.614 916.503 337.998C916.503 337.396 916.265 337.116 914.739 336.724C913.269 336.346 912.303 335.828 912.303 334.54C912.303 333.266 913.437 332.412 915.257 332.412C916.503 332.412 917.399 332.776 918.071 333.266L917.399 334.26C916.825 333.882 916.167 333.602 915.299 333.602C914.291 333.602 913.899 333.924 913.899 334.414C913.899 334.974 914.305 335.184 915.775 335.59C917.217 335.982 918.169 336.486 918.169 337.886C918.169 339.496 916.601 340.182 914.907 340.182C913.535 340.182 912.555 339.734 911.869 339.146L912.695 338.194C913.269 338.656 914.039 338.992 914.907 338.992ZM923.567 328.982C924.169 328.982 924.589 329.416 924.589 329.976C924.589 330.536 924.169 330.956 923.567 330.956C922.951 330.956 922.545 330.536 922.545 329.976C922.545 329.416 922.951 328.982 923.567 328.982ZM924.645 332.608V338.852H926.661V340H920.879V338.852H923.077V333.756H920.949V332.608H924.645ZM935.238 331.67L935.644 332.972C935.07 333.168 934.37 333.21 933.502 333.21C934.384 333.616 934.846 334.204 934.846 335.1C934.846 336.542 933.74 337.592 931.92 337.592C931.5 337.592 931.206 337.564 930.912 337.466C930.716 337.606 930.59 337.844 930.59 338.082C930.59 338.376 930.758 338.642 931.5 338.642H932.788C934.37 338.642 935.49 339.51 935.49 340.7C935.49 342.17 934.188 343.024 931.794 343.024C929.246 343.024 928.504 342.226 928.504 340.728H929.904C929.904 341.512 930.254 341.876 931.808 341.876C933.348 341.876 933.908 341.484 933.908 340.798C933.908 340.196 933.348 339.86 932.48 339.86H931.206C929.806 339.86 929.19 339.202 929.19 338.432C929.19 337.942 929.47 337.452 930.002 337.102C929.12 336.64 928.742 335.996 928.742 335.03C928.742 333.476 930.002 332.412 931.822 332.412C933.6 332.426 934.356 332.104 935.238 331.67ZM931.836 333.504C930.828 333.504 930.338 334.12 930.338 335.03C930.338 335.954 930.842 336.57 931.85 336.57C932.788 336.57 933.278 336.01 933.278 335.002C933.278 334.008 932.802 333.504 931.836 333.504ZM937.402 340V332.608H938.76L938.872 333.574C939.488 332.818 940.37 332.412 941.266 332.412C942.638 332.412 943.324 333.224 943.324 334.61V340H941.756V335.394C941.756 334.106 941.602 333.616 940.706 333.616C939.978 333.616 939.362 334.134 938.97 334.694V340H937.402ZM951.663 330.34V331.572H949.563V338.754H951.663V340H945.839V338.754H947.939V331.572H945.839V330.34H951.663ZM954.191 340V332.608H955.549L955.661 333.574C956.277 332.818 957.159 332.412 958.055 332.412C959.427 332.412 960.113 333.224 960.113 334.61V340H958.545V335.394C958.545 334.106 958.391 333.616 957.495 333.616C956.767 333.616 956.151 334.134 955.759 334.694V340H954.191ZM965.274 338.992C966.254 338.992 966.87 338.614 966.87 337.998C966.87 337.396 966.632 337.116 965.106 336.724C963.636 336.346 962.67 335.828 962.67 334.54C962.67 333.266 963.804 332.412 965.624 332.412C966.87 332.412 967.766 332.776 968.438 333.266L967.766 334.26C967.192 333.882 966.534 333.602 965.666 333.602C964.658 333.602 964.266 333.924 964.266 334.414C964.266 334.974 964.672 335.184 966.142 335.59C967.584 335.982 968.536 336.486 968.536 337.886C968.536 339.496 966.968 340.182 965.274 340.182C963.902 340.182 962.922 339.734 962.236 339.146L963.062 338.194C963.636 338.656 964.406 338.992 965.274 338.992ZM977.154 339.608C976.608 339.958 975.824 340.182 974.998 340.182C973.276 340.182 972.366 339.216 972.366 337.76V333.756H970.728V332.608H972.366V330.956L973.934 330.774V332.608H976.44L976.258 333.756H973.934V337.746C973.934 338.544 974.312 338.922 975.222 338.922C975.754 338.922 976.216 338.782 976.594 338.572L977.154 339.608ZM984.611 332.426C985.059 332.426 985.395 332.496 985.731 332.608L985.465 335.338H984.345V333.826C983.295 333.854 982.539 334.694 982.105 336.136V338.88H983.589V340H979.445V338.88H980.537V333.728H979.445V332.608H981.727L982.007 334.316C982.567 333.084 983.337 332.426 984.611 332.426ZM989.337 332.608V337.774C989.337 338.642 989.687 338.992 990.387 338.992C991.073 338.992 991.745 338.53 992.109 337.956V332.608H993.677V340H992.319L992.221 339.048C991.675 339.79 990.765 340.182 989.897 340.182C988.455 340.182 987.769 339.356 987.769 337.97V332.608H989.337ZM999.734 338.894C1000.42 338.894 1001.01 338.628 1001.55 338.264L1002.27 339.272C1001.62 339.818 1000.66 340.182 999.678 340.182C997.396 340.182 996.08 338.656 996.08 336.346C996.08 334.092 997.424 332.412 999.706 332.412C1000.71 332.412 1001.55 332.72 1002.27 333.308L1001.54 334.288C1000.97 333.896 1000.36 333.672 999.734 333.672C998.558 333.672 997.746 334.498 997.746 336.346C997.746 338.194 998.586 338.894 999.734 338.894ZM1010.73 339.608C1010.19 339.958 1009.4 340.182 1008.58 340.182C1006.85 340.182 1005.94 339.216 1005.94 337.76V333.756H1004.31V332.608H1005.94V330.956L1007.51 330.774V332.608H1010.02L1009.84 333.756H1007.51V337.746C1007.51 338.544 1007.89 338.922 1008.8 338.922C1009.33 338.922 1009.79 338.782 1010.17 338.572L1010.73 339.608ZM1015.91 328.982C1016.51 328.982 1016.93 329.416 1016.93 329.976C1016.93 330.536 1016.51 330.956 1015.91 330.956C1015.29 330.956 1014.89 330.536 1014.89 329.976C1014.89 329.416 1015.29 328.982 1015.91 328.982ZM1016.99 332.608V338.852H1019V340H1013.22V338.852H1015.42V333.756H1013.29V332.608H1016.99ZM1024.32 332.412C1026.47 332.412 1027.65 333.938 1027.65 336.29C1027.65 338.642 1026.44 340.182 1024.3 340.182C1022.15 340.182 1020.96 338.698 1020.96 336.304C1020.96 333.994 1022.16 332.412 1024.32 332.412ZM1024.32 333.63C1023.18 333.63 1022.61 334.47 1022.61 336.304C1022.61 338.138 1023.17 338.978 1024.3 338.978C1025.44 338.978 1026 338.138 1026 336.29C1026 334.47 1025.44 333.63 1024.32 333.63ZM1029.74 340V332.608H1031.1L1031.21 333.574C1031.83 332.818 1032.71 332.412 1033.61 332.412C1034.98 332.412 1035.66 333.224 1035.66 334.61V340H1034.1V335.394C1034.1 334.106 1033.94 333.616 1033.05 333.616C1032.32 333.616 1031.7 334.134 1031.31 334.694V340H1029.74Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"368\"\n                        width=\"247\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-coral-400 dark:fill-coral-500\"\n                    />\n                    <path\n                        d=\"M876.476 377.67L876.882 378.972C876.308 379.168 875.608 379.21 874.74 379.21C875.622 379.616 876.084 380.204 876.084 381.1C876.084 382.542 874.978 383.592 873.158 383.592C872.738 383.592 872.444 383.564 872.15 383.466C871.954 383.606 871.828 383.844 871.828 384.082C871.828 384.376 871.996 384.642 872.738 384.642H874.026C875.608 384.642 876.728 385.51 876.728 386.7C876.728 388.17 875.426 389.024 873.032 389.024C870.484 389.024 869.742 388.226 869.742 386.728H871.142C871.142 387.512 871.492 387.876 873.046 387.876C874.586 387.876 875.146 387.484 875.146 386.798C875.146 386.196 874.586 385.86 873.718 385.86H872.444C871.044 385.86 870.428 385.202 870.428 384.432C870.428 383.942 870.708 383.452 871.24 383.102C870.358 382.64 869.98 381.996 869.98 381.03C869.98 379.476 871.24 378.412 873.06 378.412C874.838 378.426 875.594 378.104 876.476 377.67ZM873.074 379.504C872.066 379.504 871.576 380.12 871.576 381.03C871.576 381.954 872.08 382.57 873.088 382.57C874.026 382.57 874.516 382.01 874.516 381.002C874.516 380.008 874.04 379.504 873.074 379.504ZM879.943 382.808C880.041 384.32 880.895 384.964 881.959 384.964C882.673 384.964 883.275 384.74 883.905 384.32L884.577 385.272C883.891 385.832 882.925 386.182 881.889 386.182C879.579 386.182 878.319 384.614 878.319 382.304C878.319 380.092 879.593 378.412 881.693 378.412C883.653 378.412 884.885 379.812 884.885 382.108C884.885 382.36 884.871 382.626 884.843 382.808H879.943ZM881.707 379.574C880.727 379.574 880.027 380.26 879.929 381.744H883.359C883.331 380.344 882.757 379.574 881.707 379.574ZM893.209 385.608C892.663 385.958 891.879 386.182 891.053 386.182C889.331 386.182 888.421 385.216 888.421 383.76V379.756H886.783V378.608H888.421V376.956L889.989 376.774V378.608H892.495L892.313 379.756H889.989V383.746C889.989 384.544 890.367 384.922 891.277 384.922C891.809 384.922 892.271 384.782 892.649 384.572L893.209 385.608ZM899.196 376.144C900.512 376.144 901.324 376.494 902.108 377.124L901.268 378.132C900.68 377.656 900.022 377.418 899.266 377.418C897.824 377.418 896.606 378.426 896.606 381.156C896.606 383.83 897.754 384.866 899.28 384.866C900.316 384.866 900.932 384.46 901.464 384.04L902.248 385.034C901.604 385.664 900.638 386.182 899.224 386.182C896.76 386.182 894.912 384.432 894.912 381.156C894.912 377.908 896.844 376.144 899.196 376.144ZM909.06 378.426C909.508 378.426 909.844 378.496 910.18 378.608L909.914 381.338H908.794V379.826C907.744 379.854 906.988 380.694 906.554 382.136V384.88H908.038V386H903.894V384.88H904.986V379.728H903.894V378.608H906.176L906.456 380.316C907.016 379.084 907.786 378.426 909.06 378.426ZM913.521 382.808C913.619 384.32 914.473 384.964 915.537 384.964C916.251 384.964 916.853 384.74 917.483 384.32L918.155 385.272C917.469 385.832 916.503 386.182 915.467 386.182C913.157 386.182 911.897 384.614 911.897 382.304C911.897 380.092 913.171 378.412 915.271 378.412C917.231 378.412 918.463 379.812 918.463 382.108C918.463 382.36 918.449 382.626 918.421 382.808H913.521ZM915.285 379.574C914.305 379.574 913.605 380.26 913.507 381.744H916.937C916.909 380.344 916.335 379.574 915.285 379.574ZM926.269 384.194C926.269 384.768 926.437 384.992 926.829 385.118L926.465 386.182C925.751 386.098 925.205 385.804 924.939 385.16C924.393 385.846 923.525 386.182 922.587 386.182C921.075 386.182 920.151 385.258 920.151 383.886C920.151 382.346 921.411 381.464 923.665 381.464H924.715V380.988C924.715 380.022 924.113 379.644 923.077 379.644C922.587 379.644 921.859 379.756 921.117 380.022L920.725 378.916C921.649 378.566 922.559 378.412 923.315 378.412C925.303 378.412 926.269 379.336 926.269 380.89V384.194ZM923.049 385.034C923.693 385.034 924.351 384.684 924.715 384.082V382.444H923.847C922.377 382.444 921.803 382.962 921.803 383.83C921.803 384.614 922.223 385.034 923.049 385.034ZM935.182 385.608C934.636 385.958 933.852 386.182 933.026 386.182C931.304 386.182 930.394 385.216 930.394 383.76V379.756H928.756V378.608H930.394V376.956L931.962 376.774V378.608H934.468L934.286 379.756H931.962V383.746C931.962 384.544 932.34 384.922 933.25 384.922C933.782 384.922 934.244 384.782 934.622 384.572L935.182 385.608ZM938.704 382.808C938.802 384.32 939.656 384.964 940.72 384.964C941.434 384.964 942.036 384.74 942.666 384.32L943.338 385.272C942.652 385.832 941.686 386.182 940.65 386.182C938.34 386.182 937.08 384.614 937.08 382.304C937.08 380.092 938.354 378.412 940.454 378.412C942.414 378.412 943.646 379.812 943.646 382.108C943.646 382.36 943.632 382.626 943.604 382.808H938.704ZM940.468 379.574C939.488 379.574 938.788 380.26 938.69 381.744H942.12C942.092 380.344 941.518 379.574 940.468 379.574ZM950.445 383.676H947.001L946.329 386H944.663L947.743 376.34H949.759L952.839 386H951.117L950.445 383.676ZM947.337 382.416H950.109L948.723 377.6L947.337 382.416ZM957.761 384.894C958.447 384.894 959.035 384.628 959.581 384.264L960.295 385.272C959.651 385.818 958.685 386.182 957.705 386.182C955.423 386.182 954.107 384.656 954.107 382.346C954.107 380.092 955.451 378.412 957.733 378.412C958.741 378.412 959.581 378.72 960.295 379.308L959.567 380.288C958.993 379.896 958.391 379.672 957.761 379.672C956.585 379.672 955.773 380.498 955.773 382.346C955.773 384.194 956.613 384.894 957.761 384.894ZM966.156 384.894C966.842 384.894 967.43 384.628 967.976 384.264L968.69 385.272C968.046 385.818 967.08 386.182 966.1 386.182C963.818 386.182 962.502 384.656 962.502 382.346C962.502 380.092 963.846 378.412 966.128 378.412C967.136 378.412 967.976 378.72 968.69 379.308L967.962 380.288C967.388 379.896 966.786 379.672 966.156 379.672C964.98 379.672 964.168 380.498 964.168 382.346C964.168 384.194 965.008 384.894 966.156 384.894ZM973.948 378.412C976.104 378.412 977.28 379.938 977.28 382.29C977.28 384.642 976.076 386.182 973.934 386.182C971.778 386.182 970.588 384.698 970.588 382.304C970.588 379.994 971.792 378.412 973.948 378.412ZM973.948 379.63C972.814 379.63 972.24 380.47 972.24 382.304C972.24 384.138 972.8 384.978 973.934 384.978C975.068 384.978 975.628 384.138 975.628 382.29C975.628 380.47 975.068 379.63 973.948 379.63ZM980.943 378.608V383.774C980.943 384.642 981.293 384.992 981.993 384.992C982.679 384.992 983.351 384.53 983.715 383.956V378.608H985.283V386H983.925L983.827 385.048C983.281 385.79 982.371 386.182 981.503 386.182C980.061 386.182 979.375 385.356 979.375 383.97V378.608H980.943ZM987.769 386V378.608H989.127L989.239 379.574C989.855 378.818 990.737 378.412 991.633 378.412C993.005 378.412 993.691 379.224 993.691 380.61V386H992.123V381.394C992.123 380.106 991.969 379.616 991.073 379.616C990.345 379.616 989.729 380.134 989.337 380.694V386H987.769ZM1002.34 385.608C1001.79 385.958 1001.01 386.182 1000.18 386.182C998.46 386.182 997.55 385.216 997.55 383.76V379.756H995.912V378.608H997.55V376.956L999.118 376.774V378.608H1001.62L1001.44 379.756H999.118V383.746C999.118 384.544 999.496 384.922 1000.41 384.922C1000.94 384.922 1001.4 384.782 1001.78 384.572L1002.34 385.608ZM1010.42 376.34V377.572H1008.32V384.754H1010.42V386H1004.6V384.754H1006.7V377.572H1004.6V376.34H1010.42ZM1012.95 386V378.608H1014.31L1014.42 379.574C1015.04 378.818 1015.92 378.412 1016.82 378.412C1018.19 378.412 1018.88 379.224 1018.88 380.61V386H1017.31V381.394C1017.31 380.106 1017.15 379.616 1016.26 379.616C1015.53 379.616 1014.91 380.134 1014.52 380.694V386H1012.95ZM1024.04 384.992C1025.02 384.992 1025.63 384.614 1025.63 383.998C1025.63 383.396 1025.39 383.116 1023.87 382.724C1022.4 382.346 1021.43 381.828 1021.43 380.54C1021.43 379.266 1022.57 378.412 1024.39 378.412C1025.63 378.412 1026.53 378.776 1027.2 379.266L1026.53 380.26C1025.95 379.882 1025.3 379.602 1024.43 379.602C1023.42 379.602 1023.03 379.924 1023.03 380.414C1023.03 380.974 1023.43 381.184 1024.9 381.59C1026.35 381.982 1027.3 382.486 1027.3 383.886C1027.3 385.496 1025.73 386.182 1024.04 386.182C1022.66 386.182 1021.68 385.734 1021 385.146L1021.82 384.194C1022.4 384.656 1023.17 384.992 1024.04 384.992ZM1035.92 385.608C1035.37 385.958 1034.59 386.182 1033.76 386.182C1032.04 386.182 1031.13 385.216 1031.13 383.76V379.756H1029.49V378.608H1031.13V376.956L1032.7 376.774V378.608H1035.2L1035.02 379.756H1032.7V383.746C1032.7 384.544 1033.07 384.922 1033.98 384.922C1034.52 384.922 1034.98 384.782 1035.36 384.572L1035.92 385.608ZM1043.37 378.426C1043.82 378.426 1044.16 378.496 1044.49 378.608L1044.23 381.338H1043.11V379.826C1042.06 379.854 1041.3 380.694 1040.87 382.136V384.88H1042.35V386H1038.21V384.88H1039.3V379.728H1038.21V378.608H1040.49L1040.77 380.316C1041.33 379.084 1042.1 378.426 1043.37 378.426ZM1048.1 378.608V383.774C1048.1 384.642 1048.45 384.992 1049.15 384.992C1049.84 384.992 1050.51 384.53 1050.87 383.956V378.608H1052.44V386H1051.08L1050.98 385.048C1050.44 385.79 1049.53 386.182 1048.66 386.182C1047.22 386.182 1046.53 385.356 1046.53 383.97V378.608H1048.1ZM1058.5 384.894C1059.18 384.894 1059.77 384.628 1060.32 384.264L1061.03 385.272C1060.39 385.818 1059.42 386.182 1058.44 386.182C1056.16 386.182 1054.84 384.656 1054.84 382.346C1054.84 380.092 1056.19 378.412 1058.47 378.412C1059.48 378.412 1060.32 378.72 1061.03 379.308L1060.3 380.288C1059.73 379.896 1059.13 379.672 1058.5 379.672C1057.32 379.672 1056.51 380.498 1056.51 382.346C1056.51 384.194 1057.35 384.894 1058.5 384.894ZM1069.49 385.608C1068.95 385.958 1068.16 386.182 1067.34 386.182C1065.62 386.182 1064.71 385.216 1064.71 383.76V379.756H1063.07V378.608H1064.71V376.956L1066.27 376.774V378.608H1068.78L1068.6 379.756H1066.27V383.746C1066.27 384.544 1066.65 384.922 1067.56 384.922C1068.09 384.922 1068.56 384.782 1068.93 384.572L1069.49 385.608ZM1074.67 374.982C1075.27 374.982 1075.69 375.416 1075.69 375.976C1075.69 376.536 1075.27 376.956 1074.67 376.956C1074.05 376.956 1073.65 376.536 1073.65 375.976C1073.65 375.416 1074.05 374.982 1074.67 374.982ZM1075.75 378.608V384.852H1077.76V386H1071.98V384.852H1074.18V379.756H1072.05V378.608H1075.75ZM1083.08 378.412C1085.23 378.412 1086.41 379.938 1086.41 382.29C1086.41 384.642 1085.21 386.182 1083.06 386.182C1080.91 386.182 1079.72 384.698 1079.72 382.304C1079.72 379.994 1080.92 378.412 1083.08 378.412ZM1083.08 379.63C1081.94 379.63 1081.37 380.47 1081.37 382.304C1081.37 384.138 1081.93 384.978 1083.06 384.978C1084.2 384.978 1084.76 384.138 1084.76 382.29C1084.76 380.47 1084.2 379.63 1083.08 379.63ZM1088.5 386V378.608H1089.86L1089.97 379.574C1090.59 378.818 1091.47 378.412 1092.37 378.412C1093.74 378.412 1094.43 379.224 1094.43 380.61V386H1092.86V381.394C1092.86 380.106 1092.7 379.616 1091.81 379.616C1091.08 379.616 1090.46 380.134 1090.07 380.694V386H1088.5Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"414\"\n                        width=\"314\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M876.476 423.67L876.882 424.972C876.308 425.168 875.608 425.21 874.74 425.21C875.622 425.616 876.084 426.204 876.084 427.1C876.084 428.542 874.978 429.592 873.158 429.592C872.738 429.592 872.444 429.564 872.15 429.466C871.954 429.606 871.828 429.844 871.828 430.082C871.828 430.376 871.996 430.642 872.738 430.642H874.026C875.608 430.642 876.728 431.51 876.728 432.7C876.728 434.17 875.426 435.024 873.032 435.024C870.484 435.024 869.742 434.226 869.742 432.728H871.142C871.142 433.512 871.492 433.876 873.046 433.876C874.586 433.876 875.146 433.484 875.146 432.798C875.146 432.196 874.586 431.86 873.718 431.86H872.444C871.044 431.86 870.428 431.202 870.428 430.432C870.428 429.942 870.708 429.452 871.24 429.102C870.358 428.64 869.98 427.996 869.98 427.03C869.98 425.476 871.24 424.412 873.06 424.412C874.838 424.426 875.594 424.104 876.476 423.67ZM873.074 425.504C872.066 425.504 871.576 426.12 871.576 427.03C871.576 427.954 872.08 428.57 873.088 428.57C874.026 428.57 874.516 428.01 874.516 427.002C874.516 426.008 874.04 425.504 873.074 425.504ZM879.943 428.808C880.041 430.32 880.895 430.964 881.959 430.964C882.673 430.964 883.275 430.74 883.905 430.32L884.577 431.272C883.891 431.832 882.925 432.182 881.889 432.182C879.579 432.182 878.319 430.614 878.319 428.304C878.319 426.092 879.593 424.412 881.693 424.412C883.653 424.412 884.885 425.812 884.885 428.108C884.885 428.36 884.871 428.626 884.843 428.808H879.943ZM881.707 425.574C880.727 425.574 880.027 426.26 879.929 427.744H883.359C883.331 426.344 882.757 425.574 881.707 425.574ZM893.209 431.608C892.663 431.958 891.879 432.182 891.053 432.182C889.331 432.182 888.421 431.216 888.421 429.76V425.756H886.783V424.608H888.421V422.956L889.989 422.774V424.608H892.495L892.313 425.756H889.989V429.746C889.989 430.544 890.367 430.922 891.277 430.922C891.809 430.922 892.271 430.782 892.649 430.572L893.209 431.608ZM899.196 422.144C900.512 422.144 901.324 422.494 902.108 423.124L901.268 424.132C900.68 423.656 900.022 423.418 899.266 423.418C897.824 423.418 896.606 424.426 896.606 427.156C896.606 429.83 897.754 430.866 899.28 430.866C900.316 430.866 900.932 430.46 901.464 430.04L902.248 431.034C901.604 431.664 900.638 432.182 899.224 432.182C896.76 432.182 894.912 430.432 894.912 427.156C894.912 423.908 896.844 422.144 899.196 422.144ZM909.06 424.426C909.508 424.426 909.844 424.496 910.18 424.608L909.914 427.338H908.794V425.826C907.744 425.854 906.988 426.694 906.554 428.136V430.88H908.038V432H903.894V430.88H904.986V425.728H903.894V424.608H906.176L906.456 426.316C907.016 425.084 907.786 424.426 909.06 424.426ZM913.521 428.808C913.619 430.32 914.473 430.964 915.537 430.964C916.251 430.964 916.853 430.74 917.483 430.32L918.155 431.272C917.469 431.832 916.503 432.182 915.467 432.182C913.157 432.182 911.897 430.614 911.897 428.304C911.897 426.092 913.171 424.412 915.271 424.412C917.231 424.412 918.463 425.812 918.463 428.108C918.463 428.36 918.449 428.626 918.421 428.808H913.521ZM915.285 425.574C914.305 425.574 913.605 426.26 913.507 427.744H916.937C916.909 426.344 916.335 425.574 915.285 425.574ZM926.269 430.194C926.269 430.768 926.437 430.992 926.829 431.118L926.465 432.182C925.751 432.098 925.205 431.804 924.939 431.16C924.393 431.846 923.525 432.182 922.587 432.182C921.075 432.182 920.151 431.258 920.151 429.886C920.151 428.346 921.411 427.464 923.665 427.464H924.715V426.988C924.715 426.022 924.113 425.644 923.077 425.644C922.587 425.644 921.859 425.756 921.117 426.022L920.725 424.916C921.649 424.566 922.559 424.412 923.315 424.412C925.303 424.412 926.269 425.336 926.269 426.89V430.194ZM923.049 431.034C923.693 431.034 924.351 430.684 924.715 430.082V428.444H923.847C922.377 428.444 921.803 428.962 921.803 429.83C921.803 430.614 922.223 431.034 923.049 431.034ZM935.182 431.608C934.636 431.958 933.852 432.182 933.026 432.182C931.304 432.182 930.394 431.216 930.394 429.76V425.756H928.756V424.608H930.394V422.956L931.962 422.774V424.608H934.468L934.286 425.756H931.962V429.746C931.962 430.544 932.34 430.922 933.25 430.922C933.782 430.922 934.244 430.782 934.622 430.572L935.182 431.608ZM938.704 428.808C938.802 430.32 939.656 430.964 940.72 430.964C941.434 430.964 942.036 430.74 942.666 430.32L943.338 431.272C942.652 431.832 941.686 432.182 940.65 432.182C938.34 432.182 937.08 430.614 937.08 428.304C937.08 426.092 938.354 424.412 940.454 424.412C942.414 424.412 943.646 425.812 943.646 428.108C943.646 428.36 943.632 428.626 943.604 428.808H938.704ZM940.468 425.574C939.488 425.574 938.788 426.26 938.69 427.744H942.12C942.092 426.344 941.518 425.574 940.468 425.574ZM950.445 429.676H947.001L946.329 432H944.663L947.743 422.34H949.759L952.839 432H951.117L950.445 429.676ZM947.337 428.416H950.109L948.723 423.6L947.337 428.416ZM957.761 430.894C958.447 430.894 959.035 430.628 959.581 430.264L960.295 431.272C959.651 431.818 958.685 432.182 957.705 432.182C955.423 432.182 954.107 430.656 954.107 428.346C954.107 426.092 955.451 424.412 957.733 424.412C958.741 424.412 959.581 424.72 960.295 425.308L959.567 426.288C958.993 425.896 958.391 425.672 957.761 425.672C956.585 425.672 955.773 426.498 955.773 428.346C955.773 430.194 956.613 430.894 957.761 430.894ZM966.156 430.894C966.842 430.894 967.43 430.628 967.976 430.264L968.69 431.272C968.046 431.818 967.08 432.182 966.1 432.182C963.818 432.182 962.502 430.656 962.502 428.346C962.502 426.092 963.846 424.412 966.128 424.412C967.136 424.412 967.976 424.72 968.69 425.308L967.962 426.288C967.388 425.896 966.786 425.672 966.156 425.672C964.98 425.672 964.168 426.498 964.168 428.346C964.168 430.194 965.008 430.894 966.156 430.894ZM973.948 424.412C976.104 424.412 977.28 425.938 977.28 428.29C977.28 430.642 976.076 432.182 973.934 432.182C971.778 432.182 970.588 430.698 970.588 428.304C970.588 425.994 971.792 424.412 973.948 424.412ZM973.948 425.63C972.814 425.63 972.24 426.47 972.24 428.304C972.24 430.138 972.8 430.978 973.934 430.978C975.068 430.978 975.628 430.138 975.628 428.29C975.628 426.47 975.068 425.63 973.948 425.63ZM980.943 424.608V429.774C980.943 430.642 981.293 430.992 981.993 430.992C982.679 430.992 983.351 430.53 983.715 429.956V424.608H985.283V432H983.925L983.827 431.048C983.281 431.79 982.371 432.182 981.503 432.182C980.061 432.182 979.375 431.356 979.375 429.97V424.608H980.943ZM987.769 432V424.608H989.127L989.239 425.574C989.855 424.818 990.737 424.412 991.633 424.412C993.005 424.412 993.691 425.224 993.691 426.61V432H992.123V427.394C992.123 426.106 991.969 425.616 991.073 425.616C990.345 425.616 989.729 426.134 989.337 426.694V432H987.769ZM1002.34 431.608C1001.79 431.958 1001.01 432.182 1000.18 432.182C998.46 432.182 997.55 431.216 997.55 429.76V425.756H995.912V424.608H997.55V422.956L999.118 422.774V424.608H1001.62L1001.44 425.756H999.118V429.746C999.118 430.544 999.496 430.922 1000.41 430.922C1000.94 430.922 1001.4 430.782 1001.78 430.572L1002.34 431.608ZM1011.68 422.34L1010.35 432H1008.45L1007.5 424.846L1006.5 432H1004.57L1003.34 422.34H1004.91L1005.66 430.432L1006.7 423.46H1008.37L1009.33 430.432L1010.23 422.34H1011.68ZM1015.91 420.982C1016.51 420.982 1016.93 421.416 1016.93 421.976C1016.93 422.536 1016.51 422.956 1015.91 422.956C1015.29 422.956 1014.89 422.536 1014.89 421.976C1014.89 421.416 1015.29 420.982 1015.91 420.982ZM1016.99 424.608V430.852H1019V432H1013.22V430.852H1015.42V425.756H1013.29V424.608H1016.99ZM1027.52 431.608C1026.98 431.958 1026.19 432.182 1025.37 432.182C1023.64 432.182 1022.73 431.216 1022.73 429.76V425.756H1021.1V424.608H1022.73V422.956L1024.3 422.774V424.608H1026.81L1026.63 425.756H1024.3V429.746C1024.3 430.544 1024.68 430.922 1025.59 430.922C1026.12 430.922 1026.58 430.782 1026.96 430.572L1027.52 431.608ZM1031.31 421.486V425.518C1031.91 424.79 1032.74 424.412 1033.61 424.412C1034.99 424.412 1035.66 425.224 1035.66 426.61V432H1034.1V426.848C1034.1 425.966 1033.77 425.616 1033.03 425.616C1032.33 425.616 1031.7 426.148 1031.31 426.708V432H1029.74V421.654L1031.31 421.486ZM1044.58 429.27C1044.58 430.992 1043.22 432.182 1040.88 432.182C1039.31 432.182 1038.14 431.692 1037.32 430.894L1038.22 429.9C1038.91 430.53 1039.75 430.908 1040.88 430.908C1041.97 430.908 1042.88 430.39 1042.88 429.354C1042.88 428.5 1042.45 428.094 1040.91 427.632C1038.85 427.03 1037.79 426.26 1037.79 424.762C1037.79 423.18 1039.2 422.144 1041.1 422.144C1042.49 422.144 1043.51 422.564 1044.34 423.306L1043.48 424.272C1042.8 423.684 1042 423.418 1041.2 423.418C1040.21 423.418 1039.45 423.824 1039.45 424.664C1039.45 425.42 1039.98 425.77 1041.71 426.274C1043.34 426.764 1044.58 427.45 1044.58 429.27ZM1047.83 428.808C1047.93 430.32 1048.79 430.964 1049.85 430.964C1050.56 430.964 1051.17 430.74 1051.8 430.32L1052.47 431.272C1051.78 431.832 1050.82 432.182 1049.78 432.182C1047.47 432.182 1046.21 430.614 1046.21 428.304C1046.21 426.092 1047.48 424.412 1049.58 424.412C1051.54 424.412 1052.78 425.812 1052.78 428.108C1052.78 428.36 1052.76 428.626 1052.73 428.808H1047.83ZM1049.6 425.574C1048.62 425.574 1047.92 426.26 1047.82 427.744H1051.25C1051.22 426.344 1050.65 425.574 1049.6 425.574ZM1056.23 428.808C1056.33 430.32 1057.18 430.964 1058.24 430.964C1058.96 430.964 1059.56 430.74 1060.19 430.32L1060.86 431.272C1060.18 431.832 1059.21 432.182 1058.17 432.182C1055.86 432.182 1054.6 430.614 1054.6 428.304C1054.6 426.092 1055.88 424.412 1057.98 424.412C1059.94 424.412 1061.17 425.812 1061.17 428.108C1061.17 428.36 1061.16 428.626 1061.13 428.808H1056.23ZM1057.99 425.574C1057.01 425.574 1056.31 426.26 1056.21 427.744H1059.64C1059.62 426.344 1059.04 425.574 1057.99 425.574ZM1067.66 421.458L1069.23 421.64V432H1067.84L1067.73 431.09C1067.24 431.79 1066.53 432.182 1065.66 432.182C1063.75 432.182 1062.87 430.628 1062.87 428.304C1062.87 426.05 1063.98 424.412 1065.8 424.412C1066.57 424.412 1067.18 424.692 1067.66 425.224V421.458ZM1066.2 425.616C1065.15 425.616 1064.54 426.456 1064.54 428.304C1064.54 430.194 1065.1 430.992 1066.08 430.992C1066.78 430.992 1067.3 430.516 1067.66 429.928V426.442C1067.3 425.924 1066.81 425.616 1066.2 425.616ZM1077.58 422.34V423.572H1075.48V430.754H1077.58V432H1071.76V430.754H1073.86V423.572H1071.76V422.34H1077.58ZM1080.11 432V424.608H1081.47L1081.58 425.574C1082.2 424.818 1083.08 424.412 1083.97 424.412C1085.35 424.412 1086.03 425.224 1086.03 426.61V432H1084.46V427.394C1084.46 426.106 1084.31 425.616 1083.41 425.616C1082.69 425.616 1082.07 426.134 1081.68 426.694V432H1080.11ZM1091.19 430.992C1092.17 430.992 1092.79 430.614 1092.79 429.998C1092.79 429.396 1092.55 429.116 1091.02 428.724C1089.55 428.346 1088.59 427.828 1088.59 426.54C1088.59 425.266 1089.72 424.412 1091.54 424.412C1092.79 424.412 1093.68 424.776 1094.36 425.266L1093.68 426.26C1093.11 425.882 1092.45 425.602 1091.58 425.602C1090.58 425.602 1090.18 425.924 1090.18 426.414C1090.18 426.974 1090.59 427.184 1092.06 427.59C1093.5 427.982 1094.45 428.486 1094.45 429.886C1094.45 431.496 1092.89 432.182 1091.19 432.182C1089.82 432.182 1088.84 431.734 1088.15 431.146L1088.98 430.194C1089.55 430.656 1090.32 430.992 1091.19 430.992ZM1103.07 431.608C1102.53 431.958 1101.74 432.182 1100.92 432.182C1099.19 432.182 1098.28 431.216 1098.28 429.76V425.756H1096.65V424.608H1098.28V422.956L1099.85 422.774V424.608H1102.36L1102.18 425.756H1099.85V429.746C1099.85 430.544 1100.23 430.922 1101.14 430.922C1101.67 430.922 1102.13 430.782 1102.51 430.572L1103.07 431.608ZM1110.53 424.426C1110.98 424.426 1111.31 424.496 1111.65 424.608L1111.38 427.338H1110.26V425.826C1109.21 425.854 1108.46 426.694 1108.02 428.136V430.88H1109.51V432H1105.36V430.88H1106.45V425.728H1105.36V424.608H1107.64L1107.92 426.316C1108.48 425.084 1109.25 424.426 1110.53 424.426ZM1115.26 424.608V429.774C1115.26 430.642 1115.61 430.992 1116.31 430.992C1116.99 430.992 1117.66 430.53 1118.03 429.956V424.608H1119.6V432H1118.24L1118.14 431.048C1117.59 431.79 1116.68 432.182 1115.82 432.182C1114.37 432.182 1113.69 431.356 1113.69 429.97V424.608H1115.26ZM1125.65 430.894C1126.34 430.894 1126.93 430.628 1127.47 430.264L1128.19 431.272C1127.54 431.818 1126.58 432.182 1125.6 432.182C1123.31 432.182 1122 430.656 1122 428.346C1122 426.092 1123.34 424.412 1125.62 424.412C1126.63 424.412 1127.47 424.72 1128.19 425.308L1127.46 426.288C1126.88 425.896 1126.28 425.672 1125.65 425.672C1124.48 425.672 1123.66 426.498 1123.66 428.346C1123.66 430.194 1124.5 430.894 1125.65 430.894ZM1136.65 431.608C1136.1 431.958 1135.32 432.182 1134.49 432.182C1132.77 432.182 1131.86 431.216 1131.86 429.76V425.756H1130.22V424.608H1131.86V422.956L1133.43 422.774V424.608H1135.94L1135.75 425.756H1133.43V429.746C1133.43 430.544 1133.81 430.922 1134.72 430.922C1135.25 430.922 1135.71 430.782 1136.09 430.572L1136.65 431.608ZM1141.83 420.982C1142.43 420.982 1142.85 421.416 1142.85 421.976C1142.85 422.536 1142.43 422.956 1141.83 422.956C1141.21 422.956 1140.8 422.536 1140.8 421.976C1140.8 421.416 1141.21 420.982 1141.83 420.982ZM1142.9 424.608V430.852H1144.92V432H1139.14V430.852H1141.34V425.756H1139.21V424.608H1142.9ZM1150.23 424.412C1152.39 424.412 1153.57 425.938 1153.57 428.29C1153.57 430.642 1152.36 432.182 1150.22 432.182C1148.06 432.182 1146.87 430.698 1146.87 428.304C1146.87 425.994 1148.08 424.412 1150.23 424.412ZM1150.23 425.63C1149.1 425.63 1148.53 426.47 1148.53 428.304C1148.53 430.138 1149.09 430.978 1150.22 430.978C1151.35 430.978 1151.91 430.138 1151.91 428.29C1151.91 426.47 1151.35 425.63 1150.23 425.63ZM1155.66 432V424.608H1157.02L1157.13 425.574C1157.75 424.818 1158.63 424.412 1159.52 424.412C1160.9 424.412 1161.58 425.224 1161.58 426.61V432H1160.01V427.394C1160.01 426.106 1159.86 425.616 1158.96 425.616C1158.24 425.616 1157.62 426.134 1157.23 426.694V432H1155.66Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"460\"\n                        width=\"46\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M874.645 476.824C874.645 476.082 875.233 475.48 875.989 475.48C876.759 475.48 877.347 476.082 877.347 476.824C877.347 477.58 876.759 478.182 875.989 478.182C875.233 478.182 874.645 477.58 874.645 476.824ZM880.245 476.824C880.245 476.082 880.833 475.48 881.589 475.48C882.359 475.48 882.947 476.082 882.947 476.824C882.947 477.58 882.359 478.182 881.589 478.182C880.833 478.182 880.245 477.58 880.245 476.824ZM885.845 476.824C885.845 476.082 886.433 475.48 887.189 475.48C887.959 475.48 888.547 476.082 888.547 476.824C888.547 477.58 887.959 478.182 887.189 478.182C886.433 478.182 885.845 477.58 885.845 476.824Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"92\"\n                        width=\"256\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M873.816 108.894C874.502 108.894 875.09 108.628 875.636 108.264L876.35 109.272C875.706 109.818 874.74 110.182 873.76 110.182C871.478 110.182 870.162 108.656 870.162 106.346C870.162 104.092 871.506 102.412 873.788 102.412C874.796 102.412 875.636 102.72 876.35 103.308L875.622 104.288C875.048 103.896 874.446 103.672 873.816 103.672C872.64 103.672 871.828 104.498 871.828 106.346C871.828 108.194 872.668 108.894 873.816 108.894ZM883.877 102.426C884.325 102.426 884.661 102.496 884.997 102.608L884.731 105.338H883.611V103.826C882.561 103.854 881.805 104.694 881.371 106.136V108.88H882.855V110H878.711V108.88H879.803V103.728H878.711V102.608H880.993L881.273 104.316C881.833 103.084 882.603 102.426 883.877 102.426ZM888.337 106.808C888.435 108.32 889.289 108.964 890.353 108.964C891.067 108.964 891.669 108.74 892.299 108.32L892.971 109.272C892.285 109.832 891.319 110.182 890.283 110.182C887.973 110.182 886.713 108.614 886.713 106.304C886.713 104.092 887.987 102.412 890.087 102.412C892.047 102.412 893.279 103.812 893.279 106.108C893.279 106.36 893.265 106.626 893.237 106.808H888.337ZM890.101 103.574C889.121 103.574 888.421 104.26 888.323 105.744H891.753C891.725 104.344 891.151 103.574 890.101 103.574ZM901.086 108.194C901.086 108.768 901.254 108.992 901.646 109.118L901.282 110.182C900.568 110.098 900.022 109.804 899.756 109.16C899.21 109.846 898.342 110.182 897.404 110.182C895.892 110.182 894.968 109.258 894.968 107.886C894.968 106.346 896.228 105.464 898.482 105.464H899.532V104.988C899.532 104.022 898.93 103.644 897.894 103.644C897.404 103.644 896.676 103.756 895.934 104.022L895.542 102.916C896.466 102.566 897.376 102.412 898.132 102.412C900.12 102.412 901.086 103.336 901.086 104.89V108.194ZM897.866 109.034C898.51 109.034 899.168 108.684 899.532 108.082V106.444H898.664C897.194 106.444 896.62 106.962 896.62 107.83C896.62 108.614 897.04 109.034 897.866 109.034ZM909.998 109.608C909.452 109.958 908.668 110.182 907.842 110.182C906.12 110.182 905.21 109.216 905.21 107.76V103.756H903.572V102.608H905.21V100.956L906.778 100.774V102.608H909.284L909.102 103.756H906.778V107.746C906.778 108.544 907.156 108.922 908.066 108.922C908.598 108.922 909.06 108.782 909.438 108.572L909.998 109.608ZM913.521 106.808C913.619 108.32 914.473 108.964 915.537 108.964C916.251 108.964 916.853 108.74 917.483 108.32L918.155 109.272C917.469 109.832 916.503 110.182 915.467 110.182C913.157 110.182 911.897 108.614 911.897 106.304C911.897 104.092 913.171 102.412 915.271 102.412C917.231 102.412 918.463 103.812 918.463 106.108C918.463 106.36 918.449 106.626 918.421 106.808H913.521ZM915.285 103.574C914.305 103.574 913.605 104.26 913.507 105.744H916.937C916.909 104.344 916.335 103.574 915.285 103.574ZM927.053 107.27C927.053 108.992 925.695 110.182 923.357 110.182C921.789 110.182 920.613 109.692 919.801 108.894L920.697 107.9C921.383 108.53 922.223 108.908 923.357 108.908C924.449 108.908 925.359 108.39 925.359 107.354C925.359 106.5 924.925 106.094 923.385 105.632C921.327 105.03 920.263 104.26 920.263 102.762C920.263 101.18 921.677 100.144 923.581 100.144C924.967 100.144 925.989 100.564 926.815 101.306L925.961 102.272C925.275 101.684 924.477 101.418 923.679 101.418C922.685 101.418 921.929 101.824 921.929 102.664C921.929 103.42 922.461 103.77 924.183 104.274C925.821 104.764 927.053 105.45 927.053 107.27ZM931.976 102.412C934.132 102.412 935.308 103.938 935.308 106.29C935.308 108.642 934.104 110.182 931.962 110.182C929.806 110.182 928.616 108.698 928.616 106.304C928.616 103.994 929.82 102.412 931.976 102.412ZM931.976 103.63C930.842 103.63 930.268 104.47 930.268 106.304C930.268 108.138 930.828 108.978 931.962 108.978C933.096 108.978 933.656 108.138 933.656 106.29C933.656 104.47 933.096 103.63 931.976 103.63ZM940.65 99.64V107.984C940.65 108.67 941.112 108.922 941.77 108.922C942.19 108.922 942.568 108.824 942.946 108.67L943.338 109.762C942.904 110 942.26 110.182 941.434 110.182C939.95 110.182 939.082 109.3 939.082 107.844V100.788H936.856V99.64H940.65ZM951.453 108.194C951.453 108.768 951.621 108.992 952.013 109.118L951.649 110.182C950.935 110.098 950.389 109.804 950.123 109.16C949.577 109.846 948.709 110.182 947.771 110.182C946.259 110.182 945.335 109.258 945.335 107.886C945.335 106.346 946.595 105.464 948.849 105.464H949.899V104.988C949.899 104.022 949.297 103.644 948.261 103.644C947.771 103.644 947.043 103.756 946.301 104.022L945.909 102.916C946.833 102.566 947.743 102.412 948.499 102.412C950.487 102.412 951.453 103.336 951.453 104.89V108.194ZM948.233 109.034C948.877 109.034 949.535 108.684 949.899 108.082V106.444H949.031C947.561 106.444 946.987 106.962 946.987 107.83C946.987 108.614 947.407 109.034 948.233 109.034ZM954.191 110V102.608H955.549L955.661 103.574C956.277 102.818 957.159 102.412 958.055 102.412C959.427 102.412 960.113 103.224 960.113 104.61V110H958.545V105.394C958.545 104.106 958.391 103.616 957.495 103.616C956.767 103.616 956.151 104.134 955.759 104.694V110H954.191ZM968.242 108.194C968.242 108.768 968.41 108.992 968.802 109.118L968.438 110.182C967.724 110.098 967.178 109.804 966.912 109.16C966.366 109.846 965.498 110.182 964.56 110.182C963.048 110.182 962.124 109.258 962.124 107.886C962.124 106.346 963.384 105.464 965.638 105.464H966.688V104.988C966.688 104.022 966.086 103.644 965.05 103.644C964.56 103.644 963.832 103.756 963.09 104.022L962.698 102.916C963.622 102.566 964.532 102.412 965.288 102.412C967.276 102.412 968.242 103.336 968.242 104.89V108.194ZM965.022 109.034C965.666 109.034 966.324 108.684 966.688 108.082V106.444H965.82C964.35 106.444 963.776 106.962 963.776 107.83C963.776 108.614 964.196 109.034 965.022 109.034ZM977.378 103.14C977.378 104.554 976.426 105.422 975.18 105.8L977.924 110H976.034L973.598 106.024H972.548V110H970.924V100.34H973.612C976.09 100.34 977.378 101.264 977.378 103.14ZM975.684 103.14C975.684 102.006 975.04 101.544 973.71 101.544H972.548V104.834H973.752C974.984 104.834 975.684 104.358 975.684 103.14ZM982.987 102.412C984.933 102.412 985.675 103.938 985.675 106.29C985.675 108.544 984.695 110.182 982.819 110.182C982.049 110.182 981.419 109.916 980.943 109.37V112.842L979.375 113.024V102.608H980.733L980.831 103.56C981.391 102.804 982.161 102.412 982.987 102.412ZM982.553 103.616C981.853 103.616 981.307 104.106 980.943 104.68V108.138C981.293 108.67 981.797 108.964 982.399 108.964C983.463 108.964 984.023 108.152 984.023 106.304C984.023 104.4 983.533 103.616 982.553 103.616ZM991.339 108.894C992.025 108.894 992.613 108.628 993.159 108.264L993.873 109.272C993.229 109.818 992.263 110.182 991.283 110.182C989.001 110.182 987.685 108.656 987.685 106.346C987.685 104.092 989.029 102.412 991.311 102.412C992.319 102.412 993.159 102.72 993.873 103.308L993.145 104.288C992.571 103.896 991.969 103.672 991.339 103.672C990.163 103.672 989.351 104.498 989.351 106.346C989.351 108.194 990.191 108.894 991.339 108.894ZM1002.6 107.27C1002.6 108.992 1001.25 110.182 998.908 110.182C997.34 110.182 996.164 109.692 995.352 108.894L996.248 107.9C996.934 108.53 997.774 108.908 998.908 108.908C1000 108.908 1000.91 108.39 1000.91 107.354C1000.91 106.5 1000.48 106.094 998.936 105.632C996.878 105.03 995.814 104.26 995.814 102.762C995.814 101.18 997.228 100.144 999.132 100.144C1000.52 100.144 1001.54 100.564 1002.37 101.306L1001.51 102.272C1000.83 101.684 1000.03 101.418 999.23 101.418C998.236 101.418 997.48 101.824 997.48 102.664C997.48 103.42 998.012 103.77 999.734 104.274C1001.37 104.764 1002.6 105.45 1002.6 107.27ZM1006.13 102.608V107.774C1006.13 108.642 1006.48 108.992 1007.18 108.992C1007.86 108.992 1008.53 108.53 1008.9 107.956V102.608H1010.47V110H1009.11L1009.01 109.048C1008.46 109.79 1007.55 110.182 1006.69 110.182C1005.24 110.182 1004.56 109.356 1004.56 107.97V102.608H1006.13ZM1014.52 103.49C1015.03 102.818 1015.74 102.412 1016.55 102.412C1018.5 102.412 1019.31 103.938 1019.31 106.29C1019.31 108.544 1018.27 110.182 1016.36 110.182C1015.56 110.182 1014.9 109.888 1014.42 109.272L1014.34 110H1012.95V99.64L1014.52 99.458V103.49ZM1015.98 108.992C1017.03 108.992 1017.64 108.152 1017.64 106.304C1017.64 104.4 1017.1 103.616 1016.12 103.616C1015.43 103.616 1014.89 104.106 1014.52 104.68V108.138C1014.87 108.67 1015.36 108.992 1015.98 108.992ZM1024.04 108.992C1025.02 108.992 1025.63 108.614 1025.63 107.998C1025.63 107.396 1025.39 107.116 1023.87 106.724C1022.4 106.346 1021.43 105.828 1021.43 104.54C1021.43 103.266 1022.57 102.412 1024.39 102.412C1025.63 102.412 1026.53 102.776 1027.2 103.266L1026.53 104.26C1025.95 103.882 1025.3 103.602 1024.43 103.602C1023.42 103.602 1023.03 103.924 1023.03 104.414C1023.03 104.974 1023.43 105.184 1024.9 105.59C1026.35 105.982 1027.3 106.486 1027.3 107.886C1027.3 109.496 1025.73 110.182 1024.04 110.182C1022.66 110.182 1021.68 109.734 1021 109.146L1021.82 108.194C1022.4 108.656 1023.17 108.992 1024.04 108.992ZM1033.31 108.894C1034 108.894 1034.59 108.628 1035.13 108.264L1035.85 109.272C1035.2 109.818 1034.24 110.182 1033.26 110.182C1030.97 110.182 1029.66 108.656 1029.66 106.346C1029.66 104.092 1031 102.412 1033.28 102.412C1034.29 102.412 1035.13 102.72 1035.85 103.308L1035.12 104.288C1034.54 103.896 1033.94 103.672 1033.31 103.672C1032.14 103.672 1031.32 104.498 1031.32 106.346C1031.32 108.194 1032.16 108.894 1033.31 108.894ZM1043.37 102.426C1043.82 102.426 1044.16 102.496 1044.49 102.608L1044.23 105.338H1043.11V103.826C1042.06 103.854 1041.3 104.694 1040.87 106.136V108.88H1042.35V110H1038.21V108.88H1039.3V103.728H1038.21V102.608H1040.49L1040.77 104.316C1041.33 103.084 1042.1 102.426 1043.37 102.426ZM1049.49 98.982C1050.09 98.982 1050.51 99.416 1050.51 99.976C1050.51 100.536 1050.09 100.956 1049.49 100.956C1048.87 100.956 1048.46 100.536 1048.46 99.976C1048.46 99.416 1048.87 98.982 1049.49 98.982ZM1050.56 102.608V108.852H1052.58V110H1046.8V108.852H1049V103.756H1046.87V102.608H1050.56ZM1058.54 102.412C1060.48 102.412 1061.23 103.938 1061.23 106.29C1061.23 108.544 1060.25 110.182 1058.37 110.182C1057.6 110.182 1056.97 109.916 1056.49 109.37V112.842L1054.93 113.024V102.608H1056.28L1056.38 103.56C1056.94 102.804 1057.71 102.412 1058.54 102.412ZM1058.1 103.616C1057.4 103.616 1056.86 104.106 1056.49 104.68V108.138C1056.84 108.67 1057.35 108.964 1057.95 108.964C1059.01 108.964 1059.57 108.152 1059.57 106.304C1059.57 104.4 1059.08 103.616 1058.1 103.616ZM1069.49 109.608C1068.95 109.958 1068.16 110.182 1067.34 110.182C1065.62 110.182 1064.71 109.216 1064.71 107.76V103.756H1063.07V102.608H1064.71V100.956L1066.27 100.774V102.608H1068.78L1068.6 103.756H1066.27V107.746C1066.27 108.544 1066.65 108.922 1067.56 108.922C1068.09 108.922 1068.56 108.782 1068.93 108.572L1069.49 109.608ZM1074.67 98.982C1075.27 98.982 1075.69 99.416 1075.69 99.976C1075.69 100.536 1075.27 100.956 1074.67 100.956C1074.05 100.956 1073.65 100.536 1073.65 99.976C1073.65 99.416 1074.05 98.982 1074.67 98.982ZM1075.75 102.608V108.852H1077.76V110H1071.98V108.852H1074.18V103.756H1072.05V102.608H1075.75ZM1083.08 102.412C1085.23 102.412 1086.41 103.938 1086.41 106.29C1086.41 108.642 1085.21 110.182 1083.06 110.182C1080.91 110.182 1079.72 108.698 1079.72 106.304C1079.72 103.994 1080.92 102.412 1083.08 102.412ZM1083.08 103.63C1081.94 103.63 1081.37 104.47 1081.37 106.304C1081.37 108.138 1081.93 108.978 1083.06 108.978C1084.2 108.978 1084.76 108.138 1084.76 106.29C1084.76 104.47 1084.2 103.63 1083.08 103.63ZM1088.5 110V102.608H1089.86L1089.97 103.574C1090.59 102.818 1091.47 102.412 1092.37 102.412C1093.74 102.412 1094.43 103.224 1094.43 104.61V110H1092.86V105.394C1092.86 104.106 1092.7 103.616 1091.81 103.616C1091.08 103.616 1090.46 104.134 1090.07 104.694V110H1088.5ZM1099.59 108.992C1100.57 108.992 1101.18 108.614 1101.18 107.998C1101.18 107.396 1100.94 107.116 1099.42 106.724C1097.95 106.346 1096.98 105.828 1096.98 104.54C1096.98 103.266 1098.12 102.412 1099.94 102.412C1101.18 102.412 1102.08 102.776 1102.75 103.266L1102.08 104.26C1101.5 103.882 1100.85 103.602 1099.98 103.602C1098.97 103.602 1098.58 103.924 1098.58 104.414C1098.58 104.974 1098.98 105.184 1100.45 105.59C1101.9 105.982 1102.85 106.486 1102.85 107.886C1102.85 109.496 1101.28 110.182 1099.59 110.182C1098.21 110.182 1097.23 109.734 1096.55 109.146L1097.37 108.194C1097.95 108.656 1098.72 108.992 1099.59 108.992Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"184\"\n                        width=\"289\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M872.934 200.992C873.914 200.992 874.53 200.614 874.53 199.998C874.53 199.396 874.292 199.116 872.766 198.724C871.296 198.346 870.33 197.828 870.33 196.54C870.33 195.266 871.464 194.412 873.284 194.412C874.53 194.412 875.426 194.776 876.098 195.266L875.426 196.26C874.852 195.882 874.194 195.602 873.326 195.602C872.318 195.602 871.926 195.924 871.926 196.414C871.926 196.974 872.332 197.184 873.802 197.59C875.244 197.982 876.196 198.486 876.196 199.886C876.196 201.496 874.628 202.182 872.934 202.182C871.562 202.182 870.582 201.734 869.896 201.146L870.722 200.194C871.296 200.656 872.066 200.992 872.934 200.992ZM879.943 198.808C880.041 200.32 880.895 200.964 881.959 200.964C882.673 200.964 883.275 200.74 883.905 200.32L884.577 201.272C883.891 201.832 882.925 202.182 881.889 202.182C879.579 202.182 878.319 200.614 878.319 198.304C878.319 196.092 879.593 194.412 881.693 194.412C883.653 194.412 884.885 195.812 884.885 198.108C884.885 198.36 884.871 198.626 884.843 198.808H879.943ZM881.707 195.574C880.727 195.574 880.027 196.26 879.929 197.744H883.359C883.331 196.344 882.757 195.574 881.707 195.574ZM887.035 202V194.608H888.393L888.505 195.574C889.121 194.818 890.003 194.412 890.899 194.412C892.271 194.412 892.957 195.224 892.957 196.61V202H891.389V197.394C891.389 196.106 891.235 195.616 890.339 195.616C889.611 195.616 888.995 196.134 888.603 196.694V202H887.035ZM899.77 191.458L901.338 191.64V202H899.952L899.84 201.09C899.35 201.79 898.636 202.182 897.768 202.182C895.864 202.182 894.982 200.628 894.982 198.304C894.982 196.05 896.088 194.412 897.908 194.412C898.678 194.412 899.294 194.692 899.77 195.224V191.458ZM898.314 195.616C897.264 195.616 896.648 196.456 896.648 198.304C896.648 200.194 897.208 200.992 898.188 200.992C898.888 200.992 899.406 200.516 899.77 199.928V196.442C899.406 195.924 898.916 195.616 898.314 195.616ZM908.472 199.676H905.028L904.356 202H902.69L905.77 192.34H907.786L910.866 202H909.144L908.472 199.676ZM905.364 198.416H908.136L906.75 193.6L905.364 198.416ZM912.219 202V194.608H913.577L913.689 195.574C914.305 194.818 915.187 194.412 916.083 194.412C917.455 194.412 918.141 195.224 918.141 196.61V202H916.573V197.394C916.573 196.106 916.419 195.616 915.523 195.616C914.795 195.616 914.179 196.134 913.787 196.694V202H912.219ZM924.953 191.458L926.521 191.64V202H925.135L925.023 201.09C924.533 201.79 923.819 202.182 922.951 202.182C921.047 202.182 920.165 200.628 920.165 198.304C920.165 196.05 921.271 194.412 923.091 194.412C923.861 194.412 924.477 194.692 924.953 195.224V191.458ZM923.497 195.616C922.447 195.616 921.831 196.456 921.831 198.304C921.831 200.194 922.391 200.992 923.371 200.992C924.071 200.992 924.589 200.516 924.953 199.928V196.442C924.589 195.924 924.099 195.616 923.497 195.616ZM932.774 192.144C934.09 192.144 934.902 192.494 935.686 193.124L934.846 194.132C934.258 193.656 933.6 193.418 932.844 193.418C931.402 193.418 930.184 194.426 930.184 197.156C930.184 199.83 931.332 200.866 932.858 200.866C933.894 200.866 934.51 200.46 935.042 200.04L935.826 201.034C935.182 201.664 934.216 202.182 932.802 202.182C930.338 202.182 928.49 200.432 928.49 197.156C928.49 193.908 930.422 192.144 932.774 192.144ZM940.37 194.412C942.526 194.412 943.702 195.938 943.702 198.29C943.702 200.642 942.498 202.182 940.356 202.182C938.2 202.182 937.01 200.698 937.01 198.304C937.01 195.994 938.214 194.412 940.37 194.412ZM940.37 195.63C939.236 195.63 938.662 196.47 938.662 198.304C938.662 200.138 939.222 200.978 940.356 200.978C941.49 200.978 942.05 200.138 942.05 198.29C942.05 196.47 941.49 195.63 940.37 195.63ZM945.797 202V194.608H947.155L947.267 195.574C947.883 194.818 948.765 194.412 949.661 194.412C951.033 194.412 951.719 195.224 951.719 196.61V202H950.151V197.394C950.151 196.106 949.997 195.616 949.101 195.616C948.373 195.616 947.757 196.134 947.365 196.694V202H945.797ZM958.685 191.458C959.595 191.458 960.281 191.626 960.897 191.892L960.421 192.984C959.931 192.774 959.385 192.676 958.839 192.676C957.873 192.676 957.411 193.04 957.411 193.824V195.14H959.889L959.707 196.302H957.411V202H955.843V196.302H954.163V195.14H955.843V193.81C955.843 192.41 956.977 191.458 958.685 191.458ZM965.54 190.982C966.142 190.982 966.562 191.416 966.562 191.976C966.562 192.536 966.142 192.956 965.54 192.956C964.924 192.956 964.518 192.536 964.518 191.976C964.518 191.416 964.924 190.982 965.54 190.982ZM966.618 194.608V200.852H968.634V202H962.852V200.852H965.05V195.756H962.922V194.608H966.618ZM976.216 194.426C976.664 194.426 977 194.496 977.336 194.608L977.07 197.338H975.95V195.826C974.9 195.854 974.144 196.694 973.71 198.136V200.88H975.194V202H971.05V200.88H972.142V195.728H971.05V194.608H973.332L973.612 196.316C974.172 195.084 974.942 194.426 976.216 194.426ZM984.471 194.412C985.311 194.412 985.941 194.874 985.941 196.512V202H984.555V196.722C984.555 195.952 984.499 195.63 984.065 195.63C983.701 195.63 983.337 195.84 982.973 196.372V202H981.699V196.722C981.699 195.952 981.643 195.63 981.209 195.63C980.831 195.63 980.481 195.84 980.117 196.372V202H978.717V194.608H979.893L980.005 195.406C980.425 194.818 980.873 194.412 981.587 194.412C982.147 194.412 982.637 194.65 982.847 195.35C983.267 194.79 983.757 194.412 984.471 194.412ZM991.521 193.656V202H989.897V193.656H986.985V192.34H994.475L994.307 193.656H991.521ZM1001.4 194.426C1001.85 194.426 1002.18 194.496 1002.52 194.608L1002.25 197.338H1001.13V195.826C1000.08 195.854 999.328 196.694 998.894 198.136V200.88H1000.38V202H996.234V200.88H997.326V195.728H996.234V194.608H998.516L998.796 196.316C999.356 195.084 1000.13 194.426 1001.4 194.426ZM1010.21 200.194C1010.21 200.768 1010.38 200.992 1010.77 201.118L1010.41 202.182C1009.7 202.098 1009.15 201.804 1008.88 201.16C1008.34 201.846 1007.47 202.182 1006.53 202.182C1005.02 202.182 1004.1 201.258 1004.1 199.886C1004.1 198.346 1005.36 197.464 1007.61 197.464H1008.66V196.988C1008.66 196.022 1008.06 195.644 1007.02 195.644C1006.53 195.644 1005.8 195.756 1005.06 196.022L1004.67 194.916C1005.59 194.566 1006.5 194.412 1007.26 194.412C1009.25 194.412 1010.21 195.336 1010.21 196.89V200.194ZM1006.99 201.034C1007.64 201.034 1008.3 200.684 1008.66 200.082V198.444H1007.79C1006.32 198.444 1005.75 198.962 1005.75 199.83C1005.75 200.614 1006.17 201.034 1006.99 201.034ZM1012.95 202V194.608H1014.31L1014.42 195.574C1015.04 194.818 1015.92 194.412 1016.82 194.412C1018.19 194.412 1018.88 195.224 1018.88 196.61V202H1017.31V197.394C1017.31 196.106 1017.15 195.616 1016.26 195.616C1015.53 195.616 1014.91 196.134 1014.52 196.694V202H1012.95ZM1024.04 200.992C1025.02 200.992 1025.63 200.614 1025.63 199.998C1025.63 199.396 1025.39 199.116 1023.87 198.724C1022.4 198.346 1021.43 197.828 1021.43 196.54C1021.43 195.266 1022.57 194.412 1024.39 194.412C1025.63 194.412 1026.53 194.776 1027.2 195.266L1026.53 196.26C1025.95 195.882 1025.3 195.602 1024.43 195.602C1023.42 195.602 1023.03 195.924 1023.03 196.414C1023.03 196.974 1023.43 197.184 1024.9 197.59C1026.35 197.982 1027.3 198.486 1027.3 199.886C1027.3 201.496 1025.73 202.182 1024.04 202.182C1022.66 202.182 1021.68 201.734 1021 201.146L1021.82 200.194C1022.4 200.656 1023.17 200.992 1024.04 200.992ZM1035.4 200.194C1035.4 200.768 1035.57 200.992 1035.96 201.118L1035.59 202.182C1034.88 202.098 1034.33 201.804 1034.07 201.16C1033.52 201.846 1032.65 202.182 1031.72 202.182C1030.2 202.182 1029.28 201.258 1029.28 199.886C1029.28 198.346 1030.54 197.464 1032.79 197.464H1033.84V196.988C1033.84 196.022 1033.24 195.644 1032.21 195.644C1031.72 195.644 1030.99 195.756 1030.25 196.022L1029.85 194.916C1030.78 194.566 1031.69 194.412 1032.44 194.412C1034.43 194.412 1035.4 195.336 1035.4 196.89V200.194ZM1032.18 201.034C1032.82 201.034 1033.48 200.684 1033.84 200.082V198.444H1032.98C1031.51 198.444 1030.93 198.962 1030.93 199.83C1030.93 200.614 1031.35 201.034 1032.18 201.034ZM1041.71 200.894C1042.39 200.894 1042.98 200.628 1043.53 200.264L1044.24 201.272C1043.6 201.818 1042.63 202.182 1041.65 202.182C1039.37 202.182 1038.05 200.656 1038.05 198.346C1038.05 196.092 1039.4 194.412 1041.68 194.412C1042.69 194.412 1043.53 194.72 1044.24 195.308L1043.51 196.288C1042.94 195.896 1042.34 195.672 1041.71 195.672C1040.53 195.672 1039.72 196.498 1039.72 198.346C1039.72 200.194 1040.56 200.894 1041.71 200.894ZM1052.71 201.608C1052.16 201.958 1051.38 202.182 1050.55 202.182C1048.83 202.182 1047.92 201.216 1047.92 199.76V195.756H1046.28V194.608H1047.92V192.956L1049.49 192.774V194.608H1051.99L1051.81 195.756H1049.49V199.746C1049.49 200.544 1049.86 200.922 1050.77 200.922C1051.31 200.922 1051.77 200.782 1052.15 200.572L1052.71 201.608ZM1057.88 190.982C1058.48 190.982 1058.9 191.416 1058.9 191.976C1058.9 192.536 1058.48 192.956 1057.88 192.956C1057.26 192.956 1056.86 192.536 1056.86 191.976C1056.86 191.416 1057.26 190.982 1057.88 190.982ZM1058.96 194.608V200.852H1060.97V202H1055.19V200.852H1057.39V195.756H1055.26V194.608H1058.96ZM1066.29 194.412C1068.44 194.412 1069.62 195.938 1069.62 198.29C1069.62 200.642 1068.42 202.182 1066.27 202.182C1064.12 202.182 1062.93 200.698 1062.93 198.304C1062.93 195.994 1064.13 194.412 1066.29 194.412ZM1066.29 195.63C1065.15 195.63 1064.58 196.47 1064.58 198.304C1064.58 200.138 1065.14 200.978 1066.27 200.978C1067.41 200.978 1067.97 200.138 1067.97 198.29C1067.97 196.47 1067.41 195.63 1066.29 195.63ZM1071.71 202V194.608H1073.07L1073.18 195.574C1073.8 194.818 1074.68 194.412 1075.58 194.412C1076.95 194.412 1077.64 195.224 1077.64 196.61V202H1076.07V197.394C1076.07 196.106 1075.91 195.616 1075.02 195.616C1074.29 195.616 1073.67 196.134 1073.28 196.694V202H1071.71ZM1082.27 193.572V196.652H1085.91V197.884H1082.27V202H1080.64V192.34H1086.58L1086.41 193.572H1082.27ZM1094.16 200.194C1094.16 200.768 1094.33 200.992 1094.72 201.118L1094.36 202.182C1093.64 202.098 1093.1 201.804 1092.83 201.16C1092.28 201.846 1091.42 202.182 1090.48 202.182C1088.97 202.182 1088.04 201.258 1088.04 199.886C1088.04 198.346 1089.3 197.464 1091.56 197.464H1092.61V196.988C1092.61 196.022 1092 195.644 1090.97 195.644C1090.48 195.644 1089.75 195.756 1089.01 196.022L1088.62 194.916C1089.54 194.566 1090.45 194.412 1091.21 194.412C1093.19 194.412 1094.16 195.336 1094.16 196.89V200.194ZM1090.94 201.034C1091.58 201.034 1092.24 200.684 1092.61 200.082V198.444H1091.74C1090.27 198.444 1089.69 198.962 1089.69 199.83C1089.69 200.614 1090.11 201.034 1090.94 201.034ZM1100.47 200.894C1101.15 200.894 1101.74 200.628 1102.29 200.264L1103 201.272C1102.36 201.818 1101.39 202.182 1100.41 202.182C1098.13 202.182 1096.81 200.656 1096.81 198.346C1096.81 196.092 1098.16 194.412 1100.44 194.412C1101.45 194.412 1102.29 194.72 1103 195.308L1102.27 196.288C1101.7 195.896 1101.1 195.672 1100.47 195.672C1099.29 195.672 1098.48 196.498 1098.48 198.346C1098.48 200.194 1099.32 200.894 1100.47 200.894ZM1111.47 201.608C1110.92 201.958 1110.14 202.182 1109.31 202.182C1107.59 202.182 1106.68 201.216 1106.68 199.76V195.756H1105.04V194.608H1106.68V192.956L1108.25 192.774V194.608H1110.75L1110.57 195.756H1108.25V199.746C1108.25 200.544 1108.62 200.922 1109.53 200.922C1110.07 200.922 1110.53 200.782 1110.91 200.572L1111.47 201.608ZM1116.66 194.412C1118.81 194.412 1119.99 195.938 1119.99 198.29C1119.99 200.642 1118.78 202.182 1116.64 202.182C1114.49 202.182 1113.3 200.698 1113.3 198.304C1113.3 195.994 1114.5 194.412 1116.66 194.412ZM1116.66 195.63C1115.52 195.63 1114.95 196.47 1114.95 198.304C1114.95 200.138 1115.51 200.978 1116.64 200.978C1117.78 200.978 1118.34 200.138 1118.34 198.29C1118.34 196.47 1117.78 195.63 1116.66 195.63ZM1127.32 194.426C1127.77 194.426 1128.1 194.496 1128.44 194.608L1128.17 197.338H1127.05V195.826C1126 195.854 1125.25 196.694 1124.81 198.136V200.88H1126.3V202H1122.15V200.88H1123.24V195.728H1122.15V194.608H1124.43L1124.71 196.316C1125.27 195.084 1126.04 194.426 1127.32 194.426ZM1136.94 194.608L1134.4 202.028C1133.84 203.708 1132.84 204.842 1130.77 205.024L1130.57 203.848C1132.07 203.61 1132.55 203.064 1132.94 202H1132.41L1129.92 194.608H1131.58L1133.44 200.908L1135.33 194.608H1136.94Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"230\"\n                        width=\"46\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M874.645 246.824C874.645 246.082 875.233 245.48 875.989 245.48C876.759 245.48 877.347 246.082 877.347 246.824C877.347 247.58 876.759 248.182 875.989 248.182C875.233 248.182 874.645 247.58 874.645 246.824ZM880.245 246.824C880.245 246.082 880.833 245.48 881.589 245.48C882.359 245.48 882.947 246.082 882.947 246.824C882.947 247.58 882.359 248.182 881.589 248.182C880.833 248.182 880.245 247.58 880.245 246.824ZM885.845 246.824C885.845 246.082 886.433 245.48 887.189 245.48C887.959 245.48 888.547 246.082 888.547 246.824C888.547 247.58 887.959 248.182 887.189 248.182C886.433 248.182 885.845 247.58 885.845 246.824Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"859\"\n                        y=\"138\"\n                        width=\"146\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M872.934 154.992C873.914 154.992 874.53 154.614 874.53 153.998C874.53 153.396 874.292 153.116 872.766 152.724C871.296 152.346 870.33 151.828 870.33 150.54C870.33 149.266 871.464 148.412 873.284 148.412C874.53 148.412 875.426 148.776 876.098 149.266L875.426 150.26C874.852 149.882 874.194 149.602 873.326 149.602C872.318 149.602 871.926 149.924 871.926 150.414C871.926 150.974 872.332 151.184 873.802 151.59C875.244 151.982 876.196 152.486 876.196 153.886C876.196 155.496 874.628 156.182 872.934 156.182C871.562 156.182 870.582 155.734 869.896 155.146L870.722 154.194C871.296 154.656 872.066 154.992 872.934 154.992ZM881.595 144.982C882.197 144.982 882.617 145.416 882.617 145.976C882.617 146.536 882.197 146.956 881.595 146.956C880.979 146.956 880.573 146.536 880.573 145.976C880.573 145.416 880.979 144.982 881.595 144.982ZM882.673 148.608V154.852H884.689V156H878.907V154.852H881.105V149.756H878.977V148.608H882.673ZM893.265 147.67L893.671 148.972C893.097 149.168 892.397 149.21 891.529 149.21C892.411 149.616 892.873 150.204 892.873 151.1C892.873 152.542 891.767 153.592 889.947 153.592C889.527 153.592 889.233 153.564 888.939 153.466C888.743 153.606 888.617 153.844 888.617 154.082C888.617 154.376 888.785 154.642 889.527 154.642H890.815C892.397 154.642 893.517 155.51 893.517 156.7C893.517 158.17 892.215 159.024 889.821 159.024C887.273 159.024 886.531 158.226 886.531 156.728H887.931C887.931 157.512 888.281 157.876 889.835 157.876C891.375 157.876 891.935 157.484 891.935 156.798C891.935 156.196 891.375 155.86 890.507 155.86H889.233C887.833 155.86 887.217 155.202 887.217 154.432C887.217 153.942 887.497 153.452 888.029 153.102C887.147 152.64 886.769 151.996 886.769 151.03C886.769 149.476 888.029 148.412 889.849 148.412C891.627 148.426 892.383 148.104 893.265 147.67ZM889.863 149.504C888.855 149.504 888.365 150.12 888.365 151.03C888.365 151.954 888.869 152.57 889.877 152.57C890.815 152.57 891.305 152.01 891.305 151.002C891.305 150.008 890.829 149.504 889.863 149.504ZM895.43 156V148.608H896.788L896.9 149.574C897.516 148.818 898.398 148.412 899.294 148.412C900.666 148.412 901.352 149.224 901.352 150.61V156H899.784V151.394C899.784 150.106 899.63 149.616 898.734 149.616C898.006 149.616 897.39 150.134 896.998 150.694V156H895.43ZM907.576 147.656V156H905.952V147.656H903.04V146.34H910.53L910.362 147.656H907.576ZM917.455 148.426C917.903 148.426 918.239 148.496 918.575 148.608L918.309 151.338H917.189V149.826C916.139 149.854 915.383 150.694 914.949 152.136V154.88H916.433V156H912.289V154.88H913.381V149.728H912.289V148.608H914.571L914.851 150.316C915.411 149.084 916.181 148.426 917.455 148.426ZM926.269 154.194C926.269 154.768 926.437 154.992 926.829 155.118L926.465 156.182C925.751 156.098 925.205 155.804 924.939 155.16C924.393 155.846 923.525 156.182 922.587 156.182C921.075 156.182 920.151 155.258 920.151 153.886C920.151 152.346 921.411 151.464 923.665 151.464H924.715V150.988C924.715 150.022 924.113 149.644 923.077 149.644C922.587 149.644 921.859 149.756 921.117 150.022L920.725 148.916C921.649 148.566 922.559 148.412 923.315 148.412C925.303 148.412 926.269 149.336 926.269 150.89V154.194ZM923.049 155.034C923.693 155.034 924.351 154.684 924.715 154.082V152.444H923.847C922.377 152.444 921.803 152.962 921.803 153.83C921.803 154.614 922.223 155.034 923.049 155.034ZM929.008 156V148.608H930.366L930.478 149.574C931.094 148.818 931.976 148.412 932.872 148.412C934.244 148.412 934.93 149.224 934.93 150.61V156H933.362V151.394C933.362 150.106 933.208 149.616 932.312 149.616C931.584 149.616 930.968 150.134 930.576 150.694V156H929.008ZM940.09 154.992C941.07 154.992 941.686 154.614 941.686 153.998C941.686 153.396 941.448 153.116 939.922 152.724C938.452 152.346 937.486 151.828 937.486 150.54C937.486 149.266 938.62 148.412 940.44 148.412C941.686 148.412 942.582 148.776 943.254 149.266L942.582 150.26C942.008 149.882 941.35 149.602 940.482 149.602C939.474 149.602 939.082 149.924 939.082 150.414C939.082 150.974 939.488 151.184 940.958 151.59C942.4 151.982 943.352 152.486 943.352 153.886C943.352 155.496 941.784 156.182 940.09 156.182C938.718 156.182 937.738 155.734 937.052 155.146L937.878 154.194C938.452 154.656 939.222 154.992 940.09 154.992ZM951.453 154.194C951.453 154.768 951.621 154.992 952.013 155.118L951.649 156.182C950.935 156.098 950.389 155.804 950.123 155.16C949.577 155.846 948.709 156.182 947.771 156.182C946.259 156.182 945.335 155.258 945.335 153.886C945.335 152.346 946.595 151.464 948.849 151.464H949.899V150.988C949.899 150.022 949.297 149.644 948.261 149.644C947.771 149.644 947.043 149.756 946.301 150.022L945.909 148.916C946.833 148.566 947.743 148.412 948.499 148.412C950.487 148.412 951.453 149.336 951.453 150.89V154.194ZM948.233 155.034C948.877 155.034 949.535 154.684 949.899 154.082V152.444H949.031C947.561 152.444 946.987 152.962 946.987 153.83C946.987 154.614 947.407 155.034 948.233 155.034ZM957.761 154.894C958.447 154.894 959.035 154.628 959.581 154.264L960.295 155.272C959.651 155.818 958.685 156.182 957.705 156.182C955.423 156.182 954.107 154.656 954.107 152.346C954.107 150.092 955.451 148.412 957.733 148.412C958.741 148.412 959.581 148.72 960.295 149.308L959.567 150.288C958.993 149.896 958.391 149.672 957.761 149.672C956.585 149.672 955.773 150.498 955.773 152.346C955.773 154.194 956.613 154.894 957.761 154.894ZM968.76 155.608C968.214 155.958 967.43 156.182 966.604 156.182C964.882 156.182 963.972 155.216 963.972 153.76V149.756H962.334V148.608H963.972V146.956L965.54 146.774V148.608H968.046L967.864 149.756H965.54V153.746C965.54 154.544 965.918 154.922 966.828 154.922C967.36 154.922 967.822 154.782 968.2 154.572L968.76 155.608ZM973.934 144.982C974.536 144.982 974.956 145.416 974.956 145.976C974.956 146.536 974.536 146.956 973.934 146.956C973.318 146.956 972.912 146.536 972.912 145.976C972.912 145.416 973.318 144.982 973.934 144.982ZM975.012 148.608V154.852H977.028V156H971.246V154.852H973.444V149.756H971.316V148.608H975.012ZM982.343 148.412C984.499 148.412 985.675 149.938 985.675 152.29C985.675 154.642 984.471 156.182 982.329 156.182C980.173 156.182 978.983 154.698 978.983 152.304C978.983 149.994 980.187 148.412 982.343 148.412ZM982.343 149.63C981.209 149.63 980.635 150.47 980.635 152.304C980.635 154.138 981.195 154.978 982.329 154.978C983.463 154.978 984.023 154.138 984.023 152.29C984.023 150.47 983.463 149.63 982.343 149.63ZM987.769 156V148.608H989.127L989.239 149.574C989.855 148.818 990.737 148.412 991.633 148.412C993.005 148.412 993.691 149.224 993.691 150.61V156H992.123V151.394C992.123 150.106 991.969 149.616 991.073 149.616C990.345 149.616 989.729 150.134 989.337 150.694V156H987.769Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"853\"\n                        y=\"40\"\n                        width=\"158\"\n                        height=\"38\"\n                        rx=\"11\"\n                        stroke=\"#D8582B\"\n                        strokeWidth=\"2\"\n                        strokeDasharray=\"6 6\"\n                    />\n                    <rect\n                        x=\"853\"\n                        y=\"362\"\n                        width=\"259\"\n                        height=\"38\"\n                        rx=\"11\"\n                        stroke=\"#D8582B\"\n                        strokeWidth=\"2\"\n                        strokeDasharray=\"6 6\"\n                    />\n                    <line\n                        x1=\"153\"\n                        y1=\"151\"\n                        x2=\"252\"\n                        y2=\"151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M252 59L212 59C206.477 59 202 63.4772 202 69L202 141C202 146.523 197.523 151 192 151L152 151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M252 105L212 105C206.477 105 202 109.477 202 115L202 141C202 146.523 197.523 151 192 151L152 151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M252 243L212 243C206.477 243 202 238.523 202 233L202 161C202 155.477 197.523 151 192 151L152 151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M252 197L212 197C206.477 197 202 192.523 202 187L202 161C202 155.477 197.523 151 192 151L152 151\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <line\n                        x1=\"153\"\n                        y1=\"381\"\n                        x2=\"252\"\n                        y2=\"381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M252 289L212 289C206.477 289 202 293.477 202 299L202 371C202 376.523 197.523 381 192 381L152 381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M252 335L212 335C206.477 335 202 339.477 202 345L202 371C202 376.523 197.523 381 192 381L152 381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M252 473L212 473C206.477 473 202 468.523 202 463L202 391C202 385.477 197.523 381 192 381L152 381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <path\n                        d=\"M252 427L212 427C206.477 427 202 422.523 202 417L202 391C202 385.477 197.523 381 192 381L152 381\"\n                        className=\"stroke-linen-300 dark:stroke-linen-700\"\n                        strokeWidth=\"2\"\n                        strokeLinecap=\"round\"\n                        strokeLinejoin=\"round\"\n                    />\n                    <rect\n                        x=\"48\"\n                        y=\"138\"\n                        width=\"104\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-coral-400 dark:fill-coral-500\"\n                    />\n                    <path\n                        d=\"M63.012 146.144C64.328 146.144 65.14 146.494 65.924 147.124L65.084 148.132C64.496 147.656 63.838 147.418 63.082 147.418C61.64 147.418 60.422 148.426 60.422 151.156C60.422 153.83 61.57 154.866 63.096 154.866C64.132 154.866 64.748 154.46 65.28 154.04L66.064 155.034C65.42 155.664 64.454 156.182 63.04 156.182C60.576 156.182 58.728 154.432 58.728 151.156C58.728 147.908 60.66 146.144 63.012 146.144ZM70.6085 148.412C72.7645 148.412 73.9405 149.938 73.9405 152.29C73.9405 154.642 72.7365 156.182 70.5945 156.182C68.4385 156.182 67.2485 154.698 67.2485 152.304C67.2485 149.994 68.4525 148.412 70.6085 148.412ZM70.6085 149.63C69.4745 149.63 68.9005 150.47 68.9005 152.304C68.9005 154.138 69.4605 154.978 70.5945 154.978C71.7285 154.978 72.2885 154.138 72.2885 152.29C72.2885 150.47 71.7285 149.63 70.6085 149.63ZM76.0351 156V148.608H77.3931L77.5051 149.574C78.1211 148.818 79.0031 148.412 79.8991 148.412C81.2711 148.412 81.9571 149.224 81.9571 150.61V156H80.3891V151.394C80.3891 150.106 80.2351 149.616 79.3391 149.616C78.6111 149.616 77.9951 150.134 77.6031 150.694V156H76.0351ZM84.4296 156V148.608H85.7876L85.8996 149.574C86.5156 148.818 87.3976 148.412 88.2936 148.412C89.6656 148.412 90.3516 149.224 90.3516 150.61V156H88.7836V151.394C88.7836 150.106 88.6296 149.616 87.7336 149.616C87.0056 149.616 86.3896 150.134 85.9976 150.694V156H84.4296ZM94.1261 152.808C94.2241 154.32 95.0781 154.964 96.1421 154.964C96.8561 154.964 97.4581 154.74 98.0881 154.32L98.7601 155.272C98.0741 155.832 97.1081 156.182 96.0721 156.182C93.7621 156.182 92.5021 154.614 92.5021 152.304C92.5021 150.092 93.7761 148.412 95.8761 148.412C97.8361 148.412 99.0681 149.812 99.0681 152.108C99.0681 152.36 99.0541 152.626 99.0261 152.808H94.1261ZM95.8901 149.574C94.9101 149.574 94.2101 150.26 94.1121 151.744H97.5421C97.5141 150.344 96.9401 149.574 95.8901 149.574ZM104.789 154.894C105.475 154.894 106.063 154.628 106.609 154.264L107.323 155.272C106.679 155.818 105.713 156.182 104.733 156.182C102.451 156.182 101.135 154.656 101.135 152.346C101.135 150.092 102.479 148.412 104.761 148.412C105.769 148.412 106.609 148.72 107.323 149.308L106.595 150.288C106.021 149.896 105.419 149.672 104.789 149.672C103.613 149.672 102.801 150.498 102.801 152.346C102.801 154.194 103.641 154.894 104.789 154.894ZM115.787 155.608C115.241 155.958 114.457 156.182 113.631 156.182C111.909 156.182 110.999 155.216 110.999 153.76V149.756H109.361V148.608H110.999V146.956L112.567 146.774V148.608H115.073L114.891 149.756H112.567V153.746C112.567 154.544 112.945 154.922 113.855 154.922C114.387 154.922 114.849 154.782 115.227 154.572L115.787 155.608ZM120.962 144.982C121.564 144.982 121.984 145.416 121.984 145.976C121.984 146.536 121.564 146.956 120.962 146.956C120.346 146.956 119.94 146.536 119.94 145.976C119.94 145.416 120.346 144.982 120.962 144.982ZM122.04 148.608V154.852H124.056V156H118.274V154.852H120.472V149.756H118.344V148.608H122.04ZM129.37 148.412C131.526 148.412 132.702 149.938 132.702 152.29C132.702 154.642 131.498 156.182 129.356 156.182C127.2 156.182 126.01 154.698 126.01 152.304C126.01 149.994 127.214 148.412 129.37 148.412ZM129.37 149.63C128.236 149.63 127.662 150.47 127.662 152.304C127.662 154.138 128.222 154.978 129.356 154.978C130.49 154.978 131.05 154.138 131.05 152.29C131.05 150.47 130.49 149.63 129.37 149.63ZM134.797 156V148.608H136.155L136.267 149.574C136.883 148.818 137.765 148.412 138.661 148.412C140.033 148.412 140.719 149.224 140.719 150.61V156H139.151V151.394C139.151 150.106 138.997 149.616 138.101 149.616C137.373 149.616 136.757 150.134 136.365 150.694V156H134.797Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"22\"\n                        y=\"368\"\n                        width=\"130\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-coral-400 dark:fill-coral-500\"\n                    />\n                    <path\n                        d=\"M39.686 383.27C39.686 384.992 38.328 386.182 35.99 386.182C34.422 386.182 33.246 385.692 32.434 384.894L33.33 383.9C34.016 384.53 34.856 384.908 35.99 384.908C37.082 384.908 37.992 384.39 37.992 383.354C37.992 382.5 37.558 382.094 36.018 381.632C33.96 381.03 32.896 380.26 32.896 378.762C32.896 377.18 34.31 376.144 36.214 376.144C37.6 376.144 38.622 376.564 39.448 377.306L38.594 378.272C37.908 377.684 37.11 377.418 36.312 377.418C35.318 377.418 34.562 377.824 34.562 378.664C34.562 379.42 35.094 379.77 36.816 380.274C38.454 380.764 39.686 381.45 39.686 383.27ZM48.1085 378.608L45.5605 386.028C45.0005 387.708 44.0065 388.842 41.9345 389.024L41.7385 387.848C43.2365 387.61 43.7125 387.064 44.1045 386H43.5725L41.0805 378.608H42.7465L44.6085 384.908L46.4985 378.608H48.1085ZM52.7231 384.992C53.7031 384.992 54.3191 384.614 54.3191 383.998C54.3191 383.396 54.0811 383.116 52.5551 382.724C51.0851 382.346 50.1191 381.828 50.1191 380.54C50.1191 379.266 51.2531 378.412 53.0731 378.412C54.3191 378.412 55.2151 378.776 55.8871 379.266L55.2151 380.26C54.6411 379.882 53.9831 379.602 53.1151 379.602C52.1071 379.602 51.7151 379.924 51.7151 380.414C51.7151 380.974 52.1211 381.184 53.5911 381.59C55.0331 381.982 55.9851 382.486 55.9851 383.886C55.9851 385.496 54.4171 386.182 52.7231 386.182C51.3511 386.182 50.3711 385.734 49.6851 385.146L50.5111 384.194C51.0851 384.656 51.8551 384.992 52.7231 384.992ZM64.6036 385.608C64.0576 385.958 63.2736 386.182 62.4476 386.182C60.7256 386.182 59.8156 385.216 59.8156 383.76V379.756H58.1776V378.608H59.8156V376.956L61.3836 376.774V378.608H63.8896L63.7076 379.756H61.3836V383.746C61.3836 384.544 61.7616 384.922 62.6716 384.922C63.2036 384.922 63.6656 384.782 64.0436 384.572L64.6036 385.608ZM68.1261 382.808C68.2241 384.32 69.0781 384.964 70.1421 384.964C70.8561 384.964 71.4581 384.74 72.0881 384.32L72.7601 385.272C72.0741 385.832 71.1081 386.182 70.0721 386.182C67.7621 386.182 66.5021 384.614 66.5021 382.304C66.5021 380.092 67.7761 378.412 69.8761 378.412C71.8361 378.412 73.0681 379.812 73.0681 382.108C73.0681 382.36 73.0541 382.626 73.0261 382.808H68.1261ZM69.8901 379.574C68.9101 379.574 68.2101 380.26 68.1121 381.744H71.5421C71.5141 380.344 70.9401 379.574 69.8901 379.574ZM80.3147 378.412C81.1547 378.412 81.7847 378.874 81.7847 380.512V386H80.3987V380.722C80.3987 379.952 80.3427 379.63 79.9087 379.63C79.5447 379.63 79.1807 379.84 78.8167 380.372V386H77.5427V380.722C77.5427 379.952 77.4867 379.63 77.0527 379.63C76.6747 379.63 76.3247 379.84 75.9607 380.372V386H74.5607V378.608H75.7367L75.8487 379.406C76.2687 378.818 76.7167 378.412 77.4307 378.412C77.9907 378.412 78.4807 378.65 78.6907 379.35C79.1107 378.79 79.6007 378.412 80.3147 378.412ZM90.2632 379.378C90.2632 381.632 88.7092 382.556 86.4972 382.556H85.3212V386H83.7112V376.34H86.3852C88.8212 376.34 90.2632 377.32 90.2632 379.378ZM88.5692 379.378C88.5692 378.062 87.7432 377.558 86.4972 377.558H85.3212V381.324H86.5112C87.7292 381.324 88.5692 380.848 88.5692 379.378ZM97.2437 378.426C97.6917 378.426 98.0277 378.496 98.3637 378.608L98.0977 381.338H96.9777V379.826C95.9277 379.854 95.1717 380.694 94.7377 382.136V384.88H96.2217V386H92.0777V384.88H93.1697V379.728H92.0777V378.608H94.3597L94.6397 380.316C95.1997 379.084 95.9697 378.426 97.2437 378.426ZM103.37 378.412C105.526 378.412 106.702 379.938 106.702 382.29C106.702 384.642 105.498 386.182 103.356 386.182C101.2 386.182 100.01 384.698 100.01 382.304C100.01 379.994 101.214 378.412 103.37 378.412ZM103.37 379.63C102.236 379.63 101.662 380.47 101.662 382.304C101.662 384.138 102.222 384.978 103.356 384.978C104.49 384.978 105.05 384.138 105.05 382.29C105.05 380.47 104.49 379.63 103.37 379.63ZM115.027 377.67L115.433 378.972C114.859 379.168 114.159 379.21 113.291 379.21C114.173 379.616 114.635 380.204 114.635 381.1C114.635 382.542 113.529 383.592 111.709 383.592C111.289 383.592 110.995 383.564 110.701 383.466C110.505 383.606 110.379 383.844 110.379 384.082C110.379 384.376 110.547 384.642 111.289 384.642H112.577C114.159 384.642 115.279 385.51 115.279 386.7C115.279 388.17 113.977 389.024 111.583 389.024C109.035 389.024 108.293 388.226 108.293 386.728H109.693C109.693 387.512 110.043 387.876 111.597 387.876C113.137 387.876 113.697 387.484 113.697 386.798C113.697 386.196 113.137 385.86 112.269 385.86H110.995C109.595 385.86 108.979 385.202 108.979 384.432C108.979 383.942 109.259 383.452 109.791 383.102C108.909 382.64 108.531 381.996 108.531 381.03C108.531 379.476 109.791 378.412 111.611 378.412C113.389 378.426 114.145 378.104 115.027 377.67ZM111.625 379.504C110.617 379.504 110.127 380.12 110.127 381.03C110.127 381.954 110.631 382.57 111.639 382.57C112.577 382.57 113.067 382.01 113.067 381.002C113.067 380.008 112.591 379.504 111.625 379.504ZM122.427 378.426C122.875 378.426 123.211 378.496 123.547 378.608L123.281 381.338H122.161V379.826C121.111 379.854 120.355 380.694 119.921 382.136V384.88H121.405V386H117.261V384.88H118.353V379.728H117.261V378.608H119.543L119.823 380.316C120.383 379.084 121.153 378.426 122.427 378.426ZM131.242 384.194C131.242 384.768 131.41 384.992 131.802 385.118L131.438 386.182C130.724 386.098 130.178 385.804 129.912 385.16C129.366 385.846 128.498 386.182 127.56 386.182C126.048 386.182 125.124 385.258 125.124 383.886C125.124 382.346 126.384 381.464 128.638 381.464H129.688V380.988C129.688 380.022 129.086 379.644 128.05 379.644C127.56 379.644 126.832 379.756 126.09 380.022L125.698 378.916C126.622 378.566 127.532 378.412 128.288 378.412C130.276 378.412 131.242 379.336 131.242 380.89V384.194ZM128.022 385.034C128.666 385.034 129.324 384.684 129.688 384.082V382.444H128.82C127.35 382.444 126.776 382.962 126.776 383.83C126.776 384.614 127.196 385.034 128.022 385.034ZM139.076 378.412C139.916 378.412 140.546 378.874 140.546 380.512V386H139.16V380.722C139.16 379.952 139.104 379.63 138.67 379.63C138.306 379.63 137.942 379.84 137.578 380.372V386H136.304V380.722C136.304 379.952 136.248 379.63 135.814 379.63C135.436 379.63 135.086 379.84 134.722 380.372V386H133.322V378.608H134.498L134.61 379.406C135.03 378.818 135.478 378.412 136.192 378.412C136.752 378.412 137.242 378.65 137.452 379.35C137.872 378.79 138.362 378.412 139.076 378.412Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"46\"\n                        width=\"104\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-coral-400 dark:fill-coral-500\"\n                    />\n                    <path\n                        d=\"M269.476 55.67L269.882 56.972C269.308 57.168 268.608 57.21 267.74 57.21C268.622 57.616 269.084 58.204 269.084 59.1C269.084 60.542 267.978 61.592 266.158 61.592C265.738 61.592 265.444 61.564 265.15 61.466C264.954 61.606 264.828 61.844 264.828 62.082C264.828 62.376 264.996 62.642 265.738 62.642H267.026C268.608 62.642 269.728 63.51 269.728 64.7C269.728 66.17 268.426 67.024 266.032 67.024C263.484 67.024 262.742 66.226 262.742 64.728H264.142C264.142 65.512 264.492 65.876 266.046 65.876C267.586 65.876 268.146 65.484 268.146 64.798C268.146 64.196 267.586 63.86 266.718 63.86H265.444C264.044 63.86 263.428 63.202 263.428 62.432C263.428 61.942 263.708 61.452 264.24 61.102C263.358 60.64 262.98 59.996 262.98 59.03C262.98 57.476 264.24 56.412 266.06 56.412C267.838 56.426 268.594 56.104 269.476 55.67ZM266.074 57.504C265.066 57.504 264.576 58.12 264.576 59.03C264.576 59.954 265.08 60.57 266.088 60.57C267.026 60.57 267.516 60.01 267.516 59.002C267.516 58.008 267.04 57.504 266.074 57.504ZM272.943 60.808C273.041 62.32 273.895 62.964 274.959 62.964C275.673 62.964 276.275 62.74 276.905 62.32L277.577 63.272C276.891 63.832 275.925 64.182 274.889 64.182C272.579 64.182 271.319 62.614 271.319 60.304C271.319 58.092 272.593 56.412 274.693 56.412C276.653 56.412 277.885 57.812 277.885 60.108C277.885 60.36 277.871 60.626 277.843 60.808H272.943ZM274.707 57.574C273.727 57.574 273.027 58.26 272.929 59.744H276.359C276.331 58.344 275.757 57.574 274.707 57.574ZM286.209 63.608C285.663 63.958 284.879 64.182 284.053 64.182C282.331 64.182 281.421 63.216 281.421 61.76V57.756H279.783V56.608H281.421V54.956L282.989 54.774V56.608H285.495L285.313 57.756H282.989V61.746C282.989 62.544 283.367 62.922 284.277 62.922C284.809 62.922 285.271 62.782 285.649 62.572L286.209 63.608ZM294.912 61.214C294.912 63.37 293.05 64 291.146 64H288.318V54.34H290.964C292.77 54.34 294.492 54.9 294.492 56.79C294.492 57.994 293.624 58.666 292.7 58.876C293.75 59.058 294.912 59.618 294.912 61.214ZM292.84 56.916C292.84 55.936 292.21 55.558 291.104 55.558H289.942V58.344H291.202C292.28 58.344 292.84 57.924 292.84 56.916ZM293.218 61.214C293.218 59.912 292.392 59.562 291.314 59.562H289.942V62.74H291.258C292.182 62.74 293.218 62.502 293.218 61.214ZM302.48 62.194C302.48 62.768 302.648 62.992 303.04 63.118L302.676 64.182C301.962 64.098 301.416 63.804 301.15 63.16C300.604 63.846 299.736 64.182 298.798 64.182C297.286 64.182 296.362 63.258 296.362 61.886C296.362 60.346 297.622 59.464 299.876 59.464H300.926V58.988C300.926 58.022 300.324 57.644 299.288 57.644C298.798 57.644 298.07 57.756 297.328 58.022L296.936 56.916C297.86 56.566 298.77 56.412 299.526 56.412C301.514 56.412 302.48 57.336 302.48 58.89V62.194ZM299.26 63.034C299.904 63.034 300.562 62.684 300.926 62.082V60.444H300.058C298.588 60.444 298.014 60.962 298.014 61.83C298.014 62.614 298.434 63.034 299.26 63.034ZM308.467 53.64V61.984C308.467 62.67 308.929 62.922 309.587 62.922C310.007 62.922 310.385 62.824 310.763 62.67L311.155 63.762C310.721 64 310.077 64.182 309.251 64.182C307.767 64.182 306.899 63.3 306.899 61.844V54.788H304.673V53.64H308.467ZM319.269 62.194C319.269 62.768 319.437 62.992 319.829 63.118L319.465 64.182C318.751 64.098 318.205 63.804 317.939 63.16C317.393 63.846 316.525 64.182 315.587 64.182C314.075 64.182 313.151 63.258 313.151 61.886C313.151 60.346 314.411 59.464 316.665 59.464H317.715V58.988C317.715 58.022 317.113 57.644 316.077 57.644C315.587 57.644 314.859 57.756 314.117 58.022L313.725 56.916C314.649 56.566 315.559 56.412 316.315 56.412C318.303 56.412 319.269 57.336 319.269 58.89V62.194ZM316.049 63.034C316.693 63.034 317.351 62.684 317.715 62.082V60.444H316.847C315.377 60.444 314.803 60.962 314.803 61.83C314.803 62.614 315.223 63.034 316.049 63.034ZM322.008 64V56.608H323.366L323.478 57.574C324.094 56.818 324.976 56.412 325.872 56.412C327.244 56.412 327.93 57.224 327.93 58.61V64H326.362V59.394C326.362 58.106 326.208 57.616 325.312 57.616C324.584 57.616 323.968 58.134 323.576 58.694V64H322.008ZM333.972 62.894C334.658 62.894 335.246 62.628 335.792 62.264L336.506 63.272C335.862 63.818 334.896 64.182 333.916 64.182C331.634 64.182 330.318 62.656 330.318 60.346C330.318 58.092 331.662 56.412 333.944 56.412C334.952 56.412 335.792 56.72 336.506 57.308L335.778 58.288C335.204 57.896 334.602 57.672 333.972 57.672C332.796 57.672 331.984 58.498 331.984 60.346C331.984 62.194 332.824 62.894 333.972 62.894ZM340.099 60.808C340.197 62.32 341.051 62.964 342.115 62.964C342.829 62.964 343.431 62.74 344.061 62.32L344.733 63.272C344.047 63.832 343.081 64.182 342.045 64.182C339.735 64.182 338.475 62.614 338.475 60.304C338.475 58.092 339.749 56.412 341.849 56.412C343.809 56.412 345.041 57.812 345.041 60.108C345.041 60.36 345.027 60.626 344.999 60.808H340.099ZM341.863 57.574C340.883 57.574 340.183 58.26 340.085 59.744H343.515C343.487 58.344 342.913 57.574 341.863 57.574Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"276\"\n                        width=\"88\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M268.902 292.194C268.902 292.768 269.07 292.992 269.462 293.118L269.098 294.182C268.384 294.098 267.838 293.804 267.572 293.16C267.026 293.846 266.158 294.182 265.22 294.182C263.708 294.182 262.784 293.258 262.784 291.886C262.784 290.346 264.044 289.464 266.298 289.464H267.348V288.988C267.348 288.022 266.746 287.644 265.71 287.644C265.22 287.644 264.492 287.756 263.75 288.022L263.358 286.916C264.282 286.566 265.192 286.412 265.948 286.412C267.936 286.412 268.902 287.336 268.902 288.89V292.194ZM265.682 293.034C266.326 293.034 266.984 292.684 267.348 292.082V290.444H266.48C265.01 290.444 264.436 290.962 264.436 291.83C264.436 292.614 264.856 293.034 265.682 293.034ZM274.889 283.64V291.984C274.889 292.67 275.351 292.922 276.009 292.922C276.429 292.922 276.807 292.824 277.185 292.67L277.577 293.762C277.143 294 276.499 294.182 275.673 294.182C274.189 294.182 273.321 293.3 273.321 291.844V284.788H271.095V283.64H274.889ZM283.283 283.64V291.984C283.283 292.67 283.745 292.922 284.403 292.922C284.823 292.922 285.201 292.824 285.579 292.67L285.971 293.762C285.537 294 284.893 294.182 284.067 294.182C282.583 294.182 281.715 293.3 281.715 291.844V284.788H279.489V283.64H283.283ZM291.398 286.412C293.554 286.412 294.73 287.938 294.73 290.29C294.73 292.642 293.526 294.182 291.384 294.182C289.228 294.182 288.038 292.698 288.038 290.304C288.038 287.994 289.242 286.412 291.398 286.412ZM291.398 287.63C290.264 287.63 289.69 288.47 289.69 290.304C289.69 292.138 290.25 292.978 291.384 292.978C292.518 292.978 293.078 292.138 293.078 290.29C293.078 288.47 292.518 287.63 291.398 287.63ZM300.394 292.894C301.08 292.894 301.668 292.628 302.214 292.264L302.928 293.272C302.284 293.818 301.318 294.182 300.338 294.182C298.056 294.182 296.74 292.656 296.74 290.346C296.74 288.092 298.084 286.412 300.366 286.412C301.374 286.412 302.214 286.72 302.928 287.308L302.2 288.288C301.626 287.896 301.024 287.672 300.394 287.672C299.218 287.672 298.406 288.498 298.406 290.346C298.406 292.194 299.246 292.894 300.394 292.894ZM310.875 292.194C310.875 292.768 311.043 292.992 311.435 293.118L311.071 294.182C310.357 294.098 309.811 293.804 309.545 293.16C308.999 293.846 308.131 294.182 307.193 294.182C305.681 294.182 304.757 293.258 304.757 291.886C304.757 290.346 306.017 289.464 308.271 289.464H309.321V288.988C309.321 288.022 308.719 287.644 307.683 287.644C307.193 287.644 306.465 287.756 305.723 288.022L305.331 286.916C306.255 286.566 307.165 286.412 307.921 286.412C309.909 286.412 310.875 287.336 310.875 288.89V292.194ZM307.655 293.034C308.299 293.034 308.957 292.684 309.321 292.082V290.444H308.453C306.983 290.444 306.409 290.962 306.409 291.83C306.409 292.614 306.829 293.034 307.655 293.034ZM319.787 293.608C319.241 293.958 318.457 294.182 317.631 294.182C315.909 294.182 314.999 293.216 314.999 291.76V287.756H313.361V286.608H314.999V284.956L316.567 284.774V286.608H319.073L318.891 287.756H316.567V291.746C316.567 292.544 316.945 292.922 317.855 292.922C318.387 292.922 318.849 292.782 319.227 292.572L319.787 293.608ZM323.31 290.808C323.408 292.32 324.262 292.964 325.326 292.964C326.04 292.964 326.642 292.74 327.272 292.32L327.944 293.272C327.258 293.832 326.292 294.182 325.256 294.182C322.946 294.182 321.686 292.614 321.686 290.304C321.686 288.092 322.96 286.412 325.06 286.412C327.02 286.412 328.252 287.812 328.252 290.108C328.252 290.36 328.238 290.626 328.21 290.808H323.31ZM325.074 287.574C324.094 287.574 323.394 288.26 323.296 289.744H326.726C326.698 288.344 326.124 287.574 325.074 287.574Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"322\"\n                        width=\"71\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M268.902 338.194C268.902 338.768 269.07 338.992 269.462 339.118L269.098 340.182C268.384 340.098 267.838 339.804 267.572 339.16C267.026 339.846 266.158 340.182 265.22 340.182C263.708 340.182 262.784 339.258 262.784 337.886C262.784 336.346 264.044 335.464 266.298 335.464H267.348V334.988C267.348 334.022 266.746 333.644 265.71 333.644C265.22 333.644 264.492 333.756 263.75 334.022L263.358 332.916C264.282 332.566 265.192 332.412 265.948 332.412C267.936 332.412 268.902 333.336 268.902 334.89V338.194ZM265.682 339.034C266.326 339.034 266.984 338.684 267.348 338.082V336.444H266.48C265.01 336.444 264.436 336.962 264.436 337.83C264.436 338.614 264.856 339.034 265.682 339.034ZM274.329 338.992C275.309 338.992 275.925 338.614 275.925 337.998C275.925 337.396 275.687 337.116 274.161 336.724C272.691 336.346 271.725 335.828 271.725 334.54C271.725 333.266 272.859 332.412 274.679 332.412C275.925 332.412 276.821 332.776 277.493 333.266L276.821 334.26C276.247 333.882 275.589 333.602 274.721 333.602C273.713 333.602 273.321 333.924 273.321 334.414C273.321 334.974 273.727 335.184 275.197 335.59C276.639 335.982 277.591 336.486 277.591 337.886C277.591 339.496 276.023 340.182 274.329 340.182C272.957 340.182 271.977 339.734 271.291 339.146L272.117 338.194C272.691 338.656 273.461 338.992 274.329 338.992ZM282.723 338.992C283.703 338.992 284.319 338.614 284.319 337.998C284.319 337.396 284.081 337.116 282.555 336.724C281.085 336.346 280.119 335.828 280.119 334.54C280.119 333.266 281.253 332.412 283.073 332.412C284.319 332.412 285.215 332.776 285.887 333.266L285.215 334.26C284.641 333.882 283.983 333.602 283.115 333.602C282.107 333.602 281.715 333.924 281.715 334.414C281.715 334.974 282.121 335.184 283.591 335.59C285.033 335.982 285.985 336.486 285.985 337.886C285.985 339.496 284.417 340.182 282.723 340.182C281.351 340.182 280.371 339.734 279.685 339.146L280.511 338.194C281.085 338.656 281.855 338.992 282.723 338.992ZM291.384 328.982C291.986 328.982 292.406 329.416 292.406 329.976C292.406 330.536 291.986 330.956 291.384 330.956C290.768 330.956 290.362 330.536 290.362 329.976C290.362 329.416 290.768 328.982 291.384 328.982ZM292.462 332.608V338.852H294.478V340H288.696V338.852H290.894V333.756H288.766V332.608H292.462ZM303.054 331.67L303.46 332.972C302.886 333.168 302.186 333.21 301.318 333.21C302.2 333.616 302.662 334.204 302.662 335.1C302.662 336.542 301.556 337.592 299.736 337.592C299.316 337.592 299.022 337.564 298.728 337.466C298.532 337.606 298.406 337.844 298.406 338.082C298.406 338.376 298.574 338.642 299.316 338.642H300.604C302.186 338.642 303.306 339.51 303.306 340.7C303.306 342.17 302.004 343.024 299.61 343.024C297.062 343.024 296.32 342.226 296.32 340.728H297.72C297.72 341.512 298.07 341.876 299.624 341.876C301.164 341.876 301.724 341.484 301.724 340.798C301.724 340.196 301.164 339.86 300.296 339.86H299.022C297.622 339.86 297.006 339.202 297.006 338.432C297.006 337.942 297.286 337.452 297.818 337.102C296.936 336.64 296.558 335.996 296.558 335.03C296.558 333.476 297.818 332.412 299.638 332.412C301.416 332.426 302.172 332.104 303.054 331.67ZM299.652 333.504C298.644 333.504 298.154 334.12 298.154 335.03C298.154 335.954 298.658 336.57 299.666 336.57C300.604 336.57 301.094 336.01 301.094 335.002C301.094 334.008 300.618 333.504 299.652 333.504ZM305.219 340V332.608H306.577L306.689 333.574C307.305 332.818 308.187 332.412 309.083 332.412C310.455 332.412 311.141 333.224 311.141 334.61V340H309.573V335.394C309.573 334.106 309.419 333.616 308.523 333.616C307.795 333.616 307.179 334.134 306.787 334.694V340H305.219Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"368\"\n                        width=\"130\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-coral-400 dark:fill-coral-500\"\n                    />\n                    <path\n                        d=\"M266.816 384.894C267.502 384.894 268.09 384.628 268.636 384.264L269.35 385.272C268.706 385.818 267.74 386.182 266.76 386.182C264.478 386.182 263.162 384.656 263.162 382.346C263.162 380.092 264.506 378.412 266.788 378.412C267.796 378.412 268.636 378.72 269.35 379.308L268.622 380.288C268.048 379.896 267.446 379.672 266.816 379.672C265.64 379.672 264.828 380.498 264.828 382.346C264.828 384.194 265.668 384.894 266.816 384.894ZM276.877 378.426C277.325 378.426 277.661 378.496 277.997 378.608L277.731 381.338H276.611V379.826C275.561 379.854 274.805 380.694 274.371 382.136V384.88H275.855V386H271.711V384.88H272.803V379.728H271.711V378.608H273.993L274.273 380.316C274.833 379.084 275.603 378.426 276.877 378.426ZM281.337 382.808C281.435 384.32 282.289 384.964 283.353 384.964C284.067 384.964 284.669 384.74 285.299 384.32L285.971 385.272C285.285 385.832 284.319 386.182 283.283 386.182C280.973 386.182 279.713 384.614 279.713 382.304C279.713 380.092 280.987 378.412 283.087 378.412C285.047 378.412 286.279 379.812 286.279 382.108C286.279 382.36 286.265 382.626 286.237 382.808H281.337ZM283.101 379.574C282.121 379.574 281.421 380.26 281.323 381.744H284.753C284.725 380.344 284.151 379.574 283.101 379.574ZM294.086 384.194C294.086 384.768 294.254 384.992 294.646 385.118L294.282 386.182C293.568 386.098 293.022 385.804 292.756 385.16C292.21 385.846 291.342 386.182 290.404 386.182C288.892 386.182 287.968 385.258 287.968 383.886C287.968 382.346 289.228 381.464 291.482 381.464H292.532V380.988C292.532 380.022 291.93 379.644 290.894 379.644C290.404 379.644 289.676 379.756 288.934 380.022L288.542 378.916C289.466 378.566 290.376 378.412 291.132 378.412C293.12 378.412 294.086 379.336 294.086 380.89V384.194ZM290.866 385.034C291.51 385.034 292.168 384.684 292.532 384.082V382.444H291.664C290.194 382.444 289.62 382.962 289.62 383.83C289.62 384.614 290.04 385.034 290.866 385.034ZM302.998 385.608C302.452 385.958 301.668 386.182 300.842 386.182C299.12 386.182 298.21 385.216 298.21 383.76V379.756H296.572V378.608H298.21V376.956L299.778 376.774V378.608H302.284L302.102 379.756H299.778V383.746C299.778 384.544 300.156 384.922 301.066 384.922C301.598 384.922 302.06 384.782 302.438 384.572L302.998 385.608ZM306.521 382.808C306.619 384.32 307.473 384.964 308.537 384.964C309.251 384.964 309.853 384.74 310.483 384.32L311.155 385.272C310.469 385.832 309.503 386.182 308.467 386.182C306.157 386.182 304.897 384.614 304.897 382.304C304.897 380.092 306.171 378.412 308.271 378.412C310.231 378.412 311.463 379.812 311.463 382.108C311.463 382.36 311.449 382.626 311.421 382.808H306.521ZM308.285 379.574C307.305 379.574 306.605 380.26 306.507 381.744H309.937C309.909 380.344 309.335 379.574 308.285 379.574ZM318.261 383.676H314.817L314.145 386H312.479L315.559 376.34H317.575L320.655 386H318.933L318.261 383.676ZM315.153 382.416H317.925L316.539 377.6L315.153 382.416ZM325.578 384.894C326.264 384.894 326.852 384.628 327.398 384.264L328.112 385.272C327.468 385.818 326.502 386.182 325.522 386.182C323.24 386.182 321.924 384.656 321.924 382.346C321.924 380.092 323.268 378.412 325.55 378.412C326.558 378.412 327.398 378.72 328.112 379.308L327.384 380.288C326.81 379.896 326.208 379.672 325.578 379.672C324.402 379.672 323.59 380.498 323.59 382.346C323.59 384.194 324.43 384.894 325.578 384.894ZM333.972 384.894C334.658 384.894 335.246 384.628 335.792 384.264L336.506 385.272C335.862 385.818 334.896 386.182 333.916 386.182C331.634 386.182 330.318 384.656 330.318 382.346C330.318 380.092 331.662 378.412 333.944 378.412C334.952 378.412 335.792 378.72 336.506 379.308L335.778 380.288C335.204 379.896 334.602 379.672 333.972 379.672C332.796 379.672 331.984 380.498 331.984 382.346C331.984 384.194 332.824 384.894 333.972 384.894ZM341.765 378.412C343.921 378.412 345.097 379.938 345.097 382.29C345.097 384.642 343.893 386.182 341.751 386.182C339.595 386.182 338.405 384.698 338.405 382.304C338.405 379.994 339.609 378.412 341.765 378.412ZM341.765 379.63C340.631 379.63 340.057 380.47 340.057 382.304C340.057 384.138 340.617 384.978 341.751 384.978C342.885 384.978 343.445 384.138 343.445 382.29C343.445 380.47 342.885 379.63 341.765 379.63ZM348.759 378.608V383.774C348.759 384.642 349.109 384.992 349.809 384.992C350.495 384.992 351.167 384.53 351.531 383.956V378.608H353.099V386H351.741L351.643 385.048C351.097 385.79 350.187 386.182 349.319 386.182C347.877 386.182 347.191 385.356 347.191 383.97V378.608H348.759ZM355.586 386V378.608H356.944L357.056 379.574C357.672 378.818 358.554 378.412 359.45 378.412C360.822 378.412 361.508 379.224 361.508 380.61V386H359.94V381.394C359.94 380.106 359.786 379.616 358.89 379.616C358.162 379.616 357.546 380.134 357.154 380.694V386H355.586ZM370.154 385.608C369.608 385.958 368.824 386.182 367.998 386.182C366.276 386.182 365.366 385.216 365.366 383.76V379.756H363.728V378.608H365.366V376.956L366.934 376.774V378.608H369.44L369.258 379.756H366.934V383.746C366.934 384.544 367.312 384.922 368.222 384.922C368.754 384.922 369.216 384.782 369.594 384.572L370.154 385.608Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"414\"\n                        width=\"197\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M266.816 430.894C267.502 430.894 268.09 430.628 268.636 430.264L269.35 431.272C268.706 431.818 267.74 432.182 266.76 432.182C264.478 432.182 263.162 430.656 263.162 428.346C263.162 426.092 264.506 424.412 266.788 424.412C267.796 424.412 268.636 424.72 269.35 425.308L268.622 426.288C268.048 425.896 267.446 425.672 266.816 425.672C265.64 425.672 264.828 426.498 264.828 428.346C264.828 430.194 265.668 430.894 266.816 430.894ZM276.877 424.426C277.325 424.426 277.661 424.496 277.997 424.608L277.731 427.338H276.611V425.826C275.561 425.854 274.805 426.694 274.371 428.136V430.88H275.855V432H271.711V430.88H272.803V425.728H271.711V424.608H273.993L274.273 426.316C274.833 425.084 275.603 424.426 276.877 424.426ZM281.337 428.808C281.435 430.32 282.289 430.964 283.353 430.964C284.067 430.964 284.669 430.74 285.299 430.32L285.971 431.272C285.285 431.832 284.319 432.182 283.283 432.182C280.973 432.182 279.713 430.614 279.713 428.304C279.713 426.092 280.987 424.412 283.087 424.412C285.047 424.412 286.279 425.812 286.279 428.108C286.279 428.36 286.265 428.626 286.237 428.808H281.337ZM283.101 425.574C282.121 425.574 281.421 426.26 281.323 427.744H284.753C284.725 426.344 284.151 425.574 283.101 425.574ZM294.086 430.194C294.086 430.768 294.254 430.992 294.646 431.118L294.282 432.182C293.568 432.098 293.022 431.804 292.756 431.16C292.21 431.846 291.342 432.182 290.404 432.182C288.892 432.182 287.968 431.258 287.968 429.886C287.968 428.346 289.228 427.464 291.482 427.464H292.532V426.988C292.532 426.022 291.93 425.644 290.894 425.644C290.404 425.644 289.676 425.756 288.934 426.022L288.542 424.916C289.466 424.566 290.376 424.412 291.132 424.412C293.12 424.412 294.086 425.336 294.086 426.89V430.194ZM290.866 431.034C291.51 431.034 292.168 430.684 292.532 430.082V428.444H291.664C290.194 428.444 289.62 428.962 289.62 429.83C289.62 430.614 290.04 431.034 290.866 431.034ZM302.998 431.608C302.452 431.958 301.668 432.182 300.842 432.182C299.12 432.182 298.21 431.216 298.21 429.76V425.756H296.572V424.608H298.21V422.956L299.778 422.774V424.608H302.284L302.102 425.756H299.778V429.746C299.778 430.544 300.156 430.922 301.066 430.922C301.598 430.922 302.06 430.782 302.438 430.572L302.998 431.608ZM306.521 428.808C306.619 430.32 307.473 430.964 308.537 430.964C309.251 430.964 309.853 430.74 310.483 430.32L311.155 431.272C310.469 431.832 309.503 432.182 308.467 432.182C306.157 432.182 304.897 430.614 304.897 428.304C304.897 426.092 306.171 424.412 308.271 424.412C310.231 424.412 311.463 425.812 311.463 428.108C311.463 428.36 311.449 428.626 311.421 428.808H306.521ZM308.285 425.574C307.305 425.574 306.605 426.26 306.507 427.744H309.937C309.909 426.344 309.335 425.574 308.285 425.574ZM318.261 429.676H314.817L314.145 432H312.479L315.559 422.34H317.575L320.655 432H318.933L318.261 429.676ZM315.153 428.416H317.925L316.539 423.6L315.153 428.416ZM325.578 430.894C326.264 430.894 326.852 430.628 327.398 430.264L328.112 431.272C327.468 431.818 326.502 432.182 325.522 432.182C323.24 432.182 321.924 430.656 321.924 428.346C321.924 426.092 323.268 424.412 325.55 424.412C326.558 424.412 327.398 424.72 328.112 425.308L327.384 426.288C326.81 425.896 326.208 425.672 325.578 425.672C324.402 425.672 323.59 426.498 323.59 428.346C323.59 430.194 324.43 430.894 325.578 430.894ZM333.972 430.894C334.658 430.894 335.246 430.628 335.792 430.264L336.506 431.272C335.862 431.818 334.896 432.182 333.916 432.182C331.634 432.182 330.318 430.656 330.318 428.346C330.318 426.092 331.662 424.412 333.944 424.412C334.952 424.412 335.792 424.72 336.506 425.308L335.778 426.288C335.204 425.896 334.602 425.672 333.972 425.672C332.796 425.672 331.984 426.498 331.984 428.346C331.984 430.194 332.824 430.894 333.972 430.894ZM341.765 424.412C343.921 424.412 345.097 425.938 345.097 428.29C345.097 430.642 343.893 432.182 341.751 432.182C339.595 432.182 338.405 430.698 338.405 428.304C338.405 425.994 339.609 424.412 341.765 424.412ZM341.765 425.63C340.631 425.63 340.057 426.47 340.057 428.304C340.057 430.138 340.617 430.978 341.751 430.978C342.885 430.978 343.445 430.138 343.445 428.29C343.445 426.47 342.885 425.63 341.765 425.63ZM348.759 424.608V429.774C348.759 430.642 349.109 430.992 349.809 430.992C350.495 430.992 351.167 430.53 351.531 429.956V424.608H353.099V432H351.741L351.643 431.048C351.097 431.79 350.187 432.182 349.319 432.182C347.877 432.182 347.191 431.356 347.191 429.97V424.608H348.759ZM355.586 432V424.608H356.944L357.056 425.574C357.672 424.818 358.554 424.412 359.45 424.412C360.822 424.412 361.508 425.224 361.508 426.61V432H359.94V427.394C359.94 426.106 359.786 425.616 358.89 425.616C358.162 425.616 357.546 426.134 357.154 426.694V432H355.586ZM370.154 431.608C369.608 431.958 368.824 432.182 367.998 432.182C366.276 432.182 365.366 431.216 365.366 429.76V425.756H363.728V424.608H365.366V422.956L366.934 422.774V424.608H369.44L369.258 425.756H366.934V429.746C366.934 430.544 367.312 430.922 368.222 430.922C368.754 430.922 369.216 430.782 369.594 430.572L370.154 431.608ZM379.501 422.34L378.171 432H376.267L375.315 424.846L374.321 432H372.389L371.157 422.34H372.725L373.481 430.432L374.517 423.46H376.183L377.149 430.432L378.045 422.34H379.501ZM383.723 420.982C384.325 420.982 384.745 421.416 384.745 421.976C384.745 422.536 384.325 422.956 383.723 422.956C383.107 422.956 382.701 422.536 382.701 421.976C382.701 421.416 383.107 420.982 383.723 420.982ZM384.801 424.608V430.852H386.817V432H381.035V430.852H383.233V425.756H381.105V424.608H384.801ZM395.338 431.608C394.792 431.958 394.008 432.182 393.182 432.182C391.46 432.182 390.55 431.216 390.55 429.76V425.756H388.912V424.608H390.55V422.956L392.118 422.774V424.608H394.624L394.442 425.756H392.118V429.746C392.118 430.544 392.496 430.922 393.406 430.922C393.938 430.922 394.4 430.782 394.778 430.572L395.338 431.608ZM399.127 421.486V425.518C399.729 424.79 400.555 424.412 401.423 424.412C402.809 424.412 403.481 425.224 403.481 426.61V432H401.913V426.848C401.913 425.966 401.591 425.616 400.849 425.616C400.149 425.616 399.519 426.148 399.127 426.708V432H397.559V421.654L399.127 421.486ZM412.393 429.27C412.393 430.992 411.035 432.182 408.697 432.182C407.129 432.182 405.953 431.692 405.141 430.894L406.037 429.9C406.723 430.53 407.563 430.908 408.697 430.908C409.789 430.908 410.699 430.39 410.699 429.354C410.699 428.5 410.265 428.094 408.725 427.632C406.667 427.03 405.603 426.26 405.603 424.762C405.603 423.18 407.017 422.144 408.921 422.144C410.307 422.144 411.329 422.564 412.155 423.306L411.301 424.272C410.615 423.684 409.817 423.418 409.019 423.418C408.025 423.418 407.269 423.824 407.269 424.664C407.269 425.42 407.801 425.77 409.523 426.274C411.161 426.764 412.393 427.45 412.393 429.27ZM415.65 428.808C415.748 430.32 416.602 430.964 417.666 430.964C418.38 430.964 418.982 430.74 419.612 430.32L420.284 431.272C419.598 431.832 418.632 432.182 417.596 432.182C415.286 432.182 414.026 430.614 414.026 428.304C414.026 426.092 415.3 424.412 417.4 424.412C419.36 424.412 420.592 425.812 420.592 428.108C420.592 428.36 420.578 428.626 420.55 428.808H415.65ZM417.414 425.574C416.434 425.574 415.734 426.26 415.636 427.744H419.066C419.038 426.344 418.464 425.574 417.414 425.574ZM424.044 428.808C424.142 430.32 424.996 430.964 426.06 430.964C426.774 430.964 427.376 430.74 428.006 430.32L428.678 431.272C427.992 431.832 427.026 432.182 425.99 432.182C423.68 432.182 422.42 430.614 422.42 428.304C422.42 426.092 423.694 424.412 425.794 424.412C427.754 424.412 428.986 425.812 428.986 428.108C428.986 428.36 428.972 428.626 428.944 428.808H424.044ZM425.808 425.574C424.828 425.574 424.128 426.26 424.03 427.744H427.46C427.432 426.344 426.858 425.574 425.808 425.574ZM435.477 421.458L437.045 421.64V432H435.659L435.547 431.09C435.057 431.79 434.343 432.182 433.475 432.182C431.571 432.182 430.689 430.628 430.689 428.304C430.689 426.05 431.795 424.412 433.615 424.412C434.385 424.412 435.001 424.692 435.477 425.224V421.458ZM434.021 425.616C432.971 425.616 432.355 426.456 432.355 428.304C432.355 430.194 432.915 430.992 433.895 430.992C434.595 430.992 435.113 430.516 435.477 429.928V426.442C435.113 425.924 434.623 425.616 434.021 425.616Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"460\"\n                        width=\"46\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M267.645 476.824C267.645 476.082 268.233 475.48 268.989 475.48C269.759 475.48 270.347 476.082 270.347 476.824C270.347 477.58 269.759 478.182 268.989 478.182C268.233 478.182 267.645 477.58 267.645 476.824ZM273.245 476.824C273.245 476.082 273.833 475.48 274.589 475.48C275.359 475.48 275.947 476.082 275.947 476.824C275.947 477.58 275.359 478.182 274.589 478.182C273.833 478.182 273.245 477.58 273.245 476.824ZM278.845 476.824C278.845 476.082 279.433 475.48 280.189 475.48C280.959 475.48 281.547 476.082 281.547 476.824C281.547 477.58 280.959 478.182 280.189 478.182C279.433 478.182 278.845 477.58 278.845 476.824Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"92\"\n                        width=\"155\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M269.476 101.67L269.882 102.972C269.308 103.168 268.608 103.21 267.74 103.21C268.622 103.616 269.084 104.204 269.084 105.1C269.084 106.542 267.978 107.592 266.158 107.592C265.738 107.592 265.444 107.564 265.15 107.466C264.954 107.606 264.828 107.844 264.828 108.082C264.828 108.376 264.996 108.642 265.738 108.642H267.026C268.608 108.642 269.728 109.51 269.728 110.7C269.728 112.17 268.426 113.024 266.032 113.024C263.484 113.024 262.742 112.226 262.742 110.728H264.142C264.142 111.512 264.492 111.876 266.046 111.876C267.586 111.876 268.146 111.484 268.146 110.798C268.146 110.196 267.586 109.86 266.718 109.86H265.444C264.044 109.86 263.428 109.202 263.428 108.432C263.428 107.942 263.708 107.452 264.24 107.102C263.358 106.64 262.98 105.996 262.98 105.03C262.98 103.476 264.24 102.412 266.06 102.412C267.838 102.426 268.594 102.104 269.476 101.67ZM266.074 103.504C265.066 103.504 264.576 104.12 264.576 105.03C264.576 105.954 265.08 106.57 266.088 106.57C267.026 106.57 267.516 106.01 267.516 105.002C267.516 104.008 267.04 103.504 266.074 103.504ZM272.943 106.808C273.041 108.32 273.895 108.964 274.959 108.964C275.673 108.964 276.275 108.74 276.905 108.32L277.577 109.272C276.891 109.832 275.925 110.182 274.889 110.182C272.579 110.182 271.319 108.614 271.319 106.304C271.319 104.092 272.593 102.412 274.693 102.412C276.653 102.412 277.885 103.812 277.885 106.108C277.885 106.36 277.871 106.626 277.843 106.808H272.943ZM274.707 103.574C273.727 103.574 273.027 104.26 272.929 105.744H276.359C276.331 104.344 275.757 103.574 274.707 103.574ZM286.209 109.608C285.663 109.958 284.879 110.182 284.053 110.182C282.331 110.182 281.421 109.216 281.421 107.76V103.756H279.783V102.608H281.421V100.956L282.989 100.774V102.608H285.495L285.313 103.756H282.989V107.746C282.989 108.544 283.367 108.922 284.277 108.922C284.809 108.922 285.271 108.782 285.649 108.572L286.209 109.608ZM290.39 101.572V104.484H293.89V105.702H290.39V108.768H294.66V110H288.766V100.34H294.576L294.394 101.572H290.39ZM300.436 102.412C302.382 102.412 303.124 103.938 303.124 106.29C303.124 108.544 302.144 110.182 300.268 110.182C299.498 110.182 298.868 109.916 298.392 109.37V112.842L296.824 113.024V102.608H298.182L298.28 103.56C298.84 102.804 299.61 102.412 300.436 102.412ZM300.002 103.616C299.302 103.616 298.756 104.106 298.392 104.68V108.138C298.742 108.67 299.246 108.964 299.848 108.964C300.912 108.964 301.472 108.152 301.472 106.304C301.472 104.4 300.982 103.616 300.002 103.616ZM308.187 102.412C310.343 102.412 311.519 103.938 311.519 106.29C311.519 108.642 310.315 110.182 308.173 110.182C306.017 110.182 304.827 108.698 304.827 106.304C304.827 103.994 306.031 102.412 308.187 102.412ZM308.187 103.63C307.053 103.63 306.479 104.47 306.479 106.304C306.479 108.138 307.039 108.978 308.173 108.978C309.307 108.978 309.867 108.138 309.867 106.29C309.867 104.47 309.307 103.63 308.187 103.63ZM317.183 108.894C317.869 108.894 318.457 108.628 319.003 108.264L319.717 109.272C319.073 109.818 318.107 110.182 317.127 110.182C314.845 110.182 313.529 108.656 313.529 106.346C313.529 104.092 314.873 102.412 317.155 102.412C318.163 102.412 319.003 102.72 319.717 103.308L318.989 104.288C318.415 103.896 317.813 103.672 317.183 103.672C316.007 103.672 315.195 104.498 315.195 106.346C315.195 108.194 316.035 108.894 317.183 108.894ZM323.576 99.486V103.518C324.178 102.79 325.004 102.412 325.872 102.412C327.258 102.412 327.93 103.224 327.93 104.61V110H326.362V104.848C326.362 103.966 326.04 103.616 325.298 103.616C324.598 103.616 323.968 104.148 323.576 104.708V110H322.008V99.654L323.576 99.486ZM336.842 107.27C336.842 108.992 335.484 110.182 333.146 110.182C331.578 110.182 330.402 109.692 329.59 108.894L330.486 107.9C331.172 108.53 332.012 108.908 333.146 108.908C334.238 108.908 335.148 108.39 335.148 107.354C335.148 106.5 334.714 106.094 333.174 105.632C331.116 105.03 330.052 104.26 330.052 102.762C330.052 101.18 331.466 100.144 333.37 100.144C334.756 100.144 335.778 100.564 336.604 101.306L335.75 102.272C335.064 101.684 334.266 101.418 333.468 101.418C332.474 101.418 331.718 101.824 331.718 102.664C331.718 103.42 332.25 103.77 333.972 104.274C335.61 104.764 336.842 105.45 336.842 107.27ZM342.367 108.894C343.053 108.894 343.641 108.628 344.187 108.264L344.901 109.272C344.257 109.818 343.291 110.182 342.311 110.182C340.029 110.182 338.713 108.656 338.713 106.346C338.713 104.092 340.057 102.412 342.339 102.412C343.347 102.412 344.187 102.72 344.901 103.308L344.173 104.288C343.599 103.896 342.997 103.672 342.367 103.672C341.191 103.672 340.379 104.498 340.379 106.346C340.379 108.194 341.219 108.894 342.367 108.894ZM348.759 99.486V103.518C349.361 102.79 350.187 102.412 351.055 102.412C352.441 102.412 353.113 103.224 353.113 104.61V110H351.545V104.848C351.545 103.966 351.223 103.616 350.481 103.616C349.781 103.616 349.151 104.148 348.759 104.708V110H347.191V99.654L348.759 99.486ZM356.888 106.808C356.986 108.32 357.84 108.964 358.904 108.964C359.618 108.964 360.22 108.74 360.85 108.32L361.522 109.272C360.836 109.832 359.87 110.182 358.834 110.182C356.524 110.182 355.264 108.614 355.264 106.304C355.264 104.092 356.538 102.412 358.638 102.412C360.598 102.412 361.83 103.812 361.83 106.108C361.83 106.36 361.816 106.626 361.788 106.808H356.888ZM358.652 103.574C357.672 103.574 356.972 104.26 356.874 105.744H360.304C360.276 104.344 359.702 103.574 358.652 103.574ZM368.32 99.458L369.888 99.64V110H368.502L368.39 109.09C367.9 109.79 367.186 110.182 366.318 110.182C364.414 110.182 363.532 108.628 363.532 106.304C363.532 104.05 364.638 102.412 366.458 102.412C367.228 102.412 367.844 102.692 368.32 103.224V99.458ZM366.864 103.616C365.814 103.616 365.198 104.456 365.198 106.304C365.198 108.194 365.758 108.992 366.738 108.992C367.438 108.992 367.956 108.516 368.32 107.928V104.442C367.956 103.924 367.466 103.616 366.864 103.616ZM373.943 102.608V107.774C373.943 108.642 374.293 108.992 374.993 108.992C375.679 108.992 376.351 108.53 376.715 107.956V102.608H378.283V110H376.925L376.827 109.048C376.281 109.79 375.371 110.182 374.503 110.182C373.061 110.182 372.375 109.356 372.375 107.97V102.608H373.943ZM384.017 99.64V107.984C384.017 108.67 384.479 108.922 385.137 108.922C385.557 108.922 385.935 108.824 386.313 108.67L386.705 109.762C386.271 110 385.627 110.182 384.801 110.182C383.317 110.182 382.449 109.3 382.449 107.844V100.788H380.223V99.64H384.017ZM390.466 106.808C390.564 108.32 391.418 108.964 392.482 108.964C393.196 108.964 393.798 108.74 394.428 108.32L395.1 109.272C394.414 109.832 393.448 110.182 392.412 110.182C390.102 110.182 388.842 108.614 388.842 106.304C388.842 104.092 390.116 102.412 392.216 102.412C394.176 102.412 395.408 103.812 395.408 106.108C395.408 106.36 395.394 106.626 395.366 106.808H390.466ZM392.23 103.574C391.25 103.574 390.55 104.26 390.452 105.744H393.882C393.854 104.344 393.28 103.574 392.23 103.574Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"138\"\n                        width=\"146\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M266.214 148.412C268.37 148.412 269.546 149.938 269.546 152.29C269.546 154.642 268.342 156.182 266.2 156.182C264.044 156.182 262.854 154.698 262.854 152.304C262.854 149.994 264.058 148.412 266.214 148.412ZM266.214 149.63C265.08 149.63 264.506 150.47 264.506 152.304C264.506 154.138 265.066 154.978 266.2 154.978C267.334 154.978 267.894 154.138 267.894 152.29C267.894 150.47 267.334 149.63 266.214 149.63ZM271.641 156V148.608H272.999L273.111 149.574C273.727 148.818 274.609 148.412 275.505 148.412C276.877 148.412 277.563 149.224 277.563 150.61V156H275.995V151.394C275.995 150.106 275.841 149.616 274.945 149.616C274.217 149.616 273.601 150.134 273.209 150.694V156H271.641ZM284.683 153.676H281.239L280.567 156H278.901L281.981 146.34H283.997L287.077 156H285.355L284.683 153.676ZM281.575 152.416H284.347L282.961 147.6L281.575 152.416ZM292 154.894C292.686 154.894 293.274 154.628 293.82 154.264L294.534 155.272C293.89 155.818 292.924 156.182 291.944 156.182C289.662 156.182 288.346 154.656 288.346 152.346C288.346 150.092 289.69 148.412 291.972 148.412C292.98 148.412 293.82 148.72 294.534 149.308L293.806 150.288C293.232 149.896 292.63 149.672 292 149.672C290.824 149.672 290.012 150.498 290.012 152.346C290.012 154.194 290.852 154.894 292 154.894ZM300.394 154.894C301.08 154.894 301.668 154.628 302.214 154.264L302.928 155.272C302.284 155.818 301.318 156.182 300.338 156.182C298.056 156.182 296.74 154.656 296.74 152.346C296.74 150.092 298.084 148.412 300.366 148.412C301.374 148.412 302.214 148.72 302.928 149.308L302.2 150.288C301.626 149.896 301.024 149.672 300.394 149.672C299.218 149.672 298.406 150.498 298.406 152.346C298.406 154.194 299.246 154.894 300.394 154.894ZM308.187 148.412C310.343 148.412 311.519 149.938 311.519 152.29C311.519 154.642 310.315 156.182 308.173 156.182C306.017 156.182 304.827 154.698 304.827 152.304C304.827 149.994 306.031 148.412 308.187 148.412ZM308.187 149.63C307.053 149.63 306.479 150.47 306.479 152.304C306.479 154.138 307.039 154.978 308.173 154.978C309.307 154.978 309.867 154.138 309.867 152.29C309.867 150.47 309.307 149.63 308.187 149.63ZM315.181 148.608V153.774C315.181 154.642 315.531 154.992 316.231 154.992C316.917 154.992 317.589 154.53 317.953 153.956V148.608H319.521V156H318.163L318.065 155.048C317.519 155.79 316.609 156.182 315.741 156.182C314.299 156.182 313.613 155.356 313.613 153.97V148.608H315.181ZM322.008 156V148.608H323.366L323.478 149.574C324.094 148.818 324.976 148.412 325.872 148.412C327.244 148.412 327.93 149.224 327.93 150.61V156H326.362V151.394C326.362 150.106 326.208 149.616 325.312 149.616C324.584 149.616 323.968 150.134 323.576 150.694V156H322.008ZM336.576 155.608C336.03 155.958 335.246 156.182 334.42 156.182C332.698 156.182 331.788 155.216 331.788 153.76V149.756H330.15V148.608H331.788V146.956L333.356 146.774V148.608H335.862L335.68 149.756H333.356V153.746C333.356 154.544 333.734 154.922 334.644 154.922C335.176 154.922 335.638 154.782 336.016 154.572L336.576 155.608ZM342.563 146.144C343.879 146.144 344.691 146.494 345.475 147.124L344.635 148.132C344.047 147.656 343.389 147.418 342.633 147.418C341.191 147.418 339.973 148.426 339.973 151.156C339.973 153.83 341.121 154.866 342.647 154.866C343.683 154.866 344.299 154.46 344.831 154.04L345.615 155.034C344.971 155.664 344.005 156.182 342.591 156.182C340.127 156.182 338.279 154.432 338.279 151.156C338.279 147.908 340.211 146.144 342.563 146.144ZM348.759 145.486V149.518C349.361 148.79 350.187 148.412 351.055 148.412C352.441 148.412 353.113 149.224 353.113 150.61V156H351.545V150.848C351.545 149.966 351.223 149.616 350.481 149.616C349.781 149.616 349.151 150.148 348.759 150.708V156H347.191V145.654L348.759 145.486ZM361.242 154.194C361.242 154.768 361.41 154.992 361.802 155.118L361.438 156.182C360.724 156.098 360.178 155.804 359.912 155.16C359.366 155.846 358.498 156.182 357.56 156.182C356.048 156.182 355.124 155.258 355.124 153.886C355.124 152.346 356.384 151.464 358.638 151.464H359.688V150.988C359.688 150.022 359.086 149.644 358.05 149.644C357.56 149.644 356.832 149.756 356.09 150.022L355.698 148.916C356.622 148.566 357.532 148.412 358.288 148.412C360.276 148.412 361.242 149.336 361.242 150.89V154.194ZM358.022 155.034C358.666 155.034 359.324 154.684 359.688 154.082V152.444H358.82C357.35 152.444 356.776 152.962 356.776 153.83C356.776 154.614 357.196 155.034 358.022 155.034ZM363.98 156V148.608H365.338L365.45 149.574C366.066 148.818 366.948 148.412 367.844 148.412C369.216 148.412 369.902 149.224 369.902 150.61V156H368.334V151.394C368.334 150.106 368.18 149.616 367.284 149.616C366.556 149.616 365.94 150.134 365.548 150.694V156H363.98ZM378.605 147.67L379.011 148.972C378.437 149.168 377.737 149.21 376.869 149.21C377.751 149.616 378.213 150.204 378.213 151.1C378.213 152.542 377.107 153.592 375.287 153.592C374.867 153.592 374.573 153.564 374.279 153.466C374.083 153.606 373.957 153.844 373.957 154.082C373.957 154.376 374.125 154.642 374.867 154.642H376.155C377.737 154.642 378.857 155.51 378.857 156.7C378.857 158.17 377.555 159.024 375.161 159.024C372.613 159.024 371.871 158.226 371.871 156.728H373.271C373.271 157.512 373.621 157.876 375.175 157.876C376.715 157.876 377.275 157.484 377.275 156.798C377.275 156.196 376.715 155.86 375.847 155.86H374.573C373.173 155.86 372.557 155.202 372.557 154.432C372.557 153.942 372.837 153.452 373.369 153.102C372.487 152.64 372.109 151.996 372.109 151.03C372.109 149.476 373.369 148.412 375.189 148.412C376.967 148.426 377.723 148.104 378.605 147.67ZM375.203 149.504C374.195 149.504 373.705 150.12 373.705 151.03C373.705 151.954 374.209 152.57 375.217 152.57C376.155 152.57 376.645 152.01 376.645 151.002C376.645 150.008 376.169 149.504 375.203 149.504ZM382.071 152.808C382.169 154.32 383.023 154.964 384.087 154.964C384.801 154.964 385.403 154.74 386.033 154.32L386.705 155.272C386.019 155.832 385.053 156.182 384.017 156.182C381.707 156.182 380.447 154.614 380.447 152.304C380.447 150.092 381.721 148.412 383.821 148.412C385.781 148.412 387.013 149.812 387.013 152.108C387.013 152.36 386.999 152.626 386.971 152.808H382.071ZM383.835 149.574C382.855 149.574 382.155 150.26 382.057 151.744H385.487C385.459 150.344 384.885 149.574 383.835 149.574Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"184\"\n                        width=\"172\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M266.816 200.894C267.502 200.894 268.09 200.628 268.636 200.264L269.35 201.272C268.706 201.818 267.74 202.182 266.76 202.182C264.478 202.182 263.162 200.656 263.162 198.346C263.162 196.092 264.506 194.412 266.788 194.412C267.796 194.412 268.636 194.72 269.35 195.308L268.622 196.288C268.048 195.896 267.446 195.672 266.816 195.672C265.64 195.672 264.828 196.498 264.828 198.346C264.828 200.194 265.668 200.894 266.816 200.894ZM274.609 194.412C276.765 194.412 277.941 195.938 277.941 198.29C277.941 200.642 276.737 202.182 274.595 202.182C272.439 202.182 271.249 200.698 271.249 198.304C271.249 195.994 272.453 194.412 274.609 194.412ZM274.609 195.63C273.475 195.63 272.901 196.47 272.901 198.304C272.901 200.138 273.461 200.978 274.595 200.978C275.729 200.978 276.289 200.138 276.289 198.29C276.289 196.47 275.729 195.63 274.609 195.63ZM280.035 202V194.608H281.393L281.505 195.574C282.121 194.818 283.003 194.412 283.899 194.412C285.271 194.412 285.957 195.224 285.957 196.61V202H284.389V197.394C284.389 196.106 284.235 195.616 283.339 195.616C282.611 195.616 281.995 196.134 281.603 196.694V202H280.035ZM292.924 191.458C293.834 191.458 294.52 191.626 295.136 191.892L294.66 192.984C294.17 192.774 293.624 192.676 293.078 192.676C292.112 192.676 291.65 193.04 291.65 193.824V195.14H294.128L293.946 196.302H291.65V202H290.082V196.302H288.402V195.14H290.082V193.81C290.082 192.41 291.216 191.458 292.924 191.458ZM299.778 190.982C300.38 190.982 300.8 191.416 300.8 191.976C300.8 192.536 300.38 192.956 299.778 192.956C299.162 192.956 298.756 192.536 298.756 191.976C298.756 191.416 299.162 190.982 299.778 190.982ZM300.856 194.608V200.852H302.872V202H297.09V200.852H299.288V195.756H297.16V194.608H300.856ZM310.455 194.426C310.903 194.426 311.239 194.496 311.575 194.608L311.309 197.338H310.189V195.826C309.139 195.854 308.383 196.694 307.949 198.136V200.88H309.433V202H305.289V200.88H306.381V195.728H305.289V194.608H307.571L307.851 196.316C308.411 195.084 309.181 194.426 310.455 194.426ZM318.709 194.412C319.549 194.412 320.179 194.874 320.179 196.512V202H318.793V196.722C318.793 195.952 318.737 195.63 318.303 195.63C317.939 195.63 317.575 195.84 317.211 196.372V202H315.937V196.722C315.937 195.952 315.881 195.63 315.447 195.63C315.069 195.63 314.719 195.84 314.355 196.372V202H312.955V194.608H314.131L314.243 195.406C314.663 194.818 315.111 194.412 315.825 194.412C316.385 194.412 316.875 194.65 317.085 195.35C317.505 194.79 317.995 194.412 318.709 194.412ZM325.76 193.656V202H324.136V193.656H321.224V192.34H328.714L328.546 193.656H325.76ZM335.638 194.426C336.086 194.426 336.422 194.496 336.758 194.608L336.492 197.338H335.372V195.826C334.322 195.854 333.566 196.694 333.132 198.136V200.88H334.616V202H330.472V200.88H331.564V195.728H330.472V194.608H332.754L333.034 196.316C333.594 195.084 334.364 194.426 335.638 194.426ZM344.453 200.194C344.453 200.768 344.621 200.992 345.013 201.118L344.649 202.182C343.935 202.098 343.389 201.804 343.123 201.16C342.577 201.846 341.709 202.182 340.771 202.182C339.259 202.182 338.335 201.258 338.335 199.886C338.335 198.346 339.595 197.464 341.849 197.464H342.899V196.988C342.899 196.022 342.297 195.644 341.261 195.644C340.771 195.644 340.043 195.756 339.301 196.022L338.909 194.916C339.833 194.566 340.743 194.412 341.499 194.412C343.487 194.412 344.453 195.336 344.453 196.89V200.194ZM341.233 201.034C341.877 201.034 342.535 200.684 342.899 200.082V198.444H342.031C340.561 198.444 339.987 198.962 339.987 199.83C339.987 200.614 340.407 201.034 341.233 201.034ZM347.191 202V194.608H348.549L348.661 195.574C349.277 194.818 350.159 194.412 351.055 194.412C352.427 194.412 353.113 195.224 353.113 196.61V202H351.545V197.394C351.545 196.106 351.391 195.616 350.495 195.616C349.767 195.616 349.151 196.134 348.759 196.694V202H347.191ZM358.274 200.992C359.254 200.992 359.87 200.614 359.87 199.998C359.87 199.396 359.632 199.116 358.106 198.724C356.636 198.346 355.67 197.828 355.67 196.54C355.67 195.266 356.804 194.412 358.624 194.412C359.87 194.412 360.766 194.776 361.438 195.266L360.766 196.26C360.192 195.882 359.534 195.602 358.666 195.602C357.658 195.602 357.266 195.924 357.266 196.414C357.266 196.974 357.672 197.184 359.142 197.59C360.584 197.982 361.536 198.486 361.536 199.886C361.536 201.496 359.968 202.182 358.274 202.182C356.902 202.182 355.922 201.734 355.236 201.146L356.062 200.194C356.636 200.656 357.406 200.992 358.274 200.992ZM369.636 200.194C369.636 200.768 369.804 200.992 370.196 201.118L369.832 202.182C369.118 202.098 368.572 201.804 368.306 201.16C367.76 201.846 366.892 202.182 365.954 202.182C364.442 202.182 363.518 201.258 363.518 199.886C363.518 198.346 364.778 197.464 367.032 197.464H368.082V196.988C368.082 196.022 367.48 195.644 366.444 195.644C365.954 195.644 365.226 195.756 364.484 196.022L364.092 194.916C365.016 194.566 365.926 194.412 366.682 194.412C368.67 194.412 369.636 195.336 369.636 196.89V200.194ZM366.416 201.034C367.06 201.034 367.718 200.684 368.082 200.082V198.444H367.214C365.744 198.444 365.17 198.962 365.17 199.83C365.17 200.614 365.59 201.034 366.416 201.034ZM375.945 200.894C376.631 200.894 377.219 200.628 377.765 200.264L378.479 201.272C377.835 201.818 376.869 202.182 375.889 202.182C373.607 202.182 372.291 200.656 372.291 198.346C372.291 196.092 373.635 194.412 375.917 194.412C376.925 194.412 377.765 194.72 378.479 195.308L377.751 196.288C377.177 195.896 376.575 195.672 375.945 195.672C374.769 195.672 373.957 196.498 373.957 198.346C373.957 200.194 374.797 200.894 375.945 200.894ZM386.943 201.608C386.397 201.958 385.613 202.182 384.787 202.182C383.065 202.182 382.155 201.216 382.155 199.76V195.756H380.517V194.608H382.155V192.956L383.723 192.774V194.608H386.229L386.047 195.756H383.723V199.746C383.723 200.544 384.101 200.922 385.011 200.922C385.543 200.922 386.005 200.782 386.383 200.572L386.943 201.608ZM392.118 190.982C392.72 190.982 393.14 191.416 393.14 191.976C393.14 192.536 392.72 192.956 392.118 192.956C391.502 192.956 391.096 192.536 391.096 191.976C391.096 191.416 391.502 190.982 392.118 190.982ZM393.196 194.608V200.852H395.212V202H389.43V200.852H391.628V195.756H389.5V194.608H393.196ZM400.527 194.412C402.683 194.412 403.859 195.938 403.859 198.29C403.859 200.642 402.655 202.182 400.513 202.182C398.357 202.182 397.167 200.698 397.167 198.304C397.167 195.994 398.37 194.412 400.527 194.412ZM400.527 195.63C399.393 195.63 398.819 196.47 398.819 198.304C398.819 200.138 399.379 200.978 400.513 200.978C401.647 200.978 402.207 200.138 402.207 198.29C402.207 196.47 401.647 195.63 400.527 195.63ZM405.953 202V194.608H407.311L407.423 195.574C408.039 194.818 408.921 194.412 409.817 194.412C411.189 194.412 411.875 195.224 411.875 196.61V202H410.307V197.394C410.307 196.106 410.153 195.616 409.257 195.616C408.529 195.616 407.913 196.134 407.521 196.694V202H405.953Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"252\"\n                        y=\"230\"\n                        width=\"46\"\n                        height=\"26\"\n                        rx=\"5\"\n                        className=\"fill-linen-400 dark:fill-linen-600\"\n                    />\n                    <path\n                        d=\"M267.645 246.824C267.645 246.082 268.233 245.48 268.989 245.48C269.759 245.48 270.347 246.082 270.347 246.824C270.347 247.58 269.759 248.182 268.989 248.182C268.233 248.182 267.645 247.58 267.645 246.824ZM273.245 246.824C273.245 246.082 273.833 245.48 274.589 245.48C275.359 245.48 275.947 246.082 275.947 246.824C275.947 247.58 275.359 248.182 274.589 248.182C273.833 248.182 273.245 247.58 273.245 246.824ZM278.845 246.824C278.845 246.082 279.433 245.48 280.189 245.48C280.959 245.48 281.547 246.082 281.547 246.824C281.547 247.58 280.959 248.182 280.189 248.182C279.433 248.182 278.845 247.58 278.845 246.824Z\"\n                        fill=\"white\"\n                    />\n                    <rect\n                        x=\"246\"\n                        y=\"40\"\n                        width=\"209\"\n                        height=\"452\"\n                        rx=\"11\"\n                        stroke=\"#D8582B\"\n                        strokeWidth=\"2\"\n                        strokeDasharray=\"6 6\"\n                    />\n                    <path\n                        d=\"M324.119 31V20.8182H327.847C328.57 20.8182 329.168 20.9375 329.642 21.1761C330.116 21.4115 330.471 21.7313 330.706 22.1357C330.941 22.5367 331.059 22.9891 331.059 23.4929C331.059 23.9171 330.981 24.2751 330.825 24.5668C330.67 24.8551 330.461 25.0871 330.199 25.2628C329.94 25.4351 329.655 25.5611 329.344 25.6406V25.7401C329.682 25.7566 330.012 25.866 330.333 26.0682C330.658 26.267 330.926 26.5504 331.138 26.9183C331.351 27.2862 331.457 27.7337 331.457 28.2607C331.457 28.781 331.334 29.2483 331.089 29.6626C330.847 30.0736 330.472 30.4001 329.965 30.642C329.458 30.8807 328.81 31 328.021 31H324.119ZM325.655 29.6825H327.872C328.608 29.6825 329.135 29.54 329.453 29.255C329.771 28.9699 329.93 28.6136 329.93 28.1861C329.93 27.8646 329.849 27.5696 329.687 27.3011C329.524 27.0327 329.292 26.8189 328.991 26.6598C328.692 26.5007 328.338 26.4212 327.927 26.4212H325.655V29.6825ZM325.655 25.223H327.713C328.058 25.223 328.368 25.1567 328.643 25.0241C328.921 24.8916 329.142 24.706 329.304 24.4673C329.47 24.2254 329.553 23.9403 329.553 23.6122C329.553 23.1913 329.405 22.8383 329.11 22.5533C328.815 22.2682 328.363 22.1257 327.753 22.1257H325.655V25.223ZM337.997 27.8331V23.3636H339.488V31H338.027V29.6776H337.947C337.771 30.0852 337.49 30.425 337.102 30.6967C336.717 30.9652 336.239 31.0994 335.665 31.0994C335.175 31.0994 334.74 30.9917 334.363 30.7763C333.988 30.5575 333.693 30.2344 333.478 29.8068C333.266 29.3793 333.159 28.8506 333.159 28.2209V23.3636H334.646V28.0419C334.646 28.5623 334.79 28.9766 335.078 29.2848C335.367 29.593 335.741 29.7472 336.202 29.7472C336.48 29.7472 336.757 29.6776 337.032 29.5384C337.311 29.3991 337.541 29.1887 337.723 28.907C337.909 28.6252 338 28.2673 337.997 27.8331ZM342.972 26.4659V31H341.486V23.3636H342.912V24.6065H343.007C343.183 24.2022 343.458 23.8774 343.832 23.6321C344.21 23.3868 344.686 23.2642 345.259 23.2642C345.779 23.2642 346.235 23.3736 346.626 23.5923C347.017 23.8078 347.321 24.1293 347.536 24.5568C347.751 24.9844 347.859 25.513 347.859 26.1428V31H346.373V26.3217C346.373 25.7682 346.229 25.3357 345.94 25.0241C345.652 24.7093 345.256 24.5518 344.752 24.5518C344.407 24.5518 344.101 24.6264 343.832 24.7756C343.567 24.9247 343.357 25.1435 343.201 25.4318C343.048 25.7169 342.972 26.0616 342.972 26.4659ZM352.711 31.1491C352.095 31.1491 351.545 30.9917 351.061 30.6768C350.58 30.3587 350.202 29.9062 349.927 29.3196C349.656 28.7296 349.52 28.022 349.52 27.1967C349.52 26.3714 349.657 25.6655 349.932 25.0788C350.211 24.4922 350.592 24.0431 351.076 23.7315C351.56 23.42 352.108 23.2642 352.721 23.2642C353.195 23.2642 353.577 23.3438 353.865 23.5028C354.157 23.6586 354.382 23.8409 354.541 24.0497C354.703 24.2585 354.829 24.4425 354.919 24.6016H355.008V20.8182H356.495V31H355.043V29.8118H354.919C354.829 29.9742 354.7 30.1598 354.531 30.3686C354.365 30.5774 354.137 30.7597 353.845 30.9155C353.553 31.0713 353.175 31.1491 352.711 31.1491ZM353.04 29.8814C353.467 29.8814 353.828 29.7687 354.123 29.5433C354.422 29.3146 354.647 28.9981 354.8 28.5938C354.955 28.1894 355.033 27.7187 355.033 27.1818C355.033 26.6515 354.957 26.1875 354.805 25.7898C354.652 25.392 354.428 25.0821 354.133 24.8601C353.838 24.638 353.474 24.527 353.04 24.527C352.592 24.527 352.219 24.643 351.921 24.875C351.623 25.107 351.397 25.4235 351.245 25.8246C351.096 26.2256 351.021 26.678 351.021 27.1818C351.021 27.6922 351.097 28.1513 351.25 28.5589C351.402 28.9666 351.628 29.2898 351.926 29.5284C352.228 29.7637 352.599 29.8814 353.04 29.8814ZM360.103 20.8182V31H358.616V20.8182H360.103ZM365.394 31.1541C364.642 31.1541 363.994 30.9934 363.45 30.6719C362.91 30.3471 362.492 29.8913 362.197 29.3047C361.906 28.7147 361.76 28.0237 361.76 27.2315C361.76 26.4493 361.906 25.7599 362.197 25.1634C362.492 24.5668 362.903 24.1011 363.43 23.7663C363.961 23.4316 364.58 23.2642 365.29 23.2642C365.72 23.2642 366.138 23.3355 366.542 23.478C366.947 23.6205 367.31 23.8442 367.631 24.1491C367.953 24.4541 368.206 24.8501 368.392 25.3374C368.577 25.8213 368.67 26.4096 368.67 27.1023V27.6293H362.6V26.5156H367.214C367.214 26.1245 367.134 25.7782 366.975 25.4766C366.816 25.1716 366.592 24.9313 366.304 24.7557C366.019 24.58 365.684 24.4922 365.3 24.4922C364.882 24.4922 364.517 24.5949 364.206 24.8004C363.898 25.0026 363.659 25.2678 363.49 25.5959C363.324 25.9207 363.241 26.2737 363.241 26.6548V27.5249C363.241 28.0353 363.331 28.4695 363.51 28.8274C363.692 29.1854 363.946 29.4588 364.27 29.6477C364.595 29.8333 364.975 29.9261 365.409 29.9261C365.691 29.9261 365.948 29.8864 366.18 29.8068C366.412 29.724 366.612 29.6013 366.781 29.4389C366.95 29.2765 367.079 29.076 367.169 28.8374L368.576 29.0909C368.463 29.5052 368.261 29.8681 367.969 30.1797C367.681 30.4879 367.318 30.7282 366.881 30.9006C366.446 31.0696 365.951 31.1541 365.394 31.1541ZM373.178 31.1491C372.562 31.1491 372.012 30.9917 371.528 30.6768C371.047 30.3587 370.669 29.9062 370.394 29.3196C370.122 28.7296 369.987 28.022 369.987 27.1967C369.987 26.3714 370.124 25.6655 370.399 25.0788C370.678 24.4922 371.059 24.0431 371.543 23.7315C372.027 23.42 372.575 23.2642 373.188 23.2642C373.662 23.2642 374.043 23.3438 374.332 23.5028C374.623 23.6586 374.849 23.8409 375.008 24.0497C375.17 24.2585 375.296 24.4425 375.386 24.6016H375.475V20.8182H376.962V31H375.51V29.8118H375.386C375.296 29.9742 375.167 30.1598 374.998 30.3686C374.832 30.5774 374.603 30.7597 374.312 30.9155C374.02 31.0713 373.642 31.1491 373.178 31.1491ZM373.506 29.8814C373.934 29.8814 374.295 29.7687 374.59 29.5433C374.888 29.3146 375.114 28.9981 375.266 28.5938C375.422 28.1894 375.5 27.7187 375.5 27.1818C375.5 26.6515 375.424 26.1875 375.271 25.7898C375.119 25.392 374.895 25.0821 374.6 24.8601C374.305 24.638 373.941 24.527 373.506 24.527C373.059 24.527 372.686 24.643 372.388 24.875C372.089 25.107 371.864 25.4235 371.712 25.8246C371.563 26.2256 371.488 26.678 371.488 27.1818C371.488 27.6922 371.564 28.1513 371.717 28.5589C371.869 28.9666 372.094 29.2898 372.393 29.5284C372.694 29.7637 373.066 29.8814 373.506 29.8814Z\"\n                        fill=\"#D8582B\"\n                    />\n                    <path\n                        d=\"M1026.12 64V53.8182H1029.85C1030.57 53.8182 1031.17 53.9375 1031.64 54.1761C1032.12 54.4115 1032.47 54.7313 1032.71 55.1357C1032.94 55.5367 1033.06 55.9891 1033.06 56.4929C1033.06 56.9171 1032.98 57.2751 1032.83 57.5668C1032.67 57.8551 1032.46 58.0871 1032.2 58.2628C1031.94 58.4351 1031.66 58.5611 1031.34 58.6406V58.7401C1031.68 58.7566 1032.01 58.866 1032.33 59.0682C1032.66 59.267 1032.93 59.5504 1033.14 59.9183C1033.35 60.2862 1033.46 60.7337 1033.46 61.2607C1033.46 61.781 1033.33 62.2483 1033.09 62.6626C1032.85 63.0736 1032.47 63.4001 1031.97 63.642C1031.46 63.8807 1030.81 64 1030.02 64H1026.12ZM1027.65 62.6825H1029.87C1030.61 62.6825 1031.13 62.54 1031.45 62.255C1031.77 61.9699 1031.93 61.6136 1031.93 61.1861C1031.93 60.8646 1031.85 60.5696 1031.69 60.3011C1031.52 60.0327 1031.29 59.8189 1030.99 59.6598C1030.69 59.5007 1030.34 59.4212 1029.93 59.4212H1027.65V62.6825ZM1027.65 58.223H1029.71C1030.06 58.223 1030.37 58.1567 1030.64 58.0241C1030.92 57.8916 1031.14 57.706 1031.3 57.4673C1031.47 57.2254 1031.55 56.9403 1031.55 56.6122C1031.55 56.1913 1031.41 55.8383 1031.11 55.5533C1030.82 55.2682 1030.36 55.1257 1029.75 55.1257H1027.65V58.223ZM1040 60.8331V56.3636H1041.49V64H1040.03V62.6776H1039.95C1039.77 63.0852 1039.49 63.425 1039.1 63.6967C1038.72 63.9652 1038.24 64.0994 1037.67 64.0994C1037.17 64.0994 1036.74 63.9917 1036.36 63.7763C1035.99 63.5575 1035.69 63.2344 1035.48 62.8068C1035.27 62.3793 1035.16 61.8506 1035.16 61.2209V56.3636H1036.65V61.0419C1036.65 61.5623 1036.79 61.9766 1037.08 62.2848C1037.37 62.593 1037.74 62.7472 1038.2 62.7472C1038.48 62.7472 1038.76 62.6776 1039.03 62.5384C1039.31 62.3991 1039.54 62.1887 1039.72 61.907C1039.91 61.6252 1040 61.2673 1040 60.8331ZM1044.97 59.4659V64H1043.49V56.3636H1044.91V57.6065H1045.01C1045.18 57.2022 1045.46 56.8774 1045.83 56.6321C1046.21 56.3868 1046.69 56.2642 1047.26 56.2642C1047.78 56.2642 1048.24 56.3736 1048.63 56.5923C1049.02 56.8078 1049.32 57.1293 1049.54 57.5568C1049.75 57.9844 1049.86 58.513 1049.86 59.1428V64H1048.37V59.3217C1048.37 58.7682 1048.23 58.3357 1047.94 58.0241C1047.65 57.7093 1047.26 57.5518 1046.75 57.5518C1046.41 57.5518 1046.1 57.6264 1045.83 57.7756C1045.57 57.9247 1045.36 58.1435 1045.2 58.4318C1045.05 58.7169 1044.97 59.0616 1044.97 59.4659ZM1054.71 64.1491C1054.09 64.1491 1053.54 63.9917 1053.06 63.6768C1052.58 63.3587 1052.2 62.9062 1051.93 62.3196C1051.66 61.7296 1051.52 61.022 1051.52 60.1967C1051.52 59.3714 1051.66 58.6655 1051.93 58.0788C1052.21 57.4922 1052.59 57.0431 1053.08 56.7315C1053.56 56.42 1054.11 56.2642 1054.72 56.2642C1055.2 56.2642 1055.58 56.3438 1055.86 56.5028C1056.16 56.6586 1056.38 56.8409 1056.54 57.0497C1056.7 57.2585 1056.83 57.4425 1056.92 57.6016H1057.01V53.8182H1058.49V64H1057.04V62.8118H1056.92C1056.83 62.9742 1056.7 63.1598 1056.53 63.3686C1056.37 63.5774 1056.14 63.7597 1055.84 63.9155C1055.55 64.0713 1055.18 64.1491 1054.71 64.1491ZM1055.04 62.8814C1055.47 62.8814 1055.83 62.7687 1056.12 62.5433C1056.42 62.3146 1056.65 61.9981 1056.8 61.5938C1056.96 61.1894 1057.03 60.7187 1057.03 60.1818C1057.03 59.6515 1056.96 59.1875 1056.8 58.7898C1056.65 58.392 1056.43 58.0821 1056.13 57.8601C1055.84 57.638 1055.47 57.527 1055.04 57.527C1054.59 57.527 1054.22 57.643 1053.92 57.875C1053.62 58.107 1053.4 58.4235 1053.24 58.8246C1053.1 59.2256 1053.02 59.678 1053.02 60.1818C1053.02 60.6922 1053.1 61.1513 1053.25 61.5589C1053.4 61.9666 1053.63 62.2898 1053.93 62.5284C1054.23 62.7637 1054.6 62.8814 1055.04 62.8814ZM1062.1 53.8182V64H1060.62V53.8182H1062.1ZM1067.39 64.1541C1066.64 64.1541 1065.99 63.9934 1065.45 63.6719C1064.91 63.3471 1064.49 62.8913 1064.2 62.3047C1063.91 61.7147 1063.76 61.0237 1063.76 60.2315C1063.76 59.4493 1063.91 58.7599 1064.2 58.1634C1064.49 57.5668 1064.9 57.1011 1065.43 56.7663C1065.96 56.4316 1066.58 56.2642 1067.29 56.2642C1067.72 56.2642 1068.14 56.3355 1068.54 56.478C1068.95 56.6205 1069.31 56.8442 1069.63 57.1491C1069.95 57.4541 1070.21 57.8501 1070.39 58.3374C1070.58 58.8213 1070.67 59.4096 1070.67 60.1023V60.6293H1064.6V59.5156H1069.21C1069.21 59.1245 1069.13 58.7782 1068.97 58.4766C1068.82 58.1716 1068.59 57.9313 1068.3 57.7557C1068.02 57.58 1067.68 57.4922 1067.3 57.4922C1066.88 57.4922 1066.52 57.5949 1066.21 57.8004C1065.9 58.0026 1065.66 58.2678 1065.49 58.5959C1065.32 58.9207 1065.24 59.2737 1065.24 59.6548V60.5249C1065.24 61.0353 1065.33 61.4695 1065.51 61.8274C1065.69 62.1854 1065.95 62.4588 1066.27 62.6477C1066.6 62.8333 1066.97 62.9261 1067.41 62.9261C1067.69 62.9261 1067.95 62.8864 1068.18 62.8068C1068.41 62.724 1068.61 62.6013 1068.78 62.4389C1068.95 62.2765 1069.08 62.076 1069.17 61.8374L1070.58 62.0909C1070.46 62.5052 1070.26 62.8681 1069.97 63.1797C1069.68 63.4879 1069.32 63.7282 1068.88 63.9006C1068.45 64.0696 1067.95 64.1541 1067.39 64.1541ZM1075.18 64.1491C1074.56 64.1491 1074.01 63.9917 1073.53 63.6768C1073.05 63.3587 1072.67 62.9062 1072.39 62.3196C1072.12 61.7296 1071.99 61.022 1071.99 60.1967C1071.99 59.3714 1072.12 58.6655 1072.4 58.0788C1072.68 57.4922 1073.06 57.0431 1073.54 56.7315C1074.03 56.42 1074.58 56.2642 1075.19 56.2642C1075.66 56.2642 1076.04 56.3438 1076.33 56.5028C1076.62 56.6586 1076.85 56.8409 1077.01 57.0497C1077.17 57.2585 1077.3 57.4425 1077.39 57.6016H1077.48V53.8182H1078.96V64H1077.51V62.8118H1077.39C1077.3 62.9742 1077.17 63.1598 1077 63.3686C1076.83 63.5774 1076.6 63.7597 1076.31 63.9155C1076.02 64.0713 1075.64 64.1491 1075.18 64.1491ZM1075.51 62.8814C1075.93 62.8814 1076.3 62.7687 1076.59 62.5433C1076.89 62.3146 1077.11 61.9981 1077.27 61.5938C1077.42 61.1894 1077.5 60.7187 1077.5 60.1818C1077.5 59.6515 1077.42 59.1875 1077.27 58.7898C1077.12 58.392 1076.9 58.0821 1076.6 57.8601C1076.31 57.638 1075.94 57.527 1075.51 57.527C1075.06 57.527 1074.69 57.643 1074.39 57.875C1074.09 58.107 1073.86 58.4235 1073.71 58.8246C1073.56 59.2256 1073.49 59.678 1073.49 60.1818C1073.49 60.6922 1073.56 61.1513 1073.72 61.5589C1073.87 61.9666 1074.09 62.2898 1074.39 62.5284C1074.69 62.7637 1075.07 62.8814 1075.51 62.8814Z\"\n                        fill=\"#D8582B\"\n                    />\n                    <path\n                        d=\"M1127.12 386V375.818H1130.85C1131.57 375.818 1132.17 375.937 1132.64 376.176C1133.12 376.411 1133.47 376.731 1133.71 377.136C1133.94 377.537 1134.06 377.989 1134.06 378.493C1134.06 378.917 1133.98 379.275 1133.83 379.567C1133.67 379.855 1133.46 380.087 1133.2 380.263C1132.94 380.435 1132.66 380.561 1132.34 380.641V380.74C1132.68 380.757 1133.01 380.866 1133.33 381.068C1133.66 381.267 1133.93 381.55 1134.14 381.918C1134.35 382.286 1134.46 382.734 1134.46 383.261C1134.46 383.781 1134.33 384.248 1134.09 384.663C1133.85 385.074 1133.47 385.4 1132.97 385.642C1132.46 385.881 1131.81 386 1131.02 386H1127.12ZM1128.65 384.683H1130.87C1131.61 384.683 1132.13 384.54 1132.45 384.255C1132.77 383.97 1132.93 383.614 1132.93 383.186C1132.93 382.865 1132.85 382.57 1132.69 382.301C1132.52 382.033 1132.29 381.819 1131.99 381.66C1131.69 381.501 1131.34 381.421 1130.93 381.421H1128.65V384.683ZM1128.65 380.223H1130.71C1131.06 380.223 1131.37 380.157 1131.64 380.024C1131.92 379.892 1132.14 379.706 1132.3 379.467C1132.47 379.225 1132.55 378.94 1132.55 378.612C1132.55 378.191 1132.41 377.838 1132.11 377.553C1131.82 377.268 1131.36 377.126 1130.75 377.126H1128.65V380.223ZM1141 382.833V378.364H1142.49V386H1141.03V384.678H1140.95C1140.77 385.085 1140.49 385.425 1140.1 385.697C1139.72 385.965 1139.24 386.099 1138.67 386.099C1138.17 386.099 1137.74 385.992 1137.36 385.776C1136.99 385.558 1136.69 385.234 1136.48 384.807C1136.27 384.379 1136.16 383.851 1136.16 383.221V378.364H1137.65V383.042C1137.65 383.562 1137.79 383.977 1138.08 384.285C1138.37 384.593 1138.74 384.747 1139.2 384.747C1139.48 384.747 1139.76 384.678 1140.03 384.538C1140.31 384.399 1140.54 384.189 1140.72 383.907C1140.91 383.625 1141 383.267 1141 382.833ZM1145.97 381.466V386H1144.49V378.364H1145.91V379.607H1146.01C1146.18 379.202 1146.46 378.877 1146.83 378.632C1147.21 378.387 1147.69 378.264 1148.26 378.264C1148.78 378.264 1149.24 378.374 1149.63 378.592C1150.02 378.808 1150.32 379.129 1150.54 379.557C1150.75 379.984 1150.86 380.513 1150.86 381.143V386H1149.37V381.322C1149.37 380.768 1149.23 380.336 1148.94 380.024C1148.65 379.709 1148.26 379.552 1147.75 379.552C1147.41 379.552 1147.1 379.626 1146.83 379.776C1146.57 379.925 1146.36 380.143 1146.2 380.432C1146.05 380.717 1145.97 381.062 1145.97 381.466ZM1155.71 386.149C1155.09 386.149 1154.54 385.992 1154.06 385.677C1153.58 385.359 1153.2 384.906 1152.93 384.32C1152.66 383.73 1152.52 383.022 1152.52 382.197C1152.52 381.371 1152.66 380.665 1152.93 380.079C1153.21 379.492 1153.59 379.043 1154.08 378.732C1154.56 378.42 1155.11 378.264 1155.72 378.264C1156.2 378.264 1156.58 378.344 1156.86 378.503C1157.16 378.659 1157.38 378.841 1157.54 379.05C1157.7 379.259 1157.83 379.442 1157.92 379.602H1158.01V375.818H1159.49V386H1158.04V384.812H1157.92C1157.83 384.974 1157.7 385.16 1157.53 385.369C1157.37 385.577 1157.14 385.76 1156.84 385.915C1156.55 386.071 1156.18 386.149 1155.71 386.149ZM1156.04 384.881C1156.47 384.881 1156.83 384.769 1157.12 384.543C1157.42 384.315 1157.65 383.998 1157.8 383.594C1157.96 383.189 1158.03 382.719 1158.03 382.182C1158.03 381.652 1157.96 381.187 1157.8 380.79C1157.65 380.392 1157.43 380.082 1157.13 379.86C1156.84 379.638 1156.47 379.527 1156.04 379.527C1155.59 379.527 1155.22 379.643 1154.92 379.875C1154.62 380.107 1154.4 380.424 1154.24 380.825C1154.1 381.226 1154.02 381.678 1154.02 382.182C1154.02 382.692 1154.1 383.151 1154.25 383.559C1154.4 383.967 1154.63 384.29 1154.93 384.528C1155.23 384.764 1155.6 384.881 1156.04 384.881ZM1163.1 375.818V386H1161.62V375.818H1163.1ZM1168.39 386.154C1167.64 386.154 1166.99 385.993 1166.45 385.672C1165.91 385.347 1165.49 384.891 1165.2 384.305C1164.91 383.715 1164.76 383.024 1164.76 382.232C1164.76 381.449 1164.91 380.76 1165.2 380.163C1165.49 379.567 1165.9 379.101 1166.43 378.766C1166.96 378.432 1167.58 378.264 1168.29 378.264C1168.72 378.264 1169.14 378.335 1169.54 378.478C1169.95 378.621 1170.31 378.844 1170.63 379.149C1170.95 379.454 1171.21 379.85 1171.39 380.337C1171.58 380.821 1171.67 381.41 1171.67 382.102V382.629H1165.6V381.516H1170.21C1170.21 381.125 1170.13 380.778 1169.97 380.477C1169.82 380.172 1169.59 379.931 1169.3 379.756C1169.02 379.58 1168.68 379.492 1168.3 379.492C1167.88 379.492 1167.52 379.595 1167.21 379.8C1166.9 380.003 1166.66 380.268 1166.49 380.596C1166.32 380.921 1166.24 381.274 1166.24 381.655V382.525C1166.24 383.035 1166.33 383.469 1166.51 383.827C1166.69 384.185 1166.95 384.459 1167.27 384.648C1167.6 384.833 1167.97 384.926 1168.41 384.926C1168.69 384.926 1168.95 384.886 1169.18 384.807C1169.41 384.724 1169.61 384.601 1169.78 384.439C1169.95 384.277 1170.08 384.076 1170.17 383.837L1171.58 384.091C1171.46 384.505 1171.26 384.868 1170.97 385.18C1170.68 385.488 1170.32 385.728 1169.88 385.901C1169.45 386.07 1168.95 386.154 1168.39 386.154ZM1176.18 386.149C1175.56 386.149 1175.01 385.992 1174.53 385.677C1174.05 385.359 1173.67 384.906 1173.39 384.32C1173.12 383.73 1172.99 383.022 1172.99 382.197C1172.99 381.371 1173.12 380.665 1173.4 380.079C1173.68 379.492 1174.06 379.043 1174.54 378.732C1175.03 378.42 1175.58 378.264 1176.19 378.264C1176.66 378.264 1177.04 378.344 1177.33 378.503C1177.62 378.659 1177.85 378.841 1178.01 379.05C1178.17 379.259 1178.3 379.442 1178.39 379.602H1178.48V375.818H1179.96V386H1178.51V384.812H1178.39C1178.3 384.974 1178.17 385.16 1178 385.369C1177.83 385.577 1177.6 385.76 1177.31 385.915C1177.02 386.071 1176.64 386.149 1176.18 386.149ZM1176.51 384.881C1176.93 384.881 1177.3 384.769 1177.59 384.543C1177.89 384.315 1178.11 383.998 1178.27 383.594C1178.42 383.189 1178.5 382.719 1178.5 382.182C1178.5 381.652 1178.42 381.187 1178.27 380.79C1178.12 380.392 1177.9 380.082 1177.6 379.86C1177.31 379.638 1176.94 379.527 1176.51 379.527C1176.06 379.527 1175.69 379.643 1175.39 379.875C1175.09 380.107 1174.86 380.424 1174.71 380.825C1174.56 381.226 1174.49 381.678 1174.49 382.182C1174.49 382.692 1174.56 383.151 1174.72 383.559C1174.87 383.967 1175.09 384.29 1175.39 384.528C1175.69 384.764 1176.07 384.881 1176.51 384.881Z\"\n                        fill=\"#D8582B\"\n                    />\n                </svg>\n            </ImageZoom>\n        </figure>\n    );\n}\n"
  },
  {
    "path": "docs/content/docs/upgrade-guide.mdx",
    "content": "---\ntitle: Upgrade guide\ndescription: Upgrade your Web3.js project to Kit\n---\n\nimport TreeShaking from './tree-shaking';\n\n## Why upgrade?\n\nKit is a complete rewrite of [the Web3.js library](https://github.com/solana-labs/solana-web3.js/). It is designed to be more composable, customizable, and efficient than its predecessor. Its functional design enables the entire library to be tree-shaken, drastically reducing your bundle size. It also takes advantage of modern JavaScript features — such as native Ed25519 key support and `bigint` for large values — resulting in an even smaller bundle, better performance and most importantly, a reduced attack surface for your application.\n\n<Spread>\n    <TreeShaking />\n</Spread>\n\nUnlike Web3.js, Kit doesn't rely on JavaScript classes or other non-tree-shakeable features. This brings us to our first key difference.\n\n## Where's my `Connection` class?\n\nIn Web3.js, the `Connection` class serves as a central entry point, making the library's API easier to discover via a single object. However, this comes at a cost: using the `Connection` class forces you to bundle every method it provides, even if you only use a few. As a result, your users must download the entire library, even when most of it goes unused.\n\nTo avoid this, **Kit does not include a single entry-point class like `Connection`**. Instead, it offers a set of functions that you can import and use as needed. Two key functions replace most of the `Connection` class's functionality: `createSolanaRpc` and `createSolanaRpcSubscriptions`.\n\nThe former, `createSolanaRpc`, returns an `Rpc` object for making RPC requests to a specified endpoint. [Read more about RPCs here](/docs/guides/rpc).\n\n<Spread>\n<div className=\"2xl:flex 2xl:*:flex-1 2xl:items-start 2xl:gap-4\">\n\n```ts title=\"Web3.js\"\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n// Create a `Connection` object.\nconst connection = new Connection('https://api.devnet.solana.com', {\n    commitment: 'confirmed',\n});\n\n// Send RPC requests.\nconst wallet = new PublicKey('1234..5678');\nconst balance = await connection.getBalance(wallet);\n```\n\n```ts twoslash title=\"Kit\"\nimport { address, createSolanaRpc } from '@solana/kit';\n\n// Create an RPC proxy object.\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\n\n// Send RPC requests.\nconst wallet = address('1234..5678');\nconst { value: balance } = await rpc.getBalance(wallet).send();\n```\n\n</div>\n</Spread>\n\nThe latter, `createSolanaRpcSubscriptions`, returns an `RpcSubscriptions` object, which lets you to subscribe to events on the Solana network. [Read more about RPC Subscriptions here](/docs/guides/rpc-subscriptions).\n\n<Spread>\n<div className=\"2xl:flex 2xl:*:flex-1 2xl:items-start 2xl:gap-4\">\n\n```ts title=\"Web3.js\"\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n// Create a `Connection` object with a WebSocket endpoint.\nconst connection = new Connection('https://api.devnet.solana.com', {\n    wsEndpoint: 'wss://api.devnet.solana.com',\n    commitment: 'confirmed',\n});\n\n// Subscribe to RPC events and listen to notifications.\nconst wallet = new PublicKey('1234..5678');\nconnection.onAccountChange(wallet, (accountInfo) => {\n    console.log(accountInfo);\n});\n```\n\n```ts twoslash title=\"Kit\"\nimport { address, createSolanaRpcSubscriptions } from '@solana/kit';\n\n// Create an RPC subscriptions proxy object.\nconst rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.devnet.solana.com');\n\n// Use an `AbortController` to cancel the subscriptions.\nconst abortController = new AbortController();\n\n// Subscribe to RPC events.\nconst wallet = address('1234..5678');\nconst accountNotifications = await rpcSubscriptions\n    .accountNotifications(wallet, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: abortController.signal });\n\ntry {\n    // Listen to event notifications.\n    for await (const accountInfo of accountNotifications) {\n        console.log(accountInfo);\n    }\n} catch (e) {\n    // Gracefully handle subscription disconnects.\n}\n```\n\n</div>\n</Spread>\n\nNote that, although `Rpc` and `RpcSubscriptions` look like classes, they are actually [`Proxy` objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy). This means they dynamically construct RPC requests or subscriptions based on method names and parameters. TypeScript is then used to provide type safety for the RPC API, making it easy to discover available RPC methods while keeping the library lightweight. Regardless of whether your RPC supports 1 method or 100, the bundle size remains unchanged.\n\n## Introducing Kit clients\n\nThe functional approach above gives you maximum treeshakability, but it can feel verbose compared to Web3.js's `Connection`. Kit addresses this with **plugin-based clients** — a single object that bundles the functionality you need while still letting you choose what goes in. You cherry-pick plugins, so you typically only bundle what you actually use.\n\n<Spread>\n<div className=\"2xl:flex 2xl:*:flex-1 2xl:items-start 2xl:gap-4\">\n\n```ts title=\"Web3.js\"\nimport { Connection, PublicKey } from '@solana/web3.js';\n\n// Create a `Connection` object.\nconst connection = new Connection('https://api.devnet.solana.com');\n\n// Use the connection.\nconst wallet = new PublicKey('1234..5678');\nconst balance = await connection.getBalance(wallet);\n```\n\n```ts twoslash title=\"Kit\"\nimport { address, createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signer } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\n\n// Create a client with the plugins you need.\nconst payer = await generateKeyPairSigner();\nconst client = createClient().use(signer(payer)).use(solanaDevnetRpc()).use(systemProgram());\n\n// Use the client.\nconst wallet = address('1234..5678');\nconst { value: balance } = await client.rpc.getBalance(wallet).send();\n```\n\n</div>\n</Spread>\n\nA Kit client is an immutable JavaScript object built by chaining `.use()` calls. Each plugin adds capabilities to the client — like signer roles, RPC access, transaction sending, or typed program instructions. Start with `createClient()` from `@solana/kit`, add signer plugins such as `signer(payer)`, then apply RPC bundles like `solanaDevnetRpc()` to install RPC, subscriptions, transaction planning, sending, and devnet airdrops. You may then extend it with program plugins like `systemProgram()` and `tokenProgram()` to add typed access to the accounts and instructions of those programs.\n\nThe rest of this guide uses a client for the Kit examples. To learn more about the plugin system, see [Plugins](/docs/plugins).\n\n## Fetching and decoding accounts\n\nFetching onchain accounts is as simple as calling the appropriate RPC method on the client. Kit also provides helper functions like `fetchEncodedAccount`, which returns a `MaybeAccount` object with an `exists` boolean to indicate whether the account is present onchain:\n\n<Spread>\n<div className=\"2xl:flex 2xl:*:flex-1 2xl:items-start 2xl:gap-4\">\n\n```ts title=\"Web3.js\"\nimport { PublicKey } from '@solana/web3.js';\n\nconst wallet = new PublicKey('1234..5678');\nconst account = await connection.getAccountInfo(wallet);\n```\n\n```ts twoslash title=\"Kit\"\nimport { address, assertAccountExists, fetchEncodedAccount } from '@solana/kit';\n// ---cut-start---\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signer } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst payer = await generateKeyPairSigner();\nconst client = createClient().use(signer(payer)).use(solanaDevnetRpc()).use(systemProgram());\n// ---cut-end---\n\nconst wallet = address('1234..5678');\nconst account = await fetchEncodedAccount(client.rpc, wallet);\nassertAccountExists(account);\naccount.data satisfies Uint8Array;\n```\n\n</div>\n</Spread>\n\nTo decode raw account data, Kit provides a composable serialization library called **codecs**. You can define a codec for any account type by combining primitives:\n\n```ts twoslash title=\"Kit\"\nimport {\n    address,\n    Address,\n    addCodecSizePrefix,\n    getAddressCodec,\n    getStructCodec,\n    getU32Codec,\n    getU8Codec,\n    getUtf8Codec,\n} from '@solana/kit';\n\ntype Person = {\n    age: number;\n    discriminator: number;\n    name: string;\n    wallet: Address;\n};\n\nconst personCodec = getStructCodec([\n    ['discriminator', getU8Codec()], // A single-byte account discriminator.\n    ['wallet', getAddressCodec()], // A 32-byte account address.\n    ['age', getU8Codec()], // An 8-bit unsigned integer.\n    ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())], // A UTF-8 string with a 32-bit length prefix.\n]);\n\nconst bytes = personCodec.encode({\n    age: 42,\n    discriminator: 0,\n    name: 'Alice',\n    wallet: address('1234..5678'),\n});\n```\n\n[You can read more about codecs here](/docs/advanced-guides/codecs).\n\nOnce you have a codec, you can use `decodeAccount` to transform an encoded account into a decoded one:\n\n```ts twoslash title=\"Kit\"\nimport { address, decodeAccount, fetchEncodedAccount } from '@solana/kit';\n// ---cut-start---\nimport {\n    Address,\n    createSolanaRpc,\n    addCodecSizePrefix,\n    getAddressCodec,\n    getStructCodec,\n    getU32Codec,\n    getU8Codec,\n    getUtf8Codec,\n} from '@solana/kit';\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\ntype Person = {\n    age: number;\n    discriminator: number;\n    name: string;\n    wallet: Address;\n};\nconst personCodec = getStructCodec([\n    ['discriminator', getU8Codec()],\n    ['wallet', getAddressCodec()],\n    ['age', getU8Codec()],\n    ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n]);\n// ---cut-end---\n\nconst wallet = address('1234..5678');\nconst account = await fetchEncodedAccount(rpc, wallet);\nconst decodedAccount = decodeAccount(account, personCodec);\n\nif (decodedAccount.exists) {\n    decodedAccount.data satisfies Person;\n}\n```\n\n## Using program libraries\n\nFortunately, you don't need to create a custom codec for every account. Kit provides client libraries for many popular Solana programs, [generated via Codama](https://github.com/codama-idl/codama), ensuring a consistent structure across them. These libraries can be used as standalone imports or as client plugins.\n\nAs client plugins, they add typed `.accounts` and `.instructions` namespaces to your client. For example, here's how to fetch and decode a `Nonce` account using the System program:\n\n<Spread>\n<div className=\"2xl:flex 2xl:*:flex-1 2xl:items-start 2xl:gap-4\">\n\n```ts title=\"Web3.js\"\nimport { NonceAccount, PublicKey } from '@solana/web3.js';\n\nconst wallet = new PublicKey('1234..5678');\nconst accountInfo = await connection.getAccountInfo(wallet);\nconst nonce = NonceAccount.fromAccountData(accountInfo.data);\n```\n\n```ts twoslash title=\"Kit\"\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signer } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst payer = await generateKeyPairSigner();\nconst client = createClient().use(signer(payer)).use(solanaDevnetRpc()).use(systemProgram());\n// ---cut-end---\n\nconst nonce = await client.system.accounts.nonce.fetch(address('1234..5678'));\n```\n\n</div>\n</Spread>\n\nThey can also be used as standalone functions without a client:\n\n```ts twoslash title=\"Kit\"\nimport { address } from '@solana/kit';\nimport { fetchNonce } from '@solana-program/system';\n// ---cut-start---\nimport { createSolanaRpc } from '@solana/kit';\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\n// ---cut-end---\n\nconst account = await fetchNonce(rpc, address('1234..5678'));\n```\n\n[Check out the \"Available plugins\" page](/docs/plugins/available-plugins) for a list of available program libraries compatible with Kit.\n\n## Creating instructions\n\nProgram libraries also provide functions for creating instructions. With a client, you can create instructions through the program's typed namespace:\n\n<Spread>\n<div className=\"2xl:flex 2xl:*:flex-1 2xl:items-start 2xl:gap-4\">\n\n```ts title=\"Web3.js\"\nimport { PublicKey, SystemProgram } from '@solana/web3.js';\n\nconst transferSol = SystemProgram.transfer({\n    fromPubkey: new PublicKey('2222..2222'),\n    toPubkey: new PublicKey('3333..3333'),\n    lamports: 1_000_000_000, // 1 SOL.\n});\n```\n\n```ts twoslash title=\"Kit\"\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signer } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst payer = await generateKeyPairSigner();\nconst client = createClient().use(signer(payer)).use(solanaDevnetRpc()).use(systemProgram());\n// ---cut-end---\n\nconst transferSol = client.system.instructions.transferSol({\n    source: client.payer,\n    destination: address('3333..3333'),\n    amount: 1_000_000_000, // 1 SOL.\n});\n```\n\n</div>\n</Spread>\n\nWithout a client, you can use the standalone instruction helpers directly. In this case, Kit uses `TransactionSigner` objects for accounts that need to sign. This allows signers to be extracted from built transactions later, enabling automatic transaction signing without manually tracking which keys need to sign.\n\n```ts twoslash title=\"Kit\"\nimport { address, generateKeyPairSigner } from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\n\nconst source = await generateKeyPairSigner();\nconst transferSol = getTransferSolInstruction({\n    source,\n    destination: address('3333..3333'),\n    amount: 1_000_000_000, // 1 SOL.\n});\n```\n\n## Sending transactions\n\nIn Web3.js, sending a transaction involves creating a `Transaction` object, adding instructions, signing it, and sending it. Kit clients reduce this to a single call:\n\n<Spread>\n<div className=\"2xl:flex 2xl:*:flex-1 2xl:items-start 2xl:gap-4\">\n\n```ts title=\"Web3.js\"\nimport {\n    Keypair,\n    PublicKey,\n    sendAndConfirmTransaction,\n    SystemProgram,\n    Transaction,\n} from '@solana/web3.js';\n\nconst payer = Keypair.generate();\n\nconst transaction = new Transaction().add(\n    SystemProgram.transfer({\n        fromPubkey: payer.publicKey,\n        toPubkey: new PublicKey('3333..3333'),\n        lamports: 1_000_000_000,\n    }),\n);\n\nconst signature = await sendAndConfirmTransaction(connection, transaction, [payer]);\n```\n\n```ts twoslash title=\"Kit\"\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signer } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst payer = await generateKeyPairSigner();\nconst client = createClient().use(signer(payer)).use(solanaDevnetRpc()).use(systemProgram());\n// ---cut-end---\n\nconst result = await client.system.instructions\n    .transferSol({\n        source: client.payer,\n        destination: address('3333..3333'),\n        amount: 1_000_000_000,\n    })\n    .sendTransaction();\n\nconst signature = result.context.signature;\n```\n\n</div>\n</Spread>\n\nWith a client, building the transaction message, setting the fee payer, fetching a recent blockhash, signing, sending, and confirming are all handled for you.\n\nYou can also send multiple instructions as a single atomic transaction using `client.sendTransaction([...])`:\n\n```ts twoslash title=\"Kit\"\nimport { address } from '@solana/kit';\n// ---cut-start---\nimport { createClient, generateKeyPairSigner } from '@solana/kit';\nimport { solanaDevnetRpc } from '@solana/kit-plugin-rpc';\nimport { signer } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst payer = await generateKeyPairSigner();\nconst client = createClient().use(signer(payer)).use(solanaDevnetRpc()).use(systemProgram());\n// ---cut-end---\n\nawait client.sendTransaction([\n    client.system.instructions.transferSol({\n        source: client.payer,\n        destination: address('3333..3333'),\n        amount: 500_000_000,\n    }),\n    client.system.instructions.transferSol({\n        source: client.payer,\n        destination: address('4444..4444'),\n        amount: 500_000_000,\n    }),\n]);\n```\n\nFor full control over each of these steps, you can build transactions manually. Kit uses an immutable transaction model where each helper returns a new transaction object with an updated type. The `pipe` function lets you chain these helpers together:\n\n```ts twoslash title=\"Kit\"\nimport {\n    appendTransactionMessageInstructions,\n    assertIsTransactionWithBlockhashLifetime,\n    createTransactionMessage,\n    getSignatureFromTransaction,\n    pipe,\n    sendAndConfirmTransactionFactory,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signTransactionMessageWithSigners,\n} from '@solana/kit';\nimport { getCreateAccountInstruction } from '@solana-program/system';\nimport { getInitializeMintInstruction, TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';\n// ---cut-start---\nimport {\n    address,\n    createSolanaRpc,\n    createSolanaRpcSubscriptions,\n    generateKeyPairSigner,\n} from '@solana/kit';\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\nconst rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.devnet.solana.com');\nconst space = null as unknown as Parameters<typeof getCreateAccountInstruction>[0]['space'];\nconst lamports = null as unknown as Parameters<typeof getCreateAccountInstruction>[0]['lamports'];\n// ---cut-end---\n\n// Create signers — Kit uses the native CryptoKeyPair API for secure key management.\nconst [payer, mint] = await Promise.all([generateKeyPairSigner(), generateKeyPairSigner()]);\n\n// Create instructions — signers are attached directly to instructions.\nconst createAccount = getCreateAccountInstruction({\n    payer,\n    newAccount: mint,\n    space,\n    lamports,\n    programAddress: TOKEN_PROGRAM_ADDRESS,\n});\nconst initializeMint = getInitializeMintInstruction({\n    mint: mint.address,\n    mintAuthority: address('1234..5678'),\n    decimals: 2,\n});\n\n// Build the transaction message.\nconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\nconst transactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    (tx) => setTransactionMessageFeePayerSigner(payer, tx),\n    (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n    (tx) => appendTransactionMessageInstructions([createAccount, initializeMint], tx),\n);\n\n// Sign — signers are extracted automatically from the transaction message.\nconst signedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n\n// Send and confirm.\nassertIsTransactionWithBlockhashLifetime(signedTransaction);\nconst sendAndConfirm = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\nconst signature = getSignatureFromTransaction(signedTransaction);\nawait sendAndConfirm(signedTransaction, { commitment: 'confirmed' });\n```\n\nA few things to note about the manual approach:\n\n- **Signers**: Kit uses `TransactionSigner` objects (highlighted above) instead of raw keypairs. Since signers are attached to instructions and the fee payer, `signTransactionMessageWithSigners` can sign the transaction automatically without needing to pass signers separately. [Read more about signers here](/docs/advanced-guides/signers).\n- **Immutability**: Each transaction helper returns a new object with a narrower type, ensuring that required fields (fee payer, lifetime, etc.) are set before the transaction can be signed or sent. The `pipe` function chains these transformations together.\n- **Signatures**: Transaction signatures are deterministically known before sending. The `getSignatureFromTransaction` helper extracts the signature from the signed transaction, and `sendAndConfirm` does not return it.\n\n## Closing words\n\nWe've now explored the key differences between Web3.js and Kit, giving you a solid foundation for upgrading your project. Since Kit is a complete rewrite, there's no simple step-by-step migration guide, and the process may take some time.\n\nTo ease the transition, Kit provides a `@solana/compat` package, which allows for incremental migration. This package includes functions that convert core types — such as public keys and transactions — between Web3.js and Kit. This means you can start integrating Kit without having to refactor your entire project at once.\n\n```ts twoslash title=\"Kit\"\nimport { Keypair, PublicKey } from '@solana/web3.js';\nimport { createSignerFromKeyPair } from '@solana/kit';\nimport {\n    fromLegacyKeypair,\n    fromLegacyPublicKey,\n    fromLegacyTransactionInstruction,\n    fromVersionedTransaction,\n} from '@solana/compat';\n// ---cut-start---\nconst transactionInstruction = null as unknown as Parameters<\n    typeof fromLegacyTransactionInstruction\n>[0];\nconst versionedTransaction = null as unknown as Parameters<typeof fromVersionedTransaction>[0];\n// ---cut-end---\n\n// Convert `PublicKeys`.\nconst address = fromLegacyPublicKey(new PublicKey('1234..5678'));\n\n// Convert `Keypairs`.\nconst cryptoKeypair = await fromLegacyKeypair(Keypair.generate());\nconst signer = await createSignerFromKeyPair(cryptoKeypair);\n\n// Convert `TransactionInstruction`.\nconst instruction = fromLegacyTransactionInstruction(transactionInstruction);\n\n// Convert `VersionedTransaction`.\nconst transaction = fromVersionedTransaction(versionedTransaction);\n```\n\nIf you're using a Kit client, the upgrade is even more straightforward — the client-based API is conceptually closer to Web3.js's `Connection` model while still giving you the benefits of Kit's modular architecture. Check out the [Getting Started](/docs/getting-started) tutorial to see the client-based approach in action or explore [Plugins](/docs/plugins) to learn more about the plugin system.\n"
  },
  {
    "path": "docs/content/home/example-codecs.mdx",
    "content": "---\ntitle: Codecs Example\n---\n\n{/* Please keep visible code between 4 to 8 lines of code. */}\n\n```ts\nconst personCodec = getStructCodec([\n    ['age', getU8Codec()],\n    ['name', addCodecSizePrefix(getUtf8Codec(), getU16Codec())],\n]);\n\nconst bytes = personCodec.encode({ age: 30, name: 'Alice' });\nconst person = personCodec.decode(bytes);\n```\n"
  },
  {
    "path": "docs/content/home/example-rpc-subscriptions.mdx",
    "content": "---\ntitle: RPC Subscriptions Example\n---\n\n{/* Please keep visible code between 4 to 8 lines of code. */}\n\n```ts\nconst rpcSubscriptions = createSolanaRpcSubscriptions('ws://api.mainnet-beta.solana.com');\nconst accountNotifications = await rpcSubscriptions\n    .accountNotifications(myAccount, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: abortController.signal });\n\nfor await (const accountNotification of accountNotifications) {\n    console.log(accountNotification);\n}\n```\n"
  },
  {
    "path": "docs/content/home/example-rpc.mdx",
    "content": "---\ntitle: RPC Example\n---\n\n{/* Please keep visible code between 4 to 8 lines of code. */}\n\n```ts\nconst rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');\n\nconst { value: balance } = await rpc.getBalance(myWallet).send();\nconst { value: accountInfo } = await rpc.getAccountInfo(myAccount).send();\nconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n```\n"
  },
  {
    "path": "docs/content/home/example-signers.mdx",
    "content": "---\ntitle: Signers Example\n---\n\n{/* Please keep visible code between 4 to 8 lines of code. */}\n\n```ts\nconst keypairSigner = await generateKeyPairSigner();\n\nconst walletSigner = useWalletAccountTransactionSigner(wallet, 'solana:mainnet-beta');\n\nconst noopSigner = createNoopSigner(myAddress);\n```\n"
  },
  {
    "path": "docs/content/home/example-solana-programs.mdx",
    "content": "---\ntitle: Solana Programs Example\n---\n\n{/* Please keep visible code between 4 to 8 lines of code. */}\n\n```ts\nimport { getTransferSolInstruction } from '@solana-program/system';\nconst transferSol = getTransferSolInstruction({ source, destination, amount });\n\nimport { fetchMint } from '@solana-program/token';\nconst mintAccount = await fetchMint(rpc, mintAddress);\n```\n"
  },
  {
    "path": "docs/content/home/example-transactions.mdx",
    "content": "---\ntitle: Transactions Example\n---\n\n{/* Please keep visible code between 4 to 8 lines of code. */}\n\n```ts\nconst transactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    (tx) => setTransactionMessageFeePayerSigner(payer, tx),\n    (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n    (tx) => appendTransactionMessageInstructions([createAccountIx, initializeMintIx], tx),\n);\n```\n"
  },
  {
    "path": "docs/content/recipes/airdropping-tokens.mdx",
    "content": "---\ntitle: Airdropping tokens\ndescription: Airdrop tokens to many wallets using parallel transaction plans\n---\n\nThis recipe airdrops a freshly minted SPL token to many recipient wallets at once. It demonstrates how to compose an [instruction plan](/docs/guides/sending-multiple-transactions) that creates the mint sequentially first and then mints to every recipient in parallel — letting Kit pack the work into as few transactions as possible and send the parallel batches concurrently.\n\n## Set up a client\n\nInstall Kit and the plugins you need.\n\n```package-install\n@solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token\n```\n\nCompose a client with a generated signer, a local RPC connection, an airdrop to fund the signer, and the Token program plugin. Make sure a local validator is running (`solana-test-validator`) before this code executes.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(100_000_000_000n)))\n    .use(tokenProgram());\n```\n\nThe signer is funded with 100 SOL because creating ATAs costs a small amount of rent for each recipient.\n\n## Generate the recipients\n\nFor the demo, generate 100 random destination addresses up front. In a real airdrop, this list would come from a database, a CSV, or some other source.\n\n```ts twoslash\nimport { generateKeyPairSigner } from '@solana/kit';\n\nconst recipients = await Promise.all(\n    Array.from({ length: 100 }, async () => (await generateKeyPairSigner()).address),\n);\n```\n\n## Build the airdrop plan\n\nCompose the work as a `sequentialInstructionPlan` whose first child creates the mint and whose second child is a `parallelInstructionPlan` containing one mint-to-ATA plan per recipient.\n\n```ts twoslash\nimport {\n    Address,\n    generateKeyPairSigner,\n    parallelInstructionPlan,\n    sequentialInstructionPlan,\n} from '@solana/kit';\nconst recipients = null as unknown as Address[];\n// ---cut-start---\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(100_000_000_000n)))\n    .use(tokenProgram());\n// ---cut-end---\nconst mint = await generateKeyPairSigner();\n\nconst instructionPlan = sequentialInstructionPlan([\n    client.token.instructions.createMint({\n        newMint: mint,\n        decimals: 6,\n        mintAuthority: client.identity.address,\n    }),\n    parallelInstructionPlan(\n        await Promise.all(\n            recipients.map((owner) =>\n                client.token.instructions.mintToATA({\n                    mint: mint.address,\n                    owner,\n                    mintAuthority: client.identity,\n                    amount: 1_000n * 10n ** 6n, // 1,000 tokens\n                    decimals: 6,\n                }),\n            ),\n        ),\n    ),\n]);\n```\n\nThe mint must exist before any recipient can receive tokens, which is why the outer plan is sequential. Each `mintToATA` is independent of the others, so wrapping them in a `parallelInstructionPlan` lets Kit run them concurrently. The Token plugin's `mintToATA` is asynchronous because it derives each recipient's ATA address up front, so wrap the whole list in a single `Promise.all`.\n\n## Send and inspect the results\n\n`client.sendTransactions(plan)` plans, signs, sends, and confirms every transaction in the tree. Wrap the call in [`passthroughFailedTransactionPlanExecution`](/docs/advanced-guides/errors#walking-transaction-plan-results) so a failure on one transaction does not throw — you keep the full result tree and can decide what to do per recipient.\n\n```ts twoslash\nimport {\n    flattenTransactionPlanResult,\n    InstructionPlan,\n    passthroughFailedTransactionPlanExecution,\n} from '@solana/kit';\nconst instructionPlan = null as unknown as InstructionPlan;\n// ---cut-start---\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(100_000_000_000n)))\n    .use(tokenProgram());\n// ---cut-end---\nconst result = await passthroughFailedTransactionPlanExecution(\n    client.sendTransactions(instructionPlan),\n);\n\nfor (const [index, single] of flattenTransactionPlanResult(result).entries()) {\n    if (single.status === 'successful') {\n        console.log(`#${index} ✅ ${single.context.signature}`);\n    } else if (single.status === 'failed') {\n        console.error(`#${index} ❌ ${single.error.message}`);\n    } else {\n        console.warn(`#${index} ⏭️  canceled`);\n    }\n}\n```\n\n`flattenTransactionPlanResult` collapses the tree into one entry per transaction in the order they were planned, so iterating the array is enough to log each outcome individually. For a single bottom-line view across the whole airdrop, [`summarizeTransactionPlanResult`](/docs/advanced-guides/errors#walking-transaction-plan-results) returns success/failure/cancellation counts and a top-level `successful` boolean.\n\n## Next steps\n\n- [Sending multiple transactions](/docs/guides/sending-multiple-transactions) — the full guide on multi-transaction operations and instruction plan composition.\n- [Advanced guides — Errors](/docs/advanced-guides/errors) — deep dive on `TransactionPlanResult`, walking failed trees, and program-specific errors.\n- [Creating a token](/recipes/creating-a-token) — the simpler single-recipient version of this flow.\n"
  },
  {
    "path": "docs/content/recipes/creating-a-token.mdx",
    "content": "---\ntitle: Creating a token\ndescription: Create a new SPL token mint, mint tokens, and transfer them\n---\n\nThis recipe walks through the full lifecycle of an SPL token: creating a mint, minting tokens to your own associated token account (ATA), and transferring some to another wallet. It runs against a local validator so you can experiment without spending mainnet SOL.\n\n## Set up a client\n\nInstall Kit and the plugins you need.\n\n```package-install\n@solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token\n```\n\nCompose a client with a generated signer, a local RPC connection, an airdrop to fund the signer, and the Token program plugin. Make sure a local validator is running (`solana-test-validator`) before this code executes.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)))\n    .use(tokenProgram());\n```\n\n## Create the mint\n\nGenerate a fresh signer for the mint account and ask the Token program plugin to build a `createMint` instruction plan. The plan creates the mint account, funds it for rent exemption, and initializes it as a Token mint — all in one atomic operation.\n\n```ts twoslash\nimport { generateKeyPairSigner } from '@solana/kit';\n// ---cut-start---\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)))\n    .use(tokenProgram());\n// ---cut-end---\nconst mint = await generateKeyPairSigner();\n\nawait client.token.instructions\n    .createMint({\n        newMint: mint,\n        decimals: 9,\n        mintAuthority: client.identity.address,\n    })\n    .sendTransaction();\n\nconsole.log(`🎉 Mint created: ${mint.address}`);\n```\n\nThe mint authority is the signer allowed to mint new tokens later. Setting it to `client.identity.address` makes the current client's identity the authority, which is what you want for a recipe like this one.\n\n## Mint tokens to your ATA\n\nTokens live in associated token accounts (ATAs) — one ATA per `(owner, mint)` pair. The plugin's `mintToATA` helper derives the ATA address, creates it if it does not exist yet, and mints tokens to it in a single instruction plan.\n\n```ts twoslash\nimport { Address } from '@solana/kit';\nconst mintAddress = null as unknown as Address;\n// ---cut-start---\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)))\n    .use(tokenProgram());\n// ---cut-end---\nawait client.token.instructions\n    .mintToATA({\n        mint: mintAddress,\n        owner: client.identity.address,\n        mintAuthority: client.identity,\n        amount: 1_000n * 10n ** 9n, // 1,000 tokens with 9 decimals\n        decimals: 9,\n    })\n    .sendTransaction();\n```\n\n`mintToATA` is asynchronous because it derives the ATA address before building the plan, but the `.sendTransaction()` shortcut is exposed on the returned promise itself — a single `await` on the call is enough. Pass the same `decimals` you used when creating the mint; the plugin uses it as a safety check to make sure you are minting against the mint you think you are.\n\n## Transfer tokens to a recipient\n\nSending tokens to another wallet follows the same pattern as minting: the plugin derives both the source and destination ATAs, creates the destination if it doesn't exist, and issues the transfer.\n\n```ts twoslash\nimport { address, Address } from '@solana/kit';\nconst mintAddress = null as unknown as Address;\n// ---cut-start---\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { tokenProgram } from '@solana-program/token';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)))\n    .use(tokenProgram());\n// ---cut-end---\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n\nawait client.token.instructions\n    .transferToATA({\n        mint: mintAddress,\n        authority: client.identity,\n        recipient,\n        amount: 100n * 10n ** 9n, // 100 tokens\n        decimals: 9,\n    })\n    .sendTransaction();\n```\n\nThe `authority` is the owner of the source tokens, which here is the same identity that minted them. The plugin pulls tokens out of `authority`'s ATA for the given mint, creates the recipient's ATA if needed, and deposits the tokens.\n\n## Next steps\n\n- [Using program plugins](/docs/guides/using-program-plugins) — explore everything `client.token` and other program namespaces expose.\n- [Fetching accounts](/docs/guides/fetching-accounts) — read the mint and token account balances back from the chain.\n- [Airdropping tokens](/recipes/airdropping-tokens) — extend this recipe to many recipients in parallel.\n"
  },
  {
    "path": "docs/content/recipes/index.mdx",
    "content": "---\ntitle: Recipes\ndescription: Quick how-to guides for common Solana tasks\n---\n\nRecipes are short, copy-pasteable walkthroughs for specific tasks. Each one starts with a working setup, then walks through the steps you need to ship a feature — sending SOL, creating a token, airdropping tokens to many wallets, and so on.\n\nIf you are new to Kit, start with the [Getting started](/docs/getting-started) tutorial first. If you are looking for deeper, reference-style coverage, the [Guides](/docs/guides) section is the next step. Recipes sit between the two: focused, end-to-end snippets you can drop into a project today.\n"
  },
  {
    "path": "docs/content/recipes/meta.json",
    "content": "{\n    \"title\": \"Recipes\",\n    \"root\": true,\n    \"pages\": [\"...\", \"transferring-sol\", \"creating-a-token\", \"airdropping-tokens\"]\n}\n"
  },
  {
    "path": "docs/content/recipes/transferring-sol.mdx",
    "content": "---\ntitle: Transferring SOL\ndescription: Send SOL from one account to another with error handling\n---\n\nThis recipe walks through sending SOL from your client's payer to another address. It uses a local validator so you can run it end-to-end without touching real funds, and shows how to surface a useful error when a transfer fails.\n\n## Set up a client\n\nInstall Kit and the plugins you need.\n\n```package-install\n@solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/system\n```\n\nCompose a client with a generated signer, a local RPC connection, an airdrop to fund the signer, and the System program plugin. Make sure a local validator is running (`solana-test-validator`) before this code executes.\n\n```ts twoslash\nimport { createClient, lamports } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\n\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)))\n    .use(systemProgram());\n```\n\n## Send the transfer\n\nUse `client.system.instructions.transferSol` to build the transfer instruction, then call `.sendTransaction()` to plan, sign, send, and confirm it in one step.\n\n```ts twoslash\nimport { address, lamports } from '@solana/kit';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)))\n    .use(systemProgram());\n// ---cut-end---\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n\nconst result = await client.system.instructions\n    .transferSol({\n        source: client.payer,\n        destination: recipient,\n        amount: lamports(10_000_000n), // 0.01 SOL\n    })\n    .sendTransaction();\n\nconsole.log(`✅ ${result.context.signature}`);\n```\n\nThe shortcut is equivalent to passing the instruction to `client.sendTransaction([...])`. Reach for the array form when you want to combine several instructions into a single atomic transaction.\n\n## Handle errors\n\nWhen a transfer fails, `client.sendTransaction(...)` throws a [`SolanaError`](/docs/advanced-guides/errors) with the `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION` code. Wrapping the call lets you surface a useful message and inspect the underlying program error.\n\n```ts twoslash\nimport {\n    address,\n    isSolanaError,\n    lamports,\n    SingleTransactionPlanResult,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION,\n} from '@solana/kit';\nimport { getSystemErrorMessage, isSystemError } from '@solana-program/system';\n// ---cut-start---\nimport { createClient } from '@solana/kit';\nimport { solanaLocalRpc } from '@solana/kit-plugin-rpc';\nimport { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';\nimport { systemProgram } from '@solana-program/system';\nconst client = await createClient()\n    .use(generatedSigner())\n    .use(solanaLocalRpc())\n    .use(airdropSigner(lamports(1_000_000_000n)))\n    .use(systemProgram());\nconst recipient = address('GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ');\n// ---cut-end---\ntry {\n    await client.system.instructions\n        .transferSol({\n            source: client.payer,\n            destination: recipient,\n            amount: lamports(10_000_000n),\n        })\n        .sendTransaction();\n} catch (e) {\n    if (!isSolanaError(e, SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION)) throw e;\n\n    const result = e.context.transactionPlanResult as SingleTransactionPlanResult;\n    const transactionMessage = result.context.message ?? result.plannedMessage;\n    const cause = e.cause as Error;\n\n    if (isSystemError(cause, transactionMessage)) {\n        console.error(`System program error: ${getSystemErrorMessage(cause.context.code)}`);\n    } else {\n        console.error('Transfer failed:', e.message);\n    }\n}\n```\n\n`error.cause` carries the underlying error, and `error.context.transactionPlanResult` carries the planned transaction message. Pairing them with `isSystemError` and `getSystemErrorMessage` from `@solana-program/system` turns an opaque program error code into a human-readable message — invaluable when something like an underfunded source account causes the transfer to fail.\n\n## Next steps\n\n- [Sending transactions](/docs/guides/sending-transactions) — the full guide on single transactions, including planning and configuration.\n- [Advanced guides — Errors](/docs/advanced-guides/errors) — deep dive on `SolanaError` codes and program-specific error parsing.\n"
  },
  {
    "path": "docs/next.config.mjs",
    "content": "import { createMDX } from 'fumadocs-mdx/next';\n\nconst withMDX = createMDX();\n\nconst docsRouteRedirects = [\n    ['compatible-clients', 'plugins/available-plugins'],\n    ['concepts', 'advanced-guides'],\n    ['concepts/codecs', 'advanced-guides/codecs'],\n    ['concepts/errors', 'advanced-guides/errors'],\n    ['concepts/instruction-plans', 'advanced-guides/instruction-plans'],\n    ['concepts/keypairs', 'advanced-guides/keypairs'],\n    ['concepts/offchain-messages', 'advanced-guides/offchain-messages'],\n    ['concepts/rpc', 'guides/rpc'],\n    ['concepts/rpc-subscriptions', 'guides/rpc-subscriptions'],\n    ['concepts/signers', 'advanced-guides/signers'],\n    ['concepts/transactions', 'advanced-guides/transactions'],\n    ['getting-started/setup', 'advanced-guides/kit-without-a-client'],\n    ['getting-started/signers', 'advanced-guides/kit-without-a-client'],\n    ['getting-started/instructions', 'advanced-guides/kit-without-a-client'],\n    ['getting-started/build-transaction', 'advanced-guides/kit-without-a-client'],\n    ['getting-started/send-transaction', 'advanced-guides/kit-without-a-client'],\n    ['getting-started/fetch-account', 'advanced-guides/kit-without-a-client'],\n];\n\nconst createDocsRedirects = () =>\n    docsRouteRedirects.flatMap(([sourcePath, destinationPath]) => [\n        {\n            source: `/docs/${sourcePath}`,\n            destination: `/docs/${destinationPath}`,\n            permanent: true,\n        },\n        {\n            source: `/docs/${sourcePath}.mdx`,\n            destination: `/docs/${destinationPath}.mdx`,\n            permanent: true,\n        },\n    ]);\n\n/** @type {import('next').NextConfig} */\nconst config = {\n    redirects: async () => createDocsRedirects(),\n    reactStrictMode: true,\n    serverExternalPackages: ['twoslash', 'typescript'],\n    rewrites: async () => {\n        return [\n            {\n                source: '/api/:path*.mdx',\n                destination: '/llms.mdx/api/:path*',\n            },\n            {\n                source: '/docs/:path*.mdx',\n                destination: '/llms.mdx/docs/:path*',\n            },\n            {\n                source: '/recipes/:path*.mdx',\n                destination: '/llms.mdx/recipes/:path*',\n            },\n        ];\n    },\n};\n\nexport default withMDX(config);\n"
  },
  {
    "path": "docs/package.json",
    "content": "{\n    \"name\": \"@solana/kit-docs\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"scripts\": {\n        \"build\": \"NODE_OPTIONS='--max-old-space-size=8192' next build\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" next dev --turbo\",\n        \"start\": \"next start\",\n        \"postinstall\": \"fumadocs-mdx\",\n        \"prebuild\": \"./build-api-docs.sh\",\n        \"predev\": \"./build-api-docs.sh\"\n    },\n    \"dependencies\": {\n        \"@inkeep/cxkit-react\": \"^0.5.116\",\n        \"@radix-ui/react-popover\": \"^1.1.15\",\n        \"class-variance-authority\": \"^0.7.1\",\n        \"fumadocs-core\": \"15.2.10\",\n        \"fumadocs-docgen\": \"^2.1.0\",\n        \"fumadocs-mdx\": \"12.0.3\",\n        \"fumadocs-twoslash\": \"^3.1.1\",\n        \"fumadocs-ui\": \"15.2.10\",\n        \"lucide-react\": \"^0.563.0\",\n        \"next\": \"^16.1.7\",\n        \"react\": \"^19.2.4\",\n        \"react-dom\": \"^19.2.4\",\n        \"tailwind-merge\": \"^3.4.0\",\n        \"twoslash\": \"^0.3.6\"\n    },\n    \"devDependencies\": {\n        \"@solana-program/address-lookup-table\": \"^0.11.0\",\n        \"@solana-program/compute-budget\": \"^0.15.0\",\n        \"@solana-program/memo\": \"^0.11.0\",\n        \"@solana-program/system\": \"^0.12.0\",\n        \"@solana-program/token\": \"^0.12.0\",\n        \"@solana/compat\": \"6.8.0\",\n        \"@solana/kit\": \"6.8.0\",\n        \"@solana/kit-plugin-litesvm\": \"^0.10.0\",\n        \"@solana/kit-plugin-rpc\": \"^0.11.0\",\n        \"@solana/kit-plugin-signer\": \"^0.10.0\",\n        \"@solana/react\": \"6.8.0\",\n        \"@solana/wallet-account-signer\": \"6.8.0\",\n        \"@solana/web3.js\": \"^1.98.4\",\n        \"@solana/webcrypto-ed25519-polyfill\": \"6.8.0\",\n        \"@wallet-standard/ui\": \"^1.0.2\",\n        \"@tailwindcss/postcss\": \"^4.2.2\",\n        \"@types/mdx\": \"^2.0.13\",\n        \"@types/node\": \"25.4.0\",\n        \"@types/react\": \"^19.2.14\",\n        \"@types/react-dom\": \"^19.2.3\",\n        \"eslint\": \"^10\",\n        \"eslint-config-next\": \"^16.1.6\",\n        \"postcss\": \"^8.5.14\",\n        \"tailwindcss\": \"^4.2.1\",\n        \"typescript\": \"^5.9.3\",\n        \"vercel\": \"^50.22.1\"\n    },\n    \"pnpm\": {\n        \"overrides\": {\n            \"js-yaml@<3.14.2\": \"^3.14.2\",\n            \"@vercel/node>path-to-regexp\": \"^6.3.0\",\n            \"@vercel/remix-builder>path-to-regexp\": \"^6.3.0\"\n        }\n    },\n    \"packageManager\": \"pnpm@10.4.1\"\n}\n"
  },
  {
    "path": "docs/postcss.config.mjs",
    "content": "export default {\n    plugins: {\n        '@tailwindcss/postcss': {},\n    },\n};\n"
  },
  {
    "path": "docs/source.config.ts",
    "content": "import { rehypeCodeDefaultOptions } from 'fumadocs-core/mdx-plugins';\nimport { remarkInstall } from 'fumadocs-docgen';\nimport { defineConfig, defineDocs } from 'fumadocs-mdx/config';\nimport { transformerTwoslash } from 'fumadocs-twoslash';\n\nexport const api = defineDocs({\n    dir: 'content/api',\n    docs: {\n        postprocess: {\n            includeProcessedMarkdown: true,\n        },\n    },\n});\n\nexport const docs = defineDocs({\n    dir: 'content/docs',\n    docs: {\n        postprocess: {\n            includeProcessedMarkdown: true,\n        },\n    },\n});\n\nexport const recipes = defineDocs({\n    dir: 'content/recipes',\n    docs: {\n        postprocess: {\n            includeProcessedMarkdown: true,\n        },\n    },\n});\n\nexport const home = defineDocs({\n    dir: 'content/home',\n});\n\nexport default defineConfig({\n    mdxOptions: {\n        rehypeCodeOptions: {\n            langs: [\n                // FIXME(#403): If a popup itself contains a code fence in any language other than\n                // `ts`, the Shiki highlighter will throw an error that it hasn't loaded that\n                // language. Until we figure this out, preemptively load the `js` language.\n                'js',\n            ],\n            themes: {\n                dark: 'github-dark',\n                light: 'github-light',\n            },\n            transformers: [...(rehypeCodeDefaultOptions.transformers ?? []), transformerTwoslash()],\n        },\n        remarkPlugins: [() => remarkInstall({ persist: { id: 'package-install' } })],\n    },\n});\n"
  },
  {
    "path": "docs/src/app/(home)/layout.tsx",
    "content": "import type { ReactNode } from 'react';\nimport { HomeLayout, HomeLayoutProps } from 'fumadocs-ui/layouts/home';\nimport { baseOptions } from '@/app/layout.config';\n\nexport default function Layout({ children }: { children: ReactNode }) {\n    const homeProps: HomeLayoutProps = {\n        ...baseOptions,\n    };\n\n    return <HomeLayout {...homeProps}>{children}</HomeLayout>;\n}\n"
  },
  {
    "path": "docs/src/app/(home)/page/code.tsx",
    "content": "'use client';\n\nimport React, { useContext } from 'react';\nimport { ExampleContext } from './example-context';\nimport { Play } from 'lucide-react';\n\ntype Props = Readonly<{\n    examples: Record<string, React.ReactElement>;\n}>;\n\nexport default function CodeSection({ examples }: Props) {\n    const { example, progress, paused, resume } = useContext(ExampleContext);\n\n    return (\n        <section className=\"relative\">\n            <div className=\"absolute w-full max-w-home-container top-0 left-1/2 -translate-1/2 px-4\">\n                <div\n                    id=\"hero-code\"\n                    className=\"relative w-full dark:bg-fd-background/80 backdrop-blur-xl rounded-lg *:m-0 overflow-hidden\"\n                >\n                    <div\n                        className=\"absolute z-10 h-1 bottom-0 bg-mauve-400 dark:bg-mauve-500\"\n                        style={{ width: `${progress * 100}%` }}\n                    ></div>\n                    {paused && (\n                        <button\n                            className=\"absolute z-10 bottom-2 right-2 p-1.5 cursor-pointer text-mauve-100 bg-mauve-400 hover:bg-mauve-500 dark:bg-mauve-500 dark:hover:bg-mauve-400 rounded-full\"\n                            onClick={resume}\n                        >\n                            <Play size={14} fill=\"currentColor\" strokeWidth={0} />\n                        </button>\n                    )}\n                    {examples[example]}\n                </div>\n            </div>\n        </section>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/(home)/page/cta.tsx",
    "content": "import { ThemedImage } from '@/lib/ThemedImage';\nimport DarkMascotInquisitiveImage from '@/public/mascots/dark-mascot-inquisitive.svg';\nimport LightMascotInquisitiveImage from '@/public/mascots/light-mascot-inquisitive.svg';\nimport { Link } from 'fumadocs-core/framework';\n\nexport default function CtaSection() {\n    return (\n        <section className=\"bg-linear-to-b from-linen-200 to-linen-100 dark:from-mauve-800/25 dark:to-mauve-900/25\">\n            <div className=\"relative z-10 flex flex-col md:flex-row items-center gap-12 md:gap-8 w-full max-w-home-container mx-auto px-4 pt-20 pb-12 md:pb-0\">\n                <div className=\"flex-1 flex items-center justify-center\">\n                    <ThemedImage\n                        alt=\"Fox standing inquisitively looking back.\"\n                        className=\"aspect-square w-48\"\n                        src={{\n                            dark: DarkMascotInquisitiveImage,\n                            light: LightMascotInquisitiveImage,\n                        }}\n                    />\n                </div>\n                <div className=\"flex-1 max-w-lg\">\n                    <h3 className=\"font-title text-2xl text-coral-400 dark:text-coral-500\">Would you like a tour?</h3>\n                    <p className=\"text-lg text-linen-500 dark:text-mauve-300 mt-2 mb-4\">\n                        If you&apos;d like to learn more about Kit but don&apos;t know where to start, worry not! A\n                        guided tour is available to help you get acquainted with the library and its main features.\n                        Through this tour, you&apos;ll end up setting your environment, creating a token account and\n                        fetching its data.\n                    </p>\n                    <Link\n                        href=\"/docs/getting-started\"\n                        className=\"inline-block lg:text-xl 2xl:text-2xl text-white bg-mauve-400 hover:bg-mauve-500 dark:bg-mauve-500 dark:hover:bg-mauve-400 px-3 py-1.5 lg:px-6 lg:py-2 rounded-lg\"\n                    >\n                        Get started\n                    </Link>\n                </div>\n            </div>\n        </section>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/(home)/page/example-context.tsx",
    "content": "'use client';\n\nimport { createContext, useEffect, useMemo, useRef, useState } from 'react';\n\nconst EXAMPLES = ['rpc', 'codecs', 'signers', 'transactions', 'rpc-subscriptions', 'solana-programs'] as const;\nconst TIMER_INTERVAL = 8000; // 8 seconds\n\nexport type ExampleKey = (typeof EXAMPLES)[number];\n\nexport const ExampleContext = createContext<{\n    example: ExampleKey;\n    setExample: (example: ExampleKey) => void;\n    progress: number;\n    resume: () => void;\n    paused: boolean;\n}>({\n    example: EXAMPLES[0],\n    setExample: () => {},\n    progress: 0,\n    resume: () => {},\n    paused: false,\n});\n\nexport function ExampleProvider({\n    children,\n    defaultExample,\n}: {\n    children: React.ReactNode;\n    defaultExample?: ExampleKey;\n}) {\n    const [example, setExample] = useState<ExampleKey>(defaultExample ?? EXAMPLES[0]);\n    const [progress, setProgress] = useState(0);\n    const [paused, setPaused] = useState(false);\n\n    const exampleIndex = useMemo(() => EXAMPLES.findIndex(e => e === example), [example]);\n    const startTimeRef = useRef(performance.now());\n    const rafRef = useRef<number | null>(null);\n\n    useEffect(() => {\n        if (!paused) {\n            function tick() {\n                const now = performance.now();\n                const elapsed = now - startTimeRef.current;\n                const newProgress = Math.min(elapsed / TIMER_INTERVAL, 1);\n                setProgress(newProgress);\n\n                if (newProgress >= 1) {\n                    const nextIndex = (exampleIndex + 1) % EXAMPLES.length;\n                    setExample(EXAMPLES[nextIndex]);\n                    startTimeRef.current = now;\n                    setProgress(0);\n                }\n\n                rafRef.current = requestAnimationFrame(tick);\n            }\n            rafRef.current = requestAnimationFrame(tick);\n        }\n        return () => {\n            if (rafRef.current !== null) {\n                cancelAnimationFrame(rafRef.current);\n                rafRef.current = null;\n            }\n        };\n    }, [exampleIndex, paused]);\n\n    const setExampleAndPause = (newExample: ExampleKey) => {\n        setExample(newExample);\n        setProgress(0);\n        setPaused(true);\n        startTimeRef.current = performance.now();\n    };\n\n    const resume = () => {\n        startTimeRef.current = performance.now();\n        setPaused(false);\n    };\n\n    return (\n        <ExampleContext value={{ example, setExample: setExampleAndPause, progress, resume, paused }}>\n            {children}\n        </ExampleContext>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/(home)/page/features.tsx",
    "content": "'use client';\n\nimport { ThemedImage } from '@/lib/ThemedImage';\nimport DarkCodecsImage from '@/public/features/dark-codecs.png';\nimport DarkRpcSubscriptionsImage from '@/public/features/dark-rpc-subscriptions.png';\nimport DarkRpcImage from '@/public/features/dark-rpc.png';\nimport DarkSignersImage from '@/public/features/dark-signers.png';\nimport DarkSolanaProgramsImage from '@/public/features/dark-solana-programs.png';\nimport DarkTransactionsImage from '@/public/features/dark-transactions.png';\nimport LightCodecsImage from '@/public/features/light-codecs.png';\nimport LightRpcSubscriptionsImage from '@/public/features/light-rpc-subscriptions.png';\nimport LightRpcImage from '@/public/features/light-rpc.png';\nimport LightSignersImage from '@/public/features/light-signers.png';\nimport LightSolanaProgramsImage from '@/public/features/light-solana-programs.png';\nimport LightTransactionsImage from '@/public/features/light-transactions.png';\nimport { Link } from 'fumadocs-core/framework';\nimport { cn } from 'fumadocs-ui/utils/cn';\nimport { useContext } from 'react';\nimport { ExampleContext, ExampleKey } from './example-context';\nimport { StaticImageData } from 'next/image';\n\ntype Feature = {\n    key: ExampleKey;\n    label: string;\n    description: string;\n    href: string;\n    image: Readonly<{\n        dark: StaticImageData;\n        light: StaticImageData;\n    }>;\n};\n\nconst features: Feature[] = [\n    {\n        key: 'rpc',\n        label: 'RPC',\n        description: 'Configure your Solana RPC and send requests to send transactions or fetch data.',\n        href: '/docs/guides/rpc',\n        image: {\n            dark: DarkRpcImage,\n            light: LightRpcImage,\n        },\n    },\n    {\n        key: 'codecs',\n        label: 'Codecs',\n        description: 'Compose codecs together to encode and decode any value to and from a byte array.',\n        href: '/docs/advanced-guides/codecs',\n        image: {\n            dark: DarkCodecsImage,\n            light: LightCodecsImage,\n        },\n    },\n    {\n        key: 'signers',\n        label: 'Signers',\n        description: 'Create signer objects to sign transactions and/or messages with your wallets.',\n        href: '/docs/advanced-guides/signers',\n        image: {\n            dark: DarkSignersImage,\n            light: LightSignersImage,\n        },\n    },\n    {\n        key: 'transactions',\n        label: 'Transactions',\n        description: 'Gradually build transaction messages before compiling and sending them to the network.',\n        href: '/docs/advanced-guides/transactions',\n        image: {\n            dark: DarkTransactionsImage,\n            light: LightTransactionsImage,\n        },\n    },\n    {\n        key: 'rpc-subscriptions',\n        label: 'RPC Subscriptions',\n        description: 'Subscribe to RPC notifications such as account changes, slot updates, and more.',\n        href: '/docs/guides/rpc-subscriptions',\n        image: {\n            dark: DarkRpcSubscriptionsImage,\n            light: LightRpcSubscriptionsImage,\n        },\n    },\n    {\n        key: 'solana-programs',\n        label: 'Solana Programs',\n        description: 'Interact with various Solana programs using their Codama-generated SDKs.',\n        href: '/docs/plugins/available-plugins',\n        image: {\n            dark: DarkSolanaProgramsImage,\n            light: LightSolanaProgramsImage,\n        },\n    },\n];\n\nexport default function FeaturesSection() {\n    const { example, setExample } = useContext(ExampleContext);\n    const set = (key: ExampleKey) => () => setExample(key);\n\n    return (\n        <section className=\"w-full max-w-home-container mx-auto px-4 pt-40 pb-10 md:pb-20\">\n            <div className=\"grid grid-cols-1 md:grid-cols-2 gap-12 md:gap-8 lg:gap-12\">\n                {features.map(feature => (\n                    <div key={feature.key} className=\"flex gap-4 md:gap-6 lg:gap-8\">\n                        <div\n                            className=\"aspect-square w-20 md:w-24 lg:w-40 flex-shrink-0 cursor-pointer\"\n                            onClick={set(feature.key)}\n                        >\n                            <ThemedImage\n                                alt={`${feature.label} feature abstract illustration.`}\n                                sizes=\"(min-width: 64rem) 10rem, 5rem\"\n                                src={feature.image}\n                            />\n                        </div>\n                        <div className=\"flex-1\">\n                            <h3\n                                className={cn([\n                                    'font-title text-2xl cursor-pointer',\n                                    example === feature.key\n                                        ? 'text-coral-400 dark:text-coral-500'\n                                        : 'text-linen-400 dark:text-mauve-400',\n                                ])}\n                                onClick={set(feature.key)}\n                            >\n                                {feature.label}\n                            </h3>\n                            <p className=\"text-lg text-linen-500 dark:text-mauve-300 mt-2\">{feature.description}</p>\n                            <div className=\"mt-1\">\n                                <Link\n                                    href={feature.href}\n                                    className=\"inline-block text-lg text-coral-400 hover:text-coral-500 dark:text-coral-500 dark:hover:text-coral-400 transition-colors\"\n                                >\n                                    Learn more\n                                </Link>\n                            </div>\n                        </div>\n                    </div>\n                ))}\n            </div>\n            <Link\n                href=\"/docs/advanced-guides\"\n                className=\"block mt-16 font-title text-2xl text-linen-300 dark:text-mauve-500 text-center\"\n            >\n                And many more...\n            </Link>\n        </section>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/(home)/page/footer.tsx",
    "content": "import { ThemedImage } from '@/lib/ThemedImage';\nimport DarkFooter from '@/public/footer/dark-footer.svg';\nimport LightFooter from '@/public/footer/light-footer.svg';\nimport { Link } from 'fumadocs-core/framework';\n\nexport default function FooterSection() {\n    const linkClassName = 'text-linen-600 hover:text-linen-800 dark:text-mauve-300 dark:hover:text-mauve-100';\n    return (\n        <section className=\"relative -mt-8 lg:-mt-14 2xl:-mt-28\">\n            <div className=\"absolute bottom-0 w-full\">\n                <div className=\"w-full max-w-home-container mx-auto flex justify-end *:m-4 sm:*:m-6 md:*:m-8 text-sm md:text-base font-semibold\">\n                    <Link className={linkClassName} href=\"/docs\">\n                        Documentation\n                    </Link>\n                    <Link className={linkClassName} href=\"/api\">\n                        API Reference\n                    </Link>\n                    <Link className={linkClassName} href=\"https://www.anza.xyz/\">\n                        Maintained by Anza\n                    </Link>\n                </div>\n            </div>\n            <ThemedImage\n                alt=\"Dune illustrations\"\n                className=\"w-full h-full max-h-200 object-cover object-top\"\n                sizes=\"100vw\"\n                src={{\n                    dark: DarkFooter,\n                    light: LightFooter,\n                }}\n            />\n        </section>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/(home)/page/hero.tsx",
    "content": "import { ThemedImage } from '@/lib/ThemedImage';\nimport DarkHeader from '@/public/header/dark-header.jpg';\nimport LightHeader from '@/public/header/light-header.jpg';\nimport Link from 'fumadocs-core/link';\n\nexport default function HeroSection() {\n    return (\n        <section className=\"relative border-b border-mauve-400 dark:border-mauve-700\">\n            <ThemedImage\n                alt=\"Home illustration for the Kit library. A cute fox jumps towards a UI element with the Solana logo on it. It is surrounded by other UI elements such as buttons, sliders, browser windows and diagrams.\"\n                className=\"w-full h-full min-h-96 md:min-h-none 2xl:max-h-[calc(100vh-calc(var(--spacing)*50))] object-cover object-[60%_50%] md:object-center\"\n                placeholder=\"blur\"\n                sizes=\"100vw\"\n                src={{\n                    dark: DarkHeader,\n                    light: LightHeader,\n                }}\n            />\n            <div className=\"absolute bottom-20 md:bottom-30 left-0 md:left-10 lg:left-0 w-full\">\n                <div className=\"w-full max-w-home-container mx-auto px-4 py-8\">\n                    <h1 className=\"text-linen-900 text-3xl md:text-4xl lg:text-5xl xl:text-6xl 2xl:text-7xl mb-4 lg:mb-6 xl:mb-8\">\n                        Your JavaScript\n                        <br />\n                        SDK for Solana\n                    </h1>\n                    <Link\n                        href=\"/docs\"\n                        className=\"inline-block lg:text-xl 2xl:text-2xl text-white bg-coral-400 hover:bg-coral-500 dark:bg-coral-500 dark:hover:bg-coral-400 px-3 py-1.5 lg:px-6 lg:py-2 rounded-lg\"\n                    >\n                        Get started with Kit\n                    </Link>\n                </div>\n            </div>\n        </section>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/(home)/page.tsx",
    "content": "import { home } from '@/.source';\nimport React from 'react';\n\nimport { mdxComponents } from '../layout.config';\nimport HeroSection from './page/hero';\nimport CodeSection from './page/code';\nimport FeaturesSection from './page/features';\nimport CtaSection from './page/cta';\nimport FooterSection from './page/footer';\nimport { ExampleProvider } from './page/example-context';\n\nfunction getExamples(): Record<string, React.ReactElement> {\n    const examples: Record<string, React.ReactElement> = {};\n    home.docs.forEach(doc => {\n        const match = doc.info.path.match(/^example-(.*)\\.mdx$/);\n        if (match) {\n            const MDXContent = doc.body;\n            examples[match[1]] = <MDXContent components={mdxComponents} />;\n        }\n    });\n    return examples;\n}\n\nexport default function HomePage() {\n    const examples = getExamples();\n    return (\n        <main className=\"flex flex-1 flex-col\">\n            <HeroSection />\n            <ExampleProvider>\n                <CodeSection examples={examples} />\n                <FeaturesSection />\n            </ExampleProvider>\n            <CtaSection />\n            <FooterSection />\n        </main>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/api/[[...slug]]/page.tsx",
    "content": "import { mdxComponents } from '@/app/layout.config';\nimport { LLMCopyButton, ViewOptions } from '@/components/page-actions';\nimport { apiSource } from '@/lib/source';\nimport { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page';\nimport { notFound } from 'next/navigation';\n\nexport default async function Page(props: { params: Promise<{ slug?: string[] }> }) {\n    const params = await props.params;\n    const page = apiSource.getPage(params.slug);\n    if (!page) notFound();\n\n    const MDX = page.data.body;\n\n    return (\n        <DocsPage toc={page.data.toc} full={page.data.full}>\n            <DocsTitle>{page.data.title}</DocsTitle>\n            <DocsDescription className=\"mb-0\">{page.data.description}</DocsDescription>\n            <div className=\"flex flex-row gap-2 items-center mb-8\">\n                <LLMCopyButton markdownUrl={`${page.url}.mdx`} />\n                <ViewOptions\n                    markdownUrl={`${page.url}.mdx`}\n                    githubUrl={`https://github.com/anza-xyz/kit/blob/main/docs/content${page.url}.mdx`}\n                />\n            </div>\n            <DocsBody>\n                <MDX components={mdxComponents} />\n            </DocsBody>\n        </DocsPage>\n    );\n}\n\nexport async function generateStaticParams() {\n    return apiSource.generateParams();\n}\n\nexport async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {\n    const params = await props.params;\n    const page = apiSource.getPage(params.slug);\n    if (!page) notFound();\n\n    return {\n        title: page.data.title,\n        description: page.data.description,\n    };\n}\n"
  },
  {
    "path": "docs/src/app/api/layout.tsx",
    "content": "import { DocsLayout, DocsLayoutProps } from 'fumadocs-ui/layouts/docs';\nimport type { ReactNode } from 'react';\nimport { baseOptions } from '@/app/layout.config';\nimport { apiSource } from '@/lib/source';\nimport { Sidebar } from '../docs/sidebar';\nimport { Navbar } from '../docs/navbar';\n\nexport default function Layout({ children }: { children: ReactNode }) {\n    const baseProps: DocsLayoutProps = {\n        ...baseOptions,\n        tree: apiSource.pageTree,\n    };\n\n    const apiProps: DocsLayoutProps = {\n        ...baseProps,\n        sidebar: { ...baseProps.sidebar, component: Sidebar(baseProps) },\n        nav: { ...baseProps.nav, component: Navbar(baseProps) },\n    };\n\n    return <DocsLayout {...apiProps}>{children}</DocsLayout>;\n}\n"
  },
  {
    "path": "docs/src/app/docs/[[...slug]]/page.tsx",
    "content": "import { mdxComponents } from '@/app/layout.config';\nimport { LLMCopyButton, ViewOptions } from '@/components/page-actions';\nimport { overridenMdxComponents } from '@/lib/Overrides';\nimport { docsSource } from '@/lib/source';\nimport { getPageTreePeers } from 'fumadocs-core/server';\nimport { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page';\nimport { notFound } from 'next/navigation';\n\nexport default async function Page(props: { params: Promise<{ slug?: string[] }> }) {\n    const params = await props.params;\n    const page = docsSource.getPage(params.slug);\n    if (!page) notFound();\n\n    const MDX = page.data.body;\n    const hasCategory = page.file.name === 'index' && page.slugs.length > 0;\n\n    return (\n        <DocsPage toc={page.data.toc} full={page.data.full}>\n            <DocsTitle>{page.data.title}</DocsTitle>\n\n            <DocsDescription className='mb-0'>{page.data.description}</DocsDescription>\n            <div className=\"flex flex-row gap-2 items-center mb-8\">\n                <LLMCopyButton markdownUrl={`${page.url}.mdx`} />\n                <ViewOptions\n                    markdownUrl={`${page.url}.mdx`}\n                    githubUrl={`https://github.com/anza-xyz/kit/blob/main/docs/content${page.url}.mdx`}\n                />\n            </div>\n\n            <DocsBody>\n                <MDX components={mdxComponents} />\n            </DocsBody>\n            {hasCategory && (\n                <overridenMdxComponents.Cards>\n                    {getPageTreePeers(docsSource.pageTree, page.url).map(peer => (\n                        <overridenMdxComponents.Card key={peer.url} title={peer.name} href={peer.url}>\n                            {peer.description}\n                        </overridenMdxComponents.Card>\n                    ))}\n                </overridenMdxComponents.Cards>\n            )}\n        </DocsPage>\n    );\n}\n\nexport async function generateStaticParams() {\n    return docsSource.generateParams();\n}\n\nexport async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {\n    const params = await props.params;\n    const page = docsSource.getPage(params.slug);\n    if (!page) notFound();\n\n    return {\n        title: page.data.title,\n        description: page.data.description,\n    };\n}\n"
  },
  {
    "path": "docs/src/app/docs/layout.tsx",
    "content": "import { baseOptions } from '@/app/layout.config';\nimport { docsSource } from '@/lib/source';\nimport { DocsLayout, DocsLayoutProps } from 'fumadocs-ui/layouts/docs';\nimport type { ReactNode } from 'react';\nimport { Sidebar } from './sidebar';\nimport { Navbar } from './navbar';\n\nexport default function Layout({ children }: { children: ReactNode }) {\n    const baseProps: DocsLayoutProps = {\n        ...baseOptions,\n        tree: docsSource.pageTree,\n    };\n\n    const docsProps: DocsLayoutProps = {\n        ...baseProps,\n        sidebar: { ...baseProps.sidebar, component: Sidebar(baseProps) },\n        nav: { ...baseProps.nav, component: Navbar(baseProps) },\n    };\n\n    return <DocsLayout {...docsProps}>{children}</DocsLayout>;\n}\n"
  },
  {
    "path": "docs/src/app/docs/navbar.tsx",
    "content": "import Link from 'fumadocs-core/link';\nimport { SearchToggle } from 'fumadocs-ui/components/layout/search-toggle';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { DocsLayoutProps } from 'fumadocs-ui/layouts/docs';\nimport { Navbar as BaseNavbar, NavbarSidebarTrigger } from 'fumadocs-ui/layouts/docs-client';\nimport { cn } from 'fumadocs-ui/utils/cn';\nimport { Sidebar as SidebarIcon } from 'lucide-react';\nimport { Logo } from '../logo';\n\nexport function Navbar({\n    nav = {},\n    sidebar: { enabled: sidebarEnabled = true } = {},\n    searchToggle = {},\n}: DocsLayoutProps) {\n    return (\n        <BaseNavbar className=\"h-16 md:hidden\">\n            {searchToggle.enabled !== false &&\n                (searchToggle.components?.sm ?? <SearchToggle className=\"p-2\" hideIfDisabled />)}\n            <Link href={nav.url ?? '/'} className=\"flex-1 inline-flex items-center gap-2.5 font-semibold\">\n                <Logo className=\"h-10 my-2\" />\n            </Link>\n            {sidebarEnabled && (\n                <NavbarSidebarTrigger\n                    className={cn(\n                        buttonVariants({\n                            color: 'ghost',\n                            size: 'icon-sm',\n                            className: 'p-2',\n                        }),\n                    )}\n                >\n                    <SidebarIcon />\n                </NavbarSidebarTrigger>\n            )}\n        </BaseNavbar>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/docs/sidebar.tsx",
    "content": "import Link from 'fumadocs-core/link';\nimport { RootToggle } from 'fumadocs-ui/components/layout/root-toggle';\nimport { LargeSearchToggle } from 'fumadocs-ui/components/layout/search-toggle';\nimport {\n    CollapsibleSidebar,\n    SidebarCollapseTrigger,\n    SidebarFooter,\n    SidebarHeader,\n    SidebarPageTree,\n    SidebarViewport,\n} from 'fumadocs-ui/components/layout/sidebar';\nimport { ThemeToggle } from 'fumadocs-ui/components/layout/theme-toggle';\nimport { LanguageToggle } from 'fumadocs-ui/components/layout/language-toggle';\nimport { buttonVariants } from 'fumadocs-ui/components/ui/button';\nimport { CollapsibleControl, DocsLayoutProps } from 'fumadocs-ui/layouts/docs';\nimport { getSidebarTabsFromOptions, SidebarLinkItem } from 'fumadocs-ui/layouts/docs/shared';\nimport { BaseLinkItem, IconItemType } from 'fumadocs-ui/layouts/links';\nimport { getLinks } from 'fumadocs-ui/layouts/shared';\nimport { cn } from 'fumadocs-ui/utils/cn';\nimport { Languages, SidebarIcon } from 'lucide-react';\nimport { useMemo } from 'react';\nimport { LogoWithSolana } from '../logo';\n\nexport function Sidebar({\n    nav = {},\n    sidebar: {\n        tabs: sidebarTabs,\n        footer: sidebarFooter,\n        banner: sidebarBanner,\n        components: sidebarComponents,\n        ...sidebarProps\n    } = {},\n    searchToggle = {},\n    themeSwitch = { enabled: true },\n    i18n = false,\n    ...props\n}: DocsLayoutProps) {\n    const tabs = useMemo(() => getSidebarTabsFromOptions(sidebarTabs, props.tree) ?? [], [sidebarTabs, props.tree]);\n    const links = getLinks(props.links ?? [], props.githubUrl);\n    const iconLinks = links.filter((item): item is IconItemType => item.type === 'icon');\n\n    const header = (\n        <SidebarHeader className=\"data-[empty=true]:hidden\">\n            <div className=\"relative flex justify-center max-md:hidden\">\n                <Link href={nav.url ?? '/'} className=\"inline-flex items-center\">\n                    <LogoWithSolana className=\"h-16 my-4\" />\n                </Link>\n\n                <SidebarCollapseTrigger\n                    className={cn(\n                        buttonVariants({\n                            color: 'ghost',\n                            size: 'icon-sm',\n                            className: 'absolute top-0 right-0 text-fd-muted-foreground max-md:hidden',\n                        }),\n                    )}\n                >\n                    <SidebarIcon />\n                </SidebarCollapseTrigger>\n            </div>\n            {searchToggle.enabled !== false &&\n                (searchToggle.components?.lg ?? (\n                    <LargeSearchToggle hideIfDisabled className=\"max-md:hidden rounded-lg\" />\n                ))}\n            {tabs.length > 0 && <RootToggle options={tabs} />}\n\n            {sidebarBanner}\n        </SidebarHeader>\n    );\n\n    const viewport = (\n        <SidebarViewport>\n            {links\n                .filter(v => v.type !== 'icon')\n                .map((item, i, list) => (\n                    <SidebarLinkItem key={i} item={item} className={cn(i === list.length - 1 && 'mb-4')} />\n                ))}\n            <SidebarPageTree components={sidebarComponents} />\n        </SidebarViewport>\n    );\n\n    const footer = (\n        <SidebarFooter>\n            <div className=\"flex text-fd-muted-foreground items-center justify-end empty:hidden\">\n                {iconLinks.map((item, i) => (\n                    <BaseLinkItem\n                        key={i}\n                        item={item}\n                        className={cn(\n                            buttonVariants({ size: 'icon-sm', color: 'ghost' }),\n                            i === iconLinks.length - 1 && 'me-auto',\n                        )}\n                        aria-label={item.label}\n                    >\n                        {item.icon}\n                    </BaseLinkItem>\n                ))}\n                {i18n ? (\n                    <LanguageToggle>\n                        <Languages className=\"size-4.5\" />\n                    </LanguageToggle>\n                ) : null}\n                {themeSwitch.enabled !== false &&\n                    (themeSwitch.component ?? <ThemeToggle className=\"p-0 ms-1.5\" mode={themeSwitch.mode} />)}\n            </div>\n            {sidebarFooter}\n        </SidebarFooter>\n    );\n\n    return (\n        <>\n            <div className=\"max-md:hidden\">\n                <CollapsibleControl />\n            </div>\n            <CollapsibleSidebar {...sidebarProps}>\n                {header}\n                {viewport}\n                {footer}\n            </CollapsibleSidebar>\n        </>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/global.css",
    "content": "@import 'tailwindcss';\n\n/* Fumadocs imports. */\n@import 'fumadocs-ui/css/neutral.css';\n@import 'fumadocs-ui/css/preset.css';\n@import 'fumadocs-twoslash/twoslash.css';\n@source '../../node_modules/fumadocs-ui/dist/**/*.js';\n\n/* App imports. */\n@import '../../src/app/styles/brand.css';\n@import '../../src/app/styles/typography.css';\n@import '../../src/app/styles/fumadocs-overrides.css';\n"
  },
  {
    "path": "docs/src/app/layout.config.tsx",
    "content": "import { CardTab, CardTabs } from '@/components/card-tabs';\nimport { overridenMdxComponents } from '@/lib/Overrides';\nimport { Spread } from '@/lib/Spread';\nimport { Popup, PopupContent, PopupTrigger } from 'fumadocs-twoslash/ui';\nimport { ImageZoom } from 'fumadocs-ui/components/image-zoom';\nimport { Step, Steps } from 'fumadocs-ui/components/steps';\nimport type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';\nimport defaultMdxComponents from 'fumadocs-ui/mdx';\nimport { BookTextIcon, CookingPotIcon, LibraryBigIcon } from 'lucide-react';\nimport { Logo, LogoWithSolana } from './logo';\nimport { MDXComponents } from 'mdx/types';\n\n/**\n * Shared layout configurations\n *\n * you can customise layouts individually from:\n * Home Layout: app/(home)/layout.tsx\n * Docs Layout: app/docs/layout.tsx\n */\nexport const baseOptions: BaseLayoutProps = {\n    nav: {\n        title: (\n            <div className=\"flex\">\n                <LogoWithSolana className=\"h-12 max-md:hidden\" />\n                <Logo className=\"h-10 md:hidden\" />\n            </div>\n        ),\n    },\n    links: [\n        {\n            text: 'Documentation',\n            url: '/docs',\n            active: 'nested-url',\n            icon: <BookTextIcon />,\n        },\n        {\n            text: 'Recipes',\n            url: '/recipes',\n            active: 'nested-url',\n            icon: <CookingPotIcon />,\n        },\n        {\n            text: 'API Reference',\n            url: '/api',\n            active: 'nested-url',\n            icon: <LibraryBigIcon />,\n        },\n    ],\n};\n\nexport const mdxComponents: MDXComponents = {\n    ...defaultMdxComponents,\n    ...overridenMdxComponents,\n    img: props => <ImageZoom {...props} alt={props.alt ?? ''} />,\n    CardTab,\n    CardTabs,\n    Popup,\n    PopupContent,\n    PopupTrigger,\n    Spread,\n    Step,\n    Steps,\n};\n"
  },
  {
    "path": "docs/src/app/layout.tsx",
    "content": "import './global.css';\n\nimport InKeepSearchDialog from '@/lib/InKeepSearchDialog';\nimport { RootProvider } from 'fumadocs-ui/provider';\nimport type { ReactNode } from 'react';\n\nexport default function Layout({ children }: { children: ReactNode }) {\n    return (\n        <html lang=\"en\" suppressHydrationWarning>\n            <head>\n                <link rel=\"stylesheet\" href=\"https://use.typekit.net/chp6nhs.css\" />\n            </head>\n            <body className=\"flex flex-col min-h-screen\">\n                <RootProvider\n                    search={{\n                        preload: false,\n                        SearchDialog: InKeepSearchDialog,\n                    }}\n                >\n                    {children}\n                </RootProvider>\n            </body>\n        </html>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/llms-full.txt/route.ts",
    "content": "import { apiSource, docsSource, recipesSource } from '@/lib/source';\nimport { getLLMText } from '@/lib/get-llm-text';\n\n// cached forever\nexport const revalidate = false;\n\nexport async function GET() {\n    const scan = [...docsSource.getPages(), ...recipesSource.getPages(), ...apiSource.getPages()].map(getLLMText);\n    const scanned = await Promise.all(scan);\n    return new Response(scanned.join('\\n\\n'));\n}\n"
  },
  {
    "path": "docs/src/app/llms.mdx/api/[[...slug]]/route.ts",
    "content": "import { getLLMText } from '@/lib/get-llm-text';\nimport { apiSource } from '@/lib/source';\nimport { notFound } from 'next/navigation';\n\nexport const revalidate = false;\n\nexport async function GET(_req: Request, { params }: RouteContext<'/llms.mdx/api/[[...slug]]'>) {\n    const { slug } = await params;\n    const page = apiSource.getPage(slug);\n    if (!page) notFound();\n\n    return new Response(await getLLMText(page), {\n        headers: {\n            'Content-Type': 'text/markdown',\n        },\n    });\n}\n\nexport function generateStaticParams() {\n    return apiSource.generateParams();\n}\n"
  },
  {
    "path": "docs/src/app/llms.mdx/docs/[[...slug]]/route.ts",
    "content": "import { getLLMText } from '@/lib/get-llm-text';\nimport { docsSource } from '@/lib/source';\nimport { notFound } from 'next/navigation';\n\nexport const revalidate = false;\n\nexport async function GET(_req: Request, { params }: RouteContext<'/llms.mdx/docs/[[...slug]]'>) {\n    const { slug } = await params;\n    const page = docsSource.getPage(slug);\n    if (!page) notFound();\n\n    return new Response(await getLLMText(page), {\n        headers: {\n            'Content-Type': 'text/markdown',\n        },\n    });\n}\n\nexport function generateStaticParams() {\n    return docsSource.generateParams();\n}\n"
  },
  {
    "path": "docs/src/app/llms.mdx/recipes/[[...slug]]/route.ts",
    "content": "import { getLLMText } from '@/lib/get-llm-text';\nimport { recipesSource } from '@/lib/source';\nimport { notFound } from 'next/navigation';\n\nexport const revalidate = false;\n\nexport async function GET(_req: Request, { params }: RouteContext<'/llms.mdx/recipes/[[...slug]]'>) {\n    const { slug } = await params;\n    const page = recipesSource.getPage(slug);\n    if (!page) notFound();\n\n    return new Response(await getLLMText(page), {\n        headers: {\n            'Content-Type': 'text/markdown',\n        },\n    });\n}\n\nexport function generateStaticParams() {\n    return recipesSource.generateParams();\n}\n"
  },
  {
    "path": "docs/src/app/logo.tsx",
    "content": "import { cn } from 'fumadocs-ui/utils/cn';\n\nexport function LogoWithSolana({\n    className,\n    solanaClassName,\n}: React.ComponentProps<'svg'> & { solanaClassName?: string }) {\n    return (\n        <svg\n            width=\"510\"\n            height=\"330\"\n            viewBox=\"0 0 510 330\"\n            className={cn('text-linen-900 dark:text-linen-100 w-full', className)}\n            fill=\"none\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n        >\n            <g className={cn('text-linen-800 dark:text-linen-200', solanaClassName)}>\n                <path\n                    d=\"M288.613 133.595C285.438 133.595 282.444 133.127 279.633 132.188C276.821 131.252 274.415 129.945 272.413 128.271L275.526 124.484C277.651 125.908 279.851 127.014 282.126 127.803C284.402 128.591 286.563 128.984 288.613 128.984C292.337 128.984 295.218 128.346 297.256 127.072C299.294 125.796 300.313 123.996 300.313 121.673C300.313 119.722 299.699 118.335 298.476 117.51C297.251 116.685 295.645 116.147 293.659 115.897C291.672 115.647 289.552 115.433 287.303 115.259C285.729 115.135 284.166 114.941 282.616 114.677C281.066 114.415 279.654 113.958 278.379 113.308C277.103 112.658 276.086 111.702 275.322 110.441C274.558 109.18 274.179 107.472 274.179 105.323C274.179 101.572 275.535 98.6735 278.248 96.6237C280.96 94.5738 284.79 93.5477 289.741 93.5477C292.315 93.5477 294.847 93.9237 297.334 94.6733C299.82 95.4229 302.052 96.4733 304.027 97.822L300.914 101.533C299.063 100.459 297.147 99.6268 295.158 99.0397C293.171 98.4527 291.289 98.1592 289.515 98.1592C286.241 98.1592 283.703 98.7729 281.903 99.9955C280.103 101.221 279.203 102.945 279.203 105.17C279.203 106.87 279.759 108.088 280.872 108.825C281.986 109.563 283.441 110.043 285.241 110.269C287.041 110.494 289.004 110.669 291.129 110.793C292.754 110.892 294.396 111.069 296.06 111.317C297.722 111.567 299.253 112.042 300.655 112.741C302.054 113.442 303.18 114.497 304.029 115.909C304.878 117.321 305.305 119.239 305.305 121.665C305.305 125.44 303.85 128.37 300.936 130.459C298.023 132.547 293.918 133.591 288.618 133.591L288.613 133.595Z\"\n                    fill=\"currentColor\"\n                />\n                <path\n                    d=\"M329.971 133.595C324.872 133.595 320.92 132.113 318.123 129.151C315.324 126.189 313.924 122.022 313.924 116.646V110.31C313.924 104.985 315.324 100.862 318.123 97.936C320.922 95.0105 324.872 93.5477 329.971 93.5477C335.07 93.5477 339.019 95.0105 341.821 97.936C344.62 100.862 346.02 104.985 346.02 110.31V116.76C346.02 122.109 344.62 126.252 341.821 129.19C339.021 132.128 335.072 133.595 329.971 133.595ZM329.932 128.572C333.33 128.572 335.962 127.541 337.825 125.479C339.688 123.417 340.62 120.511 340.62 116.76V110.31C340.62 106.586 339.688 103.697 337.825 101.647C335.962 99.5977 333.333 98.5716 329.932 98.5716C326.531 98.5716 323.945 99.5977 322.094 101.647C320.243 103.697 319.319 106.584 319.319 110.31V116.76C319.319 120.511 320.243 123.417 322.094 125.479C323.942 127.541 326.555 128.572 329.932 128.572Z\"\n                    fill=\"currentColor\"\n                />\n                <path\n                    d=\"M362.292 78.515V122.798C362.292 124.448 362.697 125.729 363.51 126.641C364.322 127.553 365.453 128.009 366.904 128.009H370.503V133.033H366.004C363.129 133.033 360.892 132.133 359.291 130.333C357.69 128.533 356.892 125.995 356.892 122.721V78.5126H362.292V78.515Z\"\n                    fill=\"currentColor\"\n                />\n                <path\n                    d=\"M403.989 97.3369C401.314 94.8116 397.539 93.5502 392.666 93.5502C389.716 93.5502 387.035 94.045 384.622 95.0323C382.208 96.0196 380.265 97.3999 378.79 99.1756L382.727 101.876C384.127 100.777 385.713 99.9252 387.489 99.326C389.265 98.7268 391.062 98.426 392.889 98.426C395.989 98.426 398.381 99.2945 400.069 101.031C401.758 102.768 402.599 105.211 402.599 108.362V110.012H390C385.849 110.012 382.625 111.018 380.326 113.029C378.026 115.043 376.876 117.886 376.876 121.561C376.876 125.236 378.125 128.348 380.626 130.447C383.125 132.547 386.65 133.595 391.2 133.595C393.025 133.595 394.713 133.445 396.263 133.147C397.813 132.846 399.193 132.409 400.406 131.834C401.243 131.439 401.971 130.98 402.599 130.466V133.035H407.999V108.025C407.999 103.426 406.663 99.8645 403.987 97.3393L403.989 97.3369ZM399.827 127.485C397.976 128.159 395.378 128.496 392.028 128.496C388.903 128.496 386.485 127.89 384.772 126.677C383.059 125.464 382.203 123.759 382.203 121.559C382.203 119.484 382.885 117.879 384.246 116.741C385.609 115.603 387.54 115.036 390.038 115.036H402.599V124.634C402.599 125.859 401.675 126.81 399.824 127.485H399.827Z\"\n                    fill=\"currentColor\"\n                />\n                <path\n                    d=\"M419.624 133.035V94.1129H425.024V133.035H419.624ZM445.497 133.035V109.449C445.497 105.999 444.59 103.324 442.778 101.424C440.966 99.5249 438.409 98.574 435.11 98.574C431.811 98.574 429.429 99.4182 427.668 101.104C425.907 102.792 425.024 105.184 425.024 108.284L424.235 100.786C425.686 98.1107 427.578 96.2379 429.916 95.1609C432.252 94.0862 434.821 93.5477 437.623 93.5477C441.847 93.5477 445.116 94.9304 447.428 97.691C449.74 100.454 450.897 104.36 450.897 109.408V133.03H445.497V133.035Z\"\n                    fill=\"currentColor\"\n                />\n                <path\n                    d=\"M487.755 97.3369C485.079 94.8116 481.305 93.5502 476.431 93.5502C473.481 93.5502 470.801 94.045 468.387 95.0323C465.974 96.0196 464.03 97.3999 462.556 99.1756L466.493 101.876C467.892 100.777 469.479 99.9252 471.255 99.326C473.03 98.7268 474.828 98.426 476.654 98.426C479.755 98.426 482.146 99.2945 483.835 101.031C485.523 102.768 486.365 105.211 486.365 108.362V110.012H473.765C469.615 110.012 466.391 111.018 464.091 113.029C461.791 115.043 460.642 117.886 460.642 121.561C460.642 125.236 461.891 128.348 464.392 130.447C466.89 132.547 470.415 133.595 474.966 133.595C476.79 133.595 478.479 133.445 480.029 133.147C481.579 132.846 482.959 132.409 484.172 131.834C485.009 131.439 485.737 130.98 486.365 130.466V133.035H491.765V108.025C491.765 103.426 490.428 99.8645 487.752 97.3393L487.755 97.3369ZM483.595 127.485C481.744 128.159 479.146 128.496 475.796 128.496C472.671 128.496 470.253 127.89 468.54 126.677C466.827 125.464 465.971 123.759 465.971 121.559C465.971 119.484 466.653 117.879 468.014 116.741C469.377 115.603 471.308 115.036 473.806 115.036H486.367V124.634C486.367 125.859 485.443 126.81 483.592 127.485H483.595Z\"\n                    fill=\"currentColor\"\n                />\n            </g>\n            <path\n                d=\"M146.446 238.772C146.446 238.772 168.839 224.669 204.985 206.935C236.066 191.685 241.29 176.358 242.143 172.361C242.184 172.166 242.465 172.174 242.497 172.37C244.227 183.358 241.088 221.563 239.215 230.223C237.312 239.015 233.635 245.913 228.411 252.215C223.187 258.517 217.045 260.817 211.94 262.153C199.686 265.356 170.734 271.928 145.45 285.621C119.731 299.549 105.771 325.288 103.422 329.903C103.335 330.073 103.078 330.005 103.083 329.815C103.764 299.532 108.147 286.24 113.327 273.553C119.493 258.449 106.098 254.476 96.9672 254.476H59.1941C27.6216 254.476 -2.32931 233.05 0.143161 209.403C0.201337 208.846 0.627953 208.397 1.18062 208.314C11.3929 206.809 21.2659 202.022 21.2659 202.022C36.5007 195.868 48.6158 176.062 52.4554 171.734C56.295 167.406 63.1889 153.286 79.3254 149.619C95.9274 145.847 111.344 133.118 115.792 115.486C119.525 100.698 137.276 18.0317 140.665 2.23324C140.999 0.669189 142.555 -0.294984 144.107 0.0814575C159.215 3.7293 194.623 27.8361 213.624 58.1166C230.546 85.082 242.853 122.444 229.809 158.046C213.12 203.596 146.448 238.772 146.448 238.772H146.446Z\"\n                fill=\"currentColor\"\n            />\n            <path\n                d=\"M346.524 155.624H361.384C362.189 155.624 362.641 156.548 362.143 157.18L327.131 202.908C323.828 207.72 324.083 211.712 327.078 215.067C327.114 215.106 327.148 215.15 327.18 215.191L365.767 263.125C366.342 263.902 365.786 265 364.818 265H346.835C342.939 265 338.357 261.688 334.803 257.919C331.252 254.149 316.699 234.507 313.721 230.851C312.046 228.795 309.587 226.562 305.403 226.562C303.201 226.562 299.095 228.219 299.095 232.564V263.727C299.095 264.429 298.524 265 297.818 265H275.277C274.573 265 274 264.431 274 263.727V145.274C274 144.277 275.099 143.668 275.949 144.193C281.937 147.904 299.665 159.618 299.665 168.255V200.406C299.665 202.397 302.165 203.297 303.437 201.761C310.626 193.092 328.968 166.869 330.709 164.634C337.197 156.297 342.313 155.624 346.519 155.624H346.524Z\"\n                fill=\"currentColor\"\n            />\n            <path\n                d=\"M379 157.16C379 156.317 379.894 155.758 380.684 156.105C387.727 159.215 404 178.109 404 186.811V263.983C404 264.545 403.546 265 402.986 265H380.067C379.507 265 379.053 264.545 379.053 263.983L379.002 157.157L379 157.16Z\"\n                fill=\"currentColor\"\n            />\n            <path\n                d=\"M402.441 157.577C407.849 163.03 413.39 171.339 416.725 177.934C417.283 179.035 418.406 179.735 419.644 179.735H446.359C446.856 179.735 447.258 180.136 447.258 180.632V263.974C447.258 264.541 447.718 265 448.286 265H471.222C471.79 265 472.25 264.541 472.25 263.974V180.632C472.25 180.136 472.652 179.735 473.149 179.735H509.159C509.746 179.735 510.151 179.149 509.946 178.6C506.508 169.433 501.248 161.673 493.666 155.71C493.086 155.253 492.37 155 491.629 155H403.52C402.173 155 401.493 156.621 402.443 157.577H402.441Z\"\n                fill=\"currentColor\"\n            />\n        </svg>\n    );\n}\n\nexport function Logo({ className }: React.ComponentProps<'svg'>) {\n    return (\n        <svg\n            width=\"603\"\n            height=\"347\"\n            viewBox=\"0 0 603 347\"\n            className={cn('text-linen-900 dark:text-linen-100 w-full', className)}\n            fill=\"none\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n        >\n            <path\n                d=\"M154.282 251.072C154.282 251.072 177.873 236.243 215.952 217.595C248.7 201.56 254.201 185.44 255.099 181.239C255.143 181.035 255.438 181.043 255.47 181.249C257.293 192.8 253.986 232.974 252.013 242.083C250.008 251.327 246.134 258.578 240.631 265.207C235.128 271.834 228.656 274.253 223.279 275.657C210.369 279.025 179.868 285.935 153.231 300.333C126.134 314.981 111.425 342.048 108.953 346.897C108.861 347.076 108.593 347.006 108.595 346.805C109.314 314.962 113.931 300.985 119.388 287.644C125.884 271.764 111.772 267.585 102.155 267.585H62.3613C29.5502 267.585 -1.59507 245.664 0.0633979 221.203C0.143295 220.04 1.02701 219.089 2.17462 218.898C12.5951 217.171 22.4055 212.426 22.4055 212.426C38.4551 205.954 51.2193 185.127 55.2625 180.578C59.3058 176.029 66.5716 161.18 83.5703 157.325C101.06 153.359 117.301 139.973 121.989 121.434C125.921 105.883 144.624 18.9581 148.192 2.34895C148.546 0.704984 150.183 -0.309476 151.817 0.0851729C167.733 3.92271 205.036 29.2698 225.056 61.1105C242.885 89.4648 255.85 128.753 242.108 166.189C224.526 214.084 154.286 251.072 154.286 251.072H154.282Z\"\n                fill=\"currentColor\"\n            />\n            <path\n                d=\"M385.051 108.099H404.812C405.882 108.099 406.483 109.331 405.821 110.173L359.262 171.175C354.869 177.596 355.209 182.918 359.19 187.396C359.236 187.45 359.282 187.505 359.326 187.561L410.639 251.508C411.403 252.544 410.665 254.009 409.377 254.009H385.466C380.287 254.009 374.191 249.591 369.468 244.563C364.745 239.534 345.394 213.328 341.433 208.452C339.203 205.709 335.936 202.727 330.371 202.727C327.446 202.727 321.985 204.937 321.985 210.737V252.311C321.985 253.247 321.226 254.006 320.289 254.006H290.316C289.38 254.006 288.62 253.247 288.62 252.311V94.2864C288.62 92.9546 290.081 92.142 291.214 92.8454C299.178 97.7965 322.752 113.424 322.752 124.946V167.837C322.752 170.493 326.075 171.694 327.768 169.646C337.328 158.083 361.717 123.1 364.032 120.116C372.66 108.994 379.462 108.096 385.056 108.096L385.051 108.099Z\"\n                fill=\"currentColor\"\n            />\n            <path\n                d=\"M427.782 109.542C427.782 108.412 428.983 107.662 430.043 108.13C439.501 112.296 461.36 137.609 461.36 149.265V252.648C461.36 253.4 460.749 254.011 459.997 254.011H429.213C428.461 254.011 427.85 253.402 427.85 252.648L427.782 109.542Z\"\n                fill=\"currentColor\"\n            />\n            <path\n                d=\"M459.885 111.277C467.051 118.515 474.391 129.548 478.809 138.303C479.546 139.765 481.036 140.694 482.676 140.694H518.066C518.723 140.694 519.257 141.228 519.257 141.886V252.536C519.257 253.288 519.868 253.9 520.62 253.9H551.006C551.758 253.9 552.369 253.288 552.369 252.536V141.886C552.369 141.228 552.903 140.694 553.56 140.694H601.261C602.04 140.694 602.576 139.916 602.302 139.188C597.749 127.015 590.779 116.715 580.734 108.798C579.965 108.191 579.016 107.854 578.036 107.854H461.314C459.528 107.854 458.628 110.006 459.885 111.274V111.277Z\"\n                fill=\"currentColor\"\n            />\n        </svg>\n    );\n}\n"
  },
  {
    "path": "docs/src/app/recipes/[[...slug]]/page.tsx",
    "content": "import { mdxComponents } from '@/app/layout.config';\nimport { LLMCopyButton, ViewOptions } from '@/components/page-actions';\nimport { overridenMdxComponents } from '@/lib/Overrides';\nimport { recipesSource } from '@/lib/source';\nimport { getPageTreePeers } from 'fumadocs-core/server';\nimport { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page';\nimport { notFound } from 'next/navigation';\n\nexport default async function Page(props: { params: Promise<{ slug?: string[] }> }) {\n    const params = await props.params;\n    const page = recipesSource.getPage(params.slug);\n    if (!page) notFound();\n\n    const MDX = page.data.body;\n    const hasCategory = page.file.name === 'index' && page.slugs.length > 0;\n\n    return (\n        <DocsPage toc={page.data.toc} full={page.data.full}>\n            <DocsTitle>{page.data.title}</DocsTitle>\n\n            <DocsDescription className=\"mb-0\">{page.data.description}</DocsDescription>\n            <div className=\"flex flex-row gap-2 items-center mb-8\">\n                <LLMCopyButton markdownUrl={`${page.url}.mdx`} />\n                <ViewOptions\n                    markdownUrl={`${page.url}.mdx`}\n                    githubUrl={`https://github.com/anza-xyz/kit/blob/main/docs/content${page.url}.mdx`}\n                />\n            </div>\n\n            <DocsBody>\n                <MDX components={mdxComponents} />\n            </DocsBody>\n            {hasCategory && (\n                <overridenMdxComponents.Cards>\n                    {getPageTreePeers(recipesSource.pageTree, page.url).map(peer => (\n                        <overridenMdxComponents.Card key={peer.url} title={peer.name} href={peer.url}>\n                            {peer.description}\n                        </overridenMdxComponents.Card>\n                    ))}\n                </overridenMdxComponents.Cards>\n            )}\n        </DocsPage>\n    );\n}\n\nexport async function generateStaticParams() {\n    return recipesSource.generateParams();\n}\n\nexport async function generateMetadata(props: { params: Promise<{ slug?: string[] }> }) {\n    const params = await props.params;\n    const page = recipesSource.getPage(params.slug);\n    if (!page) notFound();\n\n    return {\n        title: page.data.title,\n        description: page.data.description,\n    };\n}\n"
  },
  {
    "path": "docs/src/app/recipes/layout.tsx",
    "content": "import { baseOptions } from '@/app/layout.config';\nimport { recipesSource } from '@/lib/source';\nimport { DocsLayout, DocsLayoutProps } from 'fumadocs-ui/layouts/docs';\nimport type { ReactNode } from 'react';\nimport { Sidebar } from '../docs/sidebar';\nimport { Navbar } from '../docs/navbar';\n\nexport default function Layout({ children }: { children: ReactNode }) {\n    const baseProps: DocsLayoutProps = {\n        ...baseOptions,\n        tree: recipesSource.pageTree,\n    };\n\n    const recipesProps: DocsLayoutProps = {\n        ...baseProps,\n        sidebar: { ...baseProps.sidebar, component: Sidebar(baseProps) },\n        nav: { ...baseProps.nav, component: Navbar(baseProps) },\n    };\n\n    return <DocsLayout {...recipesProps}>{children}</DocsLayout>;\n}\n"
  },
  {
    "path": "docs/src/app/styles/brand.css",
    "content": "@theme {\n    /* ---------*/\n    /* Colours. */\n    /* ---------*/\n\n    /* Linen scale. */\n    --color-linen-50: #f9f6f1;\n    --color-linen-100: #f4eee5; /* Brand color. */\n    --color-linen-200: #eae1da; /* Brand color. */\n    --color-linen-300: #d6beac; /* Brand color. */\n    --color-linen-400: #b2927c; /* Brand color. */\n    --color-linen-500: #8a6b5b;\n    --color-linen-600: #715346;\n    --color-linen-700: #513a30;\n    --color-linen-800: #2f2420;\n    --color-linen-900: #14131d; /* Brand color. */\n\n    /* Coral scale. */\n    --color-coral-50: #fff4ef;\n    --color-coral-100: #ffe3d6;\n    --color-coral-200: #ffc1ac;\n    --color-coral-300: #ffa184;\n    --color-coral-400: #f5814e; /* Brand color. */\n    --color-coral-500: #d8582b; /* Brand color. */\n    --color-coral-600: #b94727;\n    --color-coral-700: #933923;\n    --color-coral-800: #6b2a1f;\n    --color-coral-900: #421b1a;\n\n    /* Mauve scale. */\n    --color-mauve-50: #fbf9fb;\n    --color-mauve-100: #f5edf3;\n    --color-mauve-200: #e2d8e0;\n    --color-mauve-300: #c6b4c4;\n    --color-mauve-400: #9b8196; /* Brand color. */\n    --color-mauve-450: #8b79ad; /* Brand color. */\n    --color-mauve-500: #83617d; /* Brand color. */\n    --color-mauve-600: #6b4e66;\n    --color-mauve-700: #533b4f;\n    --color-mauve-800: #392938;\n    --color-mauve-900: #1f1721;\n\n    /* -------*/\n    /* Fonts. */\n    /* -------*/\n\n    --font-sans: 'corbel', 'sans-serif';\n    --font-title: 'neulis-neue', 'sans-serif';\n\n    /* -------*/\n    /* Sizes. */\n    /* -------*/\n\n    --spacing-home-container: 1000px;\n}\n"
  },
  {
    "path": "docs/src/app/styles/fumadocs-overrides.css",
    "content": "/* -------- */\n/* Colours. */\n/* -------- */\n\n@theme {\n    --color-fd-background: var(--color-linen-100);\n    --color-fd-foreground: var(--color-linen-900);\n    --color-fd-border: var(--color-linen-300);\n    --color-fd-muted: var(--color-linen-200);\n    --color-fd-muted-foreground: var(--color-linen-500);\n    --color-fd-popover: var(--color-linen-200);\n    --color-fd-popover-foreground: var(--color-linen-900);\n    --color-fd-card: var(--color-linen-200);\n    --color-fd-card-foreground: var(--color-linen-800);\n    --color-fd-primary: var(--color-coral-400);\n    --color-fd-primary-foreground: var(--color-linen-100);\n    --color-fd-secondary: var(--color-mauve-400);\n    --color-fd-secondary-foreground: var(--color-linen-100);\n    --color-fd-accent: var(--color-linen-300);\n    --color-fd-accent-foreground: var(--color-linen-900);\n}\n\n.dark {\n    --color-fd-background: var(--color-mauve-900);\n    --color-fd-foreground: var(--color-mauve-100);\n    --color-fd-border: var(--color-linen-700);\n    --color-fd-muted: var(--color-linen-800);\n    --color-fd-muted-foreground: var(--color-linen-400);\n    --color-fd-popover: var(--color-mauve-900);\n    --color-fd-popover-foreground: var(--color-linen-50);\n    --color-fd-card: var(--color-linen-800);\n    --color-fd-card-foreground: var(--color-linen-200);\n    --color-fd-primary: var(--color-coral-400);\n    --color-fd-primary-foreground: var(--color-linen-100);\n    --color-fd-secondary: var(--color-linen-800);\n    --color-fd-card-foreground: var(--color-linen-200);\n    --color-fd-accent: var(--color-linen-500);\n    --color-fd-accent-foreground: var(--color-linen-300);\n}\n\n/* ------- */\n/* Navbar. */\n/* ------- */\n\n#nd-nav {\n    --spacing-fd-container: var(--spacing-home-container);\n    --color-fd-secondary: var(--color-fd-background);\n    left: 0; /* overrides: left-1/2 */\n    max-width: 100%; /* overrides: max-w-fd-container */\n    translate: none; /* overrides: -translate-x-1/2 */\n    margin: 0; /* overrides: lg:mt-2 */\n    width: 100%; /* overrides: w-full lg:w-[calc(100%-1rem)] */\n    border: none; /* overrides: lg:border border-b border-fd-foreground/10 */\n    border-bottom: 1px solid var(--color-fd-border);\n    box-shadow: none; /* overrides: lg:shadow */\n    border-radius: 0; /* overrides: lg:rounded-2xl */\n}\n\n#nd-home-layout {\n    @apply pt-14 md:pt-18; /* overrides: pt-14 */\n}\n\n#nd-nav nav {\n    @apply h-14 md:h-18; /* overrides: h-14 */\n}\n\n#nd-nav > div:first-child {\n    @apply max-w-fd-container mx-auto;\n}\n\n/* -------- */\n/* Sidebar. */\n/* -------- */\n\n#nd-sidebar {\n    background-color: var(--color-fd-background);\n}\n\n.dark #nd-sidebar {\n    --color-fd-muted-foreground: var(--color-linen-400);\n}\n\n/* --------------- */\n/* Search buttons. */\n/* --------------- */\n\n#nd-sidebar button[data-search-full],\n#nd-nav button[data-search-full] {\n    @apply bg-linen-200 hover:bg-linen-50 dark:bg-mauve-800 dark:hover:bg-mauve-900;\n}\n\n/* ----- */\n/* Tabs. */\n/* ----- */\n\n.fd-tabs {\n    background-color: inherit;\n    --color-fd-border: var(--color-mauve-400);\n    --color-fd-secondary: var(--color-mauve-400);\n    --color-fd-muted-foreground: var(--color-mauve-200);\n}\n\n.fd-tabs > div[role='tablist'] {\n    --color-fd-primary: var(--color-linen-100);\n    --color-fd-accent-foreground: var(--color-linen-100);\n}\n\n.dark .fd-tabs {\n    --color-fd-border: var(--color-mauve-700);\n    --color-fd-secondary: var(--color-mauve-700);\n    --color-fd-muted-foreground: var(--color-mauve-200);\n}\n\n.dark .fd-tabs > div[role='tablist'] {\n    --color-fd-primary: var(--color-linen-100);\n    --color-fd-accent-foreground: var(--color-linen-100);\n}\n\n/* ----- */\n/* Code. */\n/* ----- */\n\n.fd-codeblock {\n    --color-fd-muted: var(--color-mauve-400);\n    --color-fd-muted-foreground: var(--color-linen-100);\n    --color-fd-secondary: var(--color-mauve-200);\n    --color-fd-border: var(--color-mauve-400);\n}\n\n.dark .fd-codeblock {\n    --color-fd-muted: var(--color-mauve-700);\n    --color-fd-muted-foreground: var(--color-linen-200);\n    --color-fd-secondary: var(--color-mauve-800);\n    --color-fd-border: var(--color-mauve-700);\n}\n\n#hero-code .fd-codeblock pre {\n    @apply p-4 md:p-6 lg:p-6;\n}\n\n#hero-code .fd-codeblock pre > code {\n    @apply text-sm md:text-base lg:text-base;\n}\n\n/* ------ */\n/* Steps. */\n/* ------ */\n\n.fd-steps {\n    --color-fd-border: var(--color-linen-300);\n}\n\n.fd-step::before {\n    font-family: var(--font-title);\n    font-size: 0.85rem;\n    --color-fd-secondary: var(--color-linen-400);\n}\n\n.dark .fd-steps {\n    --color-fd-border: var(--color-linen-700);\n}\n\n.dark .fd-step::before {\n    --color-fd-secondary: var(--color-linen-600);\n}\n\n/* ------ */\n/* Cards. */\n/* ------ */\n\n.fd-card {\n    @apply bg-linen-200 hover:bg-linen-300 dark:bg-linen-800 dark:hover:bg-linen-700;\n}\n\n/* ------------------ */\n/* Prev/Next Buttons. */\n/* ------------------ */\n\n#nd-page > article > div:last-child > a {\n    @apply bg-linen-100 hover:bg-linen-200 dark:bg-mauve-900 dark:hover:bg-linen-800;\n}\n"
  },
  {
    "path": "docs/src/app/styles/typography.css",
    "content": "/* ------ */\n/* Fonts. */\n/* ------ */\n\nh1,\nh2,\nh3 {\n    font-family: var(--font-title);\n    font-weight: 700;\n}\n\n.prose :where(strong):not(:where([class~='not-prose'], [class~='not-prose'] *)) {\n    font-weight: 700;\n}\n\n.prose :where(code):not(:where([class~='not-prose'], [class~='not-prose'] *)) {\n    font-weight: inherit;\n}\n\n/* -------- */\n/* Spacing. */\n/* -------- */\n\n.prose :where(h2):not(:where([class~='not-prose'], [class~='not-prose'] *, :first-child)) {\n    margin-top: 4em;\n}\n\n.prose :where(h3):not(:where([class~='not-prose'], [class~='not-prose'] *)) {\n    margin-top: 3em;\n}\n\n/* ------- */\n/* Tables. */\n/* ------- */\n\n.prose :where(table):not(:where([class~='not-prose'], [class~='not-prose'] *)) {\n    background-color: inherit;\n}\n"
  },
  {
    "path": "docs/src/components/card-tabs.tsx",
    "content": "'use client';\n\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from 'fumadocs-ui/components/ui/tabs';\nimport { createContext, useContext, useLayoutEffect, useMemo, useState, type ReactNode } from 'react';\nimport { cn } from 'fumadocs-ui/utils/cn';\nimport { FlaskConicalIcon, GlobeIcon, LaptopIcon, PuzzleIcon, type LucideIcon } from 'lucide-react';\n\nconst iconMap: Record<string, LucideIcon> = {\n    globe: GlobeIcon,\n    laptop: LaptopIcon,\n    'flask-conical': FlaskConicalIcon,\n    puzzle: PuzzleIcon,\n};\n\ninterface CardDefinition {\n    title: string;\n    description: string;\n    icon?: string;\n}\n\ninterface CardTabsProps {\n    cards: CardDefinition[];\n    groupId?: string;\n    persist?: boolean;\n    children: ReactNode;\n}\n\nfunction toValue(title: string): string {\n    return title.toLowerCase().replace(/\\s+/g, '-');\n}\n\nconst CardTabContext = createContext<{ values: string[]; register: () => number }>({\n    values: [],\n    register: () => 0,\n});\n\n/**\n * Renders a tab list as a grid of selectable cards.\n *\n * @param props - Card tab configuration and tab panel children.\n * @return A card-styled tab group.\n */\nexport function CardTabs({ cards, groupId, persist = false, children }: CardTabsProps) {\n    const values = useMemo(() => cards.map(c => toValue(c.title)), [cards]);\n    const [value, setValue] = useState(values[0]);\n\n    useLayoutEffect(() => {\n        if (!groupId) return;\n        const stored = persist ? localStorage.getItem(groupId) : sessionStorage.getItem(groupId);\n        if (stored && values.includes(stored)) {\n            setValue(stored);\n        }\n    }, [groupId, persist, values]);\n\n    function handleChange(v: string) {\n        setValue(v);\n        if (groupId) {\n            if (persist) localStorage.setItem(groupId, v);\n            else sessionStorage.setItem(groupId, v);\n        }\n    }\n\n    // Collection pattern: each CardTab calls register() during render\n    // to get its index. The counter resets on each render cycle.\n    const collectionRef = useMemo(() => ({ current: 0 }), []);\n    collectionRef.current = 0;\n\n    const ctx = useMemo(\n        () => ({\n            values,\n            register: () => collectionRef.current++,\n        }),\n        [values, collectionRef],\n    );\n\n    return (\n        <Tabs\n            value={value}\n            onValueChange={handleChange}\n            className=\"my-6 border-none bg-transparent overflow-visible rounded-none\"\n        >\n            <TabsList className=\"not-prose grid grid-cols-1 gap-3 sm:grid-cols-2 bg-transparent px-0 h-auto items-stretch\">\n                {cards.map((card, i) => {\n                    const Icon = card.icon ? iconMap[card.icon] : undefined;\n                    return (\n                        <TabsTrigger\n                            key={values[i]}\n                            value={values[i]}\n                            className={cn(\n                                'group cursor-pointer rounded-lg border p-4 text-left transition-colors whitespace-normal h-auto',\n                                'border-fd-border bg-fd-card hover:border-fd-primary/50',\n                                'data-[state=active]:border-fd-primary data-[state=active]:bg-fd-primary/5',\n                            )}\n                        >\n                            <div className=\"flex items-start gap-3\">\n                                {Icon && (\n                                    <Icon className=\"size-5 shrink-0 mt-0.5 text-fd-muted-foreground group-data-[state=active]:text-fd-primary\" />\n                                )}\n                                <div>\n                                    <div className=\"text-sm font-semibold text-fd-foreground group-data-[state=active]:text-fd-primary\">\n                                        {card.title}\n                                    </div>\n                                    <div className=\"mt-1 text-xs text-fd-muted-foreground\">{card.description}</div>\n                                </div>\n                            </div>\n                        </TabsTrigger>\n                    );\n                })}\n            </TabsList>\n            <CardTabContext.Provider value={ctx}>{children}</CardTabContext.Provider>\n        </Tabs>\n    );\n}\n\n/**\n * Renders one panel within a {@link CardTabs} group.\n *\n * @param props - The tab panel children to render.\n * @return A tab panel associated with the next card in the parent group.\n * @throws Throws if there are more `CardTab` children than card definitions.\n */\nexport function CardTab({ children }: { children: ReactNode }) {\n    const ctx = useContext(CardTabContext);\n    const index = ctx.register();\n    const value = ctx.values[index];\n\n    if (!value) {\n        throw new Error(\n            `CardTab at index ${index} does not have a matching card definition. ` +\n                `Make sure the number of CardTab children matches the number of cards.`,\n        );\n    }\n\n    return (\n        <TabsContent value={value} className=\"prose-no-margin\">\n            {children}\n        </TabsContent>\n    );\n}\n"
  },
  {
    "path": "docs/src/components/page-actions.tsx",
    "content": "'use client';\nimport { useMemo, useState } from 'react';\nimport { Check, ChevronDown, Copy, ExternalLinkIcon } from 'lucide-react';\nimport { cn } from '../lib/cn';\nimport { useCopyButton } from 'fumadocs-ui/utils/use-copy-button';\nimport { buttonVariants } from './ui/button';\nimport { Popover, PopoverContent, PopoverTrigger } from './ui/popover';\nimport { cva } from 'class-variance-authority';\n\nconst cache = new Map<string, string>();\n\nexport function LLMCopyButton({\n  /**\n   * A URL to fetch the raw Markdown/MDX content of page\n   */\n  markdownUrl,\n}: {\n  markdownUrl: string;\n}) {\n  const [isLoading, setLoading] = useState(false);\n  const [checked, onClick] = useCopyButton(async () => {\n    const cached = cache.get(markdownUrl);\n    if (cached) return navigator.clipboard.writeText(cached);\n\n    setLoading(true);\n\n    try {\n      await navigator.clipboard.write([\n        new ClipboardItem({\n          'text/plain': fetch(markdownUrl).then(async (res) => {\n            const content = await res.text();\n            cache.set(markdownUrl, content);\n\n            return content;\n          }),\n        }),\n      ]);\n    } finally {\n      setLoading(false);\n    }\n  });\n\n  return (\n    <button\n      disabled={isLoading}\n      className={cn(\n        buttonVariants({\n          color: 'secondary',\n          size: 'sm',\n          className: 'gap-2 [&_svg]:size-3.5 [&_svg]:text-fd-muted-foreground',\n        }),\n      )}\n      onClick={onClick}\n    >\n      {checked ? <Check /> : <Copy />}\n      Copy Markdown\n    </button>\n  );\n}\n\nconst optionVariants = cva(\n  'text-sm p-2 rounded-lg inline-flex items-center gap-2 hover:text-fd-accent-foreground hover:bg-fd-accent [&_svg]:size-4',\n);\n\nexport function ViewOptions({\n  markdownUrl,\n  githubUrl,\n}: {\n  /**\n   * A URL to the raw Markdown/MDX content of page\n   */\n  markdownUrl: string;\n\n  /**\n   * Source file URL on GitHub\n   */\n  githubUrl: string;\n}) {\n  const items = useMemo(() => {\n    const fullMarkdownUrl =\n      typeof window !== 'undefined' ? new URL(markdownUrl, window.location.origin) : 'loading';\n    const q = `Read ${fullMarkdownUrl}, I want to ask questions about it.`;\n\n    return [\n      {\n        title: 'Open in GitHub',\n        href: githubUrl,\n        icon: (\n          <svg fill=\"currentColor\" role=\"img\" viewBox=\"0 0 24 24\">\n            <title>GitHub</title>\n            <path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\" />\n          </svg>\n        ),\n      },\n      {\n        title: 'Open in Scira AI',\n        href: `https://scira.ai/?${new URLSearchParams({\n          q,\n        })}`,\n        icon: (\n          <svg\n            width=\"910\"\n            height=\"934\"\n            viewBox=\"0 0 910 934\"\n            fill=\"none\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n          >\n            <title>Scira AI</title>\n            <path\n              d=\"M647.664 197.775C569.13 189.049 525.5 145.419 516.774 66.8849C508.048 145.419 464.418 189.049 385.884 197.775C464.418 206.501 508.048 250.131 516.774 328.665C525.5 250.131 569.13 206.501 647.664 197.775Z\"\n              fill=\"currentColor\"\n              stroke=\"currentColor\"\n              strokeWidth=\"8\"\n              strokeLinejoin=\"round\"\n            />\n            <path\n              d=\"M516.774 304.217C510.299 275.491 498.208 252.087 480.335 234.214C462.462 216.341 439.058 204.251 410.333 197.775C439.059 191.3 462.462 179.209 480.335 161.336C498.208 143.463 510.299 120.06 516.774 91.334C523.25 120.059 535.34 143.463 553.213 161.336C571.086 179.209 594.49 191.3 623.216 197.775C594.49 204.251 571.086 216.341 553.213 234.214C535.34 252.087 523.25 275.491 516.774 304.217Z\"\n              fill=\"currentColor\"\n              stroke=\"currentColor\"\n              strokeWidth=\"8\"\n              strokeLinejoin=\"round\"\n            />\n            <path\n              d=\"M857.5 508.116C763.259 497.644 710.903 445.288 700.432 351.047C689.961 445.288 637.605 497.644 543.364 508.116C637.605 518.587 689.961 570.943 700.432 665.184C710.903 570.943 763.259 518.587 857.5 508.116Z\"\n              stroke=\"currentColor\"\n              strokeWidth=\"20\"\n              strokeLinejoin=\"round\"\n            />\n            <path\n              d=\"M700.432 615.957C691.848 589.05 678.575 566.357 660.383 548.165C642.191 529.973 619.499 516.7 592.593 508.116C619.499 499.533 642.191 486.258 660.383 468.066C678.575 449.874 691.848 427.181 700.432 400.274C709.015 427.181 722.289 449.874 740.481 468.066C758.673 486.258 781.365 499.533 808.271 508.116C781.365 516.7 758.673 529.973 740.481 548.165C722.289 566.357 709.015 589.05 700.432 615.957Z\"\n              stroke=\"currentColor\"\n              strokeWidth=\"20\"\n              strokeLinejoin=\"round\"\n            />\n            <path\n              d=\"M889.949 121.237C831.049 114.692 798.326 81.9698 791.782 23.0692C785.237 81.9698 752.515 114.692 693.614 121.237C752.515 127.781 785.237 160.504 791.782 219.404C798.326 160.504 831.049 127.781 889.949 121.237Z\"\n              fill=\"currentColor\"\n              stroke=\"currentColor\"\n              strokeWidth=\"8\"\n              strokeLinejoin=\"round\"\n            />\n            <path\n              d=\"M791.782 196.795C786.697 176.937 777.869 160.567 765.16 147.858C752.452 135.15 736.082 126.322 716.226 121.237C736.082 116.152 752.452 107.324 765.16 94.6152C777.869 81.9065 786.697 65.5368 791.782 45.6797C796.867 65.5367 805.695 81.9066 818.403 94.6152C831.112 107.324 847.481 116.152 867.338 121.237C847.481 126.322 831.112 135.15 818.403 147.858C805.694 160.567 796.867 176.937 791.782 196.795Z\"\n              fill=\"currentColor\"\n              stroke=\"currentColor\"\n              strokeWidth=\"8\"\n              strokeLinejoin=\"round\"\n            />\n            <path\n              d=\"M760.632 764.337C720.719 814.616 669.835 855.1 611.872 882.692C553.91 910.285 490.404 924.255 426.213 923.533C362.022 922.812 298.846 907.419 241.518 878.531C184.19 849.643 134.228 808.026 95.4548 756.863C56.6815 705.7 30.1238 646.346 17.8129 583.343C5.50207 520.339 7.76433 455.354 24.4266 393.359C41.089 331.364 71.7099 274.001 113.947 225.658C156.184 177.315 208.919 139.273 268.117 114.442\"\n              stroke=\"currentColor\"\n              strokeWidth=\"30\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n            />\n          </svg>\n        ),\n      },\n      {\n        title: 'Open in ChatGPT',\n        href: `https://chatgpt.com/?${new URLSearchParams({\n          hints: 'search',\n          q,\n        })}`,\n        icon: (\n          <svg\n            role=\"img\"\n            viewBox=\"0 0 24 24\"\n            fill=\"currentColor\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n          >\n            <title>OpenAI</title>\n            <path d=\"M22.2819 9.8211a5.9847 5.9847 0 0 0-.5157-4.9108 6.0462 6.0462 0 0 0-6.5098-2.9A6.0651 6.0651 0 0 0 4.9807 4.1818a5.9847 5.9847 0 0 0-3.9977 2.9 6.0462 6.0462 0 0 0 .7427 7.0966 5.98 5.98 0 0 0 .511 4.9107 6.051 6.051 0 0 0 6.5146 2.9001A5.9847 5.9847 0 0 0 13.2599 24a6.0557 6.0557 0 0 0 5.7718-4.2058 5.9894 5.9894 0 0 0 3.9977-2.9001 6.0557 6.0557 0 0 0-.7475-7.0729zm-9.022 12.6081a4.4755 4.4755 0 0 1-2.8764-1.0408l.1419-.0804 4.7783-2.7582a.7948.7948 0 0 0 .3927-.6813v-6.7369l2.02 1.1686a.071.071 0 0 1 .038.052v5.5826a4.504 4.504 0 0 1-4.4945 4.4944zm-9.6607-4.1254a4.4708 4.4708 0 0 1-.5346-3.0137l.142.0852 4.783 2.7582a.7712.7712 0 0 0 .7806 0l5.8428-3.3685v2.3324a.0804.0804 0 0 1-.0332.0615L9.74 19.9502a4.4992 4.4992 0 0 1-6.1408-1.6464zM2.3408 7.8956a4.485 4.485 0 0 1 2.3655-1.9728V11.6a.7664.7664 0 0 0 .3879.6765l5.8144 3.3543-2.0201 1.1685a.0757.0757 0 0 1-.071 0l-4.8303-2.7865A4.504 4.504 0 0 1 2.3408 7.872zm16.5963 3.8558L13.1038 8.364 15.1192 7.2a.0757.0757 0 0 1 .071 0l4.8303 2.7913a4.4944 4.4944 0 0 1-.6765 8.1042v-5.6772a.79.79 0 0 0-.407-.667zm2.0107-3.0231l-.142-.0852-4.7735-2.7818a.7759.7759 0 0 0-.7854 0L9.409 9.2297V6.8974a.0662.0662 0 0 1 .0284-.0615l4.8303-2.7866a4.4992 4.4992 0 0 1 6.6802 4.66zM8.3065 12.863l-2.02-1.1638a.0804.0804 0 0 1-.038-.0567V6.0742a4.4992 4.4992 0 0 1 7.3757-3.4537l-.142.0805L8.704 5.459a.7948.7948 0 0 0-.3927.6813zm1.0976-2.3654l2.602-1.4998 2.6069 1.4998v2.9994l-2.5974 1.4997-2.6067-1.4997Z\" />\n          </svg>\n        ),\n      },\n      {\n        title: 'Open in Claude',\n        href: `https://claude.ai/new?${new URLSearchParams({\n          q,\n        })}`,\n        icon: (\n          <svg\n            fill=\"currentColor\"\n            role=\"img\"\n            viewBox=\"0 0 24 24\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n          >\n            <title>Anthropic</title>\n            <path d=\"M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z\" />\n          </svg>\n        ),\n      },\n      {\n        title: 'Open in Cursor',\n        icon: (\n          <svg\n            fill=\"currentColor\"\n            role=\"img\"\n            viewBox=\"0 0 24 24\"\n            xmlns=\"http://www.w3.org/2000/svg\"\n          >\n            <title>Cursor</title>\n            <path d=\"M11.503.131 1.891 5.678a.84.84 0 0 0-.42.726v11.188c0 .3.162.575.42.724l9.609 5.55a1 1 0 0 0 .998 0l9.61-5.55a.84.84 0 0 0 .42-.724V6.404a.84.84 0 0 0-.42-.726L12.497.131a1.01 1.01 0 0 0-.996 0M2.657 6.338h18.55c.263 0 .43.287.297.515L12.23 22.918c-.062.107-.229.064-.229-.06V12.335a.59.59 0 0 0-.295-.51l-9.11-5.257c-.109-.063-.064-.23.061-.23\" />\n          </svg>\n        ),\n        href: `https://cursor.com/link/prompt?${new URLSearchParams({\n          text: q,\n        })}`,\n      },\n    ];\n  }, [githubUrl, markdownUrl]);\n\n  return (\n    <Popover>\n      <PopoverTrigger\n        className={cn(\n          buttonVariants({\n            color: 'secondary',\n            size: 'sm',\n            className: 'gap-2',\n          }),\n        )}\n      >\n        Open\n        <ChevronDown className=\"size-3.5 text-fd-muted-foreground\" />\n      </PopoverTrigger>\n      <PopoverContent className=\"flex flex-col\">\n        {items.map((item) => (\n          <a\n            key={item.href}\n            href={item.href}\n            rel=\"noreferrer noopener\"\n            target=\"_blank\"\n            className={cn(optionVariants())}\n          >\n            {item.icon}\n            {item.title}\n            <ExternalLinkIcon className=\"text-fd-muted-foreground size-3.5 ms-auto\" />\n          </a>\n        ))}\n      </PopoverContent>\n    </Popover>\n  );\n}\n"
  },
  {
    "path": "docs/src/components/ui/button.tsx",
    "content": "import { cva, type VariantProps } from 'class-variance-authority';\n\nconst variants = {\n  primary:\n    'bg-fd-primary text-fd-primary-foreground hover:bg-fd-primary/80 disabled:bg-fd-secondary disabled:text-fd-secondary-foreground',\n  outline: 'border hover:bg-fd-accent hover:text-fd-accent-foreground',\n  ghost: 'hover:bg-fd-accent hover:text-fd-accent-foreground',\n  secondary:\n    'border bg-linen-200 text-linen-700 hover:bg-linen-300 dark:bg-fd-secondary dark:text-fd-secondary-foreground dark:hover:bg-fd-accent dark:hover:text-fd-accent-foreground',\n} as const;\n\nexport const buttonVariants = cva(\n  'inline-flex items-center justify-center rounded-md p-2 text-sm font-medium transition-colors duration-100 cursor-pointer disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-fd-ring',\n  {\n    variants: {\n      variant: variants,\n      // fumadocs use `color` instead of `variant`\n      color: variants,\n      size: {\n        sm: 'gap-1 px-2 py-1.5 text-xs',\n        icon: 'p-1.5 [&_svg]:size-5',\n        'icon-sm': 'p-1.5 [&_svg]:size-4.5',\n        'icon-xs': 'p-1 [&_svg]:size-4',\n      },\n    },\n  },\n);\n\nexport type ButtonProps = VariantProps<typeof buttonVariants>;\n"
  },
  {
    "path": "docs/src/components/ui/popover.tsx",
    "content": "'use client';\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport * as React from 'react';\nimport { cn } from '../../lib/cn';\n\nconst Popover = PopoverPrimitive.Root;\n\nconst PopoverTrigger = PopoverPrimitive.Trigger;\n\nconst PopoverContent = React.forwardRef<\n  React.ComponentRef<typeof PopoverPrimitive.Content>,\n  React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => (\n  <PopoverPrimitive.Portal>\n    <PopoverPrimitive.Content\n      ref={ref}\n      align={align}\n      sideOffset={sideOffset}\n      side=\"bottom\"\n      className={cn(\n        'z-50 origin-(--radix-popover-content-transform-origin) overflow-y-auto max-h-(--radix-popover-content-available-height) min-w-[240px] max-w-[98vw] rounded-xl border bg-fd-popover/60 backdrop-blur-lg p-2 text-sm text-fd-popover-foreground shadow-lg focus-visible:outline-none data-[state=closed]:animate-fd-popover-out data-[state=open]:animate-fd-popover-in',\n        className,\n      )}\n      {...props}\n    />\n  </PopoverPrimitive.Portal>\n));\nPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nconst PopoverClose = PopoverPrimitive.PopoverClose;\n\nexport { Popover, PopoverTrigger, PopoverContent, PopoverClose };\n"
  },
  {
    "path": "docs/src/lib/InKeepSearchDialog.tsx",
    "content": "'use client';\n\nimport { type InkeepModalSearchAndChatProps } from '@inkeep/cxkit-react';\nimport type { SharedProps } from 'fumadocs-ui/components/dialog/search';\nimport dynamic from 'next/dynamic';\n\nconst InkeepModalSearchAndChat = dynamic(\n    () => import('@inkeep/cxkit-react').then(({ InkeepModalSearchAndChat }) => InkeepModalSearchAndChat),\n    { ssr: false },\n);\nconst AI_ASSISTANT_NAME = 'Kit';\n\nexport default function InKeepSearchDialog(props: SharedProps) {\n    const { open, onOpenChange } = props;\n    const config: InkeepModalSearchAndChatProps = {\n        baseSettings: {\n            apiKey:\n                /**\n                 * Need to use search in development?\n                 *\n                 * ```shell\n                 * pnpm vercel link -p kit-docs -S anza-tech --yes\n                 * pnpm vercel env pull --environment=development\n                 * ```\n                 */\n                process.env.NEXT_PUBLIC_INKEEP_SEARCH_API_KEY,\n            colorMode: {\n                sync: {\n                    target: globalThis.document?.documentElement,\n                    attributes: ['class'],\n                    isDarkMode: attributes => !!attributes.class?.includes('dark'),\n                },\n            },\n            ...(process.env.NODE_ENV === 'development' ? { env: 'development' } : null),\n            organizationDisplayName: 'Kit',\n            primaryBrandColor: (() => {\n                if (typeof globalThis.getComputedStyle === 'undefined') {\n                    return '#ff0000'; // Should never appear.\n                }\n                const rootStyles = getComputedStyle(document.documentElement);\n                return rootStyles.getPropertyValue('--color-coral-400').trim();\n            })(),\n            privacyPreferences: {\n                optOutAnalyticalCookies: true,\n            },\n            transformSource(source) {\n                const detectedTabs: string[] = [];\n                if (source.url.startsWith('https://solana.stackexchange.com/')) {\n                    detectedTabs.push('Q & A');\n                } else if (source.contentType === 'documentation') {\n                    detectedTabs.push(source.breadcrumbs[0] === 'API' ? 'API' : 'Docs');\n                } else if (source.breadcrumbs.length === 0 && source.tabs?.includes('GitHub')) {\n                    // InKeep does not yet produce breadcrumbs for GitHub results, so we synthesize\n                    // them here.\n                    const match = source.url.match(/\\/(issues|pull)\\/(\\d+)/);\n                    if (match) {\n                        const [\n                            // eslint-disable-next-line @typescript-eslint/no-unused-vars\n                            _,\n                            model,\n                            number,\n                        ] = match;\n                        source.breadcrumbs = [model === 'pull' ? 'Pull Request' : 'Issue', number];\n                    }\n                }\n                return {\n                    ...source,\n                    tabs: Array.from(new Set([...(source.tabs ?? []), ...detectedTabs])),\n                    url:\n                        // Strip absolute URLs from the search results because InKeep will not\n                        // consider doc site articles as being first-party from the perspective of\n                        // the main domain in all environments (eg. development, staging).\n                        [/^https:\\/\\/[\\w-]+\\.vercel\\.app\\//, /^https:\\/\\/solanakit\\.com\\//].reduce(\n                            (url, regex) => url.replace(regex, '/'),\n                            source.url,\n                        ),\n                };\n            },\n        },\n        modalSettings: {\n            isOpen: open,\n            onOpenChange,\n        },\n        searchSettings: {\n            debounceTimeMs: 250,\n            tabs: ['All', ['API', { isAlwaysVisible: true }], ['Docs', { isAlwaysVisible: true }], 'Q & A', 'GitHub'],\n        },\n        aiChatSettings: {\n            aiAssistantAvatar: {\n                dark: '/mascots/dark-mascot-3-4.svg',\n                light: '/mascots/light-mascot-3-4.svg',\n            },\n            aiAssistantName: AI_ASSISTANT_NAME,\n            conversationVisibility: 'private',\n            disclaimerSettings: {\n                isEnabled: true,\n                label: 'Disclaimer',\n                tooltip: 'These AI-generated responses may be inaccurate or incomplete.',\n            },\n            exampleQuestions: [\n                'I have a 64-byte secret key. Can I use it to sign messages and transactions with Kit?',\n                'Show me how to subscribe for updates to the data of an account',\n                'How can I fetch all transaction in a given block?',\n            ],\n            introMessage: `Hi!\\n\\nI'm an AI assistant trained on the docs and API reference on this site.\\n\\nAsk me anything about \\`${AI_ASSISTANT_NAME}\\`.`,\n            placeholder: 'Ask me a question',\n        },\n    };\n\n    return <InkeepModalSearchAndChat {...config} />;\n}\n"
  },
  {
    "path": "docs/src/lib/Overrides.tsx",
    "content": "import { Card as BaseCard, Cards as BaseCards } from 'fumadocs-ui/components/card';\nimport { Tab as BaseTab, Tabs as BaseTabs } from 'fumadocs-ui/components/tabs';\nimport { Callout as BaseCallout } from 'fumadocs-ui/components/callout';\n\nexport const Callout = (props => <BaseCallout {...props} className=\"fd-callout shadow-none\" />) as typeof BaseCallout;\n\nexport const Card: typeof BaseCard = props => <BaseCard {...props} className=\"fd-card shadow-none\" />;\nexport const Cards: typeof BaseCards = BaseCards;\n\nexport const Tab: typeof BaseTab = BaseTab;\nexport const Tabs: typeof BaseTabs = props => <BaseTabs {...props} className=\"fd-tabs rounded-lg\" />;\n\nexport const overridenMdxComponents = { Callout, Card, Cards, Tab, Tabs };\n"
  },
  {
    "path": "docs/src/lib/Spread.tsx",
    "content": "import { ReactNode } from 'react';\n\nexport function Spread({ children }: { children: ReactNode }) {\n    return (\n        <div className=\"2xl:-mx-[min(8em,calc(calc(100vw-100%-var(--fd-sidebar-width)-var(--fd-toc-width)-8em)/2))]\">\n            {children}\n        </div>\n    );\n}\n"
  },
  {
    "path": "docs/src/lib/ThemedImage.tsx",
    "content": "import { cn } from 'fumadocs-ui/utils/cn';\nimport Image, { ImageProps, StaticImageData } from 'next/image';\n\nexport function ThemedImage({\n    alt,\n    className,\n    src,\n    ...props\n}: Omit<ImageProps, 'src' | 'priority' | 'loading'> & {\n    src: Readonly<{\n        dark: StaticImageData;\n        light: StaticImageData;\n    }>;\n}) {\n    const {\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        blurWidth: _1,\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        blurHeight: _2,\n        ...darkSrc\n    } = src.dark;\n    const {\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        blurWidth: _3,\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        blurHeight: _4,\n        ...lightSrc\n    } = src.light;\n    return (\n        <>\n            <Image {...lightSrc} {...props} alt={alt} className={cn(className, 'dark:hidden')} />\n            <Image {...darkSrc} {...props} alt={alt} className={cn(className, 'not-dark:hidden')} />\n        </>\n    );\n}\n"
  },
  {
    "path": "docs/src/lib/cn.ts",
    "content": "export { twMerge as cn } from 'tailwind-merge';\n"
  },
  {
    "path": "docs/src/lib/get-llm-text.ts",
    "content": "import { apiSource, docsSource } from '@/lib/source';\nimport type { InferPageType } from 'fumadocs-core/source';\n\nexport async function getLLMText(page: InferPageType<typeof apiSource | typeof docsSource>) {\n    const processed = await page.data.getText('processed');\n\n    return `# ${page.data.title} (${page.url})\n${processed}`;\n}\n"
  },
  {
    "path": "docs/src/lib/source.ts",
    "content": "import { api, docs, recipes } from '@/.source';\nimport { loader } from 'fumadocs-core/source';\n\nexport const apiSource = loader({\n    baseUrl: '/api',\n    source: api.toFumadocsSource(),\n});\n\nexport const docsSource = loader({\n    baseUrl: '/docs',\n    source: docs.toFumadocsSource(),\n});\n\nexport const recipesSource = loader({\n    baseUrl: '/recipes',\n    source: recipes.toFumadocsSource(),\n});\n"
  },
  {
    "path": "docs/tsconfig.json",
    "content": "{\n    \"compilerOptions\": {\n        \"baseUrl\": \".\",\n        \"target\": \"ESNext\",\n        \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n        \"allowJs\": true,\n        \"skipLibCheck\": true,\n        \"strict\": true,\n        \"forceConsistentCasingInFileNames\": true,\n        \"noEmit\": true,\n        \"esModuleInterop\": true,\n        \"module\": \"esnext\",\n        \"moduleResolution\": \"bundler\",\n        \"resolveJsonModule\": true,\n        \"isolatedModules\": true,\n        \"jsx\": \"react-jsx\",\n        \"incremental\": true,\n        \"paths\": {\n            \"@/.source\": [\"./.source/index.ts\"],\n            \"@/public/*\": [\"./public/*\"],\n            \"@/*\": [\"./src/*\"]\n        },\n        \"plugins\": [\n            {\n                \"name\": \"next\"\n            }\n        ]\n    },\n    \"include\": [\"next-env.d.ts\", \"**/*.ts\", \"**/*.tsx\", \".next/types/**/*.ts\", \".next/dev/types/**/*.ts\"],\n    \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "eslint.config.mjs",
    "content": "export { default } from '@solana/eslint-config/eslint.config.mjs';\n"
  },
  {
    "path": "examples/README.md",
    "content": "# Examples\n\n## One-time setup\n\nStart by installing all dependencies.\n\n```shell\npnpm install\n```\n\nMost examples use a local test Solana validator. Install one by running the following command in the root of this monorepo.\n\n```shell\npnpm test:setup\n```\n\n## Run an example\n\nIn the directory of a given example, run its start script.\n\n```shell\npnpm start\n```\n"
  },
  {
    "path": "examples/deserialize-transaction/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/deserialize-transaction/package.json",
    "content": "{\n    \"name\": \"@solana/example-deserialize-transaction\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"scripts\": {\n        \"prestart\": \"turbo --output-logs=errors-only compile:js compile:typedefs\",\n        \"run:example\": \"tsx src/example.ts\",\n        \"start\": \"start-server-and-test '../../scripts/start-shared-test-validator.sh' http://127.0.0.1:8899/health run:example\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent --testMatch '<rootDir>src/**/*.{ts,tsx}'\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc\"\n    },\n    \"dependencies\": {\n        \"@solana-program/address-lookup-table\": \"^0.11.0\",\n        \"@solana-program/memo\": \"^0.11.0\",\n        \"@solana-program/system\": \"^0.12.0\",\n        \"@solana/example-utils\": \"workspace:*\",\n        \"@solana/kit\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"start-server-and-test\": \"^2.1.5\",\n        \"tsx\": \"^4.21.0\"\n    }\n}\n"
  },
  {
    "path": "examples/deserialize-transaction/src/example.ts",
    "content": "/**\n * EXAMPLE\n * Deserialize and inspect a transaction with @solana/kit\n *\n * Before running any of the examples in this monorepo, make sure to set up a test validator by\n * running `pnpm test:setup` in the root directory.\n *\n * To run this example, execute `pnpm start` in this directory.\n */\nimport { createLogger } from '@solana/example-utils/createLogger.js';\nimport {\n    Address,\n    appendTransactionMessageInstructions,\n    assertIsInstructionWithAccounts,\n    assertIsInstructionWithData,\n    compressTransactionMessageUsingAddressLookupTables,\n    createKeyPairSignerFromBytes,\n    createSolanaRpc,\n    createTransactionMessage,\n    decompileTransactionMessageFetchingLookupTables,\n    getBase64EncodedWireTransaction,\n    getBase64Encoder,\n    getCompiledTransactionMessageDecoder,\n    getPublicKeyFromAddress,\n    getTransactionDecoder,\n    lamports,\n    partiallySignTransactionMessageWithSigners,\n    pipe,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n    verifySignature,\n} from '@solana/kit';\nimport { fetchAddressLookupTable } from '@solana-program/address-lookup-table';\nimport { getAddMemoInstruction, MEMO_PROGRAM_ADDRESS, parseAddMemoInstruction } from '@solana-program/memo';\nimport {\n    getTransferSolInstruction,\n    identifySystemInstruction,\n    parseTransferSolInstruction,\n    SystemInstruction,\n} from '@solana-program/system';\n\nconst log = createLogger('Deserialize');\n\n/**\n * SETUP: LOOKUP TABLE ADDRESS\n * Our fixtures include a lookup table, which we're going to use for this transaction\n * This is the address of the lookup table account from `scripts/fixtures/example-deserialize-transaction-address-lookup-table.json`\n */\nconst LOOKUP_TABLE_ADDRESS = 'DUbh3qSh4Vvxa52LGtCBCcuvAEMh62FLNkupnsBjhrCc' as Address;\nlog.info({ address: LOOKUP_TABLE_ADDRESS }, '[setup] Setting lookup table address');\n\n/**\n * SETUP: RPC CONNECTION\n * While in this example we won't send the transaction, we will use the remote procedure call (RPC) server to:\n * - fetch the blockhash for the transaction lifetime\n * - fetch the address lookup table used in the transaction\n *\n * This example uses your local test validator which must be running before you run this script.\n */\nconst rpc = createSolanaRpc('http://127.0.0.1:8899');\n\n/**\n * SETUP: TRANSACTION LIFETIME\n * We will fetch the latest blockhash, which we will use as the transaction's lifetime\n * See `examples/transfer-lamports` for more detail on transaction lifetime\n */\nconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\nlog.info(latestBlockhash, '[setup] Got a blockhash');\n\n/**\n * SETUP: CREATE A TRANSACTION MESSAGE\n * We create a transaction that sends lamports from a source account to a destination account,\n * where the destination account is in the lookup table.\n * We will then serialize this transaction, and then explore how to deserialize and inspect it.\n * See the `transfer-lamports` example for more detailed documentation on creating, signing and sending a transaction.\n */\nconst SOURCE_ACCOUNT_SIGNER = await createKeyPairSignerFromBytes(\n    /**\n     * These are the bytes that we saved at the time this account's key pair was originally\n     * generated. Here, they are inlined into the source code, but you can also imagine them being\n     * loaded from disk or, better yet, read from an environment variable.\n     */\n    new Uint8Array(\n        // prettier-ignore\n        [2, 194, 94, 194, 31, 15, 34, 248, 159, 9, 59, 156, 194, 152, 79, 148, 81, 17, 63, 53, 245, 175, 37, 0, 134, 90, 111, 236, 245, 160, 3, 50, 196, 59, 123, 60, 59, 151, 65, 255, 27, 247, 241, 230, 52, 54, 143, 136, 108, 160, 7, 128, 4, 14, 232, 119, 234, 61, 47, 158, 9, 241, 48, 140],\n    ), // Address: ED1WqT2hWJLSZtj4TtTdoovmpMrr7zpkUdbfxmcJR1Fq\n);\nlog.info({ address: SOURCE_ACCOUNT_SIGNER.address }, '[setup] Loaded key pair for source account');\n\n// This is the first address in the lookup table\nconst DESTINATION_ADDRESS = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\nlog.info({ address: DESTINATION_ADDRESS }, '[setup] Setting destination address');\n\n/**\n * This is an arbitrary address that we set as the fee payer\n * In this example we won't send the transaction so it doesn't matter if this account is funded\n */\nconst FEE_PAYER_ADDRESS = '9xaf9RQvmr47tcKZ2y8KdpcSn6KyymGU6PZAFC9AKjPd' as Address;\nlog.info({ address: FEE_PAYER_ADDRESS }, '[setup] Setting fee payer address');\n\nconst transactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    tx => setTransactionMessageFeePayer(FEE_PAYER_ADDRESS, tx),\n    tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n    tx =>\n        appendTransactionMessageInstructions(\n            [\n                getTransferSolInstruction({\n                    amount: lamports(12345678n),\n                    destination: DESTINATION_ADDRESS,\n                    source: SOURCE_ACCOUNT_SIGNER,\n                }),\n                getAddMemoInstruction({\n                    memo: 'hello from @solana/kit',\n                }),\n            ],\n            tx,\n        ),\n);\nlog.info('[setup] Created the transaction message');\n\n/**\n * SETUP: COMPRESS WITH LOOKUP TABLE\n * As the destination of our transfer SOL instruction is in our lookup table, we can use the\n * lookup table to compress the transaction.\n *\n * This will modify the accounts referred to in the transaction, so that where possible they\n * refer to an index of an address lookup table instead of an address directly. This makes the\n * transaction smaller when it is compiled, particularly if many addresses can use a lookup table.\n */\n\n// We fetch the JSON parsed representation of the lookup table from the RPC\nconst lookupTableAccount = await fetchAddressLookupTable(rpc, LOOKUP_TABLE_ADDRESS);\n\nconst transactionMessageWithLookupTables = compressTransactionMessageUsingAddressLookupTables(transactionMessage, {\n    [LOOKUP_TABLE_ADDRESS]: lookupTableAccount.data.addresses,\n});\nlog.info(`[setup] Compressed the transaction message using lookup table ${LOOKUP_TABLE_ADDRESS}`);\n\n/**\n * SETUP: PARTIALLY SIGN THE TRANSACTION\n * A Solana transaction can have multiple signers that must sign before it is sent to the network.\n * In our case the fee payer and the source account would both need to sign the transaction\n * We used a signer for the source account, so it will sign it when we call `signTransactionMessageWithSigners`\n * But we only used an address for the fee payer, and we don't have its private key to sign the transaction\n * So we will use `partiallySignTransactionMessageWithSigners` to get a transaction that has been signed by\n * the source account, but not by the fee payer.\n */\nconst signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessageWithLookupTables);\nlog.info(`[setup] Partially signed the transaction with a signature from ${SOURCE_ACCOUNT_SIGNER.address}`);\n\n/**\n * SETUP: ENCODE THE TRANSACTION AS BASE64\n * This is a common format to send a transaction between different systems\n * If you wanted to convert it to a byte array instead, you could do this:\n *\n * ```ts\n * const transactionEncoder = getTransactionEncoder();\n * const transactionBytes = transactionEncoder.encode(signedTransaction);\n * ```\n */\nconst base64EncodedTransaction = getBase64EncodedWireTransaction(signedTransaction);\nlog.info(`[setup] Encoded the transaction as base64: ${base64EncodedTransaction.slice(0, 64)}...`);\n\n/**\n * SETUP COMPLETE\n * At this point, imagine we've received `base64EncodedTransaction` as input and don't know anything about it\n * Let's use web3js to decode and inspect it\n */\n\n/**\n * STEP 1: DECODE TO TRANSACTION\n * @solana/kit has encoders/decoders for many Solana data structures and common data formats,\n * including both base64 strings and our `Transaction` data structure\n * To convert between these, we first encode to a byte array, and then decode to the\n * desired data structure.\n * In our case we first encode the `base64EncodedTransaction` to a byte array, and then\n * decode to a `Transaction`.\n * If we had instead received a byte array `transactionBytes` then we would just skip\n * the base64 encode step\n */\nconst base64Encoder = getBase64Encoder();\nconst transactionBytes = base64Encoder.encode(base64EncodedTransaction);\n\nconst transactionDecoder = getTransactionDecoder();\nconst decodedTransaction = transactionDecoder.decode(transactionBytes);\nlog.info('[step 1] Decoded the transaction');\n\n/**\n * First let's inspect the signatures on our decoded transaction\n * `signatures` is a map from `Address` to `SignatureBytes | null`\n * If the address has signed the transaction then we can access their signature\n * If not then `null` will be stored\n */\n\nfor (const [address, maybeSignature] of Object.entries(decodedTransaction.signatures)) {\n    if (maybeSignature) {\n        log.info(`[step 1] ${address} has signed the transaction`);\n    } else {\n        log.info(`[step 1] ${address} is required to sign the transaction but hasn't yet`);\n    }\n}\n\n// Now we know that we have a signature for `ED1WqT2hWJLSZtj4TtTdoovmpMrr7zpkUdbfxmcJR1Fq`\n// Let's verify that it's correct\nconst signedByAddress = 'ED1WqT2hWJLSZtj4TtTdoovmpMrr7zpkUdbfxmcJR1Fq' as Address;\nconst signedBySignature = decodedTransaction.signatures[signedByAddress]!;\n// We create a public Ed25519 key with that address (a `CryptoKey` object with the role `verify`)\nconst signedByPublicKey = await getPublicKeyFromAddress(signedByAddress);\n// Now we can verify the signature using that key\nconst verifiedSignature = await verifySignature(signedByPublicKey, signedBySignature, decodedTransaction.messageBytes);\nlog.info(\n    `[step 1] The signature for ${signedByAddress} is ${verifiedSignature ? 'valid' : 'not valid'} for the transaction`,\n);\n\n/**\n * STEP 2: DECODE TO COMPILED TRANSACTION MESSAGE\n * We verified the signature is valid for the `messageBytes` field of the Transaction. This is a byte array\n * representing the compiled version of the `TransactionMessage`. If we decode this we can see some information\n * about the transaction. Let's do that next.\n */\n\n// Again we have a decoder to convert from bytes to a Solana data structure, in this case the `CompiledTransactionMessage`\nconst compiledTransactionMessageDecoder = getCompiledTransactionMessageDecoder();\nconst compiledTransactionMessage = compiledTransactionMessageDecoder.decode(decodedTransaction.messageBytes);\n\n// This gives us the data structure `CompiledTransactionMessage`. This is the format that transactions are\n// compiled before the entire transaction is encoded to base64 to be sent to the Solana network.\n\n// Let's inspect some fields of `compiledTransactionMessage`\n// We can see its version:\nlog.info(`[step 2] The transaction is version ${compiledTransactionMessage.version}`);\n\n// We can see the lifetime token, though we don't have enough context yet to know if it's a blockhash or a durable nonce\nlog.info(\n    `[step 2] We can see the transaction lifetime token, but we don't know if it's a blockhash or durable nonce: ${compiledTransactionMessage.lifetimeToken}`,\n);\n\n// We can see the static accounts:\nlog.info(compiledTransactionMessage.staticAccounts, '[step 2] Static accounts of the transaction');\n\n// Note that the destination address (F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn) is not here, as it comes from the lookup table\n\n// The `addressLookupTables` field is only included for v0 transactions\n// Here we tell Typescript to narrow the type to exclude legacy transactions\nif (compiledTransactionMessage.version !== 0) {\n    throw new Error('We compiled with version: 0');\n}\n\n// Now we can view address lookup tables:\nlog.info(compiledTransactionMessage.addressTableLookups, '[step 2] Address lookup tables for the transaction');\n\n// We see that the transaction uses our address lookup table.\n\n// Let's look at a compiled instruction\nlog.info(\n    { ...compiledTransactionMessage.instructions[0], data: '(removed for brevity)' },\n    '[step 2] The first instruction of the compiled transaction message',\n);\n\n/**\n * This is the SOL transfer instruction\n * The program account index is 2, which matches the system program (1111...) in our static accounts\n * The first account index is 1, which matches the signer we used as the source address\n * But the second account index is 4, which is outside our array of static accounts.\n * We need to resolve the lookup table in order to know what address this actually is\n */\n\n/**\n * STEP 3: DECOMPILING THE TRANSACTION MESSAGE\n * Let's decompile the transaction message into a structure that is easier to inspect and parse\n * To decompile this transaction message, we need to know the addresses in this lookup table\n * If we already have the addresses in this lookup table fetched, then we can pass them to\n * `decompileTransactionMessage` without fetching them again. Like so:\n *\n * ```ts\n * const decompiledTransactionMessage = decompileTransactionMessage(compiledTransactionMessage, {\n *   addressesByLookupTableAddress: {\n *     [LOOKUP_TABLE_ADDRESS]: lookupTableAccount.data.addresses,\n *   },\n * });\n * ```\n *\n * But let's pretend that we don't already have that data fetched, we've just received the\n * transaction and need to decompile it. We will use `decompileTransactionMessageFetchingLookupTables`\n * instead\n *\n * This will use the RPC to fetch the address lookup table data for us, and then use it to\n * decompile the transaction message.\n */\n\nconst decompiledTransactionMessage = await decompileTransactionMessageFetchingLookupTables(\n    compiledTransactionMessage,\n    rpc,\n);\n\n// This is our `TransactionMessage` structure, which is much easier to understand and parse\n// This is the same data structure that was created before we first signed the transaction\n\n// We can see the fee payer:\nlog.info(`[step 3] The transaction fee payer is ${decompiledTransactionMessage.feePayer.address}`);\n\n// And the lifetime constraint:\nlog.info(decompiledTransactionMessage.lifetimeConstraint, '[step 3] The transaction lifetime constraint');\n\n/**\n * Here we can see that the lifetime constraint is actually a blockhash\n * The `decompileTransactionMessage` call inspects the transaction and can distinguish\n * between blockhash and nonce for us\n * We can also narrow this type with typescript\n */\nif ('blockhash' in decompiledTransactionMessage.lifetimeConstraint) {\n    log.info(`[step 3] The transaction blockhash is ${decompiledTransactionMessage.lifetimeConstraint.blockhash}`);\n}\n\n/**\n * Note that the `lastValidBlockHeight` won't necessarily match that used when the transaction\n * was first created. This is not encoded into the transaction, so we can't decode it back out\n * By default `decompileTransactionMessageFetchingLookupTables` and `decompileTransactionMessage`\n * will set it to U64 MAX. But if you know the correct value,\n * you can pass it like so:\n *\n * ```ts\n * const decompiledTransactionMessage = await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, {\n *   lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,\n * })\n * ```\n */\n\n// We can also view the decompiled instructions here\nlog.info(\n    { ...decompiledTransactionMessage.instructions[0], data: '(removed for brevity)' },\n    '[step 3] The first decoded instruction',\n);\n\n/**\n * We can see the programAddress is `11111111111111111111111111111111`\n * We no longer need to look this up in a list of accounts from an index\n *\n * We also see the address of each account\n * For the second account, we have its address, as well as the lookup table it comes from\n * Decompiling the transaction message unpacks all the lookup accounts for us\n */\n\n// We removed the data array for brevity when we logged the instructions, but let's take a look at it now\nlog.info(decompiledTransactionMessage.instructions[0].data, '[step 3] The data bytes of the first instruction');\n\n// This is opaque, it's just a byte array, but it encodes exactly what the instruction is actually doing\n// Let's look next at how we can make sense of it\n\n/**\n * STEP 4: PARSING THE INSTRUCTIONS\n * To understand what is actually happening in each instruction, we need to decode the data field\n * We will do this by using the generated `@solana-program/system` client, which can decode data\n * from the @solana/kit instruction data structure for the System program\n * We know from the program address (11111111111111111111111111111111) that the first instruction\n * is to the system program\n * You can generate such a client for any Solana program using Codama\n * See https://github.com/codama-idl/codama for more information on Codama\n */\n\nconst firstInstruction = decompiledTransactionMessage.instructions[0];\n// Narrow the type, the `identifySystemInstruction` requires data to identify an instruction\nassertIsInstructionWithData(firstInstruction);\nconst identifiedInstruction = identifySystemInstruction(firstInstruction);\n\n// We can compare the `identifiedInstruction` to the enum values, like this\nif (identifiedInstruction === SystemInstruction.TransferSol) {\n    log.info('[step 4] The first instruction calls the TransferSol instruction of the system program');\n    // Narrow the type again, the instruction must have accounts to be parsed as a transfer SOL instruction\n    assertIsInstructionWithAccounts(firstInstruction);\n\n    // TODO: This can just be `parseTransferSolInstruction(firstInstruction)` when the client is updated\n    // with the `@solana/kit` version that changes the instruction data type to `ReadonlyUint8Array`\n    const parsedFirstInstruction = parseTransferSolInstruction({\n        ...firstInstruction,\n        data: firstInstruction.data as unknown as Uint8Array,\n    });\n    log.info(parsedFirstInstruction, '[step 4] The parsed Transfer SOL instruction');\n\n    // This gives us an understanding of what exactly is happening in the instruction\n    // We can see the source address, the destination address, and the amount of lamports\n    const { accounts, data } = parsedFirstInstruction;\n    log.info(\n        `[step 4] In the first instruction, ${accounts.source.address} transfers ${data.amount.toLocaleString()} lamports to ${accounts.destination.address}`,\n    );\n}\n\n// Now let's do the same with the second instruction\nconst secondInstruction = decompiledTransactionMessage.instructions[1];\nlog.info(`[step 4] The second instruction calls the ${secondInstruction.programAddress} program`);\n\n// We know that the second instruction is to the memo program, but we can also programmatically check this\n// Each generated client exposes its program address as a constant\nif (secondInstruction.programAddress === MEMO_PROGRAM_ADDRESS) {\n    log.info(`[step 4] The second instruction calls the memo program`);\n}\n\n// The memo program only has one instruction, so there is no `identify` function\n// We know it's always an addMemo instruction\n\nassertIsInstructionWithData(secondInstruction);\n\n// TODO: This can just be `parseAddMemoInstruction(secondInstruction)` when the client is updated\n// with the `@solana/kit` version that changes the instruction data type to `ReadonlyUint8Array`\nconst parsedSecondInstruction = parseAddMemoInstruction({\n    ...secondInstruction,\n    data: secondInstruction.data as unknown as Uint8Array,\n});\nlog.info(parsedSecondInstruction, '[step 4] The parsed Add Memo instruction');\nlog.info(`[step 4] The second instruction adds a memo with message \"${parsedSecondInstruction.data.memo}\"`);\n\n// We've now parsed both instructions, and we know exactly what the transaction does\n"
  },
  {
    "path": "examples/deserialize-transaction/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"module\": \"NodeNext\",\n        \"moduleResolution\": \"NodeNext\",\n        \"noEmit\": true,\n        \"target\": \"ESNext\"\n    },\n    \"display\": \"@solana/example-deserialize-transaction\",\n    \"extends\": \"../../packages/tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "examples/react-app/.gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\npnpm-debug.log*\nlerna-debug.log*\n\nnode_modules\ndist\ndist-ssr\n*.local\n\n# Editor directories and files\n.vscode/*\n!.vscode/extensions.json\n.idea\n.DS_Store\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw?\n"
  },
  {
    "path": "examples/react-app/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/react-app/README.md",
    "content": "# @solana/example-react-app\n\nThis is an example of how to use `@solana/kit` and `@solana/react` to build a React web application.\n\n## Features\n\n- Connects to browser wallets that support the Wallet Standard; one or more at a time\n- Fetches and subscribes to the balance of the selected wallet\n- Allows you to sign an arbitrary message using a wallet account\n- Allows you to make a transfer from the selected wallet to any other connected wallet\n\n## Developing\n\nStart a server in development mode.\n\n```shell\npnpm install\npnpm turbo compile:js compile:typedefs\npnpm dev\n```\n\nPress <kbd>o</kbd> + <kbd>Enter</kbd> to open the app in a browser. Edits to the source code will automatically reload the app.\n\n## Building for deployment\n\nBuild a static bundle and HTML for deployment to a webserver.\n\n```shell\npnpm install\npnpm turbo build\n```\n\nThe contents of the `dist/` directory can now be uploaded to a webserver.\n\n## Enabling Mainnet-Beta\n\nAccess to this cluster is typically blocked by [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) rules, so it is disabled in the example app by default. To enable it, start the server or compile the application with the `REACT_EXAMPLE_APP_ENABLE_MAINNET` environment variable set to `\"true\"`.\n\n```shell\nREACT_EXAMPLE_APP_ENABLE_MAINNET=true pnpm dev\nREACT_EXAMPLE_APP_ENABLE_MAINNET=true pnpm build\n```\n"
  },
  {
    "path": "examples/react-app/eslint.config.mjs",
    "content": "import solanaReactConfig from '@solana/eslint-config/eslint.config.react.mjs';\nimport reactRefreshPlugin from 'eslint-plugin-react-refresh';\nimport globals from 'globals';\n\nexport default [\n    {\n        ignores: ['**/dist', '**/*.css'],\n    },\n    ...solanaReactConfig,\n    {\n        languageOptions: {\n            globals: {\n                ...globals.browser,\n                ...globals.es2020,\n            },\n        },\n        plugins: {\n            'react-refresh': reactRefreshPlugin,\n        },\n        rules: {\n            '@typescript-eslint/no-misused-promises': 'off',\n            '@typescript-eslint/no-unsafe-argument': 'off',\n            '@typescript-eslint/no-unsafe-assignment': 'off',\n            '@typescript-eslint/restrict-template-expressions': 'error',\n            'react-refresh/only-export-components': [\n                'warn',\n                {\n                    allowConstantExport: true,\n                },\n            ],\n        },\n    },\n];\n"
  },
  {
    "path": "examples/react-app/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n        <link rel=\"icon\" type=\"image/svg+xml\" href=\"/solanaLogoMark.svg\" />\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n        <title>Solana React Example App</title>\n    </head>\n    <body>\n        <div id=\"root\"></div>\n        <script type=\"module\" src=\"/src/main.tsx\"></script>\n    </body>\n</html>\n"
  },
  {
    "path": "examples/react-app/package.json",
    "content": "{\n    \"name\": \"@solana/example-react-app\",\n    \"private\": true,\n    \"version\": \"0.0.0\",\n    \"type\": \"module\",\n    \"scripts\": {\n        \"dev\": \"vite\",\n        \"compile:js\": \"vite build\",\n        \"preview\": \"vite preview\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent --testMatch '<rootDir>src/**/*.{ts,tsx}'\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc\"\n    },\n    \"dependencies\": {\n        \"@radix-ui/react-dropdown-menu\": \"2.1.6\",\n        \"@radix-ui/react-icons\": \"1.3.2\",\n        \"@radix-ui/themes\": \"3.3.0\",\n        \"@solana-program/system\": \"^0.12.0\",\n        \"@solana/kit\": \"workspace:*\",\n        \"@solana/react\": \"workspace:*\",\n        \"@wallet-standard/core\": \"^1.1.1\",\n        \"@wallet-standard/react\": \"^1.0.1\",\n        \"react\": \"^19.2.6\",\n        \"react-dom\": \"^19.2.6\",\n        \"react-error-boundary\": \"^5.0.0\",\n        \"swr\": \"^2.4.1\"\n    },\n    \"devDependencies\": {\n        \"@solana/eslint-config\": \"workspace:*\",\n        \"@solana/wallet-standard-features\": \"^1.3.0\",\n        \"@types/react\": \"^19.2.14\",\n        \"@types/react-dom\": \"^19.2.3\",\n        \"@vitejs/plugin-react-swc\": \"^4.2.3\",\n        \"eslint\": \"^9.39.2\",\n        \"eslint-plugin-react-refresh\": \"^0.5.2\",\n        \"globals\": \"^17.6.0\",\n        \"jest\": \"^30.0.0-alpha.6\",\n        \"vite\": \"^8.0.10\"\n    }\n}\n"
  },
  {
    "path": "examples/react-app/src/components/AirdropButton.tsx",
    "content": "import { Blockquote, Button, Dialog, Flex, Link, Text } from '@radix-ui/themes';\nimport { Address, airdropFactory, lamports, Rpc, Signature, SolanaRpcApi } from '@solana/kit';\nimport { useCallback, useContext, useMemo, useRef, useState } from 'react';\n\nimport { ChainContext } from '../context/ChainContext';\nimport { RpcContext } from '../context/RpcContext';\nimport { ErrorDialog } from './ErrorDialog';\n\nexport function AirdropButton({ address }: { address: Address }) {\n    const { current: NO_ERROR } = useRef<unknown>(Symbol());\n    const { chain } = useContext(ChainContext);\n    const { rpc, rpcSubscriptions } = useContext(RpcContext);\n    const [error, setError] = useState(NO_ERROR);\n    const [lastSignature, setLastSignature] = useState<Signature | undefined>();\n\n    const isMainnet = chain === 'solana:mainnet';\n\n    // Cast RPC for airdrop, this is safe because we disable the airdrop button on mainnet\n    const airdrop = useMemo(\n        () => airdropFactory({ rpc: rpc as Rpc<SolanaRpcApi>, rpcSubscriptions }),\n        [rpc, rpcSubscriptions],\n    );\n    const [loading, setLoading] = useState(false);\n\n    const handleAirdrop = useCallback(async () => {\n        try {\n            if (isMainnet) throw new Error('Airdrops are not available on mainnet');\n            setLoading(true);\n            const signature = await airdrop({\n                commitment: 'confirmed',\n                lamports: lamports(1_000_000_000n),\n                recipientAddress: address,\n            });\n            setLastSignature(signature);\n            setError(NO_ERROR);\n        } catch (e) {\n            setError(e);\n        } finally {\n            setLoading(false);\n        }\n    }, [airdrop, address, setLoading, NO_ERROR, isMainnet]);\n\n    return (\n        <>\n            <Dialog.Root\n                open={!!lastSignature}\n                onOpenChange={open => {\n                    if (!open) {\n                        setLastSignature(undefined);\n                    }\n                }}\n            >\n                <Dialog.Trigger>\n                    <Button\n                        variant=\"outline\"\n                        color={error ? undefined : 'red'}\n                        disabled={isMainnet}\n                        loading={loading}\n                        type=\"button\"\n                        onClick={handleAirdrop}\n                    >\n                        Airdrop to fee payer\n                    </Button>\n                </Dialog.Trigger>\n                {lastSignature ? (\n                    <Dialog.Content\n                        onClick={e => {\n                            e.stopPropagation();\n                        }}\n                    >\n                        <Dialog.Title>Airdrop successful!</Dialog.Title>\n                        <Flex direction=\"column\" gap=\"2\">\n                            <Text>Signature:</Text>\n                            <Blockquote>{lastSignature}</Blockquote>\n                            <Text>\n                                <Link\n                                    href={`https://explorer.solana.com/tx/${lastSignature}?cluster=${solanaExplorerClusterName}`}\n                                    target=\"_blank\"\n                                >\n                                    View this transaction\n                                </Link>{' '}\n                                on Explorer\n                            </Text>\n                        </Flex>\n                        <Flex gap=\"3\" mt=\"4\" justify=\"end\">\n                            <Dialog.Close>\n                                <Button>Cool!</Button>\n                            </Dialog.Close>\n                        </Flex>\n                    </Dialog.Content>\n                ) : null}\n            </Dialog.Root>\n\n            {error !== NO_ERROR ? (\n                <ErrorDialog\n                    error={{ message: `This is usually because of rate limiting. Address: ${address}` }}\n                    onClose={() => setError(NO_ERROR)}\n                    title=\"Airdrop failed\"\n                />\n            ) : null}\n        </>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/Balance.tsx",
    "content": "import { ExclamationTriangleIcon } from '@radix-ui/react-icons';\nimport { Text, Tooltip } from '@radix-ui/themes';\nimport { address } from '@solana/kit';\nimport type { UiWalletAccount } from '@wallet-standard/react';\nimport { useContext, useMemo } from 'react';\nimport useSWRSubscription from 'swr/subscription';\n\nimport { ChainContext } from '../context/ChainContext';\nimport { RpcContext } from '../context/RpcContext';\nimport { getErrorMessage } from '../errors';\nimport { balanceSubscribe } from '../functions/balance';\nimport { ErrorDialog } from './ErrorDialog';\n\ntype Props = Readonly<{\n    account: UiWalletAccount;\n}>;\n\nconst seenErrors = new WeakSet();\n\nexport function Balance({ account }: Props) {\n    const { chain } = useContext(ChainContext);\n    const { rpc, rpcSubscriptions } = useContext(RpcContext);\n    const subscribe = useMemo(() => balanceSubscribe.bind(null, rpc, rpcSubscriptions), [rpc, rpcSubscriptions]);\n    const { data: lamports, error } = useSWRSubscription({ address: address(account.address), chain }, subscribe);\n    if (error && !seenErrors.has(error)) {\n        return (\n            <>\n                <ErrorDialog\n                    error={error}\n                    key={`${account.address}:${chain}`}\n                    onClose={() => {\n                        seenErrors.add(error);\n                    }}\n                    title=\"Failed to fetch account balance\"\n                />\n                <Text>\n                    <Tooltip content={<>Could not fetch balance: {getErrorMessage(error, 'Unknown reason')}</>}>\n                        <ExclamationTriangleIcon\n                            color=\"red\"\n                            style={{ height: 16, verticalAlign: 'text-bottom', width: 16 }}\n                        />\n                    </Tooltip>\n                </Text>\n            </>\n        );\n    } else if (lamports == null) {\n        return <Text>&ndash;</Text>;\n    } else {\n        const formattedSolValue = new Intl.NumberFormat(undefined, { maximumFractionDigits: 5 }).format(\n            // @ts-expect-error This format string is 100% allowed now.\n            `${lamports}E-9`,\n        );\n        return <Text>{`${formattedSolValue} \\u25CE`}</Text>;\n    }\n}\n"
  },
  {
    "path": "examples/react-app/src/components/BaseSignMessageFeaturePanel.tsx",
    "content": "import { Pencil1Icon } from '@radix-ui/react-icons';\nimport { Blockquote, Box, Button, Code, DataList, Dialog, Flex, TextField } from '@radix-ui/themes';\nimport { getBase64Decoder } from '@solana/kit';\nimport type { ReadonlyUint8Array } from '@wallet-standard/core';\nimport type { SyntheticEvent } from 'react';\nimport { useRef, useState } from 'react';\n\nimport { ErrorDialog } from '../components/ErrorDialog';\n\ntype Props = Readonly<{\n    signMessage(message: ReadonlyUint8Array): Promise<ReadonlyUint8Array>;\n}>;\n\nexport function BaseSignMessageFeaturePanel({ signMessage }: Props) {\n    const { current: NO_ERROR } = useRef(Symbol());\n    const [isSigningMessage, setIsSigningMessage] = useState(false);\n    const [error, setError] = useState(NO_ERROR);\n    const [lastSignature, setLastSignature] = useState<ReadonlyUint8Array | undefined>();\n    const [text, setText] = useState<string>();\n    return (\n        <Flex asChild gap=\"2\" direction={{ initial: 'column', sm: 'row' }} style={{ width: '100%' }}>\n            <form\n                onSubmit={async e => {\n                    e.preventDefault();\n                    setError(NO_ERROR);\n                    setIsSigningMessage(true);\n                    try {\n                        const signature = await signMessage(new TextEncoder().encode(text));\n                        setLastSignature(signature);\n                    } catch (e) {\n                        setLastSignature(undefined);\n                        setError(e);\n                    } finally {\n                        setIsSigningMessage(false);\n                    }\n                }}\n            >\n                <Box flexGrow=\"1\">\n                    <TextField.Root\n                        placeholder=\"Write a message to sign\"\n                        onChange={(e: SyntheticEvent<HTMLInputElement>) => setText(e.currentTarget.value)}\n                        value={text}\n                    >\n                        <TextField.Slot>\n                            <Pencil1Icon />\n                        </TextField.Slot>\n                    </TextField.Root>\n                </Box>\n                <Dialog.Root\n                    open={!!lastSignature}\n                    onOpenChange={open => {\n                        if (!open) {\n                            setLastSignature(undefined);\n                        }\n                    }}\n                >\n                    <Dialog.Trigger>\n                        <Button\n                            color={error ? undefined : 'red'}\n                            disabled={!text}\n                            loading={isSigningMessage}\n                            type=\"submit\"\n                        >\n                            Sign Message\n                        </Button>\n                    </Dialog.Trigger>\n                    {lastSignature ? (\n                        <Dialog.Content\n                            onClick={e => {\n                                e.stopPropagation();\n                            }}\n                        >\n                            <Dialog.Title>You Signed a Message!</Dialog.Title>\n                            <DataList.Root orientation={{ initial: 'vertical', sm: 'horizontal' }}>\n                                <DataList.Item>\n                                    <DataList.Label minWidth=\"88px\">Message</DataList.Label>\n                                    <DataList.Value>\n                                        <Blockquote>{text}</Blockquote>\n                                    </DataList.Value>\n                                </DataList.Item>\n                                <DataList.Item>\n                                    <DataList.Label minWidth=\"88px\">Signature</DataList.Label>\n                                    <DataList.Value>\n                                        <Code truncate>{getBase64Decoder().decode(lastSignature)}</Code>\n                                    </DataList.Value>\n                                </DataList.Item>\n                            </DataList.Root>\n                            <Flex gap=\"3\" mt=\"4\" justify=\"end\">\n                                <Dialog.Close>\n                                    <Button>Cool!</Button>\n                                </Dialog.Close>\n                            </Flex>\n                        </Dialog.Content>\n                    ) : null}\n                </Dialog.Root>\n                {error !== NO_ERROR ? (\n                    <ErrorDialog error={error} onClose={() => setError(NO_ERROR)} title=\"Failed to sign message\" />\n                ) : null}\n            </form>\n        </Flex>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/ConnectWalletMenu.tsx",
    "content": "import { ExclamationTriangleIcon } from '@radix-ui/react-icons';\nimport { Button, Callout, DropdownMenu } from '@radix-ui/themes';\nimport { useSelectedWalletAccount } from '@solana/react';\nimport { StandardConnect, StandardDisconnect } from '@wallet-standard/core';\nimport type { UiWallet } from '@wallet-standard/react';\nimport { uiWalletAccountBelongsToUiWallet } from '@wallet-standard/react';\nimport { useRef, useState } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\n\nimport { ConnectWalletMenuItem } from './ConnectWalletMenuItem';\nimport { ErrorDialog } from './ErrorDialog';\nimport { UnconnectableWalletMenuItem } from './UnconnectableWalletMenuItem';\nimport { WalletAccountIcon } from './WalletAccountIcon';\n\ntype Props = Readonly<{\n    children: React.ReactNode;\n}>;\n\nexport function ConnectWalletMenu({ children }: Props) {\n    const { current: NO_ERROR } = useRef(Symbol());\n    const [selectedWalletAccount, setSelectedWalletAccount, wallets] = useSelectedWalletAccount();\n    const [error, setError] = useState(NO_ERROR);\n    const [forceClose, setForceClose] = useState(false);\n    function renderItem(wallet: UiWallet) {\n        return (\n            <ErrorBoundary\n                fallbackRender={({ error }) => <UnconnectableWalletMenuItem error={error} wallet={wallet} />}\n                key={`wallet:${wallet.name}`}\n            >\n                <ConnectWalletMenuItem\n                    onAccountSelect={account => {\n                        setSelectedWalletAccount(account);\n                        setForceClose(true);\n                    }}\n                    onDisconnect={wallet => {\n                        if (selectedWalletAccount && uiWalletAccountBelongsToUiWallet(selectedWalletAccount, wallet)) {\n                            setSelectedWalletAccount(undefined);\n                        }\n                    }}\n                    onError={setError}\n                    wallet={wallet}\n                />\n            </ErrorBoundary>\n        );\n    }\n    const walletsThatSupportStandardConnect = [];\n    const unconnectableWallets = [];\n    for (const wallet of wallets) {\n        if (wallet.features.includes(StandardConnect) && wallet.features.includes(StandardDisconnect)) {\n            walletsThatSupportStandardConnect.push(wallet);\n        } else {\n            unconnectableWallets.push(wallet);\n        }\n    }\n    return (\n        <>\n            <DropdownMenu.Root open={forceClose ? false : undefined} onOpenChange={setForceClose.bind(null, false)}>\n                <DropdownMenu.Trigger>\n                    <Button>\n                        {selectedWalletAccount ? (\n                            <>\n                                <WalletAccountIcon account={selectedWalletAccount} width=\"18\" height=\"18\" />\n                                {selectedWalletAccount.address.slice(0, 8)}\n                            </>\n                        ) : (\n                            children\n                        )}\n                        <DropdownMenu.TriggerIcon />\n                    </Button>\n                </DropdownMenu.Trigger>\n                <DropdownMenu.Content>\n                    {wallets.length === 0 ? (\n                        <Callout.Root color=\"orange\" highContrast>\n                            <Callout.Icon>\n                                <ExclamationTriangleIcon />\n                            </Callout.Icon>\n                            <Callout.Text>This browser has no wallets installed.</Callout.Text>\n                        </Callout.Root>\n                    ) : (\n                        <>\n                            {walletsThatSupportStandardConnect.map(renderItem)}\n                            {unconnectableWallets.length ? (\n                                <>\n                                    <DropdownMenu.Separator />\n                                    {unconnectableWallets.map(renderItem)}\n                                </>\n                            ) : null}\n                        </>\n                    )}\n                </DropdownMenu.Content>\n            </DropdownMenu.Root>\n            {error !== NO_ERROR ? <ErrorDialog error={error} onClose={() => setError(NO_ERROR)} /> : null}\n        </>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/ConnectWalletMenuItem.tsx",
    "content": "import { DropdownMenu } from '@radix-ui/themes';\nimport { useSelectedWalletAccount } from '@solana/react';\nimport type { UiWallet, UiWalletAccount } from '@wallet-standard/react';\nimport { uiWalletAccountsAreSame, useConnect, useDisconnect } from '@wallet-standard/react';\nimport { useCallback } from 'react';\n\nimport { WalletMenuItemContent } from './WalletMenuItemContent';\n\ntype Props = Readonly<{\n    onAccountSelect(account: UiWalletAccount | undefined): void;\n    onDisconnect(wallet: UiWallet): void;\n    onError(err: unknown): void;\n    wallet: UiWallet;\n}>;\n\nexport function ConnectWalletMenuItem({ onAccountSelect, onDisconnect, onError, wallet }: Props) {\n    const [isConnecting, connect] = useConnect(wallet);\n    const [isDisconnecting, disconnect] = useDisconnect(wallet);\n    const isPending = isConnecting || isDisconnecting;\n    const isConnected = wallet.accounts.length > 0;\n    const [selectedWalletAccount] = useSelectedWalletAccount();\n    const handleConnectClick = useCallback(async () => {\n        try {\n            const existingAccounts = [...wallet.accounts];\n            const nextAccounts = await connect();\n            // Try to choose the first never-before-seen account.\n            for (const nextAccount of nextAccounts) {\n                if (!existingAccounts.some(existingAccount => uiWalletAccountsAreSame(nextAccount, existingAccount))) {\n                    onAccountSelect(nextAccount);\n                    return;\n                }\n            }\n            // Failing that, choose the first account in the list.\n            if (nextAccounts[0]) {\n                onAccountSelect(nextAccounts[0]);\n            }\n        } catch (e) {\n            onError(e);\n        }\n    }, [connect, onAccountSelect, onError, wallet.accounts]);\n    return (\n        <DropdownMenu.Sub open={!isConnected ? false : undefined}>\n            <DropdownMenu.SubTrigger disabled={isPending} onClick={!isConnected ? handleConnectClick : undefined}>\n                <WalletMenuItemContent loading={isPending} wallet={wallet} />\n            </DropdownMenu.SubTrigger>\n            <DropdownMenu.SubContent>\n                <DropdownMenu.Label>Accounts</DropdownMenu.Label>\n                <DropdownMenu.RadioGroup value={selectedWalletAccount?.address}>\n                    {wallet.accounts.map(account => (\n                        <DropdownMenu.RadioItem\n                            key={account.address}\n                            value={account.address}\n                            onSelect={() => {\n                                onAccountSelect(account);\n                            }}\n                        >\n                            {account.address.slice(0, 8)}&hellip;\n                        </DropdownMenu.RadioItem>\n                    ))}\n                </DropdownMenu.RadioGroup>\n                <DropdownMenu.Separator />\n                <DropdownMenu.Item\n                    onSelect={async e => {\n                        e.preventDefault();\n                        await handleConnectClick();\n                    }}\n                >\n                    Connect More\n                </DropdownMenu.Item>\n                <DropdownMenu.Item\n                    color=\"red\"\n                    onSelect={async e => {\n                        e.preventDefault();\n                        try {\n                            await disconnect();\n                            onDisconnect(wallet);\n                        } catch (e) {\n                            onError(e);\n                        }\n                    }}\n                >\n                    Disconnect\n                </DropdownMenu.Item>\n            </DropdownMenu.SubContent>\n        </DropdownMenu.Sub>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/DisconnectButton.tsx",
    "content": "import { ExclamationTriangleIcon, ExitIcon } from '@radix-ui/react-icons';\nimport { Button, Tooltip } from '@radix-ui/themes';\nimport type { UiWallet } from '@wallet-standard/react';\nimport { useDisconnect } from '@wallet-standard/react';\nimport { useState } from 'react';\n\nimport { NO_ERROR } from '../errors';\n\ntype Props = Readonly<{\n    wallet: UiWallet;\n}>;\n\nexport function DisconnectButton({\n    wallet,\n    ...buttonProps\n}: Omit<React.ComponentProps<typeof Button>, 'color' | 'loading' | 'onClick'> & Props) {\n    const [isDisconnecting, disconnect] = useDisconnect(wallet);\n    const [lastError, setLastError] = useState(NO_ERROR);\n    return (\n        <Tooltip\n            content={\n                <>\n                    Error:{' '}\n                    {lastError && typeof lastError === 'object' && 'message' in lastError\n                        ? lastError.message\n                        : String(lastError)}\n                </>\n            }\n            open={lastError !== NO_ERROR}\n            side=\"left\"\n        >\n            <Button\n                {...buttonProps}\n                color=\"red\"\n                loading={isDisconnecting}\n                onClick={async () => {\n                    setLastError(NO_ERROR);\n                    try {\n                        await disconnect();\n                    } catch (e) {\n                        setLastError(e);\n                    }\n                }}\n                variant=\"outline\"\n            >\n                {lastError === NO_ERROR ? <ExitIcon /> : <ExclamationTriangleIcon />}\n                Disconnect\n            </Button>\n        </Tooltip>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/ErrorDialog.tsx",
    "content": "import { AlertDialog, Blockquote, Button, Flex } from '@radix-ui/themes';\nimport { useState } from 'react';\n\nimport { getErrorMessage } from '../errors';\n\ntype Props = Readonly<{\n    error: unknown;\n    onClose?(): false | void;\n    title?: string;\n}>;\n\nexport function ErrorDialog({ error, onClose, title }: Props) {\n    const [isOpen, setIsOpen] = useState(true);\n    return (\n        <AlertDialog.Root\n            open={isOpen}\n            onOpenChange={open => {\n                if (!open) {\n                    if (!onClose || onClose() !== false) {\n                        setIsOpen(false);\n                    }\n                }\n            }}\n        >\n            <AlertDialog.Content>\n                <AlertDialog.Title color=\"red\">{title ?? 'We encountered the following error'}</AlertDialog.Title>\n                <AlertDialog.Description>\n                    <Blockquote>{getErrorMessage(error, 'Unknown')}</Blockquote>\n                </AlertDialog.Description>\n                <Flex mt=\"4\" justify=\"end\">\n                    <AlertDialog.Action>\n                        <Button variant=\"solid\">Close</Button>\n                    </AlertDialog.Action>\n                </Flex>\n            </AlertDialog.Content>\n        </AlertDialog.Root>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/FeatureNotSupportedCallout.tsx",
    "content": "import { ExclamationTriangleIcon } from '@radix-ui/react-icons';\nimport { Callout } from '@radix-ui/themes';\nimport React from 'react';\nimport type { FallbackProps } from 'react-error-boundary';\n\nimport { getErrorMessage } from '../errors';\n\ninterface Props extends Callout.RootProps, FallbackProps {}\n\nexport function FeatureNotSupportedCallout({\n    error,\n    resetErrorBoundary: _,\n    ...rootProps\n}: Props): React.ReactElement<typeof Callout.Root> {\n    return (\n        <Callout.Root color=\"gray\" size=\"1\" {...rootProps} style={{ flexGrow: 1, ...rootProps.style }}>\n            <Callout.Icon>\n                <ExclamationTriangleIcon />\n            </Callout.Icon>\n            <Callout.Text>{getErrorMessage(error, 'This account does not support this feature')}</Callout.Text>\n        </Callout.Root>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/FeaturePanel.tsx",
    "content": "import { DataList } from '@radix-ui/themes';\nimport React from 'react';\n\ntype Props = Readonly<{\n    children: React.ReactNode;\n    label: React.ReactNode;\n}>;\n\nexport function FeaturePanel({ children, label }: Props) {\n    return (\n        <DataList.Item align={{ initial: 'start', sm: 'center' }}>\n            <DataList.Label>{label}</DataList.Label>\n            <DataList.Value style={{ width: '100%' }}>{children}</DataList.Value>\n        </DataList.Item>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/Nav.tsx",
    "content": "import { Badge, Box, DropdownMenu, Flex, Heading } from '@radix-ui/themes';\nimport { useContext } from 'react';\n\nimport { ChainContext } from '../context/ChainContext';\nimport { ConnectWalletMenu } from './ConnectWalletMenu';\nimport { SignInMenu } from './SignInMenu';\n\nexport function Nav() {\n    const { displayName: currentChainName, chain, setChain } = useContext(ChainContext);\n    const currentChainBadge = (\n        <Badge color=\"gray\" style={{ verticalAlign: 'middle' }}>\n            {currentChainName}\n        </Badge>\n    );\n    return (\n        <Box\n            style={{\n                backgroundColor: 'var(--gray-1)',\n                borderBottom: '1px solid var(--gray-a6)',\n                zIndex: 1,\n            }}\n            position=\"sticky\"\n            p=\"3\"\n            top=\"0\"\n        >\n            <Flex gap=\"4\" justify=\"between\" align=\"center\">\n                <Box flexGrow=\"1\">\n                    <Heading as=\"h1\" size={{ initial: '4', xs: '6' }} truncate>\n                        Solana React App{' '}\n                        {setChain ? (\n                            <DropdownMenu.Root>\n                                <DropdownMenu.Trigger>{currentChainBadge}</DropdownMenu.Trigger>\n                                <DropdownMenu.Content>\n                                    <DropdownMenu.RadioGroup\n                                        onValueChange={value => {\n                                            setChain(value as 'solana:${string}');\n                                        }}\n                                        value={chain}\n                                    >\n                                        {process.env.REACT_EXAMPLE_APP_ENABLE_MAINNET === 'true' ? (\n                                            <DropdownMenu.RadioItem value=\"solana:mainnet\">\n                                                Mainnet Beta\n                                            </DropdownMenu.RadioItem>\n                                        ) : null}\n                                        <DropdownMenu.RadioItem value=\"solana:devnet\">Devnet</DropdownMenu.RadioItem>\n                                        <DropdownMenu.RadioItem value=\"solana:testnet\">Testnet</DropdownMenu.RadioItem>\n                                    </DropdownMenu.RadioGroup>\n                                </DropdownMenu.Content>\n                            </DropdownMenu.Root>\n                        ) : (\n                            currentChainBadge\n                        )}\n                    </Heading>\n                </Box>\n                <ConnectWalletMenu>Connect Wallet</ConnectWalletMenu>\n                <SignInMenu>Sign In</SignInMenu>\n            </Flex>\n        </Box>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/SignInMenu.tsx",
    "content": "import { ExclamationTriangleIcon } from '@radix-ui/react-icons';\nimport { Button, Callout, DropdownMenu } from '@radix-ui/themes';\nimport { useSelectedWalletAccount } from '@solana/react';\nimport { SolanaSignIn } from '@solana/wallet-standard-features';\nimport type { UiWallet } from '@wallet-standard/react';\nimport { useRef, useState } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\n\nimport { ErrorDialog } from './ErrorDialog';\nimport { SignInMenuItem } from './SignInMenuItem';\nimport { UnconnectableWalletMenuItem } from './UnconnectableWalletMenuItem';\n\ntype Props = Readonly<{\n    children: React.ReactNode;\n}>;\n\nexport function SignInMenu({ children }: Props) {\n    const { current: NO_ERROR } = useRef(Symbol());\n    const [, setSelectedWalletAccount, wallets] = useSelectedWalletAccount();\n    const [error, setError] = useState(NO_ERROR);\n    const [forceClose, setForceClose] = useState(false);\n    function renderItem(wallet: UiWallet) {\n        return (\n            <ErrorBoundary\n                fallbackRender={({ error }) => <UnconnectableWalletMenuItem error={error} wallet={wallet} />}\n                key={`wallet:${wallet.name}`}\n            >\n                <SignInMenuItem\n                    onSignIn={account => {\n                        setSelectedWalletAccount(account);\n                        setForceClose(true);\n                    }}\n                    onError={setError}\n                    wallet={wallet}\n                />\n            </ErrorBoundary>\n        );\n    }\n    const walletsThatSupportSignInWithSolana = [];\n    for (const wallet of wallets) {\n        if (wallet.features.includes(SolanaSignIn)) {\n            walletsThatSupportSignInWithSolana.push(wallet);\n        }\n    }\n    return (\n        <>\n            <DropdownMenu.Root open={forceClose ? false : undefined} onOpenChange={setForceClose.bind(null, false)}>\n                <DropdownMenu.Trigger>\n                    <Button>\n                        {children}\n                        <DropdownMenu.TriggerIcon />\n                    </Button>\n                </DropdownMenu.Trigger>\n                <DropdownMenu.Content>\n                    {walletsThatSupportSignInWithSolana.length === 0 ? (\n                        <Callout.Root color=\"orange\" highContrast>\n                            <Callout.Icon>\n                                <ExclamationTriangleIcon />\n                            </Callout.Icon>\n                            <Callout.Text>\n                                This browser has no wallets installed that support{' '}\n                                <a href=\"https://phantom.app/learn/developers/sign-in-with-solana\" target=\"_blank\">\n                                    Sign In With Solana\n                                </a>\n                                .\n                            </Callout.Text>\n                        </Callout.Root>\n                    ) : (\n                        walletsThatSupportSignInWithSolana.map(renderItem)\n                    )}\n                </DropdownMenu.Content>\n            </DropdownMenu.Root>\n            {error !== NO_ERROR ? <ErrorDialog error={error} onClose={() => setError(NO_ERROR)} /> : null}\n        </>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/SignInMenuItem.tsx",
    "content": "import { DropdownMenu } from '@radix-ui/themes';\nimport { useSignIn } from '@solana/react';\nimport type { UiWallet, UiWalletAccount } from '@wallet-standard/react';\nimport React, { useCallback, useState } from 'react';\n\nimport { WalletMenuItemContent } from './WalletMenuItemContent';\n\ntype Props = Readonly<{\n    onError(err: unknown): void;\n    onSignIn(account: UiWalletAccount | undefined): void;\n    wallet: UiWallet;\n}>;\n\nexport function SignInMenuItem({ onSignIn, onError, wallet }: Props) {\n    const signIn = useSignIn(wallet);\n    const [isSigningIn, setIsSigningIn] = useState(false);\n    const handleSignInClick = useCallback(\n        async (e: React.MouseEvent) => {\n            e.preventDefault();\n            try {\n                setIsSigningIn(true);\n                try {\n                    const { account } = await signIn({\n                        statement: 'You will enjoy being signed in.',\n                    });\n                    onSignIn(account);\n                } finally {\n                    setIsSigningIn(false);\n                }\n            } catch (e) {\n                onError(e);\n            }\n        },\n        [signIn, onSignIn, onError],\n    );\n    return (\n        <DropdownMenu.Item onClick={handleSignInClick}>\n            <WalletMenuItemContent loading={isSigningIn} wallet={wallet} />\n        </DropdownMenu.Item>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/SlotIndicator.tsx",
    "content": "import { Link, Text } from '@radix-ui/themes';\nimport { useContext, useEffect, useState, useSyncExternalStore } from 'react';\n\nimport { ChainContext } from '../context/ChainContext';\nimport { RpcContext } from '../context/RpcContext';\n\ntype SlotNotification = Readonly<{\n    parent: bigint;\n    root: bigint;\n    slot: bigint;\n}>;\n\ntype ReactiveStore<T> = {\n    getError(): unknown;\n    getState(): T | undefined;\n    subscribe(callback: () => void): () => void;\n};\n\nfunction createNoopStore(error?: unknown): ReactiveStore<SlotNotification> {\n    return {\n        getError: () => error,\n        getState: () => undefined,\n        subscribe: () => () => { },\n    };\n}\n\nconst slotFormatter = new Intl.NumberFormat();\n\nexport function SlotIndicator() {\n    const { rpcSubscriptions } = useContext(RpcContext);\n    const { chain, solanaExplorerClusterName } = useContext(ChainContext);\n    const [store, setStore] = useState<ReactiveStore<SlotNotification>>(createNoopStore);\n\n    useEffect(() => {\n        const abortController = new AbortController();\n        rpcSubscriptions\n            .slotNotifications()\n            .reactive({ abortSignal: abortController.signal })\n            .then(setStore)\n            .catch(e => setStore(createNoopStore(e)));\n        return () => abortController.abort();\n    }, [rpcSubscriptions, chain]);\n\n    const slot = useSyncExternalStore(store.subscribe, () => {\n        if (store.getError()) throw store.getError();\n        return store.getState();\n    });\n\n    if (!slot) {\n        return <Text>{'\\u2013'}</Text>;\n    }\n\n    return (\n        <Link\n            href={`https://explorer.solana.com/block/${slot.slot}?cluster=${solanaExplorerClusterName}`}\n            target=\"_blank\"\n        >\n            {slotFormatter.format(slot.slot)}\n        </Link>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/SolanaPartialSignTransactionFeaturePanel.tsx",
    "content": "import { Blockquote, Box, Button, Dialog, Flex, Link, Select, Text, TextField } from '@radix-ui/themes';\nimport {\n    Address,\n    address,\n    appendTransactionMessageInstruction,\n    assertIsSendableTransaction,\n    assertIsTransactionWithBlockhashLifetime,\n    createKeyPairFromBytes,\n    createTransactionMessage,\n    getBase58Encoder,\n    getSignatureFromTransaction,\n    getTransactionDecoder,\n    getTransactionEncoder,\n    lamports,\n    pipe,\n    SendableTransaction,\n    sendAndConfirmTransactionFactory,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n    Signature,\n    SignatureBytes,\n    signTransaction,\n    signTransactionMessageWithSigners,\n    Transaction,\n    TransactionPartialSigner,\n    TransactionWithBlockhashLifetime,\n} from '@solana/kit';\nimport { useWalletAccountTransactionSigner } from '@solana/react';\nimport { getTransferSolInstruction } from '@solana-program/system';\nimport { ReadonlyUint8Array } from '@wallet-standard/core';\nimport { getUiWalletAccountStorageKey, type UiWalletAccount, useWallets } from '@wallet-standard/react';\nimport type { SyntheticEvent } from 'react';\nimport { useContext, useId, useMemo, useRef, useState } from 'react';\nimport { useSWRConfig } from 'swr';\n\nimport { ChainContext } from '../context/ChainContext';\nimport { RpcContext } from '../context/RpcContext';\nimport signerBytes from '../signerBytes.json' with { type: 'json' };\nimport { AirdropButton } from './AirdropButton';\nimport { ErrorDialog } from './ErrorDialog';\nimport { WalletMenuItemContent } from './WalletMenuItemContent';\n\ntype Props = Readonly<{\n    account: UiWalletAccount;\n}>;\n\nfunction solStringToLamports(solQuantityString: string) {\n    if (Number.isNaN(parseFloat(solQuantityString))) {\n        throw new Error('Could not parse token quantity: ' + String(solQuantityString));\n    }\n    const formatter = new Intl.NumberFormat('en-US', { useGrouping: false });\n    const bigIntLamports = BigInt(\n        // @ts-expect-error - scientific notation is supported by `Intl.NumberFormat` but the types are wrong\n        formatter.format(`${solQuantityString}E9`).split('.')[0],\n    );\n    return lamports(bigIntLamports);\n}\n\ntype SignTransactionState =\n    | {\n          kind: 'creating-transaction';\n      }\n    | {\n          kind: 'inputs-form-active';\n      }\n    | {\n          kind: 'ready-to-send';\n          recipientAddress: Address;\n          transaction: SendableTransaction & Transaction & TransactionWithBlockhashLifetime;\n      }\n    | {\n          kind: 'sending-transaction';\n      };\n\nasync function mockApiRequest(serializedTransaction: ReadonlyUint8Array): Promise<SignatureBytes> {\n    const keypair = await createKeyPairFromBytes(new Uint8Array(signerBytes));\n    const transaction = getTransactionDecoder().decode(serializedTransaction);\n    const signedTransaction = await signTransaction([keypair], transaction);\n    return getBase58Encoder().encode(getSignatureFromTransaction(signedTransaction)) as SignatureBytes;\n}\n\nexport function SolanaPartialSignTransactionFeaturePanel({ account }: Props) {\n    const { mutate } = useSWRConfig();\n    const { current: NO_ERROR } = useRef(Symbol());\n    const { rpc, rpcSubscriptions } = useContext(RpcContext);\n    const sendAndConfirmTransaction = useMemo(\n        () => sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions }),\n        [rpc, rpcSubscriptions],\n    );\n    const wallets = useWallets();\n    const [error, setError] = useState<unknown>(NO_ERROR);\n    const [lastSignature, setLastSignature] = useState<Signature | undefined>();\n    const [solQuantityString, setSolQuantityString] = useState<string>('');\n    const [recipientAccountStorageKey, setRecipientAccountStorageKey] = useState<string | undefined>();\n    const recipientAccount = useMemo(() => {\n        if (recipientAccountStorageKey) {\n            for (const wallet of wallets) {\n                for (const account of wallet.accounts) {\n                    if (getUiWalletAccountStorageKey(account) === recipientAccountStorageKey) {\n                        return account;\n                    }\n                }\n            }\n        }\n    }, [recipientAccountStorageKey, wallets]);\n    const { chain: currentChain, solanaExplorerClusterName } = useContext(ChainContext);\n    const transactionSigner = useWalletAccountTransactionSigner(account, currentChain);\n    const lamportsInputId = useId();\n    const recipientSelectId = useId();\n    const [signTransactionState, setSignTransactionState] = useState<SignTransactionState>({\n        kind: 'inputs-form-active',\n    });\n    const formDisabled = signTransactionState.kind !== 'inputs-form-active';\n    const formLoading =\n        signTransactionState.kind === 'creating-transaction' || signTransactionState.kind === 'sending-transaction';\n\n    const feePayerAddress = address('HWJowarVUwY7ewUMeFCBqwkin9RPmkmfsVPYrUszNHDV');\n    const transactionEncoder = getTransactionEncoder();\n    const feePayerSigner: TransactionPartialSigner = {\n        address: feePayerAddress,\n        async signTransactions(transactions) {\n            return await Promise.all(\n                transactions.map(async transaction => {\n                    const serializedTransaction = transactionEncoder.encode(transaction);\n                    const signatureBytes = await mockApiRequest(serializedTransaction);\n                    return { [feePayerAddress]: signatureBytes };\n                }),\n            );\n        },\n    };\n\n    async function handleCreateTransaction(event: React.FormEvent<HTMLFormElement>) {\n        event.preventDefault();\n        setError(NO_ERROR);\n        setSignTransactionState({ kind: 'creating-transaction' });\n        try {\n            const amount = solStringToLamports(solQuantityString);\n            if (!recipientAccount) {\n                throw new Error('The address of the recipient could not be found');\n            }\n            const { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: 'confirmed' }).send();\n            const message = pipe(\n                createTransactionMessage({ version: 0 }),\n                m => setTransactionMessageFeePayerSigner(feePayerSigner, m),\n                m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n                m =>\n                    appendTransactionMessageInstruction(\n                        getTransferSolInstruction({\n                            amount,\n                            destination: address(recipientAccount.address),\n                            source: transactionSigner,\n                        }),\n                        m,\n                    ),\n            );\n            const transaction = await signTransactionMessageWithSigners(message);\n            assertIsSendableTransaction(transaction);\n            assertIsTransactionWithBlockhashLifetime(transaction);\n            setSignTransactionState({\n                kind: 'ready-to-send',\n                recipientAddress: recipientAccount.address as Address,\n                transaction,\n            });\n        } catch (e) {\n            setLastSignature(undefined);\n            setError(e);\n            setSignTransactionState({ kind: 'inputs-form-active' });\n        }\n    }\n\n    async function handleSendTransaction(\n        {\n            recipientAddress,\n            transaction,\n        }: {\n            recipientAddress: Address;\n            transaction: SendableTransaction & Transaction & TransactionWithBlockhashLifetime;\n        },\n        event: React.FormEvent<HTMLFormElement>,\n    ) {\n        event.preventDefault();\n        setError(NO_ERROR);\n        setSignTransactionState({ kind: 'sending-transaction' });\n        try {\n            const signature = getSignatureFromTransaction(transaction);\n            await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n            void mutate({ address: transactionSigner.address, chain: currentChain });\n            void mutate({ address: recipientAddress, chain: currentChain });\n            setLastSignature(signature);\n            setSolQuantityString('');\n            setSignTransactionState({ kind: 'inputs-form-active' });\n        } catch (e) {\n            setLastSignature(undefined);\n            setError(e);\n            setSignTransactionState({ kind: 'inputs-form-active' });\n        }\n    }\n\n    return (\n        <Flex asChild gap=\"2\" direction={{ initial: 'column', sm: 'row' }} style={{ width: '100%' }}>\n            <form\n                onSubmit={\n                    signTransactionState.kind === 'inputs-form-active'\n                        ? handleCreateTransaction\n                        : signTransactionState.kind === 'ready-to-send'\n                          ? handleSendTransaction.bind(null, signTransactionState)\n                          : undefined\n                }\n            >\n                <Box flexGrow=\"1\" overflow=\"hidden\">\n                    <Flex gap=\"3\" align=\"center\">\n                        <Box flexGrow=\"1\" minWidth=\"90px\" maxWidth=\"130px\">\n                            <TextField.Root\n                                disabled={formDisabled}\n                                id={lamportsInputId}\n                                placeholder=\"Amount\"\n                                onChange={(e: SyntheticEvent<HTMLInputElement>) =>\n                                    setSolQuantityString(e.currentTarget.value)\n                                }\n                                style={{ width: 'auto' }}\n                                type=\"number\"\n                                value={solQuantityString}\n                            >\n                                <TextField.Slot side=\"right\">{'\\u25ce'}</TextField.Slot>\n                            </TextField.Root>\n                        </Box>\n                        <Box flexShrink=\"0\">\n                            <Text as=\"label\" color=\"gray\" htmlFor={recipientSelectId} weight=\"medium\">\n                                To Account\n                            </Text>\n                        </Box>\n                        <Select.Root\n                            disabled={formDisabled}\n                            onValueChange={setRecipientAccountStorageKey}\n                            value={recipientAccount ? getUiWalletAccountStorageKey(recipientAccount) : undefined}\n                        >\n                            <Select.Trigger\n                                style={{ flexGrow: 1, flexShrink: 1, overflow: 'hidden' }}\n                                placeholder=\"Select a Connected Account\"\n                            />\n                            <Select.Content>\n                                {wallets.flatMap(wallet =>\n                                    wallet.accounts\n                                        .filter(({ chains }) => chains.includes(currentChain))\n                                        .map(account => {\n                                            const key = getUiWalletAccountStorageKey(account);\n                                            return (\n                                                <Select.Item key={key} value={key}>\n                                                    <WalletMenuItemContent wallet={wallet}>\n                                                        {account.address}\n                                                    </WalletMenuItemContent>\n                                                </Select.Item>\n                                            );\n                                        }),\n                                )}\n                            </Select.Content>\n                        </Select.Root>\n                    </Flex>\n                </Box>\n\n                <AirdropButton address={feePayerAddress} />\n\n                <Dialog.Root\n                    open={!!lastSignature}\n                    onOpenChange={open => {\n                        if (!open) {\n                            setLastSignature(undefined);\n                        }\n                    }}\n                >\n                    <Dialog.Trigger>\n                        <Button\n                            color={\n                                error ? (signTransactionState.kind === 'ready-to-send' ? 'green' : undefined) : 'red'\n                            }\n                            disabled={solQuantityString === '' || !recipientAccount}\n                            loading={formLoading}\n                            type=\"submit\"\n                        >\n                            {signTransactionState.kind === 'ready-to-send' ? 'Send' : 'Sign'}\n                        </Button>\n                    </Dialog.Trigger>\n                    {lastSignature ? (\n                        <Dialog.Content\n                            onClick={e => {\n                                e.stopPropagation();\n                            }}\n                        >\n                            <Dialog.Title>You transferred tokens!</Dialog.Title>\n                            <Flex direction=\"column\" gap=\"2\">\n                                <Text>Signature:</Text>\n                                <Blockquote>{lastSignature}</Blockquote>\n                                <Text>\n                                    <Link\n                                        href={`https://explorer.solana.com/tx/${lastSignature}?cluster=${solanaExplorerClusterName}`}\n                                        target=\"_blank\"\n                                    >\n                                        View this transaction\n                                    </Link>{' '}\n                                    on Explorer\n                                </Text>\n                            </Flex>\n                            <Flex gap=\"3\" mt=\"4\" justify=\"end\">\n                                <Dialog.Close>\n                                    <Button>Cool!</Button>\n                                </Dialog.Close>\n                            </Flex>\n                        </Dialog.Content>\n                    ) : null}\n                </Dialog.Root>\n                {error !== NO_ERROR ? (\n                    <ErrorDialog error={error} onClose={() => setError(NO_ERROR)} title=\"Transfer failed\" />\n                ) : null}\n            </form>\n        </Flex>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/SolanaSignAndSendTransactionFeaturePanel.tsx",
    "content": "import { Blockquote, Box, Button, Dialog, Flex, Link, Select, Text, TextField } from '@radix-ui/themes';\nimport {\n    address,\n    appendTransactionMessageInstruction,\n    assertIsTransactionMessageWithSingleSendingSigner,\n    createTransactionMessage,\n    getBase58Decoder,\n    lamports,\n    pipe,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signAndSendTransactionMessageWithSigners,\n} from '@solana/kit';\nimport { useWalletAccountTransactionSendingSigner } from '@solana/react';\nimport { getTransferSolInstruction } from '@solana-program/system';\nimport { getUiWalletAccountStorageKey, type UiWalletAccount, useWallets } from '@wallet-standard/react';\nimport type { SyntheticEvent } from 'react';\nimport { useContext, useId, useMemo, useRef, useState } from 'react';\nimport { useSWRConfig } from 'swr';\n\nimport { ChainContext } from '../context/ChainContext';\nimport { RpcContext } from '../context/RpcContext';\nimport { ErrorDialog } from './ErrorDialog';\nimport { WalletMenuItemContent } from './WalletMenuItemContent';\n\ntype Props = Readonly<{\n    account: UiWalletAccount;\n}>;\n\nfunction solStringToLamports(solQuantityString: string) {\n    if (Number.isNaN(parseFloat(solQuantityString))) {\n        throw new Error('Could not parse token quantity: ' + String(solQuantityString));\n    }\n    const formatter = new Intl.NumberFormat('en-US', { useGrouping: false });\n    const bigIntLamports = BigInt(\n        // @ts-expect-error - scientific notation is supported by `Intl.NumberFormat` but the types are wrong\n        formatter.format(`${solQuantityString}E9`).split('.')[0],\n    );\n    return lamports(bigIntLamports);\n}\n\nexport function SolanaSignAndSendTransactionFeaturePanel({ account }: Props) {\n    const { mutate } = useSWRConfig();\n    const { current: NO_ERROR } = useRef(Symbol());\n    const { rpc } = useContext(RpcContext);\n    const wallets = useWallets();\n    const [isSendingTransaction, setIsSendingTransaction] = useState(false);\n    const [error, setError] = useState(NO_ERROR);\n    const [lastSignature, setLastSignature] = useState<Uint8Array | undefined>();\n    const [solQuantityString, setSolQuantityString] = useState<string>('');\n    const [recipientAccountStorageKey, setRecipientAccountStorageKey] = useState<string | undefined>();\n    const recipientAccount = useMemo(() => {\n        if (recipientAccountStorageKey) {\n            for (const wallet of wallets) {\n                for (const account of wallet.accounts) {\n                    if (getUiWalletAccountStorageKey(account) === recipientAccountStorageKey) {\n                        return account;\n                    }\n                }\n            }\n        }\n    }, [recipientAccountStorageKey, wallets]);\n    const { chain: currentChain, solanaExplorerClusterName } = useContext(ChainContext);\n    const transactionSendingSigner = useWalletAccountTransactionSendingSigner(account, currentChain);\n    const lamportsInputId = useId();\n    const recipientSelectId = useId();\n    return (\n        <Flex asChild gap=\"2\" direction={{ initial: 'column', sm: 'row' }} style={{ width: '100%' }}>\n            <form\n                onSubmit={async e => {\n                    e.preventDefault();\n                    setError(NO_ERROR);\n                    setIsSendingTransaction(true);\n                    try {\n                        const amount = solStringToLamports(solQuantityString);\n                        if (!recipientAccount) {\n                            throw new Error('The address of the recipient could not be found');\n                        }\n                        const { value: latestBlockhash } = await rpc\n                            .getLatestBlockhash({ commitment: 'confirmed' })\n                            .send();\n                        const message = pipe(\n                            createTransactionMessage({ version: 0 }),\n                            m => setTransactionMessageFeePayerSigner(transactionSendingSigner, m),\n                            m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n                            m =>\n                                appendTransactionMessageInstruction(\n                                    getTransferSolInstruction({\n                                        amount,\n                                        destination: address(recipientAccount.address),\n                                        source: transactionSendingSigner,\n                                    }),\n                                    m,\n                                ),\n                        );\n                        assertIsTransactionMessageWithSingleSendingSigner(message);\n                        const signature = await signAndSendTransactionMessageWithSigners(message);\n                        void mutate({ address: transactionSendingSigner.address, chain: currentChain });\n                        void mutate({ address: recipientAccount.address, chain: currentChain });\n                        setLastSignature(signature);\n                        setSolQuantityString('');\n                    } catch (e) {\n                        setLastSignature(undefined);\n                        setError(e);\n                    } finally {\n                        setIsSendingTransaction(false);\n                    }\n                }}\n            >\n                <Box flexGrow=\"1\" overflow=\"hidden\">\n                    <Flex gap=\"3\" align=\"center\">\n                        <Box flexGrow=\"1\" minWidth=\"90px\" maxWidth=\"130px\">\n                            <TextField.Root\n                                disabled={isSendingTransaction}\n                                id={lamportsInputId}\n                                placeholder=\"Amount\"\n                                onChange={(e: SyntheticEvent<HTMLInputElement>) =>\n                                    setSolQuantityString(e.currentTarget.value)\n                                }\n                                style={{ width: 'auto' }}\n                                type=\"number\"\n                                value={solQuantityString}\n                            >\n                                <TextField.Slot side=\"right\">{'\\u25ce'}</TextField.Slot>\n                            </TextField.Root>\n                        </Box>\n                        <Box flexShrink=\"0\">\n                            <Text as=\"label\" color=\"gray\" htmlFor={recipientSelectId} weight=\"medium\">\n                                To Account\n                            </Text>\n                        </Box>\n                        <Select.Root\n                            disabled={isSendingTransaction}\n                            onValueChange={setRecipientAccountStorageKey}\n                            value={recipientAccount ? getUiWalletAccountStorageKey(recipientAccount) : undefined}\n                        >\n                            <Select.Trigger\n                                style={{ flexGrow: 1, flexShrink: 1, overflow: 'hidden' }}\n                                placeholder=\"Select a Connected Account\"\n                            />\n                            <Select.Content>\n                                {wallets.flatMap(wallet =>\n                                    wallet.accounts\n                                        .filter(({ chains }) => chains.includes(currentChain))\n                                        .map(account => {\n                                            const key = getUiWalletAccountStorageKey(account);\n                                            return (\n                                                <Select.Item key={key} value={key}>\n                                                    <WalletMenuItemContent wallet={wallet}>\n                                                        {account.address}\n                                                    </WalletMenuItemContent>\n                                                </Select.Item>\n                                            );\n                                        }),\n                                )}\n                            </Select.Content>\n                        </Select.Root>\n                    </Flex>\n                </Box>\n                <Dialog.Root\n                    open={!!lastSignature}\n                    onOpenChange={open => {\n                        if (!open) {\n                            setLastSignature(undefined);\n                        }\n                    }}\n                >\n                    <Dialog.Trigger>\n                        <Button\n                            color={error ? undefined : 'red'}\n                            disabled={solQuantityString === '' || !recipientAccount}\n                            loading={isSendingTransaction}\n                            type=\"submit\"\n                        >\n                            Transfer\n                        </Button>\n                    </Dialog.Trigger>\n                    {lastSignature ? (\n                        <Dialog.Content\n                            onClick={e => {\n                                e.stopPropagation();\n                            }}\n                        >\n                            <Dialog.Title>You transferred tokens!</Dialog.Title>\n                            <Flex direction=\"column\" gap=\"2\">\n                                <Text>Signature:</Text>\n                                <Blockquote>{getBase58Decoder().decode(lastSignature)}</Blockquote>\n                                <Text>\n                                    <Link\n                                        href={`https://explorer.solana.com/tx/${getBase58Decoder().decode(\n                                            lastSignature,\n                                        )}?cluster=${solanaExplorerClusterName}`}\n                                        target=\"_blank\"\n                                    >\n                                        View this transaction\n                                    </Link>{' '}\n                                    on Explorer\n                                </Text>\n                            </Flex>\n                            <Flex gap=\"3\" mt=\"4\" justify=\"end\">\n                                <Dialog.Close>\n                                    <Button>Cool!</Button>\n                                </Dialog.Close>\n                            </Flex>\n                        </Dialog.Content>\n                    ) : null}\n                </Dialog.Root>\n                {error !== NO_ERROR ? (\n                    <ErrorDialog error={error} onClose={() => setError(NO_ERROR)} title=\"Transfer failed\" />\n                ) : null}\n            </form>\n        </Flex>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/SolanaSignMessageFeaturePanel.tsx",
    "content": "import type { Address } from '@solana/kit';\nimport { useWalletAccountMessageSigner } from '@solana/react';\nimport type { ReadonlyUint8Array } from '@wallet-standard/core';\nimport type { UiWalletAccount } from '@wallet-standard/react';\nimport { useCallback } from 'react';\n\nimport { BaseSignMessageFeaturePanel } from './BaseSignMessageFeaturePanel';\n\ntype Props = Readonly<{\n    account: UiWalletAccount;\n}>;\n\nexport function SolanaSignMessageFeaturePanel({ account }: Props) {\n    const messageSigner = useWalletAccountMessageSigner(account);\n    const signMessage = useCallback(\n        async (message: ReadonlyUint8Array) => {\n            const [result] = await messageSigner.modifyAndSignMessages([\n                {\n                    content: message as Uint8Array,\n                    signatures: {},\n                },\n            ]);\n            const signature = result?.signatures[account.address as Address];\n            if (!signature) {\n                throw new Error();\n            }\n            return signature as ReadonlyUint8Array;\n        },\n        [account.address, messageSigner],\n    );\n    return <BaseSignMessageFeaturePanel signMessage={signMessage} />;\n}\n"
  },
  {
    "path": "examples/react-app/src/components/SolanaSignTransactionFeaturePanel.tsx",
    "content": "import { Blockquote, Box, Button, Dialog, Flex, Link, Select, Text, TextField } from '@radix-ui/themes';\nimport {\n    Address,\n    address,\n    appendTransactionMessageInstruction,\n    assertIsSendableTransaction,\n    assertIsTransactionWithBlockhashLifetime,\n    createTransactionMessage,\n    getSignatureFromTransaction,\n    lamports,\n    pipe,\n    SendableTransaction,\n    sendAndConfirmTransactionFactory,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n    Signature,\n    signTransactionMessageWithSigners,\n    Transaction,\n    TransactionWithBlockhashLifetime,\n} from '@solana/kit';\nimport { useWalletAccountTransactionSigner } from '@solana/react';\nimport { getTransferSolInstruction } from '@solana-program/system';\nimport { getUiWalletAccountStorageKey, type UiWalletAccount, useWallets } from '@wallet-standard/react';\nimport type { SyntheticEvent } from 'react';\nimport { useContext, useId, useMemo, useRef, useState } from 'react';\nimport { useSWRConfig } from 'swr';\n\nimport { ChainContext } from '../context/ChainContext';\nimport { RpcContext } from '../context/RpcContext';\nimport { ErrorDialog } from './ErrorDialog';\nimport { WalletMenuItemContent } from './WalletMenuItemContent';\n\ntype Props = Readonly<{\n    account: UiWalletAccount;\n}>;\n\nfunction solStringToLamports(solQuantityString: string) {\n    if (Number.isNaN(parseFloat(solQuantityString))) {\n        throw new Error('Could not parse token quantity: ' + String(solQuantityString));\n    }\n    const formatter = new Intl.NumberFormat('en-US', { useGrouping: false });\n    const bigIntLamports = BigInt(\n        // @ts-expect-error - scientific notation is supported by `Intl.NumberFormat` but the types are wrong\n        formatter.format(`${solQuantityString}E9`).split('.')[0],\n    );\n    return lamports(bigIntLamports);\n}\n\ntype SignTransactionState =\n    | {\n          kind: 'creating-transaction';\n      }\n    | {\n          kind: 'inputs-form-active';\n      }\n    | {\n          kind: 'ready-to-send';\n          recipientAddress: Address;\n          transaction: SendableTransaction & Transaction & TransactionWithBlockhashLifetime;\n      }\n    | {\n          kind: 'sending-transaction';\n      };\n\nexport function SolanaSignTransactionFeaturePanel({ account }: Props) {\n    const { mutate } = useSWRConfig();\n    const { current: NO_ERROR } = useRef(Symbol());\n    const { rpc, rpcSubscriptions } = useContext(RpcContext);\n    const sendAndConfirmTransaction = useMemo(\n        () => sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions }),\n        [rpc, rpcSubscriptions],\n    );\n    const wallets = useWallets();\n    const [error, setError] = useState<unknown>(NO_ERROR);\n    const [lastSignature, setLastSignature] = useState<Signature | undefined>();\n    const [solQuantityString, setSolQuantityString] = useState<string>('');\n    const [recipientAccountStorageKey, setRecipientAccountStorageKey] = useState<string | undefined>();\n    const recipientAccount = useMemo(() => {\n        if (recipientAccountStorageKey) {\n            for (const wallet of wallets) {\n                for (const account of wallet.accounts) {\n                    if (getUiWalletAccountStorageKey(account) === recipientAccountStorageKey) {\n                        return account;\n                    }\n                }\n            }\n        }\n    }, [recipientAccountStorageKey, wallets]);\n    const { chain: currentChain, solanaExplorerClusterName } = useContext(ChainContext);\n    const transactionSigner = useWalletAccountTransactionSigner(account, currentChain);\n    const lamportsInputId = useId();\n    const recipientSelectId = useId();\n    const [signTransactionState, setSignTransactionState] = useState<SignTransactionState>({\n        kind: 'inputs-form-active',\n    });\n    const formDisabled = signTransactionState.kind !== 'inputs-form-active';\n    const formLoading =\n        signTransactionState.kind === 'creating-transaction' || signTransactionState.kind === 'sending-transaction';\n\n    async function handleCreateTransaction(event: React.FormEvent<HTMLFormElement>) {\n        event.preventDefault();\n        setError(NO_ERROR);\n        setSignTransactionState({ kind: 'creating-transaction' });\n        try {\n            const amount = solStringToLamports(solQuantityString);\n            if (!recipientAccount) {\n                throw new Error('The address of the recipient could not be found');\n            }\n            const { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: 'confirmed' }).send();\n            const message = pipe(\n                createTransactionMessage({ version: 0 }),\n                m => setTransactionMessageFeePayerSigner(transactionSigner, m),\n                m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n                m =>\n                    appendTransactionMessageInstruction(\n                        getTransferSolInstruction({\n                            amount,\n                            destination: address(recipientAccount.address),\n                            source: transactionSigner,\n                        }),\n                        m,\n                    ),\n            );\n            const transaction = await signTransactionMessageWithSigners(message);\n            assertIsSendableTransaction(transaction);\n            assertIsTransactionWithBlockhashLifetime(transaction);\n            setSignTransactionState({\n                kind: 'ready-to-send',\n                recipientAddress: recipientAccount.address as Address,\n                transaction,\n            });\n        } catch (e) {\n            setLastSignature(undefined);\n            setError(e);\n            setSignTransactionState({ kind: 'inputs-form-active' });\n        }\n    }\n\n    async function handleSendTransaction(\n        {\n            recipientAddress,\n            transaction,\n        }: {\n            recipientAddress: Address;\n            transaction: SendableTransaction & Transaction & TransactionWithBlockhashLifetime;\n        },\n        event: React.FormEvent<HTMLFormElement>,\n    ) {\n        event.preventDefault();\n        setError(NO_ERROR);\n        setSignTransactionState({ kind: 'sending-transaction' });\n        try {\n            const signature = getSignatureFromTransaction(transaction);\n            await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n            void mutate({ address: transactionSigner.address, chain: currentChain });\n            void mutate({ address: recipientAddress, chain: currentChain });\n            setLastSignature(signature);\n            setSolQuantityString('');\n            setSignTransactionState({ kind: 'inputs-form-active' });\n        } catch (e) {\n            setLastSignature(undefined);\n            setError(e);\n            setSignTransactionState({ kind: 'inputs-form-active' });\n        }\n    }\n\n    return (\n        <Flex asChild gap=\"2\" direction={{ initial: 'column', sm: 'row' }} style={{ width: '100%' }}>\n            <form\n                onSubmit={\n                    signTransactionState.kind === 'inputs-form-active'\n                        ? handleCreateTransaction\n                        : signTransactionState.kind === 'ready-to-send'\n                          ? handleSendTransaction.bind(null, signTransactionState)\n                          : undefined\n                }\n            >\n                <Box flexGrow=\"1\" overflow=\"hidden\">\n                    <Flex gap=\"3\" align=\"center\">\n                        <Box flexGrow=\"1\" minWidth=\"90px\" maxWidth=\"130px\">\n                            <TextField.Root\n                                disabled={formDisabled}\n                                id={lamportsInputId}\n                                placeholder=\"Amount\"\n                                onChange={(e: SyntheticEvent<HTMLInputElement>) =>\n                                    setSolQuantityString(e.currentTarget.value)\n                                }\n                                style={{ width: 'auto' }}\n                                type=\"number\"\n                                value={solQuantityString}\n                            >\n                                <TextField.Slot side=\"right\">{'\\u25ce'}</TextField.Slot>\n                            </TextField.Root>\n                        </Box>\n                        <Box flexShrink=\"0\">\n                            <Text as=\"label\" color=\"gray\" htmlFor={recipientSelectId} weight=\"medium\">\n                                To Account\n                            </Text>\n                        </Box>\n                        <Select.Root\n                            disabled={formDisabled}\n                            onValueChange={setRecipientAccountStorageKey}\n                            value={recipientAccount ? getUiWalletAccountStorageKey(recipientAccount) : undefined}\n                        >\n                            <Select.Trigger\n                                style={{ flexGrow: 1, flexShrink: 1, overflow: 'hidden' }}\n                                placeholder=\"Select a Connected Account\"\n                            />\n                            <Select.Content>\n                                {wallets.flatMap(wallet =>\n                                    wallet.accounts\n                                        .filter(({ chains }) => chains.includes(currentChain))\n                                        .map(account => {\n                                            const key = getUiWalletAccountStorageKey(account);\n                                            return (\n                                                <Select.Item key={key} value={key}>\n                                                    <WalletMenuItemContent wallet={wallet}>\n                                                        {account.address}\n                                                    </WalletMenuItemContent>\n                                                </Select.Item>\n                                            );\n                                        }),\n                                )}\n                            </Select.Content>\n                        </Select.Root>\n                    </Flex>\n                </Box>\n                <Dialog.Root\n                    open={!!lastSignature}\n                    onOpenChange={open => {\n                        if (!open) {\n                            setLastSignature(undefined);\n                        }\n                    }}\n                >\n                    <Dialog.Trigger>\n                        <Button\n                            color={\n                                error ? (signTransactionState.kind === 'ready-to-send' ? 'green' : undefined) : 'red'\n                            }\n                            disabled={solQuantityString === '' || !recipientAccount}\n                            loading={formLoading}\n                            type=\"submit\"\n                        >\n                            {signTransactionState.kind === 'ready-to-send' ? 'Send' : 'Sign'}\n                        </Button>\n                    </Dialog.Trigger>\n                    {lastSignature ? (\n                        <Dialog.Content\n                            onClick={e => {\n                                e.stopPropagation();\n                            }}\n                        >\n                            <Dialog.Title>You transferred tokens!</Dialog.Title>\n                            <Flex direction=\"column\" gap=\"2\">\n                                <Text>Signature:</Text>\n                                <Blockquote>{lastSignature}</Blockquote>\n                                <Text>\n                                    <Link\n                                        href={`https://explorer.solana.com/tx/${lastSignature}?cluster=${solanaExplorerClusterName}`}\n                                        target=\"_blank\"\n                                    >\n                                        View this transaction\n                                    </Link>{' '}\n                                    on Explorer\n                                </Text>\n                            </Flex>\n                            <Flex gap=\"3\" mt=\"4\" justify=\"end\">\n                                <Dialog.Close>\n                                    <Button>Cool!</Button>\n                                </Dialog.Close>\n                            </Flex>\n                        </Dialog.Content>\n                    ) : null}\n                </Dialog.Root>\n                {error !== NO_ERROR ? (\n                    <ErrorDialog error={error} onClose={() => setError(NO_ERROR)} title=\"Transfer failed\" />\n                ) : null}\n            </form>\n        </Flex>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/UnconnectableWalletMenuItem.tsx",
    "content": "import { ExclamationTriangleIcon } from '@radix-ui/react-icons';\nimport { Box, DropdownMenu, Text } from '@radix-ui/themes';\nimport type { UiWallet } from '@wallet-standard/react';\nimport { useState } from 'react';\n\nimport { ErrorDialog } from './ErrorDialog';\nimport { WalletMenuItemContent } from './WalletMenuItemContent';\n\ntype Props = Readonly<{\n    error: unknown;\n    wallet: UiWallet;\n}>;\n\nexport function UnconnectableWalletMenuItem({ error, wallet }: Props) {\n    const [dialogIsOpen, setDialogIsOpen] = useState(false);\n    return (\n        <>\n            <DropdownMenu.Item disabled onClick={() => setDialogIsOpen(true)}>\n                <WalletMenuItemContent wallet={wallet}>\n                    <Text style={{ textDecoration: 'line-through' }}>{wallet.name}</Text>\n                </WalletMenuItemContent>\n                <Box className=\"rt-BaseMenuShortcut rt-DropdownMenuShortcut\">\n                    <ExclamationTriangleIcon\n                        className=\"rt-BaseMenuSubTriggerIcon rt-DropdownMenuSubtriggerIcon\"\n                        style={{ height: 14, width: 14 }}\n                    />\n                </Box>\n            </DropdownMenu.Item>\n            {dialogIsOpen ? (\n                <ErrorDialog error={error} onClose={() => setDialogIsOpen(false)} title=\"Unconnectable wallet\" />\n            ) : null}\n        </>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/components/WalletAccountIcon.tsx",
    "content": "import type { UiWalletAccount } from '@wallet-standard/react';\nimport { uiWalletAccountBelongsToUiWallet, useWallets } from '@wallet-standard/react';\nimport React from 'react';\n\ntype Props = React.ComponentProps<'img'> &\n    Readonly<{\n        account: UiWalletAccount;\n    }>;\n\nexport function WalletAccountIcon({ account, ...imgProps }: Props) {\n    const wallets = useWallets();\n    let icon;\n    if (account.icon) {\n        icon = account.icon;\n    } else {\n        for (const wallet of wallets) {\n            if (uiWalletAccountBelongsToUiWallet(account, wallet)) {\n                icon = wallet.icon;\n                break;\n            }\n        }\n    }\n    return icon ? <img src={icon} {...imgProps} /> : null;\n}\n"
  },
  {
    "path": "examples/react-app/src/components/WalletMenuItemContent.tsx",
    "content": "import { Avatar, Flex, Spinner, Text } from '@radix-ui/themes';\nimport type { UiWallet } from '@wallet-standard/react';\nimport React from 'react';\n\ntype Props = Readonly<{\n    children?: React.ReactNode;\n    loading?: boolean;\n    wallet: UiWallet;\n}>;\n\nexport function WalletMenuItemContent({ children, loading, wallet }: Props) {\n    return (\n        <Flex align=\"center\" gap=\"2\">\n            <Spinner loading={!!loading}>\n                <Avatar\n                    fallback={<Text size=\"1\">{wallet.name.slice(0, 1)}</Text>}\n                    radius=\"none\"\n                    src={wallet.icon}\n                    style={{ height: 18, width: 18 }}\n                />\n            </Spinner>\n            <Text truncate>{children ?? wallet.name}</Text>\n        </Flex>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/context/ChainContext.tsx",
    "content": "import type { ClusterUrl } from '@solana/kit';\nimport { devnet } from '@solana/kit';\nimport { createContext } from 'react';\n\nexport type ChainContext = Readonly<{\n    chain: `solana:${string}`;\n    displayName: string;\n    setChain?(chain: `solana:${string}`): void;\n    solanaExplorerClusterName: 'devnet' | 'mainnet-beta' | 'testnet';\n    solanaRpcSubscriptionsUrl: ClusterUrl;\n    solanaRpcUrl: ClusterUrl;\n}>;\n\nexport const DEFAULT_CHAIN_CONFIG = Object.freeze({\n    chain: 'solana:devnet',\n    displayName: 'Devnet',\n    solanaExplorerClusterName: 'devnet',\n    solanaRpcSubscriptionsUrl: devnet('wss://api.devnet.solana.com'),\n    solanaRpcUrl: devnet('https://api.devnet.solana.com'),\n});\n\nexport const ChainContext = createContext<ChainContext>(DEFAULT_CHAIN_CONFIG);\n"
  },
  {
    "path": "examples/react-app/src/context/ChainContextProvider.tsx",
    "content": "import { mainnet, testnet } from '@solana/kit';\nimport { useMemo, useState } from 'react';\n\nimport { ChainContext, DEFAULT_CHAIN_CONFIG } from './ChainContext';\n\nconst STORAGE_KEY = 'solana-example-react-app:selected-chain';\n\nexport function ChainContextProvider({ children }: { children: React.ReactNode }) {\n    const [chain, setChain] = useState(() => localStorage.getItem(STORAGE_KEY) ?? 'solana:devnet');\n    const contextValue = useMemo<ChainContext>(() => {\n        switch (chain) {\n            // @ts-expect-error Intentional fall through\n            case 'solana:mainnet':\n                if (process.env.REACT_EXAMPLE_APP_ENABLE_MAINNET === 'true') {\n                    return {\n                        chain: 'solana:mainnet',\n                        displayName: 'Mainnet Beta',\n                        solanaExplorerClusterName: 'mainnet-beta',\n                        solanaRpcSubscriptionsUrl: mainnet('wss://api.mainnet-beta.solana.com'),\n                        solanaRpcUrl: mainnet('https://api.mainnet-beta.solana.com'),\n                    };\n                }\n            // falls through\n            case 'solana:testnet':\n                return {\n                    chain: 'solana:testnet',\n                    displayName: 'Testnet',\n                    solanaExplorerClusterName: 'testnet',\n                    solanaRpcSubscriptionsUrl: testnet('wss://api.testnet.solana.com'),\n                    solanaRpcUrl: testnet('https://api.testnet.solana.com'),\n                };\n            case 'solana:devnet':\n            default:\n                if (chain !== 'solana:devnet') {\n                    localStorage.removeItem(STORAGE_KEY);\n                    console.error(`Unrecognized chain \\`${chain}\\``);\n                }\n                return DEFAULT_CHAIN_CONFIG;\n        }\n    }, [chain]);\n    return (\n        <ChainContext.Provider\n            value={useMemo(\n                () => ({\n                    ...contextValue,\n                    setChain(chain) {\n                        localStorage.setItem(STORAGE_KEY, chain);\n                        setChain(chain);\n                    },\n                }),\n                [contextValue],\n            )}\n        >\n            {children}\n        </ChainContext.Provider>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/context/RpcContext.tsx",
    "content": "import type { Rpc, RpcSubscriptions, SolanaRpcApiMainnet, SolanaRpcSubscriptionsApi } from '@solana/kit';\nimport { createSolanaRpc, createSolanaRpcSubscriptions, devnet } from '@solana/kit';\nimport { createContext } from 'react';\n\nexport const RpcContext = createContext<{\n    rpc: Rpc<SolanaRpcApiMainnet>; // Limit the API to only those methods found on Mainnet (ie. not `requestAirdrop`)\n    rpcSubscriptions: RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n}>({\n    rpc: createSolanaRpc(devnet('https://api.devnet.solana.com')),\n    rpcSubscriptions: createSolanaRpcSubscriptions(devnet('wss://api.devnet.solana.com')),\n});\n"
  },
  {
    "path": "examples/react-app/src/context/RpcContextProvider.tsx",
    "content": "import { createSolanaRpc, createSolanaRpcSubscriptions } from '@solana/kit';\nimport { ReactNode, useContext, useMemo } from 'react';\n\nimport { ChainContext } from './ChainContext';\nimport { RpcContext } from './RpcContext';\n\ntype Props = Readonly<{\n    children: ReactNode;\n}>;\n\nexport function RpcContextProvider({ children }: Props) {\n    const { solanaRpcSubscriptionsUrl, solanaRpcUrl } = useContext(ChainContext);\n    return (\n        <RpcContext.Provider\n            value={useMemo(\n                () => ({\n                    rpc: createSolanaRpc(solanaRpcUrl),\n                    rpcSubscriptions: createSolanaRpcSubscriptions(solanaRpcSubscriptionsUrl),\n                }),\n                [solanaRpcSubscriptionsUrl, solanaRpcUrl],\n            )}\n        >\n            {children}\n        </RpcContext.Provider>\n    );\n}\n"
  },
  {
    "path": "examples/react-app/src/errors.tsx",
    "content": "import { Code, Flex, Text } from '@radix-ui/themes';\nimport { isSolanaError, SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE } from '@solana/kit';\nimport {\n    isWalletStandardError,\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED,\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED,\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_FEATURE_UNIMPLEMENTED,\n} from '@wallet-standard/core';\nimport React from 'react';\n\nexport const NO_ERROR = Symbol();\n\nexport function getErrorMessage(err: unknown, fallbackMessage: React.ReactNode): React.ReactNode {\n    if (isWalletStandardError(err, WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED)) {\n        return (\n            <>\n                This account does not support the <Code>{err.context.featureName}</Code> feature\n            </>\n        );\n    } else if (isWalletStandardError(err, WALLET_STANDARD_ERROR__FEATURES__WALLET_FEATURE_UNIMPLEMENTED)) {\n        return (\n            <Flex direction=\"column\" gap=\"4\">\n                <Text as=\"p\">\n                    The wallet '{err.context.walletName}' (\n                    {err.context.supportedChains.sort().map((chain, ii, { length }) => (\n                        <React.Fragment key={chain}>\n                            <Code>{chain}</Code>\n                            {ii === length - 1 ? null : ', '}\n                        </React.Fragment>\n                    ))}\n                    ) does not support the <Code>{err.context.featureName}</Code> feature.\n                </Text>\n                <Text as=\"p\" trim=\"end\">\n                    Features supported:\n                    <ul>\n                        {err.context.supportedFeatures.sort().map(featureName => (\n                            <li key={featureName}>\n                                <Code>{featureName}</Code>\n                            </li>\n                        ))}\n                    </ul>\n                </Text>\n            </Flex>\n        );\n    } else if (isWalletStandardError(err, WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED)) {\n        return (\n            <Flex direction=\"column\" gap=\"4\">\n                <Text as=\"p\">\n                    This account does not support the chain <Code>{err.context.chain}</Code>.\n                </Text>\n                <Text as=\"p\" trim=\"end\">\n                    Chains supported:\n                    <ul>\n                        {err.context.supportedChains.sort().map(chain => (\n                            <li key={chain}>\n                                <Code>{chain}</Code>\n                            </li>\n                        ))}\n                    </ul>\n                </Text>\n            </Flex>\n        );\n    } else if (isSolanaError(err, SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE)) {\n        return (\n            <Flex direction=\"column\" gap=\"4\">\n                <Text as=\"p\">{err.message}</Text>\n                <Text as=\"p\" trim=\"end\">\n                    Transaction logs:\n                    <ol>\n                        {Object.entries(err.context.logs ?? []).map(([key, value]) => (\n                            <li key={key}>{String(value)}</li>\n                        ))}\n                    </ol>\n                </Text>\n            </Flex>\n        );\n    } else if (err && typeof err === 'object' && 'message' in err) {\n        return String(err.message);\n    }\n    return fallbackMessage;\n}\n"
  },
  {
    "path": "examples/react-app/src/functions/balance.ts",
    "content": "import {\n    AccountNotificationsApi,\n    Address,\n    createReactiveStoreWithInitialValueAndSlotTracking,\n    GetBalanceApi,\n    Lamports,\n    Rpc,\n    RpcSubscriptions,\n} from '@solana/kit';\nimport { SWRSubscription } from 'swr/subscription';\n\n/**\n * This is an example of a strategy to fetch some account data and to keep it up to date over time.\n * It's implemented as an SWR subscription function (https://swr.vercel.app/docs/subscription) but\n * the approach is generalizable.\n *\n * It uses {@link createReactiveStoreWithInitialValueAndSlotTracking} to combine an initial RPC fetch with an\n * ongoing subscription, using slot-based comparison to ensure only the latest value is published.\n */\nexport function balanceSubscribe(\n    rpc: Rpc<GetBalanceApi>,\n    rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi>,\n    ...subscriptionArgs: Parameters<SWRSubscription<{ address: Address }, Lamports>>\n) {\n    const [{ address }, { next }] = subscriptionArgs;\n    const abortController = new AbortController();\n    const store = createReactiveStoreWithInitialValueAndSlotTracking({\n        abortSignal: abortController.signal,\n        rpcRequest: rpc.getBalance(address, { commitment: 'confirmed' }),\n        rpcSubscriptionRequest: rpcSubscriptions.accountNotifications(address),\n        rpcSubscriptionValueMapper: ({ lamports }) => lamports,\n        rpcValueMapper: lamports => lamports,\n    });\n    store.subscribe(() => {\n        const error = store.getError();\n        if (error) {\n            next(error as Error);\n        } else {\n            next(null, store.getState()?.value);\n        }\n    });\n    return () => {\n        abortController.abort();\n    };\n}\n"
  },
  {
    "path": "examples/react-app/src/hooks/useStable.ts",
    "content": "/* eslint-disable react-hooks/refs */\nimport { useRef } from 'react';\n\nconst UNRESOLVED = Symbol();\n\nexport function useStable<T>(getValue: () => T): T {\n    const ref = useRef<T | typeof UNRESOLVED>(UNRESOLVED);\n    if (ref.current === UNRESOLVED) {\n        ref.current = getValue();\n    }\n    return ref.current;\n}\n"
  },
  {
    "path": "examples/react-app/src/index.css",
    "content": "@import './reset.css';\n"
  },
  {
    "path": "examples/react-app/src/main.tsx",
    "content": "import './index.css';\nimport '@radix-ui/themes/styles.css';\n\nimport { Flex, Section, Theme } from '@radix-ui/themes';\nimport { SelectedWalletAccountContextProvider } from '@solana/react';\nimport type { UiWallet } from '@wallet-standard/react';\nimport { StrictMode } from 'react';\nimport { createRoot } from 'react-dom/client';\n\nimport { Nav } from './components/Nav.tsx';\nimport { ChainContextProvider } from './context/ChainContextProvider.tsx';\nimport { RpcContextProvider } from './context/RpcContextProvider.tsx';\nimport Root from './routes/root.tsx';\n\nconst STORAGE_KEY = 'solana-wallet-standard-example-react:selected-wallet-and-address';\nconst stateSync = {\n    deleteSelectedWallet: () => localStorage.removeItem(STORAGE_KEY),\n    getSelectedWallet: () => localStorage.getItem(STORAGE_KEY),\n    storeSelectedWallet: (accountKey: string) => localStorage.setItem(STORAGE_KEY, accountKey),\n};\n\nconst rootNode = document.getElementById('root')!;\nconst root = createRoot(rootNode);\nroot.render(\n    <StrictMode>\n        <Theme>\n            <ChainContextProvider>\n                <SelectedWalletAccountContextProvider filterWallets={(_: UiWallet) => true} stateSync={stateSync}>\n                    <RpcContextProvider>\n                        <Flex direction=\"column\">\n                            <Nav />\n                            <Section>\n                                <Root />\n                            </Section>\n                        </Flex>\n                    </RpcContextProvider>\n                </SelectedWalletAccountContextProvider>\n            </ChainContextProvider>\n        </Theme>\n    </StrictMode>,\n);\n"
  },
  {
    "path": "examples/react-app/src/reset.css",
    "content": "/* Box sizing rules */\n*,\n*::before,\n*::after {\n    box-sizing: border-box;\n}\n\n/* Remove default margin */\nbody,\nh1,\nh2,\nh3,\nh4,\np,\nfigure,\nblockquote,\ndl,\ndd {\n    margin: 0;\n}\n\n/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */\nul[role='list'],\nol[role='list'] {\n    list-style: none;\n}\n\n/* Set core root defaults */\nhtml:focus-within {\n    scroll-behavior: smooth;\n}\n\n/* Set core body defaults */\nbody {\n    min-height: 100vh;\n    text-rendering: optimizeSpeed;\n    line-height: 1.5;\n}\n\n/* A elements that don't have a class get default styles */\na:not([class]) {\n    text-decoration-skip-ink: auto;\n}\n\n/* Make images easier to work with */\nimg,\npicture {\n    max-width: 100%;\n    display: block;\n}\n\n/* Inherit fonts for inputs and buttons */\ninput,\nbutton,\ntextarea,\nselect {\n    font: inherit;\n}\n\n/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */\n@media (prefers-reduced-motion: reduce) {\n    html:focus-within {\n        scroll-behavior: auto;\n    }\n\n    *,\n    *::before,\n    *::after {\n        animation-duration: 0.01ms !important;\n        animation-iteration-count: 1 !important;\n        transition-duration: 0.01ms !important;\n        scroll-behavior: auto !important;\n    }\n}\n"
  },
  {
    "path": "examples/react-app/src/routes/root.tsx",
    "content": "import { Box, Code, Container, DataList, Flex, Heading, Spinner, Text } from '@radix-ui/themes';\nimport { useSelectedWalletAccount } from '@solana/react';\nimport { getUiWalletAccountStorageKey } from '@wallet-standard/react';\nimport { Suspense, useContext } from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\n\nimport { Balance } from '../components/Balance';\nimport { FeatureNotSupportedCallout } from '../components/FeatureNotSupportedCallout';\nimport { FeaturePanel } from '../components/FeaturePanel';\nimport { SlotIndicator } from '../components/SlotIndicator';\nimport { SolanaPartialSignTransactionFeaturePanel } from '../components/SolanaPartialSignTransactionFeaturePanel';\nimport { SolanaSignAndSendTransactionFeaturePanel } from '../components/SolanaSignAndSendTransactionFeaturePanel';\nimport { SolanaSignMessageFeaturePanel } from '../components/SolanaSignMessageFeaturePanel';\nimport { SolanaSignTransactionFeaturePanel } from '../components/SolanaSignTransactionFeaturePanel';\nimport { WalletAccountIcon } from '../components/WalletAccountIcon';\nimport { ChainContext } from '../context/ChainContext';\n\nfunction Root() {\n    const { chain } = useContext(ChainContext);\n    const [selectedWalletAccount] = useSelectedWalletAccount();\n    const errorBoundaryResetKeys = [\n        chain,\n        selectedWalletAccount && getUiWalletAccountStorageKey(selectedWalletAccount),\n    ].filter(Boolean);\n    const slotIndicator = (\n        <Flex direction=\"column\" align=\"end\">\n            <Heading as=\"h4\" size=\"3\">\n                Slot\n            </Heading>\n            <ErrorBoundary fallback={<Text>&ndash;</Text>} key={chain}>\n                <SlotIndicator />\n            </ErrorBoundary>\n        </Flex>\n    );\n    return (\n        <Container mx={{ initial: '3', xs: '6' }}>\n            {selectedWalletAccount ? (\n                <Flex gap=\"6\" direction=\"column\">\n                    <Flex gap=\"2\">\n                        <Flex align=\"center\" gap=\"3\" flexGrow=\"1\">\n                            <WalletAccountIcon account={selectedWalletAccount} height=\"48\" width=\"48\" />\n                            <Box>\n                                <Heading as=\"h4\" size=\"3\">\n                                    {selectedWalletAccount.label ?? 'Unlabeled Account'}\n                                </Heading>\n                                <Code variant=\"outline\" truncate size={{ initial: '1', xs: '2' }}>\n                                    {selectedWalletAccount.address}\n                                </Code>\n                            </Box>\n                        </Flex>\n                        <Flex gap=\"6\" align=\"end\">\n                            {slotIndicator}\n                            <Flex direction=\"column\" align=\"end\">\n                                <Heading as=\"h4\" size=\"3\">\n                                    Balance\n                                </Heading>\n                                <ErrorBoundary\n                                    fallback={<Text>&ndash;</Text>}\n                                    key={`${selectedWalletAccount.address}:${chain}`}\n                                >\n                                    <Suspense fallback={<Spinner loading my=\"1\" />}>\n                                        <Balance account={selectedWalletAccount} />\n                                    </Suspense>\n                                </ErrorBoundary>\n                            </Flex>\n                        </Flex>\n                    </Flex>\n                    <DataList.Root orientation={{ initial: 'vertical', sm: 'horizontal' }} size=\"3\">\n                        <FeaturePanel label=\"Sign Message\">\n                            <ErrorBoundary\n                                FallbackComponent={FeatureNotSupportedCallout}\n                                resetKeys={errorBoundaryResetKeys}\n                            >\n                                <SolanaSignMessageFeaturePanel account={selectedWalletAccount} />\n                            </ErrorBoundary>\n                        </FeaturePanel>\n                        <FeaturePanel label=\"Sign And Send Transaction\">\n                            <ErrorBoundary\n                                FallbackComponent={FeatureNotSupportedCallout}\n                                resetKeys={errorBoundaryResetKeys}\n                            >\n                                <SolanaSignAndSendTransactionFeaturePanel account={selectedWalletAccount} />\n                            </ErrorBoundary>\n                        </FeaturePanel>\n                        <FeaturePanel label=\"Sign Transaction\">\n                            <ErrorBoundary\n                                FallbackComponent={FeatureNotSupportedCallout}\n                                resetKeys={errorBoundaryResetKeys}\n                            >\n                                <SolanaSignTransactionFeaturePanel account={selectedWalletAccount} />\n                            </ErrorBoundary>\n                        </FeaturePanel>\n                        <FeaturePanel label=\"Partial Sign Transaction\">\n                            <ErrorBoundary\n                                FallbackComponent={FeatureNotSupportedCallout}\n                                resetKeys={errorBoundaryResetKeys}\n                            >\n                                <SolanaPartialSignTransactionFeaturePanel account={selectedWalletAccount} />\n                            </ErrorBoundary>\n                        </FeaturePanel>\n                    </DataList.Root>\n                </Flex>\n            ) : (\n                <Flex gap=\"6\" direction=\"column\">\n                    <Flex justify=\"end\">{slotIndicator}</Flex>\n                    <Text as=\"p\">Click &ldquo;Connect Wallet&rdquo; to get started.</Text>\n                </Flex>\n            )}\n        </Container>\n    );\n}\n\nexport default Root;\n"
  },
  {
    "path": "examples/react-app/src/signerBytes.json",
    "content": "[\n    220, 120, 88, 208, 87, 244, 238, 165, 90, 164, 136, 113, 27, 148, 169, 29, 21, 60, 86, 177, 76, 127, 211, 167, 247,\n    197, 252, 79, 54, 129, 133, 164, 245, 60, 248, 170, 228, 164, 94, 72, 61, 61, 38, 217, 24, 41, 169, 145, 19, 101,\n    146, 47, 59, 199, 9, 139, 92, 13, 33, 135, 34, 249, 98, 108\n]\n"
  },
  {
    "path": "examples/react-app/src/storage.ts",
    "content": "let storage: Storage | undefined;\ntry {\n    if (typeof window !== 'undefined' && window.localStorage) {\n        storage = window.localStorage;\n    }\n} catch {\n    /* empty */\n}\n\nfunction guard<TArgs extends unknown[], TReturn, TFallbackReturn>(\n    fn: (...args: TArgs) => TReturn,\n    fallbackReturn: TFallbackReturn,\n): (...args: TArgs) => TFallbackReturn | TReturn;\nfunction guard<TArgs extends unknown[], TReturn>(\n    fn: (...args: TArgs) => TReturn,\n): (...args: TArgs) => TReturn | undefined;\nfunction guard<TArgs extends unknown[], TReturn, TFallbackReturn>(\n    fn: (...args: TArgs) => TReturn,\n    fallbackReturn?: TFallbackReturn,\n): (...args: TArgs) => TFallbackReturn | TReturn | undefined {\n    return (...args) => {\n        try {\n            return fn(...args);\n        } catch (e) {\n            console.error(e);\n            return fallbackReturn;\n        }\n    };\n}\n\nexport const localStorage: Pick<Storage, 'getItem' | 'removeItem' | 'setItem'> = {\n    getItem: guard(k => {\n        return storage?.getItem(k) ?? null;\n    }, null),\n    removeItem: guard(k => {\n        storage?.removeItem(k);\n    }),\n    setItem: guard((k, v) => {\n        storage?.setItem(k, v);\n    }),\n};\n"
  },
  {
    "path": "examples/react-app/src/vite-env.d.ts",
    "content": "/// <reference types=\"vite/client\" />\n"
  },
  {
    "path": "examples/react-app/tsconfig.app.json",
    "content": "{\n    \"compilerOptions\": {\n        \"composite\": true,\n        \"tsBuildInfoFile\": \"./node_modules/.tmp/tsconfig.app.tsbuildinfo\",\n        \"target\": \"ES2020\",\n        \"useDefineForClassFields\": true,\n        \"lib\": [\"ES2020\", \"DOM\", \"DOM.Iterable\"],\n        \"module\": \"ESNext\",\n        \"skipLibCheck\": true,\n\n        /* Bundler mode */\n        \"moduleResolution\": \"bundler\",\n        \"allowImportingTsExtensions\": true,\n        \"resolveJsonModule\": true,\n        \"isolatedModules\": true,\n        \"moduleDetection\": \"force\",\n        \"noEmit\": true,\n        \"jsx\": \"react-jsx\",\n\n        /* Linting */\n        \"strict\": true,\n        \"noUnusedLocals\": true,\n        \"noUnusedParameters\": true,\n        \"noFallthroughCasesInSwitch\": true\n    },\n    \"include\": [\"./eslint.config.mjs\", \"src\"]\n}\n"
  },
  {
    "path": "examples/react-app/tsconfig.json",
    "content": "{\n    \"files\": [],\n    \"references\": [\n        {\n            \"path\": \"./tsconfig.app.json\"\n        },\n        {\n            \"path\": \"./tsconfig.node.json\"\n        }\n    ]\n}\n"
  },
  {
    "path": "examples/react-app/tsconfig.node.json",
    "content": "{\n    \"compilerOptions\": {\n        \"composite\": true,\n        \"tsBuildInfoFile\": \"./node_modules/.tmp/tsconfig.node.tsbuildinfo\",\n        \"skipLibCheck\": true,\n        \"module\": \"ESNext\",\n        \"moduleResolution\": \"bundler\",\n        \"allowSyntheticDefaultImports\": true,\n        \"strict\": true,\n        \"noEmit\": true\n    },\n    \"include\": [\"vite.config.ts\"]\n}\n"
  },
  {
    "path": "examples/react-app/vite.config.ts",
    "content": "import react from '@vitejs/plugin-react-swc';\nimport { defineConfig, Plugin } from 'vite';\n\nfunction replaceProcessEnv(mode: string): Plugin {\n    const nodeEnvRegex = /process(\\.env(\\.NODE_ENV)|\\[\"env\"\\]\\.NODE_ENV)/g;\n    return {\n        name: 'replace-process-env',\n        renderChunk(code) {\n            return code.replace(nodeEnvRegex, JSON.stringify(mode));\n        },\n    };\n}\n\n// https://vitejs.dev/config/\nexport default defineConfig(({ mode }) => ({\n    base: process.env.REACT_EXAMPLE_APP_BASE_PATH,\n    define: {\n        'process.env': process.env,\n    },\n    plugins: [react(), replaceProcessEnv(mode)],\n}));\n"
  },
  {
    "path": "examples/rpc-custom-api/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/rpc-custom-api/package.json",
    "content": "{\n    \"name\": \"@solana/example-rpc-custom-api\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"scripts\": {\n        \"prestart\": \"turbo --output-logs=errors-only compile:js compile:typedefs\",\n        \"start\": \"tsx src/example.ts\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent --testMatch '<rootDir>src/**/*.{ts,tsx}'\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc\"\n    },\n    \"dependencies\": {\n        \"@solana/example-utils\": \"workspace:*\",\n        \"@solana/kit\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"tsx\": \"^4.21.0\"\n    }\n}\n"
  },
  {
    "path": "examples/rpc-custom-api/src/example.ts",
    "content": "/**\n * EXAMPLE\n * Add a custom JSON RPC method to the base Solana JSON RPC API using @solana/kit.\n *\n * To run this example, execute `pnpm start` in this directory.\n */\nimport { createLogger } from '@solana/example-utils/createLogger.js';\nimport {\n    Address,\n    address,\n    createDefaultRpcTransport,\n    createRpc,\n    createRpcMessage,\n    createSolanaRpcApi,\n    DEFAULT_RPC_CONFIG,\n    mainnet,\n    RpcApi,\n    RpcPlan,\n    SolanaRpcApiMainnet,\n} from '@solana/kit';\n\nconst log = createLogger('Custom JSON RPC API');\n\n/**\n * STEP 1: CUSTOM JSON RPC API CALL SIGNATURE\n * Define the call signature of the custom API. For this example we will use the Triton One\n * `getAsset` API, available on the public mainnet RPC server.\n * https://docs.triton.one/digital-assets-api/metaplex-digital-assets-api/get-asset\n */\ntype AssetMetadata = Readonly<{\n    description: string;\n    name: string;\n    symbol: string;\n}>;\ntype TritonGetAssetApi = {\n    /**\n     * Define the ideal developer-facing API as a TypeScript type. Doing so will enable typechecking\n     * and autocompletion for it on the RPC instance.\n     */\n    getAssetMetadata(address: Address): AssetMetadata;\n};\n\n/**\n * STEP 2: CUSTOM JSON RPC API IMPLEMENTATION\n * Create an instance of the default JSON RPC API, then create a wrapper around it to intercept\n * calls for custom API methods. The wrapper should format the inputs to satisfy the API of the JSON\n * RPC server, and post-process the server response to satisfy the call signature defined above.\n */\nconst solanaRpcApi = createSolanaRpcApi<SolanaRpcApiMainnet>(DEFAULT_RPC_CONFIG);\n/**\n * Create a proxy that wraps the Solana RPC API and adds extra functionality.\n */\nconst customizedRpcApi = new Proxy(solanaRpcApi, {\n    defineProperty() {\n        return false;\n    },\n    deleteProperty() {\n        return false;\n    },\n    get(target, p, receiver): (address: Address) => RpcPlan<AssetMetadata> {\n        const methodName = p.toString();\n        if (methodName === 'getAssetMetadata') {\n            /**\n             * When the `getAssetMetadata` method is called on the RPC, return a custom definition.\n             */\n            return address => {\n                const request = {\n                    /**\n                     * If the JSON RPC API method is named differently than the method exposed on\n                     * the custom API, supply it here.\n                     */\n                    methodName: 'getAsset',\n                    /**\n                     * When the params that the JSON RPC API expects are formatted differently than\n                     * the arguments to the method exposed on the custom API, reformat them here.\n                     */\n                    params: { id: address },\n                };\n                return {\n                    execute: async ({ signal, transport }) => {\n                        const response: { result: { content: { metadata: AssetMetadata } } } = await transport({\n                            payload: createRpcMessage(request),\n                            signal,\n                        });\n                        /**\n                         * When the return type of the method exposed on the custom API has a different\n                         * shape than the result returned from the JSON RPC API, supply a transform.\n                         */\n                        return response.result.content.metadata;\n                    },\n                };\n            };\n        } else {\n            /**\n             * If the method called is not a custom one, delegate to the original implementation.\n             */\n            return Reflect.get(target, p, receiver);\n        }\n    },\n}) as RpcApi<SolanaRpcApiMainnet & TritonGetAssetApi>; // Cast to a type that is a mix of both APIs.\n\n/**\n * STEP 3: RPC CONNECTION\n * Combine the custom RPC API with a default JSON RPC transport to create an RPC instance.\n */\nconst customizedRpc = createRpc({\n    api: customizedRpcApi,\n    transport: createDefaultRpcTransport({ url: mainnet('https://api.mainnet-beta.solana.com') }),\n});\n\n/**\n * STEP 4: USE THE DEFAULT API\n * Test that the base API still works by calling a Solana RPC API method like `getLatestBlockhash`.\n */\nconst { value: latestBlockhash } = await customizedRpc.getLatestBlockhash().send();\nlog.info(latestBlockhash, '[step 1] Solana RPC methods like `getLatestBlockhash` still work');\n\n/**\n * STEP 5: USE THE CUSTOM API\n * Test the custom `getAssetMetadata` method.\n */\nconst metadata = await customizedRpc.getAssetMetadata(address('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v')).send();\nlog.info({ metadata }, '[step 2] The custom `getAssetMetadata` that we implemented also works');\n"
  },
  {
    "path": "examples/rpc-custom-api/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"module\": \"NodeNext\",\n        \"moduleResolution\": \"NodeNext\",\n        \"noEmit\": true,\n        \"target\": \"ESNext\"\n    },\n    \"display\": \"@solana/example-rpc-custom-api\",\n    \"extends\": \"../../packages/tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "examples/rpc-transport-throttled/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/rpc-transport-throttled/package.json",
    "content": "{\n    \"name\": \"@solana/example-rpc-transport-throttled\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"scripts\": {\n        \"prestart\": \"turbo --output-logs=errors-only compile:js compile:typedefs\",\n        \"run:example\": \"tsx src/example.ts\",\n        \"start\": \"start-server-and-test '../../scripts/start-shared-test-validator.sh' http://127.0.0.1:8899/health run:example\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent --testMatch '<rootDir>src/**/*.{ts,tsx}'\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc\"\n    },\n    \"dependencies\": {\n        \"@solana/example-utils\": \"workspace:*\",\n        \"@solana/kit\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"start-server-and-test\": \"^2.1.5\",\n        \"tsx\": \"^4.21.0\"\n    }\n}\n"
  },
  {
    "path": "examples/rpc-transport-throttled/src/example.ts",
    "content": "/**\n * EXAMPLE\n * Create a custom RPC transport that will only send a certain number of requests per second.\n *\n * Before running any of the examples in this monorepo, make sure to set up a test validator by\n * running `pnpm test:setup` in the root directory.\n *\n * To run this example, execute `pnpm start` in this directory.\n */\nimport { createLoggerWithTimestamp } from '@solana/example-utils/createLogger.js';\nimport {\n    ClusterUrl,\n    createDefaultRpcTransport,\n    createSolanaRpcFromTransport,\n    mainnet,\n    RpcTransportFromClusterUrl,\n} from '@solana/kit';\n\nconst log = createLoggerWithTimestamp('Throttling transport');\n\n/**\n * SETUP: Define the maximum requests-per-second this RPC should make.\n */\nconst MAX_RPS = 2;\n\n/**\n * STEP 1: CUSTOM THROTTLING TRANSPORT\n * Create a function that will wrap an existing transport to implement rate-limiting logic. The\n * wrapper should delegate calls to the underlying transport as and when appropriate.\n */\ntype QueuedRequest<TClusterUrl extends ClusterUrl> = Readonly<{\n    config: Parameters<RpcTransportFromClusterUrl<TClusterUrl>>[0];\n    reject: (reason?: unknown) => void;\n    requestNumber: number;\n    resolve: (value: unknown) => void;\n}>;\nfunction getThrottledTransport<TClusterUrl extends ClusterUrl>(\n    originalTransport: RpcTransportFromClusterUrl<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n    /**\n     * Keep track of how many more requests are allowed to be made in the current 1 second span.\n     */\n    let requestBudgetRemaining = MAX_RPS;\n    /**\n     * When the first request is made, schedule a reset of the request budget for 1 second from now,\n     * and store the timer of that scheduled reset here.\n     */\n    let pendingQueueRunTimerId: NodeJS.Timeout | undefined;\n    /**\n     * Keep a queue of requests and resolve/reject functions.\n     */\n    const queuedRequests: QueuedRequest<TClusterUrl>[] = [];\n    function processQueue() {\n        if (requestBudgetRemaining === 0) {\n            return;\n        }\n        log.debug({ numQueuedRequests: queuedRequests.length }, '[transport] Processing request queue');\n        while (queuedRequests.length && requestBudgetRemaining > 0) {\n            const request = queuedRequests.shift()!;\n            log.debug({ requestBudgetRemaining }, '[transport] Processing request %d', request.requestNumber);\n            if (request.config.signal?.aborted) {\n                log.debug('[transport] Skipping aborted request %d', request.requestNumber);\n                continue;\n            }\n            log.debug('[transport] Starting request %d', request.requestNumber);\n            /**\n             * When a request's slot comes up, delegate it to the underlying transport.\n             */\n            originalTransport(request.config).then(request.resolve).catch(request.reject);\n            requestBudgetRemaining--;\n            if (pendingQueueRunTimerId === undefined) {\n                log.debug('[transport] Setting request budget reset deadline for 1 second from now');\n                pendingQueueRunTimerId = setTimeout(() => {\n                    log.debug('[transport] Replenishing request budget');\n                    pendingQueueRunTimerId = undefined;\n                    requestBudgetRemaining = MAX_RPS;\n                    processQueue();\n                }, 1_000 /* 1 second */);\n            }\n        }\n    }\n    let requestCount = 0;\n    return function throttlingTransport(config) {\n        /**\n         * Whenever the throttling transport is called, return a promise for the response, to be\n         * resolved by the rate-limiting request queue processor.\n         */\n        return new Promise((resolve, reject) => {\n            queuedRequests.push({\n                config,\n                reject,\n                requestNumber: ++requestCount,\n                resolve,\n            } as QueuedRequest<TClusterUrl>);\n            if (config.signal) {\n                config.signal.addEventListener('abort', function () {\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n                    reject(this.reason);\n                });\n            }\n            processQueue();\n        });\n    } as RpcTransportFromClusterUrl<TClusterUrl>;\n}\n\n/**\n * STEP 2: RPC CONNECTION WITH CUSTOM TRANSPORT\n * Create a default RPC transport, wrap it in a throttled transport, then create a Solana RPC\n * instance from the resulting transport.\n */\nconst defaultTransport = createDefaultRpcTransport({\n    url: mainnet('https://api.mainnet-beta.solana.com'),\n});\nconst throttledTransport = getThrottledTransport(defaultTransport);\nconst throttledRpc = createSolanaRpcFromTransport(throttledTransport);\n\n/**\n * STEP 3: MAKE 11 REQUESTS AT THE SAME TIME; CANCEL THE 8TH BEFORE IT STARTS\n * Verify using the logs that only two requests are made in any 1 second span of time, and that\n * the aborted request that has yet to be made gets skipped when its slot comes up.\n */\nfor (let ii = 1; ii <= 11; ii++) {\n    let abortSignal;\n    if (ii === 8) {\n        // Set the 8th request to be aborted after 2.5 seconds; before it gets made.\n        const abortController = new AbortController();\n        abortSignal = abortController.signal;\n        setTimeout(() => {\n            log.debug('Aborting request 8');\n            abortController.abort('Request 8 was aborted');\n        }, 2_500 /* 2.5 seconds */);\n    }\n    throttledRpc\n        .getLatestBlockhash()\n        .send({ abortSignal })\n        .then(({ value }) => log.info(value, 'Request %d succeeded', ii))\n        .catch(error => log.error({ error }, 'Request %d failed', ii));\n}\n"
  },
  {
    "path": "examples/rpc-transport-throttled/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"module\": \"NodeNext\",\n        \"moduleResolution\": \"NodeNext\",\n        \"noEmit\": true,\n        \"target\": \"ESNext\"\n    },\n    \"display\": \"@solana/example-rpc-transport-throttled\",\n    \"extends\": \"../../packages/tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "examples/signers/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/signers/package.json",
    "content": "{\n    \"name\": \"@solana/example-signers\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"scripts\": {\n        \"prestart\": \"turbo --output-logs=errors-only compile:js compile:typedefs\",\n        \"run:example\": \"tsx src/example.ts\",\n        \"start\": \"pnpm run:example\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent --testMatch '<rootDir>src/**/*.{ts,tsx}'\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc\"\n    },\n    \"dependencies\": {\n        \"@solana-program/system\": \"^0.12.0\",\n        \"@solana/example-utils\": \"workspace:*\",\n        \"@solana/kit\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"start-server-and-test\": \"^2.1.5\",\n        \"tsx\": \"^4.21.0\"\n    }\n}\n"
  },
  {
    "path": "examples/signers/src/example-keypair.json",
    "content": "[\n    107, 145, 66, 123, 253, 251, 77, 186, 176, 211, 187, 232, 47, 142, 54, 214, 142, 152, 37, 182, 65, 117, 85, 75, 133,\n    97, 107, 11, 180, 24, 73, 245, 160, 114, 3, 57, 51, 114, 113, 153, 78, 211, 199, 86, 240, 220, 223, 19, 254, 107,\n    250, 11, 190, 31, 112, 13, 15, 146, 198, 211, 48, 140, 218, 239\n]\n"
  },
  {
    "path": "examples/signers/src/example.ts",
    "content": "/**\n * EXAMPLE\n * Create and use signers with @solana/kit.\n *\n * Before running any of the examples in this monorepo, make sure to set up a test validator by\n * running `pnpm test:setup` in the root directory.\n *\n * To run this example, execute `pnpm start` in this directory.\n */\nimport { createLogger } from '@solana/example-utils/createLogger.js';\nimport {\n    address,\n    appendTransactionMessageInstruction,\n    assertIsTransactionWithinSizeLimit,\n    Blockhash,\n    compileTransaction,\n    createKeyPairSignerFromBytes,\n    createKeyPairSignerFromPrivateKeyBytes,\n    createNoopSigner,\n    createSignableMessage,\n    createTransactionMessage,\n    generateKeyPairSigner,\n    getBase58Decoder,\n    MessagePartialSigner,\n    partiallySignTransactionMessageWithSigners,\n    pipe,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithLifetime,\n    TransactionPartialSigner,\n    TransactionSigner,\n} from '@solana/kit';\nimport { getTransferSolInstruction } from '@solana-program/system';\nimport { readFile } from 'fs/promises';\nimport path from 'path';\n\nconst log = createLogger('Signers');\n\n/**\n * SETUP: CREATE A NEW TRANSACTION MESSAGE\n * This helper function creates a new transaction message for us such that:\n * - Its lifetime is set to the latest blockhash.\n * - Its fee payer is set to the given signer.\n * - It contains a single instruction to transfer 1 SOL to some other address.\n *\n * You can read more about this transaction and how to send it\n * in the `examples/transfer-lamports` example.\n */\nfunction getTransferSolTransactionMessage(signer: TransactionSigner) {\n    // Create the transfer SOL instruction by passing the signer as the source.\n    const instruction = getTransferSolInstruction({\n        amount: 1n,\n        destination: address('ED1WqT2hWJLSZtj4TtTdoovmpMrr7zpkUdbfxmcJR1Fq'),\n        source: signer, // <- We pass the signer here, not just the address.\n    });\n\n    // Use a mock blockhash as a transaction lifetime constraint.\n    const mockBlockhash = {\n        blockhash: '9fBfi7Q23LHd6gDENDhp25jRnzeGJZesAtCkKuqkga63' as Blockhash,\n        lastValidBlockHeight: 1119n,\n    };\n\n    // Prepare the transaction message.\n    return pipe(\n        createTransactionMessage({ version: 0 }),\n        tx => setTransactionMessageLifetimeUsingBlockhash(mockBlockhash, tx),\n        tx => setTransactionMessageFeePayerSigner(signer, tx), // <- Here as well, we provide the payer as a signer.\n        tx => appendTransactionMessageInstruction(instruction, tx),\n    );\n}\n\n/**\n * SETUP: SIGN A MESSAGE\n * This helper function signs a message using the given signer.\n */\nasync function signMessage(signer: MessagePartialSigner, message: string) {\n    const [signatureDictionary] = await signer.signMessages([createSignableMessage(message)]);\n    const signature = signatureDictionary[signer.address];\n    log.info(\n        { signature: signature ? getBase58Decoder().decode(signature) : null },\n        `>>  Signing the message \"${message}\"`,\n    );\n}\n\n/**\n * SETUP: SIGN A TRANSACTION\n * This helper function signs a transaction message using the given signer.\n */\nasync function signTransaction(\n    signer: TransactionPartialSigner,\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime,\n) {\n    const transaction = compileTransaction(transactionMessage);\n    assertIsTransactionWithinSizeLimit(transaction);\n    const [signatureDictionary] = await signer.signTransactions([transaction]);\n    const signature = signatureDictionary[signer.address];\n    log.info(\n        { signature: signature ? getBase58Decoder().decode(signature) : null },\n        '>>  Signing a transfer SOL transaction',\n    );\n}\n\n/**\n * SETUP: SIGN A TRANSACTION USING REGISTERED SIGNERS\n * This helper function signs a transaction message by retrieving\n * the signers registered within the transaction message.\n * For instance, in our transfer SOL transaction message, we can\n * extract the fee payer and the transfer source as signers.\n */\nasync function signTransactionWithSigners(\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime,\n) {\n    const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n    const signature = signedTransaction.signatures[transactionMessage.feePayer.address];\n    log.info(\n        { signature: signature ? getBase58Decoder().decode(signature) : null },\n        '>>  Signing a transfer SOL transaction using its registered signers',\n    );\n}\n\n/**\n * OPTION 1: GENERATED KEY PAIR SIGNER\n * With this option, we generate a brand new key pair\n * and wrap it in a signer object.\n */\n{\n    // Generate a new key pair signer.\n    const signer = await generateKeyPairSigner();\n    log.info({ address: signer.address }, '[option 1] Using a generated key pair signer');\n\n    // Use it to sign messages and transactions.\n    const transactionMessage = getTransferSolTransactionMessage(signer);\n    await signMessage(signer, 'Hello, World!');\n    await signTransaction(signer, transactionMessage);\n    await signTransactionWithSigners(transactionMessage);\n}\n\n/**\n * OPTION 2: KEY PAIR SIGNER FROM FILE\n * With this option, we load the content of the key pair\n * from a JSON file and wrap it in a signer object.\n */\n{\n    // Load a key pair signer from a JSON file.\n    const keypairPath = path.join('src', 'example-keypair.json');\n    const keypairBytes = new Uint8Array(JSON.parse(await readFile(keypairPath, 'utf-8')));\n    const signer = await createKeyPairSignerFromBytes(keypairBytes);\n    log.info({ address: signer.address }, '[option 2] Using a key pair signer from a JSON file');\n\n    // Use it to sign messages and transactions.\n    const transactionMessage = getTransferSolTransactionMessage(signer);\n    await signMessage(signer, 'Hello, World!');\n    await signTransaction(signer, transactionMessage);\n    await signTransactionWithSigners(transactionMessage);\n}\n\n/**\n * OPTION 3: KEY PAIR SIGNER FROM SEED\n * With this option, we derive a key pair from a seed —\n * i.e. the 32 bytes of its private key — and wrap it\n * in a signer object.\n */\n{\n    // Access the 32 bytes of the private key.\n    // Note that this is the first 32 bytes of the `example-keypair.json` file,\n    // Meaning we will get the same signatures as in the previous example.\n    const seed = new Uint8Array([\n        107, 145, 66, 123, 253, 251, 77, 186, 176, 211, 187, 232, 47, 142, 54, 214, 142, 152, 37, 182, 65, 117, 85, 75,\n        133, 97, 107, 11, 180, 24, 73, 245,\n    ]);\n\n    // Create a key pair signer using this private key seed.\n    const signer = await createKeyPairSignerFromPrivateKeyBytes(seed);\n    log.info({ address: signer.address }, '[option 3] Using a key pair signer from a seed');\n\n    // Use it to sign messages and transactions.\n    const transactionMessage = getTransferSolTransactionMessage(signer);\n    await signMessage(signer, 'Hello, World!');\n    await signTransaction(signer, transactionMessage);\n    await signTransactionWithSigners(transactionMessage);\n}\n\n/**\n * OPTION 4: NOOP SIGNER\n * With this option, we create a no-operation signer that pretends\n * sign messages and transactions without actually doing so.\n * This can be useful when a function requires a signer object but\n * we don't actually want to sign anything at this point.\n * For instance, we can use it to create a transaction with a\n * server-side fee payer that will be signed by the server later on.\n */\n{\n    // Create a no-op signer.\n    const signer = createNoopSigner(address('BoK4mWeYVU6LdgNfo8QF7zxmTRiHw7VKMhodToZgrRup'));\n    log.info({ address: signer.address }, '[option 4] Using a no-op signer');\n\n    // Use it to sign messages and transactions.\n    const transactionMessage = getTransferSolTransactionMessage(signer);\n    await signMessage(signer, 'Hello, World!');\n    await signTransaction(signer, transactionMessage);\n    await signTransactionWithSigners(transactionMessage);\n}\n"
  },
  {
    "path": "examples/signers/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"module\": \"NodeNext\",\n        \"moduleResolution\": \"NodeNext\",\n        \"noEmit\": true,\n        \"target\": \"ESNext\"\n    },\n    \"display\": \"@solana/example-signers\",\n    \"extends\": \"../../packages/tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "examples/token-airdrop/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/token-airdrop/package.json",
    "content": "{\n    \"name\": \"@solana/example-token-airdrop\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"scripts\": {\n        \"prestart\": \"turbo --output-logs=errors-only compile:js compile:typedefs\",\n        \"run:example\": \"tsx src/example.ts\",\n        \"start\": \"start-server-and-test '../../scripts/start-shared-test-validator.sh' http://127.0.0.1:8899/health run:example\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent --testMatch '<rootDir>src/**/*.{ts,tsx}'\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc\"\n    },\n    \"dependencies\": {\n        \"@solana-program/system\": \"^0.12.0\",\n        \"@solana-program/token\": \"^0.13.0\",\n        \"@solana/example-utils\": \"workspace:*\",\n        \"@solana/kit\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"start-server-and-test\": \"^2.1.5\",\n        \"tsx\": \"^4.21.0\"\n    }\n}\n"
  },
  {
    "path": "examples/token-airdrop/src/example.ts",
    "content": "/**\n * EXAMPLE\n * Create a new token mint and airdrop it to 100 recipients.\n *\n * Before running any of the examples in this monorepo, make sure to set up a test validator by\n * running `pnpm test:setup` in the root directory.\n *\n * To run this example, execute `pnpm start` in this directory.\n */\nimport { createLogger } from '@solana/example-utils/createLogger.js';\nimport pressAnyKeyPrompt from '@solana/example-utils/pressAnyKeyPrompt.js';\nimport {\n    assertIsTransactionWithBlockhashLifetime,\n    createKeyPairSignerFromBytes,\n    createSolanaRpc,\n    createSolanaRpcSubscriptions,\n    createTransactionMessage,\n    createTransactionPlanExecutor,\n    createTransactionPlanner,\n    estimateAndSetComputeUnitLimitFactory,\n    estimateComputeUnitLimitFactory,\n    fillTransactionMessageProvisoryComputeUnitLimit,\n    generateKeyPairSigner,\n    getSignatureFromTransaction,\n    parallelInstructionPlan,\n    pipe,\n    sendAndConfirmTransactionFactory,\n    sequentialInstructionPlan,\n    setTransactionMessageComputeUnitPrice,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signTransactionMessageWithSigners,\n    TransactionPlan,\n} from '@solana/kit';\nimport { getCreateMintInstructionPlan, getMintToATAInstructionPlanAsync } from '@solana-program/token';\n\nconst log = createLogger('Token Airdrop');\n\n/**\n * SETUP: SOURCE ACCOUNT\n * The account that will pay for the airdrop needs to sign the transaction. We need to\n * create a `TransactionSigner` for it. You can find the account this key relates to in the test\n * validator fixtures in `/scripts/fixtures/example-transfer-sol-source-account.json`\n */\nconst SOURCE_ACCOUNT_SIGNER = await createKeyPairSignerFromBytes(\n    /**\n     * These are the bytes that we saved at the time this account's key pair was originally\n     * generated. Here, they are inlined into the source code, but you can also imagine them being\n     * loaded from disk or, better yet, read from an environment variable.\n     */\n    new Uint8Array(\n        // prettier-ignore\n        [2, 194, 94, 194, 31, 15, 34, 248, 159, 9, 59, 156, 194, 152, 79, 148, 81, 17, 63, 53, 245, 175, 37, 0, 134, 90, 111, 236, 245, 160, 3, 50, 196, 59, 123, 60, 59, 151, 65, 255, 27, 247, 241, 230, 52, 54, 143, 136, 108, 160, 7, 128, 4, 14, 232, 119, 234, 61, 47, 158, 9, 241, 48, 140],\n    ), // Address: ED1WqT2hWJLSZtj4TtTdoovmpMrr7zpkUdbfxmcJR1Fq\n);\nlog.info({ address: SOURCE_ACCOUNT_SIGNER.address }, '[setup] Loaded key pair for source account');\n\n/**\n * SETUP: RPC CONNECTION\n * When it comes time to send our transaction to the Solana network for execution, we will do so\n * through a remote procedure call (RPC) server. This example uses your local test validator which\n * must be running before you run this script.\n */\nconst rpc = createSolanaRpc('http://127.0.0.1:8899');\nconst rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');\n\n/**\n * SETUP: DESTINATION ACCOUNTS\n * We will generate 100 new random accounts to receive the airdropped tokens.\n * In a real world scenario, these would be the addresses you want to airdrop tokens to.\n */\nconst destinationAddresses = await Promise.all(\n    Array.from({ length: 100 }, async () => {\n        const signer = await generateKeyPairSigner();\n        return signer.address;\n    }),\n);\nlog.info('[setup] Generated 100 destination account addresses');\n\n/**\n * TOKEN MINT ADDRESS\n * We will create a new token mint for this airdrop.\n * Note that the new mint must sign the transaction that initializes it.\n */\nconst tokenMint = await generateKeyPairSigner();\nlog.info({ address: tokenMint.address }, '[setup] Generated token mint address');\n\n/**\n * CREATE TRANSACTION PLANNER\n * A transaction planner is responsible for providing the structure of how transaction messages are built.\n */\nconst transactionPlanner = createTransactionPlanner({\n    /**\n     * This function is called each time the transaction planner needs to create a new transaction message.\n     * It determines the base structure of the transaction message before any instructions are added to it.\n     * Note that this function can also be async if necessary\n     * Also note that the returned transaction message does not need to be ready to sign at this stage,\n     * in this case we are not setting any transaction lifetime at this stage.\n     */\n    createTransactionMessage() {\n        return pipe(\n            createTransactionMessage({ version: 0 }),\n            // Set the fee payer to the source account\n            tx => setTransactionMessageFeePayer(SOURCE_ACCOUNT_SIGNER.address, tx),\n            /**\n             * Compute Program Instructions\n             * In this example we are setting a fixed Compute Unit (CU) price of 100 microlamports/CU.\n             */\n            tx => setTransactionMessageComputeUnitPrice(100n, tx),\n            /**\n             * We are also adding a provisory CU limit. At this point we don't know what\n             * instructions will be added to the transaction, so we don't know what the CU limit\n             * will be. The CU limit will be updated later by the transaction executor.\n             * The transaction planner is going to add as many instructions as possible to each\n             * transaction, so we may not be able to add instructions later in the transaction\n             * executor. By using the provisory limit, we ensure that there is always space for\n             * the CU limit.\n             */\n            tx => fillTransactionMessageProvisoryComputeUnitLimit(tx),\n        );\n    },\n});\n\n/**\n * SETUP: TRANSACTION SENDER\n * We use the RPC connection that we created earlier to build a reusable transaction sender.\n */\nconst sendAndConfirmTransaction = sendAndConfirmTransactionFactory({\n    /**\n     * The RPC implements a `sendTransaction` method which relays transactions to the network.\n     */\n    rpc,\n    /**\n     * RPC subscriptions allow the transaction sender to subscribe to the status of our transaction.\n     * The sender will resolve when the transaction is reported to have been confirmed, or will\n     * reject in the event of an error, or a timeout if the transaction lifetime is thought to have\n     * expired.\n     */\n    rpcSubscriptions,\n});\n\n/**\n * CU LIMIT ESTIMATOR\n * We create a compute unit limit estimator which will be used by the transaction executor to\n * estimate the CU limit for each transaction message before sending it.\n * It does this by simulating the transaction message using the RPC we created earlier.\n */\nconst estimateCULimit = estimateComputeUnitLimitFactory({ rpc });\n// We multiply the simulated limit by 1.1 to add a 10% buffer\nasync function estimateWithMultiplier(...args: Parameters<typeof estimateCULimit>): Promise<number> {\n    const estimate = await estimateCULimit(...args);\n    return Math.ceil(estimate * 1.1);\n}\n/**\n * This helper will take the estimate and use it to update the provisory CU limit\n * that we included in the planner base transaction message.\n */\nconst estimateAndSetCULimit = estimateAndSetComputeUnitLimitFactory(estimateWithMultiplier);\n\n/**\n * TRANSACTION EXECUTOR\n * The transaction executor is responsible for executing the transaction plan created by the\n * transaction planner.\n */\nconst transactionExecutor = createTransactionPlanExecutor({\n    /**\n     * This function is called to actually execute each transaction message created by the transaction planner.\n     * It is responsible for signing, sending, and confirming the transaction message.\n     * It only needs to deal with one transaction message.\n     */\n    async executeTransactionMessage(context, message, config) {\n        const abortSignal = config ? config.abortSignal : undefined;\n\n        /**\n         * We fetch the latest blockhash at this point, so that it is the latest possible\n         * when the transaction is sent.\n         */\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash().send({ abortSignal });\n        const updatedMessage = await pipe(\n            message,\n            tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n            /**\n             * We use the helper that we created to estimate and set the CU limit.\n             * This returns an updated transaction message with the CU limit set.\n             * Recall that this replaces the provisory CU limit that was added in the planner.\n             */\n            tx => estimateAndSetCULimit(tx, { abortSignal }),\n        );\n\n        // Store the updated message in the context for potential error handling.\n        context.message = updatedMessage;\n\n        // Sign this updated transaction message with any signers included in its instructions\n        const signedTransaction = await signTransactionMessageWithSigners(updatedMessage, { abortSignal });\n\n        const signature = getSignatureFromTransaction(signedTransaction);\n        log.info({ signature }, `[transaction executor] Sending transaction`);\n\n        // Store the signed transaction and its signature in the context for potential error handling.\n        context.transaction = signedTransaction;\n        context.signature = signature;\n\n        // Send and confirm the transaction using the helper we created earlier\n        assertIsTransactionWithBlockhashLifetime(signedTransaction);\n        await sendAndConfirmTransaction(signedTransaction, { abortSignal, commitment: 'confirmed' });\n        log.info(\n            { signature },\n            `[transaction executor] Transaction confirmed: https://explorer.solana.com/tx/${signature}?cluster=custom&customUrl=127.0.0.1:8899`,\n        );\n        return signedTransaction;\n    },\n});\n\n/**\n * CREATE INSTRUCTION PLAN\n * An instruction plan describes all of the instructions that need to be executed.\n * These instructions will be grouped into transaction messages by the transaction planner\n * and executed by the transaction executor.\n * At this point none of the instructions are being executed, we are just defining the instructions that\n * will be executed.\n *\n * In this example, we are creating a new mint, and then airdropping it to the 100 destination addresses.\n *\n * Instruction plans can be sequential or parallel, and can be nested.\n * In this case, we need to create the new mint before we can mint tokens to the destination addresses.\n * But we can mint to all destination addresses in parallel.\n */\nconst instructionPlan = sequentialInstructionPlan([\n    /**\n     * This helper returns an instruction plan including all the instructions necessary to create a mint.\n     * It is itself a `SequentialInstructionPlan`.\n     */\n    getCreateMintInstructionPlan({\n        decimals: 6,\n        mintAuthority: SOURCE_ACCOUNT_SIGNER.address,\n        newMint: tokenMint,\n        payer: SOURCE_ACCOUNT_SIGNER,\n    }),\n    // Here we mint to all destination addresses in parallel\n    parallelInstructionPlan(\n        /**\n         * When we mint tokens for a destination address, we mint them to the associated token account (ATA)\n         * for that address. This helper returns an instruction plan to mint to the ATA, creating it on-chain\n         * first if it does not already exist.\n         *\n         * It is async because it first derives the address of the ATA for us.\n         * We can do this in parallel for all destination addresses, using `Promise.all`.\n         *\n         * We then pass these instruction plans to `parallelInstructionPlan`, as we will later execute these\n         * instructions for all destination addresses in parallel.\n         *\n         * Note that again the returned instruction plan is itself a `SequentialInstructionPlan`.\n         */\n        await Promise.all(\n            destinationAddresses.map(address =>\n                getMintToATAInstructionPlanAsync({\n                    amount: 1_000_000_000n,\n                    // 1,000 tokens, with 6 decimals\n                    decimals: 6,\n\n                    mint: tokenMint.address,\n\n                    mintAuthority: SOURCE_ACCOUNT_SIGNER,\n\n                    owner: address,\n                    payer: SOURCE_ACCOUNT_SIGNER,\n                }),\n            ),\n        ),\n    ),\n]);\n\n/**\n * CREATE TRANSACTION PLAN\n * Now that we have the instruction plan, we can create a transaction plan using the\n * transaction planner that we created earlier.\n * This creates actual transaction messages using the instructions defined in the instruction\n * plan, and the `createTransactionPlan` function of the planner.\n *\n * Under the hood, the created transaction plan has a similar structure to the instruction plan.\n * Ours will look something like this:\n *\n * SequentialTransactionPlan(\n *     First Transaction: create the mint, plus as many airdrops as will fit,\n *     ParallelTransactionPlan(\n *        Second Transaction: remaining airdrops that didn't fit in the first,\n *        Third Transaction: remaining airdrops that didn't fit in the first,\n *        ...\n *     )\n * )\n *\n */\nconst transactionPlan: TransactionPlan = await transactionPlanner(instructionPlan);\n\n/**\n * EXECUTE TRANSACTION PLAN\n * Finally, we can execute the transaction plan using the transaction executor that we created earlier.\n * This will execute all of the transaction messages created by the transaction planner,\n * using the `executeTransactionPlan` function of the executor.\n */\nawait transactionExecutor(transactionPlan);\n\nawait pressAnyKeyPrompt('Press any key to quit');\n"
  },
  {
    "path": "examples/token-airdrop/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"module\": \"NodeNext\",\n        \"moduleResolution\": \"NodeNext\",\n        \"noEmit\": true,\n        \"target\": \"ESNext\"\n    },\n    \"display\": \"@solana/example-transfer-lamports\",\n    \"extends\": \"../../packages/tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "examples/transfer-lamports/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/transfer-lamports/package.json",
    "content": "{\n    \"name\": \"@solana/example-transfer-lamports\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"scripts\": {\n        \"prestart\": \"turbo --output-logs=errors-only compile:js compile:typedefs\",\n        \"run:example\": \"tsx src/example.ts\",\n        \"start\": \"start-server-and-test '../../scripts/start-shared-test-validator.sh' http://127.0.0.1:8899/health run:example\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent --testMatch '<rootDir>src/**/*.{ts,tsx}'\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc\"\n    },\n    \"dependencies\": {\n        \"@solana-program/system\": \"^0.12.0\",\n        \"@solana/example-utils\": \"workspace:*\",\n        \"@solana/kit\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"start-server-and-test\": \"^2.1.5\",\n        \"tsx\": \"^4.21.0\"\n    }\n}\n"
  },
  {
    "path": "examples/transfer-lamports/src/example.ts",
    "content": "/**\n * EXAMPLE\n * Transfer Lamports from one account to another with @solana/kit.\n *\n * Before running any of the examples in this monorepo, make sure to set up a test validator by\n * running `pnpm test:setup` in the root directory.\n *\n * To run this example, execute `pnpm start` in this directory.\n */\nimport { createLogger } from '@solana/example-utils/createLogger.js';\nimport pressAnyKeyPrompt from '@solana/example-utils/pressAnyKeyPrompt.js';\nimport {\n    address,\n    appendTransactionMessageInstruction,\n    assertIsSendableTransaction,\n    assertIsTransactionWithBlockhashLifetime,\n    createKeyPairSignerFromBytes,\n    createSolanaRpc,\n    createSolanaRpcSubscriptions,\n    createTransactionMessage,\n    getSignatureFromTransaction,\n    isSolanaError,\n    lamports,\n    pipe,\n    sendAndConfirmTransactionFactory,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signTransactionMessageWithSigners,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n} from '@solana/kit';\nimport { getSystemErrorMessage, getTransferSolInstruction, isSystemError } from '@solana-program/system';\n\nconst log = createLogger('Transfer');\n\n/**\n * SETUP: SOURCE ACCOUNT\n * The account from which the tokens will be transferred needs to sign the transaction. We need to\n * create a `TransactionSigner` for it. You can find the account this key relates to in the test\n * validator fixtures in `/scripts/fixtures/example-transfer-sol-source-account.json`\n */\nconst SOURCE_ACCOUNT_SIGNER = await createKeyPairSignerFromBytes(\n    /**\n     * These are the bytes that we saved at the time this account's key pair was originally\n     * generated. Here, they are inlined into the source code, but you can also imagine them being\n     * loaded from disk or, better yet, read from an environment variable.\n     */\n    new Uint8Array(\n        // prettier-ignore\n        [2, 194, 94, 194, 31, 15, 34, 248, 159, 9, 59, 156, 194, 152, 79, 148, 81, 17, 63, 53, 245, 175, 37, 0, 134, 90, 111, 236, 245, 160, 3, 50, 196, 59, 123, 60, 59, 151, 65, 255, 27, 247, 241, 230, 52, 54, 143, 136, 108, 160, 7, 128, 4, 14, 232, 119, 234, 61, 47, 158, 9, 241, 48, 140],\n    ), // Address: ED1WqT2hWJLSZtj4TtTdoovmpMrr7zpkUdbfxmcJR1Fq\n);\nlog.info({ address: SOURCE_ACCOUNT_SIGNER.address }, '[setup] Loaded key pair for source account');\n\n/**\n * SETUP: DESTINATION ACCOUNT\n * Since the account to which the tokens will be transferred does not need to sign the transaction\n * to receive them, we only need an address.\n */\nconst DESTINATION_ACCOUNT_ADDRESS = address('GdG9JHTSWBChvf6dfBATEYCZbDwKtcC6tJEpqoyuVfqV');\nlog.info({ address: DESTINATION_ACCOUNT_ADDRESS }, '[setup] Setting destination account address');\n\n/**\n * SETUP: RPC CONNECTION\n * When it comes time to send our transaction to the Solana network for execution, we will do so\n * through a remote procedure call (RPC) server. This example uses your local test validator which\n * must be running before you run this script.\n */\nconst rpc = createSolanaRpc('http://127.0.0.1:8899');\nconst rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');\n\n/**\n * SETUP: TRANSACTION SENDER\n * We use the RPC connection that you just created to build a reusable transaction sender.\n */\nconst sendAndConfirmTransaction = sendAndConfirmTransactionFactory({\n    /**\n     * The RPC implements a `sendTransaction` method which relays transactions to the network.\n     */\n    rpc,\n    /**\n     * RPC subscriptions allow the transaction sender to subscribe to the status of our transaction.\n     * The sender will resolve when the transaction is reported to have been confirmed, or will\n     * reject in the event of an error, or a timeout if the transaction lifetime is thought to have\n     * expired.\n     */\n    rpcSubscriptions,\n});\n\n/**\n * SETUP: TRANSACTION LIFETIME\n * Every transaction needs to specify a valid lifetime for it to be accepted for execution on the\n * network. For this transaction, we will fetch the latest block's hash as proof that this\n * transaction was prepared close in time to when we tried to execute it. The network will accept\n * transactions which include this hash until it progresses past the block specified as\n * `latestBlockhash.lastValidBlockHeight`.\n *\n * TIP: It is desirable for your program to fetch this block hash as late as possible before signing\n * and sending the transaction so as to ensure that it's as 'fresh' as possible.\n */\nlog.info(\"[setup] Fetching a blockhash for use as the transaction's lifetime constraint\");\nconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\nlog.info(latestBlockhash, '[setup] Got a blockhash');\n\n/**\n * STEP 1: CREATE THE TRANSFER TRANSACTION\n */\nconst transactionMessage = pipe(\n    (log.info('[step 1] Creating a transaction message'), createTransactionMessage({ version: 0 })),\n    /**\n     * Every transaction must state from which account the transaction fee should be debited from,\n     * and that account must sign the transaction. Here, we'll make the source account pay the fee.\n     */\n    tx => (\n        log.info({ address: SOURCE_ACCOUNT_SIGNER.address }, '[step 1] Setting the fee payer'),\n        setTransactionMessageFeePayer(SOURCE_ACCOUNT_SIGNER.address, tx)\n    ),\n    /**\n     * A transaction is valid for execution as long as it includes a valid lifetime constraint. Here\n     * we supply the hash of a recent block. The network will accept this transaction until it\n     * considers that hash to be 'expired' for the purpose of transaction execution.\n     */\n    tx => (\n        log.info(latestBlockhash, '[step 1] Setting the transaction lifetime'),\n        setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx)\n    ),\n    /**\n     * Every transaction needs at least one instruction. This instruction describes the transfer.\n     */\n    tx =>\n        appendTransactionMessageInstruction(\n            /**\n             * The system program has the exclusive right to transfer Lamports from one account to\n             * another. Here we use an instruction creator from the `@solana-program/system` package\n             * to create a transfer instruction for the system program.\n             */\n            (log.info(\n                '[step 1] Creating an instruction to transfer Lamports from %s to %s',\n                SOURCE_ACCOUNT_SIGNER.address,\n                DESTINATION_ACCOUNT_ADDRESS,\n            ),\n            getTransferSolInstruction({\n                amount: lamports(1_000_000n),\n                destination: DESTINATION_ACCOUNT_ADDRESS,\n                /**\n                 * By supplying a `TransactionSigner` here instead of just an address, you give this\n                 * transaction message superpowers. Later in this example, the\n                 * `signTransactionMessageWithSigners` method, in consideration of the fact that the\n                 * source account must sign System program transfer instructions, will use this\n                 * `TransactionSigner` to produce a transaction signed on behalf of\n                 * `SOURCE_ACCOUNT_SIGNER.address`, without any further configuration.\n                 */\n                source: SOURCE_ACCOUNT_SIGNER,\n            })),\n            tx,\n        ),\n);\n\n/**\n * STEP 2: SIGN THE TRANSACTION\n * In order to prove that the owner of the account from which the tokens are being transferred\n * approves of the transfer itself, the transaction will need to include a cryptographic signature\n * that only the owner of that account could produce. We have already loaded the account owner's\n * key pair above, so we can sign the transaction now.\n */\nlog.info('[step 2] Signing the transaction');\nconst signedTransaction = await signTransactionMessageWithSigners(transactionMessage);\nlog.info({ signature: getSignatureFromTransaction(signedTransaction) }, '[step 2] Transaction signed');\n\n/**\n * STEP 3: SEND AND CONFIRM THE TRANSACTION\n * Now that the transaction is signed, we send it to an RPC. The RPC will relay it to the Solana\n * network for execution. The `sendAndConfirmTransaction` method will resolve when the transaction\n * is reported to have been confirmed. It will reject in the event of an error (eg. a failure to\n * simulate the transaction), or may timeout if the transaction lifetime is thought to have expired\n * (eg. the network has progressed past the `lastValidBlockHeight` of the transaction's blockhash\n * lifetime constraint).\n */\nlog.info(\n    '[step 3] Sending transaction: https://explorer.solana.com/tx/%s?cluster=custom&customUrl=127.0.0.1:8899',\n    getSignatureFromTransaction(signedTransaction),\n);\nlog.warn(\n    '[step 3] The URL above does not work on Brave or Safari because they block localhost ' +\n        'connections. Use Chrome.',\n);\ntry {\n    assertIsSendableTransaction(signedTransaction);\n    assertIsTransactionWithBlockhashLifetime(signedTransaction);\n    await sendAndConfirmTransaction(signedTransaction, { commitment: 'confirmed' });\n    log.info('[success] Transfer confirmed');\n    await pressAnyKeyPrompt('Press any key to quit');\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE)) {\n        const preflightErrorContext = e.context;\n        const preflightErrorMessage = e.message;\n        const errorDetailMessage = isSystemError(e.cause, transactionMessage)\n            ? getSystemErrorMessage(e.cause.context.code)\n            : e.cause?.message;\n        if (errorDetailMessage !== undefined) {\n            log.error('%O %s: %s', preflightErrorContext, preflightErrorMessage, errorDetailMessage);\n        } else {\n            log.error('%O %s', preflightErrorContext, preflightErrorMessage);\n        }\n    } else {\n        throw e;\n    }\n}\n"
  },
  {
    "path": "examples/transfer-lamports/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"module\": \"NodeNext\",\n        \"moduleResolution\": \"NodeNext\",\n        \"noEmit\": true,\n        \"target\": \"ESNext\"\n    },\n    \"display\": \"@solana/example-transfer-lamports\",\n    \"extends\": \"../../packages/tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "examples/utils/.gitignore",
    "content": "dist/\n"
  },
  {
    "path": "examples/utils/.prettierignore",
    "content": "dist/\n"
  },
  {
    "path": "examples/utils/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "examples/utils/createLogger.ts",
    "content": "import process from 'node:process';\n\nimport { DestinationStream, Logger, pino } from 'pino';\nimport { build } from 'pino-pretty';\n\nconst BASE_OPTIONS = {\n    colorize: true,\n    colorizeObjects: true,\n    sync: true,\n} as const;\n\nconst prettyStream = build({\n    ...BASE_OPTIONS,\n    ignore: 'hostname,pid,time',\n});\nconst prettyStreamWithTimestamp = build({\n    ...BASE_OPTIONS,\n    ignore: 'hostname,pid',\n});\n\nlet fatalLoggerInstalled = false;\nfunction ensureFatalLogger(logger: Logger<never>) {\n    if (fatalLoggerInstalled) {\n        return;\n    }\n    fatalLoggerInstalled = true;\n    process.on('uncaughtException', err => {\n        logger.fatal(err);\n        process.exit(1);\n    });\n}\n\nfunction createLoggerWithName(name: string, stream: DestinationStream) {\n    return pino(\n        {\n            level: 'debug',\n            name,\n        },\n        stream,\n    );\n}\n\nexport function createLogger(name: string) {\n    const logger = createLoggerWithName(name, prettyStream);\n    ensureFatalLogger(logger);\n    return logger;\n}\n\nexport function createLoggerWithTimestamp(name: string) {\n    const logger = createLoggerWithName(name, prettyStreamWithTimestamp);\n    ensureFatalLogger(logger);\n    return logger;\n}\n"
  },
  {
    "path": "examples/utils/package.json",
    "content": "{\n    \"name\": \"@solana/example-utils\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"dependencies\": {\n        \"@inquirer/core\": \"^11.1.9\",\n        \"pino\": \"^10.3.1\",\n        \"pino-pretty\": \"^13.1.2\"\n    },\n    \"devDependencies\": {\n        \"yoctocolors\": \"^2.1.2\"\n    }\n}\n"
  },
  {
    "path": "examples/utils/pressAnyKeyPrompt.ts",
    "content": "import { createPrompt, useKeypress, usePrefix } from '@inquirer/core';\nimport colors from 'yoctocolors';\n\nexport default createPrompt<void, string>((message = 'Press any key to exit', done) => {\n    const prefix = usePrefix({});\n    useKeypress(() => {\n        done();\n    });\n    return `${prefix} ${colors.bold(message)}`;\n});\n"
  },
  {
    "path": "examples/utils/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"isolatedModules\": false,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"src/index.browser.ts\"]\n}\n"
  },
  {
    "path": "examples/utils/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\"]\n    },\n    \"display\": \"Crypto Implementation\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n    \"name\": \"solana-js-monorepo\",\n    \"private\": true,\n    \"scripts\": {\n        \"build\": \"turbo run --concurrency=${TURBO_CONCURRENCY:-95.84%} build\",\n        \"changeset:publish\": \"turbo publish-packages --concurrency=${TURBO_CONCURRENCY:-95.84%}\",\n        \"compile\": \"turbo run --concurrency=${TURBO_CONCURRENCY:-95.84%} compile:js compile:typedefs\",\n        \"lint\": \"turbo run --concurrency=${TURBO_CONCURRENCY:-95.84%} test:lint\",\n        \"style:fix\": \"turbo  run --concurrency=${TURBO_CONCURRENCY:-95.84%} style:fix && pnpm prettier --log-level warn --ignore-unknown --write '{.,!packages}/*'\",\n        \"test\": \"turbo run --concurrency=${TURBO_CONCURRENCY:-95.84%} test:unit:browser test:unit:node\",\n        \"test:setup\": \"./scripts/setup-test-validator.sh\"\n    },\n    \"devDependencies\": {\n        \"@changesets/changelog-github\": \"^0.5.2\",\n        \"@changesets/cli\": \"^2.31.0\",\n        \"@prettier/sync\": \"^0.6.1\",\n        \"@solana/build-scripts\": \"workspace:*\",\n        \"@solana/eslint-config\": \"workspace:*\",\n        \"@solana/prettier-config-solana\": \"0.0.6\",\n        \"@solana/test-config\": \"workspace:*\",\n        \"@solana/test-matchers\": \"workspace:*\",\n        \"@solana/tsconfig\": \"workspace:*\",\n        \"@swc/jest\": \"^0.2.39\",\n        \"@types/jest\": \"^29.5.14\",\n        \"@types/node\": \"^25\",\n        \"agadoo\": \"^3.0.0\",\n        \"bundlemon\": \"^3.1.0\",\n        \"eslint\": \"^9.39.2\",\n        \"jest\": \"^30.2.0\",\n        \"jest-environment-jsdom\": \"^30.2.0\",\n        \"jest-runner-eslint\": \"^2.3.0\",\n        \"jest-runner-prettier\": \"^1.0.0\",\n        \"jest-watch-master\": \"^1.0.0\",\n        \"jest-watch-select-projects\": \"^2.0.0\",\n        \"jest-watch-typeahead\": \"^2.2.2\",\n        \"prettier\": \"^3.8.3\",\n        \"ts-node\": \"^10.9.2\",\n        \"tsup\": \"^8.5.1\",\n        \"turbo\": \"^2.5.5\",\n        \"typedoc\": \"^0.28.19\",\n        \"typedoc-plugin-frontmatter\": \"^1.3.1\",\n        \"typedoc-plugin-markdown\": \"^4.10.0\",\n        \"typedoc-plugin-mdn-links\": \"^5.1.1\",\n        \"typescript\": \"^5.9.3\"\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\",\n        \"npm\": \"please-use-pnpm\",\n        \"pnpm\": \"^10\",\n        \"yarn\": \"please-use-pnpm\"\n    },\n    \"packageManager\": \"pnpm@10.24.0\",\n    \"pnpm\": {\n        \"overrides\": {\n            \"axios@<1.8.2\": \"^1.12.0\",\n            \"agadoo>rollup\": \"^4\",\n            \"conventional-changelog-conventionalcommits\": \">= 8.0.0\",\n            \"dset@<3.1.4\": \"^3.1.4\",\n            \"jsdom\": \"^22\",\n            \"js-yaml@<3.14.2\": \"^3.14.2\",\n            \"mock-socket\": \"^9.3.1\",\n            \"shelljs\": \">=0.8.5\",\n            \"tmp\": \">=0.2.4\"\n        },\n        \"patchedDependencies\": {\n            \"jest-runner-prettier@1.0.0\": \"patches/jest-runner-prettier@1.0.0.patch\"\n        }\n    },\n    \"prettier\": \"@solana/prettier-config-solana\"\n}"
  },
  {
    "path": "packages/accounts/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/accounts/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/accounts/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/accounts/CHANGELOG.md",
    "content": "# @solana/accounts\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/rpc-spec@6.9.0\n    - @solana/rpc-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/rpc-spec@6.8.0\n    - @solana/rpc-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/rpc-spec@6.7.0\n    - @solana/rpc-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/rpc-spec@6.6.0\n    - @solana/rpc-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/rpc-spec@6.5.0\n    - @solana/rpc-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/rpc-spec@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/rpc-spec@6.3.1\n    - @solana/rpc-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/rpc-spec@6.3.0\n    - @solana/rpc-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/rpc-spec@6.2.0\n    - @solana/rpc-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-strings@6.1.0\n    - @solana/rpc-spec@6.1.0\n    - @solana/rpc-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/rpc-spec@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/rpc-spec@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/rpc-spec@5.5.1\n    - @solana/rpc-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/rpc-spec@5.5.0\n    - @solana/rpc-types@5.5.0\n\n## 5.4.0\n\n### Minor Changes\n\n- [#1152](https://github.com/anza-xyz/kit/pull/1152) [`fb1c576`](https://github.com/anza-xyz/kit/commit/fb1c5761122bebc9955179a911a79a33a391e032) Thanks [@rajgoesout](https://github.com/rajgoesout)! - Include program + type when available in fetchJsonParsedAccount\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-strings@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/rpc-spec@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/rpc-spec@5.3.0\n    - @solana/rpc-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/rpc-spec@5.2.0\n    - @solana/rpc-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/rpc-spec@5.1.0\n    - @solana/rpc-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-strings@5.0.0\n    - @solana/rpc-spec@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/codecs-strings@4.0.0\n    - @solana/rpc-spec@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/codecs-strings@3.0.0\n    - @solana/rpc-spec@3.0.0\n    - @solana/rpc-types@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/rpc-spec@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-strings@2.3.0\n    - @solana/rpc-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/rpc-spec@2.2.1\n    - @solana/rpc-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/addresses@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/rpc-spec@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-strings@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/rpc-spec@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add missing `space` attribute to `AccountInfoBase` and `BaseAccount`\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/rpc-spec@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3213](https://github.com/solana-labs/solana-web3.js/pull/3213) [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcApi: no longer extend RpcApiMethods + remove export\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597), [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/rpc-spec@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/rpc-types@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n    - @solana/rpc-spec@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-spec@2.0.0-rc.3\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3213](https://github.com/solana-labs/solana-web3.js/pull/3213) [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcApi: no longer extend RpcApiMethods + remove export\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/rpc-spec@2.0.0-rc.2\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/rpc-spec@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/rpc-spec@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n    - @solana/rpc-spec@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/rpc-spec@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/addresses@2.0.0-preview.2\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-strings@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n    - @solana/rpc-spec@2.0.0-preview.2\n    - @solana/rpc-types@2.0.0-preview.2\n"
  },
  {
    "path": "packages/accounts/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/accounts/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/accounts?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/accounts?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/accounts\n\n# @solana/accounts\n\nThis package contains types and helper methods for representing, fetching and decoding Solana accounts. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nIt provides a unified definition of a Solana account regardless of how it was retrieved and can represent both encoded and decoded accounts. It also introduces the concept of a `MaybeAccount` which represents a fetched account that may or may not exist on-chain whilst keeping track of its address in both cases.\n\nHelper functions are provided for fetching, parsing and decoding accounts as well as asserting that an account exists.\n\n```ts\n// Fetch.\nconst myAddress = address('1234..5678');\nconst myAccount = await fetchEncodedAccount(rpc, myAddress);\nmyAccount satisfies MaybeEncodedAccount<'1234..5678'>;\n\n// Assert.\nassertAccountExists(myAccount);\nmyAccount satisfies EncodedAccount<'1234..5678'>;\n\n// Decode.\ntype MyAccountData = { name: string; age: number };\nconst myDecoder: Decoder<MyAccountData> = getStructDecoder([\n    ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n    ['age', getU32Decoder()],\n]);\nconst myDecodedAccount = decodeAccount(myAccount, myDecoder);\nmyDecodedAccount satisfies Account<MyAccountData, '1234..5678'>;\n```\n\n## Types\n\n### `BaseAccount`\n\nThe `BaseAccount` type defines the attributes common to all Solana accounts. Namely, it contains everything stored on-chain except the account data itself.\n\n```ts\nconst BaseAccount: BaseAccount = {\n    executable: false,\n    lamports: lamports(1_000_000_000n),\n    programAddress: address('1111..1111'),\n    space: 42n,\n};\n```\n\nThis package also exports a `BASE_ACCOUNT_SIZE` constant representing the size of the `BaseAccount` attributes in bytes.\n\n```ts\nconst myTotalAccountSize = myAccountDataSize + BASE_ACCOUNT_SIZE;\n```\n\n### `Account` and `EncodedAccount`\n\nThe `Account` type contains all the information relevant to a Solana account. It contains the `BaseAccount` described above as well as the account data and the address of the account.\n\nThe account data can be represented as either a `Uint8Array` — meaning the account is encoded — or a custom data type — meaning the account is decoded.\n\n```ts\n// Encoded.\nconst myEncodedAccount: Account<Uint8Array, '1234..5678'> = {\n    address: address('1234..5678'),\n    data: new Uint8Array([1, 2, 3]),\n    executable: false,\n    lamports: lamports(1_000_000_000n),\n    programAddress: address('1111..1111'),\n    space: 42n,\n};\n\n// Decoded.\ntype MyAccountData = { name: string; age: number };\nconst myDecodedAccount: Account<MyAccountData, '1234..5678'> = {\n    address: address('1234..5678'),\n    data: { name: 'Alice', age: 30 },\n    executable: false,\n    lamports: lamports(1_000_000_000n),\n    programAddress: address('1111..1111'),\n    space: 42n,\n};\n```\n\nThe `EncodedAccount` type can also be used to represent an encoded account and is equivalent to an `Account` with a `Uint8Array` account data.\n\n```ts\nmyEncodedAccount satisfies EncodedAccount<'1234..5678'>;\n```\n\n### `MaybeAccount` and `MaybeEncodedAccount`\n\nThe `MaybeAccount` type is a union type representing an account that may or may not exist on-chain. When the account exists, it is represented as an `Account` type with an additional `exists` attribute set to `true`. When it does not exist, it is represented by an object containing only the address of the account and an `exists` attribute set to `false`.\n\n```ts\n// Account exists.\nconst myExistingAccount: MaybeAccount<MyAccountData, '1234..5678'> = {\n    exists: true,\n    address: address('1234..5678'),\n    data: { name: 'Alice', age: 30 },\n    // ...\n};\n\n// Account does not exist.\nconst myMissingAccount: MaybeAccount<MyAccountData, '8765..4321'> = {\n    exists: false,\n    address: address('8765..4321'),\n};\n```\n\nSimilarly to the `Account` type, the `MaybeAccount` type can be used to represent an encoded account by using the `Uint8Array` data type or by using the `MaybeEncodedAccount` helper type.\n\n```ts\n// Encoded account exists.\nconst myExistingAccount: MaybeEncodedAccount<'1234..5678'> = {\n    exists: true,\n    address: address('1234..5678'),\n    data: new Uint8Array([1, 2, 3]),\n    // ...\n};\n\n// Encoded account does not exist.\nconst myMissingAccount: MaybeEncodedAccount<'8765..4321'> = {\n    exists: false,\n    address: address('8765..4321'),\n};\n```\n\n## Functions\n\n### `assertAccountExists()`\n\nGiven a `MaybeAccount`, this function asserts that the account exists and allows it to be used as an `Account` type going forward.\n\n```ts\nconst myAccount: MaybeEncodedAccount<'1234..5678'>;\nassertAccountExists(myAccount);\n\n// Now we can use myAccount as an Account.\nmyAccount satisfies EncodedAccount<'1234..5678'>;\n```\n\n### `assertAccountsExist()`\n\nGiven an array of `MaybeAccount`s, this function asserts that all the accounts\nexist and allows them to be used as an array of `Account`s going forward.\n\n```ts\nconst myAccounts: MaybeEncodedAccount<Address>[];\nassertAccountsExist(myAccounts);\n\n// Now we can use them as an array of accounts\nfor (const a of myAccounts) {\n    a satisfies EncodedAccount<Address>;\n}\n```\n\n### `parseBase64RpcAccount()`\n\nThis function parses a base64-encoded account provided by the RPC client into an `EncodedAccount` type or a `MaybeEncodedAccount` type if the raw data can be set to `null`.\n\n```ts\nconst myAddress = address('1234..5678');\nconst myRpcAccount = await rpc.getAccountInfo(myAddress, { encoding: 'base64' }).send();\nconst myAccount: MaybeEncodedAccount<'1234..5678'> = parseBase64RpcAccount(myRpcAccount);\n```\n\n### `parseBase58RpcAccount()`\n\nThis function parses a base58-encoded account provided by the RPC client into an `EncodedAccount` type or a `MaybeEncodedAccount` type if the raw data can be set to `null`.\n\n```ts\nconst myAddress = address('1234..5678');\nconst myRpcAccount = await rpc.getAccountInfo(myAddress, { encoding: 'base58' }).send();\nconst myAccount: MaybeEncodedAccount<'1234..5678'> = parseBase58RpcAccount(myRpcAccount);\n```\n\n### `parseJsonRpcAccount()`\n\nThis function parses an arbitrary `jsonParsed` account provided by the RPC client into an `Account` type or a `MaybeAccount` type if the raw data can be set to `null`. The expected data type should be explicitly provided as the first type parameter.\n\n```ts\nconst myAccount: Account<MyData> = parseJsonRpcAccount<MyData>(myJsonRpcAccount);\n```\n\n### `fetchEncodedAccount()`\n\nThis function fetches a `MaybeEncodedAccount` from the provided RPC client and address. It uses the `getAccountInfo` RPC method under the hood with base64 encoding and an additional configuration object can be provided to customize the behavior of the RPC call.\n\n```ts\nconst myAddress = address('1234..5678');\nconst myAccount: MaybeEncodedAccount<'1234..5678'> = await fetchEncodedAccount(rpc, myAddress);\n\n// With custom configuration.\nconst myAccount: MaybeEncodedAccount<'1234..5678'> = await fetchEncodedAccount(rpc, myAddress, {\n    abortSignal: myAbortController.signal,\n    commitment: 'confirmed',\n});\n```\n\n### `fetchEncodedAccounts()`\n\nThis function fetches an array of `MaybeEncodedAccount` from the provided RPC client and an array of addresses. It uses the `getMultipleAccounts` RPC method under the hood with base64 encodings and an additional configuration object can be provided to customize the behavior of the RPC call.\n\n```ts\nconst myAddressA = address('1234..5678');\nconst myAddressB = address('8765..4321');\nconst [myAccountA, myAccountB] = await fetchEncodedAccounts(rpc, [myAddressA, myAddressB]);\nmyAccountA satisfies MaybeEncodedAccount<'1234..5678'>;\nmyAccountB satisfies MaybeEncodedAccount<'8765..4321'>;\n\n// With custom configuration.\nconst [myAccountA, myAccountB] = await fetchEncodedAccounts(rpc, [myAddressA, myAddressB], {\n    abortSignal: myAbortController.signal,\n    commitment: 'confirmed',\n});\n```\n\n### `fetchJsonParsedAccount()`\n\nThis function fetches a `MaybeAccount` from the provided RPC client and address by using `getAccountInfo` under the hood with the `jsonParsed` encoding. It may also return a `MaybeEncodedAccount` if the RPC client does not know how to parse the account at the requested address. In any case, the expected data type should be explicitly provided as the first type parameter.\n\n```ts\ntype TokenData = { mint: Address; owner: Address };\nconst myAccount = await fetchJsonParsedAccount<TokenData>(rpc, myAddress);\nmyAccount satisfies MaybeAccount<TokenData> | MaybeEncodedAccount;\n\n// With custom configuration.\nconst myAccount = await fetchJsonParsedAccount<TokenData>(rpc, myAddress, {\n    abortSignal: myAbortController.signal,\n    commitment: 'confirmed',\n});\n```\n\n### `fetchJsonParsedAccounts()`\n\nSimilarly to the `fetchJsonParsedAccount` method, this method fetches an array of `MaybeAccount` from a provided RPC client and an array of addresses. It uses the `getMultipleAccounts` RPC method under the hood with the `jsonParsed` encoding. It may also return a `MaybeEncodedAccount` instead of the expected `MaybeAccount` if the RPC client does not know how to parse some of the requested accounts. In any case, the array of expected data types should be explicitly provided as the first type parameter.\n\n```ts\ntype TokenData = { mint: Address; owner: Address };\ntype MintData = { supply: bigint };\nconst [myAccountA, myAccountB] = await fetchJsonParsedAccounts<[TokenData, MintData]>(rpc, [myAddressA, myAddressB]);\nmyAccountA satisfies MaybeAccount<TokenData> | MaybeEncodedAccount;\nmyAccountB satisfies MaybeAccount<MintData> | MaybeEncodedAccount;\n```\n\n### `decodeAccount()`\n\nThis function transforms an `EncodedAccount` into an `Account` (or a `MaybeEncodedAccount` into a `MaybeAccount`) by decoding the account data using the provided `Decoder` instance.\n\n```ts\ntype MyAccountData = { name: string; age: number };\n\nconst myAccount: EncodedAccount<'1234..5678'>;\nconst myDecoder: Decoder<MyAccountData> = getStructDecoder([\n    ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n    ['age', getU32Decoder()],\n]);\n\nconst myDecodedAccount = decodeAccount(myAccount, myDecoder);\nmyDecodedAccount satisfies Account<MyAccountData, '1234..5678'>;\n```\n\n### `assertAccountDecoded()`\n\nThis function asserts that an account stores decoded data, ie not a Uint8Array. Note that it does not check the shape of the data matches the decoded type, only that it is not a Uint8Array.\n\n```ts\ntype MyAccountData = { name: string; age: number };\n\nconst myAccount: Account<MyAccountData | Uint8Array, '1234..5678'>;\nassertAccountDecoded(myAccount);\n\n// now the account data can be used as MyAccountData\naccount.data satisfies MyAccountData;\n```\n\nThis is particularly useful for narrowing the result of fetching a JSON parsed account.\n\n```ts\nconst account: MaybeAccount<MockData | Uint8Array> = await fetchJsonParsedAccount<MockData>(\n    rpc,\n    '1234..5678' as Address,\n);\n\nassertAccountDecoded(account);\n// now we have a MaybeAccount<MockData>\naccount satisfies MaybeAccount<MockData>;\n```\n\n### `assertAccountsDecoded`\n\nThis function asserts that all input accounts store decoded data, ie not a Uint8Array. As with `assertAccountDecoded` it does not check the shape of the data matches the decoded type, only that it is not a Uint8Array.\n\n```ts\ntype MyAccountData = { name: string; age: number };\n\nconst myAccounts: Account<MyAccountData | Uint8Array, Address>[];\nassertAccountsDecoded(myAccounts);\n\n// now the account data can be used as MyAccountData\nfor (const a of account) {\n    account.data satisfies MyAccountData;\n}\n```\n"
  },
  {
    "path": "packages/accounts/package.json",
    "content": "{\n    \"name\": \"@solana/accounts\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for representing, fetching and decoding Solana accounts\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaaccounts\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/rpc-spec\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/accounts/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/accounts/src/__tests__/__setup__.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Decoder } from '@solana/codecs-core';\nimport type { PendingRpcRequest, Rpc } from '@solana/rpc-spec';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\nimport type { GetAccountInfoApi, GetMultipleAccountsApi, JsonParsedDataResponse } from '../rpc-api';\n\nexport type Base64RpcAccount = AccountInfoBase & AccountInfoWithBase64EncodedData;\nexport type Base58RpcAccount = AccountInfoBase & (AccountInfoWithBase58Bytes | AccountInfoWithBase58EncodedData);\nexport type JsonParsedRpcAccount = AccountInfoBase & { readonly data: JsonParsedDataResponse<unknown> };\n\nexport function getMockRpc(\n    accounts: Record<Address, Base64RpcAccount | JsonParsedRpcAccount>,\n): Rpc<GetAccountInfoApi | GetMultipleAccountsApi> & { getAccountInfo: jest.Mock; getMultipleAccounts: jest.Mock } {\n    const wrapInPendingResponse = <T>(value: T): PendingRpcRequest<SolanaRpcResponse<T>> => {\n        const send = jest.fn().mockResolvedValue({ context: { slot: 0n }, value });\n        const reactiveStore = jest.fn().mockImplementation(() => {\n            throw new Error('not implemented');\n        });\n        return { reactiveStore, send };\n    };\n\n    const getAccountInfo = jest\n        .fn()\n        .mockImplementation((address: Address) => wrapInPendingResponse(accounts[address] ?? null));\n\n    const getMultipleAccounts = jest\n        .fn()\n        .mockImplementation((addresses: Address[]) =>\n            wrapInPendingResponse(addresses.map(address => accounts[address] ?? null)),\n        );\n\n    return { getAccountInfo, getMultipleAccounts };\n}\n\nexport function getMockDecoder<T>(mockValue: T): Decoder<T> {\n    return {\n        decode: jest.fn().mockReturnValueOnce(mockValue),\n        read: jest.fn().mockReturnValueOnce([mockValue, 42]),\n    } as Decoder<T>;\n}\n"
  },
  {
    "path": "packages/accounts/src/__tests__/decode-account-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED,\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT,\n    SolanaError,\n} from '@solana/errors';\n\nimport { Account, EncodedAccount } from '../account';\nimport { assertAccountDecoded, assertAccountsDecoded, decodeAccount } from '../decode-account';\nimport { MaybeAccount, MaybeEncodedAccount } from '../maybe-account';\nimport { getMockDecoder } from './__setup__';\n\ndescribe('decodeAccount', () => {\n    it('decodes the account data of an existing encoded account', () => {\n        // Given an encoded account.\n        const encodedAccount = <EncodedAccount>{\n            address: '1111',\n            data: new Uint8Array([1, 2, 3]) as ReadonlyUint8Array,\n            executable: false,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 3n,\n        };\n\n        // And a mock decoder.\n        const decoder = getMockDecoder<{ foo: 42 }>({ foo: 42 });\n\n        // When we decode the encoded account.\n        const account = decodeAccount(encodedAccount, decoder);\n\n        // Then we expect the account data to have been decoded.\n        expect(account).toStrictEqual({\n            address: '1111',\n            data: { foo: 42 },\n            executable: false,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 3n,\n        });\n\n        // And the decoder to have been called with the encoded account data.\n        expect(decoder.decode).toHaveBeenCalledWith(encodedAccount.data);\n    });\n\n    it('freezes the decoded account', () => {\n        // Given an encoded account.\n        const encodedAccount = <EncodedAccount>{\n            address: '1111',\n            data: new Uint8Array([1, 2, 3]) as ReadonlyUint8Array,\n            executable: false,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 3n,\n        };\n\n        // And a mock decoder.\n        const decoder = getMockDecoder<{ foo: 42 }>({ foo: 42 });\n\n        // When we decode the encoded account.\n        const account = decodeAccount(encodedAccount, decoder);\n\n        // Then we expect the decoded account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n\n    it('returns non-existing accounts as-is', () => {\n        // Given a non-existing encoded account.\n        const encodedAccount = <MaybeEncodedAccount>{ address: '1111', exists: false };\n\n        // And a mock decoder.\n        const decoder = getMockDecoder<{ foo: 42 }>({ foo: 42 });\n\n        // When we decode the non-existing account.\n        const account = decodeAccount(encodedAccount, decoder);\n\n        // Then we expect the decoded account to be the same as the original account.\n        expect(account).toBe(encodedAccount);\n    });\n});\n\ndescribe('assertDecodedAccount', () => {\n    type MockData = { foo: 42 };\n\n    it('throws if the provided account is encoded', () => {\n        // Given an account with Uint8Array data\n        const account = <EncodedAccount>{\n            address: '1111' as Address,\n            data: new Uint8Array([]) as ReadonlyUint8Array,\n        };\n\n        // When we assert that the account is decoded\n        const fn = () => assertAccountDecoded(account);\n\n        // Then we expect an error to be thrown\n        expect(fn).toThrow(\n            new SolanaError(SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT, {\n                address: account.address,\n            }),\n        );\n    });\n\n    it('does not throw if the provided account is decoded', () => {\n        // Given an account with decoded data\n        const account = <Account<MockData>>{\n            address: '1111' as Address,\n            data: { foo: 42 },\n        };\n\n        // When we assert that the account is decoded\n        const fn = () => assertAccountDecoded(account);\n\n        // Then we expect an error not to be thrown\n        expect(fn).not.toThrow();\n    });\n\n    it('does not throw if the input account does not exist', () => {\n        // Given an account that does not exist\n        const account = <MaybeAccount<MockData>>{\n            address: '1111' as Address,\n            exists: false,\n        };\n\n        // When we assert that the account is decoded\n        const fn = () => assertAccountDecoded(account);\n\n        // Then we expect an error not to be thrown\n        expect(fn).not.toThrow();\n    });\n});\n\ndescribe('assertDecodedAccounts', () => {\n    type MockData = { foo: 42 };\n\n    it('throws if any of the provided accounts are encoded', () => {\n        // Given two encoded accounts and one decoded account\n        const accounts = [\n            <EncodedAccount>{\n                address: '1111' as Address,\n                data: new Uint8Array([]) as ReadonlyUint8Array,\n            },\n            <EncodedAccount>{\n                address: '2222' as Address,\n                data: new Uint8Array([]) as ReadonlyUint8Array,\n            },\n            <Account<MockData>>{\n                address: '3333' as Address,\n                data: { foo: 42 },\n            },\n        ];\n\n        // When we assert that the accounts are decoded\n        const fn = () => assertAccountsDecoded(accounts);\n\n        // Then we expect an error to be thrown\n        expect(fn).toThrow(\n            new SolanaError(SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED, {\n                addresses: [accounts[0].address, accounts[1].address],\n            }),\n        );\n    });\n\n    it('does not throw if all of the provided accounts are decoded', () => {\n        // Given three decoded accounts\n        const accounts = [\n            <Account<MockData>>{\n                address: '1111' as Address,\n                data: { foo: 42 },\n            },\n            <Account<MockData>>{\n                address: '2222' as Address,\n                data: { foo: 42 },\n            },\n            <Account<MockData>>{\n                address: '3333' as Address,\n                data: { foo: 42 },\n            },\n        ];\n\n        // When we assert that the accounts are decoded\n        const fn = () => assertAccountsDecoded(accounts);\n\n        // Then we expect an error not to be thrown\n        expect(fn).not.toThrow();\n    });\n\n    it('does not throw if all provided accounts are missing', () => {\n        // Given three missing accounts\n        const accounts = [\n            <MaybeAccount<MockData>>{\n                address: '1111' as Address,\n                exists: false,\n            },\n            <MaybeAccount<MockData>>{\n                address: '2222' as Address,\n                exists: false,\n            },\n            <MaybeAccount<MockData>>{\n                address: '3333' as Address,\n                exists: false,\n            },\n        ];\n\n        // When we assert that the accounts are decoded\n        const fn = () => assertAccountsDecoded(accounts);\n\n        // Then we expect an error not to be thrown\n        expect(fn).not.toThrow();\n    });\n});\n"
  },
  {
    "path": "packages/accounts/src/__tests__/fetch-account-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\n\nimport {\n    fetchEncodedAccount,\n    fetchEncodedAccounts,\n    fetchJsonParsedAccount,\n    fetchJsonParsedAccounts,\n} from '../fetch-account';\nimport { MaybeAccount, MaybeEncodedAccount } from '../maybe-account';\nimport { Base64RpcAccount, getMockRpc, JsonParsedRpcAccount } from './__setup__';\n\ndescribe('fetchEncodedAccount', () => {\n    it('fetches and parses an existing base64-encoded account from an RPC', async () => {\n        expect.assertions(2);\n\n        // Given a mock RPC client returning a mock account at a given address.\n        const address = '1111' as Address<'1111'>;\n        const rpc = getMockRpc({\n            [address]: <Base64RpcAccount>{\n                data: ['somedata', 'base64'],\n                executable: false,\n                lamports: 1_000_000_000n,\n                owner: '9999',\n                space: 6n,\n            },\n        });\n\n        // When we fetch that account using the fetchEncodedAccount function.\n        const account = await fetchEncodedAccount(rpc, address);\n\n        // Then we expect the following parsed encoded account to be returned.\n        account satisfies MaybeEncodedAccount;\n        expect(account).toStrictEqual({\n            address,\n            data: new Uint8Array([178, 137, 158, 117, 171, 90]),\n            executable: false,\n            exists: true,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 6n,\n        });\n\n        // And the getAccountInfo RPC method to have been called with the given address and an explicit base64 encoding.\n        expect(rpc.getAccountInfo).toHaveBeenCalledWith(address, { encoding: 'base64' });\n    });\n\n    it('fetches and parses a missing encoded account from an RPC', async () => {\n        expect.assertions(2);\n\n        // Given an address and a mock RPC that does not contain an account at that address.\n        const address = '1111' as Address<'1111'>;\n        const rpc = getMockRpc({});\n\n        // When we try to fetch the account at that address using the fetchEncodedAccount function.\n        const account = await fetchEncodedAccount(rpc, address);\n\n        // Then we expect the following non-existing account to be returned.\n        account satisfies MaybeEncodedAccount;\n        expect(account).toStrictEqual({ address, exists: false });\n\n        // And the getAccountInfo RPC method to have been called with the given address and an explicity base64 encoding.\n        expect(rpc.getAccountInfo).toHaveBeenCalledWith(address, { encoding: 'base64' });\n    });\n\n    it('freezes the returned account', async () => {\n        expect.assertions(1);\n\n        // Given a mock RPC client returning a mock account at a given address.\n        const address = '1111' as Address<'1111'>;\n        const rpc = getMockRpc({\n            [address]: <Base64RpcAccount>{\n                data: ['somedata', 'base64'],\n                executable: false,\n                lamports: 1_000_000_000n,\n                owner: '9999',\n                space: 6n,\n            },\n        });\n\n        // When we fetch that account using the fetchEncodedAccount function.\n        const account = await fetchEncodedAccount(rpc, address);\n\n        // Then we expect the returned account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n});\n\ndescribe('fetchJsonParsedAccount', () => {\n    it('fetches and parses an existing jsonParsed account from an RPC', async () => {\n        expect.assertions(2);\n\n        // Given a mock RPC client returning a mock jsonParsed account at a given address.\n        const address = '1111' as Address<'1111'>;\n        const rpc = getMockRpc({\n            [address]: <JsonParsedRpcAccount>{\n                data: {\n                    parsed: {\n                        info: { mint: '2222' as Address<'2222'>, owner: '3333' as Address<'3333'> },\n                        type: 'token',\n                    },\n                    program: 'splToken',\n                    space: 165n, // The space field is provided again on some JSON-parsed RPC response.\n                },\n                executable: false,\n                lamports: 1_000_000_000n,\n                owner: '9999',\n                space: 165n,\n            },\n        });\n\n        // When we fetch that account using the jsonParsed encoding.\n        type MyData = { mint: Address; owner: Address };\n        const account = await fetchJsonParsedAccount<MyData>(rpc, address);\n\n        // Then we expect the following jsonParsed encoded account to be returned.\n        account satisfies MaybeAccount<MyData> | MaybeEncodedAccount;\n        expect(account).toStrictEqual(<\n            MaybeAccount<MyData & { parsedAccountMeta?: { program: string; type?: string } }>\n        >{\n            address,\n            data: {\n                mint: '2222' as Address<'2222'>,\n                owner: '3333' as Address<'3333'>,\n                parsedAccountMeta: {\n                    program: 'splToken',\n                    type: 'token',\n                },\n            },\n            executable: false,\n            exists: true,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 165n,\n        });\n\n        // And the getAccountInfo RPC method to have been called with the given address and an explicit jsonParsed encoding.\n        expect(rpc.getAccountInfo).toHaveBeenCalledWith(address, { encoding: 'jsonParsed' });\n    });\n\n    it('fetches and parses a missing encoded account from an RPC', async () => {\n        expect.assertions(2);\n\n        // Given an address and a mock RPC that does not contain an account at that address.\n        const address = '1111' as Address<'1111'>;\n        const rpc = getMockRpc({});\n\n        // When we try to fetch the account at that address using the fetchJsonParsedAccount function.\n        type MyData = { mint: Address; owner: Address };\n        const account = await fetchJsonParsedAccount<MyData>(rpc, address);\n\n        // Then we expect the following non-existing account to be returned.\n        account satisfies MaybeAccount<MyData> | MaybeEncodedAccount;\n        expect(account).toStrictEqual({ address, exists: false });\n\n        // And the getAccountInfo RPC method to have been called with the given address and an explicity jsonParsed encoding.\n        expect(rpc.getAccountInfo).toHaveBeenCalledWith(address, { encoding: 'jsonParsed' });\n    });\n\n    it('freezes the returned account', async () => {\n        expect.assertions(1);\n\n        // Given a mock RPC client returning a mock account at a given address.\n        const address = '1111' as Address<'1111'>;\n        const rpc = getMockRpc({\n            [address]: <JsonParsedRpcAccount>{\n                data: {\n                    parsed: {\n                        info: { mint: '2222' as Address<'2222'>, owner: '3333' as Address<'3333'> },\n                        type: 'token',\n                    },\n                    program: 'splToken',\n                    space: 165n,\n                },\n                executable: false,\n                lamports: 1_000_000_000n,\n                owner: '9999',\n            },\n        });\n\n        // When we fetch that account using the fetchJsonParsedAccount function.\n        const account = await fetchJsonParsedAccount(rpc, address);\n\n        // Then we expect the returned account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n});\n\ndescribe('fetchEncodedAccounts', () => {\n    it('fetches and parses multiple accounts from an RPC', async () => {\n        expect.assertions(3);\n\n        // Given two addresses A and B.\n        const addressA = '1111' as Address<'1111'>;\n        const addressB = '2222' as Address<'2222'>;\n\n        // And a mock RPC client such that A exists and B does not.\n        const rpc = getMockRpc({\n            [addressA]: <Base64RpcAccount>{\n                data: ['somedata', 'base64'],\n                executable: false,\n                lamports: 1_000_000_000n,\n                owner: '9999',\n                space: 6n,\n            },\n        });\n\n        // When we fetch both of these accounts using the fetchEncodedAccounts function.\n        const [accountA, accountB] = await fetchEncodedAccounts(rpc, [addressA, addressB]);\n\n        // Then each account is returned as a MaybeEncodedAccount.\n        accountA satisfies MaybeEncodedAccount;\n        accountB satisfies MaybeEncodedAccount;\n\n        // And account A is returned as an existing account.\n        expect(accountA).toStrictEqual({\n            address: addressA,\n            data: new Uint8Array([178, 137, 158, 117, 171, 90]),\n            executable: false,\n            exists: true,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 6n,\n        });\n\n        // And account B is returned as a non-existing account.\n        expect(accountB).toStrictEqual({ address: addressB, exists: false });\n\n        // And the getMultipleAccounts RPC method to have been called with the given addresses and an explicity base64 encoding.\n        expect(rpc.getMultipleAccounts).toHaveBeenCalledWith([addressA, addressB], { encoding: 'base64' });\n    });\n\n    it('freezes the returned accounts', async () => {\n        expect.assertions(2);\n\n        // Given two addresses A and B.\n        const addressA = '1111' as Address<'1111'>;\n        const addressB = '2222' as Address<'2222'>;\n\n        // And a mock RPC client such that A exists and B does not.\n        const rpc = getMockRpc({\n            [addressA]: <Base64RpcAccount>{\n                data: ['somedata', 'base64'],\n                executable: false,\n                lamports: 1_000_000_000n,\n                owner: '9999',\n                space: 6n,\n            },\n        });\n\n        // When we fetch both of these accounts using the fetchEncodedAccounts function.\n        const [accountA, accountB] = await fetchEncodedAccounts(rpc, [addressA, addressB]);\n\n        // Then both accounts are frozen.\n        expect(accountA).toBeFrozenObject();\n        expect(accountB).toBeFrozenObject();\n    });\n});\n\ndescribe('fetchJsonParsedAccounts', () => {\n    it('fetches and parses multiple accounts from an RPC', async () => {\n        expect.assertions(3);\n\n        // Given two addresses A and B.\n        const addressA = '1111' as Address<'1111'>;\n        const addressB = '2222' as Address<'2222'>;\n\n        // And a mock RPC client such that A exists and B does not.\n        const rpc = getMockRpc({\n            [addressA]: <JsonParsedRpcAccount>{\n                data: {\n                    parsed: {\n                        info: { mint: '3333' as Address<'3333'>, owner: '4444' as Address<'4444'> },\n                        type: 'token',\n                    },\n                    program: 'splToken',\n                    space: 165n, // The space field is provided again on some JSON-parsed RPC response.\n                },\n                executable: false,\n                lamports: 1_000_000_000n,\n                owner: '9999',\n                space: 165n,\n            },\n        });\n\n        // When we fetch both of these accounts using the fetchJsonParsedAccounts function.\n        type MyData = { mint: Address; owner: Address };\n        const [accountA, accountB] = await fetchJsonParsedAccounts<MyData[]>(rpc, [addressA, addressB]);\n\n        // Then each account is returned as a MaybeEncodedAccount.\n        accountA satisfies MaybeAccount<MyData> | MaybeEncodedAccount;\n        accountB satisfies MaybeAccount<MyData> | MaybeEncodedAccount;\n\n        // And account A is returned as an existing account.\n        expect(accountA).toStrictEqual({\n            address: addressA,\n            data: {\n                mint: '3333',\n                owner: '4444',\n                parsedAccountMeta: { program: 'splToken', type: 'token' },\n            },\n            executable: false,\n            exists: true,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 165n,\n        });\n\n        // And account B is returned as a non-existing account.\n        expect(accountB).toStrictEqual({ address: addressB, exists: false });\n\n        // And the getMultipleAccounts RPC method to have been called with the given addresses and an explicity jsonParsed encoding.\n        expect(rpc.getMultipleAccounts).toHaveBeenCalledWith([addressA, addressB], { encoding: 'jsonParsed' });\n    });\n\n    it('freezes the returned accounts', async () => {\n        expect.assertions(2);\n\n        // Given two addresses A and B.\n        const addressA = '1111' as Address<'1111'>;\n        const addressB = '2222' as Address<'2222'>;\n\n        // And a mock RPC client such that A exists and B does not.\n        const rpc = getMockRpc({\n            [addressA]: <JsonParsedRpcAccount>{\n                data: {\n                    parsed: {\n                        info: { mint: '3333' as Address<'3333'>, owner: '4444' as Address<'4444'> },\n                        type: 'token',\n                    },\n                    program: 'splToken',\n                    space: 165n,\n                },\n                executable: false,\n                lamports: 1_000_000_000n,\n                owner: '9999',\n            },\n        });\n\n        // When we fetch both of these accounts using the fetchJsonParsedAccounts function.\n        const [accountA, accountB] = await fetchJsonParsedAccounts(rpc, [addressA, addressB]);\n\n        // Then both accounts are frozen.\n        expect(accountA).toBeFrozenObject();\n        expect(accountB).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/accounts/src/__tests__/maybe-account-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND,\n    SolanaError,\n} from '@solana/errors';\n\nimport { assertAccountExists, assertAccountsExist, MaybeEncodedAccount } from '../maybe-account';\n\ndescribe('assertAccountExists', () => {\n    it('fails if the provided MaybeAccount does not exist', () => {\n        // Given a non-existing account.\n        const maybeAccount = <MaybeEncodedAccount>{ address: '1111', exists: false };\n\n        // When we assert that the account exists.\n        const fn = () => assertAccountExists(maybeAccount);\n\n        // Then we expect an error to be thrown.\n        expect(fn).toThrow(\n            new SolanaError(SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND, {\n                address: maybeAccount.address,\n            }),\n        );\n    });\n});\n\ndescribe('assertAccountsExist', () => {\n    it('fails if any of the provided MaybeAccounts do not exist', () => {\n        // Given two non-existing accounts and an existing account.\n        const maybeAccounts = [\n            <MaybeEncodedAccount>{ address: '1111', exists: false },\n            <MaybeEncodedAccount>{ address: '2222', exists: false },\n            <MaybeEncodedAccount>{ address: '3333', exists: true },\n        ];\n\n        // When we assert that all the accounts exist.\n        const fn = () => assertAccountsExist(maybeAccounts);\n\n        // Then we expect an error to be thrown with the non-existent accounts\n        expect(fn).toThrow(\n            new SolanaError(SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND, {\n                addresses: [maybeAccounts[0].address, maybeAccounts[1].address],\n            }),\n        );\n    });\n\n    it('does not fail if all accounts exist', () => {\n        // Given three accounts that all exist\n        const maybeAccounts = [\n            <MaybeEncodedAccount>{ address: '1111', exists: true },\n            <MaybeEncodedAccount>{ address: '2222', exists: true },\n            <MaybeEncodedAccount>{ address: '3333', exists: true },\n        ];\n\n        // When we assert that all the accounts exist.\n        const fn = () => assertAccountsExist(maybeAccounts);\n\n        // Then we expect an error not to be thrown\n        expect(fn).not.toThrow();\n    });\n});\n"
  },
  {
    "path": "packages/accounts/src/__tests__/parse-account-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport type { Address } from '@solana/addresses';\nimport { lamports } from '@solana/rpc-types';\n\nimport { Account, EncodedAccount } from '../account';\nimport { MaybeAccount, MaybeEncodedAccount } from '../maybe-account';\nimport { parseBase58RpcAccount, parseBase64RpcAccount, parseJsonRpcAccount } from '../parse-account';\nimport { Base58RpcAccount, Base64RpcAccount, JsonParsedRpcAccount } from './__setup__';\n\ndescribe('parseBase64RpcAccount', () => {\n    it('parses an encoded account with base64 data', () => {\n        // Given an address and an RPC account with base64 data.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <Base64RpcAccount>{\n            data: ['somedata', 'base64'],\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 6n,\n        };\n\n        // When we parse that RPC account using the parseBase64RpcAccount function.\n        const account = parseBase64RpcAccount(address, rpcAccount);\n\n        // Then we expect account to be an EncodedAccount.\n        account satisfies EncodedAccount;\n\n        // And we expect the following parsed encoded account to be returned.\n        expect(account).toStrictEqual({\n            address: '1111',\n            data: new Uint8Array([178, 137, 158, 117, 171, 90]),\n            executable: false,\n            exists: true,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 6n,\n        });\n    });\n\n    it('parses an empty account', () => {\n        // Given an address with no matching RPC account.\n        const address = '1111' as Address<'1111'>;\n\n        // When we parse null for that address using the parseBase64RpcAccount function.\n        const account = parseBase64RpcAccount(address, null);\n\n        // Then we expect account to be a MaybeEncodedAccount.\n        account satisfies MaybeEncodedAccount;\n\n        // And we expect the following parsed data to be returned.\n        expect(account).toStrictEqual({ address: '1111', exists: false });\n    });\n\n    it('freezes the returned encoded account', () => {\n        // Given an address and an RPC account with base64 data.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <Base64RpcAccount>{\n            data: ['somedata', 'base64'],\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 6n,\n        };\n\n        // When we parse that RPC account using the parseBase64RpcAccount function.\n        const account = parseBase64RpcAccount(address, rpcAccount);\n\n        // Then we expect the returned account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n\n    it('freezes the returned empty account', () => {\n        // Given an address with no matching RPC account.\n        const address = '1111' as Address<'1111'>;\n\n        // When we parse that address with a null RPC account.\n        const account = parseBase64RpcAccount(address, null);\n\n        // Then we expect the returned empty account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n});\n\ndescribe('parseBase58RpcAccount', () => {\n    it('parses an encoded account with base58 data', () => {\n        // Given an address and an RPC account with base58 data.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <Base58RpcAccount>{\n            data: ['somedata', 'base58'],\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 6n,\n        };\n\n        // When we parse that RPC account using the parseBase58RpcAccount function.\n        const account = parseBase58RpcAccount(address, rpcAccount);\n\n        // Then we expect account to be an EncodedAccount.\n        account satisfies EncodedAccount;\n\n        // And we expect the following parsed encoded account to be returned.\n        expect(account).toStrictEqual({\n            address: '1111',\n            data: new Uint8Array([102, 6, 221, 155, 82, 67]),\n            executable: false,\n            exists: true,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 6n,\n        });\n    });\n\n    it('parses an encoded account with implicit base58 data', () => {\n        // Given an address and an RPC account with implicit base58 data.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <Base58RpcAccount>{\n            data: 'somedata',\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 6n,\n        };\n\n        // When we parse that RPC account using the parseBase58RpcAccount function.\n        const account = parseBase58RpcAccount(address, rpcAccount);\n\n        // Then we expect account to be an EncodedAccount.\n        account satisfies EncodedAccount;\n\n        // And we expect the following parsed encoded account to be returned.\n        expect(account).toStrictEqual({\n            address: '1111',\n            data: new Uint8Array([102, 6, 221, 155, 82, 67]),\n            executable: false,\n            exists: true,\n            lamports: 1_000_000_000n,\n            programAddress: '9999',\n            space: 6n,\n        });\n    });\n\n    it('parses an empty account', () => {\n        // Given an address with no matching RPC account.\n        const address = '1111' as Address<'1111'>;\n\n        // When we parse null for that address using the parseBase58RpcAccount function.\n        const account = parseBase58RpcAccount(address, null);\n\n        // Then we expect account to be a MaybeEncodedAccount.\n        account satisfies MaybeEncodedAccount;\n\n        // And we expect the following parsed data to be returned.\n        expect(account).toStrictEqual({ address: '1111', exists: false });\n    });\n\n    it('freezes the returned encoded account', () => {\n        // Given an address and an RPC account with base58 data.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <Base58RpcAccount>{\n            data: ['somedata', 'base58'],\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 6n,\n        };\n\n        // When we parse that RPC account using the parseBase58RpcAccount function.\n        const account = parseBase58RpcAccount(address, rpcAccount);\n\n        // Then we expect the returned account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n\n    it('freezes the returned empty account', () => {\n        // Given an address with no matching RPC account.\n        const address = '1111' as Address<'1111'>;\n\n        // When we parse that address with a null RPC account.\n        const account = parseBase58RpcAccount(address, null);\n\n        // Then we expect the returned empty account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n});\n\ndescribe('parseJsonRpcAccount', () => {\n    it('parses an json parsed account with custom data', () => {\n        // Given an address and a json-parsed RPC account.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    info: { mint: '2222' as Address<'2222'>, owner: '3333' as Address<'3333'> },\n                    type: 'token',\n                },\n                program: 'splToken',\n                space: 165n, // The space field is provided again on some JSON-parsed RPC response.\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function and a custom data type.\n        type MyData = { mint: Address; owner: Address };\n        const account = parseJsonRpcAccount<MyData>(address, rpcAccount);\n\n        // Then we expect account to be an Account with the custom data type.\n        account satisfies Account<MyData>;\n\n        // And we expect the following parsed encoded account to be returned.\n        expect(account).toStrictEqual({\n            address: '1111' as Address<'1111'>,\n            data: {\n                mint: '2222' as Address<'2222'>,\n                owner: '3333' as Address<'3333'>,\n                parsedAccountMeta: {\n                    program: 'splToken',\n                    type: 'token',\n                },\n            },\n            executable: false,\n            exists: true,\n            lamports: lamports(1_000_000_000n),\n            programAddress: '9999' as Address<'9999'>,\n            space: 165n,\n        } as Account<MyData>);\n    });\n\n    it('preserves array data and includes metadata when available', () => {\n        // Given an address and a json-parsed RPC account with array data.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    info: [\n                        {\n                            blockhash: '1111',\n                            feeCalculator: { lamportsPerSignature: '1' },\n                        },\n                    ],\n                    type: 'recentBlockhashes',\n                },\n                program: 'sysvar',\n                space: 165n,\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function.\n        type MyData = { blockhash: string; feeCalculator: { lamportsPerSignature: string } }[];\n        const account = parseJsonRpcAccount<MyData>(address, rpcAccount);\n\n        // Then we expect the data to remain an array and include metadata.\n        expect(Array.isArray(account.data)).toBe(true);\n        expect(account.data).toMatchObject(\n            expect.arrayContaining([\n                {\n                    blockhash: '1111',\n                    feeCalculator: { lamportsPerSignature: '1' },\n                },\n            ]),\n        );\n        expect(account.data.parsedAccountMeta).toStrictEqual({\n            program: 'sysvar',\n            type: 'recentBlockhashes',\n        });\n    });\n\n    it('parses metadata without a type when not provided', () => {\n        // Given an address and a json-parsed RPC account without a parsed type.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    info: { mint: '2222' as Address<'2222'> },\n                },\n                program: 'splToken',\n                space: 165n,\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function.\n        type MyData = { mint: Address };\n        const account = parseJsonRpcAccount<MyData>(address, rpcAccount);\n\n        // Then we expect metadata to include only the program.\n        expect(account).toMatchObject({\n            data: {\n                mint: '2222',\n                parsedAccountMeta: {\n                    program: 'splToken',\n                },\n            },\n        });\n    });\n\n    it('does not include metadata when program and type are missing', () => {\n        // Given an address and a json-parsed RPC account without metadata.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    info: { mint: '2222' as Address<'2222'> },\n                },\n                program: undefined as unknown as string,\n                space: 165n,\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function.\n        type MyData = { mint: Address };\n        const account = parseJsonRpcAccount<MyData>(address, rpcAccount);\n\n        // Then we expect parsedAccountMeta to be omitted.\n        expect(account.data).toEqual({\n            mint: '2222',\n        });\n    });\n\n    it('includes metadata when only type is provided', () => {\n        // Given an address and a json-parsed RPC account with only a type.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    info: { mint: '2222' as Address<'2222'> },\n                    type: 'token',\n                },\n                program: undefined as unknown as string,\n                space: 165n,\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function.\n        type MyData = { mint: Address };\n        const account = parseJsonRpcAccount<MyData>(address, rpcAccount);\n\n        // Then we expect metadata to include only the type.\n        expect(account).toMatchObject({\n            data: {\n                mint: '2222',\n                parsedAccountMeta: {\n                    type: 'token',\n                },\n            },\n        });\n    });\n\n    it('uses metadata when info is null', () => {\n        // Given an address and a json-parsed RPC account with null info.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    info: null,\n                    type: 'token',\n                },\n                program: 'splToken',\n                space: 165n,\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function.\n        const account = parseJsonRpcAccount<object>(address, rpcAccount);\n\n        // Then we expect the data to only include metadata.\n        expect(account).toMatchObject({\n            data: {\n                parsedAccountMeta: {\n                    program: 'splToken',\n                    type: 'token',\n                },\n            },\n        });\n    });\n\n    it('preserves array data when metadata is missing', () => {\n        // Given an address and a json-parsed RPC account with array info and no metadata.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    info: [\n                        {\n                            blockhash: '1111',\n                            feeCalculator: { lamportsPerSignature: '1' },\n                        },\n                    ],\n                },\n                program: undefined as unknown as string,\n                space: 165n,\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function.\n        type MyData = { blockhash: string; feeCalculator: { lamportsPerSignature: string } }[];\n        const account = parseJsonRpcAccount<MyData>(address, rpcAccount);\n\n        // Then we expect the data to remain an array without metadata.\n        expect(Array.isArray(account.data)).toBe(true);\n        expect(account.data).toEqual(\n            expect.arrayContaining([\n                {\n                    blockhash: '1111',\n                    feeCalculator: { lamportsPerSignature: '1' },\n                },\n            ]),\n        );\n    });\n\n    it('parses an json parsed account without info', () => {\n        // Given an address and a json-parsed RPC account without info.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    type: 'token',\n                },\n                program: 'splToken',\n                space: 165n,\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function.\n        const account = parseJsonRpcAccount<object>(address, rpcAccount);\n\n        // Then we expect the metadata fields to be included.\n        expect(account).toStrictEqual({\n            address: '1111' as Address<'1111'>,\n            data: {\n                parsedAccountMeta: {\n                    program: 'splToken',\n                    type: 'token',\n                },\n            },\n            executable: false,\n            exists: true,\n            lamports: lamports(1_000_000_000n),\n            programAddress: '9999' as Address<'9999'>,\n            space: 165n,\n        });\n    });\n\n    it('parses an empty account', () => {\n        // Given an address with no matching RPC account.\n        const address = '1111' as Address<'1111'>;\n\n        // When we parse null for that address using the parseJsonRpcAccount function.\n        type MyData = { mint: Address; owner: Address };\n        const account = parseJsonRpcAccount<MyData>(address, null);\n\n        // Then we expect account to be a MaybeAccount.\n        account satisfies MaybeAccount<MyData>;\n\n        // And we expect the following parsed data to be returned.\n        expect(account).toStrictEqual({ address: '1111', exists: false });\n    });\n\n    it('freezes the returned encoded account', () => {\n        // Given an address and an RPC account with base64 data.\n        const address = '1111' as Address<'1111'>;\n        const rpcAccount = <JsonParsedRpcAccount>{\n            data: {\n                parsed: {\n                    info: { mint: '2222' as Address<'2222'>, owner: '3333' as Address<'3333'> },\n                    type: 'token',\n                },\n                program: 'splToken',\n                space: 165n, // The space field is provided again on some JSON-parsed RPC response.\n            },\n            executable: false,\n            lamports: 1_000_000_000n,\n            owner: '9999',\n            space: 165n,\n        };\n\n        // When we parse that RPC account using the parseJsonRpcAccount function.\n        const account = parseJsonRpcAccount(address, rpcAccount);\n\n        // Then we expect the returned account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n\n    it('freezes the returned empty account', () => {\n        // Given an address with no matching RPC account.\n        const address = '1111' as Address<'1111'>;\n\n        // When we parse that address with a null RPC account.\n        const account = parseJsonRpcAccount(address, null);\n\n        // Then we expect the returned empty account to be frozen.\n        expect(account).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/accounts/src/__typetests__/decode-account-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Decoder, ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { Account, EncodedAccount } from '../account';\nimport { assertAccountDecoded, assertAccountsDecoded, decodeAccount } from '../decode-account';\nimport { MaybeAccount, MaybeEncodedAccount } from '../maybe-account';\n\ntype MockData = { foo: 42 };\ntype MockDataDecoder = Decoder<MockData>;\n\n{\n    // It decodes an EncodedAccount into an Account.\n    const account = decodeAccount({} as EncodedAccount<'1111'>, {} as MockDataDecoder);\n    account satisfies Account<MockData, '1111'>;\n}\n\n{\n    // It decodes an MaybeEncodedAccount into a MaybeAccount.\n    const account = decodeAccount({} as MaybeEncodedAccount<'1111'>, {} as MockDataDecoder);\n    account satisfies MaybeAccount<MockData, '1111'>;\n    // @ts-expect-error The account should not be of type Account as it may not exist.\n    account satisfies Account<MockData, '1111'>;\n}\n\n{\n    // It narrows an account with data MockData | Uint8Array to MockData\n    const account = {} as unknown as Account<MockData | Uint8Array, '1111'>;\n    assertAccountDecoded(account);\n    account satisfies Account<MockData, '1111'>;\n    account.data satisfies MockData;\n}\n\n{\n    // It narrows a list of accounts with data MockData | Uint8Array to MockData\n    const accounts = [\n        {} as unknown as Account<MockData | ReadonlyUint8Array, '1111'>,\n        {} as unknown as Account<MockData | ReadonlyUint8Array, '2222'>,\n        {} as unknown as Account<MockData | ReadonlyUint8Array, '3333'>,\n    ];\n    assertAccountsDecoded(accounts);\n    accounts satisfies Account<MockData, Address>[];\n    for (const a of accounts) {\n        a.data satisfies MockData;\n    }\n}\n"
  },
  {
    "path": "packages/accounts/src/__typetests__/fetch-account-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\n\nimport type { Address } from '@solana/addresses';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport {\n    fetchEncodedAccount,\n    fetchEncodedAccounts,\n    fetchJsonParsedAccount,\n    fetchJsonParsedAccounts,\n} from '../fetch-account';\nimport type { MaybeAccount, MaybeEncodedAccount } from '../maybe-account';\nimport type { GetAccountInfoApi, GetMultipleAccountsApi } from '../rpc-api';\n\nconst rpc = {} as Rpc<GetAccountInfoApi & GetMultipleAccountsApi>;\nconst address = '1111' as Address<'1111'>;\nconst otherAddress = '2222' as Address<'2222'>;\n\n{\n    // [fetchEncodedAccount]: returns a MaybeEncodedAccount by default or when using a base64 encoding.\n    fetchEncodedAccount(rpc, address) satisfies Promise<MaybeEncodedAccount<'1111'>>;\n}\n\n{\n    // [fetchJsonParsedAccount]: It returns a MaybeAccount using a provided custom data type or a MaybeEncodedAccount when using a jsonParsed encoding.\n    type MockData = { foo: 42 };\n    // Unfortunately, TypeScript does not support \"Partial type argument inference\", which means,\n    // as we provide the first type argument for the data type, we have to provide the second\n    // one as well for the address since it won't be inferred and will default to `string`.\n    fetchJsonParsedAccount<MockData, '1111'>(rpc, address) satisfies Promise<\n        | MaybeAccount<MockData & { parsedAccountMeta?: { program: string; type?: string } }, '1111'>\n        | MaybeEncodedAccount<'1111'>\n    >;\n    // @ts-expect-error It does not only satisfy MaybeAccount<MockData>.\n    fetchJsonParsedAccount<MockData>(rpc, address) satisfies Promise<MaybeAccount<MockData>>;\n    // @ts-expect-error It does not only satisfy MaybeEncodedAccount.\n    fetchJsonParsedAccount<MockData>(rpc, address) satisfies Promise<MaybeEncodedAccount>;\n}\n\n{\n    // [fetchEncodedAccounts]: It matches the returned MaybeEncodedAccounts with the provided addresses.\n    fetchEncodedAccounts(rpc, [] as Address[]) satisfies Promise<MaybeEncodedAccount[]>;\n    fetchEncodedAccounts(rpc, [address, otherAddress]) satisfies Promise<\n        [MaybeEncodedAccount<'1111'>, MaybeEncodedAccount<'2222'>]\n    >;\n    // @ts-expect-error The first MaybeEncodedAccount does not match the first address.\n    fetchEncodedAccounts(rpc, [address, otherAddress]) satisfies Promise<\n        [MaybeEncodedAccount<'2222'>, MaybeEncodedAccount<'2222'>]\n    >;\n    // @ts-expect-error The second MaybeEncodedAccount does not match the second address.\n    fetchEncodedAccounts(rpc, [address, otherAddress]) satisfies Promise<\n        [MaybeEncodedAccount<'1111'>, MaybeEncodedAccount<'1111'>]\n    >;\n}\n\n{\n    // [fetchJsonParsedAccounts]: It matches the jsonParsed returned types with the provided addresses and data array.\n    type MockData = { foo: 42 };\n    type OtherMockData = { bar: 42 };\n    fetchJsonParsedAccounts<MockData[]>(rpc, [] as Address[]) satisfies Promise<\n        (MaybeAccount<MockData & { parsedAccountMeta?: { program: string; type?: string } }> | MaybeEncodedAccount)[]\n    >;\n    fetchJsonParsedAccounts<MockData[], ['1111', '2222']>(rpc, [address, otherAddress]) satisfies Promise<\n        [\n            (\n                | MaybeAccount<MockData & { parsedAccountMeta?: { program: string; type?: string } }, '1111'>\n                | MaybeEncodedAccount<'1111'>\n            ),\n            (\n                | MaybeAccount<MockData & { parsedAccountMeta?: { program: string; type?: string } }, '2222'>\n                | MaybeEncodedAccount<'2222'>\n            ),\n        ]\n    >;\n    fetchJsonParsedAccounts<[MockData, OtherMockData]>(rpc, [address, otherAddress]) satisfies Promise<\n        [\n            MaybeAccount<MockData & { parsedAccountMeta?: { program: string; type?: string } }> | MaybeEncodedAccount,\n            (\n                | MaybeAccount<OtherMockData & { parsedAccountMeta?: { program: string; type?: string } }>\n                | MaybeEncodedAccount\n            ),\n        ]\n    >;\n    fetchJsonParsedAccounts<[MockData, OtherMockData], ['1111', '2222']>(rpc, [\n        address,\n        otherAddress,\n    ]) satisfies Promise<\n        [\n            (\n                | MaybeAccount<MockData & { parsedAccountMeta?: { program: string; type?: string } }, '1111'>\n                | MaybeEncodedAccount<'1111'>\n            ),\n            (\n                | MaybeAccount<OtherMockData & { parsedAccountMeta?: { program: string; type?: string } }, '2222'>\n                | MaybeEncodedAccount<'2222'>\n            ),\n        ]\n    >;\n}\n"
  },
  {
    "path": "packages/accounts/src/__typetests__/maybe-account-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { Account } from '../account';\nimport { assertAccountExists, assertAccountsExist, MaybeAccount } from '../maybe-account';\n\ntype MockData = { foo: 42 };\n\n{\n    // It narrows a MaybeAccount to an Account\n    const account = {} as unknown as MaybeAccount<MockData, '1111'>;\n    assertAccountExists(account);\n    account satisfies Account<MockData, '1111'>;\n}\n\n{\n    // It narrows an array of MaybeAccounts to an array of Accounts\n    const accounts = [\n        {} as unknown as MaybeAccount<MockData, '1111'>,\n        {} as unknown as MaybeAccount<MockData, '2222'>,\n        {} as unknown as MaybeAccount<MockData, '3333'>,\n    ];\n    assertAccountsExist(accounts);\n    accounts satisfies Account<MockData, Address>[];\n}\n"
  },
  {
    "path": "packages/accounts/src/__typetests__/parse-account-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { Base58RpcAccount, Base64RpcAccount, JsonParsedRpcAccount } from '../__tests__/__setup__';\nimport { Account, EncodedAccount } from '../account';\nimport { MaybeAccount, MaybeEncodedAccount } from '../maybe-account';\nimport { parseBase58RpcAccount, parseBase64RpcAccount, parseJsonRpcAccount } from '../parse-account';\n\nconst address = '1111' as Address<'1111'>;\ntype MyData = { mint: Address; token: Address };\n\n{\n    // [parseBase64RpcAccount]: It returns a EncodedAccount when the RPC account is not nullable.\n    const account = parseBase64RpcAccount(address, {} as Base64RpcAccount);\n    account satisfies EncodedAccount<'1111'>;\n}\n\n{\n    // [parseBase64RpcAccount]: It returns a MaybeEncodedAccount when the RPC account is nullable.\n    const account = parseBase64RpcAccount(address, {} as Base64RpcAccount | null);\n    account satisfies MaybeEncodedAccount<'1111'>;\n    // @ts-expect-error The account should not be an EncodedAccount as null can be provided.\n    account satisfies EncodedAccount;\n}\n\n{\n    // [parseBase58RpcAccount]: It returns a EncodedAccount when the RPC account is not nullable.\n    const account = parseBase58RpcAccount(address, {} as Base58RpcAccount);\n    account satisfies EncodedAccount<'1111'>;\n}\n\n{\n    // [parseBase58RpcAccount]: It returns a MaybeEncodedAccount when the RPC account is nullable.\n    const account = parseBase58RpcAccount(address, {} as Base58RpcAccount | null);\n    account satisfies MaybeEncodedAccount<'1111'>;\n    // @ts-expect-error The account should not be an EncodedAccount as null can be provided.\n    account satisfies EncodedAccount;\n}\n\n{\n    // [parseJsonRpcAccount]: It returns a custom Account when the RPC is a JSON parsed account.\n    const account = parseJsonRpcAccount<MyData, '1111'>(address, {} as JsonParsedRpcAccount);\n    account satisfies Account<MyData & { parsedAccountMeta?: { program: string; type?: string } }, '1111'>;\n}\n\n{\n    // [parseJsonRpcAccount]: It returns a MaybeAccount when passing null with a custom Data type.\n    const account = parseJsonRpcAccount<MyData, '1111'>(address, null);\n    account satisfies MaybeAccount<MyData & { parsedAccountMeta?: { program: string; type?: string } }, '1111'>;\n}\n"
  },
  {
    "path": "packages/accounts/src/account.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport type { Lamports } from '@solana/rpc-types';\n\n/**\n * The number of bytes required to store the {@link BaseAccount} information without its data.\n *\n * @example\n * ```ts\n * const myTotalAccountSize = myAccountDataSize + BASE_ACCOUNT_SIZE;\n * ```\n */\nexport const BASE_ACCOUNT_SIZE = 128;\n\n/**\n * Defines the attributes common to all Solana accounts. Namely, it contains everything stored\n * on-chain except the account data itself.\n *\n * @interface\n *\n * @example\n * ```ts\n * const BaseAccount: BaseAccount = {\n *     executable: false,\n *     lamports: lamports(1_000_000_000n),\n *     programAddress: address('1111..1111'),\n *     space: 42n,\n * };\n * ```\n */\nexport type BaseAccount = {\n    readonly executable: boolean;\n    readonly lamports: Lamports;\n    readonly programAddress: Address;\n    readonly space: bigint;\n};\n\n/**\n * Contains all the information relevant to a Solana account. It includes the account's address and\n * data, as well as the properties of {@link BaseAccount}.\n *\n * @interface\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TData - The nature of this account's data. It can be represented as either a\n * `Uint8Array` &ndash; meaning the account is encoded &ndash; or a custom data type &ndash; meaning\n * the account is decoded.\n *\n * @example\n * ```ts\n * // Encoded\n * const myEncodedAccount: Account<Uint8Array, '1234..5678'> = {\n *     address: address('1234..5678'),\n *     data: new Uint8Array([1, 2, 3]),\n *     executable: false,\n *     lamports: lamports(1_000_000_000n),\n *     programAddress: address('1111..1111'),\n *     space: 42n,\n * };\n *\n * // Decoded\n * type MyAccountData = { name: string; age: number };\n * const myDecodedAccount: Account<MyAccountData, '1234..5678'> = {\n *     address: address('1234..5678'),\n *     data: { name: 'Alice', age: 30 },\n *     executable: false,\n *     lamports: lamports(1_000_000_000n),\n *     programAddress: address('1111..1111'),\n *     space: 42n,\n * };\n * ```\n */\nexport type Account<TData extends Uint8Array | object, TAddress extends string = string> = BaseAccount & {\n    readonly address: Address<TAddress>;\n    readonly data: TData;\n};\n\n/**\n * Represents an encoded account and is equivalent to an {@link Account} with `Uint8Array` account\n * data.\n *\n * @interface\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n *\n * @example\n * ```ts\n * {\n *     address: address('1234..5678'),\n *     data: new Uint8Array([1, 2, 3]),\n *     executable: false,\n *     lamports: lamports(1_000_000_000n),\n *     programAddress: address('1111..1111'),\n *     space: 42n,\n * } satisfies EncodedAccount<'1234..5678'>;\n * ```\n */\nexport type EncodedAccount<TAddress extends string = string> = Account<ReadonlyUint8Array, TAddress>;\n"
  },
  {
    "path": "packages/accounts/src/decode-account.ts",
    "content": "import type { Decoder, ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED,\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT,\n    SOLANA_ERROR__ACCOUNTS__FAILED_TO_DECODE_ACCOUNT,\n    SolanaError,\n} from '@solana/errors';\n\nimport type { Account, EncodedAccount } from './account';\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\n\n/**\n * Transforms an {@link EncodedAccount} into an {@link Account} (or a {@link MaybeEncodedAccount}\n * into a {@link MaybeAccount}) by decoding the account data using the provided {@link Decoder}\n * instance.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TData - The type of this account's data.\n *\n * @example\n * ```ts\n * type MyAccountData = { name: string; age: number };\n *\n * const myAccount: EncodedAccount<'1234..5678'>;\n * const myDecoder: Decoder<MyAccountData> = getStructDecoder([\n *     ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n *     ['age', getU32Decoder()],\n * ]);\n *\n * const myDecodedAccount = decodeAccount(myAccount, myDecoder);\n * myDecodedAccount satisfies Account<MyAccountData, '1234..5678'>;\n * ```\n */\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n    encodedAccount: EncodedAccount<TAddress>,\n    decoder: Decoder<TData>,\n): Account<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n    encodedAccount: MaybeEncodedAccount<TAddress>,\n    decoder: Decoder<TData>,\n): MaybeAccount<TData, TAddress>;\nexport function decodeAccount<TData extends object, TAddress extends string = string>(\n    encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>,\n    decoder: Decoder<TData>,\n): Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n    try {\n        if ('exists' in encodedAccount && !encodedAccount.exists) {\n            return encodedAccount;\n        }\n        return Object.freeze({ ...encodedAccount, data: decoder.decode(encodedAccount.data) });\n    } catch {\n        throw new SolanaError(SOLANA_ERROR__ACCOUNTS__FAILED_TO_DECODE_ACCOUNT, {\n            address: encodedAccount.address,\n        });\n    }\n}\n\nfunction accountExists<TData extends object>(account: Account<TData> | MaybeAccount<TData>): account is Account<TData> {\n    return !('exists' in account) || ('exists' in account && account.exists);\n}\n\n/**\n * Asserts that an account stores decoded data, ie. not a `Uint8Array`.\n *\n * Note that it does not check the shape of the data matches the decoded type, only that it is not a\n * `Uint8Array`.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TData - The type of this account's data.\n *\n * @example\n * ```ts\n * type MyAccountData = { name: string; age: number };\n *\n * const myAccount: Account<MyAccountData | Uint8Array, '1234..5678'>;\n * assertAccountDecoded(myAccount);\n *\n * // now the account data can be used as MyAccountData\n * account.data satisfies MyAccountData;\n * ```\n *\n * This is particularly useful for narrowing the result of fetching a JSON parsed account.\n *\n * ```ts\n * const account: MaybeAccount<MockData | Uint8Array> = await fetchJsonParsedAccount<MockData>(\n *     rpc,\n *     '1234..5678' as Address,\n * );\n *\n * assertAccountDecoded(account);\n * // now we have a MaybeAccount<MockData>\n * account satisfies MaybeAccount<MockData>;\n * ```\n */\nexport function assertAccountDecoded<TData extends object, TAddress extends string = string>(\n    account: Account<TData | Uint8Array, TAddress>,\n): asserts account is Account<TData, TAddress>;\nexport function assertAccountDecoded<TData extends object, TAddress extends string = string>(\n    account: MaybeAccount<TData | Uint8Array, TAddress>,\n): asserts account is MaybeAccount<TData, TAddress>;\nexport function assertAccountDecoded<TData extends object, TAddress extends string = string>(\n    account: Account<TData | Uint8Array, TAddress> | MaybeAccount<TData | Uint8Array, TAddress>,\n): asserts account is Account<TData, TAddress> | MaybeAccount<TData, TAddress> {\n    if (accountExists(account) && account.data instanceof Uint8Array) {\n        throw new SolanaError(SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT, {\n            address: account.address,\n        });\n    }\n}\n\n/**\n * Asserts that all input accounts store decoded data, ie. not a `Uint8Array`.\n *\n * As with {@link assertAccountDecoded} it does not check the shape of the data matches the decoded\n * type, only that it is not a `Uint8Array`.\n *\n * @example\n * ```ts\n * type MyAccountData = { name: string; age: number };\n *\n * const myAccounts: Account<MyAccountData | Uint8Array, Address>[];\n * assertAccountsDecoded(myAccounts);\n *\n * // now the account data can be used as MyAccountData\n * for (const a of account) {\n *     account.data satisfies MyAccountData;\n * }\n * ```\n */\nexport function assertAccountsDecoded<TData extends object, TAddress extends string = string>(\n    accounts: Account<ReadonlyUint8Array | TData, TAddress>[],\n): asserts accounts is Account<TData, TAddress>[];\nexport function assertAccountsDecoded<TData extends object, TAddress extends string = string>(\n    accounts: MaybeAccount<ReadonlyUint8Array | TData, TAddress>[],\n): asserts accounts is MaybeAccount<TData, TAddress>[];\nexport function assertAccountsDecoded<TData extends object, TAddress extends string = string>(\n    accounts: (Account<ReadonlyUint8Array | TData, TAddress> | MaybeAccount<ReadonlyUint8Array | TData, TAddress>)[],\n): asserts accounts is (Account<TData, TAddress> | MaybeAccount<TData, TAddress>)[] {\n    const encoded = accounts.filter(a => accountExists(a) && a.data instanceof Uint8Array);\n    if (encoded.length > 0) {\n        const encodedAddresses = encoded.map(a => a.address);\n        throw new SolanaError(SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED, {\n            addresses: encodedAddresses,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/accounts/src/fetch-account.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment, Slot } from '@solana/rpc-types';\n\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\nimport { parseBase64RpcAccount, parseJsonRpcAccount } from './parse-account';\nimport type { GetAccountInfoApi, GetMultipleAccountsApi } from './rpc-api';\n\n/**\n * Optional configuration for fetching a singular account.\n *\n * @interface\n */\nexport type FetchAccountConfig = {\n    abortSignal?: AbortSignal;\n    /**\n     * Fetch the details of the account as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n};\n\n/**\n * Fetches a {@link MaybeEncodedAccount} from the provided RPC client and address.\n *\n * It uses the {@link GetAccountInfoApi.getAccountInfo | getAccountInfo} RPC method under the hood\n * with base64 encoding and an additional configuration object can be provided to customize the\n * behavior of the RPC call.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n *\n * @example\n * ```ts\n * const myAddress = address('1234..5678');\n * const myAccount: MaybeEncodedAccount<'1234..5678'> = await fetchEncodedAccount(rpc, myAddress);\n *\n * // With custom configuration.\n * const myAccount: MaybeEncodedAccount<'1234..5678'> = await fetchEncodedAccount(rpc, myAddress, {\n *     abortSignal: myAbortController.signal,\n *     commitment: 'confirmed',\n * });\n * ```\n */\nexport async function fetchEncodedAccount<TAddress extends string = string>(\n    rpc: Rpc<GetAccountInfoApi>,\n    address: Address<TAddress>,\n    config: FetchAccountConfig = {},\n): Promise<MaybeEncodedAccount<TAddress>> {\n    const { abortSignal, ...rpcConfig } = config;\n    const response = await rpc.getAccountInfo(address, { ...rpcConfig, encoding: 'base64' }).send({ abortSignal });\n    return parseBase64RpcAccount(address, response.value);\n}\n\n/**\n * Fetches a {@link MaybeAccount} from the provided RPC client and address by using\n * {@link GetAccountInfoApi.getAccountInfo | getAccountInfo} under the hood with the `jsonParsed`\n * encoding.\n *\n * It may also return a {@link MaybeEncodedAccount} if the RPC client does not know how to parse the\n * account at the requested address. In any case, the expected data type should be explicitly\n * provided as the first type parameter.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TData - The expected type of this account's data.\n *\n * @example\n * ```ts\n * type TokenData = { mint: Address; owner: Address };\n * const myAccount = await fetchJsonParsedAccount<TokenData>(rpc, myAddress);\n * myAccount satisfies MaybeAccount<TokenData> | MaybeEncodedAccount;\n *\n * // With custom configuration.\n * const myAccount = await fetchJsonParsedAccount<TokenData>(rpc, myAddress, {\n *     abortSignal: myAbortController.signal,\n *     commitment: 'confirmed',\n * });\n * ```\n */\nexport async function fetchJsonParsedAccount<TData extends object, TAddress extends string = string>(\n    rpc: Rpc<GetAccountInfoApi>,\n    address: Address<TAddress>,\n    config: FetchAccountConfig = {},\n): Promise<\n    | MaybeAccount<TData & { parsedAccountMeta?: { program: string; type?: string } }, TAddress>\n    | MaybeEncodedAccount<TAddress>\n> {\n    const { abortSignal, ...rpcConfig } = config;\n    const { value: account } = await rpc\n        .getAccountInfo(address, { ...rpcConfig, encoding: 'jsonParsed' })\n        .send({ abortSignal });\n    return !!account && typeof account === 'object' && 'parsed' in account.data\n        ? parseJsonRpcAccount<TData, TAddress>(address, account as Parameters<typeof parseJsonRpcAccount>[1])\n        : parseBase64RpcAccount<TAddress>(address, account as Parameters<typeof parseBase64RpcAccount>[1]);\n}\n\n/**\n * Optional configuration for fetching multiple accounts.\n *\n * @interface\n */\nexport type FetchAccountsConfig = {\n    abortSignal?: AbortSignal;\n    /**\n     * Fetch the details of the accounts as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n};\n\n/**\n * Fetches an array of {@link MaybeEncodedAccount | MaybeEncodedAccounts} from the provided RPC\n * client and an array of addresses.\n *\n * It uses the {@link GetMultipleAccountsApi#getMultipleAccounts | getMultipleAccounts} RPC method\n * under the hood with base64 encodings and an additional configuration object can be provided to\n * customize the behavior of the RPC call.\n *\n * @typeParam TAddresses - Supply an array of string literals to define accounts having particular\n * addresses.\n *\n * @example\n * ```ts\n * const myAddressA = address('1234..5678');\n * const myAddressB = address('8765..4321');\n * const [myAccountA, myAccountB] = await fetchEncodedAccounts(rpc, [myAddressA, myAddressB]);\n * myAccountA satisfies MaybeEncodedAccount<'1234..5678'>;\n * myAccountB satisfies MaybeEncodedAccount<'8765..4321'>;\n *\n * // With custom configuration.\n * const [myAccountA, myAccountB] = await fetchEncodedAccounts(rpc, [myAddressA, myAddressB], {\n *     abortSignal: myAbortController.signal,\n *     commitment: 'confirmed',\n * });\n * ```\n */\nexport async function fetchEncodedAccounts<\n    TAddresses extends string[] = string[],\n    TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n        [P in keyof TAddresses]: Address<TAddresses[P]>;\n    },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n    const { abortSignal, ...rpcConfig } = config;\n    const response = await rpc\n        .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'base64' })\n        .send({ abortSignal });\n    return response.value.map((account, index) => parseBase64RpcAccount(addresses[index], account)) as {\n        [P in keyof TAddresses]: MaybeEncodedAccount<TAddresses[P]>;\n    };\n}\n\n/**\n * Fetches an array of {@link MaybeAccount | MaybeAccounts} from a provided RPC client and an array\n * of addresses.\n *\n * It uses the {@link GetMultipleAccountsApi#getMultipleAccounts | getMultipleAccounts} RPC method\n * under the hood with the `jsonParsed` encoding. It may also return a\n * {@link MaybeEncodedAccount} instead of the expected {@link MaybeAccount} if the RPC client does\n * not know how to parse some of the requested accounts. In any case, the array of expected data\n * types should be explicitly provided as the first type parameter.\n *\n * @typeParam TAddresses - Supply an array of string literals to define accounts having particular\n * addresses.\n * @typeParam TData - The expected types of these accounts' data.\n \n * @example\n * ```ts\n * type TokenData = { mint: Address; owner: Address };\n * type MintData = { supply: bigint };\n * const [myAccountA, myAccountB] = await fetchJsonParsedAccounts<[TokenData, MintData]>(rpc, [myAddressA, myAddressB]);\n * myAccountA satisfies MaybeAccount<TokenData> | MaybeEncodedAccount;\n * myAccountB satisfies MaybeAccount<MintData> | MaybeEncodedAccount;\n * ```\n */\nexport async function fetchJsonParsedAccounts<\n    TData extends object[],\n    TAddresses extends string[] = string[],\n    TWrappedAddresses extends { [P in keyof TAddresses]: Address<TAddresses[P]> } = {\n        [P in keyof TAddresses]: Address<TAddresses[P]>;\n    },\n>(rpc: Rpc<GetMultipleAccountsApi>, addresses: TWrappedAddresses, config: FetchAccountsConfig = {}) {\n    const { abortSignal, ...rpcConfig } = config;\n    const response = await rpc\n        .getMultipleAccounts(addresses, { ...rpcConfig, encoding: 'jsonParsed' })\n        .send({ abortSignal });\n    return response.value.map((account, index) => {\n        return !!account && typeof account === 'object' && 'parsed' in account.data\n            ? parseJsonRpcAccount(addresses[index], account as Parameters<typeof parseJsonRpcAccount>[1])\n            : parseBase64RpcAccount(addresses[index], account as Parameters<typeof parseBase64RpcAccount>[1]);\n    }) as {\n        [P in keyof TAddresses]:\n            | MaybeAccount<\n                  TData[P & keyof TData] & { parsedAccountMeta?: { program: string; type?: string } },\n                  TAddresses[P]\n              >\n            | MaybeEncodedAccount<TAddresses[P]>;\n    } & {\n        [P in keyof TData]:\n            | MaybeAccount<\n                  TData[P] & { parsedAccountMeta?: { program: string; type?: string } },\n                  TAddresses[P & keyof TAddresses]\n              >\n            | MaybeEncodedAccount<TAddresses[P & keyof TAddresses]>;\n    };\n}\n"
  },
  {
    "path": "packages/accounts/src/index.ts",
    "content": "/**\n * This package contains types and helper methods for representing, fetching and decoding Solana\n * accounts. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * It provides a unified definition of a Solana account regardless of how it was retrieved and can\n * represent both encoded and decoded accounts. It also introduces the concept of a\n * {@link MaybeAccount} which represents a fetched account that may or may not exist on-chain whilst\n * keeping track of its address in both cases.\n *\n * Helper functions are provided for fetching, parsing and decoding accounts as well as asserting\n * that an account exists.\n *\n * @packageDocumentation\n * @example\n * ```ts\n * // Fetch.\n * const myAddress = address('1234..5678');\n * const myAccount = await fetchEncodedAccount(rpc, myAddress);\n * myAccount satisfies MaybeEncodedAccount<'1234..5678'>;\n *\n * // Assert.\n * assertAccountExists(myAccount);\n * myAccount satisfies EncodedAccount<'1234..5678'>;\n *\n * // Decode.\n * type MyAccountData = { name: string; age: number };\n * const myDecoder: Decoder<MyAccountData> = getStructDecoder([\n *     ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n *     ['age', getU32Decoder()],\n * ]);\n * const myDecodedAccount = decodeAccount(myAccount, myDecoder);\n * myDecodedAccount satisfies Account<MyAccountData, '1234..5678'>;\n * ```\n */\nexport * from './account';\nexport * from './decode-account';\nexport * from './fetch-account';\nexport * from './maybe-account';\nexport * from './parse-account';\n"
  },
  {
    "path": "packages/accounts/src/maybe-account.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND,\n    SolanaError,\n} from '@solana/errors';\n\nimport { Account } from './account';\n\n/**\n * Represents an account that may or may not exist on-chain.\n *\n * When the account exists, it is represented as an {@link Account} type with an additional `exists`\n * attribute set to `true`. When it does not exist, it is represented by an object containing only\n * the address of the account and an `exists` attribute set to `false`.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TData - The nature of this account's data. It can be represented as either a\n * `Uint8Array` &ndash; meaning the account is encoded &ndash; or a custom data type &ndash; meaning\n * the account is decoded.\n *\n * @example\n * ```ts\n * // Account exists\n * const myExistingAccount: MaybeAccount<MyAccountData, '1234..5678'> = {\n *     exists: true,\n *     address: address('1234..5678'),\n *     data: { name: 'Alice', age: 30 },\n *     // ...\n * };\n *\n * // Account does not exist\n * const myMissingAccount: MaybeAccount<MyAccountData, '8765..4321'> = {\n *     exists: false,\n *     address: address('8765..4321'),\n * };\n * ```\n */\nexport type MaybeAccount<TData extends Uint8Array | object, TAddress extends string = string> =\n    | { readonly address: Address<TAddress>; readonly exists: false }\n    | (Account<TData, TAddress> & { readonly exists: true });\n\n/**\n * Represents an encoded account that may or may not exist on-chain.\n *\n * When the account exists, it is represented as an {@link Account} type having its `TData` type\n * parameter set to `Uint8Array` with an additional `exists` attribute set to `true`. When it does\n * not exist, it is represented by an object containing only the address of the account and an\n * `exists` attribute set to `false`.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n *\n * @example\n * ```ts\n * // Encoded account exists\n * const myExistingAccount: MaybeEncodedAccount<'1234..5678'> = {\n *     exists: true,\n *     address: address('1234..5678'),\n *     data: new Uint8Array([1, 2, 3]),\n *     // ...\n * };\n *\n * // Encoded account does not exist\n * const myMissingAccount: MaybeEncodedAccount<'8765..4321'> = {\n *     exists: false,\n *     address: address('8765..4321'),\n * };\n * ```\n */\nexport type MaybeEncodedAccount<TAddress extends string = string> = MaybeAccount<Uint8Array, TAddress>;\n\n/**\n * Given a {@link MaybeAccount}, asserts that the account exists and allows it to be used as an\n * {@link Account} type going forward.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TData - The nature of this account's data. It can be represented as either a\n * `Uint8Array` &ndash; meaning the account is encoded &ndash; or a custom data type &ndash; meaning\n * the account is decoded.\n *\n * @example\n * ```ts\n * const myAccount: MaybeEncodedAccount<'1234..5678'>;\n * assertAccountExists(myAccount);\n *\n * // Now we can use myAccount as an `EncodedAccount`\n * myAccount satisfies EncodedAccount<'1234..5678'>;\n * ```\n */\nexport function assertAccountExists<TData extends Uint8Array | object, TAddress extends string = string>(\n    account: MaybeAccount<TData, TAddress>,\n): asserts account is Account<TData, TAddress> & { exists: true } {\n    if (!account.exists) {\n        throw new SolanaError(SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND, { address: account.address });\n    }\n}\n\n/**\n * Given an array of {@link MaybeAccount | MaybeAccounts}, asserts that all the accounts exist and\n * allows them to be used as an array of {@link Account | Accounts} going forward.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TData - The nature of this account's data. It can be represented as either a\n * `Uint8Array` &ndash; meaning the account is encoded &ndash; or a custom data type &ndash; meaning\n * the account is decoded.\n *\n * @example\n * ```ts\n * const myAccounts: MaybeEncodedAccount<Address>[];\n * assertAccountsExist(myAccounts);\n *\n * // Now we can use them as an array of `EncodedAccounts`\n * for (const a of myAccounts) {\n *     a satisfies EncodedAccount<Address>;\n * }\n * ```\n */\nexport function assertAccountsExist<TData extends Uint8Array | object, TAddress extends string = string>(\n    accounts: MaybeAccount<TData, TAddress>[],\n): asserts accounts is (Account<TData, TAddress> & { exists: true })[] {\n    const missingAccounts = accounts.filter(a => !a.exists);\n    if (missingAccounts.length > 0) {\n        const missingAddresses = missingAccounts.map(a => a.address);\n        throw new SolanaError(SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND, { addresses: missingAddresses });\n    }\n}\n"
  },
  {
    "path": "packages/accounts/src/parse-account.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { getBase58Encoder, getBase64Encoder } from '@solana/codecs-strings';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n} from '@solana/rpc-types';\n\nimport type { Account, BaseAccount, EncodedAccount } from './account';\nimport type { MaybeAccount, MaybeEncodedAccount } from './maybe-account';\nimport type { JsonParsedDataResponse } from './rpc-api';\n\ntype Base64EncodedRpcAccount = AccountInfoBase & AccountInfoWithBase64EncodedData;\n\n/**\n * Parses a base64-encoded account provided by the RPC client into an {@link EncodedAccount} type or\n * a {@link MaybeEncodedAccount} type if the raw data can be set to `null`.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n *\n * @example\n * ```ts\n * const myAddress = address('1234..5678');\n * const myRpcAccount = await rpc.getAccountInfo(myAddress, { encoding: 'base64' }).send();\n * const myAccount: MaybeEncodedAccount<'1234..5678'> = parseBase64RpcAccount(myRpcAccount);\n * ```\n */\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: Base64EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: Base64EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase64RpcAccount<TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: Base64EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n    if (!rpcAccount) return Object.freeze({ address, exists: false });\n    const data = getBase64Encoder().encode(rpcAccount.data[0]);\n    return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype Base58EncodedRpcAccount = AccountInfoBase & (AccountInfoWithBase58Bytes | AccountInfoWithBase58EncodedData);\n\n/**\n * Parses a base58-encoded account provided by the RPC client into an {@link EncodedAccount} type or\n * a {@link MaybeEncodedAccount} type if the raw data can be set to `null`.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n *\n * @example\n * ```ts\n * const myAddress = address('1234..5678');\n * const myRpcAccount = await rpc.getAccountInfo(myAddress, { encoding: 'base58' }).send();\n * const myAccount: MaybeEncodedAccount<'1234..5678'> = parseBase58RpcAccount(myRpcAccount);\n * ```\n */\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: Base58EncodedRpcAccount,\n): EncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: Base58EncodedRpcAccount | null,\n): MaybeEncodedAccount<TAddress>;\nexport function parseBase58RpcAccount<TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: Base58EncodedRpcAccount | null,\n): EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress> {\n    if (!rpcAccount) return Object.freeze({ address, exists: false });\n    const data = getBase58Encoder().encode(typeof rpcAccount.data === 'string' ? rpcAccount.data : rpcAccount.data[0]);\n    return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\ntype JsonParsedRpcAccount = AccountInfoBase & { readonly data: JsonParsedDataResponse<unknown> };\ntype ParsedAccountMeta = { program: string; type?: string };\ntype JsonParsedAccountData<TData extends object> = TData & { parsedAccountMeta?: ParsedAccountMeta };\n\n/**\n * Parses an arbitrary `jsonParsed` account provided by the RPC client into an {@link Account} type\n * or a {@link MaybeAccount} type if the raw data can be set to `null`.\n *\n * The expected data type should be explicitly provided as the first type parameter.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TData - The expected type of this account's data.\n *\n * @example\n * ```ts\n * const myAccount: Account<MyData> = parseJsonRpcAccount<MyData>(myJsonRpcAccount);\n * ```\n */\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: JsonParsedRpcAccount,\n): Account<JsonParsedAccountData<TData>, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: JsonParsedRpcAccount | null,\n): MaybeAccount<JsonParsedAccountData<TData>, TAddress>;\nexport function parseJsonRpcAccount<TData extends object, TAddress extends string = string>(\n    address: Address<TAddress>,\n    rpcAccount: JsonParsedRpcAccount | null,\n): Account<JsonParsedAccountData<TData>, TAddress> | MaybeAccount<JsonParsedAccountData<TData>, TAddress> {\n    if (!rpcAccount) return Object.freeze({ address, exists: false });\n    const data = (rpcAccount.data.parsed.info || {}) as TData;\n\n    if (rpcAccount.data.program || rpcAccount.data.parsed.type) {\n        (data as JsonParsedAccountData<TData>).parsedAccountMeta = {\n            program: rpcAccount.data.program,\n            type: rpcAccount.data.parsed.type,\n        };\n    }\n\n    return Object.freeze({ ...parseBaseAccount(rpcAccount), address, data, exists: true });\n}\n\nfunction parseBaseAccount(rpcAccount: AccountInfoBase): BaseAccount {\n    return Object.freeze({\n        executable: rpcAccount.executable,\n        lamports: rpcAccount.lamports,\n        programAddress: rpcAccount.owner,\n        space: rpcAccount.space,\n    });\n}\n"
  },
  {
    "path": "packages/accounts/src/rpc-api/common.ts",
    "content": "export type JsonParsedDataResponse<TData = object> = Readonly<{\n    parsed: {\n        info?: TData;\n        type: string;\n    };\n    // Name of the program that owns this account.\n    program: string;\n    space: bigint;\n}>;\n"
  },
  {
    "path": "packages/accounts/src/rpc-api/getAccountInfo.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithJsonData,\n    Commitment,\n    DataSlice,\n    Slot,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype GetAccountInfoApiResponseBase = SolanaRpcResponse<AccountInfoBase | null>;\n\ntype NestInRpcResponseOrNull<T> = Readonly<{\n    value: T | null;\n}>;\n\ntype GetAccountInfoApiCommonConfig = Readonly<{\n    /**\n     * Fetch the details of the account as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Determines how the account data should be encoded in the response.\n     *\n     * - `'base58'` returns a tuple whose first element is the data as a base58-encoded string. If\n     *   the account contains more than 129 bytes of data, an error will be raised.\n     * - `'base64'` returns a tuple whose first element is the data as a base64-encoded string.\n     * - `'base64+zstd'` returns a tuple whose first element is the\n     *   [ZStandard](https://facebook.github.io/zstd/)-compressed data as a base64-encoded string.\n     * - `'jsonParsed'` will cause the server to attempt to process the data using a parser specific\n     *   to the account's owning program. If successful, the parsed data will be returned in the\n     *   response as JSON. Otherwise, the raw account data will be returned in the response as a\n     *   tuple whose first element is a base64-encoded string.\n     */\n    encoding: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n}>;\n\ntype GetAccountInfoApiSliceableCommonConfig = Readonly<{\n    /**\n     * Define which slice of the account's data you want the RPC to return.\n     *\n     * Use this to save network bandwidth and encoding time when you do not need the entire buffer.\n     *\n     * Data slicing is only available for `\"base58\"`, `\"base64\"`, and `\"base64+zstd\"` encodings.\n     */\n    dataSlice?: DataSlice;\n}>;\n\nexport type GetAccountInfoApi = {\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, it will be returned in the response as a base64-encoded string.\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config: GetAccountInfoApiCommonConfig &\n            GetAccountInfoApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ): GetAccountInfoApiResponseBase & NestInRpcResponseOrNull<AccountInfoWithBase64EncodedData>;\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a base64-encoded string.\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config: GetAccountInfoApiCommonConfig &\n            GetAccountInfoApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n            }>,\n    ): GetAccountInfoApiResponseBase & NestInRpcResponseOrNull<AccountInfoWithBase64EncodedZStdCompressedData>;\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, the server will attempt to process it using a parser specific to the\n     * account's owning program. If successful, the parsed data will be returned in the response as\n     * JSON. Otherwise, the raw account data will be returned in the response as a base64-encoded\n     * string.\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config: GetAccountInfoApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ): GetAccountInfoApiResponseBase & NestInRpcResponseOrNull<AccountInfoWithJsonData>;\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, it will be returned in the response as a base58-encoded string. If\n     * the account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config: GetAccountInfoApiCommonConfig &\n            GetAccountInfoApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ): GetAccountInfoApiResponseBase & NestInRpcResponseOrNull<AccountInfoWithBase58EncodedData>;\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, it will be returned in the response as a base58-encoded string. If\n     * the account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * {@label base58-legacy}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config?: Omit<GetAccountInfoApiCommonConfig, 'encoding'>,\n    ): GetAccountInfoApiResponseBase & NestInRpcResponseOrNull<AccountInfoWithBase58Bytes>;\n};\n"
  },
  {
    "path": "packages/accounts/src/rpc-api/getMultipleAccounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithJsonData,\n    Commitment,\n    DataSlice,\n    Slot,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype GetMultipleAccountsApiResponseBase = AccountInfoBase | null;\n\ntype GetMultipleAccountsApiCommonConfig = Readonly<{\n    /**\n     * Fetch the details of the accounts as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Determines how the accounts' data should be encoded in the response.\n     *\n     * - `'base58'` returns a tuple whose first element is the data as a base58-encoded string. If\n     *   the account contains more than 129 bytes of data, an error will be raised.\n     * - `'base64'` returns a tuple whose first element is the data as a base64-encoded string.\n     * - `'base64+zstd'` returns a tuple whose first element is the\n     *   [ZStandard](https://facebook.github.io/zstd/)-compressed data as a base64-encoded string.\n     * - `'jsonParsed'` will cause the server to attempt to process the data using a parser specific\n     *   to each account's owning program. If successful, the parsed data will be returned in the\n     *   response as JSON. Otherwise, the raw account data will be returned in the response as a\n     *   tuple whose first element is a base64-encoded string.\n     */\n    encoding?: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n}>;\n\ntype GetMultipleAccountsApiSliceableCommonConfig = Readonly<{\n    /**\n     * Define which slice of the accounts' data you want the RPC to return.\n     *\n     * Use this to save network bandwidth and encoding time when you do not need the entire buffer.\n     *\n     * Data slicing is only available for `\"base58\"`, `\"base64\"`, and `\"base64+zstd\"` encodings.\n     */\n    dataSlice?: DataSlice;\n}>;\n\nexport type GetMultipleAccountsApi = {\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, it will be returned in the response as a tuple whose first element\n     * is a base64-encoded string.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: Address[],\n        config: GetMultipleAccountsApiCommonConfig &\n            GetMultipleAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ): SolanaRpcResponse<(GetMultipleAccountsApiResponseBase & (AccountInfoWithBase64EncodedData | null))[]>;\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: Address[],\n        config: GetMultipleAccountsApiCommonConfig &\n            GetMultipleAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n            }>,\n    ): SolanaRpcResponse<\n        (GetMultipleAccountsApiResponseBase & (AccountInfoWithBase64EncodedZStdCompressedData | null))[]\n    >;\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, the server will attempt to process it using a parser specific to\n     * each account's owning program. If successful, the parsed data will be returned in the\n     * response as JSON. Otherwise, the raw account data will be returned in the response as a tuple\n     * whose first element is a base64-encoded string.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: Address[],\n        config: GetMultipleAccountsApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ): SolanaRpcResponse<(GetMultipleAccountsApiResponseBase & (AccountInfoWithJsonData | null))[]>;\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, it will be returned in the response as a tuple whose first element\n     * is a base58-encoded string. If any account contains more than 129 bytes of data, this method\n     * will raise an error.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: Address[],\n        config: GetMultipleAccountsApiCommonConfig &\n            GetMultipleAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ): SolanaRpcResponse<(GetMultipleAccountsApiResponseBase & (AccountInfoWithBase58EncodedData | null))[]>;\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, it will be returned in the response as a base58-encoded string. If\n     * any account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label base58-legacy}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: Address[],\n        config?: GetMultipleAccountsApiCommonConfig,\n    ): SolanaRpcResponse<(GetMultipleAccountsApiResponseBase & (AccountInfoWithBase64EncodedData | null))[]>;\n};\n"
  },
  {
    "path": "packages/accounts/src/rpc-api/index.ts",
    "content": "export * from './common';\nexport * from './getAccountInfo';\nexport * from './getMultipleAccounts';\n"
  },
  {
    "path": "packages/accounts/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/accounts/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/accounts\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/accounts/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/addresses/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/addresses/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/addresses/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/addresses/CHANGELOG.md",
    "content": "# @solana/addresses\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/assertions@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/nominal-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/assertions@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/nominal-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/nominal-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/assertions@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/nominal-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/nominal-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/assertions@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/nominal-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/nominal-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/assertions@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/nominal-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/assertions@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/nominal-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/assertions@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-strings@6.1.0\n    - @solana/nominal-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/nominal-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/nominal-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/assertions@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/nominal-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/assertions@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/nominal-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-strings@5.4.0\n    - @solana/nominal-types@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/assertions@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/nominal-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/assertions@5.2.0\n    - @solana/nominal-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#1040](https://github.com/anza-xyz/kit/pull/1040) [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c) Thanks [@OrmEmbaar](https://github.com/OrmEmbaar)! - Add a function called bytesEqual to codecs-core that you can use to compare two byte arrays for equality.\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/assertions@5.1.0\n    - @solana/nominal-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/assertions@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-strings@5.0.0\n    - @solana/nominal-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/assertions@4.0.0\n    - @solana/codecs-strings@4.0.0\n    - @solana/nominal-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/assertions@3.0.0\n    - @solana/codecs-strings@3.0.0\n    - @solana/nominal-types@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/assertions@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-strings@2.3.0\n    - @solana/nominal-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/nominal-types@2.2.1\n\n## 2.2.0\n\n### Minor Changes\n\n- [`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893) Thanks [@nickfrosty](https://github.com/nickfrosty)! - Added an `OffCurveAddress` type to represent addresses for which there is no associated private key. These are addresses that can not be signed for by keyholders, only by programs. An example of such an address is the address of an associated token account, for which only the Token Program can sign transactions that seek to modify its contents.\n\n    Also added an `offCurveAddress()` function that you can use to assert and coerce an `Address` to an `OffCurveAddress`, as well as an `isOffCurveAddress()` guard function, and a `assertIsOffCurveAddress()` assertion function.\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/nominal-types@2.2.0\n    - @solana/assertions@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-strings@2.1.1\n    - @solana/nominal-types@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/assertions@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Minor Changes\n\n- [#117](https://github.com/anza-xyz/kit/pull/117) [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12) Thanks [@beeman](https://github.com/beeman)! - Add getPublicKeyFromAddress to derive public keys from addresses\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/assertions@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403) Thanks [@steveluscher](https://github.com/steveluscher)! - `isAddress()` no longer throws despite that the input might be unparseable as a base-58 string. Now, it correctly, simply, returns `false`.\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#2352](https://github.com/solana-labs/solana-web3.js/pull/2352) [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1) Thanks [@steveluscher](https://github.com/steveluscher)! - `SubtleCrypto` assertion methods that can make their assertions synchronously are now synchronous, for performance.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`441fa3a`](https://github.com/solana-labs/solana-web3.js/commit/441fa3a6c7c104961f935e65e259f40c10e82f8a), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/assertions@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/assertions@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403) Thanks [@steveluscher](https://github.com/steveluscher)! - `isAddress()` no longer throws despite that the input might be unparseable as a base-58 string. Now, it correctly, simply, returns `false`.\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`441fa3a`](https://github.com/solana-labs/solana-web3.js/commit/441fa3a6c7c104961f935e65e259f40c10e82f8a), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/assertions@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/assertions@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/assertions@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2352](https://github.com/solana-labs/solana-web3.js/pull/2352) [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1) Thanks [@steveluscher](https://github.com/steveluscher)! - `SubtleCrypto` assertion methods that can make their assertions synchronously are now synchronous, for performance.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/assertions@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/assertions@2.0.0-preview.2\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-strings@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/addresses/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/addresses/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/addresses?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/addresses?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/addresses\n\n# @solana/addresses\n\nThis package contains utilities for generating account addresses. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Types\n\n### `Address`\n\nThis type represents a string that validates as a Solana address. Functions that require well-formed addresses should specify their inputs in terms of this type.\n\nWhenever you need to validate an arbitrary string as a base58-encoded address, use the `address()`, `assertIsAddress()`, or `isAddress()` functions in this package.\n\n### `ProgramDerivedAddress`\n\nThis type represents the tuple of a program derived address and the bump seed used to ensure that the address, as derived, is not found on the Ed25519 curve.\n\nWhenever you need to validate an arbitrary tuple as one that represents a program derived address, use the `assertIsProgramDerivedAddress()` or `isProgramDerivedAddress()` functions in this package.\n\n### `ProgramDerivedAddressBump`\n\nThis type represents an integer between 0-255 used as a seed when deriving a program derived address. The purpose of this value is to modify the derivation enough to ensure that the derived address does not find itself on the Ed25519 curve.\n\n## Functions\n\n### `address()`\n\nThis helper combines _asserting_ that a string is an address with _coercing_ it to the `Address` type. It's best used with untrusted input.\n\n```ts\nimport { address } from '@solana/addresses';\n\nawait transfer(address(fromAddress), address(toAddress), lamports(100000n));\n```\n\nWhen starting from a known-good address as a string, it's more efficient to typecast it rather than to use the `address()` helper, because the helper unconditionally performs validation on its input.\n\n```ts\nimport { Address } from '@solana/addresses';\n\nconst MEMO_PROGRAM_ADDRESS =\n    'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr' as Address<'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'>;\n```\n\n### `assertIsAddress()`\n\nClient applications primarily deal with addresses and public keys in the form of base58-encoded strings. Addresses returned from the RPC API conform to the type `Address`. You can use a value of that type wherever a base58-encoded address is expected.\n\nFrom time to time you might acquire a string, that you expect to validate as an address, from an untrusted network API or user input. To assert that such an arbitrary string is a base58-encoded address, use the `assertIsAddress` function.\n\n```ts\nimport { assertIsAddress } from '@solana/addresses';\n\n// Imagine a function that fetches an account's balance when a user submits a form.\nfunction handleSubmit() {\n    // We know only that what the user typed conforms to the `string` type.\n    const address: string = accountAddressInput.value;\n    try {\n        // If this type assertion function doesn't throw, then\n        // Typescript will upcast `address` to `Address`.\n        assertIsAddress(address);\n        // At this point, `address` is an `Address` that can be used with the RPC.\n        const balanceInLamports = await rpc.getBalance(address).send();\n    } catch (e) {\n        // `address` turned out not to be a base58-encoded address\n    }\n}\n```\n\n### `assertIsProgramDerivedAddress()`\n\nIn the event that you receive an address/bump-seed tuple from some untrusted source, you can assert that such a tuple conforms to the `ProgramDerivedAddress` type using this function.\n\nSee [`assertIsAddress()`](#assertisaddress) for an example of how to use an assertion function.\n\n### `createAddressWithSeed()`\n\nReturns a base58-encoded address derived from some base address, some program address, and a seed string or byte array.\n\n```ts\nimport { createAddressWithSeed } from '@solana/addresses';\n\nconst derivedAddress = await createAddressWithSeed({\n    // The private key associated with this address will be able to sign for `derivedAddress`.\n    baseAddress: 'B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka' as Address,\n    // Only this program will be able to write data to this account.\n    programAddress: '445erYq578p2aERrGW9mn9KiYe3fuG6uHdcJ2LPPShGw' as Address,\n    seed: 'data-account',\n});\n```\n\n### `getAddressDecoder()`\n\nReturns a decoder that you can use to convert an array of 32 bytes representing an address to the base58-encoded representation of that address. Returns a tuple of the `Address` and the offset within the byte array at which the decoder stopped reading.\n\n```ts\nimport { getAddressDecoder } from '@solana/addresses';\n\nconst addressBytes = new Uint8Array([\n    150, 183, 190, 48, 171, 8, 39, 156, 122, 213, 172, 108, 193, 95, 26, 158, 149, 243, 115, 254, 20, 200, 36, 30, 248,\n    179, 178, 232, 220, 89, 53, 127,\n]);\nconst addressDecoder = getAddressDecoder();\nconst address = addressDecoder.decode(address); // B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka\n```\n\n### `getAddressEncoder()`\n\nReturns an encoder that you can use to encode a base58-encoded address to a byte array.\n\n```ts\nimport { getAddressEncoder } from '@solana/addresses';\n\nconst address = 'B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka' as Address;\nconst addressEncoder = getAddressEncoder();\nconst addressBytes = addressEncoder.encode(address);\n// Uint8Array(32) [\n//   150, 183, 190,  48, 171,   8, 39, 156,\n//   122, 213, 172, 108, 193,  95, 26, 158,\n//   149, 243, 115, 254,  20, 200, 36,  30,\n//   248, 179, 178, 232, 220,  89, 53, 127\n// ]\n```\n\n### `getAddressFromPublicKey()`\n\nGiven a public `CryptoKey`, this method will return its associated `Address`.\n\n```ts\nimport { getAddressFromPublicKey } from '@solana/addresses';\n\nconst address = await getAddressFromPublicKey(publicKey);\n```\n\n### `getProgramDerivedAddress()`\n\nGiven a program's `Address` and up to 16 `Seeds`, this method will return the program derived address (PDA) associated with each.\n\n```ts\nimport { getAddressEncoder, getProgramDerivedAddress } from '@solana/addresses';\n\nconst addressEncoder = getAddressEncoder();\nconst [pda, bumpSeed] = await getProgramDerivedAddress({\n    programAddress: 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL' as Address,\n    seeds: [\n        // Owner\n        addressEncoder.encode('9fYLFVoVqwH37C3dyPi6cpeobfbQ2jtLpN5HgAYDDdkm' as Address),\n        // Token program\n        addressEncoder.encode('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address),\n        // Mint\n        addressEncoder.encode('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' as Address),\n    ],\n});\n```\n\n### `isAddress()`\n\nThis is a type guard that accepts a string as input. It will both return `true` if the string conforms to the `Address` type and will refine the type for use in your program.\n\n```ts\nimport { isAddress } from '@solana/addresses';\n\nif (isAddress(ownerAddress)) {\n    // At this point, `ownerAddress` has been refined to a\n    // `Address` that can be used with the RPC.\n    const { value: lamports } = await rpc.getBalance(ownerAddress).send();\n    setBalanceLamports(lamports);\n} else {\n    setError(`${ownerAddress} is not an address`);\n}\n```\n\n### `isProgramDerivedAddress()`\n\nThis is a type guard that accepts a tuple as input. It will both return `true` if the tuple conforms to the `ProgramDerivedAddress` type and will refine the type for use in your program.\n\nSee [`isAddress()`](#isaddress) for an example of how to use a type guard.\n"
  },
  {
    "path": "packages/addresses/package.json",
    "content": "{\n    \"name\": \"@solana/addresses\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for generating account addresses\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaaddresses\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/assertions\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/nominal-types\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/addresses/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/addresses/src/__tests__/address-test.ts",
    "content": "import { VariableSizeEncoder } from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH,\n    SolanaError,\n} from '@solana/errors';\n\nimport { Address, getAddressCodec, getAddressComparator } from '../address';\n\njest.mock('@solana/codecs-strings', () => ({\n    ...jest.requireActual('@solana/codecs-strings'),\n    getBase58Decoder: jest.fn(),\n    getBase58Encoder: jest.fn(),\n}));\n// HACK: Pierce the veil of `jest.isolateModules` so that the modules inside get the same version of\n//       `@solana/errors` that is imported above.\njest.mock('@solana/errors', () => jest.requireActual('@solana/errors'));\n\n// real implementations\nconst originalBase58Module = jest.requireActual('@solana/codecs-strings');\nconst originalGetBase58Encoder = originalBase58Module.getBase58Encoder();\nconst originalGetBase58Decoder = originalBase58Module.getBase58Decoder();\n\ndescribe('Address', () => {\n    describe('isAddress()', () => {\n        let isAddress: typeof import('../address').isAddress;\n        // Reload `isAddress` before each test to reset memoized state\n        beforeEach(async () => {\n            await jest.isolateModulesAsync(async () => {\n                const base58ModulePromise =\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    // @ts-ignore\n                    import('../address');\n                isAddress = (await base58ModulePromise).isAddress;\n            });\n        });\n\n        describe('using the real base58 implementation', () => {\n            beforeEach(() => {\n                // use real implementation\n                jest.mocked(getBase58Encoder).mockReturnValue(originalGetBase58Encoder);\n            });\n            it('does not throw when supplied a non-base58 address', () => {\n                expect(() => {\n                    isAddress('not-a-base-58-encoded-string');\n                }).not.toThrow();\n            });\n            it('returns false when supplied a non-base58 string', () => {\n                expect(isAddress('not-a-base-58-encoded-string')).toBe(false);\n            });\n            it('returns false when the decoded byte array has a length other than 32 bytes', () => {\n                expect(\n                    isAddress(\n                        // 31 bytes [128, ..., 128]\n                        '2xea9jWJ9eca3dFiefTeSPP85c6qXqunCqL2h2JNffM',\n                    ),\n                ).toBe(false);\n            });\n            it('returns true when supplied a base-58 encoded address', () => {\n                expect(isAddress('11111111111111111111111111111111')).toBe(true);\n            });\n        });\n        describe('using a mock base58 implementation', () => {\n            const mockEncode = jest.fn();\n            beforeEach(() => {\n                // use mock implementation\n                mockEncode.mockClear();\n                jest.mocked(getBase58Encoder).mockReturnValue({\n                    encode: mockEncode,\n                } as unknown as VariableSizeEncoder<string>);\n            });\n\n            [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44].forEach(len => {\n                it(`attempts to encode input strings of exactly ${len} characters`, () => {\n                    try {\n                        isAddress('1'.repeat(len));\n                        // eslint-disable-next-line no-empty\n                    } catch {}\n                    expect(mockEncode).toHaveBeenCalled();\n                });\n            });\n            it('does not attempt to decode too-short input strings', () => {\n                try {\n                    isAddress(\n                        // 31 bytes [0, ..., 0]\n                        '1111111111111111111111111111111', // 31 characters\n                    );\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                expect(mockEncode).not.toHaveBeenCalled();\n            });\n            it('does not attempt to decode too-long input strings', () => {\n                try {\n                    isAddress(\n                        // 33 bytes [0, 255, ..., 255]\n                        '1JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG', // 45 characters\n                    );\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                expect(mockEncode).not.toHaveBeenCalled();\n            });\n            it('memoizes getBase58Encoder when called multiple times', () => {\n                try {\n                    isAddress('1'.repeat(32));\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                try {\n                    isAddress('1'.repeat(32));\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                expect(jest.mocked(getBase58Encoder)).toHaveBeenCalledTimes(1);\n            });\n        });\n    });\n\n    describe('assertIsAddress()', () => {\n        let assertIsAddress: typeof import('../address').assertIsAddress;\n        // Reload `assertIsAddress` before each test to reset memoized state\n        beforeEach(async () => {\n            await jest.isolateModulesAsync(async () => {\n                const base58ModulePromise =\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    // @ts-ignore\n                    import('../address');\n                assertIsAddress = (await base58ModulePromise).assertIsAddress;\n            });\n        });\n\n        describe('using the real base58 implementation', () => {\n            beforeEach(() => {\n                // use real implementation\n                jest.mocked(getBase58Encoder).mockReturnValue(originalGetBase58Encoder);\n            });\n            it('throws when supplied a non-base58 string', () => {\n                expect(() => {\n                    assertIsAddress('not-a-base-58-encoded-string');\n                }).toThrow(\n                    new SolanaError(SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE, {\n                        actualLength: 28,\n                    }),\n                );\n            });\n            it('throws when the decoded byte array has a length other than 32 bytes', () => {\n                expect(() => {\n                    assertIsAddress(\n                        // 31 bytes [128, ..., 128]\n                        '2xea9jWJ9eca3dFiefTeSPP85c6qXqunCqL2h2JNffM',\n                    );\n                }).toThrow(\n                    new SolanaError(SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH, {\n                        actualLength: 31,\n                    }),\n                );\n            });\n            it('does not throw when supplied a base-58 encoded address', () => {\n                expect(() => {\n                    assertIsAddress('11111111111111111111111111111111');\n                }).not.toThrow();\n            });\n            it('returns undefined when supplied a base-58 encoded address', () => {\n                expect(assertIsAddress('11111111111111111111111111111111')).toBeUndefined();\n            });\n        });\n        describe('using a mock base58 implementation', () => {\n            const mockEncode = jest.fn();\n            beforeEach(() => {\n                // use mock implementation\n                mockEncode.mockClear();\n                jest.mocked(getBase58Encoder).mockReturnValue({\n                    encode: mockEncode,\n                } as unknown as VariableSizeEncoder<string>);\n            });\n\n            [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44].forEach(len => {\n                it(`attempts to encode input strings of exactly ${len} characters`, () => {\n                    try {\n                        assertIsAddress('1'.repeat(len));\n                        // eslint-disable-next-line no-empty\n                    } catch {}\n                    expect(mockEncode).toHaveBeenCalled();\n                });\n            });\n            it('does not attempt to decode too-short input strings', () => {\n                try {\n                    assertIsAddress(\n                        // 31 bytes [0, ..., 0]\n                        '1111111111111111111111111111111', // 31 characters\n                    );\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                expect(mockEncode).not.toHaveBeenCalled();\n            });\n            it('does not attempt to decode too-long input strings', () => {\n                try {\n                    assertIsAddress(\n                        // 33 bytes [0, 255, ..., 255]\n                        '1JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG', // 45 characters\n                    );\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                expect(mockEncode).not.toHaveBeenCalled();\n            });\n            it('memoizes getBase58Encoder when called multiple times', () => {\n                try {\n                    assertIsAddress('1'.repeat(32));\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                try {\n                    assertIsAddress('1'.repeat(32));\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                expect(jest.mocked(getBase58Encoder)).toHaveBeenCalledTimes(1);\n            });\n        });\n    });\n\n    describe('getAddressCodec', () => {\n        let address: ReturnType<typeof getAddressCodec>;\n        beforeEach(() => {\n            // use real implementations\n            jest.mocked(getBase58Encoder).mockReturnValue(originalGetBase58Encoder);\n            jest.mocked(getBase58Decoder).mockReturnValue(originalGetBase58Decoder);\n\n            address = getAddressCodec();\n        });\n        it('serializes a base58 encoded address into a 32-byte buffer', () => {\n            expect(\n                address.encode(\n                    '4wBqpZM9xaSheZzJSMawUHDgZ7miWfSsxmfVF5jJpYP' as Address<'4wBqpZM9xaSheZzJSMawUKKwhdpChKbZ5eu5ky4Vigw'>,\n                ),\n            ).toEqual(\n                new Uint8Array([\n                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n                    0,\n                ]),\n            );\n        });\n        it('deserializes a byte buffer representing an address into a base58 encoded address', () => {\n            expect(\n                address.decode(\n                    new Uint8Array([\n                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n                        27, 28, 29, 30, 31, 32,\n                        // Followed by extra bytes not part of the address\n                        33, 34,\n                    ]),\n                ),\n            ).toBe(\n                '4wBqpZM9xaSheZzJSMawUKKwhdpChKbZ5eu5ky4Vigw' as Address<'4wBqpZM9xaSheZzJSMawUKKwhdpChKbZ5eu5ky4Vigw'>,\n            );\n        });\n        it('fatals when trying to deserialize a byte buffer shorter than 32-bytes', () => {\n            const tooShortBuffer = new Uint8Array(Array(31).fill(0));\n            expect(() => address.decode(tooShortBuffer)).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n                    bytesLength: 31,\n                    codecDescription: 'fixCodecSize',\n                    expected: 32,\n                }),\n            );\n        });\n        it('memoizes getBase58Encoder and getBase58Decoder when called multiple times', async () => {\n            expect.assertions(2);\n\n            // reload the module to reset memoized state\n            let getAddressCodec: typeof import('../address').getAddressCodec;\n            await jest.isolateModulesAsync(async () => {\n                const base58ModulePromise =\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    // @ts-ignore\n                    import('../address');\n                getAddressCodec = (await base58ModulePromise).getAddressCodec;\n            });\n\n            address = getAddressCodec!();\n            address.encode(\n                '4wBqpZM9xaSheZzJSMawUHDgZ7miWfSsxmfVF5jJpYP' as Address<'4wBqpZM9xaSheZzJSMawUKKwhdpChKbZ5eu5ky4Vigw'>,\n            );\n\n            address = getAddressCodec!();\n            address.encode(\n                '4wBqpZM9xaSheZzJSMawUHDgZ7miWfSsxmfVF5jJpYP' as Address<'4wBqpZM9xaSheZzJSMawUKKwhdpChKbZ5eu5ky4Vigw'>,\n            );\n\n            expect(jest.mocked(getBase58Encoder)).toHaveBeenCalledTimes(1);\n            expect(jest.mocked(getBase58Decoder)).toHaveBeenCalledTimes(1);\n        });\n    });\n\n    describe('getAddressComparator', () => {\n        it('sorts base 58 addresses', () => {\n            expect(\n                // These addresses were chosen such that sorting these conventionally (ie. using\n                // the default `Array.sort`) or numerically (ie. on the basis of the underlying\n                // numerical value of the address) would fail to produce the expected output. This\n                // exercises the 'specialness' of the base 58 encoded address comparator.\n                [\n                    'Ht1VrhoyhwMGMpBBi89BPdJp5R39Mu49suKx3A22W9Qs',\n                    'J9ZSLc9qPg3FR8UqfN6ae1QkVReUmnpLgQqFkGEPqmod',\n                    '6JYSQqSHY1E5JDwEfgWMieozqA1KCwiP2cH69to9eWKH',\n                    '7YR1xA7yzFAT4yQCsS4rpowjU1tsh5YUJd9hWMHRppcX',\n                    '7grJ9YUAEHxckLFqCY7fq8cM1UrragNSuPH1dvwJ8EEK',\n                    'AJBPNWCjVLwxff2eJynW56cMRCGmyU4y3vbuvtVdgVgb',\n                    'B8A2zUEDtJjR7nrokNUJYhgUQiwEBzC88rZc6WUE5ZeF',\n                    'BKggsVVp7yLmXtPuBDtC3FXBzvLyyye3Q2tFKUUGCHLj',\n                    'Ds72joawSKQ9nCDAAmGMKFiwiY6HR7PDzYDHDzZom3tj',\n                    'F1zKr4ZUYo5UAnH1fvYaD6R7ne137NYfS1r5HrCb8NpF',\n                ].sort(getAddressComparator()),\n            ).toEqual([\n                '6JYSQqSHY1E5JDwEfgWMieozqA1KCwiP2cH69to9eWKH',\n                '7grJ9YUAEHxckLFqCY7fq8cM1UrragNSuPH1dvwJ8EEK',\n                '7YR1xA7yzFAT4yQCsS4rpowjU1tsh5YUJd9hWMHRppcX',\n                'AJBPNWCjVLwxff2eJynW56cMRCGmyU4y3vbuvtVdgVgb',\n                'B8A2zUEDtJjR7nrokNUJYhgUQiwEBzC88rZc6WUE5ZeF',\n                'BKggsVVp7yLmXtPuBDtC3FXBzvLyyye3Q2tFKUUGCHLj',\n                'Ds72joawSKQ9nCDAAmGMKFiwiY6HR7PDzYDHDzZom3tj',\n                'F1zKr4ZUYo5UAnH1fvYaD6R7ne137NYfS1r5HrCb8NpF',\n                'Ht1VrhoyhwMGMpBBi89BPdJp5R39Mu49suKx3A22W9Qs',\n                'J9ZSLc9qPg3FR8UqfN6ae1QkVReUmnpLgQqFkGEPqmod',\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/addresses/src/__tests__/coercions-test.ts",
    "content": "import {\n    SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { Address, address } from '../address';\n\ndescribe('coercions', () => {\n    describe('address', () => {\n        it('can coerce to `Address`', () => {\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            const raw =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n            const coerced = address('GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G');\n            expect(coerced).toBe(raw);\n        });\n        it.each([31, 45])('throws given an address with length %s', actualLength => {\n            const thisThrows = () => address('3'.repeat(actualLength));\n            expect(thisThrows).toThrow(\n                new SolanaError(SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE, {\n                    actualLength,\n                }),\n            );\n        });\n        it.each([\n            [31, 'tVojvhToWjQ8Xvo4UPx2Xz9eRy7auyYMmZBjc2XfN'],\n            [33, 'JJEfe6DcPM2ziB2vfUWDV6aHVerXRGkv3TcyvJUNGHZz'],\n        ])('throws given an address that decodes to have %s bytes', (actualLength, badAddress) => {\n            const thisThrows = () => address(badAddress);\n            expect(thisThrows).toThrow(\n                new SolanaError(SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH, {\n                    actualLength,\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/addresses/src/__tests__/curve-test.ts",
    "content": "import {\n    SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { address } from '../address';\nimport { assertIsOffCurveAddress, isOffCurveAddress } from '../curve';\nimport { compressedPointBytesAreOnCurve } from '../curve-internal';\n\nconst OFF_CURVE_KEY_BYTES = [\n    new Uint8Array([\n        0, 121, 240, 130, 166, 28, 199, 78, 165, 226, 171, 237, 100, 187, 247, 95, 50, 251, 221, 83, 122, 255, 247, 82,\n        87, 237, 103, 22, 201, 227, 114, 153,\n    ]),\n    new Uint8Array([\n        194, 222, 197, 61, 68, 225, 252, 198, 155, 150, 247, 44, 45, 10, 115, 8, 12, 50, 138, 12, 106, 199, 75, 172,\n        159, 87, 94, 122, 251, 246, 136, 75,\n    ]),\n];\n\nconst ON_CURVE_KEY_BYTES = [\n    new Uint8Array([\n        107, 141, 87, 175, 101, 27, 216, 58, 238, 95, 193, 175, 21, 151, 207, 102, 28, 107, 157, 178, 69, 77, 203, 89,\n        199, 77, 162, 19, 27, 108, 57, 155,\n    ]),\n    new Uint8Array([\n        52, 94, 161, 109, 55, 62, 164, 12, 183, 165, 56, 112, 86, 103, 19, 109, 196, 33, 93, 42, 143, 6, 221, 172, 173,\n        21, 130, 96, 170, 101, 82, 200,\n    ]),\n];\n\nconst ON_CURVE_ADDRESSES = [\n    'nick6zJc6HpW3kfBm4xS2dmbuVRyb5F3AnUvj5ymzR5', // \"wallet\" account\n    '11111111111111111111111111111111', // system program\n    'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', // legacy token program\n    'SQDS4ep65T869zMMBKyuUq6aD6EgTu8psMjkvj52pCf', // Squads multi-sig program\n].map(address);\n\nconst OFF_CURVE_ADDRESSES = [\n    'CCMCWh4FudPEmY6Q1AVi5o8mQMXkHYkJUmZfzRGdcJ9P', // ATA\n    '2DRxyJDsDccGL6mb8PLMsKQTCU3C7xUq8aprz53VcW4k', // random Squads multi-sig account\n].map(address);\n\ndescribe('compressedPointBytesAreOnCurve', () => {\n    it.each(OFF_CURVE_KEY_BYTES)('returns false when a public key does not lie on the Ed25519 curve [%#]', bytes => {\n        expect(compressedPointBytesAreOnCurve(bytes)).toBe(false);\n    });\n    it.each(ON_CURVE_KEY_BYTES)('returns true when a public key lies on the Ed25519 curve [%#]', bytes => {\n        expect(compressedPointBytesAreOnCurve(bytes)).toBe(true);\n    });\n});\n\ndescribe('isOffCurveAddress', () => {\n    it.each(OFF_CURVE_ADDRESSES)('returns true when an address does not lie on the Ed25519 curve [%#]', address => {\n        expect(isOffCurveAddress(address)).toBe(true);\n    });\n    it.each(ON_CURVE_ADDRESSES)('returns false when an address lies on the Ed25519 curve [%#]', address => {\n        expect(isOffCurveAddress(address)).toBe(false);\n    });\n    it('throws when supplied a non-base58 string', () => {\n        expect(() => {\n            assertIsOffCurveAddress(\n                // @ts-expect-error Pass corrupt data for the sake of this test.\n                'not-a-base-58-encoded-string',\n            );\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE, {\n                actualLength: 28,\n            }),\n        );\n    });\n    it('throws when the decoded byte array has a length other than 32 bytes', () => {\n        expect(() => {\n            assertIsOffCurveAddress(\n                // 31 bytes [128, ..., 128]\n                // @ts-expect-error Pass corrupt data for the sake of this test.\n                '2xea9jWJ9eca3dFiefTeSPP85c6qXqunCqL2h2JNffM',\n            );\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH, {\n                actualLength: 31,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/addresses/src/__tests__/program-derived-address-test.ts",
    "content": "import {\n    SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED,\n    SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED,\n    SOLANA_ERROR__ADDRESSES__PDA_ENDS_WITH_PDA_MARKER,\n    SolanaError,\n} from '@solana/errors';\n\nimport { Address } from '../address';\nimport { createAddressWithSeed, getProgramDerivedAddress } from '../program-derived-address';\n\ndescribe('getProgramDerivedAddress()', () => {\n    it('fatals when supplied more than 16 seeds', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: 'FN2R9R724eb4WaxeDmDYrUtmJgoSzkBiQMEHELV3ocyg' as Address,\n                seeds: Array(17).fill(''),\n            }),\n        ).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED, {\n                actual: 18, // With bump.\n                maxSeeds: 16,\n            }),\n        );\n    });\n    it.each([new Uint8Array(Array(33).fill(0)), 'a'.repeat(33)])(\n        'fatals when supplied a seed that is 33 bytes long',\n        async oversizedSeed => {\n            expect.assertions(1);\n            await expect(\n                getProgramDerivedAddress({\n                    programAddress: '5eUi55m4FVaDqKubGH9r6ca1TxjmimmXEU9v1WUZJ47Z' as Address,\n                    seeds: [oversizedSeed],\n                }),\n            ).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED, {\n                    actual: 33,\n                    index: 0,\n                    maxSeedLength: 32,\n                }),\n            );\n        },\n    );\n    it('returns a program derived address given a program address and no seeds', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: 'CZ3TbkgUYpDAJVEWpujQhDSgzNTeqbokrJmYa1j4HAZc' as Address,\n                seeds: [],\n            }),\n        ).resolves.toStrictEqual(['9tVtkyCGAHSDDBPwz7895aC3p2gJRjpu2v26o35FTUco', 255]);\n    });\n    it('returns a program derived address after having tried multiple bump seeds given a program address and no seeds', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: 'EfTbwNBrSqSuCNBhWUHsBoBdSMWgRU1S47daqRNgW7aK' as Address,\n                seeds: [],\n            }),\n        ).resolves.toStrictEqual(['CKWT8KZ5GMzKpVRiAULWKPg1LiHt9U3NdAtbuTErHCTq', 251]);\n    });\n    it('returns a program derived address given a program address and a byte-array seed', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: 'FD3PDEvpQ9JXq8tv7FpJPyZrCjWkCnAaTju16gFPdpqP' as Address,\n                seeds: [new Uint8Array([1, 2, 3])],\n            }),\n        ).resolves.toStrictEqual(['9Tj3hpMWacDiZoBe94sjwJQ72zsUVvEQYsrqyy2CfHky', 255]);\n    });\n    it('returns a program derived address after having tried multiple bump seeds given a program address and a byte-array seed', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: '9HT3iB4oX1aZPH5V8eNUGByKuwhfcKjBQ3x9rfEAuNeF' as Address,\n                seeds: [new Uint8Array([1, 2, 3])],\n            }),\n        ).resolves.toStrictEqual(['EeTcRajHcPh74C5D4GqZePac1wYB7Dj9ChTaNHaTH77V', 251]);\n    });\n    it('returns a program derived address given a program address and a string seed', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: 'EKaNRGA37uiGRyRPMap5EZg9cmbT5mt7KWrGwKwAQ3rK' as Address,\n                seeds: ['hello'],\n            }),\n        ).resolves.toStrictEqual(['6V76gtKMCmVVjrx4sxR9uB868HtZbL3piKEmadC7rSgf', 255]);\n    });\n    it('returns a program derived address after having tried multiple bump seeds given a program address and a string seed', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: '9PyoV2rqNtoboSvg2JD7GWhM5RQvHGwgdDvK7MCfpgX1' as Address,\n                seeds: ['hello'],\n            }),\n        ).resolves.toStrictEqual(['E6npEurFu1UEbQFh1DsqBvny17XxUK2QPMgxD3Edn3aG', 251]);\n    });\n    it('returns a program derived address given a program address and a UTF-8 string seed', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: 'A5dcVPLJsE2vbf7hkqqyYkYDK9UjUfNxuwGtWF2m2vEz' as Address,\n                seeds: ['\\uD83D\\uDE80'],\n            }),\n        ).resolves.toStrictEqual(['GYpAzW57Ex4Sw3rp4pq95QrjvtsDyqZsMhSZwqz3NMsE', 255]);\n    });\n    it('returns a program derived address after having tried multiple bump seeds given a program address and a UTF-8 string seed', async () => {\n        expect.assertions(1);\n        await expect(\n            getProgramDerivedAddress({\n                programAddress: 'H8gBP21L5ietkHgXcGbgQBCVVEdPUQyuP9Q5MPRLLSJu' as Address,\n                seeds: ['\\uD83D\\uDE80'],\n            }),\n        ).resolves.toStrictEqual(['46v3JvPtEPeQmH3euXydEbxYD6yfxeZjWSzkkYvvM5Pp', 251]);\n    });\n    it('returns the same result given a program address and two different seed inputs that concatenate to the same bytes', async () => {\n        expect.assertions(1);\n        const [pdaButterfly, pdaButterFly] = await Promise.all([\n            getProgramDerivedAddress({\n                programAddress: '9PyoV2rqNtoboSvg2JD7GWhM5RQvHGwgdDvK7MCfpgX1' as Address,\n                seeds: ['butterfly'],\n            }),\n            getProgramDerivedAddress({\n                programAddress: '9PyoV2rqNtoboSvg2JD7GWhM5RQvHGwgdDvK7MCfpgX1' as Address,\n                seeds: ['butter', 'fly'],\n            }),\n        ]);\n        expect(pdaButterfly).toStrictEqual(pdaButterFly);\n    });\n    // https://solana.stackexchange.com/questions/7253/what-combination-of-program-address-and-seeds-would-cause-findprogramaddress-t\n    it.todo(\n        'fatals when supplied a combination of program address and seeds for which no off-curve point can be found',\n    );\n});\n\ndescribe('createAddressWithSeed', () => {\n    it('returns an address that is the SHA-256 hash of the concatenated base address, seed, and program address', async () => {\n        expect.assertions(2);\n        const baseAddress = 'Bh1uUDP3ApWLeccVNHwyQKpnfGQbuE2UECbGA6M4jiZJ' as Address;\n        const programAddress = 'FGrddpvjBUAG6VdV4fR8Q2hEZTHS6w4SEveVBgfwbfdm' as Address;\n        const expectedAddress = 'HUKxCeXY6gZohFJFARbLE6L6C9wDEHz1SfK8ENM7QY7z' as Address;\n\n        await expect(createAddressWithSeed({ baseAddress, programAddress, seed: 'seed' })).resolves.toEqual(\n            expectedAddress,\n        );\n\n        await expect(\n            createAddressWithSeed({ baseAddress, programAddress, seed: new Uint8Array([0x73, 0x65, 0x65, 0x64]) }),\n        ).resolves.toEqual(expectedAddress);\n    });\n    it('fails when the seed is longer than 32 bytes', async () => {\n        expect.assertions(1);\n        const baseAddress = 'Bh1uUDP3ApWLeccVNHwyQKpnfGQbuE2UECbGA6M4jiZJ' as Address;\n        const programAddress = 'FGrddpvjBUAG6VdV4fR8Q2hEZTHS6w4SEveVBgfwbfdm' as Address;\n\n        await expect(createAddressWithSeed({ baseAddress, programAddress, seed: 'a'.repeat(33) })).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED, {\n                actual: 33,\n                index: 0,\n                maxSeedLength: 32,\n            }),\n        );\n    });\n    it('fails with a malicious programAddress meant to produce an address that would collide with a PDA', async () => {\n        expect.assertions(1);\n        const baseAddress = 'Bh1uUDP3ApWLeccVNHwyQKpnfGQbuE2UECbGA6M4jiZJ' as Address;\n        // The ending bytes of this address decode to the ASCII string 'ProgramDerivedAddress'\n        const programAddress = '4vJ9JU1bJJE96FbKdjWme2JfVK1knU936FHTDZV7AC2' as Address;\n\n        await expect(createAddressWithSeed({ baseAddress, programAddress, seed: 'seed' })).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__ADDRESSES__PDA_ENDS_WITH_PDA_MARKER),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/addresses/src/__tests__/public-key-test.ts",
    "content": "import { address } from '../address';\nimport { getAddressFromPublicKey, getPublicKeyFromAddress } from '../public-key';\n\n// Corresponds to address `DcESq8KFcdTdpjWtr2DoGcvu5McM3VJoBetgM1X1vVct`\nconst MOCK_PUBLIC_KEY_BYTES = new Uint8Array([\n    0xbb, 0x52, 0xc6, 0x2d, 0x52, 0x4f, 0x7f, 0xea, 0x4f, 0x2c, 0x27, 0x13, 0xd6, 0x20, 0x80, 0xad, 0x6a, 0x36, 0x9a,\n    0x0e, 0x36, 0x71, 0x74, 0x32, 0x8d, 0x1a, 0xf7, 0xee, 0x7e, 0x04, 0x76, 0x19,\n]);\n\ndescribe('getAddressFromPublicKey', () => {\n    it('returns the public key that corresponds to a given secret key', async () => {\n        expect.assertions(1);\n        const publicKey = await crypto.subtle.importKey(\n            'raw',\n            MOCK_PUBLIC_KEY_BYTES,\n            'Ed25519',\n            /* extractable */ true,\n            ['verify'],\n        );\n        await expect(getAddressFromPublicKey(publicKey)).resolves.toBe('DcESq8KFcdTdpjWtr2DoGcvu5McM3VJoBetgM1X1vVct');\n    });\n    it('throws when the public key is non-extractable', async () => {\n        expect.assertions(1);\n        const publicKey = await crypto.subtle.importKey(\n            'raw',\n            MOCK_PUBLIC_KEY_BYTES,\n            'Ed25519',\n            /* extractable */ false,\n            ['verify'],\n        );\n        await expect(() => getAddressFromPublicKey(publicKey)).rejects.toThrow();\n    });\n    it('throws when called with a secret', async () => {\n        expect.assertions(1);\n        const publicKey = await crypto.subtle.generateKey(\n            {\n                length: 256,\n                name: 'AES-GCM',\n            },\n            true,\n            ['encrypt', 'decrypt'],\n        );\n        await expect(() => getAddressFromPublicKey(publicKey)).rejects.toThrow();\n    });\n    it.each([\n        { __variant: 'P256', name: 'ECDSA', namedCurve: 'P-256' },\n        { __variant: 'P384', name: 'ECDSA', namedCurve: 'P-384' } as EcKeyGenParams,\n        { __variant: 'P521', name: 'ECDSA', namedCurve: 'P-521' } as EcKeyGenParams,\n        ...['RSASSA-PKCS1-v1_5', 'RSA-PSS'].flatMap(rsaAlgoName =>\n            ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'].map(\n                hashName =>\n                    ({\n                        __variant: hashName,\n                        hash: { name: hashName },\n                        modulusLength: 2048,\n                        name: rsaAlgoName,\n                        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n                    }) as RsaHashedKeyGenParams,\n            ),\n        ),\n    ])(\n        'throws when called with a $name/$__variant public key',\n        async algorithm => {\n            expect.assertions(1);\n            const { publicKey } = await crypto.subtle.generateKey(algorithm, true, ['sign', 'verify']);\n            await expect(() => getAddressFromPublicKey(publicKey)).rejects.toThrow();\n        },\n        10_000 /* Increase `timeout` to 10 seconds; GitHub Actions runner is really slow. */,\n    );\n    it('throws when called with a private key', async () => {\n        expect.assertions(1);\n        const mockPrivateKey = await crypto.subtle.importKey(\n            'pkcs8',\n            new Uint8Array([\n                0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20, 0xf2,\n                0x29, 0xe0, 0x33, 0x09, 0x44, 0x10, 0xd9, 0x64, 0x80, 0x42, 0x85, 0x9a, 0x18, 0x5c, 0x4a, 0x45, 0x45,\n                0xd9, 0xd1, 0x75, 0xeb, 0x30, 0x89, 0xb4, 0x2b, 0x7b, 0xe3, 0xca, 0xbf, 0x63, 0xc9,\n            ]),\n            'Ed25519',\n            /* extractable */ false,\n            ['sign'],\n        );\n        await expect(() => getAddressFromPublicKey(mockPrivateKey)).rejects.toThrow();\n    });\n});\n\ndescribe('getPublicKeyFromAddress', () => {\n    it('returns the public key that corresponds to a given address', async () => {\n        expect.assertions(1);\n        const publicKey = await getPublicKeyFromAddress(address('DcESq8KFcdTdpjWtr2DoGcvu5McM3VJoBetgM1X1vVct'));\n        expect(new Uint8Array(await crypto.subtle.exportKey('raw', publicKey))).toEqual(MOCK_PUBLIC_KEY_BYTES);\n    });\n});\n"
  },
  {
    "path": "packages/addresses/src/__typetests__/coercions-typetest.ts",
    "content": "import { AffinePoint, Brand, EncodedString } from '@solana/nominal-types';\n\nimport { Address, address } from '../address';\nimport { assertIsOffCurveAddress, isOffCurveAddress, OffCurveAddress, offCurveAddress } from '../curve';\n\naddress('555555555555555555555555') satisfies Address<'555555555555555555555555'>;\naddress('555555555555555555555555') satisfies Brand<'555555555555555555555555', 'Address'>;\naddress('555555555555555555555555') satisfies EncodedString<'555555555555555555555555', 'base58'>;\n\nconst addressWithUnknownValidity = address('555555555555555555555555') as Address<'555555555555555555555555'> & {\n    some: 1;\n};\noffCurveAddress(addressWithUnknownValidity) satisfies Address<'555555555555555555555555'>;\noffCurveAddress(addressWithUnknownValidity) satisfies AffinePoint<'555555555555555555555555', 'invalid'>;\noffCurveAddress(addressWithUnknownValidity) satisfies Brand<'555555555555555555555555', 'Address'>;\noffCurveAddress(addressWithUnknownValidity) satisfies EncodedString<'555555555555555555555555', 'base58'>;\noffCurveAddress(addressWithUnknownValidity) satisfies OffCurveAddress<'555555555555555555555555'>;\noffCurveAddress(addressWithUnknownValidity) satisfies { some: 1 };\n\nvoid (() => {\n    assertIsOffCurveAddress(addressWithUnknownValidity);\n    addressWithUnknownValidity satisfies Address<'555555555555555555555555'>;\n    addressWithUnknownValidity satisfies AffinePoint<'555555555555555555555555', 'invalid'>;\n    addressWithUnknownValidity satisfies Brand<'555555555555555555555555', 'Address'>;\n    addressWithUnknownValidity satisfies EncodedString<'555555555555555555555555', 'base58'>;\n    addressWithUnknownValidity satisfies OffCurveAddress<'555555555555555555555555'>;\n    addressWithUnknownValidity satisfies { some: 1 };\n});\n\nif (isOffCurveAddress(addressWithUnknownValidity)) {\n    addressWithUnknownValidity satisfies Address<'555555555555555555555555'>;\n    addressWithUnknownValidity satisfies AffinePoint<'555555555555555555555555', 'invalid'>;\n    addressWithUnknownValidity satisfies Brand<'555555555555555555555555', 'Address'>;\n    addressWithUnknownValidity satisfies EncodedString<'555555555555555555555555', 'base58'>;\n    addressWithUnknownValidity satisfies OffCurveAddress<'555555555555555555555555'>;\n    addressWithUnknownValidity satisfies { some: 1 };\n}\n"
  },
  {
    "path": "packages/addresses/src/address.ts",
    "content": "import {\n    combineCodec,\n    Decoder,\n    Encoder,\n    fixDecoderSize,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    fixEncoderSize,\n    transformEncoder,\n} from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\n/**\n * Represents a string that validates as a Solana address. Functions that require well-formed\n * addresses should specify their inputs in terms of this type.\n *\n * Whenever you need to validate an arbitrary string as a base58-encoded address, use the\n * {@link address}, {@link assertIsAddress}, or {@link isAddress} functions in this package.\n */\nexport type Address<TAddress extends string = string> = Brand<EncodedString<TAddress, 'base58'>, 'Address'>;\n\nlet memoizedBase58Encoder: Encoder<string> | undefined;\nlet memoizedBase58Decoder: Decoder<string> | undefined;\n\nfunction getMemoizedBase58Encoder(): Encoder<string> {\n    if (!memoizedBase58Encoder) memoizedBase58Encoder = getBase58Encoder();\n    return memoizedBase58Encoder;\n}\n\nfunction getMemoizedBase58Decoder(): Decoder<string> {\n    if (!memoizedBase58Decoder) memoizedBase58Decoder = getBase58Decoder();\n    return memoizedBase58Decoder;\n}\n\n/**\n * A type guard that returns `true` if the input string conforms to the {@link Address} type, and\n * refines its type for use in your program.\n *\n * @example\n * ```ts\n * import { isAddress } from '@solana/addresses';\n *\n * if (isAddress(ownerAddress)) {\n *     // At this point, `ownerAddress` has been refined to a\n *     // `Address` that can be used with the RPC.\n *     const { value: lamports } = await rpc.getBalance(ownerAddress).send();\n *     setBalanceLamports(lamports);\n * } else {\n *     setError(`${ownerAddress} is not an address`);\n * }\n * ```\n */\nexport function isAddress(putativeAddress: string): putativeAddress is Address<typeof putativeAddress> {\n    // Fast-path; see if the input string is of an acceptable length.\n    if (\n        // Lowest address (32 bytes of zeroes)\n        putativeAddress.length < 32 ||\n        // Highest address (32 bytes of 255)\n        putativeAddress.length > 44\n    ) {\n        return false;\n    }\n    // Slow-path; actually attempt to decode the input string.\n    const base58Encoder = getMemoizedBase58Encoder();\n    try {\n        return base58Encoder.encode(putativeAddress).byteLength === 32;\n    } catch {\n        return false;\n    }\n}\n\n/**\n * From time to time you might acquire a string, that you expect to validate as an address or public\n * key, from an untrusted network API or user input. Use this function to assert that such an\n * arbitrary string is a base58-encoded address.\n *\n * @example\n * ```ts\n * import { assertIsAddress } from '@solana/addresses';\n *\n * // Imagine a function that fetches an account's balance when a user submits a form.\n * function handleSubmit() {\n *     // We know only that what the user typed conforms to the `string` type.\n *     const address: string = accountAddressInput.value;\n *     try {\n *         // If this type assertion function doesn't throw, then\n *         // Typescript will upcast `address` to `Address`.\n *         assertIsAddress(address);\n *         // At this point, `address` is an `Address` that can be used with the RPC.\n *         const balanceInLamports = await rpc.getBalance(address).send();\n *     } catch (e) {\n *         // `address` turned out not to be a base58-encoded address\n *     }\n * }\n * ```\n */\nexport function assertIsAddress(putativeAddress: string): asserts putativeAddress is Address<typeof putativeAddress> {\n    // Fast-path; see if the input string is of an acceptable length.\n    if (\n        // Lowest address (32 bytes of zeroes)\n        putativeAddress.length < 32 ||\n        // Highest address (32 bytes of 255)\n        putativeAddress.length > 44\n    ) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE, {\n            actualLength: putativeAddress.length,\n        });\n    }\n    // Slow-path; actually attempt to decode the input string.\n    const base58Encoder = getMemoizedBase58Encoder();\n    const bytes = base58Encoder.encode(putativeAddress);\n    const numBytes = bytes.byteLength;\n    if (numBytes !== 32) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH, {\n            actualLength: numBytes,\n        });\n    }\n}\n\n/**\n * Combines _asserting_ that a string is an address with _coercing_ it to the {@link Address} type.\n * It's most useful with untrusted input.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n *\n * await transfer(address(fromAddress), address(toAddress), lamports(100000n));\n * ```\n *\n * > [!TIP]\n * > When starting from a known-good address as a string, it's more efficient to typecast it rather\n * than to use the {@link address} helper, because the helper unconditionally performs validation on\n * its input.\n * >\n * > ```ts\n * > import { Address } from '@solana/addresses';\n * >\n * > const MEMO_PROGRAM_ADDRESS =\n * >     'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr' as Address<'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'>;\n * > ```\n */\nexport function address<TAddress extends string = string>(putativeAddress: TAddress): Address<TAddress> {\n    assertIsAddress(putativeAddress);\n    return putativeAddress as Address<TAddress>;\n}\n\n/**\n * Returns an encoder that you can use to encode a base58-encoded address to a byte array.\n *\n * @example\n * ```ts\n * import { getAddressEncoder } from '@solana/addresses';\n *\n * const address = 'B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka' as Address;\n * const addressEncoder = getAddressEncoder();\n * const addressBytes = addressEncoder.encode(address);\n * // Uint8Array(32) [\n * //   150, 183, 190,  48, 171,   8, 39, 156,\n * //   122, 213, 172, 108, 193,  95, 26, 158,\n * //   149, 243, 115, 254,  20, 200, 36,  30,\n * //   248, 179, 178, 232, 220,  89, 53, 127\n * // ]\n * ```\n */\nexport function getAddressEncoder(): FixedSizeEncoder<Address, 32> {\n    return transformEncoder(fixEncoderSize(getMemoizedBase58Encoder(), 32), putativeAddress =>\n        address(putativeAddress),\n    );\n}\n\n/**\n * Returns a decoder that you can use to convert an array of 32 bytes representing an address to the\n * base58-encoded representation of that address.\n *\n * @example\n * ```ts\n * import { getAddressDecoder } from '@solana/addresses';\n *\n * const addressBytes = new Uint8Array([\n *     150, 183, 190,  48, 171,   8, 39, 156,\n *     122, 213, 172, 108, 193,  95, 26, 158,\n *     149, 243, 115, 254,  20, 200, 36,  30,\n *     248, 179, 178, 232, 220,  89, 53, 127\n * ]);\n * const addressDecoder = getAddressDecoder();\n * const address = addressDecoder.decode(addressBytes); // B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka\n * ```\n */\nexport function getAddressDecoder(): FixedSizeDecoder<Address, 32> {\n    return fixDecoderSize(getMemoizedBase58Decoder(), 32) as FixedSizeDecoder<Address, 32>;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a base-58 encoded address.\n *\n * @see {@link getAddressDecoder}\n * @see {@link getAddressEncoder}\n */\nexport function getAddressCodec(): FixedSizeCodec<Address, Address, 32> {\n    return combineCodec(getAddressEncoder(), getAddressDecoder());\n}\n\nexport function getAddressComparator(): (x: string, y: string) => number {\n    return new Intl.Collator('en', {\n        caseFirst: 'lower',\n        ignorePunctuation: false,\n        localeMatcher: 'best fit',\n        numeric: false,\n        sensitivity: 'variant',\n        usage: 'sort',\n    }).compare;\n}\n"
  },
  {
    "path": "packages/addresses/src/curve-internal.ts",
    "content": "import { ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { pointIsOnCurve } from './vendor/noble/ed25519';\n\nfunction byteToHex(byte: number): string {\n    const hexString = byte.toString(16);\n    if (hexString.length === 1) {\n        return `0${hexString}`;\n    } else {\n        return hexString;\n    }\n}\n\nfunction decompressPointBytes(bytes: ReadonlyUint8Array): bigint {\n    const hexString = bytes.reduce((acc, byte, ii) => `${byteToHex(ii === 31 ? byte & ~0x80 : byte)}${acc}`, '');\n    const integerLiteralString = `0x${hexString}`;\n    return BigInt(integerLiteralString);\n}\n\nexport function compressedPointBytesAreOnCurve(bytes: ReadonlyUint8Array): boolean {\n    if (bytes.byteLength !== 32) {\n        return false;\n    }\n    const y = decompressPointBytes(bytes);\n    return pointIsOnCurve(y, bytes[31]);\n}\n"
  },
  {
    "path": "packages/addresses/src/curve.ts",
    "content": "import { SOLANA_ERROR__ADDRESSES__INVALID_OFF_CURVE_ADDRESS, SolanaError } from '@solana/errors';\nimport type { AffinePoint } from '@solana/nominal-types';\n\nimport { type Address, getAddressCodec } from './address';\nimport { compressedPointBytesAreOnCurve } from './curve-internal';\n\n/**\n * Represents an {@link Address} that validates as being off-curve. Functions that require off-curve\n * addresses should specify their inputs in terms of this type.\n *\n * Whenever you need to validate an address as being off-curve, use the {@link offCurveAddress},\n * {@link assertIsOffCurveAddress}, or {@link isOffCurveAddress} functions in this package.\n */\nexport type OffCurveAddress<TAddress extends string = string> = AffinePoint<Address<TAddress>, 'invalid'>;\n\n/**\n * A type guard that returns `true` if the input address conforms to the {@link OffCurveAddress}\n * type, and refines its type for use in your application.\n *\n * @example\n * ```ts\n * import { isOffCurveAddress } from '@solana/addresses';\n *\n * if (isOffCurveAddress(accountAddress)) {\n *     // At this point, `accountAddress` has been refined to a\n *     // `OffCurveAddress` that can be used within your business logic.\n *     const { value: account } = await rpc.getAccountInfo(accountAddress).send();\n * } else {\n *     setError(`${accountAddress} is not off-curve`);\n * }\n * ```\n */\nexport function isOffCurveAddress<TAddress extends Address>(\n    putativeOffCurveAddress: TAddress,\n): putativeOffCurveAddress is OffCurveAddress<TAddress> {\n    const addressBytes = getAddressCodec().encode(putativeOffCurveAddress);\n    return compressedPointBytesAreOnCurve(addressBytes) === false;\n}\n\n/**\n * From time to time you might acquire an {@link Address}, that you expect to validate as an\n * off-curve address, from an untrusted source. Use this function to assert that such an address is\n * off-curve.\n *\n * @example\n * ```ts\n * import { assertIsOffCurveAddress } from '@solana/addresses';\n *\n * // Imagine a function that fetches an account's balance when a user submits a form.\n * function handleSubmit() {\n *     // We know only that the input conforms to the `string` type.\n *     const address: string = accountAddressInput.value;\n *     try {\n *         // If this type assertion function doesn't throw, then\n *         // Typescript will upcast `address` to `Address`.\n *         assertIsAddress(address);\n *         // If this type assertion function doesn't throw, then\n *         // Typescript will upcast `address` to `OffCurveAddress`.\n *         assertIsOffCurveAddress(address);\n *         // At this point, `address` is an `OffCurveAddress` that can be used with the RPC.\n *         const balanceInLamports = await rpc.getBalance(address).send();\n *     } catch (e) {\n *         // `address` turned out to NOT be a base58-encoded off-curve address\n *     }\n * }\n * ```\n */\nexport function assertIsOffCurveAddress<TAddress extends Address>(\n    putativeOffCurveAddress: TAddress,\n): asserts putativeOffCurveAddress is OffCurveAddress<TAddress> {\n    if (!isOffCurveAddress(putativeOffCurveAddress)) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__INVALID_OFF_CURVE_ADDRESS);\n    }\n}\n\n/**\n * Combines _asserting_ that an {@link Address} is off-curve with _coercing_ it to the\n * {@link OffCurveAddress} type. It's most useful with untrusted input.\n */\nexport function offCurveAddress<TAddress extends Address>(\n    putativeOffCurveAddress: TAddress,\n): OffCurveAddress<TAddress> {\n    assertIsOffCurveAddress(putativeOffCurveAddress);\n    return putativeOffCurveAddress;\n}\n"
  },
  {
    "path": "packages/addresses/src/index.ts",
    "content": "/**\n * This package contains utilities for generating account addresses. It can be used standalone, but\n * it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './address';\nexport * from './curve';\nexport * from './program-derived-address';\nexport * from './public-key';\n"
  },
  {
    "path": "packages/addresses/src/program-derived-address.ts",
    "content": "import { assertDigestCapabilityIsAvailable } from '@solana/assertions';\nimport { bytesEqual, type ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    isSolanaError,\n    SOLANA_ERROR__ADDRESSES__FAILED_TO_FIND_VIABLE_PDA_BUMP_SEED,\n    SOLANA_ERROR__ADDRESSES__INVALID_SEEDS_POINT_ON_CURVE,\n    SOLANA_ERROR__ADDRESSES__MALFORMED_PDA,\n    SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED,\n    SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED,\n    SOLANA_ERROR__ADDRESSES__PDA_BUMP_SEED_OUT_OF_RANGE,\n    SOLANA_ERROR__ADDRESSES__PDA_ENDS_WITH_PDA_MARKER,\n    SolanaError,\n} from '@solana/errors';\nimport { Brand } from '@solana/nominal-types';\n\nimport { Address, assertIsAddress, getAddressCodec, isAddress } from './address';\nimport { compressedPointBytesAreOnCurve } from './curve-internal';\n\n/**\n * A tuple representing a program derived address (derived from the address of some program and a\n * set of seeds) and the associated bump seed used to ensure that the address, as derived, does not\n * fall on the Ed25519 curve.\n *\n * Whenever you need to validate an arbitrary tuple as one that represents a program derived\n * address, use the {@link assertIsProgramDerivedAddress} or {@link isProgramDerivedAddress}\n * functions in this package.\n */\nexport type ProgramDerivedAddress<TAddress extends string = string> = Readonly<\n    [Address<TAddress>, ProgramDerivedAddressBump]\n>;\n\n/**\n * Represents an integer in the range [0,255] used in the derivation of a program derived address to\n * ensure that it does not fall on the Ed25519 curve.\n */\nexport type ProgramDerivedAddressBump = Brand<number, 'ProgramDerivedAddressBump'>;\n\n/**\n * A type guard that returns `true` if the input tuple conforms to the {@link ProgramDerivedAddress}\n * type, and refines its type for use in your program.\n *\n * @see The {@link isAddress} function for an example of how to use a type guard.\n */\nexport function isProgramDerivedAddress<TAddress extends string = string>(\n    value: unknown,\n): value is ProgramDerivedAddress<TAddress> {\n    return (\n        Array.isArray(value) &&\n        value.length === 2 &&\n        typeof value[0] === 'string' &&\n        typeof value[1] === 'number' &&\n        value[1] >= 0 &&\n        value[1] <= 255 &&\n        isAddress(value[0])\n    );\n}\n\n/**\n * In the event that you receive an address/bump-seed tuple from some untrusted source, use this\n * function to assert that it conforms to the {@link ProgramDerivedAddress} interface.\n *\n * @see The {@link assertIsAddress} function for an example of how to use an assertion function.\n */\nexport function assertIsProgramDerivedAddress<TAddress extends string = string>(\n    value: unknown,\n): asserts value is ProgramDerivedAddress<TAddress> {\n    const validFormat =\n        Array.isArray(value) && value.length === 2 && typeof value[0] === 'string' && typeof value[1] === 'number';\n    if (!validFormat) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__MALFORMED_PDA);\n    }\n    if (value[1] < 0 || value[1] > 255) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__PDA_BUMP_SEED_OUT_OF_RANGE, {\n            bump: value[1],\n        });\n    }\n    assertIsAddress(value[0]);\n}\n\ntype ProgramDerivedAddressInput = Readonly<{\n    programAddress: Address;\n    seeds: Seed[];\n}>;\n\ntype SeedInput = Readonly<{\n    baseAddress: Address;\n    programAddress: Address;\n    seed: Seed;\n}>;\n\ntype Seed = ReadonlyUint8Array | string;\n\nconst MAX_SEED_LENGTH = 32;\nconst MAX_SEEDS = 16;\nconst PDA_MARKER_BYTES = [\n    // The string 'ProgramDerivedAddress'\n    80, 114, 111, 103, 114, 97, 109, 68, 101, 114, 105, 118, 101, 100, 65, 100, 100, 114, 101, 115, 115,\n] as const;\n\nasync function createProgramDerivedAddress({ programAddress, seeds }: ProgramDerivedAddressInput): Promise<Address> {\n    assertDigestCapabilityIsAvailable();\n    if (seeds.length > MAX_SEEDS) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED, {\n            actual: seeds.length,\n            maxSeeds: MAX_SEEDS,\n        });\n    }\n    let textEncoder: TextEncoder;\n    const seedBytes = seeds.reduce((acc, seed, ii) => {\n        const bytes = typeof seed === 'string' ? (textEncoder ||= new TextEncoder()).encode(seed) : seed;\n        if (bytes.byteLength > MAX_SEED_LENGTH) {\n            throw new SolanaError(SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED, {\n                actual: bytes.byteLength,\n                index: ii,\n                maxSeedLength: MAX_SEED_LENGTH,\n            });\n        }\n        acc.push(...bytes);\n        return acc;\n    }, [] as number[]);\n    const base58EncodedAddressCodec = getAddressCodec();\n    const programAddressBytes = base58EncodedAddressCodec.encode(programAddress);\n    const addressBytesBuffer = await crypto.subtle.digest(\n        'SHA-256',\n        new Uint8Array([...seedBytes, ...programAddressBytes, ...PDA_MARKER_BYTES]),\n    );\n    const addressBytes = new Uint8Array(addressBytesBuffer);\n    if (compressedPointBytesAreOnCurve(addressBytes)) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__INVALID_SEEDS_POINT_ON_CURVE);\n    }\n    return base58EncodedAddressCodec.decode(addressBytes);\n}\n\n/**\n * Given a program's {@link Address} and up to 16 {@link Seed | Seeds}, this method will return the\n * program derived address (PDA) associated with each.\n *\n * @example\n * ```ts\n * import { getAddressEncoder, getProgramDerivedAddress } from '@solana/addresses';\n *\n * const addressEncoder = getAddressEncoder();\n * const [pda, bumpSeed] = await getProgramDerivedAddress({\n *     programAddress: 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL' as Address,\n *     seeds: [\n *         // Owner\n *         addressEncoder.encode('9fYLFVoVqwH37C3dyPi6cpeobfbQ2jtLpN5HgAYDDdkm' as Address),\n *         // Token program\n *         addressEncoder.encode('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address),\n *         // Mint\n *         addressEncoder.encode('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' as Address),\n *     ],\n * });\n * ```\n */\nexport async function getProgramDerivedAddress({\n    programAddress,\n    seeds,\n}: ProgramDerivedAddressInput): Promise<ProgramDerivedAddress> {\n    let bumpSeed = 255;\n    while (bumpSeed > 0) {\n        try {\n            const address = await createProgramDerivedAddress({\n                programAddress,\n                seeds: [...seeds, new Uint8Array([bumpSeed])],\n            });\n            return [address, bumpSeed as ProgramDerivedAddressBump];\n        } catch (e) {\n            if (isSolanaError(e, SOLANA_ERROR__ADDRESSES__INVALID_SEEDS_POINT_ON_CURVE)) {\n                bumpSeed--;\n            } else {\n                throw e;\n            }\n        }\n    }\n    throw new SolanaError(SOLANA_ERROR__ADDRESSES__FAILED_TO_FIND_VIABLE_PDA_BUMP_SEED);\n}\n\n/**\n * Returns a base58-encoded address derived from some base address, some program address, and a seed\n * string or byte array.\n *\n * @example\n * ```ts\n * import { createAddressWithSeed } from '@solana/addresses';\n *\n * const derivedAddress = await createAddressWithSeed({\n *     // The private key associated with this address will be able to sign for `derivedAddress`.\n *     baseAddress: 'B9Lf9z5BfNPT4d5KMeaBFx8x1G4CULZYR1jA2kmxRDka' as Address,\n *     // Only this program will be able to write data to this account.\n *     programAddress: '445erYq578p2aERrGW9mn9KiYe3fuG6uHdcJ2LPPShGw' as Address,\n *     seed: 'data-account',\n * });\n * ```\n */\nexport async function createAddressWithSeed({ baseAddress, programAddress, seed }: SeedInput): Promise<Address> {\n    const { encode, decode } = getAddressCodec();\n\n    const seedBytes = typeof seed === 'string' ? new TextEncoder().encode(seed) : seed;\n    if (seedBytes.byteLength > MAX_SEED_LENGTH) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED, {\n            actual: seedBytes.byteLength,\n            index: 0,\n            maxSeedLength: MAX_SEED_LENGTH,\n        });\n    }\n\n    const programAddressBytes = encode(programAddress);\n    if (\n        programAddressBytes.length >= PDA_MARKER_BYTES.length &&\n        bytesEqual(programAddressBytes.slice(-PDA_MARKER_BYTES.length), new Uint8Array(PDA_MARKER_BYTES))\n    ) {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__PDA_ENDS_WITH_PDA_MARKER);\n    }\n\n    const addressBytesBuffer = await crypto.subtle.digest(\n        'SHA-256',\n        new Uint8Array([...encode(baseAddress), ...seedBytes, ...programAddressBytes]),\n    );\n    const addressBytes = new Uint8Array(addressBytesBuffer);\n\n    return decode(addressBytes);\n}\n"
  },
  {
    "path": "packages/addresses/src/public-key.ts",
    "content": "import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__ADDRESSES__INVALID_ED25519_PUBLIC_KEY, SolanaError } from '@solana/errors';\n\nimport { Address, getAddressDecoder, getAddressEncoder } from './address';\n\n/**\n * Given a public {@link CryptoKey}, this method will return its associated {@link Address}.\n *\n * @example\n * ```ts\n * import { getAddressFromPublicKey } from '@solana/addresses';\n *\n * const address = await getAddressFromPublicKey(publicKey);\n * ```\n */\nexport async function getAddressFromPublicKey(publicKey: CryptoKey): Promise<Address> {\n    assertKeyExporterIsAvailable();\n    if (publicKey.type !== 'public' || publicKey.algorithm.name !== 'Ed25519') {\n        throw new SolanaError(SOLANA_ERROR__ADDRESSES__INVALID_ED25519_PUBLIC_KEY);\n    }\n    const publicKeyBytes = await crypto.subtle.exportKey('raw', publicKey);\n    return getAddressDecoder().decode(new Uint8Array(publicKeyBytes));\n}\n\n/**\n * Given an {@link Address}, return a {@link CryptoKey} that can be used to verify signatures.\n *\n * @example\n * ```ts\n * import { getAddressFromPublicKey } from '@solana/addresses';\n *\n * const publicKey = await getPublicKeyFromAddress(address);\n * ```\n */\nexport async function getPublicKeyFromAddress(address: Address) {\n    const addressBytes = getAddressEncoder().encode(address);\n    return await crypto.subtle.importKey('raw', addressBytes, { name: 'Ed25519' }, true /* extractable */, ['verify']);\n}\n"
  },
  {
    "path": "packages/addresses/src/vendor/noble/ed25519.ts",
    "content": "/**!\n * noble-ed25519\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2019 Paul Miller (https://paulmillr.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the “Software”), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\nconst D = 37095705934669439343138083508754565189542113879843219016388785533085940283555n;\nconst P = 57896044618658097711785492504343953926634992332820282019728792003956564819949n; // 2n ** 255n - 19n;  ed25519 is twisted edwards curve\nconst RM1 = 19681161376707505956807079304988542015446066515923890162744021073123829784752n; // √-1\n\n// mod division\nfunction mod(a: bigint): bigint {\n    const r = a % P;\n    return r >= 0n ? r : P + r;\n}\nfunction pow2(x: bigint, power: bigint): bigint {\n    // pow2(x, 4) == x^(2^4)\n    let r = x;\n    while (power-- > 0n) {\n        r *= r;\n        r %= P;\n    }\n    return r;\n}\nfunction pow_2_252_3(x: bigint): bigint {\n    // x^(2^252-3) unrolled util for square root\n    const x2 = (x * x) % P; // x^2,       bits 1\n    const b2 = (x2 * x) % P; // x^3,       bits 11\n    const b4 = (pow2(b2, 2n) * b2) % P; // x^(2^4-1), bits 1111\n    const b5 = (pow2(b4, 1n) * x) % P; // x^(2^5-1), bits 11111\n    const b10 = (pow2(b5, 5n) * b5) % P; // x^(2^10)\n    const b20 = (pow2(b10, 10n) * b10) % P; // x^(2^20)\n    const b40 = (pow2(b20, 20n) * b20) % P; // x^(2^40)\n    const b80 = (pow2(b40, 40n) * b40) % P; // x^(2^80)\n    const b160 = (pow2(b80, 80n) * b80) % P; // x^(2^160)\n    const b240 = (pow2(b160, 80n) * b80) % P; // x^(2^240)\n    const b250 = (pow2(b240, 10n) * b10) % P; // x^(2^250)\n    const pow_p_5_8 = (pow2(b250, 2n) * x) % P; // < To pow to (p+3)/8, multiply it by x.\n    return pow_p_5_8;\n}\nfunction uvRatio(u: bigint, v: bigint): bigint | null {\n    // for sqrt comp\n    const v3 = mod(v * v * v); // v³\n    const v7 = mod(v3 * v3 * v); // v⁷\n    const pow = pow_2_252_3(u * v7); // (uv⁷)^(p-5)/8\n    let x = mod(u * v3 * pow); // (uv³)(uv⁷)^(p-5)/8\n    const vx2 = mod(v * x * x); // vx²\n    const root1 = x; // First root candidate\n    const root2 = mod(x * RM1); // Second root candidate; RM1 is √-1\n    const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root\n    const useRoot2 = vx2 === mod(-u); // If vx² = -u, set x <-- x * 2^((p-1)/4)\n    const noRoot = vx2 === mod(-u * RM1); // There is no valid root, vx² = -u√-1\n    if (useRoot1) x = root1;\n    if (useRoot2 || noRoot) x = root2; // We return root2 anyway, for const-time\n    if ((mod(x) & 1n) === 1n) x = mod(-x); // edIsNegative\n    if (!useRoot1 && !useRoot2) {\n        return null;\n    }\n    return x;\n}\n// https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.3\nexport function pointIsOnCurve(y: bigint, lastByte: number): boolean {\n    const y2 = mod(y * y); // y²\n    const u = mod(y2 - 1n); // u=y²-1\n    const v = mod(D * y2 + 1n);\n    const x = uvRatio(u, v); // (uv³)(uv⁷)^(p-5)/8; square root\n    if (x === null) {\n        return false;\n    }\n    const isLastByteOdd = (lastByte & 0x80) !== 0; // x_0, last bit\n    if (x === 0n && isLastByteOdd) {\n        return false;\n    }\n    return true;\n}\n"
  },
  {
    "path": "packages/addresses/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/addresses/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2019.Array\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/addresses\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/addresses/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/assertions/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/assertions/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/assertions/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/assertions/.vscode/settings.json",
    "content": "{\n    \"typescript.tsdk\": \"node_modules/typescript/lib\"\n}\n"
  },
  {
    "path": "packages/assertions/CHANGELOG.md",
    "content": "# @solana/assertions\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f)]:\n    - @solana/errors@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3361](https://github.com/solana-labs/solana-web3.js/pull/3361) [`441fa3a`](https://github.com/solana-labs/solana-web3.js/commit/441fa3a6c7c104961f935e65e259f40c10e82f8a) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug where calls to `isEd25519CurveSupported()` might have resulted in uncaught rejections bubbling up through the app, in cases where Ed25519 is not supported\n\n- [#2329](https://github.com/solana-labs/solana-web3.js/pull/2329) [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8) Thanks [@luu-alex](https://github.com/luu-alex)! - `createKeyPairFromBytes()` now validates that the public key imported is the one that would be derived from the private key imported\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#2352](https://github.com/solana-labs/solana-web3.js/pull/2352) [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1) Thanks [@steveluscher](https://github.com/steveluscher)! - `SubtleCrypto` assertion methods that can make their assertions synchronously are now synchronous, for performance.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3361](https://github.com/solana-labs/solana-web3.js/pull/3361) [`441fa3a`](https://github.com/solana-labs/solana-web3.js/commit/441fa3a6c7c104961f935e65e259f40c10e82f8a) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug where calls to `isEd25519CurveSupported()` might have resulted in uncaught rejections bubbling up through the app, in cases where Ed25519 is not supported\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2329](https://github.com/solana-labs/solana-web3.js/pull/2329) [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8) Thanks [@luu-alex](https://github.com/luu-alex)! - `createKeyPairFromBytes()` now validates that the public key imported is the one that would be derived from the private key imported\n\n- [#2352](https://github.com/solana-labs/solana-web3.js/pull/2352) [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1) Thanks [@steveluscher](https://github.com/steveluscher)! - `SubtleCrypto` assertion methods that can make their assertions synchronously are now synchronous, for performance.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/assertions/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/assertions/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/assertions?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/assertions?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/assertions\n\n# @solana/assertions\n\nThis package contains utilities for asserting that a JavaScript environment supports certain features necessary for the operation of the Solana JavaScript SDK.\n\n## Functions\n\n`assertDigestCapabilityIsAvailable()`\n\nThrows an exception unless `crypto.subtle.digest()` is available in the current JavaScript environment.\n\n`assertKeyExporterIsAvailable()`\n\nThrows an exception unless `crypto.subtle.exportKey()` is available in the current JavaScript environment.\n\n`assertKeyGenerationIsAvailable()`\n\nThrows an exception unless `crypto.subtle.generateKey()` is available in the current JavaScript environment and has support for the `Ed25519` curve.\n\n`assertSigningCapabilityIsAvailable()`\n\nThrows an exception unless `crypto.subtle.sign()` is available in the current JavaScript environment.\n\n`assertVerificationCapabilityIsAvailable()`\n\nThrows an exception unless `crypto.subtle.sign()` is available in the current JavaScript environment.\n"
  },
  {
    "path": "packages/assertions/package.json",
    "content": "{\n    \"name\": \"@solana/assertions\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for asserting that a JavaScript environment supports certain features necessary for the operation of the Solana JavaScript SDK\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaassertions\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/assertions/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/assertions/src/__tests__/crypto-test.ts",
    "content": "import { SOLANA_ERROR__CRYPTO__RANDOM_VALUES_FUNCTION_UNIMPLEMENTED, SolanaError } from '@solana/errors';\n\nimport { assertPRNGIsAvailable } from '../crypto';\n\ndescribe('assertPRNGIsAvailable()', () => {\n    describe('when getRandomValues is available', () => {\n        it('does not throw', () => {\n            expect(assertPRNGIsAvailable).not.toThrow();\n        });\n        it('returns `undefined`', () => {\n            expect(assertPRNGIsAvailable()).toBeUndefined();\n        });\n    });\n    describe('when getRandomValues is not available', () => {\n        let oldCrypto: InstanceType<typeof Crypto>['getRandomValues'];\n        beforeEach(() => {\n            oldCrypto = globalThis.crypto.getRandomValues;\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.getRandomValues = undefined;\n        });\n        afterEach(() => {\n            globalThis.crypto.getRandomValues = oldCrypto;\n        });\n        it('throws', () => {\n            expect(assertPRNGIsAvailable).toThrow(\n                new SolanaError(SOLANA_ERROR__CRYPTO__RANDOM_VALUES_FUNCTION_UNIMPLEMENTED),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/assertions/src/__tests__/subtle-crypto-test.ts",
    "content": "import {\n    SOLANA_ERROR__SUBTLE_CRYPTO__DIGEST_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT,\n    SOLANA_ERROR__SUBTLE_CRYPTO__ED25519_ALGORITHM_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__EXPORT_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__GENERATE_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__SIGN_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__VERIFY_FUNCTION_UNIMPLEMENTED,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    assertDigestCapabilityIsAvailable,\n    assertKeyExporterIsAvailable,\n    assertSigningCapabilityIsAvailable,\n    assertVerificationCapabilityIsAvailable,\n} from '../subtle-crypto';\n\n// HACK: Pierce the veil of `jest.isolateModules` so that the modules inside get the same version of\n//       `@solana/errors` that is imported above.\njest.mock('@solana/errors', () => jest.requireActual('@solana/errors'));\n\ndescribe('assertDigestCapabilityIsAvailable()', () => {\n    describe('when `SubtleCrypto::digest` is available', () => {\n        it('does not throw', () => {\n            expect(assertDigestCapabilityIsAvailable).not.toThrow();\n        });\n        it('returns `undefined`', () => {\n            expect(assertDigestCapabilityIsAvailable()).toBeUndefined();\n        });\n    });\n    if (__BROWSER__) {\n        describe('when in an insecure browser context', () => {\n            beforeEach(() => {\n                globalThis.isSecureContext = false;\n            });\n            it('throws', () => {\n                expect(assertDigestCapabilityIsAvailable).toThrow(\n                    new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT),\n                );\n            });\n        });\n    }\n    describe('when `SubtleCrypto::digest` is not available', () => {\n        let oldDigest: InstanceType<typeof SubtleCrypto>['digest'];\n        beforeEach(() => {\n            oldDigest = globalThis.crypto.subtle.digest;\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.digest = undefined;\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.digest = oldDigest;\n        });\n        it('throws', () => {\n            expect(assertDigestCapabilityIsAvailable).toThrow(\n                new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__DIGEST_UNIMPLEMENTED),\n            );\n        });\n    });\n});\n\ndescribe('assertKeyExporterIsAvailable()', () => {\n    describe('when `SubtleCrypto::exportKey` is available', () => {\n        it('does not throw', () => {\n            expect(assertKeyExporterIsAvailable).not.toThrow();\n        });\n        it('returns `undefined`', () => {\n            expect(assertKeyExporterIsAvailable()).toBeUndefined();\n        });\n    });\n    if (__BROWSER__) {\n        describe('when in an insecure browser context', () => {\n            beforeEach(() => {\n                globalThis.isSecureContext = false;\n            });\n            it('throws', () => {\n                expect(assertKeyExporterIsAvailable).toThrow(\n                    new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT),\n                );\n            });\n        });\n    }\n    describe('when `SubtleCrypto::exportKey` is not available', () => {\n        let oldExportKey: InstanceType<typeof SubtleCrypto>['exportKey'];\n        beforeEach(() => {\n            oldExportKey = globalThis.crypto.subtle.exportKey;\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.exportKey = undefined;\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.exportKey = oldExportKey;\n        });\n        it('throws', () => {\n            expect(assertKeyExporterIsAvailable).toThrow(\n                new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__EXPORT_FUNCTION_UNIMPLEMENTED),\n            );\n        });\n    });\n});\n\ndescribe('assertKeyGenerationIsAvailable()', () => {\n    let assertKeyGenerationIsAvailable: typeof import('../subtle-crypto').assertKeyGenerationIsAvailable;\n    beforeEach(async () => {\n        await jest.isolateModulesAsync(async () => {\n            const guardModulePromise =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                import('../subtle-crypto');\n            assertKeyGenerationIsAvailable = (await guardModulePromise).assertKeyGenerationIsAvailable;\n        });\n    });\n    it('resolves to `undefined` without throwing', async () => {\n        expect.assertions(1);\n        await expect(assertKeyGenerationIsAvailable()).resolves.toBeUndefined();\n    });\n    if (__BROWSER__) {\n        describe('when in an insecure browser context', () => {\n            beforeEach(() => {\n                globalThis.isSecureContext = false;\n            });\n            it('rejects', async () => {\n                expect.assertions(1);\n                await expect(assertKeyGenerationIsAvailable()).rejects.toThrow(\n                    new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT),\n                );\n            });\n        });\n    }\n    describe('when `SubtleCrypto::generateKey` is not available', () => {\n        let oldGenerateKey: InstanceType<typeof SubtleCrypto>['generateKey'];\n        beforeEach(() => {\n            oldGenerateKey = globalThis.crypto.subtle.generateKey;\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.generateKey = undefined;\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.generateKey = oldGenerateKey;\n        });\n        it('rejects', async () => {\n            expect.assertions(1);\n            await expect(assertKeyGenerationIsAvailable()).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__GENERATE_FUNCTION_UNIMPLEMENTED),\n            );\n        });\n    });\n    describe('when the Ed25519 curve is not available', () => {\n        beforeEach(() => {\n            const oldGenerateKey = globalThis.crypto.subtle.generateKey;\n            jest.spyOn(globalThis.crypto.subtle, 'generateKey').mockImplementation(async (algorithm, ...rest) => {\n                if (algorithm === 'Ed25519') {\n                    throw new Error('Ed25519 not supported');\n                }\n                return await oldGenerateKey.call(globalThis.crypto.subtle, algorithm, ...rest);\n            });\n        });\n        it('rejects', async () => {\n            expect.assertions(1);\n            await expect(assertKeyGenerationIsAvailable()).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__ED25519_ALGORITHM_UNIMPLEMENTED),\n            );\n        });\n        it('remembers the result from the first time it is called (parallel checks)', async () => {\n            expect.assertions(1);\n            try {\n                await Promise.all([assertKeyGenerationIsAvailable(), assertKeyGenerationIsAvailable()]);\n            } catch {\n                /* empty */\n            }\n            expect(globalThis.crypto.subtle.generateKey).toHaveBeenCalledTimes(1);\n        });\n        it('remembers the result from the first time it is called (serial checks)', async () => {\n            expect.assertions(1);\n            try {\n                await assertKeyGenerationIsAvailable();\n                await assertKeyGenerationIsAvailable();\n            } catch {\n                /* empty */\n            }\n            expect(globalThis.crypto.subtle.generateKey).toHaveBeenCalledTimes(1);\n        });\n    });\n});\n\ndescribe('assertSigningCapabilityIsAvailable()', () => {\n    describe('when `SubtleCrypto::sign` is available', () => {\n        it('does not throw', () => {\n            expect(assertSigningCapabilityIsAvailable).not.toThrow();\n        });\n        it('returns `undefined`', () => {\n            expect(assertSigningCapabilityIsAvailable()).toBeUndefined();\n        });\n    });\n    if (__BROWSER__) {\n        describe('when in an insecure browser context', () => {\n            beforeEach(() => {\n                globalThis.isSecureContext = false;\n            });\n            it('throws', () => {\n                expect(assertSigningCapabilityIsAvailable).toThrow(\n                    new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT),\n                );\n            });\n        });\n    }\n    describe('when `SubtleCrypto::sign` is not available', () => {\n        let oldSign: InstanceType<typeof SubtleCrypto>['sign'];\n        beforeEach(() => {\n            oldSign = globalThis.crypto.subtle.sign;\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.sign = undefined;\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.sign = oldSign;\n        });\n        it('throws', () => {\n            expect(assertSigningCapabilityIsAvailable).toThrow(\n                new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__SIGN_FUNCTION_UNIMPLEMENTED),\n            );\n        });\n    });\n});\n\ndescribe('assertVerificationCapabilityIsAvailable()', () => {\n    describe('when `SubtleCrypto::verify` is available', () => {\n        it('does not throw', () => {\n            expect(assertVerificationCapabilityIsAvailable).not.toThrow();\n        });\n        it('returns `undefined`', () => {\n            expect(assertVerificationCapabilityIsAvailable()).toBeUndefined();\n        });\n    });\n    if (__BROWSER__) {\n        describe('when in an insecure browser context', () => {\n            beforeEach(() => {\n                globalThis.isSecureContext = false;\n            });\n            it('throws', () => {\n                expect(assertVerificationCapabilityIsAvailable).toThrow(\n                    new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT),\n                );\n            });\n        });\n    }\n    describe('when `SubtleCrypto::sign` is not available', () => {\n        let oldVerify: InstanceType<typeof SubtleCrypto>['verify'];\n        beforeEach(() => {\n            oldVerify = globalThis.crypto.subtle.verify;\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.verify = undefined;\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.verify = oldVerify;\n        });\n        it('throws', () => {\n            expect(assertVerificationCapabilityIsAvailable).toThrow(\n                new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__VERIFY_FUNCTION_UNIMPLEMENTED),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/assertions/src/crypto.ts",
    "content": "import { SOLANA_ERROR__CRYPTO__RANDOM_VALUES_FUNCTION_UNIMPLEMENTED, SolanaError } from '@solana/errors';\n\n/**\n * Throws an exception unless {@link Crypto#getRandomValues | `crypto.getRandomValues()`} is\n * available in the current JavaScript environment.\n */\nexport function assertPRNGIsAvailable() {\n    if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.getRandomValues !== 'function') {\n        throw new SolanaError(SOLANA_ERROR__CRYPTO__RANDOM_VALUES_FUNCTION_UNIMPLEMENTED);\n    }\n}\n"
  },
  {
    "path": "packages/assertions/src/index.ts",
    "content": "/**\n * This package contains utilities for asserting that a JavaScript environment supports certain\n * features necessary for the operation of the Solana JavaScript SDK.\n *\n * @packageDocumentation\n */\nexport * from './crypto';\nexport * from './subtle-crypto';\n"
  },
  {
    "path": "packages/assertions/src/subtle-crypto.ts",
    "content": "import {\n    SOLANA_ERROR__SUBTLE_CRYPTO__DIGEST_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT,\n    SOLANA_ERROR__SUBTLE_CRYPTO__ED25519_ALGORITHM_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__EXPORT_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__GENERATE_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__SIGN_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__VERIFY_FUNCTION_UNIMPLEMENTED,\n    SolanaError,\n} from '@solana/errors';\n\nfunction assertIsSecureContext() {\n    if (__BROWSER__ && !globalThis.isSecureContext) {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT);\n    }\n}\n\nlet cachedEd25519Decision: PromiseLike<boolean> | boolean | undefined;\nasync function isEd25519CurveSupported(subtle: SubtleCrypto): Promise<boolean> {\n    if (cachedEd25519Decision === undefined) {\n        cachedEd25519Decision = new Promise(resolve => {\n            subtle\n                .generateKey('Ed25519', /* extractable */ false, ['sign', 'verify'])\n                .then(() => {\n                    resolve((cachedEd25519Decision = true));\n                })\n                .catch(() => {\n                    resolve((cachedEd25519Decision = false));\n                });\n        });\n    }\n    if (typeof cachedEd25519Decision === 'boolean') {\n        return cachedEd25519Decision;\n    } else {\n        return await cachedEd25519Decision;\n    }\n}\n\n/**\n * Throws an exception unless {@link SubtleCrypto#digest | `crypto.subtle.digest()`} is available in\n * the current JavaScript environment.\n */\nexport function assertDigestCapabilityIsAvailable() {\n    assertIsSecureContext();\n    if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.subtle?.digest !== 'function') {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__DIGEST_UNIMPLEMENTED);\n    }\n}\n\n/**\n * Throws an exception unless {@link SubtleCrypto#generateKey | `crypto.subtle.generateKey()`} is\n * available in the current JavaScript environment and has support for the Ed25519 curve.\n */\nexport async function assertKeyGenerationIsAvailable() {\n    assertIsSecureContext();\n    if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.subtle?.generateKey !== 'function') {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__GENERATE_FUNCTION_UNIMPLEMENTED);\n    }\n    if (!(await isEd25519CurveSupported(globalThis.crypto.subtle))) {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__ED25519_ALGORITHM_UNIMPLEMENTED);\n    }\n}\n\n/**\n * Throws an exception unless {@link SubtleCrypto#exportKey | `crypto.subtle.exportKey()`} is\n * available in the current JavaScript environment.\n */\nexport function assertKeyExporterIsAvailable() {\n    assertIsSecureContext();\n    if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.subtle?.exportKey !== 'function') {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__EXPORT_FUNCTION_UNIMPLEMENTED);\n    }\n}\n\n/**\n * Throws an exception unless {@link SubtleCrypto#sign | `crypto.subtle.sign()`} is available in the\n * current JavaScript environment.\n */\nexport function assertSigningCapabilityIsAvailable() {\n    assertIsSecureContext();\n    if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.subtle?.sign !== 'function') {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__SIGN_FUNCTION_UNIMPLEMENTED);\n    }\n}\n/**\n * Throws an exception unless {@link SubtleCrypto#verify | `crypto.subtle.verify()`} is available in\n * the current JavaScript environment.\n */\nexport function assertVerificationCapabilityIsAvailable() {\n    assertIsSecureContext();\n    if (typeof globalThis.crypto === 'undefined' || typeof globalThis.crypto.subtle?.verify !== 'function') {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__VERIFY_FUNCTION_UNIMPLEMENTED);\n    }\n}\n"
  },
  {
    "path": "packages/assertions/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/assertions/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/addresses\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"],\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\"]\n    }\n}\n"
  },
  {
    "path": "packages/assertions/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/build-scripts/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/build-scripts/README.md",
    "content": "# `build-scripts`\n\nThis is the base build script shared across all packages in this monorepo.\n"
  },
  {
    "path": "packages/build-scripts/build-time-constants.d.ts",
    "content": "// Build time constant roughly equivalent to `NODE_ENV !== 'production'`\n// See build-scripts/dev-flag.ts\ndeclare const __DEV__: boolean;\n\n// Build targets; mutually exclusive (only one can be true)\n// See build-scripts/getBaseConfig.ts\ndeclare const __BROWSER__: boolean;\ndeclare const __NODEJS__: boolean;\ndeclare const __REACTNATIVE__: boolean;\n\n// Build-time constant representing the version of the npm package\n// See build-scripts/getBaseConfig.ts\ndeclare const __VERSION__: string;\n"
  },
  {
    "path": "packages/build-scripts/constants.ts",
    "content": "export const ORG_NAME = 'anza-xyz';\nexport const REPO_NAME = 'kit';\nexport const SEMVER_REGEX = /^0*(\\d+)\\.0*(\\d+)\\.0*(\\d+)$/;\n"
  },
  {
    "path": "packages/build-scripts/create-github-release.ts",
    "content": "#!/usr/bin/env -S pnpm dlx tsx --\n\n// @ts-check\nimport { execSync } from 'node:child_process';\nimport { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\n\nimport { RestEndpointMethodTypes } from '@octokit/rest';\nimport minimist from 'minimist';\nimport remarkParse from 'remark-parse';\nimport remarkStringify from 'remark-stringify';\nimport { unified } from 'unified';\n\nimport { ORG_NAME, REPO_NAME } from './constants.js';\nimport { getCurrentLinkedVersion } from './current-linked-version.js';\nimport { getGitHubApi } from './github-api.js';\nimport { getPriorRelease } from './prior-release.js';\n\ntype Level = string;\ntype PackageName = string;\ntype ReleaseNotesTextContent = string;\n\nfunction isDefined<T>(value: T | null | undefined): value is NonNullable<T> {\n    return value !== null && value !== undefined;\n}\n\nconst config = minimist(process.argv.slice(2), {\n    boolean: 'dry-run',\n});\n\nconst { packages, tag, version } = await getCurrentLinkedVersion();\n\nconst { makeLatest, priorRelease } = await getPriorRelease(version);\n\n/**\n * Read in all of their changelogs and grab the entries related to that version.\n */\ntype Token = ReturnType<typeof markdown.parse>['children'][number];\nconst markdown = unified().use(remarkParse).use(remarkStringify);\nconst releaseNotesByPackage = Object.fromEntries(\n    /**\n     * Load all of the changelog Markdown source text\n     */\n    (\n        await Promise.all(\n            packages.map(async p => {\n                try {\n                    return [\n                        p.packageJson.name,\n                        await readFile(join(p.dir, 'CHANGELOG.md'), {\n                            encoding: 'utf-8',\n                        }),\n                    ] as const;\n                } catch (e) {\n                    if (e && typeof e === 'object' && 'code' in e && e.code === 'ENOENT') {\n                        return;\n                    }\n                    throw e;\n                }\n            }),\n        )\n    )\n        .filter(isDefined)\n        /**\n         * Parse the Markdown source to an AST\n         */\n        .map(([packageName, markdownSource]) => [packageName, markdown.parse(markdownSource)] as const)\n        /**\n         * Extract the section of the changelog that matches the current version.\n         */\n        .map(([packageName, rootContent]) => {\n            const tokensByVersionBumpLevel: Record<string, Token[]> = {};\n            let currentTokensByVersionBumpLevel: Token[] = [];\n            let state: 'collecting' | 'scanning' = 'scanning';\n            for (const token of rootContent.children) {\n                if (state === 'collecting') {\n                    if (token.type === 'heading' && token.depth == 2) {\n                        break;\n                    }\n                } else if (\n                    token.type === 'heading' &&\n                    token.depth == 2 &&\n                    token.children.length === 1 &&\n                    token.children[0].type === 'text' &&\n                    token.children[0].value === version\n                ) {\n                    state = 'collecting';\n                }\n                if (state === 'collecting') {\n                    if (\n                        token.type === 'heading' &&\n                        token.depth == 3 &&\n                        token.children.length === 1 &&\n                        token.children[0].type === 'text' &&\n                        token.children[0].value.endsWith('Changes')\n                    ) {\n                        currentTokensByVersionBumpLevel = [];\n                        const match = token.children[0].value.match(/(\\w+) Changes$/);\n                        if (!match) {\n                            throw new Error(\n                                'Expected third-level headings to be of the form ' +\n                                    '\"{Patch|Minor|Major} Changes\". ' +\n                                    '`create-github-releases.ts` needs to be updated to ' +\n                                    'handle whatever the new format is.',\n                            );\n                        }\n                        const [_, level] = match;\n                        tokensByVersionBumpLevel[level] = currentTokensByVersionBumpLevel;\n                    } else if (token.type === 'list') {\n                        currentTokensByVersionBumpLevel.push(\n                            ...token.children\n                                // Filter out any list item that is just a report of which\n                                // package dependencies were updated.\n                                .filter(\n                                    t =>\n                                        !(\n                                            t.children[0].type === 'paragraph' &&\n                                            t.children[0].children[0].type === 'text' &&\n                                            t.children[0].children[0].value.startsWith('Updated dependencies')\n                                        ),\n                                ),\n                        );\n                    }\n                }\n            }\n            Object.keys(tokensByVersionBumpLevel).forEach(level => {\n                if (tokensByVersionBumpLevel[level].length === 0) {\n                    delete tokensByVersionBumpLevel[level];\n                }\n            });\n            if (Object.keys(tokensByVersionBumpLevel).length === 0) {\n                return;\n            }\n            return [packageName, tokensByVersionBumpLevel] as const;\n        })\n        .filter(isDefined),\n);\n\n/**\n * Convert from:\n *     PACKAGE_NAME -> LEVEL -> RELEASE_NOTE_AST[]\n * ...to:\n *     LEVEL -> RELEASE_NOTE_TEXT -> PACKAGE_NAME[]\n */\nconst releaseNotesByLevel: Record<Level, Record<ReleaseNotesTextContent, PackageName[]>> = {};\nfor (const [packageName, notesRecord] of Object.entries(releaseNotesByPackage)) {\n    Object.keys(notesRecord).forEach(level => {\n        const notes = (releaseNotesByLevel[level] ||= {});\n        notesRecord[level].forEach(note => {\n            const releaseNotesText = markdown.stringify({ children: [note], type: 'root' });\n            notes[releaseNotesText] ||= [];\n            notes[releaseNotesText].push(packageName);\n        });\n    });\n}\n\n/**\n * Format an aggregate release note\n */\nconst releaseDate = new Date();\nconst releaseDateString =\n    releaseDate.getFullYear() +\n    '-' +\n    String(releaseDate.getMonth() + 1).padStart(2, '0') +\n    '-' +\n    String(releaseDate.getDate()).padStart(2, '0');\nconst aggregateReleaseNotes =\n    `# @solana/${REPO_NAME}\\n\\n` +\n    `## [${tag}](https://github.com/${ORG_NAME}/${REPO_NAME}/compare/${priorRelease?.tag_name}...${tag}) (${releaseDateString})\\n\\n` +\n    Object.keys(releaseNotesByLevel)\n        .toSorted((a, b) =>\n            a === b ? 0 : a === 'Major' ? -1 : b === 'Major' ? 1 : a === 'Minor' ? -1 : b === 'Minor' ? 1 : 0,\n        )\n        .flatMap(level => {\n            return [\n                `### ${level} Changes\\n\\n`,\n                ...Object.keys(releaseNotesByLevel[level]).map(\n                    listItem =>\n                        listItem.replace(/^\\* /, '* [`' + releaseNotesByLevel[level][listItem].join('`, `') + '`] ') +\n                        '\\n',\n                ),\n            ];\n        })\n        .join('');\n\n/**\n * Create the release on GitHub\n */\nconst createReleaseParams: RestEndpointMethodTypes['repos']['createRelease']['parameters'] = {\n    body: aggregateReleaseNotes,\n    make_latest: makeLatest ? 'true' : 'false',\n    name: tag,\n    owner: ORG_NAME,\n    repo: REPO_NAME,\n    tag_name: tag,\n    // Supplying this implies that GitHub will *create* the tag specified by `tag_name`\n    target_commitish: execSync('git rev-parse HEAD').toString().trim(),\n};\nif (config['dry-run']) {\n    console.log(createReleaseParams);\n} else {\n    const api = getGitHubApi();\n    await api.rest.repos.createRelease(createReleaseParams);\n}\n"
  },
  {
    "path": "packages/build-scripts/current-linked-version.ts",
    "content": "import { getPackages } from '@manypkg/get-packages';\n\nexport async function getCurrentLinkedVersion() {\n    /**\n     * Get a list of all the packages, their paths, and their `package.json` files.\n     */\n    const { packages: allPackages } = await getPackages(import.meta.dirname);\n    const packages = allPackages.filter(p => p.relativeDir.startsWith('packages/'));\n\n    /**\n     * Compute the version that they all share. Fail unless they all share the same version.\n     */\n    let version: string | undefined;\n    for (const {\n        packageJson: { private: isPrivate, version: packageVersion },\n    } of packages) {\n        if (isPrivate) {\n            continue;\n        }\n        if (!version) {\n            version = packageVersion;\n        } else if (version !== packageVersion) {\n            throw new Error('Expected all versions to be identical');\n        }\n    }\n    if (!version) {\n        throw new Error('Found no packages');\n    }\n    const tag = `v${version}`;\n    return {\n        packages,\n        tag,\n        version,\n    };\n}\n"
  },
  {
    "path": "packages/build-scripts/dev-flag.ts",
    "content": "import { readFile } from 'fs/promises';\nimport jscodeshift from 'jscodeshift';\nimport { Options } from 'tsup';\n\ntype Loader = NonNullable<\n    NonNullable<Awaited<NonNullable<ReturnType<Parameters<Parameters<Plugin['setup']>[0]['onLoad']>[1]>>>>['loader']\n>;\ntype Plugin = NonNullable<Options['esbuildPlugins']>[number];\n\nfunction replaceDev(source: string): string {\n    if (/__DEV__/.test(source) !== true) {\n        return source;\n    }\n    const j = jscodeshift.withParser('tsx');\n    const root = j(source);\n    root.find(j.Identifier, { name: '__DEV__' }).replaceWith(() =>\n        j.binaryExpression(\n            '!==',\n            j.memberExpression(\n                j.memberExpression(j.identifier('process'), j.identifier('env')),\n                j.identifier('NODE_ENV'),\n            ),\n            j.stringLiteral('production'),\n        ),\n    );\n    return root.toSource();\n}\n\nexport const DevFlagPlugin: Plugin = {\n    name: 'dev-flag-plugin',\n    setup(build) {\n        build.onLoad({ filter: /\\.(t|j)sx?$/, namespace: 'file' }, async ({ path }) => {\n            const contents = await readFile(path, 'utf-8');\n            const ext = path.slice(path.lastIndexOf('.') + 1);\n            const loader = (ext.match(/(j|t)sx?$/) ? ext : 'js') as Loader;\n            return {\n                contents: replaceDev(contents),\n                loader,\n            };\n        });\n    },\n};\n"
  },
  {
    "path": "packages/build-scripts/getBaseConfig.ts",
    "content": "import { env } from 'node:process';\n\nimport browsersListToEsBuild from 'browserslist-to-esbuild';\nimport { Format, Options } from 'tsup';\n\nimport { DevFlagPlugin } from './dev-flag';\n\ntype Platform =\n    | 'browser'\n    // React Native\n    | 'native'\n    | 'node';\n\nconst BROWSERSLIST_TARGETS = browsersListToEsBuild();\n\nexport function getBaseConfig(platform: Platform, formats: Format[], _options: Options): Options[] {\n    // `@solana/kit` has an additional subpath entry point that should be published separately.\n    const moduleEntry =\n        env.npm_package_name === '@solana/kit'\n            ? ['./src/index.ts', './src/program-client-core.ts']\n            : ['./src/index.ts'];\n\n    return [true, false]\n        .flatMap<Options | null>(isDebugBuild =>\n            formats.map(format =>\n                format !== 'iife' && isDebugBuild\n                    ? null // We don't build debug builds for packages; only for the iife bundle.\n                    : {\n                          define: {\n                              __BROWSER__: `${platform === 'browser'}`,\n                              __NODEJS__: `${platform === 'node'}`,\n                              __REACTNATIVE__: `${platform === 'native'}`,\n                              __VERSION__: `\"${env.npm_package_version}\"`,\n                          },\n                          // We don't need subpath exports for iife bundles.\n                          entry: format === 'iife' ? ['./src/index.ts'] : moduleEntry,\n                          esbuildOptions(options, context) {\n                              const { format } = context;\n                              options.minify = format === 'iife' && !isDebugBuild;\n                              if (format === 'iife') {\n                                  options.define = {\n                                      ...options.define,\n                                      __DEV__: `${isDebugBuild}`,\n                                  };\n                                  options.target = BROWSERSLIST_TARGETS;\n                              } else {\n                                  options.define = {\n                                      ...options.define,\n                                      // Preserve `process.env.NODE_ENV` in the output without\n                                      // replacing it. This allows consumers' bundlers to replace it\n                                      // as they see fit.\n                                      'process.env.NODE_ENV': 'process.env.NODE_ENV',\n                                  };\n                              }\n                          },\n                          esbuildPlugins: [DevFlagPlugin],\n                          external: [\n                              // Despite inlining `@solana/text-encoding-impl`, do not recursively inline `fastestsmallesttextencoderdecoder`.\n                              'fastestsmallesttextencoderdecoder',\n                              // Despite inlining `@solana/ws-impl`, do not recursively inline `ws`.\n                              'ws',\n                          ],\n                          format,\n                          globalName: 'globalThis.solanaWeb3',\n                          name: platform,\n                          // Inline private, non-published packages.\n                          // WARNING: This inlines packages recursively. Make sure these don't have deep dep trees.\n                          noExternal: [\n                              // @noble/ed25519 is an ESM-only module, so we have to inline it in CJS builds.\n                              ...(format === 'cjs' ? ['@noble/ed25519'] : []),\n                              '@solana/crypto-impl',\n                              '@solana/event-target-impl',\n                              '@solana/fs-impl',\n                              '@solana/text-encoding-impl',\n                              '@solana/ws-impl',\n                          ],\n                          outExtension({ format }) {\n                              let extension;\n                              if (format === 'iife') {\n                                  extension = `.${isDebugBuild ? 'development' : 'production.min'}.js`;\n                              } else {\n                                  extension = `.${platform}.${format === 'cjs' ? 'cjs' : 'mjs'}`;\n                              }\n                              return {\n                                  js: extension,\n                              };\n                          },\n                          platform: platform === 'node' ? 'node' : 'browser',\n                          pure: ['process'],\n                          sourcemap: format !== 'iife' || isDebugBuild,\n                          treeshake: true,\n                      },\n            ),\n        )\n        .filter(Boolean) as Options[];\n}\n"
  },
  {
    "path": "packages/build-scripts/github-api.ts",
    "content": "import { Octokit } from '@octokit/rest';\nimport minimist from 'minimist';\n\nconst config = minimist(process.argv.slice(2), {\n    string: 'token',\n});\n\nconst GITHUB_TOKEN = config.token ?? (process.env.GH_TOKEN || process.env.GITHUB_TOKEN);\nif (typeof GITHUB_TOKEN !== 'string') {\n    console.error(\n        'The required --token argument was not provided. Please use it to supply a GitHub token with write permissions',\n    );\n    process.exit(1);\n}\n\nlet api: Octokit;\nexport function getGitHubApi(): Octokit {\n    if (!api) {\n        api = new Octokit({\n            auth: GITHUB_TOKEN,\n        });\n    }\n    return api;\n}\n"
  },
  {
    "path": "packages/build-scripts/maybe-tag-latest.ts",
    "content": "#!/usr/bin/env -S pnpm dlx tsx --\n\n// @ts-check\nimport { execSync } from 'node:child_process';\n\nimport minimist from 'minimist';\n\nimport { getCurrentLinkedVersion } from './current-linked-version.js';\nimport { getPriorRelease } from './prior-release.js';\n\nconst config = minimist(process.argv.slice(2), {\n    boolean: 'dry-run',\n});\n\nconst { version } = await getCurrentLinkedVersion();\n\nconst { makeLatest } = await getPriorRelease(version);\n\nconst command = `pnpm dist-tag add ${config._[0]} latest`;\n\nif (config['dry-run']) {\n    console.log(\n        makeLatest\n            ? `Would have tagged this as the latest release with: \\`${command}\\``\n            : 'Would not have tagged this as the latest release',\n    );\n} else {\n    execSync(command);\n}\n"
  },
  {
    "path": "packages/build-scripts/package.json",
    "content": "{\n    \"name\": \"@solana/build-scripts\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"files\": [\n        \"register-node-globals.mjs\",\n        \"tsup.config.library.ts\",\n        \"tsup.config.package.ts\"\n    ],\n    \"devDependencies\": {\n        \"@manypkg/get-packages\": \"^3.1.0\",\n        \"@octokit/rest\": \"^22.0.1\",\n        \"@types/jscodeshift\": \"^17.3.0\",\n        \"@types/minimist\": \"^1.2.5\",\n        \"browserslist-to-esbuild\": \"^2.1.1\",\n        \"jscodeshift\": \"^17.3.0\",\n        \"minimist\": \"^1.2.8\",\n        \"remark-parse\": \"^11.0.0\",\n        \"remark-stringify\": \"^11.0.0\",\n        \"unified\": \"^11.0.5\"\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/build-scripts/prior-release.ts",
    "content": "import { RestEndpointMethodTypes } from '@octokit/rest';\nimport minimist from 'minimist';\n\nimport { ORG_NAME, REPO_NAME, SEMVER_REGEX } from './constants.js';\nimport { getGitHubApi } from './github-api.js';\n\nfunction cmpVersions(a: string, b: string): number {\n    const stripZeroesRegex = /(\\\\.0+)+$/;\n    const semverPartsA = a.replace(stripZeroesRegex, '').split('.');\n    const semverPartsB = b.replace(stripZeroesRegex, '').split('.');\n    for (let ii = 0; ii < Math.min(semverPartsA.length, semverPartsB.length); ii++) {\n        const diff = parseInt(semverPartsA[ii], 10) - parseInt(semverPartsB[ii], 10);\n        if (diff) return diff;\n    }\n    return semverPartsA.length - semverPartsB.length;\n}\n\nconst config = minimist(process.argv.slice(2), {\n    boolean: 'dry-run',\n});\n\nconst api = getGitHubApi();\n\nexport async function getPriorRelease(version: string): Promise<{\n    makeLatest: boolean;\n    priorRelease: RestEndpointMethodTypes['repos']['listReleases']['response']['data'][number] | undefined;\n    releases: RestEndpointMethodTypes['repos']['listReleases']['response']['data'];\n}> {\n    const [_, major] = version.match(SEMVER_REGEX)!;\n\n    /**\n     * Find the release just before the current one, if any.\n     */\n    const releases = await api.paginate<RestEndpointMethodTypes['repos']['listReleases']['response']['data'][number]>(\n        api.repos.listReleases.endpoint.merge({\n            owner: ORG_NAME,\n            repo: REPO_NAME,\n        }),\n    );\n    if (!config['dry-run'] && releases.some(({ tag_name: releaseTagName }) => releaseTagName === `v${version}`)) {\n        throw new Error(`There is already a latest release on GitHub for v${version}`);\n    }\n    let priorRelease: RestEndpointMethodTypes['repos']['listReleases']['response']['data'][number] | undefined;\n    releases.forEach(release => {\n        const candidateVersion = release.tag_name.replace(/^v/, '');\n        const [_, candidateMajor] = candidateVersion.match(SEMVER_REGEX)!;\n        if (parseInt(candidateMajor, 10) > parseInt(major, 10)) {\n            return;\n        }\n        if (candidateMajor === major && cmpVersions(candidateVersion, version) > 0) {\n            // throw new Error(\n            //     `Current version (${version}) is older than version of published release of the same major (${candidateVersion})`,\n            // );\n        }\n        if (!priorRelease || cmpVersions(priorRelease.tag_name.replace(/^v/, ''), candidateVersion) <= 0) {\n            priorRelease = release;\n        }\n    });\n    const makeLatest = releases.every(\n        release => cmpVersions('v2.4.0'.replace(/^v/, ''), version.replace(/^v/, '')) <= 0,\n    );\n    return {\n        makeLatest,\n        priorRelease,\n        releases,\n    };\n}\n"
  },
  {
    "path": "packages/build-scripts/register-node-globals.cjs",
    "content": "globalThis.__DEV__ = false;\nglobalThis.__BROWSER = false;\nglobalThis.__NODEJS__ = true;\nglobalThis.__REACTNATIVE__ = false;\n"
  },
  {
    "path": "packages/build-scripts/tag-release-manually.ts",
    "content": "#!/usr/bin/env -S pnpm dlx tsx --\n\n// @ts-check\nimport { execSync } from 'node:child_process';\n\nimport minimist from 'minimist';\n\nimport { getCurrentLinkedVersion } from './current-linked-version.js';\n\nconst config = minimist(process.argv.slice(2), {\n    boolean: 'dry-run',\n    string: ['tag', 'version'],\n});\n\nconst { packages } = await getCurrentLinkedVersion();\n\npackages\n    .filter(pkg => pkg.packageJson.private !== true)\n    .forEach(pkg => {\n        const command = `pnpm dist-tag add ${pkg.packageJson.name}@${config.version} ${config.tag}`;\n        if (config['dry-run']) {\n            console.log(`Would have run: \\`${command}\\``);\n        } else {\n            execSync(command);\n        }\n    });\n"
  },
  {
    "path": "packages/build-scripts/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"module\": \"NodeNext\",\n        \"moduleResolution\": \"NodeNext\",\n        \"types\": [\"node\"]\n    },\n    \"display\": \"Build Scripts\",\n    \"extends\": \"../tsconfig/base.json\"\n}\n"
  },
  {
    "path": "packages/build-scripts/tsup.config.browser.ts",
    "content": "import { defineConfig } from 'tsup';\n\nimport { getBaseConfig } from './getBaseConfig';\n\nexport default defineConfig(options => [...getBaseConfig('browser', ['cjs', 'esm'], options)]);\n"
  },
  {
    "path": "packages/build-scripts/tsup.config.library.ts",
    "content": "import { defineConfig } from 'tsup';\n\nimport { getBaseConfig } from './getBaseConfig';\nimport packageConfigOrConfigsOrPromiseGetterForSame from './tsup.config.package';\n\nexport default defineConfig(async options => {\n    const packageConfigOptionOrOptions =\n        typeof packageConfigOrConfigsOrPromiseGetterForSame === 'function'\n            ? await packageConfigOrConfigsOrPromiseGetterForSame(options)\n            : packageConfigOrConfigsOrPromiseGetterForSame;\n    const packageConfigOptions = Array.isArray(packageConfigOptionOrOptions)\n        ? packageConfigOptionOrOptions\n        : [packageConfigOptionOrOptions];\n    return [...packageConfigOptions, ...getBaseConfig('browser', ['iife'], options)];\n});\n"
  },
  {
    "path": "packages/build-scripts/tsup.config.package.bundled_8gpidqojr8.mjs",
    "content": "// ../build-scripts/tsup.config.package.ts\nimport { defineConfig } from \"tsup\";\n\n// ../build-scripts/getBaseConfig.ts\nimport { env } from \"node:process\";\nimport browsersListToEsBuild from \"browserslist-to-esbuild\";\n\n// ../build-scripts/dev-flag.ts\nimport { readFile } from \"fs/promises\";\nimport jscodeshift from \"jscodeshift\";\nfunction replaceDev(source) {\n  if (/__DEV__/.test(source) !== true) {\n    return source;\n  }\n  const j = jscodeshift.withParser(\"tsx\");\n  const root = j(source);\n  root.find(j.Identifier, { name: \"__DEV__\" }).replaceWith(\n    () => j.binaryExpression(\n      \"!==\",\n      j.memberExpression(\n        j.memberExpression(j.identifier(\"process\"), j.identifier(\"env\")),\n        j.identifier(\"NODE_ENV\")\n      ),\n      j.stringLiteral(\"production\")\n    )\n  );\n  return root.toSource();\n}\nvar DevFlagPlugin = {\n  name: \"dev-flag-plugin\",\n  setup(build) {\n    build.onLoad({ filter: /\\.(t|j)sx?$/, namespace: \"file\" }, async ({ path }) => {\n      const contents = await readFile(path, \"utf-8\");\n      const ext = path.slice(path.lastIndexOf(\".\") + 1);\n      const loader = ext.match(/(j|t)sx?$/) ? ext : \"js\";\n      return {\n        contents: replaceDev(contents),\n        loader\n      };\n    });\n  }\n};\n\n// ../build-scripts/getBaseConfig.ts\nvar BROWSERSLIST_TARGETS = browsersListToEsBuild();\nfunction getBaseConfig(platform, formats, _options) {\n  return [true, false].flatMap(\n    (isDebugBuild) => formats.map(\n      (format) => format !== \"iife\" && isDebugBuild ? null : {\n        define: {\n          __BROWSER__: `${platform === \"browser\"}`,\n          __NODEJS__: `${platform === \"node\"}`,\n          __REACTNATIVE__: `${platform === \"native\"}`,\n          __VERSION__: `\"${env.npm_package_version}\"`\n        },\n        entry: [`./src/index.ts`],\n        esbuildOptions(options, context) {\n          const { format: format2 } = context;\n          options.minify = format2 === \"iife\" && !isDebugBuild;\n          if (format2 === \"iife\") {\n            options.define = {\n              ...options.define,\n              __DEV__: `${isDebugBuild}`\n            };\n            options.target = BROWSERSLIST_TARGETS;\n          } else {\n            options.define = {\n              ...options.define,\n              // Preserve `process.env.NODE_ENV` in the output without\n              // replacing it. This allows consumers' bundlers to replace it\n              // as they see fit.\n              \"process.env.NODE_ENV\": \"process.env.NODE_ENV\"\n            };\n          }\n        },\n        esbuildPlugins: [DevFlagPlugin],\n        external: [\n          // Despite inlining `@solana/text-encoding-impl`, do not recursively inline `fastestsmallesttextencoderdecoder`.\n          \"fastestsmallesttextencoderdecoder\",\n          // Despite inlining `@solana/ws-impl`, do not recursively inline `ws`.\n          \"ws\"\n        ],\n        format,\n        globalName: \"globalThis.solanaWeb3\",\n        name: platform,\n        // Inline private, non-published packages.\n        // WARNING: This inlines packages recursively. Make sure these don't have deep dep trees.\n        noExternal: [\n          // @noble/ed25519 is an ESM-only module, so we have to inline it in CJS builds.\n          ...format === \"cjs\" ? [\"@noble/ed25519\"] : [],\n          \"@solana/crypto-impl\",\n          \"@solana/event-target-impl\",\n          \"@solana/text-encoding-impl\",\n          \"@solana/ws-impl\"\n        ],\n        outExtension({ format: format2 }) {\n          let extension;\n          if (format2 === \"iife\") {\n            extension = `.${isDebugBuild ? \"development\" : \"production.min\"}.js`;\n          } else {\n            extension = `.${platform}.${format2 === \"cjs\" ? \"cjs\" : \"mjs\"}`;\n          }\n          return {\n            js: extension\n          };\n        },\n        platform: platform === \"node\" ? \"node\" : \"browser\",\n        pure: [\"process\"],\n        sourcemap: format !== \"iife\" || isDebugBuild,\n        treeshake: true\n      }\n    )\n  ).filter(Boolean);\n}\n\n// ../build-scripts/tsup.config.package.ts\nvar tsup_config_package_default = defineConfig((options) => [\n  ...getBaseConfig(\"node\", [\"cjs\", \"esm\"], options),\n  ...getBaseConfig(\"browser\", [\"cjs\", \"esm\"], options),\n  ...getBaseConfig(\"native\", [\"esm\"], options)\n]);\nexport {\n  tsup_config_package_default as default\n};\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vYnVpbGQtc2NyaXB0cy90c3VwLmNvbmZpZy5wYWNrYWdlLnRzIiwgIi4uL2J1aWxkLXNjcmlwdHMvZ2V0QmFzZUNvbmZpZy50cyIsICIuLi9idWlsZC1zY3JpcHRzL2Rldi1mbGFnLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX2luamVjdGVkX2ZpbGVuYW1lX18gPSBcIi9ob21lL3NvbC9zcmMva2l0L3BhY2thZ2VzL2J1aWxkLXNjcmlwdHMvdHN1cC5jb25maWcucGFja2FnZS50c1wiO2NvbnN0IF9faW5qZWN0ZWRfZGlybmFtZV9fID0gXCIvaG9tZS9zb2wvc3JjL2tpdC9wYWNrYWdlcy9idWlsZC1zY3JpcHRzXCI7Y29uc3QgX19pbmplY3RlZF9pbXBvcnRfbWV0YV91cmxfXyA9IFwiZmlsZTovLy9ob21lL3NvbC9zcmMva2l0L3BhY2thZ2VzL2J1aWxkLXNjcmlwdHMvdHN1cC5jb25maWcucGFja2FnZS50c1wiO2ltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gJ3RzdXAnO1xuXG5pbXBvcnQgeyBnZXRCYXNlQ29uZmlnIH0gZnJvbSAnLi9nZXRCYXNlQ29uZmlnJztcblxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKG9wdGlvbnMgPT4gW1xuICAgIC4uLmdldEJhc2VDb25maWcoJ25vZGUnLCBbJ2NqcycsICdlc20nXSwgb3B0aW9ucyksXG4gICAgLi4uZ2V0QmFzZUNvbmZpZygnYnJvd3NlcicsIFsnY2pzJywgJ2VzbSddLCBvcHRpb25zKSxcbiAgICAuLi5nZXRCYXNlQ29uZmlnKCduYXRpdmUnLCBbJ2VzbSddLCBvcHRpb25zKSxcbl0pO1xuIiwgImNvbnN0IF9faW5qZWN0ZWRfZmlsZW5hbWVfXyA9IFwiL2hvbWUvc29sL3NyYy9raXQvcGFja2FnZXMvYnVpbGQtc2NyaXB0cy9nZXRCYXNlQ29uZmlnLnRzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIi9ob21lL3NvbC9zcmMva2l0L3BhY2thZ2VzL2J1aWxkLXNjcmlwdHNcIjtjb25zdCBfX2luamVjdGVkX2ltcG9ydF9tZXRhX3VybF9fID0gXCJmaWxlOi8vL2hvbWUvc29sL3NyYy9raXQvcGFja2FnZXMvYnVpbGQtc2NyaXB0cy9nZXRCYXNlQ29uZmlnLnRzXCI7aW1wb3J0IHsgZW52IH0gZnJvbSAnbm9kZTpwcm9jZXNzJztcblxuaW1wb3J0IGJyb3dzZXJzTGlzdFRvRXNCdWlsZCBmcm9tICdicm93c2Vyc2xpc3QtdG8tZXNidWlsZCc7XG5pbXBvcnQgeyBGb3JtYXQsIE9wdGlvbnMgfSBmcm9tICd0c3VwJztcblxuaW1wb3J0IHsgRGV2RmxhZ1BsdWdpbiB9IGZyb20gJy4vZGV2LWZsYWcnO1xuXG50eXBlIFBsYXRmb3JtID1cbiAgICB8ICdicm93c2VyJ1xuICAgIC8vIFJlYWN0IE5hdGl2ZVxuICAgIHwgJ25hdGl2ZSdcbiAgICB8ICdub2RlJztcblxuY29uc3QgQlJPV1NFUlNMSVNUX1RBUkdFVFMgPSBicm93c2Vyc0xpc3RUb0VzQnVpbGQoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJhc2VDb25maWcocGxhdGZvcm06IFBsYXRmb3JtLCBmb3JtYXRzOiBGb3JtYXRbXSwgX29wdGlvbnM6IE9wdGlvbnMpOiBPcHRpb25zW10ge1xuICAgIHJldHVybiBbdHJ1ZSwgZmFsc2VdXG4gICAgICAgIC5mbGF0TWFwPE9wdGlvbnMgfCBudWxsPihpc0RlYnVnQnVpbGQgPT5cbiAgICAgICAgICAgIGZvcm1hdHMubWFwKGZvcm1hdCA9PlxuICAgICAgICAgICAgICAgIGZvcm1hdCAhPT0gJ2lpZmUnICYmIGlzRGVidWdCdWlsZFxuICAgICAgICAgICAgICAgICAgICA/IG51bGwgLy8gV2UgZG9uJ3QgYnVpbGQgZGVidWcgYnVpbGRzIGZvciBwYWNrYWdlczsgb25seSBmb3IgdGhlIGlpZmUgYnVuZGxlLlxuICAgICAgICAgICAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX0JST1dTRVJfXzogYCR7cGxhdGZvcm0gPT09ICdicm93c2VyJ31gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19OT0RFSlNfXzogYCR7cGxhdGZvcm0gPT09ICdub2RlJ31gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19SRUFDVE5BVElWRV9fOiBgJHtwbGF0Zm9ybSA9PT0gJ25hdGl2ZSd9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fVkVSU0lPTl9fOiBgXCIke2Vudi5ucG1fcGFja2FnZV92ZXJzaW9ufVwiYCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnk6IFtgLi9zcmMvaW5kZXgudHNgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXNidWlsZE9wdGlvbnMob3B0aW9ucywgY29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBmb3JtYXQgfSA9IGNvbnRleHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm1pbmlmeSA9IGZvcm1hdCA9PT0gJ2lpZmUnICYmICFpc0RlYnVnQnVpbGQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybWF0ID09PSAnaWlmZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmRlZmluZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ub3B0aW9ucy5kZWZpbmUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fREVWX186IGAke2lzRGVidWdCdWlsZH1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy50YXJnZXQgPSBCUk9XU0VSU0xJU1RfVEFSR0VUUztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5kZWZpbmUgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLm9wdGlvbnMuZGVmaW5lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQcmVzZXJ2ZSBgcHJvY2Vzcy5lbnYuTk9ERV9FTlZgIGluIHRoZSBvdXRwdXQgd2l0aG91dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyByZXBsYWNpbmcgaXQuIFRoaXMgYWxsb3dzIGNvbnN1bWVycycgYnVuZGxlcnMgdG8gcmVwbGFjZSBpdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhcyB0aGV5IHNlZSBmaXQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwcm9jZXNzLmVudi5OT0RFX0VOVic6ICdwcm9jZXNzLmVudi5OT0RFX0VOVicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXNidWlsZFBsdWdpbnM6IFtEZXZGbGFnUGx1Z2luXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZXJuYWw6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlc3BpdGUgaW5saW5pbmcgYEBzb2xhbmEvdGV4dC1lbmNvZGluZy1pbXBsYCwgZG8gbm90IHJlY3Vyc2l2ZWx5IGlubGluZSBgZmFzdGVzdHNtYWxsZXN0dGV4dGVuY29kZXJkZWNvZGVyYC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmYXN0ZXN0c21hbGxlc3R0ZXh0ZW5jb2RlcmRlY29kZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVzcGl0ZSBpbmxpbmluZyBgQHNvbGFuYS93cy1pbXBsYCwgZG8gbm90IHJlY3Vyc2l2ZWx5IGlubGluZSBgd3NgLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3dzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICBnbG9iYWxOYW1lOiAnZ2xvYmFsVGhpcy5zb2xhbmFXZWIzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogcGxhdGZvcm0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElubGluZSBwcml2YXRlLCBub24tcHVibGlzaGVkIHBhY2thZ2VzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXQVJOSU5HOiBUaGlzIGlubGluZXMgcGFja2FnZXMgcmVjdXJzaXZlbHkuIE1ha2Ugc3VyZSB0aGVzZSBkb24ndCBoYXZlIGRlZXAgZGVwIHRyZWVzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBub0V4dGVybmFsOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBAbm9ibGUvZWQyNTUxOSBpcyBhbiBFU00tb25seSBtb2R1bGUsIHNvIHdlIGhhdmUgdG8gaW5saW5lIGl0IGluIENKUyBidWlsZHMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi4oZm9ybWF0ID09PSAnY2pzJyA/IFsnQG5vYmxlL2VkMjU1MTknXSA6IFtdKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAc29sYW5hL2NyeXB0by1pbXBsJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAc29sYW5hL2V2ZW50LXRhcmdldC1pbXBsJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdAc29sYW5hL3RleHQtZW5jb2RpbmctaW1wbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQHNvbGFuYS93cy1pbXBsJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0RXh0ZW5zaW9uKHsgZm9ybWF0IH0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBleHRlbnNpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZm9ybWF0ID09PSAnaWlmZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24gPSBgLiR7aXNEZWJ1Z0J1aWxkID8gJ2RldmVsb3BtZW50JyA6ICdwcm9kdWN0aW9uLm1pbid9LmpzYDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uID0gYC4ke3BsYXRmb3JtfS4ke2Zvcm1hdCA9PT0gJ2NqcycgPyAnY2pzJyA6ICdtanMnfWA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGpzOiBleHRlbnNpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwbGF0Zm9ybTogcGxhdGZvcm0gPT09ICdub2RlJyA/ICdub2RlJyA6ICdicm93c2VyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHVyZTogWydwcm9jZXNzJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZW1hcDogZm9ybWF0ICE9PSAnaWlmZScgfHwgaXNEZWJ1Z0J1aWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB0cmVlc2hha2U6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICksXG4gICAgICAgIClcbiAgICAgICAgLmZpbHRlcihCb29sZWFuKSBhcyBPcHRpb25zW107XG59XG4iLCAiY29uc3QgX19pbmplY3RlZF9maWxlbmFtZV9fID0gXCIvaG9tZS9zb2wvc3JjL2tpdC9wYWNrYWdlcy9idWlsZC1zY3JpcHRzL2Rldi1mbGFnLnRzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIi9ob21lL3NvbC9zcmMva2l0L3BhY2thZ2VzL2J1aWxkLXNjcmlwdHNcIjtjb25zdCBfX2luamVjdGVkX2ltcG9ydF9tZXRhX3VybF9fID0gXCJmaWxlOi8vL2hvbWUvc29sL3NyYy9raXQvcGFja2FnZXMvYnVpbGQtc2NyaXB0cy9kZXYtZmxhZy50c1wiO2ltcG9ydCB7IHJlYWRGaWxlIH0gZnJvbSAnZnMvcHJvbWlzZXMnO1xuaW1wb3J0IGpzY29kZXNoaWZ0IGZyb20gJ2pzY29kZXNoaWZ0JztcbmltcG9ydCB7IE9wdGlvbnMgfSBmcm9tICd0c3VwJztcblxudHlwZSBMb2FkZXIgPSBOb25OdWxsYWJsZTxcbiAgICBOb25OdWxsYWJsZTxBd2FpdGVkPE5vbk51bGxhYmxlPFJldHVyblR5cGU8UGFyYW1ldGVyczxQYXJhbWV0ZXJzPFBsdWdpblsnc2V0dXAnXT5bMF1bJ29uTG9hZCddPlsxXT4+Pj5bJ2xvYWRlciddXG4+O1xudHlwZSBQbHVnaW4gPSBOb25OdWxsYWJsZTxPcHRpb25zWydlc2J1aWxkUGx1Z2lucyddPltudW1iZXJdO1xuXG5mdW5jdGlvbiByZXBsYWNlRGV2KHNvdXJjZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoL19fREVWX18vLnRlc3Qoc291cmNlKSAhPT0gdHJ1ZSkge1xuICAgICAgICByZXR1cm4gc291cmNlO1xuICAgIH1cbiAgICBjb25zdCBqID0ganNjb2Rlc2hpZnQud2l0aFBhcnNlcigndHN4Jyk7XG4gICAgY29uc3Qgcm9vdCA9IGooc291cmNlKTtcbiAgICByb290LmZpbmQoai5JZGVudGlmaWVyLCB7IG5hbWU6ICdfX0RFVl9fJyB9KS5yZXBsYWNlV2l0aCgoKSA9PlxuICAgICAgICBqLmJpbmFyeUV4cHJlc3Npb24oXG4gICAgICAgICAgICAnIT09JyxcbiAgICAgICAgICAgIGoubWVtYmVyRXhwcmVzc2lvbihcbiAgICAgICAgICAgICAgICBqLm1lbWJlckV4cHJlc3Npb24oai5pZGVudGlmaWVyKCdwcm9jZXNzJyksIGouaWRlbnRpZmllcignZW52JykpLFxuICAgICAgICAgICAgICAgIGouaWRlbnRpZmllcignTk9ERV9FTlYnKSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBqLnN0cmluZ0xpdGVyYWwoJ3Byb2R1Y3Rpb24nKSxcbiAgICAgICAgKSxcbiAgICApO1xuICAgIHJldHVybiByb290LnRvU291cmNlKCk7XG59XG5cbmV4cG9ydCBjb25zdCBEZXZGbGFnUGx1Z2luOiBQbHVnaW4gPSB7XG4gICAgbmFtZTogJ2Rldi1mbGFnLXBsdWdpbicsXG4gICAgc2V0dXAoYnVpbGQpIHtcbiAgICAgICAgYnVpbGQub25Mb2FkKHsgZmlsdGVyOiAvXFwuKHR8ailzeD8kLywgbmFtZXNwYWNlOiAnZmlsZScgfSwgYXN5bmMgKHsgcGF0aCB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb250ZW50cyA9IGF3YWl0IHJlYWRGaWxlKHBhdGgsICd1dGYtOCcpO1xuICAgICAgICAgICAgY29uc3QgZXh0ID0gcGF0aC5zbGljZShwYXRoLmxhc3RJbmRleE9mKCcuJykgKyAxKTtcbiAgICAgICAgICAgIGNvbnN0IGxvYWRlciA9IChleHQubWF0Y2goLyhqfHQpc3g/JC8pID8gZXh0IDogJ2pzJykgYXMgTG9hZGVyO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBjb250ZW50czogcmVwbGFjZURldihjb250ZW50cyksXG4gICAgICAgICAgICAgICAgbG9hZGVyLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfSxcbn07XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQXNSLFNBQVMsb0JBQW9COzs7QUNBekMsU0FBUyxXQUFXO0FBRTlSLE9BQU8sMkJBQTJCOzs7QUNGOE4sU0FBUyxnQkFBZ0I7QUFDelIsT0FBTyxpQkFBaUI7QUFReEIsU0FBUyxXQUFXLFFBQXdCO0FBQ3hDLE1BQUksVUFBVSxLQUFLLE1BQU0sTUFBTSxNQUFNO0FBQ2pDLFdBQU87QUFBQSxFQUNYO0FBQ0EsUUFBTSxJQUFJLFlBQVksV0FBVyxLQUFLO0FBQ3RDLFFBQU0sT0FBTyxFQUFFLE1BQU07QUFDckIsT0FBSyxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0sVUFBVSxDQUFDLEVBQUU7QUFBQSxJQUFZLE1BQ3JELEVBQUU7QUFBQSxNQUNFO0FBQUEsTUFDQSxFQUFFO0FBQUEsUUFDRSxFQUFFLGlCQUFpQixFQUFFLFdBQVcsU0FBUyxHQUFHLEVBQUUsV0FBVyxLQUFLLENBQUM7QUFBQSxRQUMvRCxFQUFFLFdBQVcsVUFBVTtBQUFBLE1BQzNCO0FBQUEsTUFDQSxFQUFFLGNBQWMsWUFBWTtBQUFBLElBQ2hDO0FBQUEsRUFDSjtBQUNBLFNBQU8sS0FBSyxTQUFTO0FBQ3pCO0FBRU8sSUFBTSxnQkFBd0I7QUFBQSxFQUNqQyxNQUFNO0FBQUEsRUFDTixNQUFNLE9BQU87QUFDVCxVQUFNLE9BQU8sRUFBRSxRQUFRLGVBQWUsV0FBVyxPQUFPLEdBQUcsT0FBTyxFQUFFLEtBQUssTUFBTTtBQUMzRSxZQUFNLFdBQVcsTUFBTSxTQUFTLE1BQU0sT0FBTztBQUM3QyxZQUFNLE1BQU0sS0FBSyxNQUFNLEtBQUssWUFBWSxHQUFHLElBQUksQ0FBQztBQUNoRCxZQUFNLFNBQVUsSUFBSSxNQUFNLFdBQVcsSUFBSSxNQUFNO0FBQy9DLGFBQU87QUFBQSxRQUNILFVBQVUsV0FBVyxRQUFRO0FBQUEsUUFDN0I7QUFBQSxNQUNKO0FBQUEsSUFDSixDQUFDO0FBQUEsRUFDTDtBQUNKOzs7QUQ1QkEsSUFBTSx1QkFBdUIsc0JBQXNCO0FBRTVDLFNBQVMsY0FBYyxVQUFvQixTQUFtQixVQUE4QjtBQUMvRixTQUFPLENBQUMsTUFBTSxLQUFLLEVBQ2Q7QUFBQSxJQUF3QixrQkFDckIsUUFBUTtBQUFBLE1BQUksWUFDUixXQUFXLFVBQVUsZUFDZixPQUNBO0FBQUEsUUFDSSxRQUFRO0FBQUEsVUFDSixhQUFhLEdBQUcsYUFBYSxTQUFTO0FBQUEsVUFDdEMsWUFBWSxHQUFHLGFBQWEsTUFBTTtBQUFBLFVBQ2xDLGlCQUFpQixHQUFHLGFBQWEsUUFBUTtBQUFBLFVBQ3pDLGFBQWEsSUFBSSxJQUFJLG1CQUFtQjtBQUFBLFFBQzVDO0FBQUEsUUFDQSxPQUFPLENBQUMsZ0JBQWdCO0FBQUEsUUFDeEIsZUFBZSxTQUFTLFNBQVM7QUFDN0IsZ0JBQU0sRUFBRSxRQUFBQSxRQUFPLElBQUk7QUFDbkIsa0JBQVEsU0FBU0EsWUFBVyxVQUFVLENBQUM7QUFDdkMsY0FBSUEsWUFBVyxRQUFRO0FBQ25CLG9CQUFRLFNBQVM7QUFBQSxjQUNiLEdBQUcsUUFBUTtBQUFBLGNBQ1gsU0FBUyxHQUFHLFlBQVk7QUFBQSxZQUM1QjtBQUNBLG9CQUFRLFNBQVM7QUFBQSxVQUNyQixPQUFPO0FBQ0gsb0JBQVEsU0FBUztBQUFBLGNBQ2IsR0FBRyxRQUFRO0FBQUE7QUFBQTtBQUFBO0FBQUEsY0FJWCx3QkFBd0I7QUFBQSxZQUM1QjtBQUFBLFVBQ0o7QUFBQSxRQUNKO0FBQUEsUUFDQSxnQkFBZ0IsQ0FBQyxhQUFhO0FBQUEsUUFDOUIsVUFBVTtBQUFBO0FBQUEsVUFFTjtBQUFBO0FBQUEsVUFFQTtBQUFBLFFBQ0o7QUFBQSxRQUNBO0FBQUEsUUFDQSxZQUFZO0FBQUEsUUFDWixNQUFNO0FBQUE7QUFBQTtBQUFBLFFBR04sWUFBWTtBQUFBO0FBQUEsVUFFUixHQUFJLFdBQVcsUUFBUSxDQUFDLGdCQUFnQixJQUFJLENBQUM7QUFBQSxVQUM3QztBQUFBLFVBQ0E7QUFBQSxVQUNBO0FBQUEsVUFDQTtBQUFBLFFBQ0o7QUFBQSxRQUNBLGFBQWEsRUFBRSxRQUFBQSxRQUFPLEdBQUc7QUFDckIsY0FBSTtBQUNKLGNBQUlBLFlBQVcsUUFBUTtBQUNuQix3QkFBWSxJQUFJLGVBQWUsZ0JBQWdCLGdCQUFnQjtBQUFBLFVBQ25FLE9BQU87QUFDSCx3QkFBWSxJQUFJLFFBQVEsSUFBSUEsWUFBVyxRQUFRLFFBQVEsS0FBSztBQUFBLFVBQ2hFO0FBQ0EsaUJBQU87QUFBQSxZQUNILElBQUk7QUFBQSxVQUNSO0FBQUEsUUFDSjtBQUFBLFFBQ0EsVUFBVSxhQUFhLFNBQVMsU0FBUztBQUFBLFFBQ3pDLE1BQU0sQ0FBQyxTQUFTO0FBQUEsUUFDaEIsV0FBVyxXQUFXLFVBQVU7QUFBQSxRQUNoQyxXQUFXO0FBQUEsTUFDZjtBQUFBLElBQ1Y7QUFBQSxFQUNKLEVBQ0MsT0FBTyxPQUFPO0FBQ3ZCOzs7QURuRkEsSUFBTyw4QkFBUSxhQUFhLGFBQVc7QUFBQSxFQUNuQyxHQUFHLGNBQWMsUUFBUSxDQUFDLE9BQU8sS0FBSyxHQUFHLE9BQU87QUFBQSxFQUNoRCxHQUFHLGNBQWMsV0FBVyxDQUFDLE9BQU8sS0FBSyxHQUFHLE9BQU87QUFBQSxFQUNuRCxHQUFHLGNBQWMsVUFBVSxDQUFDLEtBQUssR0FBRyxPQUFPO0FBQy9DLENBQUM7IiwKICAibmFtZXMiOiBbImZvcm1hdCJdCn0K\n"
  },
  {
    "path": "packages/build-scripts/tsup.config.package.ts",
    "content": "import { defineConfig } from 'tsup';\n\nimport { getBaseConfig } from './getBaseConfig';\n\nexport default defineConfig(options => [\n    ...getBaseConfig('node', ['cjs', 'esm'], options),\n    ...getBaseConfig('browser', ['cjs', 'esm'], options),\n    ...getBaseConfig('native', ['esm'], options),\n]);\n"
  },
  {
    "path": "packages/codecs/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/codecs/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/codecs/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/codecs/CHANGELOG.md",
    "content": "# @solana/codecs\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1570](https://github.com/anza-xyz/kit/pull/1570) [`c5e0e14`](https://github.com/anza-xyz/kit/commit/c5e0e1444ae420390047d5e37a13650edf042954) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a new `@solana/fixed-points` package providing precise fixed-point number types for Solana, both decimal (power-of-10 scale) and binary (power-of-2 scale), in signed and unsigned flavors with arbitrary bit widths. The package includes factories, guards, arithmetic, comparisons, signedness conversions, rescaling, string/number formatting, and byte-level codecs. Also re-exported from `@solana/codecs` and `@solana/kit`.\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`c5e0e14`](https://github.com/anza-xyz/kit/commit/c5e0e1444ae420390047d5e37a13650edf042954), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/fixed-points@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-data-structures@6.9.0\n    - @solana/codecs-numbers@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/options@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b)]:\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-data-structures@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/options@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-data-structures@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/options@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-data-structures@6.6.0\n    - @solana/codecs-numbers@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/options@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-data-structures@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/options@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/codecs-data-structures@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/options@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-data-structures@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/options@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-data-structures@6.3.0\n    - @solana/codecs-numbers@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/options@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`5390602`](https://github.com/anza-xyz/kit/commit/53906024cffc3facb7259ab65ab974b6b1038f56), [`3f4c5f0`](https://github.com/anza-xyz/kit/commit/3f4c5f003e343c21a785e8f339f84c8d6bd3a3b1)]:\n    - @solana/codecs-data-structures@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/options@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`70b1ed8`](https://github.com/anza-xyz/kit/commit/70b1ed83be4c5445f81c600a8ca70127dbdf3463), [`7ce7545`](https://github.com/anza-xyz/kit/commit/7ce75455659ace9776042def6774678a81c43a4a)]:\n    - @solana/codecs-data-structures@6.1.0\n    - @solana/options@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-numbers@6.1.0\n    - @solana/codecs-strings@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-data-structures@6.0.1\n    - @solana/codecs-numbers@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/options@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-data-structures@6.0.0\n    - @solana/codecs-numbers@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/options@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-data-structures@5.5.1\n    - @solana/codecs-numbers@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/options@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-data-structures@5.5.0\n    - @solana/codecs-numbers@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/options@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09)]:\n    - @solana/codecs-data-structures@5.4.0\n    - @solana/codecs-numbers@5.4.0\n    - @solana/codecs-strings@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/options@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-data-structures@5.3.0\n    - @solana/codecs-numbers@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/options@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-numbers@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/codecs-data-structures@5.2.0\n    - @solana/options@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/codecs-strings@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/codecs-data-structures@5.1.0\n    - @solana/codecs-numbers@5.1.0\n    - @solana/options@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-data-structures@5.0.0\n    - @solana/codecs-numbers@5.0.0\n    - @solana/codecs-strings@5.0.0\n    - @solana/options@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb)]:\n    - @solana/codecs-core@4.0.0\n    - @solana/codecs-data-structures@4.0.0\n    - @solana/codecs-numbers@4.0.0\n    - @solana/codecs-strings@4.0.0\n    - @solana/options@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`9205484`](https://github.com/anza-xyz/kit/commit/9205484d33af9426fc9de9594bab204b8f954faf), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/codecs-data-structures@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/codecs-numbers@3.0.0\n    - @solana/codecs-strings@3.0.0\n    - @solana/options@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-data-structures@2.3.0\n    - @solana/codecs-numbers@2.3.0\n    - @solana/codecs-strings@2.3.0\n    - @solana/options@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-data-structures@2.2.1\n    - @solana/codecs-numbers@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/options@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-data-structures@2.2.0\n    - @solana/codecs-numbers@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/options@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-data-structures@2.1.1\n    - @solana/codecs-numbers@2.1.1\n    - @solana/codecs-strings@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/options@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`cfe6910`](https://github.com/anza-xyz/kit/commit/cfe691010a493d06983a8a2728cda9751135906d)]:\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-data-structures@2.1.0\n    - @solana/codecs-numbers@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/options@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2715](https://github.com/solana-labs/solana-web3.js/pull/2715) [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Consolidated `getNullableCodec` and `getOptionCodec` with their `Zeroable` counterparts and added more configurations\n\n    Namely, the `prefix` option can now be set to `null` and the `fixed` option was replaced with the `noneValue` option which can be set to `\"zeroes\"` for `Zeroable` codecs or a custom byte array for custom representations of none values. This means the `getZeroableNullableCodec` and `getZeroableOptionCodec` functions were removed in favor of the new options.\n\n    ```ts\n    // Before.\n    getZeroableNullableCodec(getU16Codec());\n\n    // After.\n    getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n    ```\n\n    Additionally, it is now possible to create nullable codecs that have no `prefix` nor `noneValue`. In this case, the existence of the nullable item is indicated by the presence of any remaining bytes left to decode.\n\n    ```ts\n    const codec = getNullableCodec(getU16Codec(), { prefix: null });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // Encodes nothing.\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([])); // null\n    ```\n\n    Also note that it is now possible for custom `noneValue` byte arrays to be of any length — previously, it had to match the fixed-size of the nullable item.\n\n    Here is a recap of all supported scenarios, using a `u16` codec as an example:\n\n    | `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n    | ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n    | `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n    | Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n    | No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n    Reciprocal changes were made with `getOptionCodec`.\n\n- [#2383](https://github.com/solana-labs/solana-web3.js/pull/2383) [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getScalarEnumCodec` is now called `getEnumCodec`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2382](https://github.com/solana-labs/solana-web3.js/pull/2382) [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getDataEnumCodec` is now called `getDiscriminatedUnionCodec`\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6), [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636), [`a29bfee`](https://github.com/solana-labs/solana-web3.js/commit/a29bfeeb2119d99906a31fb1e5103d8ebf783ceb), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e)]:\n    - @solana/codecs-data-structures@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/options@2.0.0\n    - @solana/codecs-numbers@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-data-structures@2.0.0-rc.4\n    - @solana/codecs-numbers@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n    - @solana/options@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-data-structures@2.0.0-rc.3\n    - @solana/codecs-numbers@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/options@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/codecs-data-structures@2.0.0-rc.2\n    - @solana/codecs-numbers@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n    - @solana/options@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-data-structures@2.0.0-rc.1\n    - @solana/codecs-numbers@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/options@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-data-structures@2.0.0-rc.0\n    - @solana/codecs-numbers@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n    - @solana/options@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2715](https://github.com/solana-labs/solana-web3.js/pull/2715) [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Consolidated `getNullableCodec` and `getOptionCodec` with their `Zeroable` counterparts and added more configurations\n\n    Namely, the `prefix` option can now be set to `null` and the `fixed` option was replaced with the `noneValue` option which can be set to `\"zeroes\"` for `Zeroable` codecs or a custom byte array for custom representations of none values. This means the `getZeroableNullableCodec` and `getZeroableOptionCodec` functions were removed in favor of the new options.\n\n    ```ts\n    // Before.\n    getZeroableNullableCodec(getU16Codec());\n\n    // After.\n    getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n    ```\n\n    Additionally, it is now possible to create nullable codecs that have no `prefix` nor `noneValue`. In this case, the existence of the nullable item is indicated by the presence of any remaining bytes left to decode.\n\n    ```ts\n    const codec = getNullableCodec(getU16Codec(), { prefix: null });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // Encodes nothing.\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([])); // null\n    ```\n\n    Also note that it is now possible for custom `noneValue` byte arrays to be of any length — previously, it had to match the fixed-size of the nullable item.\n\n    Here is a recap of all supported scenarios, using a `u16` codec as an example:\n\n    | `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n    | ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n    | `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n    | Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n    | No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n    Reciprocal changes were made with `getOptionCodec`.\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`a29bfee`](https://github.com/solana-labs/solana-web3.js/commit/a29bfeeb2119d99906a31fb1e5103d8ebf783ceb), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/codecs-data-structures@2.0.0-preview.4\n    - @solana/options@2.0.0-preview.4\n    - @solana/codecs-numbers@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2383](https://github.com/solana-labs/solana-web3.js/pull/2383) [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getScalarEnumCodec` is now called `getEnumCodec`\n\n- [#2382](https://github.com/solana-labs/solana-web3.js/pull/2382) [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getDataEnumCodec` is now called `getDiscriminatedUnionCodec`\n\n- Updated dependencies [[`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6), [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e)]:\n    - @solana/codecs-data-structures@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/options@2.0.0-preview.3\n    - @solana/codecs-numbers@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-data-structures@2.0.0-preview.2\n    - @solana/codecs-numbers@2.0.0-preview.2\n    - @solana/codecs-strings@2.0.0-preview.2\n    - @solana/options@2.0.0-preview.2\n"
  },
  {
    "path": "packages/codecs/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/codecs/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/codecs?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/codecs?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/codecs\n\n# @solana/codecs\n\nThis package contains all types and helpers for encoding and decoding anything to and from a `Uint8Array`. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nNo matter which serialization strategy we use, Codecs abstract away its implementation and offers a simple `encode` and `decode` interface. Codecs are also highly composable, allowing us to build complex data structures from simple building blocks.\n\nHere's a quick example that encodes and decodes a simple `Person` object.\n\n```ts\n// Use composable codecs to build complex data structures.\ntype Person = { name: string; age: number };\nconst getPersonCodec = (): Codec<Person> =>\n    getStructCodec([\n        ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n        ['age', getU32Codec()],\n    ]);\n\n// Use your own codecs to encode and decode data.\nconst person = { name: 'John', age: 42 };\nconst personCodec = getPersonCodec();\nconst encodedPerson: Uint8Array = personCodec.encode(person);\nconst decodedPerson: Person = personCodec.decode(encodedPerson);\n```\n\nWhilst Codecs can both encode and decode, it is possible to only focus on encoding or decoding data, enabling the unused logic to be tree-shaken. For instance, here’s our previous example using Decoders only to decode a `Person` type.\n\n```ts\nconst getPersonDecoder = (): Decoder<Person> =>\n    getStructDecoder([\n        ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n        ['age', getU32Decoder()],\n    ]);\n```\n\nThe `@solana/codecs` package is composed of several smaller packages, each with its own set of responsibilities. You can learn more about codecs and how to create your own by reading their respective documentation.\n\n- [`@solana/codecs-core`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core) This package lays the foundation of codecs by providing core type and helper functions to create and compose them.\n    - [Composing codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#composing-codecs).\n    - [Composing encoders and decoders](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#composing-encoders-and-decoders).\n    - [Combining encoders and decoders](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#combining-encoders-and-decoders).\n    - [Different From and To types](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#different-from-and-to-types).\n    - [Fixed-size and variable-size codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#fixed-size-and-variable-size-codecs).\n    - [Creating custom codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#creating-custom-codecs).\n    - [Transforming codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#transforming-codecs).\n    - [Fixing the size of codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#fixing-the-size-of-codecs).\n    - [Prefixing codecs with their size](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#prefixing-codecs-with-their-size).\n    - [Adding sentinels to codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#adding-sentinels-to-codecs).\n    - [Adjusting the size of codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#adjusting-the-size-of-codecs).\n    - [Offsetting codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#offsetting-codecs).\n    - [Padding codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#padding-codecs).\n    - [Reversing codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#reversing-codecs).\n    - [Byte helpers](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#byte-helpers).\n- [`@solana/codecs-numbers`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-numbers) This package offers codecs for numbers of various sizes and characteristics.\n    - [Integer codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-numbers#integer-codecs).\n    - [Decimal number codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-numbers#decimal-number-codecs).\n    - [Short u16 codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-numbers#short-u16-codec).\n- [`@solana/codecs-strings`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings) This package provides codecs for strings of various encodings and size strategies.\n    - [Sizing string codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings#sizing-string-codecs).\n    - [Utf8 codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings#utf8-codec).\n    - [Base 64 codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings#base-64-codec).\n    - [Base 58 codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings#base-58-codec).\n    - [Base 16 codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings#base-16-codec).\n    - [Base 10 codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings#base-10-codec).\n    - [Base X codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings#base-x-codec).\n    - [Re-slicing base X codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings#re-slicing-base-x-codec).\n- [`@solana/codecs-data-structures`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures) This package offers a set of helpers for a variety of data structures such as objects, enums, arrays, maps, etc.\n    - [Array codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#array-codec).\n    - [Set codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#set-codec).\n    - [Map codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#map-codec).\n    - [Tuple codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#tuple-codec).\n    - [Struct codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#struct-codec).\n    - [Enum codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#enum-codec).\n    - [Literal union codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#literal-union-codec).\n    - [Discriminated union codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#discriminated-union-codec).\n    - [Union codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#union-codec).\n    - [Boolean codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#boolean-codec).\n    - [Nullable codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#nullable-codec).\n    - [Bytes codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#bytes-codec).\n    - [Bit array codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#bit-array-codec).\n    - [Constant codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#constant-codec).\n    - [Unit codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#unit-codec).\n    - [Hidden prefix and suffix codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#hidden-prefix-and-suffix-codec).\n- [`@solana/options`](https://github.com/anza-xyz/kit/tree/main/packages/options) This package adds Rust-like `Options` to JavaScript and offers codecs and helpers to manage them.\n    - [Creating options](https://github.com/anza-xyz/kit/tree/main/packages/options#creating-options).\n    - [Option helpers](https://github.com/anza-xyz/kit/tree/main/packages/options#option-helpers).\n    - [Unwrapping options](https://github.com/anza-xyz/kit/tree/main/packages/options#unwrapping-options).\n    - [Option codec](https://github.com/anza-xyz/kit/tree/main/packages/options#option-codec).\n"
  },
  {
    "path": "packages/codecs/package.json",
    "content": "{\n    \"name\": \"@solana/codecs\",\n    \"version\": \"6.9.0\",\n    \"description\": \"A library for encoding and decoding any data structure\",\n    \"homepage\": \"https://www.solanakit.com/api#solanacodecs\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-data-structures\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/fixed-points\": \"workspace:*\",\n        \"@solana/options\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/codecs/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/codecs/src/index.ts",
    "content": "export * from '@solana/codecs-core';\nexport * from '@solana/codecs-data-structures';\nexport * from '@solana/codecs-numbers';\nexport * from '@solana/codecs-strings';\nexport * from '@solana/fixed-points';\nexport * from '@solana/options';\n"
  },
  {
    "path": "packages/codecs/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/codecs/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/codecs\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/codecs/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/codecs-core/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/codecs-core/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/codecs-core/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/codecs-core/CHANGELOG.md",
    "content": "# @solana/codecs-core\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- [#1391](https://github.com/anza-xyz/kit/pull/1391) [`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c) Thanks [@holps-7](https://github.com/holps-7)! - Fix unnecessary array slicing/cloning when using negative offsets matching the array length.\n\n- Updated dependencies []:\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- [#1115](https://github.com/anza-xyz/kit/pull/1115) [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a function that gives you a non-shared `ArrayBuffer` given any kind of `Uint8Array`\n\n- [#1116](https://github.com/anza-xyz/kit/pull/1116) [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549) Thanks [@steveluscher](https://github.com/steveluscher)! - Any `SharedArrayBuffer` that gets passed to a crypto operation like `signBytes` or `verifySignature` will now be copied as non-shared. Crypto operations like `sign` and `verify` reject `SharedArrayBuffers` otherwise\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#1040](https://github.com/anza-xyz/kit/pull/1040) [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c) Thanks [@OrmEmbaar](https://github.com/OrmEmbaar)! - Add a function called bytesEqual to codecs-core that you can use to compare two byte arrays for equality.\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#944](https://github.com/anza-xyz/kit/pull/944) [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function to create a decoder that checks the size of the input bytes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- [#685](https://github.com/anza-xyz/kit/pull/685) [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0) Thanks [@steveluscher](https://github.com/steveluscher)! - `padBytes` now strips extra types from the input array, but otherwise returns the same flavour of `Uint8Array` you gave it, in terms of writability\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f)]:\n    - @solana/errors@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2397](https://github.com/solana-labs/solana-web3.js/pull/2397) [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `addCodecSizePrefix` primitive\n\n    ```ts\n    const codec = addCodecSizePrefix(getBase58Codec(), getU32Codec());\n\n    codec.encode('hello world');\n    // 0x0b00000068656c6c6f20776f726c64\n    //   |       └-- Our encoded base-58 string.\n    //   └-- Our encoded u32 size prefix.\n    ```\n\n- [#2419](https://github.com/solana-labs/solana-web3.js/pull/2419) [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `addCodecSentinel` primitive\n\n    The `addCodecSentinel` function provides a new way of delimiting the size of a codec. It allows us to add a sentinel to the end of the encoded data and to read until that sentinel is found when decoding. It accepts any codec and a `Uint8Array` sentinel responsible for delimiting the encoded data.\n\n    ```ts\n    const codec = addCodecSentinel(getUtf8Codec(), new Uint8Array([255, 255]));\n    codec.encode('hello');\n    // 0x68656c6c6fffff\n    //   |        └-- Our sentinel.\n    //   └-- Our encoded string.\n    ```\n\n- [#2400](https://github.com/solana-labs/solana-web3.js/pull/2400) [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `containsBytes` and `getConstantCodec` helpers\n\n    The `containsBytes` helper checks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n\n    ```ts\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n    ```\n\n    The `getConstantCodec` function accepts any `Uint8Array` and returns a `Codec<void>`. When encoding, it will set the provided `Uint8Array` as-is. When decoding, it will assert that the next bytes contain the provided `Uint8Array` and move the offset forward.\n\n    ```ts\n    const codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n\n    codec.encode(undefined); // 0x010203\n    codec.decode(new Uint8Array([1, 2, 3])); // undefined\n    codec.decode(new Uint8Array([1, 2, 4])); // Throws an error.\n    ```\n\n- [#2383](https://github.com/solana-labs/solana-web3.js/pull/2383) [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getScalarEnumCodec` is now called `getEnumCodec`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2382](https://github.com/solana-labs/solana-web3.js/pull/2382) [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getDataEnumCodec` is now called `getDiscriminatedUnionCodec`\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2397](https://github.com/solana-labs/solana-web3.js/pull/2397) [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `addCodecSizePrefix` primitive\n\n    ```ts\n    const codec = addCodecSizePrefix(getBase58Codec(), getU32Codec());\n\n    codec.encode('hello world');\n    // 0x0b00000068656c6c6f20776f726c64\n    //   |       └-- Our encoded base-58 string.\n    //   └-- Our encoded u32 size prefix.\n    ```\n\n- [#2419](https://github.com/solana-labs/solana-web3.js/pull/2419) [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `addCodecSentinel` primitive\n\n    The `addCodecSentinel` function provides a new way of delimiting the size of a codec. It allows us to add a sentinel to the end of the encoded data and to read until that sentinel is found when decoding. It accepts any codec and a `Uint8Array` sentinel responsible for delimiting the encoded data.\n\n    ```ts\n    const codec = addCodecSentinel(getUtf8Codec(), new Uint8Array([255, 255]));\n    codec.encode('hello');\n    // 0x68656c6c6fffff\n    //   |        └-- Our sentinel.\n    //   └-- Our encoded string.\n    ```\n\n- [#2400](https://github.com/solana-labs/solana-web3.js/pull/2400) [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `containsBytes` and `getConstantCodec` helpers\n\n    The `containsBytes` helper checks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n\n    ```ts\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n    ```\n\n    The `getConstantCodec` function accepts any `Uint8Array` and returns a `Codec<void>`. When encoding, it will set the provided `Uint8Array` as-is. When decoding, it will assert that the next bytes contain the provided `Uint8Array` and move the offset forward.\n\n    ```ts\n    const codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n\n    codec.encode(undefined); // 0x010203\n    codec.decode(new Uint8Array([1, 2, 3])); // undefined\n    codec.decode(new Uint8Array([1, 2, 4])); // Throws an error.\n    ```\n\n- [#2383](https://github.com/solana-labs/solana-web3.js/pull/2383) [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getScalarEnumCodec` is now called `getEnumCodec`\n\n- [#2382](https://github.com/solana-labs/solana-web3.js/pull/2382) [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getDataEnumCodec` is now called `getDiscriminatedUnionCodec`\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/codecs-core/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/codecs-core/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/codecs-core?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/codecs-core?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/codecs-core\n\n# @solana/codecs-core\n\nThis package contains the core types and functions for encoding and decoding data structures on Solana. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nThis package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) which acts as an entry point for all codec packages as well as for their documentation.\n\n## Composing codecs\n\nThe easiest way to create your own codecs is to compose the [various codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs) offered by this library. For instance, here’s how you would define a codec for a `Person` object that contains a `name` string attribute and an `age` number stored in 4 bytes.\n\n```ts\ntype Person = { name: string; age: number };\nconst getPersonCodec = (): Codec<Person> =>\n    getStructCodec([\n        ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n        ['age', getU32Codec()],\n    ]);\n```\n\nThis function returns a `Codec` object which contains both an `encode` and `decode` function that can be used to convert a `Person` type to and from a `Uint8Array`.\n\n```ts\nconst personCodec = getPersonCodec();\nconst bytes = personCodec.encode({ name: 'John', age: 42 });\nconst person = personCodec.decode(bytes);\n```\n\nThere is a significant library of composable codecs at your disposal, enabling you to compose complex types. You may be interested in the documentation of these other packages to learn more about them:\n\n- [`@solana/codecs-numbers`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-numbers) for number codecs.\n- [`@solana/codecs-strings`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings) for string codecs.\n- [`@solana/codecs-data-structures`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures) for many data structure codecs such as objects, arrays, tuples, sets, maps, enums, discriminated unions, booleans, etc.\n- [`@solana/options`](https://github.com/anza-xyz/kit/tree/main/packages/options) for a Rust-like `Option` type and associated codec.\n\nYou may also be interested in some of the helpers of this `@solana/codecs-core` library such as `transformCodec`, `fixCodecSize` or `reverseCodec` that create new codecs from existing ones.\n\nNote that all of these libraries are included in the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) as well as the main `@solana/kit` package for your convenience.\n\n## Composing encoders and decoders\n\nWhilst Codecs can both encode and decode, it is possible to only focus on encoding or decoding data, enabling the unused logic to be tree-shaken. For instance, here’s our previous example using Encoders only to encode a `Person` type.\n\n```ts\nconst getPersonEncoder = (): Encoder<Person> =>\n    getStructEncoder([\n        ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n        ['age', getU32Encoder()],\n    ]);\n\nconst bytes = getPersonEncoder().encode({ name: 'John', age: 42 });\n```\n\nThe same can be done for decoding the `Person` type by using Decoders like so.\n\n```ts\nconst getPersonDecoder = (): Decoder<Person> =>\n    getStructDecoder([\n        ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n        ['age', getU32Decoder()],\n    ]);\n\nconst person = getPersonDecoder().decode(bytes);\n```\n\n## Combining encoders and decoders\n\nSeparating Codecs into Encoders and Decoders is particularly good practice for library maintainers as it allows their users to tree-shake any of the encoders and/or decoders they don’t need. However, we may still want to offer a codec helper for users who need both for convenience.\n\nThat’s why this library offers a `combineCodec` helper that creates a `Codec` instance from a matching `Encoder` and `Decoder`.\n\n```ts\nconst getPersonCodec = (): Codec<Person> => combineCodec(getPersonEncoder(), getPersonDecoder());\n```\n\nThis means library maintainers can offer Encoders, Decoders and Codecs for all their types whilst staying efficient and tree-shakeable. In summary, we recommend the following pattern when creating codecs for library types.\n\n```ts\ntype MyType = /* ... */;\nconst getMyTypeEncoder = (): Encoder<MyType> => { /* ... */ };\nconst getMyTypeDecoder = (): Decoder<MyType> => { /* ... */ };\nconst getMyTypeCodec = (): Codec<MyType> =>\n    combineCodec(getMyTypeEncoder(), getMyTypeDecoder());\n```\n\n## Different From and To types\n\nWhen creating codecs, the encoded type is allowed to be looser than the decoded type. A good example of that is the u64 number codec:\n\n```ts\nconst u64Codec: Codec<number | bigint, bigint> = getU64Codec();\n```\n\nAs you can see, the first type parameter is looser since it accepts numbers or big integers, whereas the second type parameter only accepts big integers. That’s because when _encoding_ a u64 number, you may provide either a `bigint` or a `number` for convenience. However, when you decode a u64 number, you will always get a `bigint` because not all u64 values can fit in a JavaScript `number` type.\n\n```ts\nconst bytes = u64Codec.encode(42);\nconst value = u64Codec.decode(bytes); // BigInt(42)\n```\n\nThis relationship between the type we encode “From” and decode “To” can be generalized in TypeScript as `To extends From`.\n\nHere’s another example using an object with default values. You can read more about the `transformEncoder` helper below.\n\n```ts\ntype Person = { name: string, age: number };\ntype PersonInput = { name: string, age?: number };\n\nconst getPersonEncoder = (): Encoder<PersonInput> =>\n    transformEncoder(\n        getStructEncoder([\n            ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n            ['age', getU32Encoder()],\n        ]),\n        input => { ...input, age: input.age ?? 42 }\n    );\n\nconst getPersonDecoder = (): Decoder<Person> =>\n    getStructDecoder([\n        ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n        ['age', getU32Decoder()],\n    ]);\n\nconst getPersonCodec = (): Codec<PersonInput, Person> =>\n  combineCodec(getPersonEncoder(), getPersonDecoder())\n```\n\n## Fixed-size and variable-size codecs\n\nIt is also worth noting that Codecs can either be of fixed size or variable size.\n\n`FixedSizeCodecs` have a `fixedSize` number attribute that tells us exactly how big their encoded data is in bytes.\n\n```ts\nconst myCodec: FixedSizeCodec<number> = getU32Codec();\nmyCodec.fixedSize; // 4 bytes.\n```\n\nOn the other hand, `VariableSizeCodecs` do not know the size of their encoded data in advance. Instead, they will grab that information either from the provided encoded data or from the value to encode. For the former, we can simply access the length of the `Uint8Array`. For the latter, it provides a `getSizeFromValue` that tells us the encoded byte size of the provided value.\n\n```ts\nconst myCodec: VariableSizeCodec<string> = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\nmyCodec.getSizeFromValue('hello world'); // 4 + 11 bytes.\n```\n\nAlso note that, if the `VariableSizeCodec` is bounded by a maximum size, it can be provided as a `maxSize` number attribute.\n\nThe following type guards are available to identify and/or assert the size of codecs: `isFixedSize`, `isVariableSize`, `assertIsFixedSize` and `assertIsVariableSize`.\n\nFinally, note that the same is true for `Encoders` and `Decoders`.\n\n- A `FixedSizeEncoder` has a `fixedSize` number attribute.\n- A `VariableSizeEncoder` has a `getSizeFromValue` function and an optional `maxSize` number attribute.\n- A `FixedSizeDecoder` has a `fixedSize` number attribute.\n- A `VariableSizeDecoder` has an optional `maxSize` number attribute.\n\n## Creating custom codecs\n\nIf composing codecs isn’t enough for you, you may implement your own codec logic by using the `createCodec` function. This function requires an object with a `read` and a `write` function telling us how to read from and write to an existing byte array.\n\nThe `read` function accepts the `bytes` to decode from and the `offset` at each we should start reading. It returns an array with two items:\n\n- The first item should be the decoded value.\n- The second item should be the next offset to read from.\n\n```ts\ncreateCodec({\n    read(bytes, offset) {\n        const value = bytes[offset];\n        return [value, offset + 1];\n    },\n    // ...\n});\n```\n\nReciprocally, the `write` function accepts the `value` to encode, the array of `bytes` to write the encoded value to and the `offset` at which it should be written. It should encode the given value, insert it in the byte array, and provide the next offset to write to as the return value.\n\n```ts\ncreateCodec({\n    write(value, bytes, offset) {\n        bytes.set(value, offset);\n        return offset + 1;\n    },\n    // ...\n});\n```\n\nAdditionally, we must specify the size of the codec. If we are defining a `FixedSizeCodec`, we must simply provide the `fixedSize` number attribute. For `VariableSizeCodecs`, we must provide the `getSizeFromValue` function as described in the previous section.\n\n```ts\n// FixedSizeCodec.\ncreateCodec({\n    fixedSize: 1,\n    // ...\n});\n\n// VariableSizeCodec.\ncreateCodec({\n    getSizeFromValue: (value: string) => value.length,\n    // ...\n});\n```\n\nHere’s a concrete example of a custom codec that encodes any unsigned integer in a single byte. Since a single byte can only store integers from 0 to 255, if any other integer is provided it will take its modulo 256 to ensure it fits in a single byte. Because it always requires a single byte, that codec is a `FixedSizeCodec` of size `1`.\n\n```ts\nconst getModuloU8Codec = () =>\n    createCodec<number>({\n        fixedSize: 1,\n        read(bytes, offset) {\n            const value = bytes[offset];\n            return [value, offset + 1];\n        },\n        write(value, bytes, offset) {\n            bytes.set(value % 256, offset);\n            return offset + 1;\n        },\n    });\n```\n\nNote that, it is also possible to create custom encoders and decoders separately by using the `createEncoder` and `createDecoder` functions respectively and then use the `combineCodec` function on them just like we were doing with composed codecs.\n\nThis approach is recommended to library maintainers as it allows their users to tree-shake any of the encoders and/or decoders they don’t need.\n\nHere’s our previous modulo u8 example but split into separate `Encoder`, `Decoder` and `Codec` instances.\n\n```ts\nconst getModuloU8Encoder = () =>\n    createEncoder<number>({\n        fixedSize: 1,\n        write(value, bytes, offset) {\n            bytes.set(value % 256, offset);\n            return offset + 1;\n        },\n    });\n\nconst getModuloU8Decoder = () =>\n    createDecoder<number>({\n        fixedSize: 1,\n        read(bytes, offset) {\n            const value = bytes[offset];\n            return [value, offset + 1];\n        },\n    });\n\nconst getModuloU8Codec = () => combineCodec(getModuloU8Encoder(), getModuloU8Decoder());\n```\n\nHere’s another example returning a `VariableSizeCodec`. This one transforms a simple string composed of characters from `a` to `z` to a buffer of numbers from `1` to `26` where `0` bytes are spaces.\n\n```ts\nconst alphabet = ' abcdefghijklmnopqrstuvwxyz';\n\nconst getCipherEncoder = () =>\n    createEncoder<string>({\n        getSizeFromValue: value => value.length,\n        write(value, bytes, offset) {\n            const bytesToAdd = [...value].map(char => alphabet.indexOf(char));\n            bytes.set(bytesToAdd, offset);\n            return offset + bytesToAdd.length;\n        },\n    });\n\nconst getCipherDecoder = () =>\n    createDecoder<string>({\n        read(bytes, offset) {\n            const value = [...bytes.slice(offset)].map(byte => alphabet.charAt(byte)).join('');\n            return [value, bytes.length];\n        },\n    });\n\nconst getCipherCodec = () => combineCodec(getCipherEncoder(), getCipherDecoder());\n```\n\n## Transforming codecs\n\nIt is possible to transform a `Codec<T>` to a `Codec<U>` by providing two mapping functions: one that goes from `T` to `U` and one that does the opposite.\n\nFor instance, here’s how you would map a `u32` integer into a `string` representation of that number.\n\n```ts\nconst getStringU32Codec = () =>\n    transformCodec(\n        getU32Codec(),\n        (integerAsString: string): number => parseInt(integerAsString),\n        (integer: number): string => integer.toString(),\n    );\n\ngetStringU32Codec().encode('42'); // new Uint8Array([42])\ngetStringU32Codec().decode(new Uint8Array([42])); // \"42\"\n```\n\nIf a `Codec` has [different From and To types](#different-from-and-to-types), say `Codec<OldFrom, OldTo>`, and we want to map it to `Codec<NewFrom, NewTo>`, we must provide functions that map from `NewFrom` to `OldFrom` and from `OldTo` to `NewTo`.\n\nTo illustrate that, let’s take our previous `getStringU32Codec` example but make it use a `getU64Codec` codec instead as it returns a `Codec<number | bigint, bigint>`. Additionally, let’s make it so our `getStringU64Codec` function returns a `Codec<number | string, string>` so that it also accepts numbers when encoding values. Here’s what our mapping functions look like:\n\n```ts\nconst getStringU64Codec = () =>\n    transformCodec(\n        getU64Codec(),\n        (integerInput: number | string): number | bigint =>\n            typeof integerInput === 'string' ? BigInt(integerAsString) : integerInput,\n        (integer: bigint): string => integer.toString(),\n    );\n```\n\nNote that the second function that maps the decoded type is optional. That means, you can omit it to simply update or loosen the type to encode whilst keeping the decoded type the same.\n\nThis is particularly useful to provide default values to object structures. For instance, here’s how we can map our `Person` codec to give a default value to its `age` attribute.\n\n```ts\ntype Person = { name: string; age: number; }\nconst getPersonCodec = (): Codec<Person> => { /*...*/ }\n\ntype PersonInput = { name: string; age?: number; }\nconst getPersonWithDefaultValueCodec = (): Codec<PersonInput, Person> =>\n    transformCodec(\n        getPersonCodec(),\n        (person: PersonInput): Person => { ...person, age: person.age ?? 42 }\n    )\n```\n\nSimilar helpers exist to map `Encoder` and `Decoder` instances allowing you to separate your codec logic into tree-shakeable functions. Here’s our `getStringU32Codec` written that way.\n\n```ts\nconst getStringU32Encoder = () =>\n    transformEncoder(getU32Encoder(), (integerAsString: string): number => parseInt(integerAsString));\nconst getStringU32Decoder = () => transformDecoder(getU32Decoder(), (integer: number): string => integer.toString());\nconst getStringU32Codec = () => combineCodec(getStringU32Encoder(), getStringU32Decoder());\n```\n\n## Fixing the size of codecs\n\nThe `fixCodecSize` function allows you to bind the size of a given codec to the given fixed size.\n\nFor instance, say you want to represent a base-58 string that uses exactly 32 bytes when decoded. Here’s how you can use the `fixCodecSize` helper to achieve that.\n\n```ts\nconst get32BytesBase58Codec = () => fixCodecSize(getBase58Codec(), 32);\n```\n\nYou may also use the `fixEncoderSize` and `fixDecoderSize` functions to separate your codec logic like so:\n\n```ts\nconst get32BytesBase58Encoder = () => fixEncoderSize(getBase58Encoder(), 32);\nconst get32BytesBase58Decoder = () => fixDecoderSize(getBase58Decoder(), 32);\nconst get32BytesBase58Codec = () => combineCodec(get32BytesBase58Encoder(), get32BytesBase58Decoder());\n```\n\n## Prefixing codecs with their size\n\nThe `addCodecSizePrefix` function allows you to store the byte size of any codec as a number prefix. This allows you to contain variable-size codecs to their actual size.\n\nWhen encoding, the size of the encoded data is stored before the encoded data itself. When decoding, the size is read first to know how many bytes to read next.\n\nFor example, say we want to represent a variable-size base-58 string using a `u32` size prefix. Here’s how you can use the `addCodecSizePrefix` function to achieve that.\n\n```ts\nconst getU32Base58Codec = () => addCodecSizePrefix(getBase58Codec(), getU32Codec());\n\ngetU32Base58Codec().encode('hello world');\n// 0x0b00000068656c6c6f20776f726c64\n//   |       └-- Our encoded base-58 string.\n//   └-- Our encoded u32 size prefix.\n```\n\nYou may also use the `addEncoderSizePrefix` and `addDecoderSizePrefix` functions to separate your codec logic like so:\n\n```ts\nconst getU32Base58Encoder = () => addEncoderSizePrefix(getBase58Encoder(), getU32Encoder());\nconst getU32Base58Decoder = () => addDecoderSizePrefix(getBase58Decoder(), getU32Decoder());\nconst getU32Base58Codec = () => combineCodec(getU32Base58Encoder(), getU32Base58Decoder());\n```\n\n## Adding sentinels to codecs\n\nAnother way of delimiting the size of a codec is to use sentinels. The `addCodecSentinel` function allows us to add a sentinel to the end of the encoded data and to read until that sentinel is found when decoding. It accepts any codec and a `Uint8Array` sentinel responsible for delimiting the encoded data.\n\n```ts\nconst codec = addCodecSentinel(getUtf8Codec(), new Uint8Array([255, 255]));\ncodec.encode('hello');\n// 0x68656c6c6fffff\n//   |        └-- Our sentinel.\n//   └-- Our encoded string.\n```\n\nNote that the sentinel _must not_ be present in the encoded data and _must_ be present in the decoded data for this to work. If this is not the case, dedicated errors will be thrown.\n\n```ts\nconst sentinel = new Uint8Array([108, 108]); // 'll'\nconst codec = addCodecSentinel(getUtf8Codec(), sentinel);\n\ncodec.encode('hello'); // Throws: sentinel is in encoded data.\ncodec.decode(new Uint8Array([1, 2, 3])); // Throws: sentinel missing in decoded data.\n```\n\nSeparate `addEncoderSentinel` and `addDecoderSentinel` functions are also available.\n\n```ts\nconst bytes = addEncoderSentinel(getUtf8Encoder(), sentinel).encode('hello');\nconst value = addDecoderSentinel(getUtf8Decoder(), sentinel).decode(bytes);\n```\n\n## Adjusting the size of codecs\n\nThe `resizeCodec` helper re-defines the size of a given codec by accepting a function that takes the current size of the codec and returns a new size. This works for both fixed-size and variable-size codecs.\n\n```ts\n// Fixed-size codec.\nconst getBiggerU32Codec = () => resizeCodec(getU32Codec(), size => size + 4);\ngetBiggerU32Codec().encode(42);\n// 0x2a00000000000000\n//   |       └-- Empty buffer space caused by the resizeCodec function.\n//   └-- Our encoded u32 number.\n\n// Variable-size codec.\nconst getBiggerUtf8Codec = () => resizeCodec(getUtf8Codec(), size => size + 4);\ngetBiggerUtf8Codec().encode('ABC');\n// 0x41424300000000\n//   |     └-- Empty buffer space caused by the resizeCodec function.\n//   └-- Our encoded string.\n```\n\nNote that the `resizeCodec` function doesn't change any encoded or decoded bytes, it merely tells the `encode` and `decode` functions how big the `Uint8Array` should be before delegating to their respective `write` and `read` functions. In fact, this is completely bypassed when using the `write` and `read` functions directly. For instance:\n\n```ts\nconst getBiggerU32Codec = () => resizeCodec(getU32Codec(), size => size + 4);\n\n// Using the encode function.\ngetBiggerU32Codec().encode(42);\n// 0x2a00000000000000\n\n// Using the lower-level write function.\nconst myCustomBytes = new Uint8Array(4);\ngetBiggerU32Codec().write(42, myCustomBytes, 0);\n// 0x2a000000\n```\n\nSo when would it make sense to use the `resizeCodec` function? This function is particularly useful when combined with the `offsetCodec` function described below. Whilst the `offsetCodec` may help us push the offset forward — e.g. to skip some padding — it won't change the size of the encoded data which means the last bytes will be truncated by how much we pushed the offset forward. The `resizeCodec` function can be used to fix that. For instance, here's how we can use the `resizeCodec` and the `offsetCodec` functions together to create a struct codec that includes some padding.\n\n```ts\nconst personCodec = getStructCodec([\n    ['name', fixCodecSize(getUtf8Codec(), 8)],\n    // There is a 4-byte padding between name and age.\n    [\n        'age',\n        offsetCodec(\n            resizeCodec(getU32Codec(), size => size + 4),\n            { preOffset: ({ preOffset }) => preOffset + 4 },\n        ),\n    ],\n]);\n\npersonCodec.encode({ name: 'Alice', age: 42 });\n// 0x416c696365000000000000002a000000\n//   |               |       └-- Our encoded u32 (42).\n//   |               └-- The 4-bytes of padding we are skipping.\n//   └-- Our 8-byte encoded string (\"Alice\").\n```\n\nAs usual, the `resizeEncoder` and `resizeDecoder` functions can also be used to achieve that.\n\n```ts\nconst getBiggerU32Encoder = () => resizeEncoder(getU32Codec(), size => size + 4);\nconst getBiggerU32Decoder = () => resizeDecoder(getU32Codec(), size => size + 4);\nconst getBiggerU32Codec = () => combineCodec(getBiggerU32Encoder(), getBiggerU32Decoder());\n```\n\n## Offsetting codecs\n\nThe `offsetCodec` function is a powerful codec primitive that allows you to move the offset of a given codec forward or backwards. It accepts one or two functions that takes the current offset and returns a new offset.\n\nTo understand how this works, let's take our previous `biggerU32Codec` example which encodes a `u32` number inside an 8-byte buffer.\n\n```ts\nconst biggerU32Codec = resizeCodec(getU32Codec(), size => size + 4);\nbiggerU32Codec.encode(0xffffffff);\n// 0xffffffff00000000\n//   |       └-- Empty buffer space caused by the resizeCodec function.\n//   └-- Our encoded u32 number.\n```\n\nNow, let's say we want to move the offset of that codec 2 bytes forward so that the encoded number sits in the middle of the buffer. To achieve, this we can use the `offsetCodec` helper and provide a `preOffset` function that moves the \"pre-offset\" of the codec 2 bytes forward.\n\n```ts\nconst u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n    preOffset: ({ preOffset }) => preOffset + 2,\n});\nu32InTheMiddleCodec.encode(0xffffffff);\n// 0x0000ffffffff0000\n//       └-- Our encoded u32 number is now in the middle of the buffer.\n```\n\nWe refer to this offset as the \"pre-offset\" because, once the inner codec is encoded or decoded, an additional offset will be returned which we refer to as the \"post-offset\". That \"post-offset\" is important as, unless we are reaching the end of our codec, it will be used by any further codecs to continue encoding or decoding data.\n\nBy default, that \"post-offset\" is simply the addition of the \"pre-offset\" and the size of the encoded or decoded inner data.\n\n```ts\nconst u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n    preOffset: ({ preOffset }) => preOffset + 2,\n});\nu32InTheMiddleCodec.encode(0xffffffff);\n// 0x0000ffffffff0000\n//   |   |       └-- Post-offset.\n//   |   └-- New pre-offset: The original pre-offset + 2.\n//   └-- Pre-offset: The original pre-offset before we adjusted it.\n```\n\nHowever, you may also provide a `postOffset` function to adjust the \"post-offset\". For instance, let's push the \"post-offset\" 2 bytes forward as well such that any further codecs will start doing their job at the end of our 8-byte `u32` number.\n\n```ts\nconst u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n    preOffset: ({ preOffset }) => preOffset + 2,\n    postOffset: ({ postOffset }) => postOffset + 2,\n});\nu32InTheMiddleCodec.encode(0xffffffff);\n// 0x0000ffffffff0000\n//   |   |       |   └-- New post-offset: The original post-offset + 2.\n//   |   |       └-- Post-offset: The original post-offset before we adjusted it.\n//   |   └-- New pre-offset: The original pre-offset + 2.\n//   └-- Pre-offset: The original pre-offset before we adjusted it.\n```\n\nBoth the `preOffset` and `postOffset` functions offer the following attributes:\n\n- `bytes`: The entire byte array being encoded or decoded.\n- `preOffset`: The original and unaltered pre-offset.\n- `wrapBytes`: A helper function that wraps the given offset around the byte array length. E.g. `wrapBytes(-1)` will refer to the last byte of the byte array.\n\nAdditionally, the post-offset function also provides the following attributes:\n\n- `newPreOffset`: The new pre-offset after the pre-offset function has been applied.\n- `postOffset`: The original and unaltered post-offset.\n\nNote that you may also decide to ignore these attributes to achieve absolute offsets. However, relative offsets are usually recommended as they won't break your codecs when composed with other codecs.\n\n```ts\nconst u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n    preOffset: () => 2,\n    postOffset: () => 8,\n});\nu32InTheMiddleCodec.encode(0xffffffff);\n// 0x0000ffffffff0000\n```\n\nAlso note that any negative offset or offset that exceeds the size of the byte array will throw a `SolanaError` of code `SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE`.\n\n```ts\nconst u32InTheEndCodec = offsetCodec(biggerU32Codec, { preOffset: () => -4 });\nu32InTheEndCodec.encode(0xffffffff);\n// throws new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE)\n```\n\nTo avoid this, you may use the `wrapBytes` function to wrap the offset around the byte array length. For instance, here's how we can use the `wrapBytes` function to move the pre-offset 4 bytes from the end of the byte array.\n\n```ts\nconst u32InTheEndCodec = offsetCodec(biggerU32Codec, {\n    preOffset: ({ wrapBytes }) => wrapBytes(-4),\n});\nu32InTheEndCodec.encode(0xffffffff);\n// 0x00000000ffffffff\n```\n\nAs you can see, the `offsetCodec` helper allows you to jump all over the place with your codecs. This non-linear approach to encoding and decoding data allows you to achieve complex serialization strategies that would otherwise be impossible.\n\nAs usual, the `offsetEncoder` and `offsetDecoder` functions can also be used to split your codec logic into tree-shakeable functions.\n\n```ts\nconst getU32InTheMiddleEncoder = () => offsetEncoder(biggerU32Encoder, { preOffset: ({ preOffset }) => preOffset + 2 });\nconst getU32InTheMiddleDecoder = () => offsetDecoder(biggerU32Decoder, { preOffset: ({ preOffset }) => preOffset + 2 });\nconst getU32InTheMiddleCodec = () => combineCodec(getU32InTheMiddleEncoder(), getU32InTheMiddleDecoder());\n```\n\n## Padding codecs\n\nThe `padLeftCodec` and `padRightCodec` helpers can be used to add padding to the left or right of a given codec. They accept an `offset` number that tells us how big the padding should be.\n\n```ts\nconst getLeftPaddedCodec = () => padLeftCodec(getU16Codec(), 4);\ngetLeftPaddedCodec().encode(0xffff);\n// 0x00000000ffff\n//   |       └-- Our encoded u16 number.\n//   └-- Our 4-byte padding.\n\nconst getRightPaddedCodec = () => padRightCodec(getU16Codec(), 4);\ngetRightPaddedCodec().encode(0xffff);\n// 0xffff00000000\n//   |   └-- Our 4-byte padding.\n//   └-- Our encoded u16 number.\n```\n\nNote that both the `padLeftCodec` and `padRightCodec` functions are simple wrappers around the `offsetCodec` and `resizeCodec` functions. For more complex padding strategies, you may want to use the `offsetCodec` and `resizeCodec` functions directly instead.\n\nAs usual, encoder-only and decoder-only helpers are available for these padding functions. Namely, `padLeftEncoder`, `padRightEncoder`, `padLeftDecoder` and `padRightDecoder`.\n\n```ts\nconst getMyPaddedEncoder = () => padLeftEncoder(getU16Encoder());\nconst getMyPaddedDecoder = () => padLeftDecoder(getU16Decoder());\nconst getMyPaddedCodec = () => combineCodec(getMyPaddedEncoder(), getMyPaddedDecoder());\n```\n\n## Reversing codecs\n\nThe `reverseCodec` helper reverses the bytes of the provided `FixedSizeCodec`.\n\n```ts\nconst getBigEndianU64Codec = () => reverseCodec(getU64Codec());\n```\n\nNote that number codecs can already do that for you via their `endian` option.\n\n```ts\nconst getBigEndianU64Codec = () => getU64Codec({ endian: Endian.Big });\n```\n\nAs usual, the `reverseEncoder` and `reverseDecoder` functions can also be used to achieve that.\n\n```ts\nconst getBigEndianU64Encoder = () => reverseEncoder(getU64Encoder());\nconst getBigEndianU64Decoder = () => reverseDecoder(getU64Decoder());\nconst getBigEndianU64Codec = () => combineCodec(getBigEndianU64Encoder(), getBigEndianU64Decoder());\n```\n\n## Byte helpers\n\nThis package also provides utility functions for managing bytes such as:\n\n- `mergeBytes`: Concatenates an array of `Uint8Arrays` into a single `Uint8Array`.\n- `padBytes`: Pads a `Uint8Array` with zeroes (to the right) to the specified length.\n- `fixBytes`: Pads or truncates a `Uint8Array` so it has the specified length.\n- `containsBytes`: Checks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n\n```ts\n// Merge multiple Uint8Array buffers into one.\nmergeBytes([new Uint8Array([1, 2]), new Uint8Array([3, 4])]); // Uint8Array([1, 2, 3, 4])\n\n// Pad a Uint8Array buffer to the given size.\npadBytes(new Uint8Array([1, 2]), 4); // Uint8Array([1, 2, 0, 0])\npadBytes(new Uint8Array([1, 2, 3, 4]), 2); // Uint8Array([1, 2, 3, 4])\n\n// Pad and truncate a Uint8Array buffer to the given size.\nfixBytes(new Uint8Array([1, 2]), 4); // Uint8Array([1, 2, 0, 0])\nfixBytes(new Uint8Array([1, 2, 3, 4]), 2); // Uint8Array([1, 2])\n\n// Check if a Uint8Array contains another Uint8Array at a given offset.\ncontainsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\ncontainsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n```\n\n---\n\nTo read more about the available codecs and how to use them, check out the documentation of the main [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs).\n"
  },
  {
    "path": "packages/codecs-core/package.json",
    "content": "{\n    \"name\": \"@solana/codecs-core\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Core types and helpers for encoding and decoding byte arrays on Solana\",\n    \"homepage\": \"https://www.solanakit.com/api#solanacodecs-core\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"benchmark\": \"./src/__benchmarks__/run.ts\",\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"tinybench\": \"^6.0.0\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/codecs-core/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/codecs-core/src/__benchmarks__/run.ts",
    "content": "#!/usr/bin/env -S pnpm dlx tsx -r ../build-scripts/register-node-globals.cjs\n\nimport { webcrypto as crypto } from 'node:crypto';\n\nimport { Bench } from 'tinybench';\n\nimport { createCodec, FixedSizeCodec } from '../codec';\nimport { ReadonlyUint8Array } from '../readonly-uint8array';\nimport { reverseCodec } from '../reverse-codec';\n\nconst bench = new Bench({\n    throws: true,\n});\n\nconst noopCodec: FixedSizeCodec<ReadonlyUint8Array, ReadonlyUint8Array> = createCodec({\n    fixedSize: 32,\n    read(bytes, offset) {\n        return [bytes.slice(offset), bytes.length];\n    },\n    write(value, bytes, offset) {\n        bytes.set(value, offset);\n        return value.length + offset;\n    },\n});\n\nconst bytes32 = new Uint8Array(32);\nfunction randomizeBytes() {\n    crypto.getRandomValues(bytes32);\n}\n\nconst reverseBytes = reverseCodec(noopCodec);\n\nbench\n    .add(\n        'Decode reverse',\n        () => {\n            reverseBytes.decode(bytes32);\n        },\n        { beforeEach: randomizeBytes },\n    )\n    .add(\n        'Encode reverse',\n        () => {\n            reverseBytes.encode(bytes32);\n        },\n        { beforeEach: randomizeBytes },\n    );\n\nvoid (async () => {\n    await bench.run();\n\n    console.table(bench.table());\n})();\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/__setup__.ts",
    "content": "import { Codec, createCodec, FixedSizeCodec, Offset } from '../codec';\n\nexport const b = (s: string) => base16.encode(s);\n\nexport const base16: Codec<string> = createCodec({\n    getSizeFromValue: (value: string) => Math.ceil(value.length / 2),\n    read(bytes, offset) {\n        const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n        return [value, bytes.length];\n    },\n    write(value: string, bytes, offset) {\n        const matches = value.toLowerCase().match(/.{1,2}/g);\n        const hexBytes = matches ? matches.map((byte: string) => parseInt(byte, 16)) : [];\n        bytes.set(hexBytes, offset);\n        return offset + hexBytes.length;\n    },\n});\n\ntype GetMockCodecConfig = {\n    defaultValue?: string;\n    description?: string;\n    innerSize?: number;\n    size?: number | null;\n};\n\ntype GetMockCodecReturnType = Codec<unknown> & {\n    readonly getSizeFromValue: jest.Mock<number>;\n    readonly read: jest.Mock;\n    readonly write: jest.Mock;\n};\n\nexport function getMockCodec<TSize extends number>(\n    config: GetMockCodecConfig & { size: TSize },\n): FixedSizeCodec<unknown, unknown, TSize> & GetMockCodecReturnType;\nexport function getMockCodec(config?: GetMockCodecConfig): GetMockCodecReturnType;\nexport function getMockCodec(config: GetMockCodecConfig = {}): GetMockCodecReturnType {\n    const innerSize = config.innerSize ?? config.size ?? 0;\n    return createCodec({\n        ...(config.size != null ? { fixedSize: config.size } : { getSizeFromValue: jest.fn().mockReturnValue(0) }),\n        read: jest.fn().mockImplementation((_bytes, offset: Offset) => [config.defaultValue ?? '', offset + innerSize]),\n        write: jest.fn().mockImplementation((_value, _bytes, offset: Offset) => offset + innerSize),\n    }) as GetMockCodecReturnType;\n}\n\nexport function expectNewPreOffset(\n    codec: FixedSizeCodec<unknown>,\n    mockCodec: FixedSizeCodec<unknown>,\n    preOffset: number,\n    expectedNewPreOffset: number,\n) {\n    const bytes = new Uint8Array(Array.from({ length: codec.fixedSize }, () => 0));\n    codec.write(null, bytes, preOffset);\n    expect(mockCodec.write).toHaveBeenCalledWith(null, bytes, expectedNewPreOffset);\n    void codec.read(bytes, preOffset)[1];\n    expect(mockCodec.read).toHaveBeenCalledWith(bytes, expectedNewPreOffset);\n}\n\nexport function expectNewPostOffset(codec: FixedSizeCodec<unknown>, preOffset: number, expectedNewPostOffset: number) {\n    const bytes = new Uint8Array(Array.from({ length: codec.fixedSize }, () => 0));\n    expect(codec.write(null, bytes, preOffset)).toBe(expectedNewPostOffset);\n    expect(codec.read(bytes, preOffset)[1]).toBe(expectedNewPostOffset);\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/add-codec-sentinel-test.ts",
    "content": "import {\n    SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL,\n    SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES,\n    SolanaError,\n} from '@solana/errors';\n\nimport { addCodecSentinel } from '../add-codec-sentinel';\nimport { Offset } from '../codec';\nimport { b, getMockCodec } from './__setup__';\n\ndescribe('addCodecSentinel', () => {\n    it('encodes the sentinel after the main content', () => {\n        const mockCodec = getMockCodec();\n        mockCodec.getSizeFromValue.mockReturnValue(10);\n        mockCodec.write.mockImplementation((_, bytes: Uint8Array, offset: Offset) => {\n            bytes.set(b('68656c6c6f776f726c64'), offset);\n            return offset + 10;\n        });\n        const codec = addCodecSentinel(mockCodec, b('ff'));\n\n        expect(codec.encode('helloworld')).toStrictEqual(b('68656c6c6f776f726c64ff'));\n        expect(mockCodec.write).toHaveBeenCalledWith('helloworld', expect.any(Uint8Array), 0);\n    });\n\n    it('decodes until the first occurrence of the sentinel is found', () => {\n        const mockCodec = getMockCodec();\n        mockCodec.read.mockReturnValue(['helloworld', 10]);\n        const codec = addCodecSentinel(mockCodec, b('ff'));\n\n        expect(codec.decode(b('68656c6c6f776f726c64ff0000'))).toBe('helloworld');\n        expect(mockCodec.read).toHaveBeenCalledWith(b('68656c6c6f776f726c64'), 0);\n    });\n\n    it('fails if the encoded bytes contain the sentinel', () => {\n        const mockCodec = getMockCodec();\n        mockCodec.getSizeFromValue.mockReturnValue(10);\n        mockCodec.write.mockImplementation((_, bytes: Uint8Array, offset: Offset) => {\n            bytes.set(b('68656c6c6f776f726cff'), offset);\n            return offset + 10;\n        });\n        const codec = addCodecSentinel(mockCodec, b('ff'));\n\n        expect(() => codec.encode('helloworld')).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL, {\n                encodedBytes: b('68656c6c6f776f726cff'),\n                hexEncodedBytes: '68656c6c6f776f726cff',\n                hexSentinel: 'ff',\n                sentinel: b('ff'),\n            }),\n        );\n    });\n\n    it('fails if the decoded bytes do not contain the sentinel', () => {\n        const mockCodec = getMockCodec();\n        const codec = addCodecSentinel(mockCodec, b('ff'));\n\n        expect(() => codec.decode(b('68656c6c6f776f726c64000000'))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES, {\n                decodedBytes: b('68656c6c6f776f726c64000000'),\n                hexDecodedBytes: '68656c6c6f776f726c64000000',\n                hexSentinel: 'ff',\n                sentinel: b('ff'),\n            }),\n        );\n    });\n\n    it('returns the correct fixed size', () => {\n        const mockCodec = getMockCodec({ size: 10 });\n        const codec = addCodecSentinel(mockCodec, b('ffff'));\n        expect(codec.fixedSize).toBe(12);\n    });\n\n    it('returns the correct variable size', () => {\n        const mockCodec = getMockCodec();\n        mockCodec.getSizeFromValue.mockReturnValueOnce(10);\n        const codec = addCodecSentinel(mockCodec, b('ffff'));\n        expect(codec.getSizeFromValue('helloworld')).toBe(12);\n    });\n\n    it('is correct when offset equals negative byteLength', () => {\n        const mockCodec = getMockCodec();\n        mockCodec.read.mockReturnValue(['helloworld', 10]);\n        const codec = addCodecSentinel(mockCodec, b('ff'));\n        const bytes = b('68656c6c6f776f726c64ff');\n        expect(codec.read(bytes, -bytes.byteLength)[0]).toBe(codec.read(bytes, 0)[0]);\n    });\n\n    it('is correct when offset is negative greater than byteLength', () => {\n        const mockCodec = getMockCodec();\n        mockCodec.read.mockReturnValue(['helloworld', 10]);\n        const codec = addCodecSentinel(mockCodec, b('ff'));\n        const bytes = b('68656c6c6f776f726c64ff');\n        expect(codec.read(bytes, -(bytes.byteLength + 1))[0]).toBe(codec.read(bytes, 0)[0]);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/add-codec-size-prefix-test.ts",
    "content": "import { addCodecSizePrefix } from '../add-codec-size-prefix';\nimport { assertIsFixedSize, assertIsVariableSize, Codec } from '../codec';\nimport { b, getMockCodec } from './__setup__';\n\ndescribe('addCodecSizePrefix', () => {\n    it('encodes the byte length before the content', () => {\n        const numberCodec = getMockCodec({ size: 4 });\n        const contentCodec = getMockCodec({ size: 10 });\n        const prefixedCodec = addCodecSizePrefix(contentCodec, numberCodec as Codec<number>);\n\n        prefixedCodec.encode('helloworld');\n        expect(numberCodec.write).toHaveBeenCalledWith(10, expect.any(Uint8Array), 0);\n        expect(contentCodec.write).toHaveBeenCalledWith('helloworld', expect.any(Uint8Array), 0);\n    });\n\n    it('decodes the byte length before the reading the content', () => {\n        const numberCodec = getMockCodec({ size: 4 });\n        numberCodec.read.mockReturnValue([10, 4]);\n        const contentCodec = getMockCodec({ size: 10 });\n        const prefixedCodec = addCodecSizePrefix(contentCodec, numberCodec as Codec<number>);\n\n        prefixedCodec.decode(b('0a00000068656c6c6f776f726c64'));\n        expect(numberCodec.read).toHaveBeenCalledWith(b('0a00000068656c6c6f776f726c64'), 0);\n        expect(contentCodec.read).toHaveBeenCalledWith(b('68656c6c6f776f726c64'), 0);\n    });\n\n    it('lets the size codec fail if the byte length overflows the size codec', () => {\n        const numberCodec = getMockCodec({ size: 1 });\n        const overflowError = new Error('overflow');\n        numberCodec.write.mockImplementation((value: number) => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (value > 255) throw overflowError;\n        });\n        const contentCodec = getMockCodec({ size: 256 });\n        const prefixedCodec = addCodecSizePrefix(contentCodec, numberCodec as Codec<number>);\n        expect(() => prefixedCodec.encode(null)).toThrow(overflowError);\n    });\n\n    it('returns the correct fixed size', () => {\n        const numberCodec = getMockCodec({ size: 4 });\n        const contentCodec = getMockCodec({ size: 10 });\n        const prefixedCodec = addCodecSizePrefix(contentCodec, numberCodec as Codec<number>);\n        assertIsFixedSize(prefixedCodec);\n        expect(prefixedCodec.fixedSize).toBe(14);\n    });\n\n    it('returns the correct variable size', () => {\n        const numberCodec = getMockCodec({ size: 4 });\n        const contentCodec = getMockCodec();\n        contentCodec.getSizeFromValue.mockReturnValueOnce(10);\n        const prefixedCodec = addCodecSizePrefix(contentCodec, numberCodec as Codec<number>);\n        assertIsVariableSize(prefixedCodec);\n        expect(prefixedCodec.getSizeFromValue('helloworld')).toBe(14);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/array-buffers-test.ts",
    "content": "import { toArrayBuffer } from '../array-buffers';\n\ndescribe('toArrayBuffer', () => {\n    it('converts shared array buffers to non-shared copies', () => {\n        const sharedArrayBuffer = new SharedArrayBuffer(1024);\n        const byteArray = new Uint8Array(sharedArrayBuffer);\n        const arrayBuffer = toArrayBuffer(byteArray);\n        expect(arrayBuffer).not.toBeInstanceOf(SharedArrayBuffer);\n    });\n    it('returns the buffer without modification when no slice is specified', () => {\n        const byteArray = new Uint8Array([1, 2, 3]);\n        expect(toArrayBuffer(byteArray)).toBe(byteArray.buffer);\n    });\n    it.each([\n        [0, 3],\n        [-3, 3],\n    ])(\n        'returns the buffer without modification when the specified slice encompasses the entire data (offset: %d, length: %d)',\n        (offset, length) => {\n            const byteArray = new Uint8Array([1, 2, 3]);\n            expect(toArrayBuffer(byteArray, offset, length)).toBe(byteArray.buffer);\n        },\n    );\n    it.each([\n        [-3, 0],\n        [-3, 1],\n        [-3, 2],\n        [-3, 2],\n        [-1, 0],\n        [-1, 1],\n        [-1, 2],\n        [-2, 0],\n        [-2, 1],\n        [0, 0],\n        [0, 1],\n        [0, 2],\n        [1, 0],\n        [1, 1],\n        [1, 2],\n        [2, 0],\n        [2, 1],\n        [2, 2],\n    ])('returns a new buffer when the slice reduces the data set (offset: %d, length: %d)', (offset, length) => {\n        const byteArray = new Uint8Array([1, 2, 3]);\n        expect(toArrayBuffer(byteArray, offset, length)).not.toBe(byteArray.buffer);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/bytes-test.ts",
    "content": "import { bytesEqual, containsBytes, fixBytes, mergeBytes, padBytes } from '../bytes';\n\ndescribe('mergeBytes', () => {\n    it('can merge multiple arrays of bytes together', () => {\n        const merged = mergeBytes([new Uint8Array([1, 2, 3]), new Uint8Array([4, 5]), new Uint8Array([6, 7, 8, 9])]);\n        expect(merged).toStrictEqual(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9]));\n    });\n    it('reuses the original byte array when applicable', () => {\n        const emptyBytesA = new Uint8Array();\n        const emptyBytesB = new Uint8Array();\n        const nonEmptyBytesA = new Uint8Array([1, 2, 3]);\n        const nonEmptyBytesB = new Uint8Array([4, 5, 6]);\n\n        // A new byte array is created when merging an empty array.\n        expect(mergeBytes([])).toStrictEqual(new Uint8Array(0));\n\n        // The first empty byte array is returned when merging multiple empty byte arrays.\n        expect(mergeBytes([emptyBytesA])).toBe(emptyBytesA);\n        expect(mergeBytes([emptyBytesA, emptyBytesB])).toBe(emptyBytesA);\n        expect(mergeBytes([emptyBytesB, emptyBytesA])).toBe(emptyBytesB);\n\n        // The first non-empty byte array is returned when merging multiple byte arrays such that only one is non-empty.\n        expect(mergeBytes([nonEmptyBytesA, emptyBytesA, emptyBytesB])).toBe(nonEmptyBytesA);\n        expect(mergeBytes([emptyBytesA, emptyBytesB, nonEmptyBytesA])).toBe(nonEmptyBytesA);\n\n        // A new byte array is created when merging multiple non-empty byte arrays.\n        expect(mergeBytes([nonEmptyBytesA, nonEmptyBytesB, emptyBytesA])).not.toBe(nonEmptyBytesA);\n        expect(mergeBytes([nonEmptyBytesA, nonEmptyBytesB, emptyBytesA])).not.toBe(nonEmptyBytesB);\n    });\n});\n\ndescribe('padBytes', () => {\n    it('can pad an array of bytes to the specified length', () => {\n        expect(padBytes(new Uint8Array([1, 2, 3]), 5)).toStrictEqual(new Uint8Array([1, 2, 3, 0, 0]));\n        expect(padBytes(new Uint8Array([1, 2, 3]), 2)).toStrictEqual(new Uint8Array([1, 2, 3]));\n    });\n    it('reuses the original byte array when applicable', () => {\n        const bytes = new Uint8Array([1, 2, 3, 4, 5]);\n        expect(padBytes(bytes, 5)).toBe(bytes);\n        expect(padBytes(bytes, 2)).toBe(bytes);\n        expect(padBytes(bytes, 10)).not.toBe(bytes);\n    });\n});\n\ndescribe('fixBytes', () => {\n    it('can fix an array of bytes to the specified length', () => {\n        expect(fixBytes(new Uint8Array([1, 2, 3]), 5)).toStrictEqual(new Uint8Array([1, 2, 3, 0, 0]));\n        expect(fixBytes(new Uint8Array([1, 2, 3]), 2)).toStrictEqual(new Uint8Array([1, 2]));\n    });\n    it('reuses the original byte array when applicable', () => {\n        const bytes = new Uint8Array([1, 2, 3, 4, 5]);\n        expect(fixBytes(bytes, 5)).toBe(bytes);\n        expect(fixBytes(bytes, 2)).not.toBe(bytes);\n        expect(fixBytes(bytes, 10)).not.toBe(bytes);\n    });\n});\n\ndescribe('bytesEqual', () => {\n    it('can check if two byte arrays are equal', () => {\n        expect(bytesEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3]))).toBe(true);\n        expect(bytesEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 4]))).toBe(false);\n    });\n    it('treats empty byte arrays as equal', () => {\n        expect(bytesEqual(new Uint8Array([]), new Uint8Array([]))).toBe(true);\n        expect(bytesEqual(new Uint8Array([]), new Uint8Array([0]))).toBe(false);\n        expect(bytesEqual(new Uint8Array([0]), new Uint8Array([]))).toBe(false);\n    });\n    it('returns false when byte arrays are different lengths', () => {\n        expect(bytesEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3, 4]))).toBe(false);\n        expect(bytesEqual(new Uint8Array([1, 2, 3, 4]), new Uint8Array([1, 2, 3]))).toBe(false);\n    });\n});\n\ndescribe('containsBytes', () => {\n    it('returns true when the data contains the bytes at the given offset', () => {\n        const data = new Uint8Array([1, 2, 3, 4]);\n        expect(containsBytes(data, new Uint8Array([1, 2, 3, 4]), 0)).toBe(true);\n        expect(containsBytes(data, new Uint8Array([2, 3]), 1)).toBe(true);\n        expect(containsBytes(data, new Uint8Array([1, 2]), 2)).toBe(false);\n    });\n\n    it('does not slice the data when offset is 0', () => {\n        const data = new Uint8Array([1, 2, 3]);\n        // Spy on slice to confirm it is not called when offset === 0.\n        const sliceSpy = jest.spyOn(data, 'slice');\n        containsBytes(data, new Uint8Array([1, 2, 3]), 0);\n        expect(sliceSpy).not.toHaveBeenCalled();\n        sliceSpy.mockRestore();\n    });\n\n    it('does not slice the data when offset equals negative byteLength', () => {\n        const data = new Uint8Array([1, 2, 3]);\n        const sliceSpy = jest.spyOn(data, 'slice');\n        containsBytes(data, new Uint8Array([1, 2, 3]), -3);\n        expect(sliceSpy).not.toHaveBeenCalled();\n        sliceSpy.mockRestore();\n    });\n\n    it('does not slice the data when offset is negative greater than byteLength', () => {\n        const data = new Uint8Array([1, 2, 3]);\n        const sliceSpy = jest.spyOn(data, 'slice');\n        containsBytes(data, new Uint8Array([1, 2, 3]), -4);\n        expect(sliceSpy).not.toHaveBeenCalled();\n        sliceSpy.mockRestore();\n    });\n\n    it('slices the data when offset is a non-zero partial offset', () => {\n        const data = new Uint8Array([1, 2, 3]);\n        const sliceSpy = jest.spyOn(data, 'slice');\n        containsBytes(data, new Uint8Array([2, 3]), 1);\n        expect(sliceSpy).toHaveBeenCalled();\n        sliceSpy.mockRestore();\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/codec-test.ts",
    "content": "import { Codec, createCodec, createDecoder, createEncoder, Encoder } from '../codec';\nimport { ReadonlyUint8Array } from '../readonly-uint8array';\n\ndescribe('Encoder', () => {\n    it('can define Encoder instances', () => {\n        const myEncoder: Encoder<string> = createEncoder({\n            fixedSize: 32,\n            write: (value: string, bytes, offset) => {\n                const charCodes = [...value.slice(0, 32)].map(char => Math.min(char.charCodeAt(0), 255));\n                bytes.set(charCodes, offset);\n                return offset + 32;\n            },\n        });\n\n        expect(myEncoder.fixedSize).toBe(32);\n\n        const expectedBytes = new Uint8Array(32).fill(0);\n        expectedBytes.set(new Uint8Array([104, 101, 108, 108, 111]));\n        expect(myEncoder.encode('hello')).toStrictEqual(expectedBytes);\n\n        const writtenBytes = new Uint8Array(32).fill(0);\n        expect(myEncoder.write('hello', writtenBytes, 0)).toBe(32);\n        expect(writtenBytes).toStrictEqual(expectedBytes);\n    });\n});\n\ndescribe('Decoder', () => {\n    it('can define Decoder instances', () => {\n        const myDecoder = createDecoder({\n            fixedSize: 32,\n            read: (bytes: ReadonlyUint8Array | Uint8Array, offset) => {\n                const slice = bytes.slice(offset, offset + 32);\n                const str = [...slice].map(charCode => String.fromCharCode(charCode)).join('');\n                return [str, offset + 32];\n            },\n        });\n\n        expect(myDecoder.fixedSize).toBe(32);\n\n        expect(myDecoder.decode(new Uint8Array([104, 101, 108, 108, 111]))).toBe('hello');\n        expect(myDecoder.read(new Uint8Array([104, 101, 108, 108, 111]), 0)).toStrictEqual(['hello', 32]);\n    });\n});\n\ndescribe('Codec', () => {\n    it('can define Codec instances', () => {\n        const myCodec: Codec<string> = createCodec({\n            fixedSize: 32,\n            read: (bytes: ReadonlyUint8Array | Uint8Array, offset) => {\n                const slice = bytes.slice(offset, offset + 32);\n                const str = [...slice].map(charCode => String.fromCharCode(charCode)).join('');\n                return [str, offset + 32];\n            },\n            write: (value: string, bytes, offset) => {\n                const charCodes = [...value.slice(0, 32)].map(char => Math.min(char.charCodeAt(0), 255));\n                bytes.set(charCodes, offset);\n                return offset + 32;\n            },\n        });\n\n        expect(myCodec.fixedSize).toBe(32);\n\n        const expectedBytes = new Uint8Array(32).fill(0);\n        expectedBytes.set(new Uint8Array([104, 101, 108, 108, 111]));\n        expect(myCodec.encode('hello')).toStrictEqual(expectedBytes);\n\n        const writtenBytes = new Uint8Array(32).fill(0);\n        expect(myCodec.write('hello', writtenBytes, 0)).toBe(32);\n        expect(writtenBytes).toStrictEqual(expectedBytes);\n\n        expect(myCodec.decode(new Uint8Array([104, 101, 108, 108, 111]))).toBe('hello');\n        expect(myCodec.read(new Uint8Array([104, 101, 108, 108, 111]), 0)).toStrictEqual(['hello', 32]);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/combine-codec.ts",
    "content": "import {\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH,\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH,\n    SolanaError,\n} from '@solana/errors';\n\nimport { createDecoder, createEncoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '../codec';\nimport { combineCodec } from '../combine-codec';\nimport { ReadonlyUint8Array } from '../readonly-uint8array';\n\ndescribe('combineCodec', () => {\n    it('can join encoders and decoders with the same type', () => {\n        const u8Encoder = createEncoder({\n            fixedSize: 1,\n            write: (value: number, buffer, offset) => {\n                buffer.set([value], offset);\n                return offset + 1;\n            },\n        });\n\n        const u8Decoder = createDecoder({\n            fixedSize: 1,\n            read: (bytes: ReadonlyUint8Array | Uint8Array, offset = 0) => [bytes[offset], offset + 1],\n        });\n\n        const u8Codec = combineCodec(u8Encoder, u8Decoder);\n\n        expect(u8Codec.fixedSize).toBe(1);\n        expect(u8Codec.encode(42)).toStrictEqual(new Uint8Array([42]));\n        expect(u8Codec.decode(new Uint8Array([42]))).toBe(42);\n    });\n\n    it('can join encoders and decoders with different but matching types', () => {\n        const u8Encoder: FixedSizeEncoder<bigint | number> = createEncoder({\n            fixedSize: 1,\n            write: (value: bigint | number, buffer, offset) => {\n                buffer.set([Number(value)], offset);\n                return offset + 1;\n            },\n        });\n\n        const u8Decoder: FixedSizeDecoder<bigint> = createDecoder({\n            fixedSize: 1,\n            read: (bytes: ReadonlyUint8Array | Uint8Array, offset = 0) => [BigInt(bytes[offset]), offset + 1],\n        });\n\n        const u8Codec: FixedSizeCodec<bigint | number, bigint> = combineCodec(u8Encoder, u8Decoder);\n\n        expect(u8Codec.fixedSize).toBe(1);\n        expect(u8Codec.encode(42)).toStrictEqual(new Uint8Array([42]));\n        expect(u8Codec.encode(42n)).toStrictEqual(new Uint8Array([42]));\n        expect(u8Codec.decode(new Uint8Array([42]))).toBe(42n);\n    });\n\n    it('cannot join encoders and decoders with different sizes', () => {\n        expect(() =>\n            combineCodec(\n                createEncoder({ fixedSize: 1, write: jest.fn() }),\n                createDecoder({ fixedSize: 2, read: jest.fn() }),\n            ),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH, {\n                decoderFixedSize: 2,\n                encoderFixedSize: 1,\n            }),\n        );\n\n        expect(() =>\n            combineCodec(\n                createEncoder({ getSizeFromValue: jest.fn(), maxSize: 1, write: jest.fn() }),\n                createDecoder({ read: jest.fn() }),\n            ),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH, {\n                decoderMaxSize: undefined,\n                encoderMaxSize: 1,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/decoder-entire-byte-array-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY, SolanaError } from '@solana/errors';\n\nimport { createDecoder, Decoder } from '../codec';\nimport { createDecoderThatConsumesEntireByteArray } from '../decoder-entire-byte-array';\n\ndescribe('createDecoderThatConsumesEntireByteArray', () => {\n    // Given: a decoder that consumes exactly 4 bytes\n    const outputNumber = 1234;\n    const innerDecoder: Decoder<number> = createDecoder({\n        fixedSize: 4,\n        read: (_bytes, offset) => [outputNumber, offset + 4],\n    });\n\n    describe('decode function', () => {\n        describe('with no offset', () => {\n            it('returns the same value as the inner decoder when the entire byte array is consumed', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(4);\n                const value = decoder.decode(bytes);\n                expect(value).toBe(outputNumber);\n            });\n\n            it('fatals when the inner decoder does not consume the entire byte array', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(5);\n                expect(() => decoder.decode(bytes)).toThrow(\n                    new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY, {\n                        expectedLength: 4,\n                        numExcessBytes: 1,\n                    }),\n                );\n            });\n        });\n\n        describe('with an offset', () => {\n            it('returns the same value as the inner decoder when the entire byte array is consumed', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(6);\n                const value = decoder.decode(bytes, 2);\n                expect(value).toBe(outputNumber);\n            });\n\n            it('fatals when the inner decoder does not consume the entire byte array', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(7);\n                expect(() => decoder.decode(bytes, 2)).toThrow(\n                    new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY, {\n                        expectedLength: 6,\n                        numExcessBytes: 1,\n                    }),\n                );\n            });\n        });\n    });\n\n    describe('read function', () => {\n        describe('with no offset', () => {\n            it('returns the same value as the inner decoder when the entire byte array is consumed', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(4);\n                const [value] = decoder.read(bytes, 0);\n                expect(value).toBe(outputNumber);\n            });\n\n            it('returns the same offset as the inner decoder when the entire byte array is consumed', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(4);\n                const [, offset] = decoder.read(bytes, 0);\n                expect(offset).toBe(4);\n            });\n\n            it('fatals when the inner decoder does not consume the entire byte array', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(5);\n                expect(() => decoder.read(bytes, 0)).toThrow(\n                    new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY, {\n                        expectedLength: 4,\n                        numExcessBytes: 1,\n                    }),\n                );\n            });\n        });\n\n        describe('with an offset', () => {\n            it('returns the same value as the inner decoder when the entire byte array is consumed', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(6);\n                const [value] = decoder.read(bytes, 2);\n                expect(value).toBe(outputNumber);\n            });\n\n            it('returns the same offset as the inner decoder when the entire byte array is consumed', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(6);\n                const [, offset] = decoder.read(bytes, 2);\n                expect(offset).toBe(6);\n            });\n\n            it('fatals when the inner decoder does not consume the entire byte array', () => {\n                const decoder = createDecoderThatConsumesEntireByteArray(innerDecoder);\n                const bytes = new Uint8Array(7);\n                expect(() => decoder.read(bytes, 2)).toThrow(\n                    new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY, {\n                        expectedLength: 6,\n                        numExcessBytes: 1,\n                    }),\n                );\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/fix-codec-size-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { createCodec } from '../codec';\nimport { fixCodecSize, fixDecoderSize, fixEncoderSize } from '../fix-codec-size';\nimport { b, getMockCodec } from './__setup__';\n\ndescribe('fixCodecSize', () => {\n    it('keeps same-sized byte arrays as-is', () => {\n        const mockCodec = getMockCodec();\n\n        mockCodec.getSizeFromValue.mockReturnValueOnce(10);\n        mockCodec.write.mockImplementation((_, bytes: Uint8Array, offset: number) => {\n            bytes.set(b('08050c0c0f170f120c04'), offset);\n            return offset + 10;\n        });\n        expect(fixCodecSize(mockCodec, 10).encode('helloworld')).toStrictEqual(b('08050c0c0f170f120c04'));\n        expect(mockCodec.write).toHaveBeenCalledWith('helloworld', expect.any(Uint8Array), 0);\n\n        fixCodecSize(mockCodec, 10).decode(b('08050c0c0f170f120c04'));\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f170f120c04'), 0);\n\n        fixCodecSize(mockCodec, 10).read(b('ffff08050c0c0f170f120c04'), 2);\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f170f120c04'), 0);\n    });\n\n    it('truncates over-sized byte arrays', () => {\n        const mockCodec = getMockCodec();\n\n        mockCodec.getSizeFromValue.mockReturnValueOnce(10);\n        mockCodec.write.mockImplementation((_, bytes: Uint8Array, offset: number) => {\n            bytes.set(b('08050c0c0f170f120c04'), offset);\n            return offset + 10;\n        });\n        expect(fixCodecSize(mockCodec, 5).encode('helloworld')).toStrictEqual(b('08050c0c0f'));\n        expect(mockCodec.write).toHaveBeenCalledWith('helloworld', expect.any(Uint8Array), 0);\n\n        fixCodecSize(mockCodec, 5).decode(b('08050c0c0f170f120c04'));\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f'), 0);\n\n        fixCodecSize(mockCodec, 5).read(b('ffff08050c0c0f170f120c04'), 2);\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f'), 0);\n    });\n\n    it('pads under-sized byte arrays', () => {\n        const mockCodec = getMockCodec();\n\n        mockCodec.getSizeFromValue.mockReturnValueOnce(5);\n        mockCodec.write.mockImplementation((_, bytes: Uint8Array, offset: number) => {\n            bytes.set(b('08050c0c0f'), offset);\n            return offset + 5;\n        });\n        expect(fixCodecSize(mockCodec, 10).encode('hello')).toStrictEqual(b('08050c0c0f0000000000'));\n        expect(mockCodec.write).toHaveBeenCalledWith('hello', expect.any(Uint8Array), 0);\n\n        fixCodecSize(mockCodec, 10).decode(b('08050c0c0f0000000000'));\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f0000000000'), 0);\n\n        fixCodecSize(mockCodec, 10).read(b('ffff08050c0c0f0000000000'), 2);\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f0000000000'), 0);\n\n        expect(() => fixCodecSize(mockCodec, 10).decode(b('08050c0c0f'))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n                bytesLength: 5,\n                codecDescription: 'fixCodecSize',\n                expected: 10,\n            }),\n        );\n    });\n\n    it('has the right sizes', () => {\n        const mockCodec = getMockCodec({ size: null });\n        expect(fixCodecSize(mockCodec, 12).fixedSize).toBe(12);\n        expect(fixCodecSize(mockCodec, 42).fixedSize).toBe(42);\n    });\n\n    it('can fix a codec that requires a minimum amount of bytes', () => {\n        // Given a mock `u32` codec that ensures the byte array is 4 bytes long.\n        const u32 = createCodec<number>({\n            fixedSize: 4,\n            read(bytes, offset = 0): [number, number] {\n                // eslint-disable-next-line jest/no-conditional-in-test\n                if (bytes.slice(offset).length < offset + 4) {\n                    throw new Error('Not enough bytes to decode a u32.');\n                }\n                return [bytes.slice(offset)[0], offset + 4];\n            },\n            write: (value: number, bytes, offset) => {\n                bytes.set([value], offset);\n                return offset + 4;\n            },\n        });\n\n        // When we synthesize a `u24` from that `u32` using `fixCodecSize`.\n        const u24 = fixCodecSize(u32, 3);\n\n        // Then we can encode a `u24`.\n        const bytes = u24.encode(42);\n        expect(bytes).toStrictEqual(new Uint8Array([42, 0, 0]));\n\n        // And we can decode it back.\n        const hydrated = u24.read(bytes, 0);\n        expect(hydrated).toStrictEqual([42, 3]);\n    });\n});\n\ndescribe('fixEncoderSize', () => {\n    it('can fix an encoder to a given amount of bytes', () => {\n        const mockCodec = getMockCodec();\n\n        mockCodec.getSizeFromValue.mockReturnValueOnce(10);\n        mockCodec.write.mockImplementationOnce((_, bytes: Uint8Array, offset: number) => {\n            bytes.set(b('08050c0c0f170f120c04'), offset);\n            return offset + 10;\n        });\n        expect(fixEncoderSize(mockCodec, 10).encode('helloworld')).toStrictEqual(b('08050c0c0f170f120c04'));\n        expect(mockCodec.write).toHaveBeenCalledWith('helloworld', expect.any(Uint8Array), 0);\n\n        mockCodec.getSizeFromValue.mockReturnValueOnce(10);\n        mockCodec.write.mockImplementationOnce((_, bytes: Uint8Array, offset: number) => {\n            bytes.set(b('08050c0c0f170f120c04'), offset);\n            return offset + 10;\n        });\n        expect(fixEncoderSize(mockCodec, 5).encode('helloworld')).toStrictEqual(b('08050c0c0f'));\n        expect(mockCodec.write).toHaveBeenCalledWith('helloworld', expect.any(Uint8Array), 0);\n\n        mockCodec.getSizeFromValue.mockReturnValueOnce(5);\n        mockCodec.write.mockImplementationOnce((_, bytes: Uint8Array, offset: number) => {\n            bytes.set(b('08050c0c0f'), offset);\n            return offset + 5;\n        });\n        expect(fixEncoderSize(mockCodec, 10).encode('hello')).toStrictEqual(b('08050c0c0f0000000000'));\n        expect(mockCodec.write).toHaveBeenCalledWith('hello', expect.any(Uint8Array), 0);\n    });\n});\n\ndescribe('fixDecoderSize', () => {\n    it('can fix a decoder to a given amount of bytes', () => {\n        const mockCodec = getMockCodec();\n\n        fixDecoderSize(mockCodec, 10).decode(b('08050c0c0f170f120c04'));\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f170f120c04'), 0);\n\n        fixDecoderSize(mockCodec, 5).decode(b('08050c0c0f170f120c04'));\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f'), 0);\n\n        fixDecoderSize(mockCodec, 10).decode(b('08050c0c0f0000000000'));\n        expect(mockCodec.read).toHaveBeenCalledWith(b('08050c0c0f0000000000'), 0);\n\n        expect(() => fixDecoderSize(mockCodec, 10).decode(b('08050c0c0f'))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n                bytesLength: 5,\n                codecDescription: 'fixCodecSize',\n                expected: 10,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/offset-codec-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, SolanaError } from '@solana/errors';\n\nimport { offsetCodec } from '../offset-codec';\nimport { b, expectNewPostOffset, expectNewPreOffset, getMockCodec } from './__setup__';\n\ndescribe('offsetCodec', () => {\n    describe('with relative offsets', () => {\n        it('keeps the same pre-offset', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: ({ preOffset }) => preOffset });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 3);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x000000[pre=3]ffffffff000000\n        });\n\n        it('keeps the same post-offset', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: ({ postOffset }) => postOffset });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 7);\n            // Before: 0x000000[pre=3]ffffffff[post=7]000000\n            // After:  0x000000[pre=3]ffffffff[post=7]000000\n        });\n\n        it('doubles the pre-offset', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: ({ preOffset }) => preOffset * 2 });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 6);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x000000000000[pre=6]ffffffff\n        });\n\n        it('doubles the post-offset', () => {\n            const mockCodec = getMockCodec({ innerSize: 1, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: ({ postOffset }) => postOffset * 2 });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 8);\n            // Before: 0x000000[pre=3]ff[post=4]000000000000\n            // After:  0x000000[pre=3]ff00000000[post=8]0000\n        });\n\n        it('goes forwards and restores the original offset', () => {\n            const mockCodec = getMockCodec({ innerSize: 2, size: 10 });\n            const codec = offsetCodec(mockCodec, {\n                postOffset: ({ preOffset }) => preOffset,\n                preOffset: ({ preOffset }) => preOffset + 2,\n            });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 5);\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 3);\n            // Before: 0x000000[pre=3]ffff[post=5]0000000000\n            // After:  0x000000[post=3]0000[pre=5]ffff000000\n        });\n\n        it('goes backwards and restores the original offset', () => {\n            const mockCodec = getMockCodec({ innerSize: 2, size: 10 });\n            const codec = offsetCodec(mockCodec, {\n                postOffset: ({ preOffset }) => preOffset,\n                preOffset: ({ preOffset }) => preOffset - 3,\n            });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 5, /* newPreOffset */ 2);\n            expectNewPostOffset(codec, /* preOffset */ 5, /* newPostOffset */ 5);\n            // Before: 0x0000000000[pre=5]ffff[post=7]000000\n            // After:  0x0000[pre=2]ffff00[post=5]0000000000\n        });\n    });\n\n    describe('with absolute offsets', () => {\n        it('sets an absolute pre-offset', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: () => 6 });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 6);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x000000000000[pre=6]ffffffff\n        });\n\n        it('sets an absolute post-offset', () => {\n            const mockCodec = getMockCodec({ innerSize: 1, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: () => 8 });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 8);\n            // Before: 0x000000[pre=3]ff[post=4]000000000000\n            // After:  0x000000[pre=3]ff00000000[post=8]0000\n        });\n    });\n\n    describe('with wrapped relative offsets', () => {\n        it('uses the provided pre-offset as-is if within the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: ({ preOffset, wrapBytes }) => wrapBytes(preOffset + 2) });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 5);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x0000000000[pre=5]ffffffff00\n        });\n\n        it('uses the provided post-offset as-is if within the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, {\n                postOffset: ({ postOffset, wrapBytes }) => wrapBytes(postOffset + 2),\n            });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 9);\n            // Before: 0x000000[pre=3]ffffffff[post=7]000000\n            // After:  0x000000[pre=3]ffffffff0000[post=9]00\n        });\n\n        it('wraps the pre-offset if it is below the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, {\n                preOffset: ({ preOffset, wrapBytes }) => wrapBytes(preOffset - 12),\n            });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 1);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x00[pre=1]ffffffff0000000000\n        });\n\n        it('wraps the post-offset if it is below the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, {\n                postOffset: ({ postOffset, wrapBytes }) => wrapBytes(postOffset - 12),\n            });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 5);\n            // Before: 0x000000[pre=3]ffffffff[post=7]000000\n            // After:  0x000000[pre=3]ffff[post=5]ffff000000\n        });\n\n        it('wraps the pre-offset if it is above the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, {\n                preOffset: ({ preOffset, wrapBytes }) => wrapBytes(preOffset + 12),\n            });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 5);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x0000000000[pre=5]ffffffff00\n        });\n\n        it('wraps the post-offset if it is above the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, {\n                postOffset: ({ postOffset, wrapBytes }) => wrapBytes(postOffset + 12),\n            });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 9);\n            // Before: 0x000000[pre=3]ffffffff[post=7]000000\n            // After:  0x000000[pre=3]ffffffff0000[post=9]00\n        });\n\n        it('always uses a zero offset if the byte array is empty', () => {\n            const mockCodec = getMockCodec({ innerSize: 0, size: 0 });\n            const codec = offsetCodec(mockCodec, {\n                postOffset: ({ postOffset, wrapBytes }) => wrapBytes(postOffset - 42),\n                preOffset: ({ preOffset, wrapBytes }) => wrapBytes(preOffset + 42),\n            });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 0, /* newPreOffset */ 0);\n            expectNewPostOffset(codec, /* preOffset */ 0, /* newPostOffset */ 0);\n            // Before: 0x[pre=0][post=0]\n            // After:  0x[pre=0][post=0]\n        });\n    });\n\n    describe('with wrapped absolute offsets', () => {\n        it('uses the provided pre-offset as-is if within the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: ({ wrapBytes }) => wrapBytes(5) });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 5);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x0000000000[pre=5]ffffffff00\n        });\n\n        it('uses the provided post-offset as-is if within the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: ({ wrapBytes }) => wrapBytes(9) });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 9);\n            // Before: 0x000000[pre=3]ffffffff[post=7]000000\n            // After:  0x000000[pre=3]ffffffff0000[post=9]00\n        });\n\n        it('wraps the pre-offset if it is below the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: ({ wrapBytes }) => wrapBytes(-19) });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 1);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x00[pre=1]ffffffff0000000000\n        });\n\n        it('wraps the post-offset if it is below the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: ({ wrapBytes }) => wrapBytes(-15) });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 5);\n            // Before: 0x000000[pre=3]ffffffff[post=7]000000\n            // After:  0x000000[pre=3]ffff[post=5]ffff000000\n        });\n\n        it('wraps the pre-offset if it is above the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: ({ wrapBytes }) => wrapBytes(105) });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 3, /* newPreOffset */ 5);\n            // Before: 0x000000[pre=3]ffffffff000000\n            // After:  0x0000000000[pre=5]ffffffff00\n        });\n\n        it('wraps the post-offset if it is above the byte range', () => {\n            const mockCodec = getMockCodec({ innerSize: 4, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: ({ wrapBytes }) => wrapBytes(109) });\n            expectNewPostOffset(codec, /* preOffset */ 3, /* newPostOffset */ 9);\n            // Before: 0x000000[pre=3]ffffffff[post=7]000000\n            // After:  0x000000[pre=3]ffffffff0000[post=9]00\n        });\n\n        it('always uses a zero offset if the byte array is empty', () => {\n            const mockCodec = getMockCodec({ innerSize: 0, size: 0 });\n            const codec = offsetCodec(mockCodec, {\n                postOffset: ({ wrapBytes }) => wrapBytes(-42),\n                preOffset: ({ wrapBytes }) => wrapBytes(42),\n            });\n            expectNewPreOffset(codec, mockCodec, /* preOffset */ 0, /* newPreOffset */ 0);\n            expectNewPostOffset(codec, /* preOffset */ 0, /* newPostOffset */ 0);\n            // Before: 0x[pre=0][post=0]\n            // After:  0x[pre=0][post=0]\n        });\n    });\n\n    describe('with offset overflow', () => {\n        it('throws an error if the pre-offset is negatif', () => {\n            const mockCodec = getMockCodec({ innerSize: 0, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: () => -1 });\n            expect(() => codec.encode(42)).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n                    bytesLength: 10,\n                    codecDescription: 'offsetEncoder',\n                    offset: -1,\n                }),\n            );\n            expect(() => codec.decode(b('00'.repeat(10)))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n                    bytesLength: 10,\n                    codecDescription: 'offsetDecoder',\n                    offset: -1,\n                }),\n            );\n        });\n\n        it('throws an error if the pre-offset is above the byte array length', () => {\n            const mockCodec = getMockCodec({ innerSize: 0, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: () => 11 });\n            expect(() => codec.encode(42)).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n                    bytesLength: 10,\n                    codecDescription: 'offsetEncoder',\n                    offset: 11,\n                }),\n            );\n            expect(() => codec.decode(b('00'.repeat(10)))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n                    bytesLength: 10,\n                    codecDescription: 'offsetDecoder',\n                    offset: 11,\n                }),\n            );\n        });\n\n        it('does not throw an error if the pre-offset is equal to the byte array length', () => {\n            const mockCodec = getMockCodec({ innerSize: 0, size: 10 });\n            const codec = offsetCodec(mockCodec, { preOffset: () => 10 });\n            expect(() => codec.encode(42)).not.toThrow();\n            expect(() => codec.decode(b('00'.repeat(10)))).not.toThrow();\n        });\n\n        it('throws an error if the post-offset is negatif', () => {\n            const mockCodec = getMockCodec({ innerSize: 0, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: () => -1 });\n            expect(() => codec.encode(42)).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n                    bytesLength: 10,\n                    codecDescription: 'offsetEncoder',\n                    offset: -1,\n                }),\n            );\n            expect(() => codec.decode(b('00'.repeat(10)))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n                    bytesLength: 10,\n                    codecDescription: 'offsetDecoder',\n                    offset: -1,\n                }),\n            );\n        });\n\n        it('throws an error if the post-offset is above the byte array length', () => {\n            const mockCodec = getMockCodec({ innerSize: 0, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: () => 11 });\n            expect(() => codec.encode(42)).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n                    bytesLength: 10,\n                    codecDescription: 'offsetEncoder',\n                    offset: 11,\n                }),\n            );\n            expect(() => codec.decode(b('00'.repeat(10)))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n                    bytesLength: 10,\n                    codecDescription: 'offsetDecoder',\n                    offset: 11,\n                }),\n            );\n        });\n\n        it('does not throw an error if the post-offset is equal to the byte array length', () => {\n            const mockCodec = getMockCodec({ innerSize: 0, size: 10 });\n            const codec = offsetCodec(mockCodec, { postOffset: () => 10 });\n            expect(() => codec.encode(42)).not.toThrow();\n            expect(() => codec.decode(b('00'.repeat(10)))).not.toThrow();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/pad-codec-test.ts",
    "content": "import { padLeftCodec, padRightCodec } from '../pad-codec';\nimport { expectNewPostOffset, expectNewPreOffset, getMockCodec } from './__setup__';\n\ndescribe('padLeftCodec', () => {\n    it('offsets and resizes the codec', () => {\n        const mockCodec = getMockCodec({ size: 8 });\n        const codec = padLeftCodec(mockCodec, 4);\n        expect(codec.fixedSize).toBe(12);\n        expectNewPreOffset(codec, mockCodec, /* preOffset */ 0, /* newPreOffset */ 4);\n        expectNewPostOffset(codec, /* preOffset */ 0, /* newPostOffset */ 12);\n        // Before: 0x[pre=0]ffffffffffffffff[post=8]\n        // After:  0x00000000[pre=4]ffffffffffffffff[post=12]\n    });\n\n    it('does nothing with a zero offset', () => {\n        const mockCodec = getMockCodec({ size: 8 });\n        const codec = padLeftCodec(mockCodec, 0);\n        expect(codec.fixedSize).toBe(8);\n        expectNewPreOffset(codec, mockCodec, /* preOffset */ 0, /* newPreOffset */ 0);\n        expectNewPostOffset(codec, /* preOffset */ 0, /* newPostOffset */ 8);\n        // Before: 0x[pre=0]ffffffffffffffff[post=8]\n        // After:  0x[pre=0]ffffffffffffffff[post=8]\n    });\n});\n\ndescribe('padRightCodec', () => {\n    it('offsets and resizes the codec', () => {\n        const mockCodec = getMockCodec({ size: 8 });\n        const codec = padRightCodec(mockCodec, 4);\n        expect(codec.fixedSize).toBe(12);\n        expectNewPreOffset(codec, mockCodec, /* preOffset */ 0, /* newPreOffset */ 0);\n        expectNewPostOffset(codec, /* preOffset */ 0, /* newPostOffset */ 12);\n        // Before: 0x[pre=0]ffffffffffffffff[post=8]\n        // After:  0x[pre=0]ffffffffffffffff00000000[post=12]\n    });\n\n    it('does nothing with a zero offset', () => {\n        const mockCodec = getMockCodec({ size: 8 });\n        const codec = padRightCodec(mockCodec, 0);\n        expect(codec.fixedSize).toBe(8);\n        expectNewPreOffset(codec, mockCodec, /* preOffset */ 0, /* newPreOffset */ 0);\n        expectNewPostOffset(codec, /* preOffset */ 0, /* newPostOffset */ 8);\n        // Before: 0x[pre=0]ffffffffffffffff[post=8]\n        // After:  0x[pre=0]ffffffffffffffff[post=8]\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/resize-codec-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { FixedSizeCodec } from '../codec';\nimport { resizeCodec } from '../resize-codec';\nimport { getMockCodec } from './__setup__';\n\ndescribe('resizeCodec', () => {\n    it('resizes fixed-size codecs', () => {\n        const mockCodec = getMockCodec({ size: 42 }) as FixedSizeCodec<unknown, 42>;\n        expect(resizeCodec(mockCodec, size => size + 1).fixedSize).toBe(43);\n        expect(resizeCodec(mockCodec, size => size * 2).fixedSize).toBe(84);\n        expect(resizeCodec(mockCodec, () => 0).fixedSize).toBe(0);\n    });\n\n    it('resizes variable-size codecs', () => {\n        const mockCodec = getMockCodec();\n        mockCodec.getSizeFromValue.mockReturnValue(42);\n        expect(resizeCodec(mockCodec, size => size + 1).getSizeFromValue(null)).toBe(43);\n        expect(resizeCodec(mockCodec, size => size * 2).getSizeFromValue(null)).toBe(84);\n        expect(resizeCodec(mockCodec, () => 0).getSizeFromValue(null)).toBe(0);\n    });\n\n    it('throws when fixed-size codecs have negative sizes', () => {\n        const mockCodec = getMockCodec({ size: 42 }) as FixedSizeCodec<unknown, 42>;\n        expect(() => resizeCodec(mockCodec, size => size - 100).fixedSize).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH, {\n                bytesLength: -58,\n                codecDescription: 'resizeEncoder',\n            }),\n        );\n    });\n\n    it('throws when variable-size codecs have negative sizes', () => {\n        const mockCodec = getMockCodec();\n        mockCodec.getSizeFromValue.mockReturnValue(42);\n        expect(() => resizeCodec(mockCodec, size => size - 100).getSizeFromValue(null)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH, {\n                bytesLength: -58,\n                codecDescription: 'resizeEncoder',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/reverse-codec-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH, SolanaError } from '@solana/errors';\n\nimport { createDecoder, createEncoder } from '../codec';\nimport { fixCodecSize } from '../fix-codec-size';\nimport { reverseCodec, reverseDecoder, reverseEncoder } from '../reverse-codec';\nimport { b, base16 } from './__setup__';\n\ndescribe('reverseCodec', () => {\n    it('can reverse the bytes of a fixed-size codec', () => {\n        const s = (size: number) => reverseCodec(fixCodecSize(base16, size));\n\n        // Encode.\n        expect(s(1).encode('99')).toStrictEqual(b('99'));\n        expect(s(2).encode('99ff')).toStrictEqual(b('ff99'));\n        expect(s(2).encode('ff9999')).toStrictEqual(b('99ff'));\n        expect(s(3).encode('9999ff')).toStrictEqual(b('ff9999'));\n        expect(s(3).encode('ff9999')).toStrictEqual(b('9999ff'));\n        expect(s(4).encode('999999ff')).toStrictEqual(b('ff999999'));\n        expect(s(4).encode('ff999999')).toStrictEqual(b('999999ff'));\n        expect(s(8).encode('99999999999999ff')).toStrictEqual(b('ff99999999999999'));\n        expect(s(8).encode('ff99999999999999')).toStrictEqual(b('99999999999999ff'));\n        expect(s(32).encode(`ff${'99'.repeat(31)}`)).toStrictEqual(b(`${'99'.repeat(31)}ff`));\n        expect(s(32).encode(`${'99'.repeat(31)}ff`)).toStrictEqual(b(`ff${'99'.repeat(31)}`));\n\n        // Decode.\n        expect(s(2).decode(b('ff99'))).toBe('99ff');\n        expect(s(2).decode(b('99ff'))).toBe('ff99');\n        expect(s(3).decode(b('ff9999'))).toBe('9999ff');\n        expect(s(3).decode(b('9999ff'))).toBe('ff9999');\n        expect(s(3).read(b('aaaaff9999bbbb'), 2)).toStrictEqual(['9999ff', 5]);\n        expect(s(3).read(b('aaaa9999ffbbbb'), 2)).toStrictEqual(['ff9999', 5]);\n        expect(s(4).decode(b('999999ff'))).toBe('ff999999');\n        expect(s(4).decode(b('ff999999'))).toBe('999999ff');\n        expect(s(4).read(b('aaaaff999999bbbb'), 2)).toStrictEqual(['999999ff', 6]);\n        expect(s(4).read(b('aaaa999999ffbbbb'), 2)).toStrictEqual(['ff999999', 6]);\n\n        // Variable-size codec.\n        // @ts-expect-error Reversed codec should be fixed-size.\n        expect(() => reverseCodec(base16)).toThrow(new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH));\n    });\n});\n\ndescribe('reverseEncoder', () => {\n    it('can reverse the bytes of a fixed-size encoder', () => {\n        const encoder = createEncoder({\n            fixedSize: 2,\n            write: (value: number, bytes, offset) => {\n                bytes.set([value, 0], offset);\n                return offset + 2;\n            },\n        });\n\n        const reversedEncoder = reverseEncoder(encoder);\n        expect(reversedEncoder.fixedSize).toBe(2);\n        expect(reversedEncoder.encode(42)).toStrictEqual(new Uint8Array([0, 42]));\n\n        // @ts-expect-error Reversed encoder should be fixed-size.\n        expect(() => reverseEncoder(base16)).toThrow(new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH));\n    });\n\n    it('gives the encoder access to the unboxed original byte array', () => {\n        const write = jest.fn();\n        const encoder = createEncoder({\n            fixedSize: 2,\n            write,\n        });\n\n        const reversedEncoder = reverseEncoder(encoder);\n        const inputBytes = new Uint8Array([1, 2, 3, 4]);\n        const offset = 1;\n        reversedEncoder.write(9, inputBytes, offset);\n        expect(write).toHaveBeenCalledWith(\n            expect.anything(), // We are not testing the value being written\n            inputBytes, // The original, unboxed, uncloned bytes.\n            expect.anything(), // We are not testing the offset\n        );\n    });\n});\n\ndescribe('reverseDecoder', () => {\n    it('can reverse the bytes of a fixed-size decoder', () => {\n        const decoder = createDecoder({\n            fixedSize: 2,\n            read: (bytes, offset = 0) => [`${bytes[offset]}-${bytes[offset + 1]}`, offset + 2],\n        });\n\n        const reversedDecoder = reverseDecoder(decoder);\n        expect(reversedDecoder.fixedSize).toBe(2);\n        expect(reversedDecoder.read(new Uint8Array([42, 0]), 0)).toStrictEqual(['0-42', 2]);\n\n        // @ts-expect-error Reversed decoder should be fixed-size.\n        expect(() => reverseDecoder(base16)).toThrow(new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH));\n    });\n\n    it('does not modify the input bytes in-place', () => {\n        const decoder = createDecoder({\n            fixedSize: 2,\n            read: (bytes, offset = 0) => [`${bytes[offset]}-${bytes[offset + 1]}`, offset + 2],\n        });\n\n        const reversedDecoder = reverseDecoder(decoder);\n        const inputBytes = new Uint8Array([42, 0]);\n        reversedDecoder.read(inputBytes, 0);\n        expect(inputBytes).toStrictEqual(new Uint8Array([42, 0]));\n    });\n\n    it('gives the decoder access to the unboxed original byte array', () => {\n        const read = jest.fn();\n        const decoder = createDecoder({\n            fixedSize: 2,\n            read,\n        });\n\n        const reversedDecoder = reverseDecoder(decoder);\n        const inputBytes = new Uint8Array([1, 2, 3, 4]);\n        const offset = 1;\n        reversedDecoder.read(inputBytes, offset);\n        expect(read).toHaveBeenCalledWith(\n            expect.objectContaining([\n                1,\n                expect.any(Number), // We are not testing the post-reversal bytes, only that the\n                expect.any(Number), // original bytes at the end were supplied to the decoder.\n                4,\n            ]),\n            expect.anything(), // We are not testing the offset\n        );\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__tests__/transform-codec-test.ts",
    "content": "import { Codec, createCodec, createDecoder, createEncoder } from '../codec';\nimport { ReadonlyUint8Array } from '../readonly-uint8array';\nimport { transformCodec, transformDecoder, transformEncoder } from '../transform-codec';\n\nconst numberCodec: Codec<number> = createCodec({\n    fixedSize: 1,\n    read: (bytes: ReadonlyUint8Array | Uint8Array): [number, number] => [bytes[0], 1],\n    write: (value: number, bytes, offset) => {\n        bytes.set([value], offset);\n        return offset + 1;\n    },\n});\n\ndescribe('transformCodec', () => {\n    it('can loosen the codec input with a map', () => {\n        // From <number> to <number | string, number>.\n        const mappedCodec: Codec<number | string, number> = transformCodec(numberCodec, (value: number | string) =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            typeof value === 'number' ? value : value.length,\n        );\n\n        const bytesA = mappedCodec.encode(42);\n        expect(mappedCodec.decode(bytesA)).toBe(42);\n\n        const bytesB = mappedCodec.encode('Hello world');\n        expect(mappedCodec.decode(bytesB)).toBe(11);\n    });\n\n    it('can map both the input and output of a codec', () => {\n        // From <number> to <number | string, string>.\n        const mappedCodec: Codec<number | string, string> = transformCodec(\n            numberCodec,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            (value: number | string) => (typeof value === 'number' ? value : value.length),\n            (value: number) => 'x'.repeat(value),\n        );\n\n        const bytesA = mappedCodec.encode(42);\n        expect(mappedCodec.decode(bytesA)).toBe('x'.repeat(42));\n\n        const bytesB = mappedCodec.encode('Hello world');\n        expect(mappedCodec.decode(bytesB)).toBe('x'.repeat(11));\n    });\n\n    it('can map the input and output of a codec to the same type', () => {\n        // From <number> to <string>.\n        const mappedCodec: Codec<string> = transformCodec(\n            numberCodec,\n            (value: string) => value.length,\n            (value: number) => 'x'.repeat(value),\n        );\n\n        const bytesA = mappedCodec.encode('42');\n        expect(mappedCodec.decode(bytesA)).toBe('xx');\n\n        const bytesB = mappedCodec.encode('Hello world');\n        expect(mappedCodec.decode(bytesB)).toBe('xxxxxxxxxxx');\n    });\n\n    it('can wrap a codec type in an object using a map', () => {\n        // From <number> to <{ value: number }>.\n        type Wrap<T> = { value: T };\n        const mappedCodec: Codec<Wrap<number>> = transformCodec(\n            numberCodec,\n            (value: Wrap<number>) => value.value,\n            (value: number): Wrap<number> => ({ value }),\n        );\n\n        const bytes = mappedCodec.encode({ value: 42 });\n        expect(mappedCodec.decode(bytes)).toStrictEqual({ value: 42 });\n    });\n\n    it('map a codec to loosen its input by providing default values', () => {\n        // Create Codec<Strict>.\n        type Strict = { discriminator: number; label: string };\n        const strictCodec: Codec<Strict> = createCodec({\n            fixedSize: 2,\n            read: (bytes: ReadonlyUint8Array | Uint8Array): [Strict, number] => [\n                { discriminator: bytes[0], label: 'x'.repeat(bytes[1]) },\n                1,\n            ],\n            write: (value: Strict, bytes, offset) => {\n                bytes.set([value.discriminator, value.label.length], offset);\n                return offset + 2;\n            },\n        });\n\n        const bytesA = strictCodec.encode({ discriminator: 5, label: 'Hello world' });\n        expect(strictCodec.decode(bytesA)).toStrictEqual({\n            discriminator: 5,\n            label: 'xxxxxxxxxxx',\n        });\n\n        // From <Strict> to <Loose, Strict>.\n        type Loose = { discriminator?: number; label: string };\n        const looseCodec: Codec<Loose, Strict> = transformCodec(\n            strictCodec,\n            (value: Loose): Strict => ({\n                discriminator: 42, // <- Default value.\n                ...value,\n            }),\n        );\n\n        // With explicit discriminator.\n        const bytesB = looseCodec.encode({ discriminator: 5, label: 'Hello world' });\n        expect(looseCodec.decode(bytesB)).toStrictEqual({\n            discriminator: 5,\n            label: 'xxxxxxxxxxx',\n        });\n\n        // With implicit discriminator.\n        const bytesC = looseCodec.encode({ label: 'Hello world' });\n        expect(looseCodec.decode(bytesC)).toStrictEqual({\n            discriminator: 42,\n            label: 'xxxxxxxxxxx',\n        });\n    });\n\n    it('can loosen a tuple codec', () => {\n        const codec: Codec<[number, string]> = createCodec({\n            fixedSize: 2,\n            read: (bytes: ReadonlyUint8Array | Uint8Array): [[number, string], number] => [\n                [bytes[0], 'x'.repeat(bytes[1])],\n                2,\n            ],\n            write: (value: [number, string], bytes, offset) => {\n                bytes.set([value[0], value[1].length], offset);\n                return offset + 2;\n            },\n        });\n\n        const bytesA = codec.encode([42, 'Hello world']);\n        expect(codec.decode(bytesA)).toStrictEqual([42, 'xxxxxxxxxxx']);\n\n        const mappedCodec = transformCodec(codec, (value: [number | null, string]): [number, string] => [\n            // eslint-disable-next-line jest/no-conditional-in-test\n            value[0] ?? value[1].length,\n            value[1],\n        ]);\n\n        const bytesB = mappedCodec.encode([null, 'Hello world']);\n        expect(mappedCodec.decode(bytesB)).toStrictEqual([11, 'xxxxxxxxxxx']);\n\n        const bytesC = mappedCodec.encode([42, 'Hello world']);\n        expect(mappedCodec.decode(bytesC)).toStrictEqual([42, 'xxxxxxxxxxx']);\n    });\n});\n\ndescribe('transformEncoder', () => {\n    it('can map an encoder to another encoder', () => {\n        const encoderA = createEncoder({\n            fixedSize: 1,\n            write: (value: number, bytes, offset) => {\n                bytes.set([value], offset);\n                return offset + 1;\n            },\n        });\n\n        const encoderB = transformEncoder(encoderA, (value: string): number => value.length);\n\n        expect(encoderB.fixedSize).toBe(1);\n        expect(encoderB.encode('helloworld')).toStrictEqual(new Uint8Array([10]));\n    });\n});\n\ndescribe('transformDecoder', () => {\n    it('can map an encoder to another encoder', () => {\n        const decoder = createDecoder({\n            fixedSize: 1,\n            read: (bytes: ReadonlyUint8Array | Uint8Array, offset = 0) => [bytes[offset], offset + 1],\n        });\n\n        const decoderB = transformDecoder(decoder, (value: number): string => 'x'.repeat(value));\n\n        expect(decoderB.fixedSize).toBe(1);\n        expect(decoderB.decode(new Uint8Array([10]))).toBe('xxxxxxxxxx');\n    });\n});\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/add-codec-sentinel-typetest.ts",
    "content": "import { addCodecSentinel, addDecoderSentinel, addEncoderSentinel } from '../add-codec-sentinel';\nimport {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\n\nconst sentinel = {} as Uint8Array;\n\n{\n    // [addEncoderSentinel]: It knows if the encoder is fixed size or variable size.\n    addEncoderSentinel({} as FixedSizeEncoder<string>, sentinel) satisfies FixedSizeEncoder<string>;\n    addEncoderSentinel({} as VariableSizeEncoder<string>, sentinel) satisfies VariableSizeEncoder<string>;\n    addEncoderSentinel({} as Encoder<string>, sentinel) satisfies VariableSizeEncoder<string>;\n}\n\n{\n    // [addDecoderSentinel]: It knows if the decoder is fixed size or variable size.\n    addDecoderSentinel({} as FixedSizeDecoder<string>, sentinel) satisfies FixedSizeDecoder<string>;\n    addDecoderSentinel({} as VariableSizeDecoder<string>, sentinel) satisfies VariableSizeDecoder<string>;\n    addDecoderSentinel({} as Decoder<string>, sentinel) satisfies VariableSizeDecoder<string>;\n}\n\n{\n    // [addCodecSentinel]: It knows if the codec is fixed size or variable size.\n    addCodecSentinel({} as FixedSizeCodec<string>, sentinel) satisfies FixedSizeCodec<string>;\n    addCodecSentinel({} as VariableSizeCodec<string>, sentinel) satisfies VariableSizeCodec<string>;\n    addCodecSentinel({} as Codec<string>, sentinel) satisfies VariableSizeCodec<string>;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/add-codec-size-prefix-typetest.ts",
    "content": "import { addCodecSizePrefix, addDecoderSizePrefix, addEncoderSizePrefix } from '../add-codec-size-prefix';\nimport {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\n\nconst u32Encoder = {} as FixedSizeEncoder<number, 4>;\nconst u32Decoder = {} as FixedSizeDecoder<number, 4>;\nconst u32Codec = {} as FixedSizeCodec<number, number, 4>;\n\nconst shortU16Encoder = {} as VariableSizeEncoder<number>;\nconst shortU16Decoder = {} as VariableSizeDecoder<number>;\nconst shortU16Codec = {} as VariableSizeCodec<number>;\n\n{\n    // [addEncoderSizePrefix]: It knows if the encoder is fixed size or variable size.\n    addEncoderSizePrefix({} as FixedSizeEncoder<string>, u32Encoder) satisfies FixedSizeEncoder<string>;\n    addEncoderSizePrefix({} as VariableSizeEncoder<string>, u32Encoder) satisfies VariableSizeEncoder<string>;\n    addEncoderSizePrefix({} as Encoder<string>, u32Encoder) satisfies VariableSizeEncoder<string>;\n    addEncoderSizePrefix({} as FixedSizeEncoder<string>, shortU16Encoder) satisfies VariableSizeEncoder<string>;\n    addEncoderSizePrefix({} as VariableSizeEncoder<string>, shortU16Encoder) satisfies VariableSizeEncoder<string>;\n    addEncoderSizePrefix({} as Encoder<string>, shortU16Encoder) satisfies VariableSizeEncoder<string>;\n}\n\n{\n    // [addDecoderSizePrefix]: It knows if the decoder is fixed size or variable size.\n    addDecoderSizePrefix({} as FixedSizeDecoder<string>, u32Decoder) satisfies FixedSizeDecoder<string>;\n    addDecoderSizePrefix({} as VariableSizeDecoder<string>, u32Decoder) satisfies VariableSizeDecoder<string>;\n    addDecoderSizePrefix({} as Decoder<string>, u32Decoder) satisfies VariableSizeDecoder<string>;\n    addDecoderSizePrefix({} as FixedSizeDecoder<string>, shortU16Decoder) satisfies VariableSizeDecoder<string>;\n    addDecoderSizePrefix({} as VariableSizeDecoder<string>, shortU16Decoder) satisfies VariableSizeDecoder<string>;\n    addDecoderSizePrefix({} as Decoder<string>, shortU16Decoder) satisfies VariableSizeDecoder<string>;\n}\n\n{\n    // [addCodecSizePrefix]: It knows if the codec is fixed size or variable size.\n    addCodecSizePrefix({} as FixedSizeCodec<string>, u32Codec) satisfies FixedSizeCodec<string>;\n    addCodecSizePrefix({} as VariableSizeCodec<string>, u32Codec) satisfies VariableSizeCodec<string>;\n    addCodecSizePrefix({} as Codec<string>, u32Codec) satisfies VariableSizeCodec<string>;\n    addCodecSizePrefix({} as FixedSizeCodec<string>, shortU16Codec) satisfies VariableSizeCodec<string>;\n    addCodecSizePrefix({} as VariableSizeCodec<string>, shortU16Codec) satisfies VariableSizeCodec<string>;\n    addCodecSizePrefix({} as Codec<string>, shortU16Codec) satisfies VariableSizeCodec<string>;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/array-buffers-typetest.ts",
    "content": "import { toArrayBuffer } from '../array-buffers';\n\n// [DESCRIBE] toArrayBuffer.\n{\n    // It returns `ArrayBuffer` given a view with an underlying shared array buffer\n    {\n        const bytesWithSharedBuffer = null as unknown as Uint8Array<SharedArrayBuffer>;\n        toArrayBuffer(bytesWithSharedBuffer) satisfies ArrayBuffer;\n    }\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/bytes-typetest.ts",
    "content": "import { padBytes } from '../bytes';\nimport { ReadonlyUint8Array } from '../readonly-uint8array';\n\n// [DESCRIBE] padBytes.\n{\n    // It returns `ReadonlyUint8Array` given a readonly input\n    {\n        const readonlyArray = null as unknown as ReadonlyUint8Array;\n        padBytes(readonlyArray, 42) satisfies ReadonlyUint8Array;\n    }\n    // It returns `Uint8Array` given a writable input\n    {\n        const array = null as unknown as Uint8Array;\n        padBytes(array, 42) satisfies Uint8Array;\n    }\n    // It downcasts readonly inputs to a basic `ReadonlyUint8Array`\n    {\n        const fancyReadonlyArray = null as unknown as ReadonlyUint8Array & { glitter: true };\n        // @ts-expect-error Should have the more specific type stripped out.\n        padBytes(fancyReadonlyArray, 42) satisfies { glitter: true };\n    }\n    // It downcasts writable inputs to a basic `Uint8Array`\n    {\n        const fancyArray = null as unknown as Uint8Array & { glitter: true };\n        // @ts-expect-error Should have the more specific type stripped out.\n        padBytes(fancyArray, 42) satisfies { glitter: true };\n    }\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/codec-typetest.ts",
    "content": "import {\n    assertIsFixedSize,\n    assertIsVariableSize,\n    Codec,\n    createCodec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    isFixedSize,\n    isVariableSize,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\n\n{\n    // [createEncoder]: It knows if the encoder is fixed size or variable size.\n    createEncoder({\n        fixedSize: 42,\n        write: (_: string) => 1,\n    }) satisfies FixedSizeEncoder<string, 42>;\n    createEncoder({\n        getSizeFromValue: (_: string) => 42,\n        write: (_: string) => 1,\n    }) satisfies VariableSizeEncoder<string>;\n    createEncoder({} as Encoder<string>) satisfies Encoder<string>;\n}\n\n{\n    // [createDecoder]: It knows if the decoder is fixed size or variable size.\n    createDecoder({ fixedSize: 42, read: (): [string, number] => ['', 1] }) satisfies FixedSizeDecoder<string, 42>;\n    createDecoder({ read: (): [string, number] => ['', 1] }) satisfies VariableSizeDecoder<string>;\n    createDecoder({} as Decoder<string>) satisfies Decoder<string>;\n}\n\n{\n    // [createCodec]: It knows if the codec is fixed size or variable size.\n    createCodec({\n        fixedSize: 42,\n        read: (): [string, number] => ['', 1],\n        write: (_: string) => 1,\n    }) satisfies FixedSizeCodec<string, string, 42>;\n    createCodec({\n        getSizeFromValue: (_: string) => 42,\n        read: (): [string, number] => ['', 1],\n        write: (_: string) => 1,\n    }) satisfies VariableSizeCodec<string>;\n    createCodec({} as Codec<string>) satisfies Codec<string>;\n}\n\n{\n    // [isFixedSize]: It returns true if the codec is fixed size and keeps the type information.\n    const codec = {} as FixedSizeCodec<string, string, 42> | VariableSizeCodec<string>;\n    if (isFixedSize(codec)) {\n        codec satisfies FixedSizeCodec<string, string, 42>;\n    }\n}\n\n{\n    // [isFixedSize]: It works with codec sizes only.\n    const codec = {} as { fixedSize: 42 } | { maxSize?: number };\n    if (isFixedSize(codec)) {\n        codec satisfies { fixedSize: 42 };\n    }\n}\n\n{\n    // [assertIsFixedSize]: It asserts the codec is fixed size and keeps the type information.\n    const codec = {} as FixedSizeCodec<string, string, 42> | VariableSizeCodec<string>;\n    assertIsFixedSize(codec);\n    codec satisfies FixedSizeCodec<string, string, 42>;\n}\n\n{\n    // [assertIsFixedSize]: It works with codec sizes only.\n    const codec = {} as { fixedSize: 42 } | { maxSize?: number };\n    assertIsFixedSize(codec);\n    codec satisfies { fixedSize: 42 };\n}\n\n{\n    // [isVariableSize]: It returns true if the codec is variable size.\n    const codec = {} as FixedSizeCodec<string, string, 42> | VariableSizeCodec<string>;\n    if (isVariableSize(codec)) {\n        codec satisfies VariableSizeCodec<string>;\n    }\n}\n\n{\n    // [isVariableSize]: It works with codec sizes only.\n    const codec = {} as { fixedSize: 42 } | { foo: 'bar'; maxSize?: number };\n    if (isVariableSize(codec)) {\n        codec satisfies { foo: 'bar'; maxSize?: number };\n    }\n}\n\n{\n    // [assertIsVariableSize]: It asserts the codec is variable size.\n    const codec = {} as FixedSizeCodec<string, string, 42> | VariableSizeCodec<string>;\n    assertIsVariableSize(codec);\n    codec satisfies VariableSizeCodec<string>;\n}\n\n{\n    // [assertIsVariableSize]: It works with codec sizes only.\n    const codec = {} as { fixedSize: 42 } | { foo: 'bar'; maxSize?: number };\n    assertIsVariableSize(codec);\n    codec satisfies { foo: 'bar'; maxSize?: number };\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/combine-codec-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\nimport { combineCodec } from '../combine-codec';\n\n{\n    // [combineCodec]: It keeps track of the fixed or variable size types.\n    combineCodec({} as FixedSizeEncoder<string, 42>, {} as FixedSizeDecoder<string, 42>) satisfies FixedSizeCodec<\n        string,\n        string,\n        42\n    >;\n    combineCodec(\n        {} as VariableSizeEncoder<string>,\n        {} as VariableSizeDecoder<string>,\n    ) satisfies VariableSizeCodec<string>;\n    combineCodec({} as Encoder<string>, {} as Decoder<string>) satisfies Codec<string>;\n}\n\n{\n    // [combineCodec]: It authorizes From and To types that such that To extends From.\n    combineCodec({} as Encoder<bigint | number>, {} as Decoder<bigint>) satisfies Codec<bigint | number, bigint>;\n    combineCodec({} as Encoder<{ name: string }>, {} as Decoder<{ age: number; name: string }>) satisfies Codec<\n        { name: string },\n        { age: number; name: string }\n    >;\n}\n\n{\n    // [combineCodec]: It forbids From and To types that are not compatible.\n    // @ts-expect-error Expected a number decoder or a string encoder.\n    combineCodec({} as Encoder<number>, {} as Decoder<string>) satisfies Codec<string>;\n    // @ts-expect-error number | bigint is not assignable to bigint.\n    combineCodec({} as Encoder<bigint>, {} as Decoder<bigint | number>) satisfies Codec<bigint, bigint | number>;\n    // @ts-expect-error The decoded value does not extend the encoded value.\n    combineCodec({} as Encoder<{ age: number; name: string }>, {} as Decoder<{ name: string }>) satisfies Codec<\n        { age: number; name: string },\n        // @ts-expect-error Age property is missing.\n        { name: string }\n    >;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/fix-codec-size-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\nimport { fixCodecSize, fixDecoderSize, fixEncoderSize } from '../fix-codec-size';\n\n{\n    // [fixEncoderSize]: It transforms any encoder into a fixed size encoder.\n    fixEncoderSize({} as FixedSizeEncoder<string>, 42) satisfies FixedSizeEncoder<string, 42>;\n    fixEncoderSize({} as VariableSizeEncoder<string>, 42) satisfies FixedSizeEncoder<string, 42>;\n    fixEncoderSize({} as Encoder<string>, 42) satisfies FixedSizeEncoder<string, 42>;\n}\n\n{\n    // [fixDecoderSize]: It transforms any decoder into a fixed size decoder.\n    fixDecoderSize({} as FixedSizeDecoder<string>, 42) satisfies FixedSizeDecoder<string, 42>;\n    fixDecoderSize({} as VariableSizeDecoder<string>, 42) satisfies FixedSizeDecoder<string, 42>;\n    fixDecoderSize({} as Decoder<string>, 42) satisfies FixedSizeDecoder<string, 42>;\n}\n\n{\n    // [fixCodecSize]: It transforms any codec into a fixed size codec.\n    fixCodecSize({} as FixedSizeCodec<string>, 42) satisfies FixedSizeCodec<string, string, 42>;\n    fixCodecSize({} as VariableSizeCodec<string>, 42) satisfies FixedSizeCodec<string, string, 42>;\n    fixCodecSize({} as Codec<string>, 42) satisfies FixedSizeCodec<string, string, 42>;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/offset-codec-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\nimport { offsetCodec, offsetDecoder, offsetEncoder } from '../offset-codec';\n\ntype BrandedEncoder = Encoder<42> & { readonly __brand: unique symbol };\ntype BrandedDecoder = Decoder<42> & { readonly __brand: unique symbol };\ntype BrandedCodec = Codec<42> & { readonly __brand: unique symbol };\nconst config = {};\n\n{\n    // [offsetEncoder]: It returns the same encoder type as the one provided.\n    offsetEncoder({} as BrandedEncoder, config) satisfies BrandedEncoder;\n    offsetEncoder({} as FixedSizeEncoder<string, 42>, config) satisfies FixedSizeEncoder<string, 42>;\n    offsetEncoder({} as VariableSizeEncoder<string>, config) satisfies VariableSizeEncoder<string>;\n    offsetEncoder({} as Encoder<string>, config) satisfies Encoder<string>;\n}\n\n{\n    // [offsetDecoder]: It returns the same decoder type as the one provided.\n    offsetDecoder({} as BrandedDecoder, config) satisfies BrandedDecoder;\n    offsetDecoder({} as FixedSizeDecoder<string, 42>, config) satisfies FixedSizeDecoder<string, 42>;\n    offsetDecoder({} as VariableSizeDecoder<string>, config) satisfies VariableSizeDecoder<string>;\n    offsetDecoder({} as Decoder<string>, config) satisfies Decoder<string>;\n}\n\n{\n    // [offsetCodec]: It returns the same codec type as the one provided.\n    offsetCodec({} as BrandedCodec, config) satisfies BrandedCodec;\n    offsetCodec({} as FixedSizeCodec<string, string, 42>, config) satisfies FixedSizeCodec<string, string, 42>;\n    offsetCodec({} as VariableSizeCodec<string>, config) satisfies VariableSizeCodec<string>;\n    offsetCodec({} as Codec<string>, config) satisfies Codec<string>;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/pad-codec-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\nimport {\n    padLeftCodec,\n    padLeftDecoder,\n    padLeftEncoder,\n    padRightCodec,\n    padRightDecoder,\n    padRightEncoder,\n} from '../pad-codec';\n\ntype BrandedEncoder = Encoder<42> & { readonly __brand: unique symbol };\ntype BrandedDecoder = Decoder<42> & { readonly __brand: unique symbol };\ntype BrandedCodec = Codec<42> & { readonly __brand: unique symbol };\n\n{\n    // [padLeftEncoder]: It returns the same encoder type as the one provided.\n    padLeftEncoder({} as BrandedEncoder, 8) satisfies BrandedEncoder;\n    padLeftEncoder({} as FixedSizeEncoder<string, 42>, 8) satisfies FixedSizeEncoder<string, 42>;\n    padLeftEncoder({} as VariableSizeEncoder<string>, 8) satisfies VariableSizeEncoder<string>;\n    padLeftEncoder({} as Encoder<string>, 8) satisfies Encoder<string>;\n}\n\n{\n    // [padLeftDecoder]: It returns the same decoder type as the one provided.\n    padLeftDecoder({} as BrandedDecoder, 8) satisfies BrandedDecoder;\n    padLeftDecoder({} as FixedSizeDecoder<string, 42>, 8) satisfies FixedSizeDecoder<string, 42>;\n    padLeftDecoder({} as VariableSizeDecoder<string>, 8) satisfies VariableSizeDecoder<string>;\n    padLeftDecoder({} as Decoder<string>, 8) satisfies Decoder<string>;\n}\n\n{\n    // [padLeftCodec]: It returns the same codec type as the one provided.\n    padLeftCodec({} as BrandedCodec, 8) satisfies BrandedCodec;\n    padLeftCodec({} as FixedSizeCodec<string, string, 42>, 8) satisfies FixedSizeCodec<string, string, 42>;\n    padLeftCodec({} as VariableSizeCodec<string>, 8) satisfies VariableSizeCodec<string>;\n    padLeftCodec({} as Codec<string>, 8) satisfies Codec<string>;\n}\n\n{\n    // [padRightEncoder]: It returns the same encoder type as the one provided.\n    padRightEncoder({} as BrandedEncoder, 8) satisfies BrandedEncoder;\n    padRightEncoder({} as FixedSizeEncoder<string, 42>, 8) satisfies FixedSizeEncoder<string, 42>;\n    padRightEncoder({} as VariableSizeEncoder<string>, 8) satisfies VariableSizeEncoder<string>;\n    padRightEncoder({} as Encoder<string>, 8) satisfies Encoder<string>;\n}\n\n{\n    // [padRightDecoder]: It returns the same decoder type as the one provided.\n    padRightDecoder({} as BrandedDecoder, 8) satisfies BrandedDecoder;\n    padRightDecoder({} as FixedSizeDecoder<string, 42>, 8) satisfies FixedSizeDecoder<string, 42>;\n    padRightDecoder({} as VariableSizeDecoder<string>, 8) satisfies VariableSizeDecoder<string>;\n    padRightDecoder({} as Decoder<string>, 8) satisfies Decoder<string>;\n}\n\n{\n    // [padRightCodec]: It returns the same codec type as the one provided.\n    padRightCodec({} as BrandedCodec, 8) satisfies BrandedCodec;\n    padRightCodec({} as FixedSizeCodec<string, string, 42>, 8) satisfies FixedSizeCodec<string, string, 42>;\n    padRightCodec({} as VariableSizeCodec<string>, 8) satisfies VariableSizeCodec<string>;\n    padRightCodec({} as Codec<string>, 8) satisfies Codec<string>;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/resize-codec-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\nimport { resizeCodec, resizeDecoder, resizeEncoder } from '../resize-codec';\n\ntype NumberToArray<N extends number, T extends unknown[] = []> = T['length'] extends N\n    ? T\n    : NumberToArray<N, [...T, unknown]>;\ntype Increment<N extends number> = [...NumberToArray<N>, unknown]['length'];\n\n{\n    // [resizeEncoder]: It returns the same encoder type as the one provided for non-fixed size encoders.\n    type BrandedEncoder = Encoder<42> & { readonly __brand: unique symbol };\n    const resize = (size: number) => size * 2;\n    resizeEncoder({} as BrandedEncoder, resize) satisfies BrandedEncoder;\n    resizeEncoder({} as VariableSizeEncoder<string>, resize) satisfies VariableSizeEncoder<string>;\n    resizeEncoder({} as Encoder<string>, resize) satisfies Encoder<string>;\n}\n\n{\n    // [resizeEncoder]: It uses the resize ReturnType as size for fixed-size encoders.\n    const doubleResize = (size: number): number => size * 2;\n    const encoder = {} as FixedSizeEncoder<string, 42>;\n    resizeEncoder(encoder, doubleResize) satisfies FixedSizeEncoder<string, number>;\n    // @ts-expect-error We no longer know if the fixed size is 42.\n    resizeEncoder(encoder, doubleResize) satisfies FixedSizeEncoder<string, 42>;\n    const incrementResize = <TSize extends number>(size: TSize) => (size + 1) as Increment<TSize>;\n    resizeEncoder(encoder, incrementResize) satisfies FixedSizeEncoder<string, 43>;\n}\n\n{\n    // [resizeDecoder]: It returns the same decoder type as the one provided for non-fixed size decoders.\n    type BrandedDecoder = Decoder<42> & { readonly __brand: unique symbol };\n    const resize = (size: number) => size * 2;\n    resizeDecoder({} as BrandedDecoder, resize) satisfies BrandedDecoder;\n    resizeDecoder({} as VariableSizeDecoder<string>, resize) satisfies VariableSizeDecoder<string>;\n    resizeDecoder({} as Decoder<string>, resize) satisfies Decoder<string>;\n}\n\n{\n    // [resizeDecoder]: It uses the resize ReturnType as size for fixed-size decoders.\n    const doubleResize = (size: number): number => size * 2;\n    const decoder = {} as FixedSizeDecoder<string, 42>;\n    resizeDecoder(decoder, doubleResize) satisfies FixedSizeDecoder<string, number>;\n    // @ts-expect-error We no longer know if the fixed size is 42.\n    resizeDecoder(decoder, doubleResize) satisfies FixedSizeDecoder<string, 42>;\n    const incrementResize = <TSize extends number>(size: TSize) => (size + 1) as Increment<TSize>;\n    resizeDecoder(decoder, incrementResize) satisfies FixedSizeDecoder<string, 43>;\n}\n\n{\n    // [resizeCodec]: It returns the same codec type as the one provided for non-fixed size codecs.\n    type BrandedCodec = Codec<42> & { readonly __brand: unique symbol };\n    const resize = (size: number) => size * 2;\n    resizeCodec({} as BrandedCodec, resize) satisfies BrandedCodec;\n    resizeCodec({} as VariableSizeCodec<string>, resize) satisfies VariableSizeCodec<string>;\n    resizeCodec({} as Codec<string>, resize) satisfies Codec<string>;\n}\n\n{\n    // [resizeCodec]: It uses the resize ReturnType as size for fixed-size codecs.\n    const doubleResize = (size: number): number => size * 2;\n    const codec = {} as FixedSizeCodec<string, string, 42>;\n    resizeCodec(codec, doubleResize) satisfies FixedSizeCodec<string, string, number>;\n    // @ts-expect-error We no longer know if the fixed size is 42.\n    resizeCodec(codec, doubleResize) satisfies FixedSizeCodec<string, 42>;\n    const incrementResize = <TSize extends number>(size: TSize) => (size + 1) as Increment<TSize>;\n    resizeCodec(codec, incrementResize) satisfies FixedSizeCodec<string, string, 43>;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/reverse-codec-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\nimport { reverseCodec, reverseDecoder, reverseEncoder } from '../reverse-codec';\n\n{\n    // [reverseEncoder]: It only works with fixed size encoders.\n    reverseEncoder({} as FixedSizeEncoder<string, 42>) satisfies FixedSizeEncoder<string, 42>;\n    // @ts-expect-error Expected a fixed size encoder.\n    reverseEncoder({} as VariableSizeEncoder<string>);\n    // @ts-expect-error Expected a fixed size encoder.\n    reverseEncoder({} as Encoder<string>);\n}\n\n{\n    // [reverseDecoder]: It only works with fixed size decoders.\n    reverseDecoder({} as FixedSizeDecoder<string, 42>) satisfies FixedSizeDecoder<string, 42>;\n    // @ts-expect-error Expected a fixed size decoder.\n    reverseDecoder({} as VariableSizeDecoder<string>);\n    // @ts-expect-error Expected a fixed size decoder.\n    reverseDecoder({} as Decoder<string>);\n}\n\n{\n    // [reverseCodec]: It only works with fixed size codecs.\n    reverseCodec({} as FixedSizeCodec<string, string, 42>) satisfies FixedSizeCodec<string, string, 42>;\n    // @ts-expect-error Expected a fixed size codec.\n    reverseCodec({} as VariableSizeCodec<string>);\n    // @ts-expect-error Expected a fixed size codec.\n    reverseCodec({} as Codec<string>);\n}\n"
  },
  {
    "path": "packages/codecs-core/src/__typetests__/transform-codec-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '../codec';\nimport { transformCodec, transformDecoder, transformEncoder } from '../transform-codec';\n\n{\n    // [transformEncoder]: It keeps track of the nested encoder's size.\n    transformEncoder({} as FixedSizeEncoder<string, 42>, (_: number) => '42') satisfies FixedSizeEncoder<number, 42>;\n    transformEncoder({} as VariableSizeEncoder<string>, (_: number) => '42') satisfies VariableSizeEncoder<number>;\n    transformEncoder({} as Encoder<string>, (_: number) => '42') satisfies Encoder<number>;\n}\n\n{\n    // [transformDecoder]: It keeps track of the nested decoder's size.\n    transformDecoder({} as FixedSizeDecoder<string, 42>, (_: string) => 42) satisfies FixedSizeDecoder<number, 42>;\n    transformDecoder({} as VariableSizeDecoder<string>, (_: string) => 42) satisfies VariableSizeDecoder<number>;\n    transformDecoder({} as Decoder<string>, (_: string) => 42) satisfies Decoder<number>;\n}\n\n{\n    // [transformCodec]: It keeps track of the nested codec's size.\n    transformCodec(\n        {} as FixedSizeCodec<string, string, 42>,\n        (_: number) => '42',\n        (_: string) => 42,\n    ) satisfies FixedSizeCodec<number, number, 42>;\n    transformCodec(\n        {} as VariableSizeCodec<string>,\n        (_: number) => '42',\n        (_: string) => 42,\n    ) satisfies VariableSizeCodec<number>;\n    transformCodec(\n        {} as Codec<string>,\n        (_: number) => '42',\n        (_: string) => 42,\n    ) satisfies Codec<number>;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/add-codec-sentinel.ts",
    "content": "import {\n    SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL,\n    SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES,\n    SolanaError,\n} from '@solana/errors';\n\nimport { containsBytes } from './bytes';\nimport {\n    Codec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    isFixedSize,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from './codec';\nimport { combineCodec } from './combine-codec';\nimport { ReadonlyUint8Array } from './readonly-uint8array';\n\n/**\n * Creates an encoder that writes a `Uint8Array` sentinel after the encoded value.\n * This is useful to delimit the encoded value when being read by a decoder.\n *\n * See {@link addCodecSentinel} for more information.\n *\n * @typeParam TFrom - The type of the value to encode.\n *\n * @see {@link addCodecSentinel}\n */\nexport function addEncoderSentinel<TFrom>(\n    encoder: FixedSizeEncoder<TFrom>,\n    sentinel: ReadonlyUint8Array,\n): FixedSizeEncoder<TFrom>;\nexport function addEncoderSentinel<TFrom>(\n    encoder: Encoder<TFrom>,\n    sentinel: ReadonlyUint8Array,\n): VariableSizeEncoder<TFrom>;\nexport function addEncoderSentinel<TFrom>(encoder: Encoder<TFrom>, sentinel: ReadonlyUint8Array): Encoder<TFrom> {\n    const write = ((value, bytes, offset) => {\n        // Here we exceptionally use the `encode` function instead of the `write`\n        // function to contain the content of the encoder within its own bounds\n        // and to avoid writing the sentinel as part of the encoded value.\n        const encoderBytes = encoder.encode(value);\n        if (findSentinelIndex(encoderBytes, sentinel) >= 0) {\n            throw new SolanaError(SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL, {\n                encodedBytes: encoderBytes,\n                hexEncodedBytes: hexBytes(encoderBytes),\n                hexSentinel: hexBytes(sentinel),\n                sentinel,\n            });\n        }\n        bytes.set(encoderBytes, offset);\n        offset += encoderBytes.length;\n        bytes.set(sentinel, offset);\n        offset += sentinel.length;\n        return offset;\n    }) as Encoder<TFrom>['write'];\n\n    if (isFixedSize(encoder)) {\n        return createEncoder({ ...encoder, fixedSize: encoder.fixedSize + sentinel.length, write });\n    }\n\n    return createEncoder({\n        ...encoder,\n        ...(encoder.maxSize != null ? { maxSize: encoder.maxSize + sentinel.length } : {}),\n        getSizeFromValue: value => encoder.getSizeFromValue(value) + sentinel.length,\n        write,\n    });\n}\n\n/**\n * Creates a decoder that continues reading until\n * a given `Uint8Array` sentinel is found.\n *\n * See {@link addCodecSentinel} for more information.\n *\n * @typeParam TTo - The type of the decoded value.\n *\n * @see {@link addCodecSentinel}\n */\nexport function addDecoderSentinel<TTo>(\n    decoder: FixedSizeDecoder<TTo>,\n    sentinel: ReadonlyUint8Array,\n): FixedSizeDecoder<TTo>;\nexport function addDecoderSentinel<TTo>(decoder: Decoder<TTo>, sentinel: ReadonlyUint8Array): VariableSizeDecoder<TTo>;\nexport function addDecoderSentinel<TTo>(decoder: Decoder<TTo>, sentinel: ReadonlyUint8Array): Decoder<TTo> {\n    const read = ((bytes, offset) => {\n        const candidateBytes = offset === 0 || offset <= -bytes.byteLength ? bytes : bytes.slice(offset);\n        const sentinelIndex = findSentinelIndex(candidateBytes, sentinel);\n        if (sentinelIndex === -1) {\n            throw new SolanaError(SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES, {\n                decodedBytes: candidateBytes,\n                hexDecodedBytes: hexBytes(candidateBytes),\n                hexSentinel: hexBytes(sentinel),\n                sentinel,\n            });\n        }\n        const preSentinelBytes = candidateBytes.slice(0, sentinelIndex);\n        // Here we exceptionally use the `decode` function instead of the `read`\n        // function to contain the content of the decoder within its own bounds\n        // and ensure that the sentinel is not part of the decoded value.\n        return [decoder.decode(preSentinelBytes), offset + preSentinelBytes.length + sentinel.length];\n    }) as Decoder<TTo>['read'];\n\n    if (isFixedSize(decoder)) {\n        return createDecoder({ ...decoder, fixedSize: decoder.fixedSize + sentinel.length, read });\n    }\n\n    return createDecoder({\n        ...decoder,\n        ...(decoder.maxSize != null ? { maxSize: decoder.maxSize + sentinel.length } : {}),\n        read,\n    });\n}\n\n/**\n * Creates a Codec that writes a given `Uint8Array` sentinel after the encoded\n * value and, when decoding, continues reading until the sentinel is found.\n *\n * This sets a limit on variable-size codecs and tells us when to stop decoding.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n *\n * @example\n * ```ts\n * const codec = addCodecSentinel(getUtf8Codec(), new Uint8Array([255, 255]));\n * codec.encode('hello');\n * // 0x68656c6c6fffff\n * //   |        └-- Our sentinel.\n * //   └-- Our encoded string.\n * ```\n *\n * @remarks\n * Note that the sentinel _must not_ be present in the encoded data and\n * _must_ be present in the decoded data for this to work.\n * If this is not the case, dedicated errors will be thrown.\n *\n * ```ts\n * const sentinel = new Uint8Array([108, 108]); // 'll'\n * const codec = addCodecSentinel(getUtf8Codec(), sentinel);\n *\n * codec.encode('hello'); // Throws: sentinel is in encoded data.\n * codec.decode(new Uint8Array([1, 2, 3])); // Throws: sentinel missing in decoded data.\n * ```\n *\n * Separate {@link addEncoderSentinel} and {@link addDecoderSentinel} functions are also available.\n *\n * ```ts\n * const bytes = addEncoderSentinel(getUtf8Encoder(), sentinel).encode('hello');\n * const value = addDecoderSentinel(getUtf8Decoder(), sentinel).decode(bytes);\n * ```\n *\n * @see {@link addEncoderSentinel}\n * @see {@link addDecoderSentinel}\n */\nexport function addCodecSentinel<TFrom, TTo extends TFrom>(\n    codec: FixedSizeCodec<TFrom, TTo>,\n    sentinel: ReadonlyUint8Array,\n): FixedSizeCodec<TFrom, TTo>;\nexport function addCodecSentinel<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n    sentinel: ReadonlyUint8Array,\n): VariableSizeCodec<TFrom, TTo>;\nexport function addCodecSentinel<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n    sentinel: ReadonlyUint8Array,\n): Codec<TFrom, TTo> {\n    return combineCodec(addEncoderSentinel(codec, sentinel), addDecoderSentinel(codec, sentinel));\n}\n\nfunction findSentinelIndex(bytes: ReadonlyUint8Array, sentinel: ReadonlyUint8Array) {\n    return bytes.findIndex((byte, index, arr) => {\n        if (sentinel.length === 1) return byte === sentinel[0];\n        return containsBytes(arr, sentinel, index);\n    });\n}\n\nfunction hexBytes(bytes: ReadonlyUint8Array): string {\n    return bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n}\n"
  },
  {
    "path": "packages/codecs-core/src/add-codec-size-prefix.ts",
    "content": "import { assertByteArrayHasEnoughBytesForCodec } from './assertions';\nimport {\n    Codec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    getEncodedSize,\n    isFixedSize,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\ntype NumberEncoder = Encoder<bigint | number> | Encoder<number>;\ntype FixedSizeNumberEncoder<TSize extends number = number> =\n    | FixedSizeEncoder<bigint | number, TSize>\n    | FixedSizeEncoder<number, TSize>;\ntype NumberDecoder = Decoder<bigint> | Decoder<number>;\ntype FixedSizeNumberDecoder<TSize extends number = number> =\n    | FixedSizeDecoder<bigint, TSize>\n    | FixedSizeDecoder<number, TSize>;\ntype NumberCodec = Codec<bigint | number, bigint> | Codec<number>;\ntype FixedSizeNumberCodec<TSize extends number = number> =\n    | FixedSizeCodec<bigint | number, bigint, TSize>\n    | FixedSizeCodec<number, number, TSize>;\n\n/**\n * Stores the size of the `encoder` in bytes as a prefix using the `prefix` encoder.\n *\n * See {@link addCodecSizePrefix} for more information.\n *\n * @typeParam TFrom - The type of the value to encode.\n *\n * @see {@link addCodecSizePrefix}\n */\nexport function addEncoderSizePrefix<TFrom>(\n    encoder: FixedSizeEncoder<TFrom>,\n    prefix: FixedSizeNumberEncoder,\n): FixedSizeEncoder<TFrom>;\nexport function addEncoderSizePrefix<TFrom>(encoder: Encoder<TFrom>, prefix: NumberEncoder): VariableSizeEncoder<TFrom>;\nexport function addEncoderSizePrefix<TFrom>(encoder: Encoder<TFrom>, prefix: NumberEncoder): Encoder<TFrom> {\n    const write = ((value, bytes, offset) => {\n        // Here we exceptionally use the `encode` function instead of the `write`\n        // function to contain the content of the encoder within its own bounds.\n        const encoderBytes = encoder.encode(value);\n        offset = prefix.write(encoderBytes.length, bytes, offset);\n        bytes.set(encoderBytes, offset);\n        return offset + encoderBytes.length;\n    }) as Encoder<TFrom>['write'];\n\n    if (isFixedSize(prefix) && isFixedSize(encoder)) {\n        return createEncoder({ ...encoder, fixedSize: prefix.fixedSize + encoder.fixedSize, write });\n    }\n\n    const prefixMaxSize = isFixedSize(prefix) ? prefix.fixedSize : (prefix.maxSize ?? null);\n    const encoderMaxSize = isFixedSize(encoder) ? encoder.fixedSize : (encoder.maxSize ?? null);\n    const maxSize = prefixMaxSize !== null && encoderMaxSize !== null ? prefixMaxSize + encoderMaxSize : null;\n\n    return createEncoder({\n        ...encoder,\n        ...(maxSize !== null ? { maxSize } : {}),\n        getSizeFromValue: value => {\n            const encoderSize = getEncodedSize(value, encoder);\n            return getEncodedSize(encoderSize, prefix) + encoderSize;\n        },\n        write,\n    });\n}\n\n/**\n * Bounds the size of the nested `decoder` by reading its encoded `prefix`.\n *\n * See {@link addCodecSizePrefix} for more information.\n *\n * @typeParam TTo - The type of the decoded value.\n *\n * @see {@link addCodecSizePrefix}\n */\nexport function addDecoderSizePrefix<TTo>(\n    decoder: FixedSizeDecoder<TTo>,\n    prefix: FixedSizeNumberDecoder,\n): FixedSizeDecoder<TTo>;\nexport function addDecoderSizePrefix<TTo>(decoder: Decoder<TTo>, prefix: NumberDecoder): VariableSizeDecoder<TTo>;\nexport function addDecoderSizePrefix<TTo>(decoder: Decoder<TTo>, prefix: NumberDecoder): Decoder<TTo> {\n    const read = ((bytes, offset) => {\n        const [bigintSize, decoderOffset] = prefix.read(bytes, offset);\n        const size = Number(bigintSize);\n        offset = decoderOffset;\n        // Slice the byte array to the contained size if necessary.\n        if (offset > 0 || bytes.length > size) {\n            bytes = bytes.slice(offset, offset + size);\n        }\n        assertByteArrayHasEnoughBytesForCodec('addDecoderSizePrefix', size, bytes);\n        // Here we exceptionally use the `decode` function instead of the `read`\n        // function to contain the content of the decoder within its own bounds.\n        return [decoder.decode(bytes), offset + size];\n    }) as Decoder<TTo>['read'];\n\n    if (isFixedSize(prefix) && isFixedSize(decoder)) {\n        return createDecoder({ ...decoder, fixedSize: prefix.fixedSize + decoder.fixedSize, read });\n    }\n\n    const prefixMaxSize = isFixedSize(prefix) ? prefix.fixedSize : (prefix.maxSize ?? null);\n    const decoderMaxSize = isFixedSize(decoder) ? decoder.fixedSize : (decoder.maxSize ?? null);\n    const maxSize = prefixMaxSize !== null && decoderMaxSize !== null ? prefixMaxSize + decoderMaxSize : null;\n    return createDecoder({ ...decoder, ...(maxSize !== null ? { maxSize } : {}), read });\n}\n\n/**\n * Stores the byte size of any given codec as an encoded number prefix.\n *\n * This sets a limit on variable-size codecs and tells us when to stop decoding.\n * When encoding, the size of the encoded data is stored before the encoded data itself.\n * When decoding, the size is read first to know how many bytes to read next.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n *\n * @example\n * For example, say we want to bound a variable-size base-58 string using a `u32` size prefix.\n * Here’s how you can use the `addCodecSizePrefix` function to achieve that.\n *\n * ```ts\n * const getU32Base58Codec = () => addCodecSizePrefix(getBase58Codec(), getU32Codec());\n *\n * getU32Base58Codec().encode('hello world');\n * // 0x0b00000068656c6c6f20776f726c64\n * //   |       └-- Our encoded base-58 string.\n * //   └-- Our encoded u32 size prefix.\n * ```\n *\n * @remarks\n * Separate {@link addEncoderSizePrefix} and {@link addDecoderSizePrefix} functions are also available.\n *\n * ```ts\n * const bytes = addEncoderSizePrefix(getBase58Encoder(), getU32Encoder()).encode('hello');\n * const value = addDecoderSizePrefix(getBase58Decoder(), getU32Decoder()).decode(bytes);\n * ```\n *\n * @see {@link addEncoderSizePrefix}\n * @see {@link addDecoderSizePrefix}\n */\nexport function addCodecSizePrefix<TFrom, TTo extends TFrom>(\n    codec: FixedSizeCodec<TFrom, TTo>,\n    prefix: FixedSizeNumberCodec,\n): FixedSizeCodec<TFrom, TTo>;\nexport function addCodecSizePrefix<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n    prefix: NumberCodec,\n): VariableSizeCodec<TFrom, TTo>;\nexport function addCodecSizePrefix<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n    prefix: NumberCodec,\n): Codec<TFrom, TTo> {\n    return combineCodec(addEncoderSizePrefix(codec, prefix), addDecoderSizePrefix(codec, prefix));\n}\n"
  },
  {
    "path": "packages/codecs-core/src/array-buffers.ts",
    "content": "import { ReadonlyUint8Array } from './readonly-uint8array';\n\n/**\n * Converts a `Uint8Array` to an `ArrayBuffer`. If the underlying buffer is a `SharedArrayBuffer`,\n * it will be copied to a non-shared buffer, for safety.\n *\n * @remarks\n * Source: https://stackoverflow.com/questions/37228285/uint8array-to-arraybuffer\n */\nexport function toArrayBuffer(bytes: ReadonlyUint8Array | Uint8Array, offset?: number, length?: number): ArrayBuffer {\n    const bytesOffset = bytes.byteOffset + (offset ?? 0);\n    const bytesLength = length ?? bytes.byteLength;\n    let buffer: ArrayBuffer;\n    if (typeof SharedArrayBuffer === 'undefined') {\n        buffer = bytes.buffer as ArrayBuffer;\n    } else if (bytes.buffer instanceof SharedArrayBuffer) {\n        buffer = new ArrayBuffer(bytes.length);\n        new Uint8Array(buffer).set(new Uint8Array(bytes));\n    } else {\n        buffer = bytes.buffer;\n    }\n    return (bytesOffset === 0 || bytesOffset === -bytes.byteLength) && bytesLength === bytes.byteLength\n        ? buffer\n        : buffer.slice(bytesOffset, bytesOffset + bytesLength);\n}\n"
  },
  {
    "path": "packages/codecs-core/src/assertions.ts",
    "content": "import {\n    SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY,\n    SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { ReadonlyUint8Array } from './readonly-uint8array';\n\n/**\n * Asserts that a given byte array is not empty (after the optional provided offset).\n *\n * Returns void if the byte array is not empty but throws a {@link SolanaError} otherwise.\n *\n * @param codecDescription - A description of the codec used by the assertion error.\n * @param bytes - The byte array to check.\n * @param offset - The offset from which to start checking the byte array.\n * If provided, the byte array is considered empty if it has no bytes after the offset.\n *\n * @example\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02, 0x03]);\n * assertByteArrayIsNotEmptyForCodec('myCodec', bytes); // OK\n * assertByteArrayIsNotEmptyForCodec('myCodec', bytes, 1); // OK\n * assertByteArrayIsNotEmptyForCodec('myCodec', bytes, 3); // Throws\n * ```\n */\nexport function assertByteArrayIsNotEmptyForCodec(\n    codecDescription: string,\n    bytes: ReadonlyUint8Array | Uint8Array,\n    offset = 0,\n) {\n    if (bytes.length - offset <= 0) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY, {\n            codecDescription,\n        });\n    }\n}\n\n/**\n * Asserts that a given byte array has enough bytes to decode\n * (after the optional provided offset).\n *\n * Returns void if the byte array has at least the expected number\n * of bytes but throws a {@link SolanaError} otherwise.\n *\n * @param codecDescription - A description of the codec used by the assertion error.\n * @param expected - The minimum number of bytes expected in the byte array.\n * @param bytes - The byte array to check.\n * @param offset - The offset from which to start checking the byte array.\n *\n * @example\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02, 0x03]);\n * assertByteArrayHasEnoughBytesForCodec('myCodec', 3, bytes); // OK\n * assertByteArrayHasEnoughBytesForCodec('myCodec', 4, bytes); // Throws\n * assertByteArrayHasEnoughBytesForCodec('myCodec', 2, bytes, 1); // OK\n * assertByteArrayHasEnoughBytesForCodec('myCodec', 3, bytes, 1); // Throws\n * ```\n */\nexport function assertByteArrayHasEnoughBytesForCodec(\n    codecDescription: string,\n    expected: number,\n    bytes: ReadonlyUint8Array | Uint8Array,\n    offset = 0,\n) {\n    const bytesLength = bytes.length - offset;\n    if (bytesLength < expected) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n            bytesLength,\n            codecDescription,\n            expected,\n        });\n    }\n}\n\n/**\n * Asserts that a given offset is within the byte array bounds.\n * This range is between 0 and the byte array length and is inclusive.\n * An offset equals to the byte array length is considered a valid offset\n * as it allows the post-offset of codecs to signal the end of the byte array.\n *\n * @param codecDescription - A description of the codec used by the assertion error.\n * @param offset - The offset to check.\n * @param bytesLength - The length of the byte array from which the offset should be within bounds.\n *\n * @example\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02, 0x03]);\n * assertByteArrayOffsetIsNotOutOfRange('myCodec', 0, bytes.length); // OK\n * assertByteArrayOffsetIsNotOutOfRange('myCodec', 3, bytes.length); // OK\n * assertByteArrayOffsetIsNotOutOfRange('myCodec', 4, bytes.length); // Throws\n * ```\n */\nexport function assertByteArrayOffsetIsNotOutOfRange(codecDescription: string, offset: number, bytesLength: number) {\n    if (offset < 0 || offset > bytesLength) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE, {\n            bytesLength,\n            codecDescription,\n            offset,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/codecs-core/src/bytes.ts",
    "content": "import { ReadonlyUint8Array } from './readonly-uint8array';\n\n/**\n * Concatenates an array of `Uint8Array`s into a single `Uint8Array`.\n * Reuses the original byte array when applicable.\n *\n * @param byteArrays - The array of byte arrays to concatenate.\n *\n * @example\n * ```ts\n * const bytes1 = new Uint8Array([0x01, 0x02]);\n * const bytes2 = new Uint8Array([]);\n * const bytes3 = new Uint8Array([0x03, 0x04]);\n * const bytes = mergeBytes([bytes1, bytes2, bytes3]);\n * //    ^ [0x01, 0x02, 0x03, 0x04]\n * ```\n */\nexport const mergeBytes = (byteArrays: Uint8Array[]): Uint8Array => {\n    const nonEmptyByteArrays = byteArrays.filter(arr => arr.length);\n    if (nonEmptyByteArrays.length === 0) {\n        return byteArrays.length ? byteArrays[0] : new Uint8Array();\n    }\n\n    if (nonEmptyByteArrays.length === 1) {\n        return nonEmptyByteArrays[0];\n    }\n\n    const totalLength = nonEmptyByteArrays.reduce((total, arr) => total + arr.length, 0);\n    const result = new Uint8Array(totalLength);\n    let offset = 0;\n    nonEmptyByteArrays.forEach(arr => {\n        result.set(arr, offset);\n        offset += arr.length;\n    });\n    return result;\n};\n\n/**\n * Pads a `Uint8Array` with zeroes to the specified length.\n * If the array is longer than the specified length, it is returned as-is.\n *\n * @param bytes - The byte array to pad.\n * @param length - The desired length of the byte array.\n *\n * @example\n * Adds zeroes to the end of the byte array to reach the desired length.\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02]);\n * const paddedBytes = padBytes(bytes, 4);\n * //    ^ [0x01, 0x02, 0x00, 0x00]\n * ```\n *\n * @example\n * Returns the original byte array if it is already at the desired length.\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02]);\n * const paddedBytes = padBytes(bytes, 2);\n * // bytes === paddedBytes\n * ```\n */\nexport function padBytes(bytes: Uint8Array, length: number): Uint8Array;\nexport function padBytes(bytes: ReadonlyUint8Array, length: number): ReadonlyUint8Array;\nexport function padBytes(bytes: ReadonlyUint8Array, length: number): ReadonlyUint8Array {\n    if (bytes.length >= length) return bytes;\n    const paddedBytes = new Uint8Array(length).fill(0);\n    paddedBytes.set(bytes);\n    return paddedBytes;\n}\n\n/**\n * Fixes a `Uint8Array` to the specified length.\n * If the array is longer than the specified length, it is truncated.\n * If the array is shorter than the specified length, it is padded with zeroes.\n *\n * @param bytes - The byte array to truncate or pad.\n * @param length - The desired length of the byte array.\n *\n * @example\n * Truncates the byte array to the desired length.\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02, 0x03, 0x04]);\n * const fixedBytes = fixBytes(bytes, 2);\n * //    ^ [0x01, 0x02]\n * ```\n *\n * @example\n * Adds zeroes to the end of the byte array to reach the desired length.\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02]);\n * const fixedBytes = fixBytes(bytes, 4);\n * //    ^ [0x01, 0x02, 0x00, 0x00]\n * ```\n *\n * @example\n * Returns the original byte array if it is already at the desired length.\n * ```ts\n * const bytes = new Uint8Array([0x01, 0x02]);\n * const fixedBytes = fixBytes(bytes, 2);\n * // bytes === fixedBytes\n * ```\n */\nexport const fixBytes = (bytes: ReadonlyUint8Array | Uint8Array, length: number): ReadonlyUint8Array | Uint8Array =>\n    padBytes(bytes.length <= length ? bytes : bytes.slice(0, length), length);\n\n/**\n * Returns true if and only if the provided `data` byte array contains\n * the provided `bytes` byte array at the specified `offset`.\n *\n * @param data - The byte array in which to search for `bytes`.\n * @param bytes - The byte sequence to search for.\n * @param offset - The position in `data` where the search begins.\n *\n * @example\n * ```ts\n * const data = new Uint8Array([0x01, 0x02, 0x03, 0x04]);\n * const bytes = new Uint8Array([0x02, 0x03]);\n * containsBytes(data, bytes, 1); // true\n * containsBytes(data, bytes, 2); // false\n * ```\n */\nexport function containsBytes(\n    data: ReadonlyUint8Array | Uint8Array,\n    bytes: ReadonlyUint8Array | Uint8Array,\n    offset: number,\n): boolean {\n    const slice =\n        (offset === 0 || offset <= -data.byteLength) && data.length === bytes.length\n            ? data\n            : data.slice(offset, offset + bytes.length);\n    return bytesEqual(slice, bytes);\n}\n\n/**\n * Returns true if and only if the provided `bytes1` and `bytes2` byte arrays are equal.\n *\n * @param bytes1 - The first byte array to compare.\n * @param bytes2 - The second byte array to compare.\n *\n * @example\n * ```ts\n * const bytes1 = new Uint8Array([0x01, 0x02, 0x03, 0x04]);\n * const bytes2 = new Uint8Array([0x01, 0x02, 0x03, 0x04]);\n * bytesEqual(bytes1, bytes2); // true\n * ```\n */\nexport function bytesEqual(bytes1: ReadonlyUint8Array | Uint8Array, bytes2: ReadonlyUint8Array | Uint8Array): boolean {\n    return bytes1.length === bytes2.length && bytes1.every((value, index) => value === bytes2[index]);\n}\n"
  },
  {
    "path": "packages/codecs-core/src/codec.ts",
    "content": "import {\n    SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH,\n    SOLANA_ERROR__CODECS__EXPECTED_VARIABLE_LENGTH,\n    SolanaError,\n} from '@solana/errors';\n\nimport { ReadonlyUint8Array } from './readonly-uint8array';\n\n/**\n * Defines an offset in bytes.\n */\nexport type Offset = number;\n\n/**\n * An object that can encode a value of type {@link TFrom} into a {@link ReadonlyUint8Array}.\n *\n * This is a common interface for {@link FixedSizeEncoder} and {@link VariableSizeEncoder}.\n *\n * @interface\n * @typeParam TFrom - The type of the value to encode.\n *\n * @see {@link FixedSizeEncoder}\n * @see {@link VariableSizeEncoder}\n */\ntype BaseEncoder<TFrom> = {\n    /** Encode the provided value and return the encoded bytes directly. */\n    readonly encode: (value: TFrom) => ReadonlyUint8Array<ArrayBuffer>;\n    /**\n     * Writes the encoded value into the provided byte array at the given offset.\n     * Returns the offset of the next byte after the encoded value.\n     */\n    readonly write: (value: TFrom, bytes: Uint8Array, offset: Offset) => Offset;\n};\n\n/**\n * An object that can encode a value of type {@link TFrom} into a fixed-size {@link ReadonlyUint8Array}.\n *\n * See {@link Encoder} to learn more about creating and composing encoders.\n *\n * @interface\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n *\n * @example\n * ```ts\n * const encoder: FixedSizeEncoder<number, 4>;\n * const bytes = encoder.encode(42);\n * const size = encoder.fixedSize; // 4\n * ```\n *\n * @see {@link Encoder}\n * @see {@link VariableSizeEncoder}\n */\nexport type FixedSizeEncoder<TFrom, TSize extends number = number> = BaseEncoder<TFrom> & {\n    /** The fixed size of the encoded value in bytes. */\n    readonly fixedSize: TSize;\n};\n\n/**\n * An object that can encode a value of type {@link TFrom} into a variable-size {@link ReadonlyUint8Array}.\n *\n * See {@link Encoder} to learn more about creating and composing encoders.\n *\n * @interface\n * @typeParam TFrom - The type of the value to encode.\n *\n * @example\n * ```ts\n * const encoder: VariableSizeEncoder<string>;\n * const bytes = encoder.encode('hello');\n * const size = encoder.getSizeFromValue('hello');\n * ```\n *\n * @see {@link Encoder}\n * @see {@link FixedSizeEncoder}\n */\nexport type VariableSizeEncoder<TFrom> = BaseEncoder<TFrom> & {\n    /** Returns the size of the encoded value in bytes for a given input. */\n    readonly getSizeFromValue: (value: TFrom) => number;\n    /** The maximum possible size of an encoded value in bytes, if applicable. */\n    readonly maxSize?: number;\n};\n\n/**\n * An object that can encode a value of type {@link TFrom} into a {@link ReadonlyUint8Array}.\n *\n * An `Encoder` can be either:\n * - A {@link FixedSizeEncoder}, where all encoded values have the same fixed size.\n * - A {@link VariableSizeEncoder}, where encoded values can vary in size.\n *\n * @typeParam TFrom - The type of the value to encode.\n *\n * @example\n * Encoding a value into a new byte array.\n * ```ts\n * const encoder: Encoder<string>;\n * const bytes = encoder.encode('hello');\n * ```\n *\n * @example\n * Writing the encoded value into an existing byte array.\n * ```ts\n * const encoder: Encoder<string>;\n * const bytes = new Uint8Array(100);\n * const nextOffset = encoder.write('hello', bytes, 20);\n * ```\n *\n * @remarks\n * You may create `Encoders` manually using the {@link createEncoder} function but it is more common\n * to compose multiple `Encoders` together using the various helpers of the `@solana/codecs` package.\n *\n * For instance, here's how you might create an `Encoder` for a `Person` object type that contains\n * a `name` string and an `age` number:\n *\n * ```ts\n * import { getStructEncoder, addEncoderSizePrefix, getUtf8Encoder, getU32Encoder } from '@solana/codecs';\n *\n * type Person = { name: string; age: number };\n * const getPersonEncoder = (): Encoder<Person> =>\n *     getStructEncoder([\n *         ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n *         ['age', getU32Encoder()],\n *     ]);\n * ```\n *\n * Note that composed `Encoder` types are clever enough to understand whether\n * they are fixed-size or variable-size. In the example above, `getU32Encoder()` is\n * a fixed-size encoder, while `addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())`\n * is a variable-size encoder. This makes the final `Person` encoder a variable-size encoder.\n *\n * @see {@link FixedSizeEncoder}\n * @see {@link VariableSizeEncoder}\n * @see {@link createEncoder}\n */\nexport type Encoder<TFrom> = FixedSizeEncoder<TFrom> | VariableSizeEncoder<TFrom>;\n\n/**\n * An object that can decode a byte array into a value of type {@link TTo}.\n *\n * This is a common interface for {@link FixedSizeDecoder} and {@link VariableSizeDecoder}.\n *\n * @interface\n * @typeParam TTo - The type of the decoded value.\n *\n * @see {@link FixedSizeDecoder}\n * @see {@link VariableSizeDecoder}\n */\ntype BaseDecoder<TTo> = {\n    /** Decodes the provided byte array at the given offset (or zero) and returns the value directly. */\n    readonly decode: (bytes: ReadonlyUint8Array | Uint8Array, offset?: Offset) => TTo;\n    /**\n     * Reads the encoded value from the provided byte array at the given offset.\n     * Returns the decoded value and the offset of the next byte after the encoded value.\n     */\n    readonly read: (bytes: ReadonlyUint8Array | Uint8Array, offset: Offset) => [TTo, Offset];\n};\n\n/**\n * An object that can decode a fixed-size byte array into a value of type {@link TTo}.\n *\n * See {@link Decoder} to learn more about creating and composing decoders.\n *\n * @interface\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n *\n * @example\n * ```ts\n * const decoder: FixedSizeDecoder<number, 4>;\n * const value = decoder.decode(bytes);\n * const size = decoder.fixedSize; // 4\n * ```\n *\n * @see {@link Decoder}\n * @see {@link VariableSizeDecoder}\n */\nexport type FixedSizeDecoder<TTo, TSize extends number = number> = BaseDecoder<TTo> & {\n    /** The fixed size of the encoded value in bytes. */\n    readonly fixedSize: TSize;\n};\n\n/**\n * An object that can decode a variable-size byte array into a value of type {@link TTo}.\n *\n * See {@link Decoder} to learn more about creating and composing decoders.\n *\n * @interface\n * @typeParam TTo - The type of the decoded value.\n *\n * @example\n * ```ts\n * const decoder: VariableSizeDecoder<number>;\n * const value = decoder.decode(bytes);\n * ```\n *\n * @see {@link Decoder}\n * @see {@link VariableSizeDecoder}\n */\nexport type VariableSizeDecoder<TTo> = BaseDecoder<TTo> & {\n    /** The maximum possible size of an encoded value in bytes, if applicable. */\n    readonly maxSize?: number;\n};\n\n/**\n * An object that can decode a byte array into a value of type {@link TTo}.\n *\n * An `Decoder` can be either:\n * - A {@link FixedSizeDecoder}, where all byte arrays have the same fixed size.\n * - A {@link VariableSizeDecoder}, where byte arrays can vary in size.\n *\n * @typeParam TTo - The type of the decoded value.\n *\n * @example\n * Getting the decoded value from a byte array.\n * ```ts\n * const decoder: Decoder<string>;\n * const value = decoder.decode(bytes);\n * ```\n *\n * @example\n * Reading the decoded value from a byte array at a specific offset\n * and getting the offset of the next byte to read.\n * ```ts\n * const decoder: Decoder<string>;\n * const [value, nextOffset] = decoder.read('hello', bytes, 20);\n * ```\n *\n * @remarks\n * You may create `Decoders` manually using the {@link createDecoder} function but it is more common\n * to compose multiple `Decoders` together using the various helpers of the `@solana/codecs` package.\n *\n * For instance, here's how you might create an `Decoder` for a `Person` object type that contains\n * a `name` string and an `age` number:\n *\n * ```ts\n * import { getStructDecoder, addDecoderSizePrefix, getUtf8Decoder, getU32Decoder } from '@solana/codecs';\n *\n * type Person = { name: string; age: number };\n * const getPersonDecoder = (): Decoder<Person> =>\n *     getStructDecoder([\n *         ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n *         ['age', getU32Decoder()],\n *     ]);\n * ```\n *\n * Note that composed `Decoder` types are clever enough to understand whether\n * they are fixed-size or variable-size. In the example above, `getU32Decoder()` is\n * a fixed-size decoder, while `addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())`\n * is a variable-size decoder. This makes the final `Person` decoder a variable-size decoder.\n *\n * @see {@link FixedSizeDecoder}\n * @see {@link VariableSizeDecoder}\n * @see {@link createDecoder}\n */\nexport type Decoder<TTo> = FixedSizeDecoder<TTo> | VariableSizeDecoder<TTo>;\n\n/**\n * An object that can encode and decode a value to and from a fixed-size byte array.\n *\n * See {@link Codec} to learn more about creating and composing codecs.\n *\n * @interface\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n *\n * @example\n * ```ts\n * const codec: FixedSizeCodec<number | bigint, bigint, 8>;\n * const bytes = codec.encode(42);\n * const value = codec.decode(bytes); // 42n\n * const size = codec.fixedSize; // 8\n * ```\n *\n * @see {@link Codec}\n * @see {@link VariableSizeCodec}\n */\nexport type FixedSizeCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number> = FixedSizeDecoder<\n    TTo,\n    TSize\n> &\n    FixedSizeEncoder<TFrom, TSize>;\n\n/**\n * An object that can encode and decode a value to and from a variable-size byte array.\n *\n * See {@link Codec} to learn more about creating and composing codecs.\n *\n * @interface\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n *\n * @example\n * ```ts\n * const codec: VariableSizeCodec<number | bigint, bigint>;\n * const bytes = codec.encode(42);\n * const value = codec.decode(bytes); // 42n\n * const size = codec.getSizeFromValue(42);\n * ```\n *\n * @see {@link Codec}\n * @see {@link FixedSizeCodec}\n */\nexport type VariableSizeCodec<TFrom, TTo extends TFrom = TFrom> = VariableSizeDecoder<TTo> & VariableSizeEncoder<TFrom>;\n\n/**\n * An object that can encode and decode a value to and from a byte array.\n *\n * A `Codec` can be either:\n * - A {@link FixedSizeCodec}, where all encoded values have the same fixed size.\n * - A {@link VariableSizeCodec}, where encoded values can vary in size.\n *\n * @example\n * ```ts\n * const codec: Codec<string>;\n * const bytes = codec.encode('hello');\n * const value = codec.decode(bytes); // 'hello'\n * ```\n *\n * @remarks\n * For convenience, codecs can encode looser types than they decode.\n * That is, type {@link TFrom} can be a superset of type {@link TTo}.\n * For instance, a `Codec<bigint | number, bigint>` can encode both\n * `bigint` and `number` values, but will always decode to a `bigint`.\n *\n * ```ts\n * const codec: Codec<bigint | number, bigint>;\n * const bytes = codec.encode(42);\n * const value = codec.decode(bytes); // 42n\n * ```\n *\n * It is worth noting that codecs are the union of encoders and decoders.\n * This means that a `Codec<TFrom, TTo>` can be combined from an `Encoder<TFrom>`\n * and a `Decoder<TTo>` using the {@link combineCodec} function. This is particularly\n * useful for library authors who want to expose all three types of objects to their users.\n *\n * ```ts\n * const encoder: Encoder<bigint | number>;\n * const decoder: Decoder<bigint>;\n * const codec: Codec<bigint | number, bigint> = combineCodec(encoder, decoder);\n * ```\n *\n * Aside from combining encoders and decoders, codecs can also be created from scratch using\n * the {@link createCodec} function but it is more common to compose multiple codecs together\n * using the various helpers of the `@solana/codecs` package.\n *\n * For instance, here's how you might create a `Codec` for a `Person` object type that contains\n * a `name` string and an `age` number:\n *\n * ```ts\n * import { getStructCodec, addCodecSizePrefix, getUtf8Codec, getU32Codec } from '@solana/codecs';\n *\n * type Person = { name: string; age: number };\n * const getPersonCodec = (): Codec<Person> =>\n *     getStructCodec([\n *         ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n *         ['age', getU32Codec()],\n *     ]);\n * ```\n *\n * Note that composed `Codec` types are clever enough to understand whether\n * they are fixed-size or variable-size. In the example above, `getU32Codec()` is\n * a fixed-size codec, while `addCodecSizePrefix(getUtf8Codec(), getU32Codec())`\n * is a variable-size codec. This makes the final `Person` codec a variable-size codec.\n *\n * @see {@link FixedSizeCodec}\n * @see {@link VariableSizeCodec}\n * @see {@link combineCodec}\n * @see {@link createCodec}\n */\nexport type Codec<TFrom, TTo extends TFrom = TFrom> = FixedSizeCodec<TFrom, TTo> | VariableSizeCodec<TFrom, TTo>;\n\n/**\n * Gets the encoded size of a given value in bytes using the provided encoder.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @param value - The value to be encoded.\n * @param encoder - The encoder used to determine the encoded size.\n * @returns The size of the encoded value in bytes.\n *\n * @example\n * ```ts\n * const fixedSizeEncoder = { fixedSize: 4 };\n * getEncodedSize(123, fixedSizeEncoder); // Returns 4.\n *\n * const variableSizeEncoder = { getSizeFromValue: (value: string) => value.length };\n * getEncodedSize(\"hello\", variableSizeEncoder); // Returns 5.\n * ```\n *\n * @see {@link Encoder}\n */\nexport function getEncodedSize<TFrom>(\n    value: TFrom,\n    encoder: { fixedSize: number } | { getSizeFromValue: (value: TFrom) => number },\n): number {\n    return 'fixedSize' in encoder ? encoder.fixedSize : encoder.getSizeFromValue(value);\n}\n\n/**\n * Creates an `Encoder` by filling in the missing `encode` function using the provided `write` function and\n * either the `fixedSize` property (for {@link FixedSizeEncoder | FixedSizeEncoders}) or\n * the `getSizeFromValue` function (for {@link VariableSizeEncoder | VariableSizeEncoders}).\n *\n * Instead of manually implementing `encode`, this utility leverages the existing `write` function\n * and the size helpers to generate a complete encoder. The provided `encode` method will allocate\n * a new `Uint8Array` of the correct size and use `write` to populate it.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TSize - The fixed size of the encoded value in bytes (for fixed-size encoders).\n *\n * @param encoder - An encoder object that implements `write`, but not `encode`.\n * - If the encoder has a `fixedSize` property, it is treated as a {@link FixedSizeEncoder}.\n * - Otherwise, it is treated as a {@link VariableSizeEncoder}.\n *\n * @returns A fully functional `Encoder` with both `write` and `encode` methods.\n *\n * @example\n * Creating a custom fixed-size encoder.\n * ```ts\n * const encoder = createEncoder({\n *     fixedSize: 4,\n *     write: (value: number, bytes, offset) => {\n *         bytes.set(new Uint8Array([value]), offset);\n *         return offset + 4;\n *     },\n * });\n *\n * const bytes = encoder.encode(42);\n * // 0x2a000000\n * ```\n *\n * @example\n * Creating a custom variable-size encoder:\n * ```ts\n * const encoder = createEncoder({\n *     getSizeFromValue: (value: string) => value.length,\n *     write: (value: string, bytes, offset) => {\n *         const encodedValue = new TextEncoder().encode(value);\n *         bytes.set(encodedValue, offset);\n *         return offset + encodedValue.length;\n *     },\n * });\n *\n * const bytes = encoder.encode(\"hello\");\n * // 0x68656c6c6f\n * ```\n *\n * @remarks\n * Note that, while `createEncoder` is useful for defining more complex encoders, it is more common to compose\n * encoders together using the various helpers and primitives of the `@solana/codecs` package.\n *\n * Here are some alternative examples using codec primitives instead of `createEncoder`.\n *\n * ```ts\n * // Fixed-size encoder for unsigned 32-bit integers.\n * const encoder = getU32Encoder();\n * const bytes = encoder.encode(42);\n * // 0x2a000000\n *\n * // Variable-size encoder for 32-bytes prefixed UTF-8 strings.\n * const encoder = addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder());\n * const bytes = encoder.encode(\"hello\");\n * // 0x0500000068656c6c6f\n *\n * // Variable-size encoder for custom objects.\n * type Person = { name: string; age: number };\n * const encoder: Encoder<Person> = getStructEncoder([\n *     ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n *     ['age', getU32Encoder()],\n * ]);\n * const bytes = encoder.encode({ name: \"Bob\", age: 42 });\n * // 0x03000000426f622a000000\n * ```\n *\n * @see {@link Encoder}\n * @see {@link FixedSizeEncoder}\n * @see {@link VariableSizeEncoder}\n * @see {@link getStructEncoder}\n * @see {@link getU32Encoder}\n * @see {@link getUtf8Encoder}\n * @see {@link addEncoderSizePrefix}\n */\nexport function createEncoder<TFrom, TSize extends number>(\n    encoder: Omit<FixedSizeEncoder<TFrom, TSize>, 'encode'>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function createEncoder<TFrom>(encoder: Omit<VariableSizeEncoder<TFrom>, 'encode'>): VariableSizeEncoder<TFrom>;\nexport function createEncoder<TFrom>(\n    encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom>;\nexport function createEncoder<TFrom>(\n    encoder: Omit<FixedSizeEncoder<TFrom>, 'encode'> | Omit<VariableSizeEncoder<TFrom>, 'encode'>,\n): Encoder<TFrom> {\n    return Object.freeze({\n        ...encoder,\n        encode: value => {\n            const bytes = new Uint8Array(getEncodedSize(value, encoder));\n            encoder.write(value, bytes, 0);\n            return bytes;\n        },\n    });\n}\n\n/**\n * Creates a `Decoder` by filling in the missing `decode` function using the provided `read` function.\n *\n * Instead of manually implementing `decode`, this utility leverages the existing `read` function\n * and the size properties to generate a complete decoder. The provided `decode` method will read\n * from a `Uint8Array` at the given offset and return the decoded value.\n *\n * If the `fixedSize` property is provided, a {@link FixedSizeDecoder} will be created, otherwise\n * a {@link VariableSizeDecoder} will be created.\n *\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes (for fixed-size decoders).\n *\n * @param decoder - A decoder object that implements `read`, but not `decode`.\n * - If the decoder has a `fixedSize` property, it is treated as a {@link FixedSizeDecoder}.\n * - Otherwise, it is treated as a {@link VariableSizeDecoder}.\n *\n * @returns A fully functional `Decoder` with both `read` and `decode` methods.\n *\n * @example\n * Creating a custom fixed-size decoder.\n * ```ts\n * const decoder = createDecoder({\n *     fixedSize: 4,\n *     read: (bytes, offset) => {\n *         const value = bytes[offset];\n *         return [value, offset + 4];\n *     },\n * });\n *\n * const value = decoder.decode(new Uint8Array([42, 0, 0, 0]));\n * // 42\n * ```\n *\n * @example\n * Creating a custom variable-size decoder:\n * ```ts\n * const decoder = createDecoder({\n *     read: (bytes, offset) => {\n *         const decodedValue = new TextDecoder().decode(bytes.subarray(offset));\n *         return [decodedValue, bytes.length];\n *     },\n * });\n *\n * const value = decoder.decode(new Uint8Array([104, 101, 108, 108, 111]));\n * // \"hello\"\n * ```\n *\n * @remarks\n * Note that, while `createDecoder` is useful for defining more complex decoders, it is more common to compose\n * decoders together using the various helpers and primitives of the `@solana/codecs` package.\n *\n * Here are some alternative examples using codec primitives instead of `createDecoder`.\n *\n * ```ts\n * // Fixed-size decoder for unsigned 32-bit integers.\n * const decoder = getU32Decoder();\n * const value = decoder.decode(new Uint8Array([42, 0, 0, 0]));\n * // 42\n *\n * // Variable-size decoder for 32-bytes prefixed UTF-8 strings.\n * const decoder = addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder());\n * const value = decoder.decode(new Uint8Array([5, 0, 0, 0, 104, 101, 108, 108, 111]));\n * // \"hello\"\n *\n * // Variable-size decoder for custom objects.\n * type Person = { name: string; age: number };\n * const decoder: Decoder<Person> = getStructDecoder([\n *     ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n *     ['age', getU32Decoder()],\n * ]);\n * const value = decoder.decode(new Uint8Array([3, 0, 0, 0, 66, 111, 98, 42, 0, 0, 0]));\n * // { name: \"Bob\", age: 42 }\n * ```\n *\n * @see {@link Decoder}\n * @see {@link FixedSizeDecoder}\n * @see {@link VariableSizeDecoder}\n * @see {@link getStructDecoder}\n * @see {@link getU32Decoder}\n * @see {@link getUtf8Decoder}\n * @see {@link addDecoderSizePrefix}\n */\nexport function createDecoder<TTo, TSize extends number>(\n    decoder: Omit<FixedSizeDecoder<TTo, TSize>, 'decode'>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function createDecoder<TTo>(decoder: Omit<VariableSizeDecoder<TTo>, 'decode'>): VariableSizeDecoder<TTo>;\nexport function createDecoder<TTo>(\n    decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo>;\nexport function createDecoder<TTo>(\n    decoder: Omit<FixedSizeDecoder<TTo>, 'decode'> | Omit<VariableSizeDecoder<TTo>, 'decode'>,\n): Decoder<TTo> {\n    return Object.freeze({\n        ...decoder,\n        decode: (bytes, offset = 0) => decoder.read(bytes, offset)[0],\n    });\n}\n\n/**\n * Creates a `Codec` by filling in the missing `encode` and `decode` functions using the provided `write` and `read` functions.\n *\n * This utility combines the behavior of {@link createEncoder} and {@link createDecoder} to produce a fully functional `Codec`.\n * The `encode` method is derived from the `write` function, while the `decode` method is derived from the `read` function.\n *\n * If the `fixedSize` property is provided, a {@link FixedSizeCodec} will be created, otherwise\n * a {@link VariableSizeCodec} will be created.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes (for fixed-size codecs).\n *\n * @param codec - A codec object that implements `write` and `read`, but not `encode` or `decode`.\n * - If the codec has a `fixedSize` property, it is treated as a {@link FixedSizeCodec}.\n * - Otherwise, it is treated as a {@link VariableSizeCodec}.\n *\n * @returns A fully functional `Codec` with `write`, `read`, `encode`, and `decode` methods.\n *\n * @example\n * Creating a custom fixed-size codec.\n * ```ts\n * const codec = createCodec({\n *     fixedSize: 4,\n *     read: (bytes, offset) => {\n *         const value = bytes[offset];\n *         return [value, offset + 4];\n *     },\n *     write: (value: number, bytes, offset) => {\n *         bytes.set(new Uint8Array([value]), offset);\n *         return offset + 4;\n *     },\n * });\n *\n * const bytes = codec.encode(42);\n * // 0x2a000000\n * const value = codec.decode(bytes);\n * // 42\n * ```\n *\n * @example\n * Creating a custom variable-size codec:\n * ```ts\n * const codec = createCodec({\n *     getSizeFromValue: (value: string) => value.length,\n *     read: (bytes, offset) => {\n *         const decodedValue = new TextDecoder().decode(bytes.subarray(offset));\n *         return [decodedValue, bytes.length];\n *     },\n *     write: (value: string, bytes, offset) => {\n *         const encodedValue = new TextEncoder().encode(value);\n *         bytes.set(encodedValue, offset);\n *         return offset + encodedValue.length;\n *     },\n * });\n *\n * const bytes = codec.encode(\"hello\");\n * // 0x68656c6c6f\n * const value = codec.decode(bytes);\n * // \"hello\"\n * ```\n *\n * @remarks\n * This function effectively combines the behavior of {@link createEncoder} and {@link createDecoder}.\n * If you only need to encode or decode (but not both), consider using those functions instead.\n *\n * Here are some alternative examples using codec primitives instead of `createCodec`.\n *\n * ```ts\n * // Fixed-size codec for unsigned 32-bit integers.\n * const codec = getU32Codec();\n * const bytes = codec.encode(42);\n * // 0x2a000000\n * const value = codec.decode(bytes);\n * // 42\n *\n * // Variable-size codec for 32-bytes prefixed UTF-8 strings.\n * const codec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const bytes = codec.encode(\"hello\");\n * // 0x0500000068656c6c6f\n * const value = codec.decode(bytes);\n * // \"hello\"\n *\n * // Variable-size codec for custom objects.\n * type Person = { name: string; age: number };\n * const codec: Codec<PersonInput, Person> = getStructCodec([\n *     ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n *     ['age', getU32Codec()],\n * ]);\n * const bytes = codec.encode({ name: \"Bob\", age: 42 });\n * // 0x03000000426f622a000000\n * const value = codec.decode(bytes);\n * // { name: \"Bob\", age: 42 }\n * ```\n *\n * @see {@link Codec}\n * @see {@link FixedSizeCodec}\n * @see {@link VariableSizeCodec}\n * @see {@link createEncoder}\n * @see {@link createDecoder}\n * @see {@link getStructCodec}\n * @see {@link getU32Codec}\n * @see {@link getUtf8Codec}\n * @see {@link addCodecSizePrefix}\n */\nexport function createCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n    codec: Omit<FixedSizeCodec<TFrom, TTo, TSize>, 'decode' | 'encode'>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n    codec: Omit<VariableSizeCodec<TFrom, TTo>, 'decode' | 'encode'>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n    codec:\n        | Omit<FixedSizeCodec<TFrom, TTo>, 'decode' | 'encode'>\n        | Omit<VariableSizeCodec<TFrom, TTo>, 'decode' | 'encode'>,\n): Codec<TFrom, TTo>;\nexport function createCodec<TFrom, TTo extends TFrom = TFrom>(\n    codec:\n        | Omit<FixedSizeCodec<TFrom, TTo>, 'decode' | 'encode'>\n        | Omit<VariableSizeCodec<TFrom, TTo>, 'decode' | 'encode'>,\n): Codec<TFrom, TTo> {\n    return Object.freeze({\n        ...codec,\n        decode: (bytes, offset = 0) => codec.read(bytes, offset)[0],\n        encode: value => {\n            const bytes = new Uint8Array(getEncodedSize(value, codec));\n            codec.write(value, bytes, 0);\n            return bytes;\n        },\n    });\n}\n\n/**\n * Determines whether the given codec, encoder, or decoder is fixed-size.\n *\n * A fixed-size object is identified by the presence of a `fixedSize` property.\n * If this property exists, the object is considered a {@link FixedSizeCodec},\n * {@link FixedSizeEncoder}, or {@link FixedSizeDecoder}.\n * Otherwise, it is assumed to be a {@link VariableSizeCodec},\n * {@link VariableSizeEncoder}, or {@link VariableSizeDecoder}.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n * @returns `true` if the object is fixed-size, `false` otherwise.\n *\n * @example\n * Checking a fixed-size encoder.\n * ```ts\n * const encoder = getU32Encoder();\n * isFixedSize(encoder); // true\n * ```\n *\n * @example\n * Checking a variable-size encoder.\n * ```ts\n * const encoder = addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder());\n * isFixedSize(encoder); // false\n * ```\n *\n * @remarks\n * This function is commonly used to distinguish between fixed-size and variable-size objects at runtime.\n * If you need to enforce this distinction with type assertions, consider using {@link assertIsFixedSize}.\n *\n * @see {@link assertIsFixedSize}\n */\nexport function isFixedSize<TFrom, TSize extends number>(\n    encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function isFixedSize<TTo, TSize extends number>(\n    decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): decoder is FixedSizeDecoder<TTo, TSize>;\nexport function isFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n    codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function isFixedSize<TSize extends number>(\n    codec: { fixedSize: TSize } | { maxSize?: number },\n): codec is { fixedSize: TSize };\nexport function isFixedSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { fixedSize: number } {\n    return 'fixedSize' in codec && typeof codec.fixedSize === 'number';\n}\n\n/**\n * Asserts that the given codec, encoder, or decoder is fixed-size.\n *\n * If the object is not fixed-size (i.e., it lacks a `fixedSize` property),\n * this function throws a {@link SolanaError} with the code `SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n * @throws {SolanaError} If the object is not fixed-size.\n *\n * @example\n * Asserting a fixed-size encoder.\n * ```ts\n * const encoder = getU32Encoder();\n * assertIsFixedSize(encoder); // Passes\n * ```\n *\n * @example\n * Attempting to assert a variable-size encoder.\n * ```ts\n * const encoder = addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder());\n * assertIsFixedSize(encoder); // Throws SolanaError\n * ```\n *\n * @remarks\n * This function is the assertion-based counterpart of {@link isFixedSize}.\n * If you only need to check whether an object is fixed-size without throwing an error, use {@link isFixedSize} instead.\n *\n * @see {@link isFixedSize}\n */\nexport function assertIsFixedSize<TFrom, TSize extends number>(\n    encoder: FixedSizeEncoder<TFrom, TSize> | VariableSizeEncoder<TFrom>,\n): asserts encoder is FixedSizeEncoder<TFrom, TSize>;\nexport function assertIsFixedSize<TTo, TSize extends number>(\n    decoder: FixedSizeDecoder<TTo, TSize> | VariableSizeDecoder<TTo>,\n): asserts decoder is FixedSizeDecoder<TTo, TSize>;\nexport function assertIsFixedSize<TFrom, TTo extends TFrom, TSize extends number>(\n    codec: FixedSizeCodec<TFrom, TTo, TSize> | VariableSizeCodec<TFrom, TTo>,\n): asserts codec is FixedSizeCodec<TFrom, TTo, TSize>;\nexport function assertIsFixedSize<TSize extends number>(\n    codec: { fixedSize: TSize } | { maxSize?: number },\n): asserts codec is { fixedSize: TSize };\nexport function assertIsFixedSize(\n    codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { fixedSize: number } {\n    if (!isFixedSize(codec)) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH);\n    }\n}\n\n/**\n * Determines whether the given codec, encoder, or decoder is variable-size.\n *\n * A variable-size object is identified by the absence of a `fixedSize` property.\n * If this property is missing, the object is considered a {@link VariableSizeCodec},\n * {@link VariableSizeEncoder}, or {@link VariableSizeDecoder}.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n * @returns `true` if the object is variable-size, `false` otherwise.\n *\n * @example\n * Checking a variable-size encoder.\n * ```ts\n * const encoder = addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder());\n * isVariableSize(encoder); // true\n * ```\n *\n * @example\n * Checking a fixed-size encoder.\n * ```ts\n * const encoder = getU32Encoder();\n * isVariableSize(encoder); // false\n * ```\n *\n * @remarks\n * This function is the inverse of {@link isFixedSize}.\n *\n * @see {@link isFixedSize}\n * @see {@link assertIsVariableSize}\n */\nexport function isVariableSize<TFrom>(encoder: Encoder<TFrom>): encoder is VariableSizeEncoder<TFrom>;\nexport function isVariableSize<TTo>(decoder: Decoder<TTo>): decoder is VariableSizeDecoder<TTo>;\nexport function isVariableSize<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n): codec is VariableSizeCodec<TFrom, TTo>;\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number };\nexport function isVariableSize(codec: { fixedSize: number } | { maxSize?: number }): codec is { maxSize?: number } {\n    return !isFixedSize(codec);\n}\n\n/**\n * Asserts that the given codec, encoder, or decoder is variable-size.\n *\n * If the object is not variable-size (i.e., it has a `fixedSize` property),\n * this function throws a {@link SolanaError} with the code `SOLANA_ERROR__CODECS__EXPECTED_VARIABLE_LENGTH`.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n * @throws {SolanaError} If the object is not variable-size.\n *\n * @example\n * Asserting a variable-size encoder.\n * ```ts\n * const encoder = addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder());\n * assertIsVariableSize(encoder); // Passes\n * ```\n *\n * @example\n * Attempting to assert a fixed-size encoder.\n * ```ts\n * const encoder = getU32Encoder();\n * assertIsVariableSize(encoder); // Throws SolanaError\n * ```\n *\n * @remarks\n * This function is the assertion-based counterpart of {@link isVariableSize}.\n * If you only need to check whether an object is variable-size without throwing an error, use {@link isVariableSize} instead.\n *\n * Also note that this function is the inverse of {@link assertIsFixedSize}.\n *\n * @see {@link isVariableSize}\n * @see {@link assertIsFixedSize}\n */\nexport function assertIsVariableSize<TFrom>(encoder: Encoder<TFrom>): asserts encoder is VariableSizeEncoder<TFrom>;\nexport function assertIsVariableSize<TTo>(decoder: Decoder<TTo>): asserts decoder is VariableSizeDecoder<TTo>;\nexport function assertIsVariableSize<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n): asserts codec is VariableSizeCodec<TFrom, TTo>;\nexport function assertIsVariableSize(\n    codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number };\nexport function assertIsVariableSize(\n    codec: { fixedSize: number } | { maxSize?: number },\n): asserts codec is { maxSize?: number } {\n    if (!isVariableSize(codec)) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_VARIABLE_LENGTH);\n    }\n}\n"
  },
  {
    "path": "packages/codecs-core/src/combine-codec.ts",
    "content": "import {\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH,\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH,\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    isFixedSize,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from './codec';\n\n/**\n * Combines an `Encoder` and a `Decoder` into a `Codec`.\n *\n * That is, given a `Encoder<TFrom>` and a `Decoder<TTo>`, this function returns a `Codec<TFrom, TTo>`.\n *\n * This allows for modular composition by keeping encoding and decoding logic separate\n * while still offering a convenient way to bundle them into a single `Codec`.\n * This is particularly useful for library maintainers who want to expose `Encoders`,\n * `Decoders`, and `Codecs` separately, enabling tree-shaking of unused logic.\n *\n * The provided `Encoder` and `Decoder` must be compatible in terms of:\n * - **Fixed Size:** If both are fixed-size, they must have the same `fixedSize` value.\n * - **Variable Size:** If either has a `maxSize` attribute, it must match the other.\n *\n * If these conditions are not met, a {@link SolanaError} will be thrown.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes (for fixed-size codecs).\n *\n * @param encoder - The `Encoder` to combine.\n * @param decoder - The `Decoder` to combine.\n * @returns A `Codec` that provides both `encode` and `decode` methods.\n *\n * @throws {SolanaError}\n * - `SOLANA_ERROR__CODECS__ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH`\n *   Thrown if the encoder and decoder have mismatched size types (fixed vs. variable).\n * - `SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH`\n *   Thrown if both are fixed-size but have different `fixedSize` values.\n * - `SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH`\n *   Thrown if the `maxSize` attributes do not match.\n *\n * @example\n * Creating a fixed-size `Codec` from an encoder and a decoder.\n * ```ts\n * const encoder = getU32Encoder();\n * const decoder = getU32Decoder();\n * const codec = combineCodec(encoder, decoder);\n *\n * const bytes = codec.encode(42); // 0x2a000000\n * const value = codec.decode(bytes); // 42\n * ```\n *\n * @example\n * Creating a variable-size `Codec` from an encoder and a decoder.\n * ```ts\n * const encoder = addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder());\n * const decoder = addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder());\n * const codec = combineCodec(encoder, decoder);\n *\n * const bytes = codec.encode(\"hello\"); // 0x0500000068656c6c6f\n * const value = codec.decode(bytes); // \"hello\"\n * ```\n *\n * @remarks\n * The recommended pattern for defining codecs in libraries is to expose separate functions for the encoder, decoder, and codec.\n * This allows users to import only what they need, improving tree-shaking efficiency.\n *\n * ```ts\n * type MyType = \\/* ... *\\/;\n * const getMyTypeEncoder = (): Encoder<MyType> => { \\/* ... *\\/ };\n * const getMyTypeDecoder = (): Decoder<MyType> => { \\/* ... *\\/ };\n * const getMyTypeCodec = (): Codec<MyType> =>\n *     combineCodec(getMyTypeEncoder(), getMyTypeDecoder());\n * ```\n *\n * @see {@link Codec}\n * @see {@link Encoder}\n * @see {@link Decoder}\n */\nexport function combineCodec<TFrom, TTo extends TFrom, TSize extends number>(\n    encoder: FixedSizeEncoder<TFrom, TSize>,\n    decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n    encoder: VariableSizeEncoder<TFrom>,\n    decoder: VariableSizeDecoder<TTo>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n    encoder: Encoder<TFrom>,\n    decoder: Decoder<TTo>,\n): Codec<TFrom, TTo>;\nexport function combineCodec<TFrom, TTo extends TFrom>(\n    encoder: Encoder<TFrom>,\n    decoder: Decoder<TTo>,\n): Codec<TFrom, TTo> {\n    if (isFixedSize(encoder) !== isFixedSize(decoder)) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH);\n    }\n\n    if (isFixedSize(encoder) && isFixedSize(decoder) && encoder.fixedSize !== decoder.fixedSize) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH, {\n            decoderFixedSize: decoder.fixedSize,\n            encoderFixedSize: encoder.fixedSize,\n        });\n    }\n\n    if (!isFixedSize(encoder) && !isFixedSize(decoder) && encoder.maxSize !== decoder.maxSize) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH, {\n            decoderMaxSize: decoder.maxSize,\n            encoderMaxSize: encoder.maxSize,\n        });\n    }\n\n    return {\n        ...decoder,\n        ...encoder,\n        decode: decoder.decode,\n        encode: encoder.encode,\n        read: decoder.read,\n        write: encoder.write,\n    };\n}\n"
  },
  {
    "path": "packages/codecs-core/src/decoder-entire-byte-array.ts",
    "content": "import { SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY, SolanaError } from '@solana/errors';\n\nimport { createDecoder, Decoder } from './codec';\n\n/**\n * Create a {@link Decoder} that asserts that the bytes provided to `decode` or `read` are fully consumed by the inner decoder\n * @param decoder A decoder to wrap\n * @returns A new decoder that will throw if provided with a byte array that it does not fully consume\n *\n * @typeParam T - The type of the decoder\n *\n * @remarks\n * Note that this compares the offset after encoding to the length of the input byte array\n *\n * The `offset` parameter to `decode` and `read` is still considered, and will affect the new offset that is compared to the byte array length\n *\n * The error that is thrown by the returned decoder is a {@link SolanaError} with the code `SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY`\n *\n * @example\n * Create a decoder that decodes a `u32` (4 bytes) and ensures the entire byte array is consumed\n * ```ts\n * const decoder = createDecoderThatUsesExactByteArray(getU32Decoder());\n * decoder.decode(new Uint8Array([0, 0, 0, 0])); // 0\n * decoder.decode(new Uint8Array([0, 0, 0, 0, 0])); // throws\n *\n * // with an offset\n * decoder.decode(new Uint8Array([0, 0, 0, 0, 0]), 1); // 0\n * decoder.decode(new Uint8Array([0, 0, 0, 0, 0, 0]), 1); // throws\n * ```\n */\nexport function createDecoderThatConsumesEntireByteArray<T>(decoder: Decoder<T>): Decoder<T> {\n    return createDecoder({\n        ...decoder,\n        read(bytes, offset) {\n            const [value, newOffset] = decoder.read(bytes, offset);\n            if (bytes.length > newOffset) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY, {\n                    expectedLength: newOffset,\n                    numExcessBytes: bytes.length - newOffset,\n                });\n            }\n            return [value, newOffset];\n        },\n    });\n}\n"
  },
  {
    "path": "packages/codecs-core/src/fix-codec-size.ts",
    "content": "import { assertByteArrayHasEnoughBytesForCodec } from './assertions';\nimport { fixBytes } from './bytes';\nimport {\n    Codec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    isFixedSize,\n    Offset,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n/**\n * Creates a fixed-size encoder from a given encoder.\n *\n * The resulting encoder ensures that encoded values always have the specified number of bytes.\n * If the original encoded value is larger than `fixedBytes`, it is truncated.\n * If it is smaller, it is padded with trailing zeroes.\n *\n * For more details, see {@link fixCodecSize}.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n *\n * @param encoder - The encoder to wrap into a fixed-size encoder.\n * @param fixedBytes - The fixed number of bytes to write.\n * @returns A `FixedSizeEncoder` that ensures a consistent output size.\n *\n * @example\n * ```ts\n * const encoder = fixEncoderSize(getUtf8Encoder(), 4);\n * encoder.encode(\"Hello\"); // 0x48656c6c (truncated)\n * encoder.encode(\"Hi\");    // 0x48690000 (padded)\n * encoder.encode(\"Hiya\");  // 0x48697961 (same length)\n * ```\n *\n * @remarks\n * If you need a full codec with both encoding and decoding, use {@link fixCodecSize}.\n *\n * @see {@link fixCodecSize}\n * @see {@link fixDecoderSize}\n */\nexport function fixEncoderSize<TFrom, TSize extends number>(\n    encoder: Encoder<TFrom>,\n    fixedBytes: TSize,\n): FixedSizeEncoder<TFrom, TSize> {\n    return createEncoder({\n        fixedSize: fixedBytes,\n        write: (value: TFrom, bytes: Uint8Array, offset: Offset) => {\n            // Here we exceptionally use the `encode` function instead of the `write`\n            // function as using the nested `write` function on a fixed-sized byte\n            // array may result in a out-of-bounds error on the nested encoder.\n            const variableByteArray = encoder.encode(value);\n            const fixedByteArray =\n                variableByteArray.length > fixedBytes ? variableByteArray.slice(0, fixedBytes) : variableByteArray;\n            bytes.set(fixedByteArray, offset);\n            return offset + fixedBytes;\n        },\n    });\n}\n\n/**\n * Creates a fixed-size decoder from a given decoder.\n *\n * The resulting decoder always reads exactly `fixedBytes` bytes from the input.\n * If the nested decoder is also fixed-size, the bytes are truncated or padded as needed.\n *\n * For more details, see {@link fixCodecSize}.\n *\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n *\n * @param decoder - The decoder to wrap into a fixed-size decoder.\n * @param fixedBytes - The fixed number of bytes to read.\n * @returns A `FixedSizeDecoder` that ensures a consistent input size.\n *\n * @example\n * ```ts\n * const decoder = fixDecoderSize(getUtf8Decoder(), 4);\n * decoder.decode(new Uint8Array([72, 101, 108, 108, 111])); // \"Hell\" (truncated)\n * decoder.decode(new Uint8Array([72, 105, 0, 0]));          // \"Hi\" (zeroes ignored)\n * decoder.decode(new Uint8Array([72, 105, 121, 97]));       // \"Hiya\" (same length)\n * ```\n *\n * @remarks\n * If you need a full codec with both encoding and decoding, use {@link fixCodecSize}.\n *\n * @see {@link fixCodecSize}\n * @see {@link fixEncoderSize}\n */\nexport function fixDecoderSize<TTo, TSize extends number>(\n    decoder: Decoder<TTo>,\n    fixedBytes: TSize,\n): FixedSizeDecoder<TTo, TSize> {\n    return createDecoder({\n        fixedSize: fixedBytes,\n        read: (bytes, offset) => {\n            assertByteArrayHasEnoughBytesForCodec('fixCodecSize', fixedBytes, bytes, offset);\n            // Slice the byte array to the fixed size if necessary.\n            if (offset > 0 || bytes.length > fixedBytes) {\n                bytes = bytes.slice(offset, offset + fixedBytes);\n            }\n            // If the nested decoder is fixed-size, pad and truncate the byte array accordingly.\n            if (isFixedSize(decoder)) {\n                bytes = fixBytes(bytes, decoder.fixedSize);\n            }\n            // Decode the value using the nested decoder.\n            const [value] = decoder.read(bytes, 0);\n            return [value, offset + fixedBytes];\n        },\n    });\n}\n\n/**\n * Creates a fixed-size codec from a given codec.\n *\n * The resulting codec ensures that both encoding and decoding operate on a fixed number of bytes.\n * When encoding:\n * - If the encoded value is larger than `fixedBytes`, it is truncated.\n * - If it is smaller, it is padded with trailing zeroes.\n * - If it is exactly `fixedBytes`, it remains unchanged.\n *\n * When decoding:\n * - Exactly `fixedBytes` bytes are read from the input.\n * - If the nested decoder has a smaller fixed size, bytes are truncated or padded as necessary.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n *\n * @param codec - The codec to wrap into a fixed-size codec.\n * @param fixedBytes - The fixed number of bytes to read/write.\n * @returns A `FixedSizeCodec` that ensures both encoding and decoding conform to a fixed size.\n *\n * @example\n * ```ts\n * const codec = fixCodecSize(getUtf8Codec(), 4);\n *\n * const bytes1 = codec.encode(\"Hello\"); // 0x48656c6c (truncated)\n * const value1 = codec.decode(bytes1);  // \"Hell\"\n *\n * const bytes2 = codec.encode(\"Hi\");    // 0x48690000 (padded)\n * const value2 = codec.decode(bytes2);  // \"Hi\"\n *\n * const bytes3 = codec.encode(\"Hiya\");  // 0x48697961 (same length)\n * const value3 = codec.decode(bytes3);  // \"Hiya\"\n * ```\n *\n * @remarks\n * If you only need to enforce a fixed size for encoding, use {@link fixEncoderSize}.\n * If you only need to enforce a fixed size for decoding, use {@link fixDecoderSize}.\n *\n * ```ts\n * const bytes = fixEncoderSize(getUtf8Encoder(), 4).encode(\"Hiya\");\n * const value = fixDecoderSize(getUtf8Decoder(), 4).decode(bytes);\n * ```\n *\n * @see {@link fixEncoderSize}\n * @see {@link fixDecoderSize}\n */\nexport function fixCodecSize<TFrom, TTo extends TFrom, TSize extends number>(\n    codec: Codec<TFrom, TTo>,\n    fixedBytes: TSize,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n    return combineCodec(fixEncoderSize(codec, fixedBytes), fixDecoderSize(codec, fixedBytes));\n}\n"
  },
  {
    "path": "packages/codecs-core/src/index.ts",
    "content": "/**\n * This package contains the core types and functions for encoding and decoding data structures on Solana. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * This package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) which acts as an entry point for all codec packages as well as for their documentation.\n *\n * ## Composing codecs\n *\n * The easiest way to create your own codecs is to compose the [various codecs](https://github.com/anza-xyz/kit/tree/main/packages/codecs) offered by this library. For instance, here’s how you would define a codec for a `Person` object that contains a `name` string attribute and an `age` number stored in 4 bytes.\n *\n * ```ts\n * type Person = { name: string; age: number };\n * const getPersonCodec = (): Codec<Person> =>\n *     getStructCodec([\n *         ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n *         ['age', getU32Codec()],\n *     ]);\n * ```\n *\n * This function returns a `Codec` object which contains both an `encode` and `decode` function that can be used to convert a `Person` type to and from a `Uint8Array`.\n *\n * ```ts\n * const personCodec = getPersonCodec();\n * const bytes = personCodec.encode({ name: 'John', age: 42 });\n * const person = personCodec.decode(bytes);\n * ```\n *\n * There is a significant library of composable codecs at your disposal, enabling you to compose complex types. You may be interested in the documentation of these other packages to learn more about them:\n *\n * - [`@solana/codecs-numbers`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-numbers) for number codecs.\n * - [`@solana/codecs-strings`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-strings) for string codecs.\n * - [`@solana/codecs-data-structures`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures) for many data structure codecs such as objects, arrays, tuples, sets, maps, enums, discriminated unions, booleans, etc.\n * - [`@solana/options`](https://github.com/anza-xyz/kit/tree/main/packages/options) for a Rust-like `Option` type and associated codec.\n *\n * You may also be interested in some of the helpers of this `@solana/codecs-core` library such as `transformCodec`, `fixCodecSize` or `reverseCodec` that create new codecs from existing ones.\n *\n * Note that all of these libraries are included in the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) as well as the main `@solana/kit` package for your convenience.\n *\n * ## Composing encoders and decoders\n *\n * Whilst Codecs can both encode and decode, it is possible to only focus on encoding or decoding data, enabling the unused logic to be tree-shaken. For instance, here’s our previous example using Encoders only to encode a `Person` type.\n *\n * ```ts\n * const getPersonEncoder = (): Encoder<Person> =>\n *     getStructEncoder([\n *         ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n *         ['age', getU32Encoder()],\n *     ]);\n *\n * const bytes = getPersonEncoder().encode({ name: 'John', age: 42 });\n * ```\n *\n * The same can be done for decoding the `Person` type by using Decoders like so.\n *\n * ```ts\n * const getPersonDecoder = (): Decoder<Person> =>\n *     getStructDecoder([\n *         ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n *         ['age', getU32Decoder()],\n *     ]);\n *\n * const person = getPersonDecoder().decode(bytes);\n * ```\n *\n * ## Combining encoders and decoders\n *\n * Separating Codecs into Encoders and Decoders is particularly good practice for library maintainers as it allows their users to tree-shake any of the encoders and/or decoders they don’t need. However, we may still want to offer a codec helper for users who need both for convenience.\n *\n * That’s why this library offers a `combineCodec` helper that creates a `Codec` instance from a matching `Encoder` and `Decoder`.\n *\n * ```ts\n * const getPersonCodec = (): Codec<Person> => combineCodec(getPersonEncoder(), getPersonDecoder());\n * ```\n *\n * This means library maintainers can offer Encoders, Decoders and Codecs for all their types whilst staying efficient and tree-shakeable. In summary, we recommend the following pattern when creating codecs for library types.\n *\n * ```ts\n * type MyType = \\/* ... *\\/;\n * const getMyTypeEncoder = (): Encoder<MyType> => { \\/* ... *\\/ };\n * const getMyTypeDecoder = (): Decoder<MyType> => { \\/* ... *\\/ };\n * const getMyTypeCodec = (): Codec<MyType> =>\n *     combineCodec(getMyTypeEncoder(), getMyTypeDecoder());\n * ```\n *\n * ## Different From and To types\n *\n * When creating codecs, the encoded type is allowed to be looser than the decoded type. A good example of that is the u64 number codec:\n *\n * ```ts\n * const u64Codec: Codec<number | bigint, bigint> = getU64Codec();\n * ```\n *\n * As you can see, the first type parameter is looser since it accepts numbers or big integers, whereas the second type parameter only accepts big integers. That’s because when _encoding_ a u64 number, you may provide either a `bigint` or a `number` for convenience. However, when you decode a u64 number, you will always get a `bigint` because not all u64 values can fit in a JavaScript `number` type.\n *\n * ```ts\n * const bytes = u64Codec.encode(42);\n * const value = u64Codec.decode(bytes); // BigInt(42)\n * ```\n *\n * This relationship between the type we encode “From” and decode “To” can be generalized in TypeScript as `To extends From`.\n *\n * Here’s another example using an object with default values. You can read more about the `transformEncoder` helper below.\n *\n * ```ts\n * type Person = { name: string, age: number };\n * type PersonInput = { name: string, age?: number };\n *\n * const getPersonEncoder = (): Encoder<PersonInput> =>\n *     transformEncoder(\n *         getStructEncoder([\n *             ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n *             ['age', getU32Encoder()],\n *         ]),\n *         input => { ...input, age: input.age ?? 42 }\n *     );\n *\n * const getPersonDecoder = (): Decoder<Person> =>\n *     getStructDecoder([\n *         ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n *         ['age', getU32Decoder()],\n *     ]);\n *\n * const getPersonCodec = (): Codec<PersonInput, Person> =>\n *   combineCodec(getPersonEncoder(), getPersonDecoder())\n * ```\n *\n * ## Fixed-size and variable-size codecs\n *\n * It is also worth noting that Codecs can either be of fixed size or variable size.\n *\n * `FixedSizeCodecs` have a `fixedSize` number attribute that tells us exactly how big their encoded data is in bytes.\n *\n * ```ts\n * const myCodec: FixedSizeCodec<number> = getU32Codec();\n * myCodec.fixedSize; // 4 bytes.\n * ```\n *\n * On the other hand, `VariableSizeCodecs` do not know the size of their encoded data in advance. Instead, they will grab that information either from the provided encoded data or from the value to encode. For the former, we can simply access the length of the `Uint8Array`. For the latter, it provides a `getSizeFromValue` that tells us the encoded byte size of the provided value.\n *\n * ```ts\n * const myCodec: VariableSizeCodec<string> = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * myCodec.getSizeFromValue('hello world'); // 4 + 11 bytes.\n * ```\n *\n * Also note that, if the `VariableSizeCodec` is bounded by a maximum size, it can be provided as a `maxSize` number attribute.\n *\n * The following type guards are available to identify and/or assert the size of codecs: `isFixedSize`, `isVariableSize`, `assertIsFixedSize` and `assertIsVariableSize`.\n *\n * Finally, note that the same is true for `Encoders` and `Decoders`.\n *\n * - A `FixedSizeEncoder` has a `fixedSize` number attribute.\n * - A `VariableSizeEncoder` has a `getSizeFromValue` function and an optional `maxSize` number attribute.\n * - A `FixedSizeDecoder` has a `fixedSize` number attribute.\n * - A `VariableSizeDecoder` has an optional `maxSize` number attribute.\n *\n * ## Creating custom codecs\n *\n * If composing codecs isn’t enough for you, you may implement your own codec logic by using the `createCodec` function. This function requires an object with a `read` and a `write` function telling us how to read from and write to an existing byte array.\n *\n * The `read` function accepts the `bytes` to decode from and the `offset` at each we should start reading. It returns an array with two items:\n *\n * - The first item should be the decoded value.\n * - The second item should be the next offset to read from.\n *\n * ```ts\n * createCodec({\n *     read(bytes, offset) {\n *         const value = bytes[offset];\n *         return [value, offset + 1];\n *     },\n *     // ...\n * });\n * ```\n *\n * Reciprocally, the `write` function accepts the `value` to encode, the array of `bytes` to write the encoded value to and the `offset` at which it should be written. It should encode the given value, insert it in the byte array, and provide the next offset to write to as the return value.\n *\n * ```ts\n * createCodec({\n *     write(value, bytes, offset) {\n *         bytes.set(value, offset);\n *         return offset + 1;\n *     },\n *     // ...\n * });\n * ```\n *\n * Additionally, we must specify the size of the codec. If we are defining a `FixedSizeCodec`, we must simply provide the `fixedSize` number attribute. For `VariableSizeCodecs`, we must provide the `getSizeFromValue` function as described in the previous section.\n *\n * ```ts\n * // FixedSizeCodec.\n * createCodec({\n *     fixedSize: 1,\n *     // ...\n * });\n *\n * // VariableSizeCodec.\n * createCodec({\n *     getSizeFromValue: (value: string) => value.length,\n *     // ...\n * });\n * ```\n *\n * Here’s a concrete example of a custom codec that encodes any unsigned integer in a single byte. Since a single byte can only store integers from 0 to 255, if any other integer is provided it will take its modulo 256 to ensure it fits in a single byte. Because it always requires a single byte, that codec is a `FixedSizeCodec` of size `1`.\n *\n * ```ts\n * const getModuloU8Codec = () =>\n *     createCodec<number>({\n *         fixedSize: 1,\n *         read(bytes, offset) {\n *             const value = bytes[offset];\n *             return [value, offset + 1];\n *         },\n *         write(value, bytes, offset) {\n *             bytes.set(value % 256, offset);\n *             return offset + 1;\n *         },\n *     });\n * ```\n *\n * Note that, it is also possible to create custom encoders and decoders separately by using the `createEncoder` and `createDecoder` functions respectively and then use the `combineCodec` function on them just like we were doing with composed codecs.\n *\n * This approach is recommended to library maintainers as it allows their users to tree-shake any of the encoders and/or decoders they don’t need.\n *\n * Here’s our previous modulo u8 example but split into separate `Encoder`, `Decoder` and `Codec` instances.\n *\n * ```ts\n * const getModuloU8Encoder = () =>\n *     createEncoder<number>({\n *         fixedSize: 1,\n *         write(value, bytes, offset) {\n *             bytes.set(value % 256, offset);\n *             return offset + 1;\n *         },\n *     });\n *\n * const getModuloU8Decoder = () =>\n *     createDecoder<number>({\n *         fixedSize: 1,\n *         read(bytes, offset) {\n *             const value = bytes[offset];\n *             return [value, offset + 1];\n *         },\n *     });\n *\n * const getModuloU8Codec = () => combineCodec(getModuloU8Encoder(), getModuloU8Decoder());\n * ```\n *\n * Here’s another example returning a `VariableSizeCodec`. This one transforms a simple string composed of characters from `a` to `z` to a buffer of numbers from `1` to `26` where `0` bytes are spaces.\n *\n * ```ts\n * const alphabet = ' abcdefghijklmnopqrstuvwxyz';\n *\n * const getCipherEncoder = () =>\n *     createEncoder<string>({\n *         getSizeFromValue: value => value.length,\n *         write(value, bytes, offset) {\n *             const bytesToAdd = [...value].map(char => alphabet.indexOf(char));\n *             bytes.set(bytesToAdd, offset);\n *             return offset + bytesToAdd.length;\n *         },\n *     });\n *\n * const getCipherDecoder = () =>\n *     createDecoder<string>({\n *         read(bytes, offset) {\n *             const value = [...bytes.slice(offset)].map(byte => alphabet.charAt(byte)).join('');\n *             return [value, bytes.length];\n *         },\n *     });\n *\n * const getCipherCodec = () => combineCodec(getCipherEncoder(), getCipherDecoder());\n * ```\n *\n * ## Transforming codecs\n *\n * It is possible to transform a `Codec<T>` to a `Codec<U>` by providing two mapping functions: one that goes from `T` to `U` and one that does the opposite.\n *\n * For instance, here’s how you would map a `u32` integer into a `string` representation of that number.\n *\n * ```ts\n * const getStringU32Codec = () =>\n *     transformCodec(\n *         getU32Codec(),\n *         (integerAsString: string): number => parseInt(integerAsString),\n *         (integer: number): string => integer.toString(),\n *     );\n *\n * getStringU32Codec().encode('42'); // new Uint8Array([42])\n * getStringU32Codec().decode(new Uint8Array([42])); // \"42\"\n * ```\n *\n * If a `Codec` has [different From and To types](#different-from-and-to-types), say `Codec<OldFrom, OldTo>`, and we want to map it to `Codec<NewFrom, NewTo>`, we must provide functions that map from `NewFrom` to `OldFrom` and from `OldTo` to `NewTo`.\n *\n * To illustrate that, let’s take our previous `getStringU32Codec` example but make it use a `getU64Codec` codec instead as it returns a `Codec<number | bigint, bigint>`. Additionally, let’s make it so our `getStringU64Codec` function returns a `Codec<number | string, string>` so that it also accepts numbers when encoding values. Here’s what our mapping functions look like:\n *\n * ```ts\n * const getStringU64Codec = () =>\n *     transformCodec(\n *         getU64Codec(),\n *         (integerInput: number | string): number | bigint =>\n *             typeof integerInput === 'string' ? BigInt(integerAsString) : integerInput,\n *         (integer: bigint): string => integer.toString(),\n *     );\n * ```\n *\n * Note that the second function that maps the decoded type is optional. That means, you can omit it to simply update or loosen the type to encode whilst keeping the decoded type the same.\n *\n * This is particularly useful to provide default values to object structures. For instance, here’s how we can map our `Person` codec to give a default value to its `age` attribute.\n *\n * ```ts\n * type Person = { name: string; age: number; }\n * const getPersonCodec = (): Codec<Person> => { \\/* ... *\\/ }\n *\n * type PersonInput = { name: string; age?: number; }\n * const getPersonWithDefaultValueCodec = (): Codec<PersonInput, Person> =>\n *     transformCodec(\n *         getPersonCodec(),\n *         (person: PersonInput): Person => { ...person, age: person.age ?? 42 }\n *     )\n * ```\n *\n * Similar helpers exist to map `Encoder` and `Decoder` instances allowing you to separate your codec logic into tree-shakeable functions. Here’s our `getStringU32Codec` written that way.\n *\n * ```ts\n * const getStringU32Encoder = () =>\n *     transformEncoder(getU32Encoder(), (integerAsString: string): number => parseInt(integerAsString));\n * const getStringU32Decoder = () => transformDecoder(getU32Decoder(), (integer: number): string => integer.toString());\n * const getStringU32Codec = () => combineCodec(getStringU32Encoder(), getStringU32Decoder());\n * ```\n *\n * ## Fixing the size of codecs\n *\n * The `fixCodecSize` function allows you to bind the size of a given codec to the given fixed size.\n *\n * For instance, say you want to represent a base-58 string that uses exactly 32 bytes when decoded. Here’s how you can use the `fixCodecSize` helper to achieve that.\n *\n * ```ts\n * const get32BytesBase58Codec = () => fixCodecSize(getBase58Codec(), 32);\n * ```\n *\n * You may also use the `fixEncoderSize` and `fixDecoderSize` functions to separate your codec logic like so:\n *\n * ```ts\n * const get32BytesBase58Encoder = () => fixEncoderSize(getBase58Encoder(), 32);\n * const get32BytesBase58Decoder = () => fixDecoderSize(getBase58Decoder(), 32);\n * const get32BytesBase58Codec = () => combineCodec(get32BytesBase58Encoder(), get32BytesBase58Decoder());\n * ```\n *\n * ## Prefixing codecs with their size\n *\n * The `addCodecSizePrefix` function allows you to store the byte size of any codec as a number prefix. This allows you to contain variable-size codecs to their actual size.\n *\n * When encoding, the size of the encoded data is stored before the encoded data itself. When decoding, the size is read first to know how many bytes to read next.\n *\n * For example, say we want to represent a variable-size base-58 string using a `u32` size prefix. Here’s how you can use the `addCodecSizePrefix` function to achieve that.\n *\n * ```ts\n * const getU32Base58Codec = () => addCodecSizePrefix(getBase58Codec(), getU32Codec());\n *\n * getU32Base58Codec().encode('hello world');\n * // 0x0b00000068656c6c6f20776f726c64\n * //   |       └-- Our encoded base-58 string.\n * //   └-- Our encoded u32 size prefix.\n * ```\n *\n * You may also use the `addEncoderSizePrefix` and `addDecoderSizePrefix` functions to separate your codec logic like so:\n *\n * ```ts\n * const getU32Base58Encoder = () => addEncoderSizePrefix(getBase58Encoder(), getU32Encoder());\n * const getU32Base58Decoder = () => addDecoderSizePrefix(getBase58Decoder(), getU32Decoder());\n * const getU32Base58Codec = () => combineCodec(getU32Base58Encoder(), getU32Base58Decoder());\n * ```\n *\n * ## Adding sentinels to codecs\n *\n * Another way of delimiting the size of a codec is to use sentinels. The `addCodecSentinel` function allows us to add a sentinel to the end of the encoded data and to read until that sentinel is found when decoding. It accepts any codec and a `Uint8Array` sentinel responsible for delimiting the encoded data.\n *\n * ```ts\n * const codec = addCodecSentinel(getUtf8Codec(), new Uint8Array([255, 255]));\n * codec.encode('hello');\n * // 0x68656c6c6fffff\n * //   |        └-- Our sentinel.\n * //   └-- Our encoded string.\n * ```\n *\n * Note that the sentinel _must not_ be present in the encoded data and _must_ be present in the decoded data for this to work. If this is not the case, dedicated errors will be thrown.\n *\n * ```ts\n * const sentinel = new Uint8Array([108, 108]); // 'll'\n * const codec = addCodecSentinel(getUtf8Codec(), sentinel);\n *\n * codec.encode('hello'); // Throws: sentinel is in encoded data.\n * codec.decode(new Uint8Array([1, 2, 3])); // Throws: sentinel missing in decoded data.\n * ```\n *\n * Separate `addEncoderSentinel` and `addDecoderSentinel` functions are also available.\n *\n * ```ts\n * const bytes = addEncoderSentinel(getUtf8Encoder(), sentinel).encode('hello');\n * const value = addDecoderSentinel(getUtf8Decoder(), sentinel).decode(bytes);\n * ```\n *\n * ## Adjusting the size of codecs\n *\n * The `resizeCodec` helper re-defines the size of a given codec by accepting a function that takes the current size of the codec and returns a new size. This works for both fixed-size and variable-size codecs.\n *\n * ```ts\n * // Fixed-size codec.\n * const getBiggerU32Codec = () => resizeCodec(getU32Codec(), size => size + 4);\n * getBiggerU32Codec().encode(42);\n * // 0x2a00000000000000\n * //   |       └-- Empty buffer space caused by the resizeCodec function.\n * //   └-- Our encoded u32 number.\n *\n * // Variable-size codec.\n * const getBiggerUtf8Codec = () => resizeCodec(getUtf8Codec(), size => size + 4);\n * getBiggerUtf8Codec().encode('ABC');\n * // 0x41424300000000\n * //   |     └-- Empty buffer space caused by the resizeCodec function.\n * //   └-- Our encoded string.\n * ```\n *\n * Note that the `resizeCodec` function doesn't change any encoded or decoded bytes, it merely tells the `encode` and `decode` functions how big the `Uint8Array` should be before delegating to their respective `write` and `read` functions. In fact, this is completely bypassed when using the `write` and `read` functions directly. For instance:\n *\n * ```ts\n * const getBiggerU32Codec = () => resizeCodec(getU32Codec(), size => size + 4);\n *\n * // Using the encode function.\n * getBiggerU32Codec().encode(42);\n * // 0x2a00000000000000\n *\n * // Using the lower-level write function.\n * const myCustomBytes = new Uint8Array(4);\n * getBiggerU32Codec().write(42, myCustomBytes, 0);\n * // 0x2a000000\n * ```\n *\n * So when would it make sense to use the `resizeCodec` function? This function is particularly useful when combined with the `offsetCodec` function described below. Whilst the `offsetCodec` may help us push the offset forward — e.g. to skip some padding — it won't change the size of the encoded data which means the last bytes will be truncated by how much we pushed the offset forward. The `resizeCodec` function can be used to fix that. For instance, here's how we can use the `resizeCodec` and the `offsetCodec` functions together to create a struct codec that includes some padding.\n *\n * ```ts\n * const personCodec = getStructCodec([\n *     ['name', fixCodecSize(getUtf8Codec(), 8)],\n *     // There is a 4-byte padding between name and age.\n *     [\n *         'age',\n *         offsetCodec(\n *             resizeCodec(getU32Codec(), size => size + 4),\n *             { preOffset: ({ preOffset }) => preOffset + 4 },\n *         ),\n *     ],\n * ]);\n *\n * personCodec.encode({ name: 'Alice', age: 42 });\n * // 0x416c696365000000000000002a000000\n * //   |               |       └-- Our encoded u32 (42).\n * //   |               └-- The 4-bytes of padding we are skipping.\n * //   └-- Our 8-byte encoded string (\"Alice\").\n * ```\n *\n * As usual, the `resizeEncoder` and `resizeDecoder` functions can also be used to achieve that.\n *\n * ```ts\n * const getBiggerU32Encoder = () => resizeEncoder(getU32Codec(), size => size + 4);\n * const getBiggerU32Decoder = () => resizeDecoder(getU32Codec(), size => size + 4);\n * const getBiggerU32Codec = () => combineCodec(getBiggerU32Encoder(), getBiggerU32Decoder());\n * ```\n *\n * ## Offsetting codecs\n *\n * The `offsetCodec` function is a powerful codec primitive that allows you to move the offset of a given codec forward or backwards. It accepts one or two functions that takes the current offset and returns a new offset.\n *\n * To understand how this works, let's take our previous `biggerU32Codec` example which encodes a `u32` number inside an 8-byte buffer.\n *\n * ```ts\n * const biggerU32Codec = resizeCodec(getU32Codec(), size => size + 4);\n * biggerU32Codec.encode(0xffffffff);\n * // 0xffffffff00000000\n * //   |       └-- Empty buffer space caused by the resizeCodec function.\n * //   └-- Our encoded u32 number.\n * ```\n *\n * Now, let's say we want to move the offset of that codec 2 bytes forward so that the encoded number sits in the middle of the buffer. To achieve, this we can use the `offsetCodec` helper and provide a `preOffset` function that moves the \"pre-offset\" of the codec 2 bytes forward.\n *\n * ```ts\n * const u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n *     preOffset: ({ preOffset }) => preOffset + 2,\n * });\n * u32InTheMiddleCodec.encode(0xffffffff);\n * // 0x0000ffffffff0000\n * //       └-- Our encoded u32 number is now in the middle of the buffer.\n * ```\n *\n * We refer to this offset as the \"pre-offset\" because, once the inner codec is encoded or decoded, an additional offset will be returned which we refer to as the \"post-offset\". That \"post-offset\" is important as, unless we are reaching the end of our codec, it will be used by any further codecs to continue encoding or decoding data.\n *\n * By default, that \"post-offset\" is simply the addition of the \"pre-offset\" and the size of the encoded or decoded inner data.\n *\n * ```ts\n * const u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n *     preOffset: ({ preOffset }) => preOffset + 2,\n * });\n * u32InTheMiddleCodec.encode(0xffffffff);\n * // 0x0000ffffffff0000\n * //   |   |       └-- Post-offset.\n * //   |   └-- New pre-offset: The original pre-offset + 2.\n * //   └-- Pre-offset: The original pre-offset before we adjusted it.\n * ```\n *\n * However, you may also provide a `postOffset` function to adjust the \"post-offset\". For instance, let's push the \"post-offset\" 2 bytes forward as well such that any further codecs will start doing their job at the end of our 8-byte `u32` number.\n *\n * ```ts\n * const u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n *     preOffset: ({ preOffset }) => preOffset + 2,\n *     postOffset: ({ postOffset }) => postOffset + 2,\n * });\n * u32InTheMiddleCodec.encode(0xffffffff);\n * // 0x0000ffffffff0000\n * //   |   |       |   └-- New post-offset: The original post-offset + 2.\n * //   |   |       └-- Post-offset: The original post-offset before we adjusted it.\n * //   |   └-- New pre-offset: The original pre-offset + 2.\n * //   └-- Pre-offset: The original pre-offset before we adjusted it.\n * ```\n *\n * Both the `preOffset` and `postOffset` functions offer the following attributes:\n *\n * - `bytes`: The entire byte array being encoded or decoded.\n * - `preOffset`: The original and unaltered pre-offset.\n * - `wrapBytes`: A helper function that wraps the given offset around the byte array length. E.g. `wrapBytes(-1)` will refer to the last byte of the byte array.\n *\n * Additionally, the post-offset function also provides the following attributes:\n *\n * - `newPreOffset`: The new pre-offset after the pre-offset function has been applied.\n * - `postOffset`: The original and unaltered post-offset.\n *\n * Note that you may also decide to ignore these attributes to achieve absolute offsets. However, relative offsets are usually recommended as they won't break your codecs when composed with other codecs.\n *\n * ```ts\n * const u32InTheMiddleCodec = offsetCodec(biggerU32Codec, {\n *     preOffset: () => 2,\n *     postOffset: () => 8,\n * });\n * u32InTheMiddleCodec.encode(0xffffffff);\n * // 0x0000ffffffff0000\n * ```\n *\n * Also note that any negative offset or offset that exceeds the size of the byte array will throw a `SolanaError` of code `SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE`.\n *\n * ```ts\n * const u32InTheEndCodec = offsetCodec(biggerU32Codec, { preOffset: () => -4 });\n * u32InTheEndCodec.encode(0xffffffff);\n * // throws new SolanaError(SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE)\n * ```\n *\n * To avoid this, you may use the `wrapBytes` function to wrap the offset around the byte array length. For instance, here's how we can use the `wrapBytes` function to move the pre-offset 4 bytes from the end of the byte array.\n *\n * ```ts\n * const u32InTheEndCodec = offsetCodec(biggerU32Codec, {\n *     preOffset: ({ wrapBytes }) => wrapBytes(-4),\n * });\n * u32InTheEndCodec.encode(0xffffffff);\n * // 0x00000000ffffffff\n * ```\n *\n * As you can see, the `offsetCodec` helper allows you to jump all over the place with your codecs. This non-linear approach to encoding and decoding data allows you to achieve complex serialization strategies that would otherwise be impossible.\n *\n * As usual, the `offsetEncoder` and `offsetDecoder` functions can also be used to split your codec logic into tree-shakeable functions.\n *\n * ```ts\n * const getU32InTheMiddleEncoder = () => offsetEncoder(biggerU32Encoder, { preOffset: ({ preOffset }) => preOffset + 2 });\n * const getU32InTheMiddleDecoder = () => offsetDecoder(biggerU32Decoder, { preOffset: ({ preOffset }) => preOffset + 2 });\n * const getU32InTheMiddleCodec = () => combineCodec(getU32InTheMiddleEncoder(), getU32InTheMiddleDecoder());\n * ```\n *\n * ## Padding codecs\n *\n * The `padLeftCodec` and `padRightCodec` helpers can be used to add padding to the left or right of a given codec. They accept an `offset` number that tells us how big the padding should be.\n *\n * ```ts\n * const getLeftPaddedCodec = () => padLeftCodec(getU16Codec(), 4);\n * getLeftPaddedCodec().encode(0xffff);\n * // 0x00000000ffff\n * //   |       └-- Our encoded u16 number.\n * //   └-- Our 4-byte padding.\n *\n * const getRightPaddedCodec = () => padRightCodec(getU16Codec(), 4);\n * getRightPaddedCodec().encode(0xffff);\n * // 0xffff00000000\n * //   |   └-- Our 4-byte padding.\n * //   └-- Our encoded u16 number.\n * ```\n *\n * Note that both the `padLeftCodec` and `padRightCodec` functions are simple wrappers around the `offsetCodec` and `resizeCodec` functions. For more complex padding strategies, you may want to use the `offsetCodec` and `resizeCodec` functions directly instead.\n *\n * As usual, encoder-only and decoder-only helpers are available for these padding functions. Namely, `padLeftEncoder`, `padRightEncoder`, `padLeftDecoder` and `padRightDecoder`.\n *\n * ```ts\n * const getMyPaddedEncoder = () => padLeftEncoder(getU16Encoder());\n * const getMyPaddedDecoder = () => padLeftDecoder(getU16Decoder());\n * const getMyPaddedCodec = () => combineCodec(getMyPaddedEncoder(), getMyPaddedDecoder());\n * ```\n *\n * ## Reversing codecs\n *\n * The `reverseCodec` helper reverses the bytes of the provided `FixedSizeCodec`.\n *\n * ```ts\n * const getBigEndianU64Codec = () => reverseCodec(getU64Codec());\n * ```\n *\n * Note that number codecs can already do that for you via their `endian` option.\n *\n * ```ts\n * const getBigEndianU64Codec = () => getU64Codec({ endian: Endian.Big });\n * ```\n *\n * As usual, the `reverseEncoder` and `reverseDecoder` functions can also be used to achieve that.\n *\n * ```ts\n * const getBigEndianU64Encoder = () => reverseEncoder(getU64Encoder());\n * const getBigEndianU64Decoder = () => reverseDecoder(getU64Decoder());\n * const getBigEndianU64Codec = () => combineCodec(getBigEndianU64Encoder(), getBigEndianU64Decoder());\n * ```\n *\n * ## Byte helpers\n *\n * This package also provides utility functions for managing bytes such as:\n *\n * - `mergeBytes`: Concatenates an array of `Uint8Arrays` into a single `Uint8Array`.\n * - `padBytes`: Pads a `Uint8Array` with zeroes (to the right) to the specified length.\n * - `fixBytes`: Pads or truncates a `Uint8Array` so it has the specified length.\n * - `containsBytes`: Checks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n *\n * ```ts\n * // Merge multiple Uint8Array buffers into one.\n * mergeBytes([new Uint8Array([1, 2]), new Uint8Array([3, 4])]); // Uint8Array([1, 2, 3, 4])\n *\n * // Pad a Uint8Array buffer to the given size.\n * padBytes(new Uint8Array([1, 2]), 4); // Uint8Array([1, 2, 0, 0])\n * padBytes(new Uint8Array([1, 2, 3, 4]), 2); // Uint8Array([1, 2, 3, 4])\n *\n * // Pad and truncate a Uint8Array buffer to the given size.\n * fixBytes(new Uint8Array([1, 2]), 4); // Uint8Array([1, 2, 0, 0])\n * fixBytes(new Uint8Array([1, 2, 3, 4]), 2); // Uint8Array([1, 2])\n *\n * // Check if a Uint8Array contains another Uint8Array at a given offset.\n * containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\n * containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n * ```\n *\n * ---\n *\n * To read more about the available codecs and how to use them, check out the documentation of the main [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs).\n *\n * @packageDocumentation\n */\nexport * from './add-codec-sentinel';\nexport * from './add-codec-size-prefix';\nexport * from './array-buffers';\nexport * from './assertions';\nexport * from './bytes';\nexport * from './codec';\nexport * from './combine-codec';\nexport * from './decoder-entire-byte-array';\nexport * from './fix-codec-size';\nexport * from './offset-codec';\nexport * from './pad-codec';\nexport * from './readonly-uint8array';\nexport * from './resize-codec';\nexport * from './reverse-codec';\nexport * from './transform-codec';\n"
  },
  {
    "path": "packages/codecs-core/src/offset-codec.ts",
    "content": "import { assertByteArrayOffsetIsNotOutOfRange } from './assertions';\nimport { Codec, createDecoder, createEncoder, Decoder, Encoder, Offset } from './codec';\nimport { combineCodec } from './combine-codec';\nimport { ReadonlyUint8Array } from './readonly-uint8array';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyEncoder = Encoder<any>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyDecoder = Decoder<any>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyCodec = Codec<any>;\n\n/**\n * Configuration object for modifying the offset of an encoder, decoder, or codec.\n *\n * This type defines optional functions for adjusting the **pre-offset** (before encoding/decoding)\n * and the **post-offset** (after encoding/decoding). These functions allow precise control\n * over where data is written or read within a byte array.\n *\n * @property preOffset - A function that modifies the offset before encoding or decoding.\n * @property postOffset - A function that modifies the offset after encoding or decoding.\n *\n * @example\n * Moving the pre-offset forward by 2 bytes.\n * ```ts\n * const config: OffsetConfig = {\n *     preOffset: ({ preOffset }) => preOffset + 2,\n * };\n * ```\n *\n * @example\n * Moving the post-offset forward by 2 bytes.\n * ```ts\n * const config: OffsetConfig = {\n *     postOffset: ({ postOffset }) => postOffset + 2,\n * };\n * ```\n *\n * @example\n * Using both pre-offset and post-offset together.\n * ```ts\n * const config: OffsetConfig = {\n *     preOffset: ({ preOffset }) => preOffset + 2,\n *     postOffset: ({ postOffset }) => postOffset + 4,\n * };\n * ```\n *\n * @see {@link offsetEncoder}\n * @see {@link offsetDecoder}\n * @see {@link offsetCodec}\n */\ntype OffsetConfig = {\n    postOffset?: PostOffsetFunction;\n    preOffset?: PreOffsetFunction;\n};\n\n/**\n * Scope provided to the `preOffset` and `postOffset` functions,\n * containing contextual information about the current encoding or decoding process.\n *\n * The pre-offset function modifies where encoding or decoding begins,\n * while the post-offset function modifies where the next operation continues.\n *\n * @property bytes - The entire byte array being encoded or decoded.\n * @property preOffset - The original offset before encoding or decoding starts.\n * @property wrapBytes - A helper function that wraps offsets around the byte array length.\n *\n * @example\n * Using `wrapBytes` to wrap a negative offset to the end of the byte array.\n * ```ts\n * const config: OffsetConfig = {\n *     preOffset: ({ wrapBytes }) => wrapBytes(-4), // Moves to last 4 bytes\n * };\n * ```\n *\n * @example\n * Adjusting the offset dynamically based on the byte array size.\n * ```ts\n * const config: OffsetConfig = {\n *     preOffset: ({ bytes }) => bytes.length > 10 ? 4 : 2,\n * };\n * ```\n *\n * @see {@link PreOffsetFunction}\n * @see {@link PostOffsetFunction}\n */\ntype PreOffsetFunctionScope = {\n    /** The entire byte array. */\n    bytes: ReadonlyUint8Array | Uint8Array;\n    /** The original offset prior to encode or decode. */\n    preOffset: Offset;\n    /** Wraps the offset to the byte array length. */\n    wrapBytes: (offset: Offset) => Offset;\n};\n\n/**\n * A function that modifies the pre-offset before encoding or decoding.\n *\n * This function is used to adjust the starting position before writing\n * or reading data in a byte array.\n *\n * @param scope - The current encoding or decoding context.\n * @returns The new offset at which encoding or decoding should start.\n *\n * @example\n * Skipping the first 2 bytes before writing or reading.\n * ```ts\n * const preOffset: PreOffsetFunction = ({ preOffset }) => preOffset + 2;\n * ```\n *\n * @example\n * Wrapping the offset to ensure it stays within bounds.\n * ```ts\n * const preOffset: PreOffsetFunction = ({ wrapBytes, preOffset }) => wrapBytes(preOffset + 10);\n * ```\n *\n * @see {@link OffsetConfig}\n * @see {@link PreOffsetFunctionScope}\n */\ntype PreOffsetFunction = (scope: PreOffsetFunctionScope) => Offset;\n\n/**\n * A function that modifies the post-offset after encoding or decoding.\n *\n * This function adjusts where the next encoder or decoder should start\n * after the current operation has completed.\n *\n * @param scope - The current encoding or decoding context, including the modified pre-offset\n * and the original post-offset.\n * @returns The new offset at which the next operation should begin.\n *\n * @example\n * Moving the post-offset forward by 4 bytes.\n * ```ts\n * const postOffset: PostOffsetFunction = ({ postOffset }) => postOffset + 4;\n * ```\n *\n * @example\n * Wrapping the post-offset within the byte array length.\n * ```ts\n * const postOffset: PostOffsetFunction = ({ wrapBytes, postOffset }) => wrapBytes(postOffset);\n * ```\n *\n * @example\n * Ensuring a minimum spacing of 8 bytes between values.\n * ```ts\n * const postOffset: PostOffsetFunction = ({ postOffset, newPreOffset }) =>\n *     Math.max(postOffset, newPreOffset + 8);\n * ```\n *\n * @see {@link OffsetConfig}\n * @see {@link PreOffsetFunctionScope}\n */\ntype PostOffsetFunction = (\n    scope: PreOffsetFunctionScope & {\n        /** The modified offset used to encode or decode. */\n        newPreOffset: Offset;\n        /** The original offset returned by the encoder or decoder. */\n        postOffset: Offset;\n    },\n) => Offset;\n\n/**\n * Moves the offset of a given encoder before and/or after encoding.\n *\n * This function allows an encoder to write its encoded value at a different offset\n * than the one originally provided. It supports both pre-offset adjustments\n * (before encoding) and post-offset adjustments (after encoding).\n *\n * The pre-offset function determines where encoding should start, while the\n * post-offset function adjusts where the next encoder should continue writing.\n *\n * For more details, see {@link offsetCodec}.\n *\n * @typeParam TFrom - The type of the value to encode.\n *\n * @param encoder - The encoder to adjust.\n * @param config - An object specifying how the offset should be modified.\n * @returns A new encoder with adjusted offsets.\n *\n * @example\n * Moving the pre-offset forward by 2 bytes.\n * ```ts\n * const encoder = offsetEncoder(getU32Encoder(), {\n *     preOffset: ({ preOffset }) => preOffset + 2,\n * });\n * const bytes = new Uint8Array(10);\n * encoder.write(42, bytes, 0); // Actually written at offset 2\n * ```\n *\n * @example\n * Moving the post-offset forward by 2 bytes.\n * ```ts\n * const encoder = offsetEncoder(getU32Encoder(), {\n *     postOffset: ({ postOffset }) => postOffset + 2,\n * });\n * const bytes = new Uint8Array(10);\n * const nextOffset = encoder.write(42, bytes, 0); // Next encoder starts at offset 6 instead of 4\n * ```\n *\n * @example\n * Using `wrapBytes` to ensure an offset wraps around the byte array length.\n * ```ts\n * const encoder = offsetEncoder(getU32Encoder(), {\n *     preOffset: ({ wrapBytes }) => wrapBytes(-4), // Moves offset to last 4 bytes of the array\n * });\n * const bytes = new Uint8Array(10);\n * encoder.write(42, bytes, 0); // Writes at bytes.length - 4\n * ```\n *\n * @remarks\n * If you need both encoding and decoding offsets to be adjusted, use {@link offsetCodec}.\n *\n * @see {@link offsetCodec}\n * @see {@link offsetDecoder}\n */\nexport function offsetEncoder<TEncoder extends AnyEncoder>(encoder: TEncoder, config: OffsetConfig): TEncoder {\n    return createEncoder({\n        ...encoder,\n        write: (value, bytes, preOffset) => {\n            const wrapBytes = (offset: Offset) => modulo(offset, bytes.length);\n            const newPreOffset = config.preOffset ? config.preOffset({ bytes, preOffset, wrapBytes }) : preOffset;\n            assertByteArrayOffsetIsNotOutOfRange('offsetEncoder', newPreOffset, bytes.length);\n            const postOffset = encoder.write(value, bytes, newPreOffset);\n            const newPostOffset = config.postOffset\n                ? config.postOffset({ bytes, newPreOffset, postOffset, preOffset, wrapBytes })\n                : postOffset;\n            assertByteArrayOffsetIsNotOutOfRange('offsetEncoder', newPostOffset, bytes.length);\n            return newPostOffset;\n        },\n    }) as TEncoder;\n}\n\n/**\n * Moves the offset of a given decoder before and/or after decoding.\n *\n * This function allows a decoder to read its input from a different offset\n * than the one originally provided. It supports both pre-offset adjustments\n * (before decoding) and post-offset adjustments (after decoding).\n *\n * The pre-offset function determines where decoding should start, while the\n * post-offset function adjusts where the next decoder should continue reading.\n *\n * For more details, see {@link offsetCodec}.\n *\n * @typeParam TTo - The type of the decoded value.\n *\n * @param decoder - The decoder to adjust.\n * @param config - An object specifying how the offset should be modified.\n * @returns A new decoder with adjusted offsets.\n *\n * @example\n * Moving the pre-offset forward by 2 bytes.\n * ```ts\n * const decoder = offsetDecoder(getU32Decoder(), {\n *     preOffset: ({ preOffset }) => preOffset + 2,\n * });\n * const bytes = new Uint8Array([0, 0, 42, 0]); // Value starts at offset 2\n * decoder.read(bytes, 0); // Actually reads from offset 2\n * ```\n *\n * @example\n * Moving the post-offset forward by 2 bytes.\n * ```ts\n * const decoder = offsetDecoder(getU32Decoder(), {\n *     postOffset: ({ postOffset }) => postOffset + 2,\n * });\n * const bytes = new Uint8Array([42, 0, 0, 0]);\n * const [value, nextOffset] = decoder.read(bytes, 0); // Next decoder starts at offset 6 instead of 4\n * ```\n *\n * @example\n * Using `wrapBytes` to read from the last 4 bytes of an array.\n * ```ts\n * const decoder = offsetDecoder(getU32Decoder(), {\n *     preOffset: ({ wrapBytes }) => wrapBytes(-4), // Moves offset to last 4 bytes of the array\n * });\n * const bytes = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 42]); // Value stored at the last 4 bytes\n * decoder.read(bytes, 0); // Reads from bytes.length - 4\n * ```\n *\n * @remarks\n * If you need both encoding and decoding offsets to be adjusted, use {@link offsetCodec}.\n *\n * @see {@link offsetCodec}\n * @see {@link offsetEncoder}\n */\nexport function offsetDecoder<TDecoder extends AnyDecoder>(decoder: TDecoder, config: OffsetConfig): TDecoder {\n    return createDecoder({\n        ...decoder,\n        read: (bytes, preOffset) => {\n            const wrapBytes = (offset: Offset) => modulo(offset, bytes.length);\n            const newPreOffset = config.preOffset ? config.preOffset({ bytes, preOffset, wrapBytes }) : preOffset;\n            assertByteArrayOffsetIsNotOutOfRange('offsetDecoder', newPreOffset, bytes.length);\n            const [value, postOffset] = decoder.read(bytes, newPreOffset);\n            const newPostOffset = config.postOffset\n                ? config.postOffset({ bytes, newPreOffset, postOffset, preOffset, wrapBytes })\n                : postOffset;\n            assertByteArrayOffsetIsNotOutOfRange('offsetDecoder', newPostOffset, bytes.length);\n            return [value, newPostOffset];\n        },\n    }) as TDecoder;\n}\n\n/**\n * Moves the offset of a given codec before and/or after encoding and decoding.\n *\n * This function allows a codec to encode and decode values at custom offsets\n * within a byte array. It modifies both the **pre-offset** (where encoding/decoding starts)\n * and the **post-offset** (where the next operation should continue).\n *\n * This is particularly useful when working with structured binary formats\n * that require skipping reserved bytes, inserting padding, or aligning fields at\n * specific locations.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n *\n * @param codec - The codec to adjust.\n * @param config - An object specifying how the offset should be modified.\n * @returns A new codec with adjusted offsets.\n *\n * @example\n * Moving the pre-offset forward by 2 bytes when encoding and decoding.\n * ```ts\n * const codec = offsetCodec(getU32Codec(), {\n *     preOffset: ({ preOffset }) => preOffset + 2,\n * });\n * const bytes = new Uint8Array(10);\n * codec.write(42, bytes, 0); // Actually written at offset 2\n * codec.read(bytes, 0);      // Actually read from offset 2\n * ```\n *\n * @example\n * Moving the post-offset forward by 2 bytes when encoding and decoding.\n * ```ts\n * const codec = offsetCodec(getU32Codec(), {\n *     postOffset: ({ postOffset }) => postOffset + 2,\n * });\n * const bytes = new Uint8Array(10);\n * codec.write(42, bytes, 0);\n * // Next encoding starts at offset 6 instead of 4\n * codec.read(bytes, 0);\n * // Next decoding starts at offset 6 instead of 4\n * ```\n *\n * @example\n * Using `wrapBytes` to loop around negative offsets.\n * ```ts\n * const codec = offsetCodec(getU32Codec(), {\n *     preOffset: ({ wrapBytes }) => wrapBytes(-4), // Moves offset to last 4 bytes\n * });\n * const bytes = new Uint8Array(10);\n * codec.write(42, bytes, 0); // Writes at bytes.length - 4\n * codec.read(bytes, 0); // Reads from bytes.length - 4\n * ```\n *\n * @remarks\n * If you only need to adjust offsets for encoding, use {@link offsetEncoder}.\n * If you only need to adjust offsets for decoding, use {@link offsetDecoder}.\n *\n * ```ts\n * const bytes = new Uint8Array(10);\n * offsetEncoder(getU32Encoder(), { preOffset: ({ preOffset }) => preOffset + 2 }).write(42, bytes, 0);\n * const [value] = offsetDecoder(getU32Decoder(), { preOffset: ({ preOffset }) => preOffset + 2 }).read(bytes, 0);\n * ```\n *\n * @see {@link offsetEncoder}\n * @see {@link offsetDecoder}\n */\nexport function offsetCodec<TCodec extends AnyCodec>(codec: TCodec, config: OffsetConfig): TCodec {\n    return combineCodec(offsetEncoder(codec, config), offsetDecoder(codec, config)) as TCodec;\n}\n\n/** A modulo function that handles negative dividends and zero divisors. */\nfunction modulo(dividend: number, divisor: number) {\n    if (divisor === 0) return 0;\n    return ((dividend % divisor) + divisor) % divisor;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/pad-codec.ts",
    "content": "import { Codec, Decoder, Encoder, Offset } from './codec';\nimport { combineCodec } from './combine-codec';\nimport { offsetDecoder, offsetEncoder } from './offset-codec';\nimport { resizeDecoder, resizeEncoder } from './resize-codec';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyEncoder = Encoder<any>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyDecoder = Decoder<any>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyCodec = Codec<any>;\n\n/**\n * Adds left padding to the given encoder, shifting the encoded value forward\n * by `offset` bytes whilst increasing the size of the encoder accordingly.\n *\n * For more details, see {@link padLeftCodec}.\n *\n * @typeParam TFrom - The type of the value to encode.\n *\n * @param encoder - The encoder to pad.\n * @param offset - The number of padding bytes to add before encoding.\n * @returns A new encoder with left padding applied.\n *\n * @example\n * ```ts\n * const encoder = padLeftEncoder(getU16Encoder(), 2);\n * const bytes = encoder.encode(0xffff); // 0x0000ffff (0xffff written at offset 2)\n * ```\n *\n * @see {@link padLeftCodec}\n * @see {@link padLeftDecoder}\n */\nexport function padLeftEncoder<TEncoder extends AnyEncoder>(encoder: TEncoder, offset: Offset): TEncoder {\n    return offsetEncoder(\n        resizeEncoder(encoder, size => size + offset),\n        { preOffset: ({ preOffset }) => preOffset + offset },\n    );\n}\n\n/**\n * Adds right padding to the given encoder, extending the encoded value by `offset`\n * bytes whilst increasing the size of the encoder accordingly.\n *\n * For more details, see {@link padRightCodec}.\n *\n * @typeParam TFrom - The type of the value to encode.\n *\n * @param encoder - The encoder to pad.\n * @param offset - The number of padding bytes to add after encoding.\n * @returns A new encoder with right padding applied.\n *\n * @example\n * ```ts\n * const encoder = padRightEncoder(getU16Encoder(), 2);\n * const bytes = encoder.encode(0xffff); // 0xffff0000 (two extra bytes added at the end)\n * ```\n *\n * @see {@link padRightCodec}\n * @see {@link padRightDecoder}\n */\nexport function padRightEncoder<TEncoder extends AnyEncoder>(encoder: TEncoder, offset: Offset): TEncoder {\n    return offsetEncoder(\n        resizeEncoder(encoder, size => size + offset),\n        { postOffset: ({ postOffset }) => postOffset + offset },\n    );\n}\n\n/**\n * Adds left padding to the given decoder, shifting the decoding position forward\n * by `offset` bytes whilst increasing the size of the decoder accordingly.\n *\n * For more details, see {@link padLeftCodec}.\n *\n * @typeParam TTo - The type of the decoded value.\n *\n * @param decoder - The decoder to pad.\n * @param offset - The number of padding bytes to skip before decoding.\n * @returns A new decoder with left padding applied.\n *\n * @example\n * ```ts\n * const decoder = padLeftDecoder(getU16Decoder(), 2);\n * const value = decoder.decode(new Uint8Array([0, 0, 0x12, 0x34])); // 0xffff (reads from offset 2)\n * ```\n *\n * @see {@link padLeftCodec}\n * @see {@link padLeftEncoder}\n */\nexport function padLeftDecoder<TDecoder extends AnyDecoder>(decoder: TDecoder, offset: Offset): TDecoder {\n    return offsetDecoder(\n        resizeDecoder(decoder, size => size + offset),\n        { preOffset: ({ preOffset }) => preOffset + offset },\n    );\n}\n\n/**\n * Adds right padding to the given decoder, extending the post-offset by `offset`\n * bytes whilst increasing the size of the decoder accordingly.\n *\n * For more details, see {@link padRightCodec}.\n *\n * @typeParam TTo - The type of the decoded value.\n *\n * @param decoder - The decoder to pad.\n * @param offset - The number of padding bytes to skip after decoding.\n * @returns A new decoder with right padding applied.\n *\n * @example\n * ```ts\n * const decoder = padRightDecoder(getU16Decoder(), 2);\n * const value = decoder.decode(new Uint8Array([0x12, 0x34, 0, 0])); // 0xffff (ignores trailing bytes)\n * ```\n *\n * @see {@link padRightCodec}\n * @see {@link padRightEncoder}\n */\nexport function padRightDecoder<TDecoder extends AnyDecoder>(decoder: TDecoder, offset: Offset): TDecoder {\n    return offsetDecoder(\n        resizeDecoder(decoder, size => size + offset),\n        { postOffset: ({ postOffset }) => postOffset + offset },\n    );\n}\n\n/**\n * Adds left padding to the given codec, shifting the encoding and decoding positions\n * forward by `offset` bytes whilst increasing the size of the codec accordingly.\n *\n * This ensures that values are read and written at a later position in the byte array,\n * while the padding bytes remain unused.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n *\n * @param codec - The codec to pad.\n * @param offset - The number of padding bytes to add before encoding and decoding.\n * @returns A new codec with left padding applied.\n *\n * @example\n * ```ts\n * const codec = padLeftCodec(getU16Codec(), 2);\n * const bytes = codec.encode(0xffff); // 0x0000ffff (0xffff written at offset 2)\n * const value = codec.decode(bytes);  // 0xffff (reads from offset 2)\n * ```\n *\n * @remarks\n * If you only need to apply padding for encoding, use {@link padLeftEncoder}.\n * If you only need to apply padding for decoding, use {@link padLeftDecoder}.\n *\n * ```ts\n * const bytes = padLeftEncoder(getU16Encoder(), 2).encode(0xffff);\n * const value = padLeftDecoder(getU16Decoder(), 2).decode(bytes);\n * ```\n *\n * @see {@link padLeftEncoder}\n * @see {@link padLeftDecoder}\n */\nexport function padLeftCodec<TCodec extends AnyCodec>(codec: TCodec, offset: Offset): TCodec {\n    return combineCodec(padLeftEncoder(codec, offset), padLeftDecoder(codec, offset)) as TCodec;\n}\n\n/**\n * Adds right padding to the given codec, extending the encoded and decoded value\n * by `offset` bytes whilst increasing the size of the codec accordingly.\n *\n * The extra bytes remain unused, ensuring that the next operation starts further\n * along the byte array.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n *\n * @param codec - The codec to pad.\n * @param offset - The number of padding bytes to add after encoding and decoding.\n * @returns A new codec with right padding applied.\n *\n * @example\n * ```ts\n * const codec = padRightCodec(getU16Codec(), 2);\n * const bytes = codec.encode(0xffff); // 0xffff0000 (two extra bytes added)\n * const value = codec.decode(bytes);  // 0xffff (ignores padding bytes)\n * ```\n *\n * @remarks\n * If you only need to apply padding for encoding, use {@link padRightEncoder}.\n * If you only need to apply padding for decoding, use {@link padRightDecoder}.\n *\n * ```ts\n * const bytes = padRightEncoder(getU16Encoder(), 2).encode(0xffff);\n * const value = padRightDecoder(getU16Decoder(), 2).decode(bytes);\n * ```\n *\n * @see {@link padRightEncoder}\n * @see {@link padRightDecoder}\n */\nexport function padRightCodec<TCodec extends AnyCodec>(codec: TCodec, offset: Offset): TCodec {\n    return combineCodec(padRightEncoder(codec, offset), padRightDecoder(codec, offset)) as TCodec;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/readonly-uint8array.ts",
    "content": "/**\n * A read-only variant of `Uint8Array`.\n *\n * This type prevents modifications to the array by omitting mutable methods such as `copyWithin`,\n * `fill`, `reverse`, `set`, and `sort`, while still allowing indexed access to elements.\n *\n * @example\n * ```ts\n * const bytes: ReadonlyUint8Array = new Uint8Array([1, 2, 3]);\n * console.log(bytes[0]); // 1\n * bytes[0] = 42; // Type error: Cannot assign to '0' because it is a read-only property.\n * ```\n */\nexport interface ReadonlyUint8Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> extends Omit<\n    Uint8Array<TArrayBuffer>,\n    TypedArrayMutableProperties\n> {\n    readonly [n: number]: number;\n}\n\ntype TypedArrayMutableProperties = 'copyWithin' | 'fill' | 'reverse' | 'set' | 'sort';\n"
  },
  {
    "path": "packages/codecs-core/src/resize-codec.ts",
    "content": "import { SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport {\n    Codec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    isFixedSize,\n} from './codec';\nimport { combineCodec } from './combine-codec';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyEncoder = Encoder<any>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyDecoder = Decoder<any>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyCodec = Codec<any>;\n\n/**\n * Updates the size of a given encoder.\n *\n * This function modifies the size of an encoder using a provided transformation function.\n * For fixed-size encoders, it updates the `fixedSize` property, and for variable-size\n * encoders, it adjusts the size calculation based on the encoded value.\n *\n * If the new size is negative, an error will be thrown.\n *\n * For more details, see {@link resizeCodec}.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TSize - The original fixed size of the encoded value.\n * @typeParam TNewSize - The new fixed size after resizing.\n *\n * @param encoder - The encoder whose size will be updated.\n * @param resize - A function that takes the current size and returns the new size.\n * @returns A new encoder with the updated size.\n *\n * @example\n * Increasing the size of a `u16` encoder by 2 bytes.\n * ```ts\n * const encoder = resizeEncoder(getU16Encoder(), size => size + 2);\n * encoder.encode(0xffff); // 0xffff0000 (two extra bytes added)\n * ```\n *\n * @example\n * Shrinking a `u32` encoder to only use 2 bytes.\n * ```ts\n * const encoder = resizeEncoder(getU32Encoder(), () => 2);\n * encoder.fixedSize; // 2\n * ```\n *\n * @see {@link resizeCodec}\n * @see {@link resizeDecoder}\n */\nexport function resizeEncoder<TFrom, TSize extends number, TNewSize extends number>(\n    encoder: FixedSizeEncoder<TFrom, TSize>,\n    resize: (size: TSize) => TNewSize,\n): FixedSizeEncoder<TFrom, TNewSize>;\nexport function resizeEncoder<TEncoder extends AnyEncoder>(\n    encoder: TEncoder,\n    resize: (size: number) => number,\n): TEncoder;\nexport function resizeEncoder<TEncoder extends AnyEncoder>(\n    encoder: TEncoder,\n    resize: (size: number) => number,\n): TEncoder {\n    if (isFixedSize(encoder)) {\n        const fixedSize = resize(encoder.fixedSize);\n        if (fixedSize < 0) {\n            throw new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH, {\n                bytesLength: fixedSize,\n                codecDescription: 'resizeEncoder',\n            });\n        }\n        return createEncoder({ ...encoder, fixedSize }) as TEncoder;\n    }\n    return createEncoder({\n        ...encoder,\n        getSizeFromValue: value => {\n            const newSize = resize(encoder.getSizeFromValue(value));\n            if (newSize < 0) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH, {\n                    bytesLength: newSize,\n                    codecDescription: 'resizeEncoder',\n                });\n            }\n            return newSize;\n        },\n    }) as TEncoder;\n}\n\n/**\n * Updates the size of a given decoder.\n *\n * This function modifies the size of a decoder using a provided transformation function.\n * For fixed-size decoders, it updates the `fixedSize` property to reflect the new size.\n * Variable-size decoders remain unchanged, as their size is determined dynamically.\n *\n * If the new size is negative, an error will be thrown.\n *\n * For more details, see {@link resizeCodec}.\n *\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The original fixed size of the decoded value.\n * @typeParam TNewSize - The new fixed size after resizing.\n *\n * @param decoder - The decoder whose size will be updated.\n * @param resize - A function that takes the current size and returns the new size.\n * @returns A new decoder with the updated size.\n *\n * @example\n * Expanding a `u16` decoder to read 4 bytes instead of 2.\n * ```ts\n * const decoder = resizeDecoder(getU16Decoder(), size => size + 2);\n * decoder.fixedSize; // 4\n * ```\n *\n * @example\n * Shrinking a `u32` decoder to only read 2 bytes.\n * ```ts\n * const decoder = resizeDecoder(getU32Decoder(), () => 2);\n * decoder.fixedSize; // 2\n * ```\n *\n * @see {@link resizeCodec}\n * @see {@link resizeEncoder}\n */\nexport function resizeDecoder<TFrom, TSize extends number, TNewSize extends number>(\n    decoder: FixedSizeDecoder<TFrom, TSize>,\n    resize: (size: TSize) => TNewSize,\n): FixedSizeDecoder<TFrom, TNewSize>;\nexport function resizeDecoder<TDecoder extends AnyDecoder>(\n    decoder: TDecoder,\n    resize: (size: number) => number,\n): TDecoder;\nexport function resizeDecoder<TDecoder extends AnyDecoder>(\n    decoder: TDecoder,\n    resize: (size: number) => number,\n): TDecoder {\n    if (isFixedSize(decoder)) {\n        const fixedSize = resize(decoder.fixedSize);\n        if (fixedSize < 0) {\n            throw new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH, {\n                bytesLength: fixedSize,\n                codecDescription: 'resizeDecoder',\n            });\n        }\n        return createDecoder({ ...decoder, fixedSize }) as TDecoder;\n    }\n    return decoder;\n}\n\n/**\n * Updates the size of a given codec.\n *\n * This function modifies the size of both the codec using a provided\n * transformation function. It is useful for adjusting the allocated byte size for\n * encoding and decoding without altering the underlying data structure.\n *\n * If the new size is negative, an error will be thrown.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The original fixed size of the encoded/decoded value (for fixed-size codecs).\n * @typeParam TNewSize - The new fixed size after resizing (for fixed-size codecs).\n *\n * @param codec - The codec whose size will be updated.\n * @param resize - A function that takes the current size and returns the new size.\n * @returns A new codec with the updated size.\n *\n * @example\n * Expanding a `u16` codec from 2 to 4 bytes.\n * ```ts\n * const codec = resizeCodec(getU16Codec(), size => size + 2);\n * const bytes = codec.encode(0xffff); // 0xffff0000 (two extra bytes added)\n * const value = codec.decode(bytes);  // 0xffff (reads original two bytes)\n * ```\n *\n * @example\n * Shrinking a `u32` codec to only use 2 bytes.\n * ```ts\n * const codec = resizeCodec(getU32Codec(), () => 2);\n * codec.fixedSize; // 2\n * ```\n *\n * @remarks\n * If you only need to resize an encoder, use {@link resizeEncoder}.\n * If you only need to resize a decoder, use {@link resizeDecoder}.\n *\n * ```ts\n * const bytes = resizeEncoder(getU32Encoder(), (size) => size + 2).encode(0xffff);\n * const value = resizeDecoder(getU32Decoder(), (size) => size + 2).decode(bytes);\n * ```\n *\n * @see {@link resizeEncoder}\n * @see {@link resizeDecoder}\n */\nexport function resizeCodec<TFrom, TTo extends TFrom, TSize extends number, TNewSize extends number>(\n    codec: FixedSizeCodec<TFrom, TTo, TSize>,\n    resize: (size: TSize) => TNewSize,\n): FixedSizeCodec<TFrom, TTo, TNewSize>;\nexport function resizeCodec<TCodec extends AnyCodec>(codec: TCodec, resize: (size: number) => number): TCodec;\nexport function resizeCodec<TCodec extends AnyCodec>(codec: TCodec, resize: (size: number) => number): TCodec {\n    return combineCodec(resizeEncoder(codec, resize), resizeDecoder(codec, resize)) as TCodec;\n}\n"
  },
  {
    "path": "packages/codecs-core/src/reverse-codec.ts",
    "content": "import {\n    assertIsFixedSize,\n    createDecoder,\n    createEncoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n} from './codec';\nimport { combineCodec } from './combine-codec';\nimport { ReadonlyUint8Array } from './readonly-uint8array';\n\nfunction copySourceToTargetInReverse(\n    source: ReadonlyUint8Array,\n    target_WILL_MUTATE: Uint8Array,\n    sourceOffset: number,\n    sourceLength: number,\n    targetOffset: number = 0,\n) {\n    while (sourceOffset < --sourceLength) {\n        const leftValue = source[sourceOffset];\n        target_WILL_MUTATE[sourceOffset + targetOffset] = source[sourceLength];\n        target_WILL_MUTATE[sourceLength + targetOffset] = leftValue;\n        sourceOffset++;\n    }\n    if (sourceOffset === sourceLength) {\n        target_WILL_MUTATE[sourceOffset + targetOffset] = source[sourceOffset];\n    }\n}\n\n/**\n * Reverses the bytes of a fixed-size encoder.\n *\n * Given a `FixedSizeEncoder`, this function returns a new `FixedSizeEncoder` that\n * reverses the bytes within the fixed-size byte array when encoding.\n *\n * This can be useful to modify endianness or for other byte-order transformations.\n *\n * For more details, see {@link reverseCodec}.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TSize - The fixed size of the encoded value in bytes.\n *\n * @param encoder - The fixed-size encoder to reverse.\n * @returns A new encoder that writes bytes in reverse order.\n *\n * @example\n * Encoding a `u16` value in reverse order.\n * ```ts\n * const encoder = reverseEncoder(getU16Encoder({ endian: Endian.Big }));\n * const bytes = encoder.encode(0x1234); // 0x3412 (bytes are flipped)\n * ```\n *\n * @see {@link reverseCodec}\n * @see {@link reverseDecoder}\n */\nexport function reverseEncoder<TFrom, TSize extends number>(\n    encoder: FixedSizeEncoder<TFrom, TSize>,\n): FixedSizeEncoder<TFrom, TSize> {\n    assertIsFixedSize(encoder);\n    return createEncoder({\n        ...encoder,\n        write: (value: TFrom, bytes, offset) => {\n            const newOffset = encoder.write(value, bytes, offset);\n            copySourceToTargetInReverse(\n                bytes /* source */,\n                bytes /* target_WILL_MUTATE */,\n                offset /* sourceOffset */,\n                offset + encoder.fixedSize /* sourceLength */,\n            );\n            return newOffset;\n        },\n    });\n}\n\n/**\n * Reverses the bytes of a fixed-size decoder.\n *\n * Given a `FixedSizeDecoder`, this function returns a new `FixedSizeDecoder` that\n * reverses the bytes within the fixed-size byte array before decoding.\n *\n * This can be useful to modify endianness or for other byte-order transformations.\n *\n * For more details, see {@link reverseCodec}.\n *\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the decoded value in bytes.\n *\n * @param decoder - The fixed-size decoder to reverse.\n * @returns A new decoder that reads bytes in reverse order.\n *\n * @example\n * Decoding a reversed `u16` value.\n * ```ts\n * const decoder = reverseDecoder(getU16Decoder({ endian: Endian.Big }));\n * const value = decoder.decode(new Uint8Array([0x34, 0x12])); // 0x1234 (bytes are flipped back)\n * ```\n *\n * @see {@link reverseCodec}\n * @see {@link reverseEncoder}\n */\nexport function reverseDecoder<TTo, TSize extends number>(\n    decoder: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeDecoder<TTo, TSize> {\n    assertIsFixedSize(decoder);\n    return createDecoder({\n        ...decoder,\n        read: (bytes, offset) => {\n            const reversedBytes = bytes.slice();\n            copySourceToTargetInReverse(\n                bytes /* source */,\n                reversedBytes /* target_WILL_MUTATE */,\n                offset /* sourceOffset */,\n                offset + decoder.fixedSize /* sourceLength */,\n            );\n            return decoder.read(reversedBytes, offset);\n        },\n    });\n}\n\n/**\n * Reverses the bytes of a fixed-size codec.\n *\n * Given a `FixedSizeCodec`, this function returns a new `FixedSizeCodec` that\n * reverses the bytes within the fixed-size byte array during encoding and decoding.\n *\n * This can be useful to modify endianness or for other byte-order transformations.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the decoded value.\n * @typeParam TSize - The fixed size of the encoded/decoded value in bytes.\n *\n * @param codec - The fixed-size codec to reverse.\n * @returns A new codec that encodes and decodes bytes in reverse order.\n *\n * @example\n * Reversing a `u16` codec.\n * ```ts\n * const codec = reverseCodec(getU16Codec({ endian: Endian.Big }));\n * const bytes = codec.encode(0x1234); // 0x3412 (bytes are flipped)\n * const value = codec.decode(bytes);  // 0x1234 (bytes are flipped back)\n * ```\n *\n * @remarks\n * If you only need to reverse an encoder, use {@link reverseEncoder}.\n * If you only need to reverse a decoder, use {@link reverseDecoder}.\n *\n * ```ts\n * const bytes = reverseEncoder(getU16Encoder()).encode(0x1234);\n * const value = reverseDecoder(getU16Decoder()).decode(bytes);\n * ```\n *\n * @see {@link reverseEncoder}\n * @see {@link reverseDecoder}\n */\nexport function reverseCodec<TFrom, TTo extends TFrom, TSize extends number>(\n    codec: FixedSizeCodec<TFrom, TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize> {\n    return combineCodec(reverseEncoder(codec), reverseDecoder(codec));\n}\n"
  },
  {
    "path": "packages/codecs-core/src/transform-codec.ts",
    "content": "import {\n    Codec,\n    createCodec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    isVariableSize,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from './codec';\nimport { ReadonlyUint8Array } from './readonly-uint8array';\n\n/**\n * Transforms an encoder by mapping its input values.\n *\n * This function takes an existing `Encoder<A>` and returns an `Encoder<B>`, allowing values of type `B`\n * to be converted into values of type `A` before encoding. The transformation is applied via the `unmap` function.\n *\n * This is useful for handling type conversions, applying default values, or structuring data before encoding.\n *\n * For more details, see {@link transformCodec}.\n *\n * @typeParam TOldFrom - The original type expected by the encoder.\n * @typeParam TNewFrom - The new type that will be transformed before encoding.\n *\n * @param encoder - The encoder to transform.\n * @param unmap - A function that converts values of `TNewFrom` into `TOldFrom` before encoding.\n * @returns A new encoder that accepts `TNewFrom` values and transforms them before encoding.\n *\n * @example\n * Encoding a string by counting its characters and storing the length as a `u32`.\n * ```ts\n * const encoder = transformEncoder(getU32Encoder(), (value: string) => value.length);\n * encoder.encode(\"hello\"); // 0x05000000 (stores length 5)\n * ```\n *\n * @see {@link transformCodec}\n * @see {@link transformDecoder}\n */\nexport function transformEncoder<TOldFrom, TNewFrom, TSize extends number>(\n    encoder: FixedSizeEncoder<TOldFrom, TSize>,\n    unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeEncoder<TNewFrom, TSize>;\nexport function transformEncoder<TOldFrom, TNewFrom>(\n    encoder: VariableSizeEncoder<TOldFrom>,\n    unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeEncoder<TNewFrom>;\nexport function transformEncoder<TOldFrom, TNewFrom>(\n    encoder: Encoder<TOldFrom>,\n    unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom>;\nexport function transformEncoder<TOldFrom, TNewFrom>(\n    encoder: Encoder<TOldFrom>,\n    unmap: (value: TNewFrom) => TOldFrom,\n): Encoder<TNewFrom> {\n    return createEncoder({\n        ...(isVariableSize(encoder)\n            ? { ...encoder, getSizeFromValue: (value: TNewFrom) => encoder.getSizeFromValue(unmap(value)) }\n            : encoder),\n        write: (value: TNewFrom, bytes, offset) => encoder.write(unmap(value), bytes, offset),\n    });\n}\n\n/**\n * Transforms a decoder by mapping its output values.\n *\n * This function takes an existing `Decoder<A>` and returns a `Decoder<B>`, allowing values of type `A`\n * to be converted into values of type `B` after decoding. The transformation is applied via the `map` function.\n *\n * This is useful for post-processing, type conversions, or enriching decoded data.\n *\n * For more details, see {@link transformCodec}.\n *\n * @typeParam TOldTo - The original type returned by the decoder.\n * @typeParam TNewTo - The new type that will be transformed after decoding.\n *\n * @param decoder - The decoder to transform.\n * @param map - A function that converts values of `TOldTo` into `TNewTo` after decoding.\n * @returns A new decoder that decodes into `TNewTo`.\n *\n * @example\n * Decoding a stored `u32` length into a string of `'x'` characters.\n * ```ts\n * const decoder = transformDecoder(getU32Decoder(), (length) => 'x'.repeat(length));\n * decoder.decode(new Uint8Array([0x05, 0x00, 0x00, 0x00])); // \"xxxxx\"\n * ```\n *\n * @see {@link transformCodec}\n * @see {@link transformEncoder}\n */\nexport function transformDecoder<TOldTo, TNewTo, TSize extends number>(\n    decoder: FixedSizeDecoder<TOldTo, TSize>,\n    map: (value: TOldTo, bytes: ReadonlyUint8Array | Uint8Array, offset: number) => TNewTo,\n): FixedSizeDecoder<TNewTo, TSize>;\nexport function transformDecoder<TOldTo, TNewTo>(\n    decoder: VariableSizeDecoder<TOldTo>,\n    map: (value: TOldTo, bytes: ReadonlyUint8Array | Uint8Array, offset: number) => TNewTo,\n): VariableSizeDecoder<TNewTo>;\nexport function transformDecoder<TOldTo, TNewTo>(\n    decoder: Decoder<TOldTo>,\n    map: (value: TOldTo, bytes: ReadonlyUint8Array | Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo>;\nexport function transformDecoder<TOldTo, TNewTo>(\n    decoder: Decoder<TOldTo>,\n    map: (value: TOldTo, bytes: ReadonlyUint8Array | Uint8Array, offset: number) => TNewTo,\n): Decoder<TNewTo> {\n    return createDecoder({\n        ...decoder,\n        read: (bytes: ReadonlyUint8Array | Uint8Array, offset) => {\n            const [value, newOffset] = decoder.read(bytes, offset);\n            return [map(value, bytes, offset), newOffset];\n        },\n    });\n}\n\n/**\n * Transforms a codec by mapping its input and output values.\n *\n * This function takes an existing `Codec<A, B>` and returns a `Codec<C, D>`, allowing:\n * - Values of type `C` to be transformed into `A` before encoding.\n * - Values of type `B` to be transformed into `D` after decoding.\n *\n * This is useful for adapting codecs to work with different representations, handling default values, or\n * converting between primitive and structured types.\n *\n * @typeParam TOldFrom - The original type expected by the codec.\n * @typeParam TNewFrom - The new type that will be transformed before encoding.\n * @typeParam TOldTo - The original type returned by the codec.\n * @typeParam TNewTo - The new type that will be transformed after decoding.\n *\n * @param codec - The codec to transform.\n * @param unmap - A function that converts values of `TNewFrom` into `TOldFrom` before encoding.\n * @param map - A function that converts values of `TOldTo` into `TNewTo` after decoding (optional).\n * @returns A new codec that encodes `TNewFrom` and decodes into `TNewTo`.\n *\n * @example\n * Mapping a `u32` codec to encode string lengths and decode them into `'x'` characters.\n * ```ts\n * const codec = transformCodec(\n *     getU32Codec(),\n *     (value: string) => value.length, // Encode string length\n *     (length) => 'x'.repeat(length)  // Decode length into a string of 'x's\n * );\n *\n * const bytes = codec.encode(\"hello\"); // 0x05000000 (stores length 5)\n * const value = codec.decode(bytes);   // \"xxxxx\"\n * ```\n *\n * @remarks\n * If only input transformation is needed, use {@link transformEncoder}.\n * If only output transformation is needed, use {@link transformDecoder}.\n *\n * ```ts\n * const bytes = transformEncoder(getU32Encoder(), (value: string) => value.length).encode(\"hello\");\n * const value = transformDecoder(getU32Decoder(), (length) => 'x'.repeat(length)).decode(bytes);\n * ```\n *\n * @see {@link transformEncoder}\n * @see {@link transformDecoder}\n */\nexport function transformCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom, TSize extends number>(\n    codec: FixedSizeCodec<TOldFrom, TTo, TSize>,\n    unmap: (value: TNewFrom) => TOldFrom,\n): FixedSizeCodec<TNewFrom, TTo, TSize>;\nexport function transformCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n    codec: VariableSizeCodec<TOldFrom, TTo>,\n    unmap: (value: TNewFrom) => TOldFrom,\n): VariableSizeCodec<TNewFrom, TTo>;\nexport function transformCodec<TOldFrom, TNewFrom, TTo extends TNewFrom & TOldFrom>(\n    codec: Codec<TOldFrom, TTo>,\n    unmap: (value: TNewFrom) => TOldFrom,\n): Codec<TNewFrom, TTo>;\nexport function transformCodec<\n    TOldFrom,\n    TNewFrom,\n    TOldTo extends TOldFrom,\n    TNewTo extends TNewFrom,\n    TSize extends number,\n>(\n    codec: FixedSizeCodec<TOldFrom, TOldTo, TSize>,\n    unmap: (value: TNewFrom) => TOldFrom,\n    map: (value: TOldTo, bytes: ReadonlyUint8Array | Uint8Array, offset: number) => TNewTo,\n): FixedSizeCodec<TNewFrom, TNewTo, TSize>;\nexport function transformCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n    codec: VariableSizeCodec<TOldFrom, TOldTo>,\n    unmap: (value: TNewFrom) => TOldFrom,\n    map: (value: TOldTo, bytes: ReadonlyUint8Array | Uint8Array, offset: number) => TNewTo,\n): VariableSizeCodec<TNewFrom, TNewTo>;\nexport function transformCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n    codec: Codec<TOldFrom, TOldTo>,\n    unmap: (value: TNewFrom) => TOldFrom,\n    map: (value: TOldTo, bytes: ReadonlyUint8Array | Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo>;\nexport function transformCodec<TOldFrom, TNewFrom, TOldTo extends TOldFrom, TNewTo extends TNewFrom>(\n    codec: Codec<TOldFrom, TOldTo>,\n    unmap: (value: TNewFrom) => TOldFrom,\n    map?: (value: TOldTo, bytes: ReadonlyUint8Array | Uint8Array, offset: number) => TNewTo,\n): Codec<TNewFrom, TNewTo> {\n    return createCodec({\n        ...transformEncoder(codec, unmap),\n        read: map ? transformDecoder(codec, map).read : (codec.read as unknown as Decoder<TNewTo>['read']),\n    });\n}\n"
  },
  {
    "path": "packages/codecs-core/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/codecs-core/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/codecs-core\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"],\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2020\", \"ES2022.Error\"]\n    }\n}\n"
  },
  {
    "path": "packages/codecs-core/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/codecs-data-structures/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/codecs-data-structures/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/codecs-data-structures/CHANGELOG.md",
    "content": "# @solana/codecs-data-structures\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-numbers@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-numbers@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-numbers@6.3.0\n\n## 6.2.0\n\n### Minor Changes\n\n- [#1394](https://github.com/anza-xyz/kit/pull/1394) [`3f4c5f0`](https://github.com/anza-xyz/kit/commit/3f4c5f003e343c21a785e8f339f84c8d6bd3a3b1) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Adds new functions `getPatternMatchEncoder`, `getPatternMatchDecoder` and `getPatternMatchCodec`.\n\n    These can be used to write an encoder that switches between any number of encoders based on the value being encoded, or a decoder that switches between any number of decoders based on the byte array being decoded.\n\n    For example for the encoder, the input is a list of [predicate, encoder] pairs. Each predicate is a function from the value being encoded to true/false. The encoder used is the first one where its predicate is true.\n\n### Patch Changes\n\n- [#1420](https://github.com/anza-xyz/kit/pull/1420) [`5390602`](https://github.com/anza-xyz/kit/commit/53906024cffc3facb7259ab65ab974b6b1038f56) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Enable pattern match encoder/codec to use type narrowing. This means that if your predicate narrows the type of the value, then the matching encoder only needs to handle the narrowed type.\n\n    This means that you can write, for example:\n\n    ```ts\n    getPatternMatchEncoder<string | number>([\n        [value => typeof value === 'string', {} as Encoder<string>],\n        [value => typeof value === 'number', {} as Encoder<number>],\n    ]);\n    ```\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n\n## 6.1.0\n\n### Minor Changes\n\n- [#1363](https://github.com/anza-xyz/kit/pull/1363) [`70b1ed8`](https://github.com/anza-xyz/kit/commit/70b1ed83be4c5445f81c600a8ca70127dbdf3463) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Adds new functions `getPredicateEncoder`, `getPredicateDecoder` and `getPredicateCodec`.\n\n    These can be used to write an encoder that switches between two encoders based on the value being encoded, or a decoder that switches between two decoders based on the byte array being decoded.\n\n- [#1369](https://github.com/anza-xyz/kit/pull/1369) [`7ce7545`](https://github.com/anza-xyz/kit/commit/7ce75455659ace9776042def6774678a81c43a4a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow passing a description to array and tuple encoders and codecs\n    - The `ArrayCodecConfig` is extended with an optional description\n    - The tuple encoder and codec now have an optional second argument, which is a new config object `TupleCodecConfig` with an optional description\n    - If either throws a `SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS` when encoding, the `codecDescription` field will be the description passed in the config. If no description is included then they will continue to default to `array` and `tuple` respectively.\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-numbers@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-numbers@6.0.1\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-numbers@6.0.0\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-numbers@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-numbers@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-numbers@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-numbers@5.3.0\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-numbers@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/codecs-numbers@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-numbers@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/codecs-numbers@4.0.0\n\n## 3.0.0\n\n### Major Changes\n\n- [#691](https://github.com/anza-xyz/kit/pull/691) [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: Removes the following deprecated functions: `getDataEnumEncoder`, `getDataEnumDecoder`, `getDataEnumCodec`, `getScalarEnumEncoder`, `getScalarEnumDecoder` and `getScalarEnumCodec`.\n\n### Patch Changes\n\n- [#701](https://github.com/anza-xyz/kit/pull/701) [`9205484`](https://github.com/anza-xyz/kit/commit/9205484d33af9426fc9de9594bab204b8f954faf) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Union codecs FixedSize if all their variants are FixedSize\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/codecs-numbers@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-numbers@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-numbers@2.2.1\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-numbers@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-numbers@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- [`cfe6910`](https://github.com/anza-xyz/kit/commit/cfe691010a493d06983a8a2728cda9751135906d) Thanks [@Jasu](https://github.com/Jasu)! - `LiteralUnionCodec` is now exported from `@solana/codecs-data-structures`\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-numbers@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2397](https://github.com/solana-labs/solana-web3.js/pull/2397) [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `addCodecSizePrefix` primitive\n\n    ```ts\n    const codec = addCodecSizePrefix(getBase58Codec(), getU32Codec());\n\n    codec.encode('hello world');\n    // 0x0b00000068656c6c6f20776f726c64\n    //   |       └-- Our encoded base-58 string.\n    //   └-- Our encoded u32 size prefix.\n    ```\n\n- [#2344](https://github.com/solana-labs/solana-web3.js/pull/2344) [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Improve `getTupleCodec` type inferences and performance\n\n    The tuple codec now infers its encoded/decoded type from the provided codec array and uses the new `DrainOuterGeneric` helper to reduce the number of TypeScript instantiations.\n\n- [#2322](https://github.com/solana-labs/solana-web3.js/pull/2322) [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `DrainOuterGeneric` helper on codec type mappings\n\n    This significantly reduces the number of TypeScript instantiations on object mappings,\n    which increases TypeScript performance and prevents \"Type instantiation is excessively deep and possibly infinite\" errors.\n\n- [#2400](https://github.com/solana-labs/solana-web3.js/pull/2400) [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `containsBytes` and `getConstantCodec` helpers\n\n    The `containsBytes` helper checks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n\n    ```ts\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n    ```\n\n    The `getConstantCodec` function accepts any `Uint8Array` and returns a `Codec<void>`. When encoding, it will set the provided `Uint8Array` as-is. When decoding, it will assert that the next bytes contain the provided `Uint8Array` and move the offset forward.\n\n    ```ts\n    const codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n\n    codec.encode(undefined); // 0x010203\n    codec.decode(new Uint8Array([1, 2, 3])); // undefined\n    codec.decode(new Uint8Array([1, 2, 4])); // Throws an error.\n    ```\n\n- [#2381](https://github.com/solana-labs/solana-web3.js/pull/2381) [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - DataEnum codecs can now use numbers or symbols as discriminator values\n\n    ```ts\n    const codec = getDataEnumCodec([[1, getStructCodec([[['one', u32]]])][(2, getStructCodec([[['two', u32]]]))]]);\n\n    codec.encode({ __kind: 1, one: 42 });\n    codec.encode({ __kind: 2, two: 42 });\n    ```\n\n    This means you can also use enum values as discriminators, like so:\n\n    ```ts\n    enum Event {\n        Click,\n        KeyPress,\n    }\n    const codec = getDataEnumCodec([\n        [\n            Event.Click,\n            getStructCodec([\n                [\n                    ['x', u32],\n                    ['y', u32],\n                ],\n            ]),\n        ],\n        [Event.KeyPress, getStructCodec([[['key', u32]]])],\n    ]);\n\n    codec.encode({ __kind: Event.Click, x: 1, y: 2 });\n    codec.encode({ __kind: Event.KeyPress, key: 3 });\n    ```\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#2715](https://github.com/solana-labs/solana-web3.js/pull/2715) [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Consolidated `getNullableCodec` and `getOptionCodec` with their `Zeroable` counterparts and added more configurations\n\n    Namely, the `prefix` option can now be set to `null` and the `fixed` option was replaced with the `noneValue` option which can be set to `\"zeroes\"` for `Zeroable` codecs or a custom byte array for custom representations of none values. This means the `getZeroableNullableCodec` and `getZeroableOptionCodec` functions were removed in favor of the new options.\n\n    ```ts\n    // Before.\n    getZeroableNullableCodec(getU16Codec());\n\n    // After.\n    getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n    ```\n\n    Additionally, it is now possible to create nullable codecs that have no `prefix` nor `noneValue`. In this case, the existence of the nullable item is indicated by the presence of any remaining bytes left to decode.\n\n    ```ts\n    const codec = getNullableCodec(getU16Codec(), { prefix: null });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // Encodes nothing.\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([])); // null\n    ```\n\n    Also note that it is now possible for custom `noneValue` byte arrays to be of any length — previously, it had to match the fixed-size of the nullable item.\n\n    Here is a recap of all supported scenarios, using a `u16` codec as an example:\n\n    | `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n    | ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n    | `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n    | Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n    | No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n    Reciprocal changes were made with `getOptionCodec`.\n\n- [#2383](https://github.com/solana-labs/solana-web3.js/pull/2383) [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getScalarEnumCodec` is now called `getEnumCodec`\n\n- [#2430](https://github.com/solana-labs/solana-web3.js/pull/2430) [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added `useValuesAsDiscriminators` option to `getEnumCodec`\n\n    When dealing with numerical enums that have explicit values, you may now use the `useValuesAsDiscriminators` option to encode the value of the enum variant instead of its index.\n\n    ```ts\n    enum Numbers {\n        One,\n        Five = 5,\n        Six,\n        Nine = 9,\n    }\n\n    const codec = getEnumCodec(Numbers, { useValuesAsDiscriminators: true });\n    codec.encode(Direction.One); // 0x00\n    codec.encode(Direction.Five); // 0x05\n    codec.encode(Direction.Six); // 0x06\n    codec.encode(Direction.Nine); // 0x09\n    ```\n\n    Note that when using the `useValuesAsDiscriminators` option on an enum that contains a lexical value, an error will be thrown.\n\n    ```ts\n    enum Lexical {\n        One,\n        Two = 'two',\n    }\n    getEnumCodec(Lexical, { useValuesAsDiscriminators: true }); // Throws an error.\n    ```\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2398](https://github.com/solana-labs/solana-web3.js/pull/2398) [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `getUnionCodec` helper that can be used to encode/decode any TypeScript union.\n\n    ```ts\n    const codec: Codec<number | boolean> = getUnionCodec(\n        [getU16Codec(), getBooleanCodec()],\n        value => (typeof value === 'number' ? 0 : 1),\n        (bytes, offset) => (bytes.slice(offset).length > 1 ? 0 : 1),\n    );\n\n    codec.encode(42); // 0x2a00\n    codec.encode(true); // 0x01\n    ```\n\n- [#2382](https://github.com/solana-labs/solana-web3.js/pull/2382) [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getDataEnumCodec` is now called `getDiscriminatedUnionCodec`\n\n- [#2401](https://github.com/solana-labs/solana-web3.js/pull/2401) [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `getHiddenPrefixCodec` and `getHiddenSuffixCodec` helpers\n\n    These functions allow us to respectively prepend or append a list of hidden `Codec<void>` to a given codec. When encoding, the hidden codecs will be encoded before or after the main codec and the offset will be moved accordingly. When decoding, the hidden codecs will be decoded but only the result of the main codec will be returned. This is particularly helpful when creating data structures that include constant values that should not be included in the final type.\n\n    ```ts\n    const codec: Codec<number> = getHiddenPrefixCodec(getU16Codec(), [\n        getConstantCodec(new Uint8Array([1, 2, 3])),\n        getConstantCodec(new Uint8Array([4, 5, 6])),\n    ]);\n\n    codec.encode(42);\n    // 0x0102030405062a00\n    //   |     |     └-- Our main u16 codec (value = 42).\n    //   |     └-- Our second hidden prefix codec.\n    //   └-- Our first hidden prefix codec.\n\n    codec.decode(new Uint8Array([1, 2, 3, 4, 5, 6, 42, 0])); // 42\n    ```\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2433](https://github.com/solana-labs/solana-web3.js/pull/2433) [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - The `getBooleanCodec` function now accepts variable-size number codecs\n\n- [#2412](https://github.com/solana-labs/solana-web3.js/pull/2412) [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed the size option of `getBytesCodec`\n\n    The `getBytesCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode byte arrays. In order to fix or prefix the size of a `getBytesCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getBytesCodec(); // Variable.\n    getBytesCodec({ size: 5 }); // Fixed.\n    getBytesCodec({ size: getU16Codec() }); // Prefixed.\n\n    // After.\n    getBytesCodec(); // Variable.\n    fixCodecSize(getBytesCodec(), 5); // Fixed.\n    addCodecSizePrefix(getBytesCodec(), getU16Codec()); // Prefixed.\n    ```\n\n- [#2394](https://github.com/solana-labs/solana-web3.js/pull/2394) [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `getLiteralUnionCodec`\n\n    ```ts\n    const codec = getLiteralUnionCodec(['left', 'right', 'up', 'down']);\n    // ^? FixedSizeCodec<\"left\" | \"right\" | \"up\" | \"down\">\n\n    const bytes = codec.encode('left'); // 0x00\n    const value = codec.decode(bytes); // 'left'\n    ```\n\n- [#2410](https://github.com/solana-labs/solana-web3.js/pull/2410) [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `getZeroableNullableCodec` and `getZeroableOptionCodec` functions\n\n    These functions rely on a zero value to represent `None` or `null` values as opposed to using a boolean prefix.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec());\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0x0000\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.encode(new Uint8Array([0, 0])); // null\n    ```\n\n    Both functions can also be provided with a custom definition of the zero value using the `zeroValue` option.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec(), {\n        zeroValue: new Uint8Array([255, 255]),\n    });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0xfffff\n    codec.encode(new Uint8Array([0, 0])); // 0\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([255, 255])); // null\n    ```\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#2380](https://github.com/solana-labs/solana-web3.js/pull/2380) [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - DataEnum codecs now support custom discriminator properties\n\n    ```ts\n    const codec = getDataEnumCodec(\n        [\n            [\n                'click',\n                getStructCodec([\n                    [\n                        ['x', u32],\n                        ['y', u32],\n                    ],\n                ]),\n            ],\n            ['keyPress', getStructCodec([[['key', u32]]])],\n        ],\n        { discriminator: 'event' },\n    );\n\n    codec.encode({ event: 'click', x: 1, y: 2 });\n    codec.encode({ event: 'keyPress', key: 3 });\n    ```\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/codecs-numbers@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-numbers@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-numbers@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-numbers@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-numbers@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-numbers@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2715](https://github.com/solana-labs/solana-web3.js/pull/2715) [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Consolidated `getNullableCodec` and `getOptionCodec` with their `Zeroable` counterparts and added more configurations\n\n    Namely, the `prefix` option can now be set to `null` and the `fixed` option was replaced with the `noneValue` option which can be set to `\"zeroes\"` for `Zeroable` codecs or a custom byte array for custom representations of none values. This means the `getZeroableNullableCodec` and `getZeroableOptionCodec` functions were removed in favor of the new options.\n\n    ```ts\n    // Before.\n    getZeroableNullableCodec(getU16Codec());\n\n    // After.\n    getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n    ```\n\n    Additionally, it is now possible to create nullable codecs that have no `prefix` nor `noneValue`. In this case, the existence of the nullable item is indicated by the presence of any remaining bytes left to decode.\n\n    ```ts\n    const codec = getNullableCodec(getU16Codec(), { prefix: null });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // Encodes nothing.\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([])); // null\n    ```\n\n    Also note that it is now possible for custom `noneValue` byte arrays to be of any length — previously, it had to match the fixed-size of the nullable item.\n\n    Here is a recap of all supported scenarios, using a `u16` codec as an example:\n\n    | `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n    | ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n    | `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n    | Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n    | No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n    Reciprocal changes were made with `getOptionCodec`.\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/codecs-numbers@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2397](https://github.com/solana-labs/solana-web3.js/pull/2397) [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `addCodecSizePrefix` primitive\n\n    ```ts\n    const codec = addCodecSizePrefix(getBase58Codec(), getU32Codec());\n\n    codec.encode('hello world');\n    // 0x0b00000068656c6c6f20776f726c64\n    //   |       └-- Our encoded base-58 string.\n    //   └-- Our encoded u32 size prefix.\n    ```\n\n- [#2344](https://github.com/solana-labs/solana-web3.js/pull/2344) [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Improve `getTupleCodec` type inferences and performance\n\n    The tuple codec now infers its encoded/decoded type from the provided codec array and uses the new `DrainOuterGeneric` helper to reduce the number of TypeScript instantiations.\n\n- [#2322](https://github.com/solana-labs/solana-web3.js/pull/2322) [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `DrainOuterGeneric` helper on codec type mappings\n\n    This significantly reduces the number of TypeScript instantiations on object mappings,\n    which increases TypeScript performance and prevents \"Type instantiation is excessively deep and possibly infinite\" errors.\n\n- [#2400](https://github.com/solana-labs/solana-web3.js/pull/2400) [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `containsBytes` and `getConstantCodec` helpers\n\n    The `containsBytes` helper checks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n\n    ```ts\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n    ```\n\n    The `getConstantCodec` function accepts any `Uint8Array` and returns a `Codec<void>`. When encoding, it will set the provided `Uint8Array` as-is. When decoding, it will assert that the next bytes contain the provided `Uint8Array` and move the offset forward.\n\n    ```ts\n    const codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n\n    codec.encode(undefined); // 0x010203\n    codec.decode(new Uint8Array([1, 2, 3])); // undefined\n    codec.decode(new Uint8Array([1, 2, 4])); // Throws an error.\n    ```\n\n- [#2381](https://github.com/solana-labs/solana-web3.js/pull/2381) [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - DataEnum codecs can now use numbers or symbols as discriminator values\n\n    ```ts\n    const codec = getDataEnumCodec([[1, getStructCodec([[['one', u32]]])][(2, getStructCodec([[['two', u32]]]))]]);\n\n    codec.encode({ __kind: 1, one: 42 });\n    codec.encode({ __kind: 2, two: 42 });\n    ```\n\n    This means you can also use enum values as discriminators, like so:\n\n    ```ts\n    enum Event {\n        Click,\n        KeyPress,\n    }\n    const codec = getDataEnumCodec([\n        [\n            Event.Click,\n            getStructCodec([\n                [\n                    ['x', u32],\n                    ['y', u32],\n                ],\n            ]),\n        ],\n        [Event.KeyPress, getStructCodec([[['key', u32]]])],\n    ]);\n\n    codec.encode({ __kind: Event.Click, x: 1, y: 2 });\n    codec.encode({ __kind: Event.KeyPress, key: 3 });\n    ```\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#2383](https://github.com/solana-labs/solana-web3.js/pull/2383) [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getScalarEnumCodec` is now called `getEnumCodec`\n\n- [#2430](https://github.com/solana-labs/solana-web3.js/pull/2430) [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added `useValuesAsDiscriminators` option to `getEnumCodec`\n\n    When dealing with numerical enums that have explicit values, you may now use the `useValuesAsDiscriminators` option to encode the value of the enum variant instead of its index.\n\n    ```ts\n    enum Numbers {\n        One,\n        Five = 5,\n        Six,\n        Nine = 9,\n    }\n\n    const codec = getEnumCodec(Numbers, { useValuesAsDiscriminators: true });\n    codec.encode(Direction.One); // 0x00\n    codec.encode(Direction.Five); // 0x05\n    codec.encode(Direction.Six); // 0x06\n    codec.encode(Direction.Nine); // 0x09\n    ```\n\n    Note that when using the `useValuesAsDiscriminators` option on an enum that contains a lexical value, an error will be thrown.\n\n    ```ts\n    enum Lexical {\n        One,\n        Two = 'two',\n    }\n    getEnumCodec(Lexical, { useValuesAsDiscriminators: true }); // Throws an error.\n    ```\n\n- [#2398](https://github.com/solana-labs/solana-web3.js/pull/2398) [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `getUnionCodec` helper that can be used to encode/decode any TypeScript union.\n\n    ```ts\n    const codec: Codec<number | boolean> = getUnionCodec(\n        [getU16Codec(), getBooleanCodec()],\n        value => (typeof value === 'number' ? 0 : 1),\n        (bytes, offset) => (bytes.slice(offset).length > 1 ? 0 : 1),\n    );\n\n    codec.encode(42); // 0x2a00\n    codec.encode(true); // 0x01\n    ```\n\n- [#2382](https://github.com/solana-labs/solana-web3.js/pull/2382) [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getDataEnumCodec` is now called `getDiscriminatedUnionCodec`\n\n- [#2401](https://github.com/solana-labs/solana-web3.js/pull/2401) [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `getHiddenPrefixCodec` and `getHiddenSuffixCodec` helpers\n\n    These functions allow us to respectively prepend or append a list of hidden `Codec<void>` to a given codec. When encoding, the hidden codecs will be encoded before or after the main codec and the offset will be moved accordingly. When decoding, the hidden codecs will be decoded but only the result of the main codec will be returned. This is particularly helpful when creating data structures that include constant values that should not be included in the final type.\n\n    ```ts\n    const codec: Codec<number> = getHiddenPrefixCodec(getU16Codec(), [\n        getConstantCodec(new Uint8Array([1, 2, 3])),\n        getConstantCodec(new Uint8Array([4, 5, 6])),\n    ]);\n\n    codec.encode(42);\n    // 0x0102030405062a00\n    //   |     |     └-- Our main u16 codec (value = 42).\n    //   |     └-- Our second hidden prefix codec.\n    //   └-- Our first hidden prefix codec.\n\n    codec.decode(new Uint8Array([1, 2, 3, 4, 5, 6, 42, 0])); // 42\n    ```\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2433](https://github.com/solana-labs/solana-web3.js/pull/2433) [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - The `getBooleanCodec` function now accepts variable-size number codecs\n\n- [#2412](https://github.com/solana-labs/solana-web3.js/pull/2412) [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed the size option of `getBytesCodec`\n\n    The `getBytesCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode byte arrays. In order to fix or prefix the size of a `getBytesCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getBytesCodec(); // Variable.\n    getBytesCodec({ size: 5 }); // Fixed.\n    getBytesCodec({ size: getU16Codec() }); // Prefixed.\n\n    // After.\n    getBytesCodec(); // Variable.\n    fixCodecSize(getBytesCodec(), 5); // Fixed.\n    addCodecSizePrefix(getBytesCodec(), getU16Codec()); // Prefixed.\n    ```\n\n- [#2394](https://github.com/solana-labs/solana-web3.js/pull/2394) [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `getLiteralUnionCodec`\n\n    ```ts\n    const codec = getLiteralUnionCodec(['left', 'right', 'up', 'down']);\n    // ^? FixedSizeCodec<\"left\" | \"right\" | \"up\" | \"down\">\n\n    const bytes = codec.encode('left'); // 0x00\n    const value = codec.decode(bytes); // 'left'\n    ```\n\n- [#2410](https://github.com/solana-labs/solana-web3.js/pull/2410) [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `getZeroableNullableCodec` and `getZeroableOptionCodec` functions\n\n    These functions rely on a zero value to represent `None` or `null` values as opposed to using a boolean prefix.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec());\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0x0000\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.encode(new Uint8Array([0, 0])); // null\n    ```\n\n    Both functions can also be provided with a custom definition of the zero value using the `zeroValue` option.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec(), {\n        zeroValue: new Uint8Array([255, 255]),\n    });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0xfffff\n    codec.encode(new Uint8Array([0, 0])); // 0\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([255, 255])); // null\n    ```\n\n- [#2380](https://github.com/solana-labs/solana-web3.js/pull/2380) [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - DataEnum codecs now support custom discriminator properties\n\n    ```ts\n    const codec = getDataEnumCodec(\n        [\n            [\n                'click',\n                getStructCodec([\n                    [\n                        ['x', u32],\n                        ['y', u32],\n                    ],\n                ]),\n            ],\n            ['keyPress', getStructCodec([[['key', u32]]])],\n        ],\n        { discriminator: 'event' },\n    );\n\n    codec.encode({ event: 'click', x: 1, y: 2 });\n    codec.encode({ event: 'keyPress', key: 3 });\n    ```\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/codecs-numbers@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-numbers@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/codecs-data-structures/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/codecs-data-structures/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/codecs-data-structures?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/codecs-data-structures?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/codecs-data-structures\n\n# @solana/codecs-data-structures\n\nThis package contains codecs for various data structures such as arrays, maps, structs, tuples, enums, etc. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nThis package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) which acts as an entry point for all codec packages as well as for their documentation.\n\n## Array codec\n\nThe `getArrayCodec` function accepts any codec of type `T` and returns a codec of type `Array<T>`. For instance, here’s how we can create a codec for arrays of numbers that each fit in a single byte.\n\n```ts\nconst bytes = getArrayCodec(getU8Codec()).encode([1, 2, 3]);\nconst array = getArrayCodec(getU8Codec()).decode(bytes);\n```\n\nBy default, the size of the array is stored as a `u32` prefix before encoding the items.\n\n```ts\ngetArrayCodec(getU8Codec()).encode([1, 2, 3]);\n// 0x03000000010203\n//   |       └-- 3 items of 1 byte each.\n//   └-- 4-byte prefix telling us to read 3 items.\n```\n\nHowever, you may use the `size` option to configure this behaviour. It can be one of the following three strategies:\n\n- `Codec<number>`: When a number codec is provided, that codec will be used to encode and decode the size prefix.\n- `number`: When a number is provided, the codec will expect a fixed number of items in the array. An error will be thrown when trying to encode an array of a different length.\n- `\"remainder\"`: When the string `\"remainder\"` is passed as a size, the codec will use the remainder of the bytes to encode/decode its items. This means the size is not stored or known in advance but simply inferred from the rest of the buffer. For instance, if we have an array of `u16` numbers and 10 bytes remaining, we know there are 5 items in this array.\n\n```ts\ngetArrayCodec(getU8Codec(), { size: getU16Codec() }).encode([1, 2, 3]);\n// 0x0300010203\n//   |   └-- 3 items of 1 byte each.\n//   └-- 2-byte prefix telling us to read 3 items.\n\ngetArrayCodec(getU8Codec(), { size: 3 }).encode([1, 2, 3]);\n// 0x010203\n//   └-- 3 items of 1 byte each. There must always be 3 items in the array.\n\ngetArrayCodec(getU8Codec(), { size: 'remainder' }).encode([1, 2, 3]);\n// 0x010203\n//   └-- 3 items of 1 byte each. The size is inferred from the remainder of the bytes.\n```\n\nSeparate `getArrayEncoder` and `getArrayDecoder` functions are also available.\n\n```ts\nconst bytes = getArrayEncoder(getU8Encoder()).encode([1, 2, 3]);\nconst array = getArrayDecoder(getU8Decoder()).decode(bytes);\n```\n\n## Set codec\n\nThe `getSetCodec` function accepts any codec of type `T` and returns a codec of type `Set<T>`. For instance, here’s how we can create a codec for sets of numbers that each fit in a single byte.\n\n```ts\nconst bytes = getSetCodec(getU8Codec()).encode(new Set([1, 2, 3]));\nconst set = getSetCodec(getU8Codec()).decode(bytes);\n```\n\nJust like the array codec, it uses a `u32` size prefix by default but can be configured using the `size` option. [See the array codec](#array-codec) for more details.\n\n```ts\ngetSetCodec(getU8Codec(), { size: getU16Codec() }).encode(new Set([1, 2, 3]));\ngetSetCodec(getU8Codec(), { size: 3 }).encode(new Set([1, 2, 3]));\ngetSetCodec(getU8Codec(), { size: 'remainder' }).encode(new Set([1, 2, 3]));\n```\n\nSeparate `getSetEncoder` and `getSetDecoder` functions are also available.\n\n```ts\nconst bytes = getSetEncoder(getU8Encoder()).encode(new Set([1, 2, 3]));\nconst set = getSetDecoder(getU8Decoder()).decode(bytes);\n```\n\n## Map codec\n\nThe `getMapCodec` function accepts two codecs of type `K` and `V` and returns a codec of type `Map<K, V>`. For instance, here’s how we can create a codec for maps such that the keys are fixed strings of 8 bytes and the values are `u8` numbers.\n\n```ts\nconst keyCodec = fixCodecSize(getUtf8Codec(), 8);\nconst valueCodec = getU8Codec();\nconst bytes = getMapCodec(keyCodec, valueCodec).encode(new Map([['alice', 42]]));\nconst map = getMapCodec(keyCodec, valueCodec).decode(bytes);\n```\n\nJust like the array codec, it uses a `u32` size prefix by default.\n\n```ts\nconst keyCodec = fixCodecSize(getUtf8Codec(), 8);\nconst valueCodec = getU8Codec();\nconst myMap = new Map<string, number>();\nmyMap.set('alice', 42);\nmyMap.set('bob', 5);\n\ngetMapCodec(keyCodec, valueCodec).encode(myMap);\n// 0x02000000616c6963650000002a626f62000000000005\n//   |       |               | |               └-- 2nd entry value (5).\n//   |       |               | └-- 2nd entry key (\"bob\").\n//   |       |               └-- 1st entry value (42).\n//   |       └-- 1st entry key (\"alice\").\n//   └-- 4-byte prefix telling us to read 2 map entries.\n```\n\nHowever, it can be configured using the `size` option. [See the `size` option of the array codec](#array-codec) for more details.\n\n```ts\ngetMapCodec(keyCodec, valueCodec, { size: getU16Codec() }).encode(myMap);\ngetMapCodec(keyCodec, valueCodec, { size: 3 }).encode(myMap);\ngetMapCodec(keyCodec, valueCodec, { size: 'remainder' }).encode(myMap);\n```\n\nSeparate `getMapEncoder` and `getMapDecoder` functions are also available.\n\n```ts\nconst bytes = getMapEncoder(keyEncoder, valueEncoder).encode(myMap);\nconst map = getMapDecoder(keyDecoder, valueDecoder).decode(bytes);\n```\n\n## Tuple codec\n\nThe `getTupleCodec` function accepts any number of codecs — `T`, `U`, `V`, etc. — and returns a tuple codec of type `[T, U, V, …]` such that each item is in the order of the provided codecs.\n\n```ts\nconst codec = getTupleCodec([addCodecSizePrefix(getUtf8Codec(), getU32Codec()), getU8Codec(), getU64Codec()]);\nconst bytes = codec.encode(['alice', 42, 123]);\nconst tuple = codec.decode(bytes);\n```\n\nSeparate `getTupleEncoder` and `getTupleDecoder` functions are also available.\n\n```ts\nconst bytes = getTupleEncoder([getU8Encoder(), getU64Encoder()]).encode([42, 123]);\nconst tuple = getTupleDecoder([getU8Decoder(), getU64Decoder()]).decode(bytes);\n```\n\n## Struct codec\n\nThe `getStructCodec` function accepts any number of field codecs and returns a codec for an object containing all these fields. Each provided field is an array such that the first item is the name of the field and the second item is the codec used to encode and decode that field type.\n\n```ts\ntype Person = { name: string; age: number };\nconst personCodec: Codec<Person> = getStructCodec([\n    ['name', addCodecSizePrefix(getUtf8Codec(), getU32Codec())],\n    ['age', getU8Codec()],\n]);\n\nconst bytes = personCodec.encode({ name: 'alice', age: 42 });\nconst person = personCodec.decode(bytes);\n```\n\nSeparate `getStructEncoder` and `getStructDecoder` functions are also available.\n\n```ts\nconst personEncoder: Encoder<Person> = getStructEncoder([\n    ['name', addEncoderSizePrefix(getUtf8Encoder(), getU32Encoder())],\n    ['age', getU8Encoder()],\n]);\nconst personDecoder: Decoder<Person> = getStructDecoder([\n    ['name', addDecoderSizePrefix(getUtf8Decoder(), getU32Decoder())],\n    ['age', getU8Decoder()],\n]);\nconst bytes = personEncoder.encode({ name: 'alice', age: 42 });\nconst person = personDecoder.decode(bytes);\n```\n\n## Enum codec\n\nThe `getEnumCodec` function accepts a JavaScript enum constructor and returns a codec for encoding and decoding values of that enum.\n\n```ts\nenum Direction {\n    Left,\n    Right,\n}\n\nconst bytes = getEnumCodec(Direction).encode(Direction.Left);\nconst direction = getEnumCodec(Direction).decode(bytes);\n```\n\nWhen encoding an enum, you may either provide the value of the enum variant — e.g. `Direction.Left` — or its key — e.g. `'Left'`.\n\n```ts\nenum Direction {\n    Left,\n    Right,\n}\n\ngetEnumCodec(Direction).encode(Direction.Left); // 0x00\ngetEnumCodec(Direction).encode(Direction.Right); // 0x01\ngetEnumCodec(Direction).encode('Left'); // 0x00\ngetEnumCodec(Direction).encode('Right'); // 0x01\n```\n\nAs you can see, by default, a `u8` number is being used to store the enum value. However, a number codec may be passed as the `size` option to configure that behaviour.\n\n```ts\nconst u32DirectionCodec = getEnumCodec(Direction, { size: getU32Codec() });\nu32DirectionCodec.encode(Direction.Left); // 0x00000000\nu32DirectionCodec.encode(Direction.Right); // 0x01000000\n```\n\nThis function also works with lexical enums — e.g. `enum Direction { Left = '←' }` — explicit numerical enums — e.g. `enum Speed { Left = 50 }` — and hybrid enums with a mix of both.\n\n```ts\nenum Numbers {\n    One,\n    Five = 5,\n    Six,\n    Nine = 'nine',\n}\n\ngetEnumCodec(Numbers).encode(Direction.One); // 0x00\ngetEnumCodec(Numbers).encode(Direction.Five); // 0x01\ngetEnumCodec(Numbers).encode(Direction.Six); // 0x02\ngetEnumCodec(Numbers).encode(Direction.Nine); // 0x03\ngetEnumCodec(Numbers).encode('One'); // 0x00\ngetEnumCodec(Numbers).encode('Five'); // 0x01\ngetEnumCodec(Numbers).encode('Six'); // 0x02\ngetEnumCodec(Numbers).encode('Nine'); // 0x03\n```\n\nNotice how, by default, the index of the enum variant is used to encode the value of the enum. For instance, in the example above, `Numbers.Five` is encoded as `0x01` even though its value is `5`. This is also true for lexical enums.\n\nHowever, when dealing with numerical enums that have explicit values, you may use the `useValuesAsDiscriminators` option to encode the value of the enum variant instead of its index.\n\n```ts\nenum Numbers {\n    One,\n    Five = 5,\n    Six,\n    Nine = 9,\n}\n\nconst codec = getEnumCodec(Numbers, { useValuesAsDiscriminators: true });\ncodec.encode(Direction.One); // 0x00\ncodec.encode(Direction.Five); // 0x05\ncodec.encode(Direction.Six); // 0x06\ncodec.encode(Direction.Nine); // 0x09\ncodec.encode('One'); // 0x00\ncodec.encode('Five'); // 0x05\ncodec.encode('Six'); // 0x06\ncodec.encode('Nine'); // 0x09\n```\n\nNote that when using the `useValuesAsDiscriminators` option on an enum that contains a lexical value, an error will be thrown.\n\n```ts\nenum Lexical {\n    One,\n    Two = 'two',\n}\ngetEnumCodec(Lexical, { useValuesAsDiscriminators: true }); // Throws an error.\n```\n\nSeparate `getEnumEncoder` and `getEnumDecoder` functions are also available.\n\n```ts\nconst bytes = getEnumEncoder(Direction).encode(Direction.Left);\nconst direction = getEnumDecoder(Direction).decode(bytes);\n```\n\n## Literal union codec\n\nThe `getLiteralUnionCodec` function works similarly to the `getUnionCodec` function but does not require a JavaScript `enum` to exist.\n\nIt accepts an array of literal values — such as `string`, `number`, `boolean`, etc. — and returns a codec that encodes and decodes such values using by using their index in the array. It uses TypeScript unions to represent all the possible values.\n\n```ts\nconst codec = getLiteralUnionCodec(['left', 'right', 'up', 'down']);\n// ^? FixedSizeCodec<\"left\" | \"right\" | \"up\" | \"down\">\n\nconst bytes = codec.encode('left'); // 0x00\nconst value = codec.decode(bytes); // 'left'\n```\n\nAs you can see, it uses a `u8` number by default to store the index of the value. However, you may provide a number codec as the `size` option of the `getLiteralUnionCodec` function to customise that behaviour.\n\n```ts\nconst codec = getLiteralUnionCodec(['left', 'right', 'up', 'down'], {\n    size: getU32Codec(),\n});\n\ncodec.encode('left'); // 0x00000000\ncodec.encode('right'); // 0x01000000\ncodec.encode('up'); // 0x02000000\ncodec.encode('down'); // 0x03000000\n```\n\nSeparate `getLiteralUnionEncoder` and `getLiteralUnionDecoder` functions are also available.\n\n```ts\nconst bytes = getLiteralUnionEncoder(['left', 'right']).encode('left'); // 0x00\nconst value = getLiteralUnionDecoder(['left', 'right']).decode(bytes); // 'left'\n```\n\n## Discriminated union codec\n\nIn Rust, enums are powerful data types whose variants can be one of the following:\n\n- An empty variant — e.g. `enum Message { Quit }`.\n- A tuple variant — e.g. `enum Message { Write(String) }`.\n- A struct variant — e.g. `enum Message { Move { x: i32, y: i32 } }`.\n\nWhilst we do not have such powerful enums in JavaScript, we can emulate them in TypeScript using a union of objects such that each object is differentiated by a specific field. **We call this a discriminated union**.\n\nWe use a special field named `__kind` to distinguish between the different variants of a discriminated union. Additionally, since all variants are objects, we can use a `fields` property to wrap the array of tuple variants. Here is an example.\n\n```ts\ntype Message =\n    | { __kind: 'Quit' } // Empty variant.\n    | { __kind: 'Write'; fields: [string] } // Tuple variant.\n    | { __kind: 'Move'; x: number; y: number }; // Struct variant.\n```\n\nThe `getDiscriminatedUnionCodec` function helps us encode and decode these discriminated unions.\n\nIt requires the discriminator and codec of each variant as a first argument. Similarly to the struct codec, these are defined as an array of variant tuples where the first item is the discriminator of the variant and the second item is its codec. Since empty variants do not have data to encode, they simply use the unit codec — documented below — which does nothing.\n\nHere is how we can create a discriminated union codec for our previous example.\n\n```ts\nconst messageCodec = getDiscriminatedUnionCodec([\n    // Empty variant.\n    ['Quit', getUnitCodec()],\n\n    // Tuple variant.\n    ['Write', getStructCodec([['fields', getTupleCodec([addCodecSizePrefix(getUtf8Codec(), getU32Codec())])]])],\n\n    // Struct variant.\n    [\n        'Move',\n        getStructCodec([\n            ['x', getI32Codec()],\n            ['y', getI32Codec()],\n        ]),\n    ],\n]);\n```\n\nAnd here’s how we can use such a codec to encode discriminated unions. Notice that by default, they use a `u8` number prefix to distinguish between the different types of variants.\n\n```ts\nmessageCodec.encode({ __kind: 'Quit' });\n// 0x00\n//   └-- 1-byte discriminator (Index 0 — the \"Quit\" variant).\n\nmessageCodec.encode({ __kind: 'Write', fields: ['Hi'] });\n// 0x01020000004869\n//   | |       └-- utf8 string content (\"Hi\").\n//   | └-- u32 string prefix (2 characters).\n//   └-- 1-byte discriminator (Index 1 — the \"Write\" variant).\n\nmessageCodec.encode({ __kind: 'Move', x: 5, y: 6 });\n// 0x020500000006000000\n//   | |       └-- Field y (6).\n//   | └-- Field x (5).\n//   └-- 1-byte discriminator (Index 2 — the \"Move\" variant).\n```\n\nHowever, you may provide a number codec as the `size` option of the `getDiscriminatedUnionCodec` function to customise that behaviour.\n\n```ts\nconst u32MessageCodec = getDiscriminatedUnionCodec([...], {\n    size: getU32Codec(),\n});\n\nu32MessageCodec.encode({ __kind: 'Quit' });\n// 0x00000000\n//   └------┘ 4-byte discriminator (Index 0).\n\nu32MessageCodec.encode({ __kind: 'Write', fields: ['Hi'] });\n// 0x01000000020000004869\n//   └------┘ 4-byte discriminator (Index 1).\n\nu32MessageCodec.encode({ __kind: 'Move', x: 5, y: 6 });\n// 0x020000000500000006000000\n//   └------┘ 4-byte discriminator (Index 2).\n```\n\nYou may also customize the discriminator property — which defaults to `__kind` — by providing the desired property name as the `discriminator` option like so:\n\n```ts\nconst messageCodec = getDiscriminatedUnionCodec([...], {\n    discriminator: 'message',\n});\n\nmessageCodec.encode({ message: 'Quit' });\nmessageCodec.encode({ message: 'Write', fields: ['Hi'] });\nmessageCodec.encode({ message: 'Move', x: 5, y: 6 });\n```\n\nNote that, the discriminator value of a variant may be any scalar value — such as `number`, `bigint`, `boolean`, a JavaScript `enum`, etc. For instance, the following is also valid:\n\n```ts\nenum Message {\n    Quit,\n    Write,\n    Move,\n}\nconst messageCodec = getDiscriminatedUnionCodec([\n    [Message.Quit, getUnitCodec()],\n    [Message.Write, getStructCodec([...])],\n    [Message.Move, getStructCodec([...])],\n]);\n\ncodec.encode({ __kind: Message.Quit });\ncodec.encode({ __kind: Message.Write, fields: ['Hi'] });\ncodec.encode({ __kind: Message.Move, x: 5, y: 6 });\n```\n\nFinally, note that separate `getDiscriminatedUnionEncoder` and `getDiscriminatedUnionDecoder` functions are available.\n\n```ts\nconst bytes = getDiscriminatedUnionEncoder(variantEncoders).encode({ __kind: 'Quit' });\nconst message = getDiscriminatedUnionDecoder(variantDecoders).decode(bytes);\n```\n\n## Union codec\n\nThe `getUnionCodec` is a lower-lever codec helper that can be used to encode/decode any TypeScript union.\n\nIt accepts the following arguments:\n\n- An array of codecs, each defining a variant of the union.\n- A `getIndexFromValue` function which, given a value of the union, returns the index of the codec that should be used to encode that value.\n- A `getIndexFromBytes` function which, given the byte array to decode at a given offset, returns the index of the codec that should be used to decode the next bytes.\n\n```ts\nconst codec: Codec<number | boolean> = getUnionCodec(\n    [getU16Codec(), getBooleanCodec()],\n    value => (typeof value === 'number' ? 0 : 1),\n    (bytes, offset) => (bytes.slice(offset).length > 1 ? 0 : 1),\n);\n\ncodec.encode(42); // 0x2a00\ncodec.encode(true); // 0x01\n```\n\nAs usual, separate `getUnionEncoder` and `getUnionDecoder` functions are also available.\n\n```ts\nconst bytes = getUnionEncoder(encoders, getIndexFromValue).encode(42);\nconst value = getUnionDecoder(decoders, getIndexFromBytes).decode(bytes);\n```\n\n## Boolean codec\n\nThe `getBooleanCodec` function returns a `Codec<boolean>` that stores the boolean as `0` or `1` using a `u8` number by default.\n\n```ts\nconst bytes = getBooleanCodec().encode(true); // 0x01\nconst value = getBooleanCodec().decode(bytes); // true\n```\n\nYou may configure that behaviour by providing an explicit number codec as the `size` option of the `getBooleanCodec` function. That number codec will then be used to encode and decode the values `0` and `1` accordingly.\n\n```ts\ngetBooleanCodec({ size: getU16Codec() }).encode(false); // 0x0000\ngetBooleanCodec({ size: getU16Codec() }).encode(true); // 0x0100\n\ngetBooleanCodec({ size: getU32Codec() }).encode(false); // 0x00000000\ngetBooleanCodec({ size: getU32Codec() }).encode(true); // 0x01000000\n```\n\nSeparate `getBooleanEncoder` and `getBooleanDecoder` functions are also available.\n\n```ts\nconst bytes = getBooleanEncoder().encode(true); // 0x01\nconst value = getBooleanDecoder().decode(bytes); // true\n```\n\n## Nullable codec\n\nThe `getNullableCodec` function accepts a codec of type `T` and returns a codec of type `T | null`. It stores whether or not the item exists as a boolean prefix using a `u8` by default.\n\n```ts\nconst stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n\ngetNullableCodec(stringCodec).encode('Hi');\n// 0x01020000004869\n//   | |       └-- utf8 string content (\"Hi\").\n//   | └-- u32 string prefix (2 characters).\n//   └-- 1-byte prefix (true — The item exists).\n\ngetNullableCodec(stringCodec).encode(null);\n// 0x00\n//   └-- 1-byte prefix (false — The item is null).\n```\n\nYou may provide a number codec as the `prefix` option of the `getNullableCodec` function to configure how to store the boolean prefix.\n\n```ts\nconst u32NullableStringCodec = getNullableCodec(stringCodec, {\n    prefix: getU32Codec(),\n});\n\nu32NullableStringCodec.encode('Hi');\n// 0x01000000020000004869\n//   └------┘ 4-byte prefix (true).\n\nu32NullableStringCodec.encode(null);\n// 0x00000000\n//   └------┘ 4-byte prefix (false).\n```\n\nAdditionally, if the item is a `FixedSizeCodec`, you may set the `noneValue` option to `\"zeroes\"` to also make the returned nullable codec a `FixedSizeCodec`. To do so, it will pad `null` values with zeroes to match the length of existing values.\n\n```ts\nconst fixedNullableStringCodec = getNullableCodec(\n    fixCodecSize(getUtf8Codec(), 8), // Only works with fixed-size items.\n    { noneValue: 'zeroes' },\n);\n\nfixedNullableStringCodec.encode('Hi');\n// 0x014869000000000000\n//   | └-- 8-byte utf8 string content (\"Hi\").\n//   └-- 1-byte prefix (true — The item exists).\n\nfixedNullableStringCodec.encode(null);\n// 0x000000000000000000\n//   | └-- 8-byte of padding to make a fixed-size codec.\n//   └-- 1-byte prefix (false — The item is null).\n```\n\nThe `noneValue` option can also be set to an explicit byte array to use as the padding for `null` values. Note that, in this case, the returned codec will not be a `FixedSizeCodec` as the byte array representing `null` values may be of any length.\n\n```ts\nconst codec = getNullableCodec(getUtf8Codec(), {\n    noneValue: new Uint8Array([255]), // 0xff means null.\n});\n\ncodec.encode('Hi');\n// 0x014869\n//   | └-- 2-byte utf8 string content (\"Hi\").\n//   └-- 1-byte prefix (true — The item exists).\n\ncodec.encode(null);\n// 0x00ff\n//   | └-- 1-byte representing null (0xff).\n//   └-- 1-byte prefix (false — The item is null).\n```\n\nLast but not least, the `prefix` option of the `getNullableCodec` function can also be set to `null`, meaning no prefix will be used to determine whether the item exists. In this case, the codec will rely on the `noneValue` option to determine whether the item is `null`.\n\n```ts\nconst codecWithZeroNoneValue = getNullableCodec(getU16Codec(), {\n    noneValue: 'zeroes', // 0x0000 means null.\n    prefix: null,\n});\ncodecWithZeroNoneValue.encode(42); // 0x2a00\ncodecWithZeroNoneValue.encode(null); // 0x0000\n\nconst codecWithCustomNoneValue = getNullableCodec(getU16Codec(), {\n    noneValue: new Uint8Array([255]), // 0xff means null.\n    prefix: null,\n});\ncodecWithCustomNoneValue.encode(42); // 0x2a00\ncodecWithCustomNoneValue.encode(null); // 0xff\n```\n\nFinally, note that if `prefix` is set to `null` and no `noneValue` is provided, the codec assumes that the item exists if and only if some remaining bytes are available to decode. This could be useful to describe data structures that may or may not have additional data to the end of the buffer.\n\n```ts\nconst codec = getNullableCodec(getU16Codec(), { prefix: null });\ncodec.encode(42); // 0x2a00\ncodec.encode(null); // Encodes nothing.\ncodec.decode(new Uint8Array([42, 0])); // 42\ncodec.decode(new Uint8Array([])); // null\n```\n\nTo recap, here are all the possible configurations of the `getNullableCodec` function, using a `u16` codec as an example.\n\n| `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n| ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n| `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n| Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n| No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\nNote that you might be interested in the Rust-like alternative version of nullable codecs, available in [the `@solana/options` package](https://github.com/anza-xyz/kit/tree/main/packages/options).\n\nSeparate `getNullableEncoder` and `getNullableDecoder` functions are also available.\n\n```ts\nconst bytes = getNullableEncoder(getU32Encoder()).encode(42);\nconst value = getNullableDecoder(getU32Decoder()).decode(bytes);\n```\n\n## Bytes codec\n\nThe `getBytesCodec` function returns a `Codec<Uint8Array>` meaning it converts `Uint8Arrays` to and from… `Uint8Arrays`! Whilst this might seem a bit useless, it can be useful when composed into other codecs. For example, you could use it in a struct codec to say that a particular field should be left unserialised.\n\n```ts\nconst bytes = getBytesCodec().encode(new Uint8Array([42])); // 0x2a\nconst value = getBytesCodec().decode(bytes); // 0x2a\n```\n\nThe `getBytesCodec` function will encode and decode `Uint8Arrays` using as much bytes as necessary. If you'd like to restrict the number of bytes used by this codec, you may combine it with the [`fixCodecSize`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#fixing-the-size-of-codecs) or [`addCodecSizePrefix`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#prefixing-the-size-of-codecs) primitives.\n\nHere are some examples of how you might use the `getBytesCodec` function.\n\n```ts\n// Variable size.\ngetBytesCodec().encode(new Uint8Array([42]));\n// 0x2a\n//   └-- Uint8Array content using any bytes available.\n\n// Prefixing the size with a 2-byte u16.\naddCodecSizePrefix(getBytesCodec(), getU16Codec()).encode(new Uint8Array([42]));\n// 0x01002a\n//   |   └-- Uint8Array content.\n//   └-- 2-byte prefix telling us to read 1 bytes\n\n// Fixing the size to 5 bytes.\nfixCodecSize(getBytesCodec(), 5).encode(new Uint8Array([42]));\n// 0x2a00000000\n//   └-- Uint8Array content padded to use exactly 5 bytes.\n```\n\nSeparate `getBytesEncoder` and `getBytesDecoder` functions are also available.\n\n```ts\nconst bytes = getBytesEncoder().encode(new Uint8Array([42]));\nconst value = getBytesDecoder().decode(bytes);\n```\n\n## Bit array codec\n\nThe `getBitArrayCodec` function returns a codec that encodes and decodes an array of booleans such that each boolean is represented by a single bit. It requires the size of the codec in bytes and an optional `backward` flag that can be used to reverse the order of the bits.\n\n```ts\nconst booleans = [true, false, true, false, true, false, true, false];\n\ngetBitArrayCodec(1).encode(booleans);\n// 0xaa or 0b10101010\n\ngetBitArrayCodec(1, { backward: true }).encode(booleans);\n// 0x55 or 0b01010101\n```\n\nSeparate `getBitArrayEncoder` and `getBitArrayDecoder` functions are also available.\n\n```ts\nconst bytes = getBitArrayEncoder(1).encode(booleans);\nconst decodedBooleans = getBitArrayDecoder(1).decode(bytes);\n```\n\n## Constant codec\n\nThe `getConstantCodec` function accepts any `Uint8Array` and returns a `Codec<void>`. When encoding, it will set the provided `Uint8Array` as-is. When decoding, it will assert that the next bytes contain the provided `Uint8Array` and move the offset forward.\n\n```ts\nconst codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n\ncodec.encode(undefined); // 0x010203\ncodec.decode(new Uint8Array([1, 2, 3])); // undefined\ncodec.decode(new Uint8Array([1, 2, 4])); // Throws an error.\n```\n\nSeparate `getConstantEncoder` and `getConstantDecoder` functions are also available.\n\n```ts\ngetConstantEncoder(new Uint8Array([1, 2, 3])).encode(undefined);\ngetConstantDecoder(new Uint8Array([1, 2, 3])).decode(new Uint8Array([1, 2, 3]));\n```\n\n## Unit codec\n\nThe `getUnitCodec` function returns a `Codec<void>` that encodes `undefined` into an empty `Uint8Array` and returns `undefined` without consuming any bytes when decoding. This is more of a low-level codec that can be used internally by other codecs. For instance, this is how discriminated union codecs describe the codecs of empty variants.\n\n```ts\ngetUnitCodec().encode(undefined); // Empty Uint8Array\ngetUnitCodec().decode(anyBytes); // undefined\n```\n\nSeparate `getUnitEncoder` and `getUnitDecoder` functions are also available.\n\n```ts\ngetUnitEncoder().encode(undefined);\ngetUnitDecoder().decode(anyBytes);\n```\n\n---\n\nTo read more about the available codecs and how to use them, check out the documentation of the main [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs).\n\n## Hidden prefix and suffix codec\n\nThe `getHiddenPrefixCodec` and `getHiddenSuffixCodec` functions allow us to respectively prepend or append a list of hidden `Codec<void>` to a given codec. When encoding, the hidden codecs will be encoded before or after the main codec and the offset will be moved accordingly. When decoding, the hidden codecs will be decoded but only the result of the main codec will be returned. This is particularly helpful when creating data structures that include constant values that should not be included in the final type.\n\n```ts\nconst codec: Codec<number> = getHiddenPrefixCodec(getU16Codec(), [\n    getConstantCodec(new Uint8Array([1, 2, 3])),\n    getConstantCodec(new Uint8Array([4, 5, 6])),\n]);\n\ncodec.encode(42);\n// 0x0102030405062a00\n//   |     |     └-- Our main u16 codec (value = 42).\n//   |     └-- Our second hidden prefix codec.\n//   └-- Our first hidden prefix codec.\n\ncodec.decode(new Uint8Array([1, 2, 3, 4, 5, 6, 42, 0])); // 42\n```\n\nAs usual, separate encoder and decoder functions are also available.\n\n```ts\ngetHiddenPrefixEncoder(encoder, prefixedEncoders);\ngetHiddenPrefixEncoder(decoder, prefixedDecoders);\ngetHiddenSuffixEncoder(encoder, suffixedEncoders);\ngetHiddenSuffixEncoder(decoder, suffixedDecoders);\n```\n"
  },
  {
    "path": "packages/codecs-data-structures/package.json",
    "content": "{\n    \"name\": \"@solana/codecs-data-structures\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Codecs for various data structures\",\n    \"homepage\": \"https://www.solanakit.com/api#solanacodecs-data-structures\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/codecs-strings\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/__setup__.ts",
    "content": "import { getBase16Encoder } from '@solana/codecs-strings';\n\nexport const b = (value: string) => getBase16Encoder().encode(value);\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/array-test.ts",
    "content": "import { addCodecSizePrefix, fixCodecSize, offsetCodec, resizeCodec } from '@solana/codecs-core';\nimport { getU8Codec, getU16Codec, getU32Codec, getU64Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, SolanaError } from '@solana/errors';\n\nimport { getArrayCodec } from '../array';\nimport { b } from './__setup__';\n\ndescribe('getArrayCodec', () => {\n    const array = getArrayCodec;\n    const u8 = getU8Codec;\n    const u16 = getU16Codec;\n    const u64 = getU64Codec;\n\n    it('encodes prefixed arrays', () => {\n        // Empty.\n        expect(array(u8()).encode([])).toStrictEqual(b('00000000')); // 4-bytes prefix.\n        expect(array(u8()).read(b('00000000'), 0)).toStrictEqual([[], 4]);\n\n        // Empty with custom prefix.\n        expect(array(u8(), { size: u8() }).encode([])).toStrictEqual(b('00')); // 1-byte prefix.\n        expect(array(u8(), { size: u8() }).read(b('00'), 0)).toStrictEqual([[], 1]);\n\n        // Numbers.\n        expect(array(u8()).encode([42, 1, 2])).toStrictEqual(b('030000002a0102'));\n        expect(array(u8()).read(b('030000002a0102'), 0)).toStrictEqual([[42, 1, 2], 4 + 3]);\n        expect(array(u8()).read(b('ffff030000002a0102'), 2)).toStrictEqual([[42, 1, 2], 2 + 4 + 3]);\n\n        // Strings.\n        const u32String = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n        expect(array(u32String).encode(['a', 'b'])).toStrictEqual(b('0200000001000000610100000062'));\n        expect(array(u32String).read(b('0200000001000000610100000062'), 0)).toStrictEqual([['a', 'b'], 4 + 10]);\n\n        // Different From and To types.\n        const arrayU64 = array<bigint | number, bigint>(u64());\n        expect(arrayU64.encode([2])).toStrictEqual(b('010000000200000000000000'));\n        expect(arrayU64.encode([2n])).toStrictEqual(b('010000000200000000000000'));\n        expect(arrayU64.read(b('010000000200000000000000'), 0)).toStrictEqual([[2n], 4 + 8]);\n    });\n\n    it('encodes fixed arrays', () => {\n        // Empty.\n        expect(array(u8(), { size: 0 }).encode([])).toStrictEqual(b(''));\n        expect(array(u8(), { size: 0 }).read(b(''), 0)).toStrictEqual([[], 0]);\n\n        // Numbers.\n        expect(array(u8(), { size: 3 }).encode([42, 1, 2])).toStrictEqual(b('2a0102'));\n        expect(array(u8(), { size: 3 }).read(b('2a0102'), 0)).toStrictEqual([[42, 1, 2], 3]);\n        expect(array(u8(), { size: 3 }).read(b('ffff2a0102'), 2)).toStrictEqual([[42, 1, 2], 5]);\n\n        // Strings.\n        const u32String = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n        expect(array(u32String, { size: 2 }).encode(['a', 'b'])).toStrictEqual(b('01000000610100000062'));\n        expect(array(u32String, { size: 2 }).read(b('01000000610100000062'), 0)).toStrictEqual([['a', 'b'], 10]);\n\n        // Different From and To types.\n        const arrayU64 = array<bigint | number, bigint>(u64(), { size: 1 });\n        expect(arrayU64.encode([2])).toStrictEqual(b('0200000000000000'));\n        expect(arrayU64.encode([2n])).toStrictEqual(b('0200000000000000'));\n        expect(arrayU64.read(b('0200000000000000'), 0)).toStrictEqual([[2n], 8]);\n\n        // It fails if the array has a different size.\n        expect(() => array(u32String, { size: 1 }).encode([])).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 0,\n                codecDescription: 'array',\n                expected: 1,\n            }),\n        );\n        expect(() => array(u32String, { size: 2 }).encode(['a', 'b', 'c'])).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 3,\n                codecDescription: 'array',\n                expected: 2,\n            }),\n        );\n\n        expect(() => array(u32String, { description: 'myDescription', size: 2 }).encode(['a', 'b', 'c'])).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 3,\n                codecDescription: 'myDescription',\n                expected: 2,\n            }),\n        );\n    });\n\n    it('encodes remainder arrays', () => {\n        const remainder = { size: 'remainder' } as const;\n\n        // Empty.\n        expect(array(u8(), remainder).encode([])).toStrictEqual(b(''));\n        expect(array(u8(), remainder).read(b(''), 0)).toStrictEqual([[], 0]);\n\n        // Numbers.\n        expect(array(u8(), remainder).encode([42, 1, 2])).toStrictEqual(b('2a0102'));\n        expect(array(u8(), remainder).read(b('2a0102'), 0)).toStrictEqual([[42, 1, 2], 3]);\n        expect(array(u8(), remainder).read(b('ffff2a0102'), 2)).toStrictEqual([[42, 1, 2], 5]);\n\n        // Strings.\n        const charString = fixCodecSize(getUtf8Codec(), 1);\n        expect(array(charString, remainder).encode(['a', 'b'])).toStrictEqual(b('6162'));\n        expect(array(charString, remainder).read(b('6162'), 0)).toStrictEqual([['a', 'b'], 2]);\n\n        // Variable sized items.\n        const u8String = addCodecSizePrefix(getUtf8Codec(), getU8Codec());\n        expect(array(u8String, remainder).encode(['a', 'bc'])).toStrictEqual(b('0161026263'));\n        expect(array(u8String, remainder).read(b('0161026263'), 0)).toStrictEqual([['a', 'bc'], 5]);\n\n        // Different From and To types.\n        const arrayU64 = array<bigint | number, bigint>(u64(), remainder);\n        expect(arrayU64.encode([2])).toStrictEqual(b('0200000000000000'));\n        expect(arrayU64.encode([2n])).toStrictEqual(b('0200000000000000'));\n        expect(arrayU64.read(b('0200000000000000'), 0)).toStrictEqual([[2n], 8]);\n    });\n\n    it('offsets the size of the array', () => {\n        const codec = array(u8(), {\n            size: offsetCodec(u8(), {\n                postOffset: ({ preOffset }) => preOffset,\n                preOffset: ({ wrapBytes }) => wrapBytes(-1),\n            }),\n        });\n        expect(codec.encode([65, 66, 67])).toStrictEqual(b('41424303'));\n        expect(codec.read(b('41424303'), 0)).toStrictEqual([[65, 66, 67], 3]);\n        expect(codec.read(b('ffff41424303'), 2)).toStrictEqual([[65, 66, 67], 5]);\n    });\n\n    it('offsets each item in the array', () => {\n        const itemCodec = offsetCodec(u8(), {\n            preOffset: ({ preOffset }) => preOffset + 2,\n        });\n        const codec = resizeCodec(array(itemCodec), () => 13);\n        expect(codec.encode([65, 66, 67])).toStrictEqual(b('03000000000041000042000043'));\n        expect(codec.read(b('03000000000041000042000043'), 0)).toStrictEqual([[65, 66, 67], 13]);\n        expect(codec.read(b('ffff03000000000041000042000043'), 2)).toStrictEqual([[65, 66, 67], 15]);\n    });\n\n    it('has the right sizes', () => {\n        expect(array(u8()).getSizeFromValue([1, 2])).toBe(4 + 2);\n        expect(array(u8()).maxSize).toBeUndefined();\n        expect(array(u8(), { size: u8() }).getSizeFromValue([1, 2])).toBe(1 + 2);\n        expect(array(u8(), { size: u8() }).maxSize).toBeUndefined();\n        expect(array(u8(), { size: 'remainder' }).getSizeFromValue([1, 2])).toBe(2);\n        expect(array(u8(), { size: 'remainder' }).maxSize).toBeUndefined();\n        expect(array(u8(), { size: 42 }).fixedSize).toBe(42);\n        expect(array(u16(), { size: 42 }).fixedSize).toBe(2 * 42);\n        const u32String = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n        expect(array(u32String, { size: 42 }).maxSize).toBeUndefined();\n        expect(array(u32String, { size: 0 }).fixedSize).toBe(0);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/bit-array-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { getBitArrayCodec } from '../bit-array';\nimport { b } from './__setup__';\n\ndescribe('getBitArrayCodec', () => {\n    const bitArray = getBitArrayCodec;\n\n    it('encodes bit arrays', () => {\n        // Helper method to create an array of booleans.\n        const a = (bits: string) => [...bits].map(bit => bit === '1');\n\n        // Single byte, all zeros.\n        expect(bitArray(1).encode(a('00000000'))).toStrictEqual(b('00'));\n        expect(bitArray(1).read(b('00'), 0)).toStrictEqual([a('00000000'), 1]);\n        expect(bitArray(1).read(b('ff00'), 1)).toStrictEqual([a('00000000'), 2]);\n\n        // Single byte, all ones.\n        expect(bitArray(1).encode(a('11111111'))).toStrictEqual(b('ff'));\n        expect(bitArray(1).read(b('ff'), 0)).toStrictEqual([a('11111111'), 1]);\n        expect(bitArray(1).read(b('00ff'), 1)).toStrictEqual([a('11111111'), 2]);\n\n        // Single byte, first 2 bits, forwards.\n        expect(bitArray(1).encode(a('11000000'))).toStrictEqual(b('c0'));\n        expect(bitArray(1).read(b('c0'), 0)).toStrictEqual([a('11000000'), 1]);\n        expect(bitArray(1).read(b('ffc0'), 1)).toStrictEqual([a('11000000'), 2]);\n\n        // Single byte, first 2 bits, backwards.\n        expect(bitArray(1, true).encode(a('11000000'))).toStrictEqual(b('03'));\n        expect(bitArray(1, true).read(b('03'), 0)).toStrictEqual([a('11000000'), 1]);\n        expect(bitArray(1, true).read(b('ff03'), 1)).toStrictEqual([a('11000000'), 2]);\n\n        // Multiple bytes, first 2 bits, forwards.\n        const bitsA = '110000000000000000000000';\n        expect(bitArray(3).encode(a(bitsA))).toStrictEqual(b('c00000'));\n        expect(bitArray(3).read(b('c00000'), 0)).toStrictEqual([a(bitsA), 3]);\n        expect(bitArray(3).read(b('ffc00000'), 1)).toStrictEqual([a(bitsA), 4]);\n\n        // Multiple bytes, first 2 bits, backwards.\n        expect(bitArray(3, true).encode(a(bitsA))).toStrictEqual(b('000003'));\n        expect(bitArray(3, true).read(b('000003'), 0)).toStrictEqual([a(bitsA), 3]);\n        expect(bitArray(3, true).read(b('ff000003'), 1)).toStrictEqual([a(bitsA), 4]);\n\n        // Multiple bytes, first half bits, forwards.\n        const bitsB = '111111111111000000000000';\n        expect(bitArray(3).encode(a(bitsB))).toStrictEqual(b('fff000'));\n        expect(bitArray(3).read(b('fff000'), 0)).toStrictEqual([a(bitsB), 3]);\n        expect(bitArray(3).read(b('00fff000'), 1)).toStrictEqual([a(bitsB), 4]);\n\n        // Multiple bytes, first half bits, backwards.\n        expect(bitArray(3, true).encode(a(bitsB))).toStrictEqual(b('000fff'));\n        expect(bitArray(3, true).read(b('000fff'), 0)).toStrictEqual([a(bitsB), 3]);\n        expect(bitArray(3, true).read(b('ff000fff'), 1)).toStrictEqual([a(bitsB), 4]);\n\n        // It pads missing boolean values with false.\n        expect(bitArray(1).encode(a('101'))).toStrictEqual(b('a0'));\n        expect(bitArray(1).read(b('a0'), 0)).toStrictEqual([a('10100000'), 1]);\n\n        // It truncates array of booleans if it is too long.\n        expect(bitArray(1).encode(a('000000001'))).toStrictEqual(b('00'));\n        expect(bitArray(1).read(b('00'), 0)).toStrictEqual([a('00000000'), 1]);\n\n        // It fails if the byte array is too short.\n        expect(() => bitArray(3).read(b('ff'), 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n                bytesLength: 1,\n                codecDescription: 'bitArray',\n                expected: 3,\n            }),\n        );\n    });\n\n    it('has the right sizes', () => {\n        expect(bitArray(42).fixedSize).toBe(42);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/boolean-test.ts",
    "content": "import { transformCodec } from '@solana/codecs-core';\nimport { getShortU16Codec, getU32Codec } from '@solana/codecs-numbers';\n\nimport { getBooleanCodec } from '../boolean';\nimport { b } from './__setup__';\n\ndescribe('getBooleanCodec', () => {\n    // A variable-size number codecs that uses 0 for `false`\n    // and the max shortU16 value for `true`.\n    const mappedShortU16 = transformCodec(\n        getShortU16Codec(),\n        v => (v === 0 ? 0 : 0xffff),\n        v => (v === 0 ? 0 : 1),\n    );\n\n    it('encodes booleans using a u8 number', () => {\n        expect(getBooleanCodec().encode(true)).toStrictEqual(b('01'));\n        expect(getBooleanCodec().encode(false)).toStrictEqual(b('00'));\n    });\n\n    it('decodes booleans using a u8 number', () => {\n        expect(getBooleanCodec().decode(b('01'))).toBe(true);\n        expect(getBooleanCodec().decode(b('00'))).toBe(false);\n    });\n\n    it('encodes booleans using a custom fixed-size number codec', () => {\n        const codec = getBooleanCodec({ size: getU32Codec() });\n        expect(codec.encode(true)).toStrictEqual(b('01000000'));\n        expect(codec.encode(false)).toStrictEqual(b('00000000'));\n    });\n\n    it('decodes booleans using a custom fixed-size number codec', () => {\n        const codec = getBooleanCodec({ size: getU32Codec() });\n        expect(codec.decode(b('01000000'))).toBe(true);\n        expect(codec.decode(b('00000000'))).toBe(false);\n    });\n\n    it('encodes booleans using a custom variable-size number codec', () => {\n        const codec = getBooleanCodec({ size: mappedShortU16 });\n        expect(codec.encode(true)).toStrictEqual(b('ffff03'));\n        expect(codec.encode(false)).toStrictEqual(b('00'));\n    });\n\n    it('decodes booleans using a custom variable-size number codec', () => {\n        const codec = getBooleanCodec({ size: mappedShortU16 });\n        expect(codec.decode(b('ffff03'))).toBe(true);\n        expect(codec.decode(b('00'))).toBe(false);\n    });\n\n    it('pushes the offset forward when writing', () => {\n        expect(getBooleanCodec().write(true, new Uint8Array(10), 6)).toBe(7);\n    });\n\n    it('pushes the offset forward when reading', () => {\n        expect(getBooleanCodec().read(b('ffff00'), 2)).toStrictEqual([false, 3]);\n    });\n\n    it('pushes the offset forward when writing using a custom size', () => {\n        expect(getBooleanCodec({ size: getU32Codec() }).write(true, new Uint8Array(10), 3)).toBe(7);\n    });\n\n    it('pushes the offset forward when reading using a custom size', () => {\n        expect(getBooleanCodec({ size: getU32Codec() }).read(b('ffff00000000'), 2)).toStrictEqual([false, 6]);\n    });\n\n    it('returns the correct default fixed size', () => {\n        const codec = getBooleanCodec();\n        expect(codec.fixedSize).toBe(1);\n    });\n\n    it('returns the correct custom fixed size', () => {\n        const codec = getBooleanCodec({ size: getU32Codec() });\n        expect(codec.fixedSize).toBe(4);\n    });\n\n    it('returns the correct custom variable size', () => {\n        const codec = getBooleanCodec({ size: mappedShortU16 });\n        expect(codec.getSizeFromValue(false)).toBe(1);\n        expect(codec.getSizeFromValue(true)).toBe(3);\n        expect(codec.maxSize).toBe(3);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/bytes-test.ts",
    "content": "import { addCodecSizePrefix, fixCodecSize, isVariableSize } from '@solana/codecs-core';\nimport { getU8Codec } from '@solana/codecs-numbers';\n\nimport { getBytesCodec } from '../bytes';\nimport { b } from './__setup__';\n\ndescribe('getBytesCodec', () => {\n    const codec = getBytesCodec();\n\n    it('encodes empty byte arrays', () => {\n        expect(codec.encode(b(''))).toStrictEqual(b(''));\n    });\n\n    it('decodes empty byte arrays', () => {\n        expect(codec.decode(b(''))).toStrictEqual(b(''));\n    });\n\n    it('encodes byte arrays as-is', () => {\n        expect(codec.encode(b('00'))).toStrictEqual(b('00'));\n        expect(codec.encode(b('2aff'))).toStrictEqual(b('2aff'));\n        expect(codec.encode(b('1234567890'))).toStrictEqual(b('1234567890'));\n    });\n\n    it('decodes byte arrays as-is', () => {\n        expect(codec.decode(b('00'))).toStrictEqual(b('00'));\n        expect(codec.decode(b('2aff'))).toStrictEqual(b('2aff'));\n        expect(codec.decode(b('1234567890'))).toStrictEqual(b('1234567890'));\n    });\n\n    it('pushes the offset forward when writing', () => {\n        expect(codec.write(b('2aff'), new Uint8Array(10), 3)).toBe(5);\n    });\n\n    it('pushes the offset forward when reading', () => {\n        expect(codec.read(b('ffff2aff00'), 2)).toStrictEqual([b('2aff00'), 5]);\n    });\n\n    it('can use fixCodecSize to become a fixed-size codec', () => {\n        const prefixedCoded = fixCodecSize(getBytesCodec(), 3);\n        expect(prefixedCoded.encode(b('2aff'))).toStrictEqual(b('2aff00'));\n        expect(prefixedCoded.encode(b('2aff00'))).toStrictEqual(b('2aff00'));\n        expect(prefixedCoded.encode(b('2aff0000'))).toStrictEqual(b('2aff00'));\n        expect(prefixedCoded.decode(b('2aff00'))).toStrictEqual(b('2aff00'));\n    });\n\n    it('can use addCodecSizePrefix to prepend the byte array length', () => {\n        const prefixedCoded = addCodecSizePrefix(getBytesCodec(), getU8Codec());\n        expect(prefixedCoded.encode(b('2aff'))).toStrictEqual(b('022aff'));\n        expect(prefixedCoded.decode(b('022aff'))).toStrictEqual(b('2aff'));\n        expect(prefixedCoded.getSizeFromValue(b('2aff'))).toBe(3);\n    });\n\n    it('returns a variable size codec', () => {\n        expect(isVariableSize(codec)).toBe(true);\n        expect(codec.getSizeFromValue(b('2aff'))).toBe(2);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/constant-test.ts",
    "content": "import { assertIsFixedSize } from '@solana/codecs-core';\nimport { SOLANA_ERROR__CODECS__INVALID_CONSTANT, SolanaError } from '@solana/errors';\n\nimport { getConstantCodec } from '../constant';\nimport { b } from './__setup__';\n\ndescribe('getConstantCodec', () => {\n    it('encodes the provided constant', () => {\n        const codec = getConstantCodec(b('010203'));\n        expect(codec.encode(undefined)).toStrictEqual(b('010203'));\n    });\n\n    it('decodes undefined when the constant is present', () => {\n        const codec = getConstantCodec(b('010203'));\n        expect(codec.decode(b('010203'))).toBeUndefined();\n    });\n\n    it('pushes the offset forward when writing', () => {\n        const codec = getConstantCodec(b('010203'));\n        expect(codec.write(undefined, new Uint8Array(10), 3)).toBe(6);\n    });\n\n    it('pushes the offset forward when reading', () => {\n        const codec = getConstantCodec(b('010203'));\n        expect(codec.read(b('ffff01020300'), 2)).toStrictEqual([undefined, 5]);\n    });\n\n    it('throws when the decoded bytes do no contain the constant bytes', () => {\n        const codec = getConstantCodec(b('010203'));\n        expect(() => codec.decode(b('0102ff'))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_CONSTANT, {\n                constant: b('010203'),\n                data: b('0102ff'),\n                hexConstant: '010203',\n                hexData: '0102ff',\n                offset: 0,\n            }),\n        );\n    });\n\n    it('returns a fixed size codec of the size of the provided byte array', () => {\n        const codec = getConstantCodec(b('010203'));\n        assertIsFixedSize(codec);\n        expect(codec.fixedSize).toBe(3);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/discriminated-union-test.ts",
    "content": "import {\n    addCodecSizePrefix,\n    assertIsFixedSize,\n    assertIsVariableSize,\n    isFixedSize,\n    isVariableSize,\n    offsetCodec,\n    resizeCodec,\n} from '@solana/codecs-core';\nimport { getU8Codec, getU16Codec, getU32Codec, getU64Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT,\n    SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { getArrayCodec } from '../array';\nimport { getBooleanCodec } from '../boolean';\nimport { getDiscriminatedUnionCodec } from '../discriminated-union';\nimport { getStructCodec } from '../struct';\nimport { getTupleCodec } from '../tuple';\nimport { getUnitCodec } from '../unit';\nimport { b } from './__setup__';\n\ndescribe('getDiscriminatedUnionCodec', () => {\n    const discriminatedUnion = getDiscriminatedUnionCodec;\n    const array = getArrayCodec;\n    const boolean = getBooleanCodec;\n    const struct = getStructCodec;\n    const tuple = getTupleCodec;\n    const u8 = getU8Codec;\n    const u16 = getU16Codec;\n    const u32 = getU32Codec;\n    const u64 = getU64Codec;\n    const unit = getUnitCodec;\n    const u32String = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n\n    type WebEvent =\n        | { __kind: 'Click'; x: number; y: number } // Struct variant.\n        | { __kind: 'KeyPress'; fields: [string] } // Tuple variant.\n        | { __kind: 'PageLoad' } // Empty variant.\n        | { __kind: 'PageUnload' }; // Empty variant (using empty struct).\n\n    const getWebEvent = () =>\n        [\n            ['PageLoad', unit()],\n            [\n                'Click',\n                struct([\n                    ['x', u8()],\n                    ['y', u8()],\n                ]),\n            ],\n            ['KeyPress', struct([['fields', tuple([u32String])]])],\n            ['PageUnload', struct([])],\n        ] as const;\n\n    const getSameSizeVariants = () =>\n        [\n            ['A', struct([['value', u16()]])],\n            [\n                'B',\n                struct([\n                    ['x', u8()],\n                    ['y', u8()],\n                ]),\n            ],\n            ['C', struct([['items', array(boolean(), { size: 2 })]])],\n        ] as const;\n\n    const getU64Enum = () =>\n        [\n            ['A', unit()],\n            ['B', struct([['value', u64()]])],\n        ] as const;\n\n    it('encodes empty variants', () => {\n        const pageLoad: WebEvent = { __kind: 'PageLoad' };\n        expect(discriminatedUnion(getWebEvent()).encode(pageLoad)).toStrictEqual(b('00'));\n        expect(discriminatedUnion(getWebEvent()).read(b('00'), 0)).toStrictEqual([pageLoad, 1]);\n        expect(discriminatedUnion(getWebEvent()).read(b('ffff00'), 2)).toStrictEqual([pageLoad, 3]);\n        const pageUnload: WebEvent = { __kind: 'PageUnload' };\n        expect(discriminatedUnion(getWebEvent()).encode(pageUnload)).toStrictEqual(b('03'));\n        expect(discriminatedUnion(getWebEvent()).read(b('03'), 0)).toStrictEqual([pageUnload, 1]);\n        expect(discriminatedUnion(getWebEvent()).read(b('ffff03'), 2)).toStrictEqual([pageUnload, 3]);\n    });\n\n    it('encodes struct variants', () => {\n        const click = (x: number, y: number): WebEvent => ({ __kind: 'Click', x, y });\n        expect(discriminatedUnion(getWebEvent()).encode(click(0, 0))).toStrictEqual(b('010000'));\n        expect(discriminatedUnion(getWebEvent()).read(b('010000'), 0)).toStrictEqual([click(0, 0), 3]);\n        expect(discriminatedUnion(getWebEvent()).read(b('ffff010000'), 2)).toStrictEqual([click(0, 0), 5]);\n        expect(discriminatedUnion(getWebEvent()).encode(click(1, 2))).toStrictEqual(b('010102'));\n        expect(discriminatedUnion(getWebEvent()).read(b('010102'), 0)).toStrictEqual([click(1, 2), 3]);\n        expect(discriminatedUnion(getWebEvent()).read(b('ffff010102'), 2)).toStrictEqual([click(1, 2), 5]);\n    });\n\n    it('encodes tuple variants', () => {\n        const press = (k: string): WebEvent => ({ __kind: 'KeyPress', fields: [k] });\n        expect(discriminatedUnion(getWebEvent()).encode(press(''))).toStrictEqual(b('0200000000'));\n        expect(discriminatedUnion(getWebEvent()).read(b('0200000000'), 0)).toStrictEqual([press(''), 5]);\n        expect(discriminatedUnion(getWebEvent()).read(b('ffff0200000000'), 2)).toStrictEqual([press(''), 7]);\n        expect(discriminatedUnion(getWebEvent()).encode(press('1'))).toStrictEqual(b('020100000031'));\n        expect(discriminatedUnion(getWebEvent()).read(b('020100000031'), 0)).toStrictEqual([press('1'), 6]);\n        expect(discriminatedUnion(getWebEvent()).read(b('ffff020100000031'), 2)).toStrictEqual([press('1'), 8]);\n        expect(discriminatedUnion(getWebEvent()).encode(press('語'))).toStrictEqual(b('0203000000e8aa9e'));\n        expect(discriminatedUnion(getWebEvent()).encode(press('enter'))).toStrictEqual(b('0205000000656e746572'));\n    });\n\n    it('handles invalid variants', () => {\n        expect(() => discriminatedUnion(getWebEvent()).encode({ __kind: 'Missing' } as unknown as WebEvent)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT, {\n                value: 'Missing',\n                variants: ['PageLoad', 'Click', 'KeyPress', 'PageUnload'],\n            }),\n        );\n        expect(() => discriminatedUnion(getWebEvent()).read(new Uint8Array([4]), 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE, { maxRange: 3, minRange: 0, variant: 4 }),\n        );\n    });\n\n    it('encodes discriminated unions with different From and To types', () => {\n        const codec = discriminatedUnion(getU64Enum());\n        expect(codec.encode({ __kind: 'B', value: 2 })).toStrictEqual(b('010200000000000000'));\n        expect(codec.encode({ __kind: 'B', value: 2n })).toStrictEqual(b('010200000000000000'));\n        expect(codec.read(b('010200000000000000'), 0)).toStrictEqual([{ __kind: 'B', value: 2n }, 9]);\n    });\n\n    it('encodes discriminated unions with a custom prefix', () => {\n        const codec = discriminatedUnion(getSameSizeVariants(), { size: u32() });\n        expect(codec.encode({ __kind: 'A', value: 42 })).toStrictEqual(b('000000002a00'));\n        expect(codec.read(b('000000002a00'), 0)).toStrictEqual([{ __kind: 'A', value: 42 }, 6]);\n    });\n\n    it('encodes discriminated unions with a custom discriminator property', () => {\n        const codec = discriminatedUnion(\n            [\n                ['small', struct([['value', u8()]])],\n                ['large', struct([['value', u32()]])],\n            ],\n            { discriminator: 'size' },\n        );\n        expect(codec.encode({ size: 'small', value: 42 })).toStrictEqual(b('002a'));\n        expect(codec.read(b('002a'), 0)).toStrictEqual([{ size: 'small', value: 42 }, 2]);\n        expect(codec.encode({ size: 'large', value: 42 })).toStrictEqual(b('012a000000'));\n        expect(codec.read(b('012a000000'), 0)).toStrictEqual([{ size: 'large', value: 42 }, 5]);\n    });\n\n    it('encodes discriminated unions with number discriminator values', () => {\n        const codec = discriminatedUnion([\n            [1, struct([['one', u8()]])],\n            [2, struct([['two', u32()]])],\n        ]);\n        expect(codec.encode({ __kind: 1, one: 42 })).toStrictEqual(b('002a'));\n        expect(codec.read(b('002a'), 0)).toStrictEqual([{ __kind: 1, one: 42 }, 2]);\n    });\n\n    it('encodes discriminated unions with boolean discriminator values', () => {\n        const codec = discriminatedUnion([\n            [true, struct([['truth', u8()]])],\n            [false, struct([['lie', u32()]])],\n        ]);\n        expect(codec.encode({ __kind: true, truth: 42 })).toStrictEqual(b('002a'));\n        expect(codec.read(b('002a'), 0)).toStrictEqual([{ __kind: true, truth: 42 }, 2]);\n    });\n\n    it('encodes discriminated unions with enum discriminator values', () => {\n        enum Event {\n            Click,\n            KeyPress,\n        }\n        const codec = discriminatedUnion([\n            [\n                Event.Click,\n                struct([\n                    ['x', u8()],\n                    ['y', u8()],\n                ]),\n            ],\n            [Event.KeyPress, struct([['key', u32()]])],\n        ]);\n        expect(codec.encode({ __kind: Event.Click, x: 1, y: 2 })).toStrictEqual(b('000102'));\n        expect(codec.read(b('000102'), 0)).toStrictEqual([{ __kind: Event.Click, x: 1, y: 2 }, 3]);\n    });\n\n    it('has the right sizes', () => {\n        const webEvent = discriminatedUnion(getWebEvent());\n        expect(isVariableSize(webEvent)).toBe(true);\n        assertIsVariableSize(webEvent);\n        expect(webEvent.getSizeFromValue({ __kind: 'PageLoad' })).toBe(1);\n        expect(webEvent.getSizeFromValue({ __kind: 'PageUnload' })).toBe(1);\n        expect(webEvent.getSizeFromValue({ __kind: 'Click', x: 0, y: 1 })).toBe(1 + 2);\n        expect(webEvent.getSizeFromValue({ __kind: 'KeyPress', fields: ['ABC'] })).toBe(1 + 4 + 3);\n        expect(webEvent.maxSize).toBeUndefined();\n\n        const sameSize = discriminatedUnion(getSameSizeVariants());\n        expect(isFixedSize(sameSize)).toBe(true);\n        assertIsFixedSize(sameSize);\n        expect(sameSize.fixedSize).toBe(3);\n\n        const sameSizeU32 = discriminatedUnion(getSameSizeVariants(), { size: u32() });\n        expect(isFixedSize(sameSizeU32)).toBe(true);\n        assertIsFixedSize(sameSizeU32);\n        expect(sameSizeU32.fixedSize).toBe(6);\n\n        const u64Enum = discriminatedUnion(getU64Enum());\n        expect(isVariableSize(u64Enum)).toBe(true);\n        assertIsVariableSize(u64Enum);\n        expect(u64Enum.maxSize).toBe(9);\n    });\n\n    it('offsets variants within a discriminated union', () => {\n        const offsettedU32 = offsetCodec(\n            resizeCodec(u32(), size => size + 2),\n            { preOffset: ({ preOffset }) => preOffset + 2 },\n        );\n        const codec = discriminatedUnion([\n            ['Simple', struct([['n', u32()]])],\n            ['WithOffset', struct([['n', offsettedU32]])],\n        ]);\n\n        const simple = { __kind: 'Simple', n: 42 } as const;\n        expect(codec.encode(simple)).toStrictEqual(b('002a000000'));\n        expect(codec.read(b('002a000000'), 0)).toStrictEqual([simple, 5]);\n        expect(codec.read(b('ffff002a000000'), 2)).toStrictEqual([simple, 7]);\n\n        const withOffset = { __kind: 'WithOffset', n: 42 } as const;\n        expect(codec.encode(withOffset)).toStrictEqual(b('0100002a000000'));\n        expect(codec.read(b('0100002a000000'), 0)).toStrictEqual([withOffset, 7]);\n        expect(codec.read(b('ffff0100002a000000'), 2)).toStrictEqual([withOffset, 9]);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/enum-helpers-test.ts",
    "content": "import {\n    formatNumericalValues,\n    getEnumIndexFromDiscriminator,\n    getEnumIndexFromVariant,\n    getEnumStats,\n} from '../enum-helpers';\n\ndescribe('getEnumStats', () => {\n    it('handles sequential numerical enums', () => {\n        enum Feedback {\n            Bad,\n            Good,\n        }\n        expect(getEnumStats(Feedback)).toStrictEqual({\n            enumKeys: ['Bad', 'Good'],\n            enumRecord: { Bad: 0, Good: 1 },\n            enumValues: [0, 1],\n            numericalValues: [0, 1],\n            stringValues: ['Bad', 'Good'],\n        });\n    });\n\n    it('handles explicit numerical enums', () => {\n        enum Prime {\n            Two = 2,\n            Three,\n            Five = 5,\n        }\n        expect(getEnumStats(Prime)).toStrictEqual({\n            enumKeys: ['Two', 'Three', 'Five'],\n            enumRecord: { Five: 5, Three: 3, Two: 2 },\n            enumValues: [2, 3, 5],\n            numericalValues: [2, 3, 5],\n            stringValues: ['Two', 'Three', 'Five'],\n        });\n    });\n\n    it('handles conflicting numerical enums', () => {\n        enum FortyTwo {\n            One = 42,\n            // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values\n            Two = 42,\n        }\n        expect(getEnumStats(FortyTwo)).toStrictEqual({\n            enumKeys: ['One', 'Two'],\n            enumRecord: { One: 42, Two: 42 },\n            enumValues: [42, 42],\n            numericalValues: [42],\n            stringValues: ['One', 'Two'],\n        });\n    });\n\n    it('handles lexical enums', () => {\n        enum Direction {\n            Up = '↑',\n            Down = '↓',\n            Left = '←',\n            Right = '→',\n        }\n        expect(getEnumStats(Direction)).toStrictEqual({\n            enumKeys: ['Up', 'Down', 'Left', 'Right'],\n            enumRecord: { Down: '↓', Left: '←', Right: '→', Up: '↑' },\n            enumValues: ['↑', '↓', '←', '→'],\n            numericalValues: [],\n            stringValues: ['Up', 'Down', 'Left', 'Right', '↑', '↓', '←', '→'],\n        });\n    });\n\n    it('handles hybrid enums', () => {\n        enum Hybrid {\n            Zero,\n            One,\n            Five = 5,\n            Six,\n            Seven = 'nana',\n            Nine = 9,\n            // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values\n            NineAgain = 9,\n        }\n        expect(getEnumStats(Hybrid)).toStrictEqual({\n            enumKeys: ['Zero', 'One', 'Five', 'Six', 'Seven', 'Nine', 'NineAgain'],\n            enumRecord: { Five: 5, Nine: 9, NineAgain: 9, One: 1, Seven: 'nana', Six: 6, Zero: 0 },\n            enumValues: [0, 1, 5, 6, 'nana', 9, 9],\n            numericalValues: [0, 1, 5, 6, 9],\n            stringValues: ['Zero', 'One', 'Five', 'Six', 'Seven', 'Nine', 'NineAgain', 'nana'],\n        });\n    });\n});\n\ndescribe('getEnumIndexFromVariant', () => {\n    it('get indices from enum values', () => {\n        enum Numbers {\n            One,\n            Two = 'two',\n            Three = 3,\n        }\n        const stats = getEnumStats(Numbers);\n        expect(getEnumIndexFromVariant({ ...stats, variant: Numbers.One })).toBe(0);\n        expect(getEnumIndexFromVariant({ ...stats, variant: Numbers.Two })).toBe(1);\n        expect(getEnumIndexFromVariant({ ...stats, variant: Numbers.Three })).toBe(2);\n    });\n\n    it('get indices from enum keys', () => {\n        enum Numbers {\n            One,\n            Two = 'two',\n            Three = 3,\n        }\n        const stats = getEnumStats(Numbers);\n        expect(getEnumIndexFromVariant({ ...stats, variant: 'One' })).toBe(0);\n        expect(getEnumIndexFromVariant({ ...stats, variant: 'Two' })).toBe(1);\n        expect(getEnumIndexFromVariant({ ...stats, variant: 'Three' })).toBe(2);\n    });\n\n    it('prioritizes indices from values', () => {\n        enum CrossedValues {\n            A = 'B',\n            B = 'A',\n        }\n        const stats = getEnumStats(CrossedValues);\n        expect(getEnumIndexFromVariant({ ...stats, variant: 'A' })).toBe(1);\n        expect(getEnumIndexFromVariant({ ...stats, variant: 'B' })).toBe(0);\n    });\n\n    it('uses the last index when duplicated numerical values are provided', () => {\n        enum Duplicates {\n            A = 42,\n            // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values\n            B = 42,\n        }\n        const stats = getEnumStats(Duplicates);\n        expect(getEnumIndexFromVariant({ ...stats, variant: 42 })).toBe(1);\n    });\n\n    it('uses the last index when duplicated lexical values are provided', () => {\n        enum Duplicates {\n            A = 'FortyTwo',\n            // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values\n            B = 'FortyTwo',\n        }\n        const stats = getEnumStats(Duplicates);\n        expect(getEnumIndexFromVariant({ ...stats, variant: 'FortyTwo' })).toBe(1);\n    });\n});\n\ndescribe('getEnumIndexFromDiscriminator', () => {\n    it('returns the discriminant as the index', () => {\n        enum Numbers {\n            One,\n            Two = 'two',\n            Three = 3,\n        }\n        const configs = { ...getEnumStats(Numbers), useValuesAsDiscriminators: false };\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 0 })).toBe(0);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 1 })).toBe(1);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 2 })).toBe(2);\n    });\n\n    it('returns -1 if the discriminant is out of range', () => {\n        enum Numbers {\n            One,\n            Two,\n        }\n        const configs = { ...getEnumStats(Numbers), useValuesAsDiscriminators: false };\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: -1 })).toBe(-1);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 2 })).toBe(-1);\n    });\n\n    it('returns the numerical value as the index if useValuesAsDiscriminators is true', () => {\n        enum Numbers {\n            Zero,\n            One,\n            Five = 5,\n            Six,\n            Nine = 9,\n        }\n        const configs = { ...getEnumStats(Numbers), useValuesAsDiscriminators: true };\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 0 })).toBe(0);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 1 })).toBe(1);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 5 })).toBe(2);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 6 })).toBe(3);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 9 })).toBe(4);\n    });\n\n    it('returns -1 if the discriminant is not a value and useValuesAsDiscriminators is true', () => {\n        enum Numbers {\n            Zero,\n            One,\n            Five = 5,\n            Six,\n            Nine = 'nine',\n        }\n        const configs = { ...getEnumStats(Numbers), useValuesAsDiscriminators: true };\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: -1 })).toBe(-1);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 2 })).toBe(-1);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 3 })).toBe(-1);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 4 })).toBe(-1);\n        expect(getEnumIndexFromDiscriminator({ ...configs, discriminator: 9 })).toBe(-1);\n    });\n});\n\ndescribe('formatNumericalValues', () => {\n    it('formats an empty array to an empty string', () => {\n        expect(formatNumericalValues([])).toBe('');\n    });\n\n    it('formats a single value', () => {\n        expect(formatNumericalValues([1])).toBe('1');\n    });\n\n    it('formats a single range', () => {\n        expect(formatNumericalValues([4, 5, 6, 7, 8])).toBe('4-8');\n    });\n\n    it('formats non-consecutive numbers', () => {\n        expect(formatNumericalValues([3, 5, 7, 11, 13])).toBe('3, 5, 7, 11, 13');\n    });\n\n    it('formats a mixture of ranges and non-consecutive numbers', () => {\n        expect(formatNumericalValues([1, 2, 3, 5, 12, 13, 14, 15, 42, 89, 90, 100])).toBe(\n            '1-3, 5, 12-15, 42, 89-90, 100',\n        );\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/enum-test.ts",
    "content": "import { getShortU16Codec, getU32Codec } from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS,\n    SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT,\n    SolanaError,\n} from '@solana/errors';\n\nimport { getEnumCodec } from '../enum';\nimport { b } from './__setup__';\n\ndescribe('getEnumCodec', () => {\n    describe('sequential numerical enums', () => {\n        enum Feedback {\n            Bad,\n            Good,\n        }\n        const codec = getEnumCodec(Feedback);\n\n        it('encodes enums by value', () => {\n            expect(codec.encode(Feedback.Bad)).toStrictEqual(b('00'));\n            expect(codec.encode(Feedback.Good)).toStrictEqual(b('01'));\n        });\n\n        it('encodes enums by key', () => {\n            expect(codec.encode('Bad')).toStrictEqual(b('00'));\n            expect(codec.encode('Good')).toStrictEqual(b('01'));\n        });\n\n        it('decodes enum values', () => {\n            expect(codec.decode(b('00'))).toBe(Feedback.Bad);\n            expect(codec.decode(b('01'))).toBe(Feedback.Good);\n        });\n\n        it('pushes the offset forward when writing', () => {\n            expect(codec.write(Feedback.Bad, new Uint8Array(10), 6)).toBe(7);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            expect(codec.read(b('ffff00'), 2)).toStrictEqual([Feedback.Bad, 3]);\n        });\n\n        it('throws an error when trying to encode a missing variant', () => {\n            // @ts-expect-error Invalid enum variant.\n            expect(() => getEnumCodec(Feedback).encode('Missing')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {\n                    formattedNumericalValues: '0-1',\n                    numericalValues: [0, 1],\n                    stringValues: ['Bad', 'Good'],\n                    variant: 'Missing',\n                }),\n            );\n        });\n\n        it('throws an error when trying to decode a out-of-range discriminator', () => {\n            expect(() => codec.decode(b('02'))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                    discriminator: 2,\n                    formattedValidDiscriminators: '0-1',\n                    validDiscriminators: [0, 1],\n                }),\n            );\n        });\n\n        it('encodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Feedback, { size: getU32Codec() });\n            expect(u32Codec.encode(Feedback.Bad)).toStrictEqual(b('00000000'));\n            expect(u32Codec.encode(Feedback.Good)).toStrictEqual(b('01000000'));\n        });\n\n        it('decodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Feedback, { size: getU32Codec() });\n            expect(u32Codec.decode(b('00000000'))).toBe(Feedback.Bad);\n            expect(u32Codec.decode(b('01000000'))).toBe(Feedback.Good);\n        });\n\n        it('returns the correct default fixed size', () => {\n            expect(codec.fixedSize).toBe(1);\n        });\n\n        it('returns the correct custom fixed size', () => {\n            const u32Codec = getEnumCodec(Feedback, { size: getU32Codec() });\n            expect(u32Codec.fixedSize).toBe(4);\n        });\n\n        it('returns the correct custom variable size', () => {\n            const u32Codec = getEnumCodec(Feedback, { size: getShortU16Codec() });\n            expect(u32Codec.getSizeFromValue(Feedback.Bad)).toBe(1);\n            expect(u32Codec.maxSize).toBe(3);\n        });\n    });\n\n    describe('explicit numerical enums', () => {\n        enum Numbers {\n            Zero,\n            Five = 5,\n            Six,\n            Nine = 9,\n        }\n        const codec = getEnumCodec(Numbers);\n\n        it('encodes enums by value', () => {\n            expect(codec.encode(Numbers.Zero)).toStrictEqual(b('00'));\n            expect(codec.encode(Numbers.Five)).toStrictEqual(b('01'));\n            expect(codec.encode(Numbers.Six)).toStrictEqual(b('02'));\n            expect(codec.encode(Numbers.Nine)).toStrictEqual(b('03'));\n        });\n\n        it('encodes enums by key', () => {\n            expect(codec.encode('Zero')).toStrictEqual(b('00'));\n            expect(codec.encode('Five')).toStrictEqual(b('01'));\n            expect(codec.encode('Six')).toStrictEqual(b('02'));\n            expect(codec.encode('Nine')).toStrictEqual(b('03'));\n        });\n\n        it('decodes enum values', () => {\n            expect(codec.decode(b('00'))).toBe(Numbers.Zero);\n            expect(codec.decode(b('01'))).toBe(Numbers.Five);\n            expect(codec.decode(b('02'))).toBe(Numbers.Six);\n            expect(codec.decode(b('03'))).toBe(Numbers.Nine);\n        });\n\n        it('pushes the offset forward when writing', () => {\n            expect(codec.write(Numbers.Zero, new Uint8Array(10), 6)).toBe(7);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            expect(codec.read(b('ffff00'), 2)).toStrictEqual([Numbers.Zero, 3]);\n        });\n\n        it('throws an error when trying to encode a missing variant', () => {\n            // @ts-expect-error Invalid enum variant.\n            expect(() => codec.encode('Missing')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {\n                    formattedNumericalValues: '0, 5-6, 9',\n                    numericalValues: [0, 5, 6, 9],\n                    stringValues: ['Zero', 'Five', 'Six', 'Nine'],\n                    variant: 'Missing',\n                }),\n            );\n        });\n\n        it('throws an error when trying to decode a out-of-range discriminator', () => {\n            expect(() => codec.decode(b('04'))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                    discriminator: 4,\n                    formattedValidDiscriminators: '0-3',\n                    validDiscriminators: [0, 1, 2, 3],\n                }),\n            );\n        });\n\n        it('encodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Numbers, { size: getU32Codec() });\n            expect(u32Codec.encode(Numbers.Zero)).toStrictEqual(b('00000000'));\n            expect(u32Codec.encode(Numbers.Five)).toStrictEqual(b('01000000'));\n            expect(u32Codec.encode(Numbers.Six)).toStrictEqual(b('02000000'));\n            expect(u32Codec.encode(Numbers.Nine)).toStrictEqual(b('03000000'));\n        });\n\n        it('decodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Numbers, { size: getU32Codec() });\n            expect(u32Codec.decode(b('00000000'))).toBe(Numbers.Zero);\n            expect(u32Codec.decode(b('01000000'))).toBe(Numbers.Five);\n            expect(u32Codec.decode(b('02000000'))).toBe(Numbers.Six);\n            expect(u32Codec.decode(b('03000000'))).toBe(Numbers.Nine);\n        });\n\n        it('returns the correct default fixed size', () => {\n            expect(codec.fixedSize).toBe(1);\n        });\n\n        it('returns the correct custom fixed size', () => {\n            const u32Codec = getEnumCodec(Numbers, { size: getU32Codec() });\n            expect(u32Codec.fixedSize).toBe(4);\n        });\n\n        it('returns the correct custom variable size', () => {\n            const u32Codec = getEnumCodec(Numbers, { size: getShortU16Codec() });\n            expect(u32Codec.getSizeFromValue(Numbers.Zero)).toBe(1);\n            expect(u32Codec.maxSize).toBe(3);\n        });\n    });\n\n    describe('explicit numerical enums using values as discriminators', () => {\n        enum Numbers {\n            Zero,\n            Five = 5,\n            Six,\n            Nine = 9,\n        }\n        const codec = getEnumCodec(Numbers, { useValuesAsDiscriminators: true });\n\n        it('encodes enums by value', () => {\n            expect(codec.encode(Numbers.Zero)).toStrictEqual(b('00'));\n            expect(codec.encode(Numbers.Five)).toStrictEqual(b('05'));\n            expect(codec.encode(Numbers.Six)).toStrictEqual(b('06'));\n            expect(codec.encode(Numbers.Nine)).toStrictEqual(b('09'));\n        });\n\n        it('encodes enums by key', () => {\n            expect(codec.encode('Zero')).toStrictEqual(b('00'));\n            expect(codec.encode('Five')).toStrictEqual(b('05'));\n            expect(codec.encode('Six')).toStrictEqual(b('06'));\n            expect(codec.encode('Nine')).toStrictEqual(b('09'));\n        });\n\n        it('decodes enum values', () => {\n            expect(codec.decode(b('00'))).toBe(Numbers.Zero);\n            expect(codec.decode(b('05'))).toBe(Numbers.Five);\n            expect(codec.decode(b('06'))).toBe(Numbers.Six);\n            expect(codec.decode(b('09'))).toBe(Numbers.Nine);\n        });\n\n        it('pushes the offset forward when writing', () => {\n            expect(codec.write(Numbers.Zero, new Uint8Array(10), 6)).toBe(7);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            expect(codec.read(b('ffff00'), 2)).toStrictEqual([Numbers.Zero, 3]);\n        });\n\n        it('throws an error when trying to encode a missing variant', () => {\n            // @ts-expect-error Invalid enum variant.\n            expect(() => codec.encode('Missing')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {\n                    formattedNumericalValues: '0, 5-6, 9',\n                    numericalValues: [0, 5, 6, 9],\n                    stringValues: ['Zero', 'Five', 'Six', 'Nine'],\n                    variant: 'Missing',\n                }),\n            );\n        });\n\n        it('throws an error when trying to decode a out-of-range discriminator', () => {\n            expect(() => codec.decode(b('01'))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                    discriminator: 1,\n                    formattedValidDiscriminators: '0, 5-6, 9',\n                    validDiscriminators: [0, 5, 6, 9],\n                }),\n            );\n        });\n\n        it('encodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Numbers, { size: getU32Codec(), useValuesAsDiscriminators: true });\n            expect(u32Codec.encode(Numbers.Zero)).toStrictEqual(b('00000000'));\n            expect(u32Codec.encode(Numbers.Five)).toStrictEqual(b('05000000'));\n            expect(u32Codec.encode(Numbers.Six)).toStrictEqual(b('06000000'));\n            expect(u32Codec.encode(Numbers.Nine)).toStrictEqual(b('09000000'));\n        });\n\n        it('decodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Numbers, { size: getU32Codec(), useValuesAsDiscriminators: true });\n            expect(u32Codec.decode(b('00000000'))).toBe(Numbers.Zero);\n            expect(u32Codec.decode(b('05000000'))).toBe(Numbers.Five);\n            expect(u32Codec.decode(b('06000000'))).toBe(Numbers.Six);\n            expect(u32Codec.decode(b('09000000'))).toBe(Numbers.Nine);\n        });\n\n        it('returns the correct default fixed size', () => {\n            expect(codec.fixedSize).toBe(1);\n        });\n\n        it('returns the correct custom fixed size', () => {\n            const u32Codec = getEnumCodec(Numbers, { size: getU32Codec() });\n            expect(u32Codec.fixedSize).toBe(4);\n        });\n\n        it('returns the correct custom variable size', () => {\n            const u32Codec = getEnumCodec(Numbers, { size: getShortU16Codec() });\n            expect(u32Codec.getSizeFromValue(Numbers.Zero)).toBe(1);\n            expect(u32Codec.maxSize).toBe(3);\n        });\n    });\n\n    describe('conflicting numerical enums', () => {\n        enum Duplicates {\n            A = 42,\n            // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values\n            B = 42,\n        }\n        const codec = getEnumCodec(Duplicates);\n\n        it('uses the last index when encoding enums by value', () => {\n            expect(codec.encode(Duplicates.A)).toStrictEqual(b('01'));\n            expect(codec.encode(Duplicates.B)).toStrictEqual(b('01'));\n        });\n\n        it('encodes enums by key', () => {\n            expect(codec.encode('A')).toStrictEqual(b('00'));\n            expect(codec.encode('B')).toStrictEqual(b('01'));\n        });\n\n        it('decodes enum values', () => {\n            expect(codec.decode(b('00'))).toBe(Duplicates.A);\n            expect(codec.decode(b('01'))).toBe(Duplicates.B);\n        });\n\n        it('throws an error when trying to encode a missing variant', () => {\n            // @ts-expect-error Invalid enum variant.\n            expect(() => codec.encode('Missing')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {\n                    formattedNumericalValues: '42',\n                    numericalValues: [42],\n                    stringValues: ['A', 'B'],\n                    variant: 'Missing',\n                }),\n            );\n        });\n\n        it('throws an error when trying to decode a out-of-range discriminator', () => {\n            expect(() => codec.decode(b('02'))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                    discriminator: 2,\n                    formattedValidDiscriminators: '0-1',\n                    validDiscriminators: [0, 1],\n                }),\n            );\n        });\n    });\n\n    describe('conflicting numerical enums using values as discriminators', () => {\n        enum Duplicates {\n            A = 42,\n            // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values\n            B = 42,\n        }\n        const codec = getEnumCodec(Duplicates, { useValuesAsDiscriminators: true });\n\n        it('encodes conflicting enum variants by value', () => {\n            expect(codec.encode(Duplicates.A)).toStrictEqual(b('2a'));\n            expect(codec.encode(Duplicates.B)).toStrictEqual(b('2a'));\n        });\n\n        it('encodes conflicting enum variants by key', () => {\n            expect(codec.encode('A')).toStrictEqual(b('2a'));\n            expect(codec.encode('B')).toStrictEqual(b('2a'));\n        });\n\n        it('uses the last variant when decoding conflicting variants', () => {\n            expect(codec.decode(b('2a'))).toBe(Duplicates.B);\n        });\n\n        it('throws an error when trying to encode a missing variant', () => {\n            // @ts-expect-error Invalid enum variant.\n            expect(() => codec.encode('Missing')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {\n                    formattedNumericalValues: '42',\n                    numericalValues: [42],\n                    stringValues: ['A', 'B'],\n                    variant: 'Missing',\n                }),\n            );\n        });\n\n        it('throws an error when trying to decode a out-of-range discriminator', () => {\n            expect(() => codec.decode(b('01'))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                    discriminator: 1,\n                    formattedValidDiscriminators: '42',\n                    validDiscriminators: [42],\n                }),\n            );\n        });\n    });\n\n    describe('lexical enums', () => {\n        enum Direction {\n            Up = '↑',\n            Down = '↓',\n            Left = '←',\n            Right = '→',\n        }\n        const codec = getEnumCodec(Direction);\n\n        it('encodes enums by value', () => {\n            expect(codec.encode(Direction.Up)).toStrictEqual(b('00'));\n            expect(codec.encode(Direction.Down)).toStrictEqual(b('01'));\n            expect(codec.encode(Direction.Left)).toStrictEqual(b('02'));\n            expect(codec.encode(Direction.Right)).toStrictEqual(b('03'));\n            expect(codec.encode('↑' as Direction)).toStrictEqual(b('00'));\n            expect(codec.encode('↓' as Direction)).toStrictEqual(b('01'));\n            expect(codec.encode('←' as Direction)).toStrictEqual(b('02'));\n            expect(codec.encode('→' as Direction)).toStrictEqual(b('03'));\n        });\n\n        it('encodes enums by key', () => {\n            expect(codec.encode('Up')).toStrictEqual(b('00'));\n            expect(codec.encode('Down')).toStrictEqual(b('01'));\n            expect(codec.encode('Left')).toStrictEqual(b('02'));\n            expect(codec.encode('Right')).toStrictEqual(b('03'));\n        });\n\n        it('decodes enum values', () => {\n            expect(codec.decode(b('00'))).toBe(Direction.Up);\n            expect(codec.decode(b('01'))).toBe(Direction.Down);\n            expect(codec.decode(b('02'))).toBe(Direction.Left);\n            expect(codec.decode(b('03'))).toBe(Direction.Right);\n        });\n\n        it('pushes the offset forward when writing', () => {\n            expect(codec.write(Direction.Up, new Uint8Array(10), 6)).toBe(7);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            expect(codec.read(b('ffff00'), 2)).toStrictEqual([Direction.Up, 3]);\n        });\n\n        it('throws an error when trying to encode a missing variant', () => {\n            // @ts-expect-error Invalid enum variant.\n            expect(() => getEnumCodec(Direction).encode('Missing')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {\n                    formattedNumericalValues: '',\n                    numericalValues: [],\n                    stringValues: ['Up', 'Down', 'Left', 'Right', '↑', '↓', '←', '→'],\n                    variant: 'Missing',\n                }),\n            );\n        });\n\n        it('throws an error when trying to decode a out-of-range discriminator', () => {\n            expect(() => codec.decode(b('04'))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                    discriminator: 4,\n                    formattedValidDiscriminators: '0-3',\n                    validDiscriminators: [0, 1, 2, 3],\n                }),\n            );\n        });\n\n        it('encodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Direction, { size: getU32Codec() });\n            expect(u32Codec.encode(Direction.Up)).toStrictEqual(b('00000000'));\n            expect(u32Codec.encode(Direction.Down)).toStrictEqual(b('01000000'));\n            expect(u32Codec.encode(Direction.Left)).toStrictEqual(b('02000000'));\n            expect(u32Codec.encode(Direction.Right)).toStrictEqual(b('03000000'));\n        });\n\n        it('decodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Direction, { size: getU32Codec() });\n            expect(u32Codec.decode(b('00000000'))).toBe(Direction.Up);\n            expect(u32Codec.decode(b('01000000'))).toBe(Direction.Down);\n            expect(u32Codec.decode(b('02000000'))).toBe(Direction.Left);\n            expect(u32Codec.decode(b('03000000'))).toBe(Direction.Right);\n        });\n\n        it('returns the correct default fixed size', () => {\n            expect(codec.fixedSize).toBe(1);\n        });\n\n        it('returns the correct custom fixed size', () => {\n            const u32Codec = getEnumCodec(Direction, { size: getU32Codec() });\n            expect(u32Codec.fixedSize).toBe(4);\n        });\n\n        it('returns the correct custom variable size', () => {\n            const u32Codec = getEnumCodec(Direction, { size: getShortU16Codec() });\n            expect(u32Codec.getSizeFromValue(Direction.Up)).toBe(1);\n            expect(u32Codec.maxSize).toBe(3);\n        });\n    });\n\n    describe('hybrid enums', () => {\n        enum Hybrid {\n            Zero,\n            Five = 5,\n            Six,\n            Seven = 'seven',\n        }\n        const codec = getEnumCodec(Hybrid);\n\n        it('encodes enums by value', () => {\n            expect(codec.encode(Hybrid.Zero)).toStrictEqual(b('00'));\n            expect(codec.encode(Hybrid.Five)).toStrictEqual(b('01'));\n            expect(codec.encode(Hybrid.Six)).toStrictEqual(b('02'));\n            expect(codec.encode(Hybrid.Seven)).toStrictEqual(b('03'));\n            expect(codec.encode(0 as Hybrid)).toStrictEqual(b('00'));\n            expect(codec.encode(5 as Hybrid)).toStrictEqual(b('01'));\n            expect(codec.encode(6 as Hybrid)).toStrictEqual(b('02'));\n            expect(codec.encode('seven' as Hybrid)).toStrictEqual(b('03'));\n        });\n\n        it('encodes enums by key', () => {\n            expect(codec.encode('Zero')).toStrictEqual(b('00'));\n            expect(codec.encode('Five')).toStrictEqual(b('01'));\n            expect(codec.encode('Six')).toStrictEqual(b('02'));\n            expect(codec.encode('Seven')).toStrictEqual(b('03'));\n        });\n\n        it('decodes enum values', () => {\n            expect(codec.decode(b('00'))).toBe(Hybrid.Zero);\n            expect(codec.decode(b('01'))).toBe(Hybrid.Five);\n            expect(codec.decode(b('02'))).toBe(Hybrid.Six);\n            expect(codec.decode(b('03'))).toBe(Hybrid.Seven);\n        });\n\n        it('pushes the offset forward when writing', () => {\n            expect(codec.write(Hybrid.Zero, new Uint8Array(10), 6)).toBe(7);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            expect(codec.read(b('ffff00'), 2)).toStrictEqual([Hybrid.Zero, 3]);\n        });\n\n        it('throws an error when trying to encode a missing variant', () => {\n            // @ts-expect-error Invalid enum variant.\n            expect(() => codec.encode('Missing')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {\n                    formattedNumericalValues: '0, 5-6',\n                    numericalValues: [0, 5, 6],\n                    stringValues: ['Zero', 'Five', 'Six', 'Seven', 'seven'],\n                    variant: 'Missing',\n                }),\n            );\n        });\n\n        it('throws an error when trying to decode a out-of-range discriminator', () => {\n            expect(() => codec.decode(b('04'))).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                    discriminator: 4,\n                    formattedValidDiscriminators: '0-3',\n                    validDiscriminators: [0, 1, 2, 3],\n                }),\n            );\n        });\n\n        it('encodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Hybrid, { size: getU32Codec() });\n            expect(u32Codec.encode(Hybrid.Zero)).toStrictEqual(b('00000000'));\n            expect(u32Codec.encode(Hybrid.Five)).toStrictEqual(b('01000000'));\n            expect(u32Codec.encode(Hybrid.Six)).toStrictEqual(b('02000000'));\n            expect(u32Codec.encode(Hybrid.Seven)).toStrictEqual(b('03000000'));\n        });\n\n        it('decodes enums using a custom discriminator size', () => {\n            const u32Codec = getEnumCodec(Hybrid, { size: getU32Codec() });\n            expect(u32Codec.decode(b('00000000'))).toBe(Hybrid.Zero);\n            expect(u32Codec.decode(b('01000000'))).toBe(Hybrid.Five);\n            expect(u32Codec.decode(b('02000000'))).toBe(Hybrid.Six);\n            expect(u32Codec.decode(b('03000000'))).toBe(Hybrid.Seven);\n        });\n\n        it('returns the correct default fixed size', () => {\n            expect(codec.fixedSize).toBe(1);\n        });\n\n        it('returns the correct custom fixed size', () => {\n            const u32Codec = getEnumCodec(Hybrid, { size: getU32Codec() });\n            expect(u32Codec.fixedSize).toBe(4);\n        });\n\n        it('returns the correct custom variable size', () => {\n            const u32Codec = getEnumCodec(Hybrid, { size: getShortU16Codec() });\n            expect(u32Codec.getSizeFromValue(Hybrid.Zero)).toBe(1);\n            expect(u32Codec.maxSize).toBe(3);\n        });\n\n        it('throws an error when trying to use values as discriminators', () => {\n            expect(() => getEnumCodec(Hybrid, { useValuesAsDiscriminators: true })).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS, {\n                    stringValues: ['seven'],\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/hidden-prefix-test.ts",
    "content": "import { assertIsFixedSize, assertIsVariableSize } from '@solana/codecs-core';\nimport { getU8Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\n\nimport { getConstantCodec } from '../constant';\nimport { getHiddenPrefixCodec } from '../hidden-prefix';\nimport { b } from './__setup__';\n\ndescribe('getHiddenPrefixCodec', () => {\n    const prefixA = getConstantCodec(b('aa'));\n    const prefixB = getConstantCodec(b('bb'));\n\n    it('encodes all prefixes before the main encoder', () => {\n        const codec = getHiddenPrefixCodec(getU8Codec(), [prefixA, prefixB]);\n        expect(codec.encode(1)).toStrictEqual(b('aabb01'));\n    });\n\n    it('decodes only the main decoder', () => {\n        const codec = getHiddenPrefixCodec(getU8Codec(), [prefixA, prefixB]);\n        expect(codec.decode(b('aabb01'))).toBe(1);\n    });\n\n    it('pushes the offset forward when writing', () => {\n        const codec = getHiddenPrefixCodec(getU8Codec(), [prefixA, prefixB]);\n        expect(codec.write(1, new Uint8Array(10), 2)).toBe(5);\n    });\n\n    it('pushes the offset forward when reading', () => {\n        const codec = getHiddenPrefixCodec(getU8Codec(), [prefixA, prefixB]);\n        expect(codec.read(b('ffffaabb0100'), 2)).toStrictEqual([1, 5]);\n    });\n\n    it('returns a fixed-size if the main codec and all prefix codecs are fixed-size', () => {\n        const codec = getHiddenPrefixCodec(getU8Codec(), [prefixA, prefixB]);\n        assertIsFixedSize(codec);\n        expect(codec.fixedSize).toBe(3);\n    });\n\n    it('returns a variable-size codec if at least one of the codec is variable-size', () => {\n        const codec = getHiddenPrefixCodec(getUtf8Codec(), [prefixA, prefixB]);\n        assertIsVariableSize(codec);\n        expect(codec.getSizeFromValue('hello')).toBe(7);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/hidden-suffix-test.ts",
    "content": "import { assertIsFixedSize, assertIsVariableSize } from '@solana/codecs-core';\nimport { getU8Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\n\nimport { getConstantCodec } from '../constant';\nimport { getHiddenSuffixCodec } from '../hidden-suffix';\nimport { b } from './__setup__';\n\ndescribe('getHiddenSuffixCodec', () => {\n    const suffixA = getConstantCodec(b('aa'));\n    const suffixB = getConstantCodec(b('bb'));\n\n    it('encodes all suffixes after the main encoder', () => {\n        const codec = getHiddenSuffixCodec(getU8Codec(), [suffixA, suffixB]);\n        expect(codec.encode(1)).toStrictEqual(b('01aabb'));\n    });\n\n    it('decodes only the main decoder', () => {\n        const codec = getHiddenSuffixCodec(getU8Codec(), [suffixA, suffixB]);\n        expect(codec.decode(b('01aabb'))).toBe(1);\n    });\n\n    it('pushes the offset forward when writing', () => {\n        const codec = getHiddenSuffixCodec(getU8Codec(), [suffixA, suffixB]);\n        expect(codec.write(1, new Uint8Array(10), 2)).toBe(5);\n    });\n\n    it('pushes the offset forward when reading', () => {\n        const codec = getHiddenSuffixCodec(getU8Codec(), [suffixA, suffixB]);\n        expect(codec.read(b('ffff01aabb00'), 2)).toStrictEqual([1, 5]);\n    });\n\n    it('returns a fixed-size if the main codec and all suffix codecs are fixed-size', () => {\n        const codec = getHiddenSuffixCodec(getU8Codec(), [suffixA, suffixB]);\n        assertIsFixedSize(codec);\n        expect(codec.fixedSize).toBe(3);\n    });\n\n    it('returns a variable-size codec if at least one of the codec is variable-size', () => {\n        const codec = getHiddenSuffixCodec(getUtf8Codec(), [suffixA, suffixB]);\n        assertIsVariableSize(codec);\n        expect(codec.getSizeFromValue('hello')).toBe(7);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/literal-union-test.ts",
    "content": "import { assertIsFixedSize, assertIsVariableSize } from '@solana/codecs-core';\nimport { getShortU16Codec, getU32Codec } from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT,\n    SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { getLiteralUnionCodec } from '../literal-union';\nimport { b } from './__setup__';\n\ndescribe('getLiteralUnionCodec', () => {\n    it('encodes string unions', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C']);\n        expect(codec.encode('A')).toStrictEqual(b('00'));\n        expect(codec.encode('B')).toStrictEqual(b('01'));\n        expect(codec.encode('C')).toStrictEqual(b('02'));\n    });\n\n    it('decodes string unions', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C']);\n        expect(codec.decode(b('00'))).toBe('A');\n        expect(codec.decode(b('01'))).toBe('B');\n        expect(codec.decode(b('02'))).toBe('C');\n    });\n\n    it('encodes number and bigint unions', () => {\n        const codec = getLiteralUnionCodec([1, 2n, 3]);\n        expect(codec.encode(1)).toStrictEqual(b('00'));\n        expect(codec.encode(2n)).toStrictEqual(b('01'));\n        expect(codec.encode(3)).toStrictEqual(b('02'));\n    });\n\n    it('decodes number and bigint unions', () => {\n        const codec = getLiteralUnionCodec([1, 2n, 3]);\n        expect(codec.decode(b('00'))).toBe(1);\n        expect(codec.decode(b('01'))).toBe(2n);\n        expect(codec.decode(b('02'))).toBe(3);\n    });\n\n    it('encodes boolean unions', () => {\n        const codec = getLiteralUnionCodec([true, false]);\n        expect(codec.encode(true)).toStrictEqual(b('00'));\n        expect(codec.encode(false)).toStrictEqual(b('01'));\n    });\n\n    it('decodes boolean unions', () => {\n        const codec = getLiteralUnionCodec([true, false]);\n        expect(codec.decode(b('00'))).toBe(true);\n        expect(codec.decode(b('01'))).toBe(false);\n    });\n\n    it('encodes null and undefined unions', () => {\n        const codec = getLiteralUnionCodec([null, undefined]);\n        expect(codec.encode(null)).toStrictEqual(b('00'));\n        expect(codec.encode(undefined)).toStrictEqual(b('01'));\n    });\n\n    it('decodes null and undefined unions', () => {\n        const codec = getLiteralUnionCodec([null, undefined]);\n        expect(codec.decode(b('00'))).toBeNull();\n        expect(codec.decode(b('01'))).toBeUndefined();\n    });\n\n    it('pushes the offset forward when writing', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C']);\n        expect(codec.write('A', new Uint8Array(10), 6)).toBe(7);\n    });\n\n    it('pushes the offset forward when reading', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C']);\n        expect(codec.read(b('ffff00'), 2)).toStrictEqual(['A', 3]);\n    });\n\n    it('encodes using a custom discriminator size', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C'], {\n            size: getU32Codec(),\n        });\n        expect(codec.encode('A')).toStrictEqual(b('00000000'));\n        expect(codec.encode('B')).toStrictEqual(b('01000000'));\n        expect(codec.encode('C')).toStrictEqual(b('02000000'));\n    });\n\n    it('decodes using a custom discriminator size', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C'], {\n            size: getU32Codec(),\n        });\n        expect(codec.decode(b('00000000'))).toBe('A');\n        expect(codec.decode(b('01000000'))).toBe('B');\n        expect(codec.decode(b('02000000'))).toBe('C');\n    });\n\n    it('throws when provided with an invalid variant', () => {\n        const codec = getLiteralUnionCodec(['one', 2, 3n, false, null]);\n        // @ts-expect-error Expected invalid variant.\n        expect(() => codec.encode('missing')).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT, {\n                value: 'missing',\n                variants: ['one', 2, 3n, false, null],\n            }),\n        );\n    });\n\n    it('throws when provided with an invalid discriminator', () => {\n        const codec = getLiteralUnionCodec(['one', 2, 3n, false, null]);\n        expect(() => codec.decode(b('05'))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE, {\n                discriminator: 5,\n                maxRange: 4,\n                minRange: 0,\n            }),\n        );\n    });\n\n    it('returns the correct default fixed size', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C']);\n        assertIsFixedSize(codec);\n        expect(codec.fixedSize).toBe(1);\n    });\n\n    it('returns the correct custom fixed size', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C'], { size: getU32Codec() });\n        assertIsFixedSize(codec);\n        expect(codec.fixedSize).toBe(4);\n    });\n\n    it('returns the correct custom variable size', () => {\n        const codec = getLiteralUnionCodec(['A', 'B', 'C'], { size: getShortU16Codec() });\n        assertIsVariableSize(codec);\n        expect(codec.getSizeFromValue('A')).toBe(1);\n        expect(codec.maxSize).toBe(3);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/map-test.ts",
    "content": "import { addCodecSizePrefix, fixCodecSize } from '@solana/codecs-core';\nimport { getU8Codec, getU16Codec, getU32Codec, getU64Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, SolanaError } from '@solana/errors';\n\nimport { getMapCodec } from '../map';\nimport { b } from './__setup__';\n\ndescribe('getMapCodec', () => {\n    const map = getMapCodec;\n    const u8 = getU8Codec;\n    const u16 = getU16Codec;\n    const u64 = getU64Codec;\n    const u8String = addCodecSizePrefix(getUtf8Codec(), getU8Codec());\n    const u32String = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n\n    it('encodes prefixed maps', () => {\n        // Empty.\n        expect(map(u8(), u8()).encode(new Map())).toStrictEqual(b('00000000')); // 4-bytes prefix.\n        expect(map(u8(), u8()).read(b('00000000'), 0)).toStrictEqual([new Map(), 4]);\n\n        // Empty with custom prefix.\n        expect(map(u8(), u8(), { size: u8() }).encode(new Map())).toStrictEqual(b('00')); // 1-byte prefix.\n        expect(map(u8(), u8(), { size: u8() }).read(b('00'), 0)).toStrictEqual([new Map(), 1]);\n\n        // Numbers.\n        expect(map(u8(), u8()).encode(new Map([[1, 2]]))).toStrictEqual(b('010000000102'));\n        expect(map(u8(), u8()).read(b('010000000102'), 0)).toStrictEqual([new Map([[1, 2]]), 6]);\n        expect(map(u8(), u8()).read(b('ffff010000000102'), 2)).toStrictEqual([new Map([[1, 2]]), 8]);\n\n        // Strings.\n        const letters = new Map([\n            ['a', 1],\n            ['b', 2],\n        ]);\n        expect(map(u32String, u8()).encode(letters)).toStrictEqual(b('02000000010000006101010000006202'));\n        expect(map(u32String, u8()).read(b('02000000010000006101010000006202'), 0)).toStrictEqual([letters, 16]);\n\n        // Different From and To types.\n        const mapU8U64 = map<number, bigint | number, number, bigint>(u8(), u64());\n        expect(mapU8U64.encode(new Map().set(42, 2))).toStrictEqual(b('010000002a0200000000000000'));\n        expect(mapU8U64.encode(new Map().set(42, 2n))).toStrictEqual(b('010000002a0200000000000000'));\n        expect(mapU8U64.read(b('010000002a0200000000000000'), 0)).toStrictEqual([new Map().set(42, 2n), 13]);\n    });\n\n    it('encodes fixed maps', () => {\n        // Empty.\n        expect(map(u8(), u8(), { size: 0 }).encode(new Map())).toStrictEqual(b(''));\n        expect(map(u8(), u8(), { size: 0 }).read(b(''), 0)).toStrictEqual([new Map(), 0]);\n\n        // Numbers.\n        expect(map(u8(), u8(), { size: 1 }).encode(new Map([[1, 2]]))).toStrictEqual(b('0102'));\n        expect(map(u8(), u8(), { size: 1 }).read(b('0102'), 0)).toStrictEqual([new Map([[1, 2]]), 2]);\n        expect(map(u8(), u8(), { size: 1 }).read(b('ffff0102'), 2)).toStrictEqual([new Map([[1, 2]]), 4]);\n\n        // Strings.\n        const letters = map(u32String, u8(), { size: 2 });\n        const lettersMap = new Map([\n            ['a', 1],\n            ['b', 2],\n        ]);\n        expect(letters.encode(lettersMap)).toStrictEqual(b('010000006101010000006202'));\n        expect(letters.read(b('010000006101010000006202'), 0)).toStrictEqual([lettersMap, 12]);\n\n        // Different From and To types.\n        const mapU64 = map<number, bigint | number, number, bigint>(u8(), u64(), {\n            size: 1,\n        });\n        expect(mapU64.encode(new Map([[1, 2]]))).toStrictEqual(b('010200000000000000'));\n        expect(mapU64.encode(new Map([[1, 2n]]))).toStrictEqual(b('010200000000000000'));\n        expect(mapU64.read(b('010200000000000000'), 0)).toStrictEqual([new Map([[1, 2n]]), 9]);\n\n        // It fails if the map has a different size.\n        expect(() => map(u8(), u8(), { size: 1 }).encode(new Map())).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 0,\n                codecDescription: 'array',\n                expected: 1,\n            }),\n        );\n        expect(() => letters.encode(lettersMap.set('c', 3))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 3,\n                codecDescription: 'array',\n                expected: 2,\n            }),\n        );\n    });\n\n    it('encodes remainder maps', () => {\n        const remainder = { size: 'remainder' } as const;\n\n        // Empty.\n        expect(map(u8(), u8(), remainder).encode(new Map())).toStrictEqual(b(''));\n        expect(map(u8(), u8(), remainder).read(b(''), 0)).toStrictEqual([new Map(), 0]);\n\n        // Numbers.\n        expect(map(u8(), u8(), remainder).encode(new Map([[1, 2]]))).toStrictEqual(b('0102'));\n        expect(map(u8(), u8(), remainder).read(b('0102'), 0)).toStrictEqual([new Map([[1, 2]]), 2]);\n        expect(map(u8(), u8(), remainder).read(b('ffff0102'), 2)).toStrictEqual([new Map([[1, 2]]), 4]);\n\n        // Strings.\n        const letters = map(fixCodecSize(getUtf8Codec(), 1), u8(), { size: 2 });\n        const lettersMap = new Map([\n            ['a', 1],\n            ['b', 2],\n        ]);\n        expect(letters.encode(lettersMap)).toStrictEqual(b('61016202'));\n        expect(letters.read(b('61016202'), 0)).toStrictEqual([lettersMap, 4]);\n\n        // Variable sized items.\n        const prefixedLetters = map(u8String, u8(), remainder);\n        const prefixedLettersMap = new Map([\n            ['a', 6],\n            ['bc', 7],\n        ]);\n        expect(prefixedLetters.encode(prefixedLettersMap)).toStrictEqual(b('01610602626307'));\n        expect(prefixedLetters.read(b('01610602626307'), 0)).toStrictEqual([prefixedLettersMap, 7]);\n\n        // Different From and To types.\n        const mapU64 = map<number, bigint | number, number, bigint>(u8(), u64(), remainder);\n        expect(mapU64.encode(new Map([[1, 2]]))).toStrictEqual(b('010200000000000000'));\n        expect(mapU64.encode(new Map([[1, 2n]]))).toStrictEqual(b('010200000000000000'));\n        expect(mapU64.read(b('010200000000000000'), 0)).toStrictEqual([new Map([[1, 2n]]), 9]);\n    });\n\n    it('has the right sizes', () => {\n        const testMap = new Map([\n            [1, 2],\n            [3, 4],\n        ]);\n        expect(map(u8(), u8()).getSizeFromValue(testMap)).toBe(4 + 2 * 2);\n        expect(map(u8(), u8()).maxSize).toBeUndefined();\n        expect(map(u8(), u8(), { size: u8() }).getSizeFromValue(testMap)).toBe(1 + 2 * 2);\n        expect(map(u8(), u8(), { size: u8() }).maxSize).toBeUndefined();\n        expect(map(u8(), u8(), { size: 'remainder' }).getSizeFromValue(testMap)).toBe(2 * 2);\n        expect(map(u8(), u8(), { size: 'remainder' }).maxSize).toBeUndefined();\n        expect(map(u8(), u8(), { size: 42 }).fixedSize).toBe(2 * 42);\n        expect(map(u8(), u16(), { size: 42 }).fixedSize).toBe(3 * 42);\n        expect(map(u8(), u32String, { size: 42 }).maxSize).toBeUndefined();\n        expect(map(u8(), u32String, { size: 0 }).fixedSize).toBe(0);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/nullable-test.ts",
    "content": "import { getShortU16Codec, getU8Codec, getU16Codec, getU32Codec, getU64Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH, SolanaError } from '@solana/errors';\n\nimport { getNullableCodec } from '../nullable';\nimport { b } from './__setup__';\n\ndescribe('getNullableCodec', () => {\n    describe('with prefix', () => {\n        it('encodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec());\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00'));\n        });\n\n        it('decodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec());\n            expect(codec.decode(b('010000'))).toBe(0);\n            expect(codec.decode(b('012a00'))).toBe(42);\n            expect(codec.decode(b('00'))).toBeNull();\n        });\n\n        it('encodes nullable numbers with explicit prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { prefix: getU8Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00'));\n        });\n\n        it('decodes nullable numbers with explicit prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { prefix: getU8Codec() });\n            expect(codec.decode(b('010000'))).toBe(0);\n            expect(codec.decode(b('012a00'))).toBe(42);\n            expect(codec.decode(b('00'))).toBeNull();\n        });\n\n        it('encodes nullable numbers with custom prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { prefix: getU32Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000000000'));\n            expect(codec.encode(42)).toStrictEqual(b('010000002a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00000000'));\n        });\n\n        it('decodes nullable numbers with custom prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { prefix: getU32Codec() });\n            expect(codec.decode(b('010000000000'))).toBe(0);\n            expect(codec.decode(b('010000002a00'))).toBe(42);\n            expect(codec.decode(b('00000000'))).toBeNull();\n        });\n\n        it('encodes nullable variable strings', () => {\n            const codec = getNullableCodec(getUtf8Codec());\n            expect(codec.encode('Hello')).toStrictEqual(b('0148656c6c6f'));\n            expect(codec.encode(null)).toStrictEqual(b('00'));\n        });\n\n        it('decodes nullable variable strings', () => {\n            const codec = getNullableCodec(getUtf8Codec());\n            expect(codec.decode(b('0148656c6c6f'))).toBe('Hello');\n            expect(codec.decode(b('00'))).toBeNull();\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getNullableCodec(getU16Codec());\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(6);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(4);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getNullableCodec(getU16Codec());\n            expect(codec.read(b('ffff01010100'), 2)).toStrictEqual([257, 5]);\n            expect(codec.read(b('ffff00'), 2)).toStrictEqual([null, 3]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getNullableCodec(getU64Codec());\n            expect(codec.encode(2)).toStrictEqual(b('010200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('010200000000000000'));\n            expect(codec.decode(b('010200000000000000'))).toBe(2n);\n        });\n\n        it('returns a variable size codec with max size', () => {\n            const codec = getNullableCodec(getU16Codec());\n            expect(codec.getSizeFromValue(null)).toBe(1);\n            expect(codec.getSizeFromValue(42)).toBe(3);\n            expect(codec.maxSize).toBe(3);\n        });\n    });\n\n    describe('with zeroable none value', () => {\n        it('encodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(null)).toStrictEqual(b('0000'));\n        });\n\n        it('decodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.decode(b('2a00'))).toBe(42);\n            expect(codec.decode(b('0000'))).toBeNull();\n        });\n\n        it('can end up encoding the none value', () => {\n            // ...because the item codec could use offsets to update the bytes in different ways.\n            // Therefore checking that the encoded value is the same as the none value is not enough.\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.encode(0)).toStrictEqual(b('0000'));\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(5);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(5);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.read(b('ffff010100'), 2)).toStrictEqual([257, 4]);\n            expect(codec.read(b('ffff000000'), 2)).toStrictEqual([null, 4]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getNullableCodec(getU64Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.encode(2)).toStrictEqual(b('0200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('0200000000000000'));\n            expect(codec.decode(b('0200000000000000'))).toBe(2n);\n        });\n\n        it('returns a fixed size codec', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.fixedSize).toBe(2);\n        });\n\n        it('fails if the items is not fixed', () => {\n            // @ts-expect-error It cannot wrap a variable size item when fixed is true.\n            expect(() => getNullableCodec(getUtf8Codec(), { noneValue: 'zeroes', prefix: null })).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH),\n            );\n        });\n    });\n\n    describe('with custom none value', () => {\n        it('encodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(null)).toStrictEqual(b('ffff'));\n        });\n\n        it('decodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.decode(b('2a00'))).toBe(42);\n            expect(codec.decode(b('ffff'))).toBeNull();\n        });\n\n        it('can end up encoding the none value', () => {\n            // ...because the item codec could use offsets to update the bytes in different ways.\n            // Therefore checking that the encoded value is the same as the none value is not enough.\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.encode(65535)).toStrictEqual(b('ffff'));\n        });\n\n        it('encodes nullable variable strings', () => {\n            const codec = getNullableCodec(getUtf8Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.encode('Hello')).toStrictEqual(b('48656c6c6f'));\n            expect(codec.encode(null)).toStrictEqual(b('ffff'));\n        });\n\n        it('decodes nullable variable strings', () => {\n            const codec = getNullableCodec(getUtf8Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.decode(b('48656c6c6f'))).toBe('Hello');\n            expect(codec.decode(b('ffff'))).toBeNull();\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(5);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(5);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('aaaa'), prefix: null });\n            expect(codec.read(b('ffff010100'), 2)).toStrictEqual([257, 4]);\n            expect(codec.read(b('ffffaaaa00'), 2)).toStrictEqual([null, 4]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getNullableCodec(getU64Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.encode(2)).toStrictEqual(b('0200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('0200000000000000'));\n            expect(codec.decode(b('0200000000000000'))).toBe(2n);\n        });\n\n        it('returns a variable size codec', () => {\n            // ...because the item and the none value do not need to have the same length.\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffffffff'), prefix: null });\n            expect(codec.getSizeFromValue(null)).toBe(4);\n            expect(codec.getSizeFromValue(42)).toBe(2);\n            expect(codec.maxSize).toBe(4);\n        });\n    });\n\n    describe('with prefix and zeroable none value', () => {\n        it('encodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('000000'));\n        });\n\n        it('decodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.decode(b('010000'))).toBe(0);\n            expect(codec.decode(b('012a00'))).toBe(42);\n            expect(codec.decode(b('000000'))).toBeNull();\n        });\n\n        it('encodes nullable numbers with explicit prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getU8Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('000000'));\n        });\n\n        it('decodes nullable numbers with explicit prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getU8Codec() });\n            expect(codec.decode(b('010000'))).toBe(0);\n            expect(codec.decode(b('012a00'))).toBe(42);\n            expect(codec.decode(b('000000'))).toBeNull();\n        });\n\n        it('encodes nullable numbers with custom prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getU32Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000000000'));\n            expect(codec.encode(42)).toStrictEqual(b('010000002a00'));\n            expect(codec.encode(null)).toStrictEqual(b('000000000000'));\n        });\n\n        it('decodes nullable numbers with custom prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getU32Codec() });\n            expect(codec.decode(b('010000000000'))).toBe(0);\n            expect(codec.decode(b('010000002a00'))).toBe(42);\n            expect(codec.decode(b('000000000000'))).toBeNull();\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(6);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(6);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.read(b('ffff01010100'), 2)).toStrictEqual([257, 5]);\n            expect(codec.read(b('ffff00000000'), 2)).toStrictEqual([null, 5]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getNullableCodec(getU64Codec(), { noneValue: 'zeroes' });\n            expect(codec.encode(2)).toStrictEqual(b('010200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('010200000000000000'));\n            expect(codec.decode(b('010200000000000000'))).toBe(2n);\n        });\n\n        it('returns a fixed size codec if the prefix is fixed', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.fixedSize).toBe(3);\n        });\n\n        it('returns a variable size codec if the prefix is variable', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getShortU16Codec() });\n            expect(codec.getSizeFromValue(null)).toBe(3);\n            expect(codec.getSizeFromValue(42)).toBe(3);\n            expect(codec.maxSize).toBe(5);\n        });\n\n        it('fails if the items is not fixed', () => {\n            // @ts-expect-error It cannot wrap a variable size item when fixed is true.\n            expect(() => getNullableCodec(getUtf8Codec(), { noneValue: 'zeroes' })).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH),\n            );\n        });\n    });\n\n    describe('with prefix and custom none value', () => {\n        it('encodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff') });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00ffff'));\n        });\n\n        it('decodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff') });\n            expect(codec.decode(b('010000'))).toBe(0);\n            expect(codec.decode(b('012a00'))).toBe(42);\n            expect(codec.decode(b('00ffff'))).toBeNull();\n        });\n\n        it('encodes nullable numbers with explicit prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff'), prefix: getU8Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00ffff'));\n        });\n\n        it('decodes nullable numbers with explicit prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff'), prefix: getU8Codec() });\n            expect(codec.decode(b('010000'))).toBe(0);\n            expect(codec.decode(b('012a00'))).toBe(42);\n            expect(codec.decode(b('00ffff'))).toBeNull();\n        });\n\n        it('encodes nullable numbers with custom prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff'), prefix: getU32Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000000000'));\n            expect(codec.encode(42)).toStrictEqual(b('010000002a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00000000ffff'));\n        });\n\n        it('decodes nullable numbers with custom prefix', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff'), prefix: getU32Codec() });\n            expect(codec.decode(b('010000000000'))).toBe(0);\n            expect(codec.decode(b('010000002a00'))).toBe(42);\n            expect(codec.decode(b('00000000ffff'))).toBeNull();\n        });\n\n        it('encodes nullable variable strings', () => {\n            const codec = getNullableCodec(getUtf8Codec(), { noneValue: b('ffff') });\n            expect(codec.encode('Hello')).toStrictEqual(b('0148656c6c6f'));\n            expect(codec.encode(null)).toStrictEqual(b('00ffff'));\n        });\n\n        it('decodes nullable variable strings', () => {\n            const codec = getNullableCodec(getUtf8Codec(), { noneValue: b('ffff') });\n            expect(codec.decode(b('0148656c6c6f'))).toBe('Hello');\n            expect(codec.decode(b('00ffff'))).toBeNull();\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffff') });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(6);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(6);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('aaaa') });\n            expect(codec.read(b('ffff01010100'), 2)).toStrictEqual([257, 5]);\n            expect(codec.read(b('ffff00aaaa00'), 2)).toStrictEqual([null, 5]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getNullableCodec(getU64Codec(), { noneValue: b('ffff') });\n            expect(codec.encode(2)).toStrictEqual(b('010200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('010200000000000000'));\n            expect(codec.decode(b('010200000000000000'))).toBe(2n);\n        });\n\n        it('returns a variable size codec', () => {\n            // ...because the item and the none value do not need to have the same length.\n            const codec = getNullableCodec(getU16Codec(), { noneValue: b('ffffffff') });\n            expect(codec.getSizeFromValue(null)).toBe(5);\n            expect(codec.getSizeFromValue(42)).toBe(3);\n            expect(codec.maxSize).toBe(5);\n        });\n    });\n\n    describe('with no prefix nor none value', () => {\n        it('encodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { prefix: null });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(null)).toStrictEqual(b(''));\n        });\n\n        it('decodes nullable numbers', () => {\n            const codec = getNullableCodec(getU16Codec(), { prefix: null });\n            expect(codec.decode(b('2a00'))).toBe(42);\n            expect(codec.decode(b(''))).toBeNull();\n        });\n\n        it('encodes nullable variable strings', () => {\n            const codec = getNullableCodec(getUtf8Codec(), { prefix: null });\n            expect(codec.encode('Hello')).toStrictEqual(b('48656c6c6f'));\n            expect(codec.encode(null)).toStrictEqual(b(''));\n        });\n\n        it('decodes nullable variable strings', () => {\n            const codec = getNullableCodec(getUtf8Codec(), { prefix: null });\n            expect(codec.decode(b('48656c6c6f'))).toBe('Hello');\n            expect(codec.decode(b(''))).toBeNull();\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getNullableCodec(getU16Codec(), { prefix: null });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(5);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(3);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getNullableCodec(getU16Codec(), { prefix: null });\n            expect(codec.read(b('ffff010100'), 2)).toStrictEqual([257, 4]);\n            expect(codec.read(b('ffff'), 2)).toStrictEqual([null, 2]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getNullableCodec(getU64Codec(), { prefix: null });\n            expect(codec.encode(2)).toStrictEqual(b('0200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('0200000000000000'));\n            expect(codec.decode(b('0200000000000000'))).toBe(2n);\n        });\n\n        it('returns a variable size codec', () => {\n            // ...because the item and the none value do not need to have the same length.\n            const codec = getNullableCodec(getU16Codec(), { prefix: null });\n            expect(codec.getSizeFromValue(null)).toBe(0);\n            expect(codec.getSizeFromValue(42)).toBe(2);\n            expect(codec.maxSize).toBe(2);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/pattern-match-test.ts",
    "content": "import { combineCodec, createDecoder, createEncoder } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES,\n    SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { getPatternMatchCodec, getPatternMatchDecoder, getPatternMatchEncoder } from '../pattern-match';\n\n// An encoder that encodes any value to [0]\nconst encodeToZero = createEncoder<number>({\n    fixedSize: 1,\n    write: (_value, bytes, offset) => {\n        bytes[offset] = 0;\n        return offset + 1;\n    },\n});\n\n// An encoder that encodes any value to [1]\nconst encodeToOne = createEncoder<number>({\n    fixedSize: 1,\n    write: (_value, bytes, offset) => {\n        bytes[offset] = 1;\n        return offset + 1;\n    },\n});\n\n// An encoder that encodes any value to [2]\nconst encodeToTwo = createEncoder<number>({\n    fixedSize: 1,\n    write: (_value, bytes, offset) => {\n        bytes[offset] = 2;\n        return offset + 1;\n    },\n});\n\n// A decoder that decodes any byte array to 0\nconst decodeToZero = createDecoder<number>({\n    fixedSize: 1,\n    read() {\n        return [0, 1];\n    },\n});\n\n// A decoder that decodes any byte array to 1\nconst decodeToOne = createDecoder<number>({\n    fixedSize: 1,\n    read() {\n        return [1, 1];\n    },\n});\n\n// A decoder that decodes any byte array to 2\nconst decodeToTwo = createDecoder<number>({\n    fixedSize: 1,\n    read() {\n        return [2, 1];\n    },\n});\n\ndescribe('getPatternMatchEncoder', () => {\n    it('encodes using the first encoder when the first pattern matches', () => {\n        const encoder = getPatternMatchEncoder([\n            [() => true, encodeToZero],\n            [() => false, encodeToOne],\n            [() => false, encodeToTwo],\n        ]);\n        expect(encoder.encode(42)).toEqual(new Uint8Array([0]));\n    });\n\n    it('encodes using the second encoder when the second pattern matches', () => {\n        const encoder = getPatternMatchEncoder([\n            [() => false, encodeToZero],\n            [() => true, encodeToOne],\n            [() => false, encodeToTwo],\n        ]);\n        expect(encoder.encode(42)).toEqual(new Uint8Array([1]));\n    });\n\n    it('encodes using the third encoder when the third pattern matches', () => {\n        const encoder = getPatternMatchEncoder([\n            [() => false, encodeToZero],\n            [() => false, encodeToOne],\n            [() => true, encodeToTwo],\n        ]);\n        expect(encoder.encode(42)).toEqual(new Uint8Array([2]));\n    });\n\n    it('throws an error when no pattern matches', () => {\n        const encoder = getPatternMatchEncoder([\n            [() => false, encodeToZero],\n            [() => false, encodeToOne],\n            [() => false, encodeToTwo],\n        ]);\n        expect(() => encoder.encode(42)).toThrow(new SolanaError(SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE));\n    });\n});\n\ndescribe('getPatternMatchDecoder', () => {\n    it('decodes using the first decoder when the first pattern matches', () => {\n        const decoder = getPatternMatchDecoder([\n            [() => true, decodeToZero],\n            [() => false, decodeToOne],\n            [() => false, decodeToTwo],\n        ]);\n        expect(decoder.decode(new Uint8Array([42]))).toBe(0);\n    });\n\n    it('decodes using the second decoder when the second pattern matches', () => {\n        const decoder = getPatternMatchDecoder([\n            [() => false, decodeToZero],\n            [() => true, decodeToOne],\n            [() => false, decodeToTwo],\n        ]);\n        expect(decoder.decode(new Uint8Array([42]))).toBe(1);\n    });\n\n    it('decodes using the third decoder when the third pattern matches', () => {\n        const decoder = getPatternMatchDecoder([\n            [() => false, decodeToZero],\n            [() => false, decodeToOne],\n            [() => true, decodeToTwo],\n        ]);\n        expect(decoder.decode(new Uint8Array([42]))).toBe(2);\n    });\n\n    it('throws an error when no pattern matches', () => {\n        const decoder = getPatternMatchDecoder([\n            [() => false, decodeToZero],\n            [() => false, decodeToOne],\n            [() => false, decodeToTwo],\n        ]);\n        const bytes = new Uint8Array([42]);\n        expect(() => decoder.decode(bytes)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES, { bytes }),\n        );\n    });\n});\n\ndescribe('getPatternMatchCodec', () => {\n    const codecZero = combineCodec(encodeToZero, decodeToZero);\n    const codecOne = combineCodec(encodeToOne, decodeToOne);\n    const codecTwo = combineCodec(encodeToTwo, decodeToTwo);\n\n    it('encodes using the first codec when the first encoder pattern matches', () => {\n        const codec = getPatternMatchCodec([\n            [() => true /* encoder predicate */, () => true /* decoder predicate */, codecZero],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecOne],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecTwo],\n        ]);\n        expect(codec.encode(42)).toEqual(new Uint8Array([0]));\n    });\n\n    it('encodes using the second codec when the second encoder pattern matches', () => {\n        const codec = getPatternMatchCodec([\n            [() => false /* encoder predicate */, () => true /* decoder predicate */, codecZero],\n            [() => true /* encoder predicate */, () => false /* decoder predicate */, codecOne],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecTwo],\n        ]);\n        expect(codec.encode(42)).toEqual(new Uint8Array([1]));\n    });\n\n    it('encodes using the third codec when the third encoder pattern matches', () => {\n        const codec = getPatternMatchCodec([\n            [() => false /* encoder predicate */, () => true /* decoder predicate */, codecZero],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecOne],\n            [() => true /* encoder predicate */, () => false /* decoder predicate */, codecTwo],\n        ]);\n        expect(codec.encode(42)).toEqual(new Uint8Array([2]));\n    });\n\n    it('throws an error when encoding and no encoder pattern matches', () => {\n        const codec = getPatternMatchCodec([\n            [() => false /* encoder predicate */, () => true /* decoder predicate */, codecZero],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecOne],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecTwo],\n        ]);\n        expect(() => codec.encode(42)).toThrow(new SolanaError(SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE));\n    });\n\n    it('decodes using the first codec when the first decoder pattern matches', () => {\n        const codec = getPatternMatchCodec([\n            [() => true /* encoder predicate */, () => true /* decoder predicate */, codecZero],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecOne],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecTwo],\n        ]);\n        expect(codec.decode(new Uint8Array([42]))).toBe(0);\n    });\n\n    it('decodes using the second codec when the second decoder pattern matches', () => {\n        const codec = getPatternMatchCodec([\n            [() => true /* encoder predicate */, () => false /* decoder predicate */, codecZero],\n            [() => false /* encoder predicate */, () => true /* decoder predicate */, codecOne],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecTwo],\n        ]);\n        expect(codec.decode(new Uint8Array([42]))).toBe(1);\n    });\n\n    it('decodes using the third codec when the third decoder pattern matches', () => {\n        const codec = getPatternMatchCodec([\n            [() => true /* encoder predicate */, () => false /* decoder predicate */, codecZero],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecOne],\n            [() => false /* encoder predicate */, () => true /* decoder predicate */, codecTwo],\n        ]);\n        expect(codec.decode(new Uint8Array([42]))).toBe(2);\n    });\n\n    it('throws an error when decoding and no decoder pattern matches', () => {\n        const codec = getPatternMatchCodec([\n            [() => true /* encoder predicate */, () => false /* decoder predicate */, codecZero],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecOne],\n            [() => false /* encoder predicate */, () => false /* decoder predicate */, codecTwo],\n        ]);\n        const bytes = new Uint8Array([42]);\n        expect(() => codec.decode(bytes)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES, { bytes }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/predicate-test.ts",
    "content": "import { combineCodec, createDecoder, createEncoder } from '@solana/codecs-core';\n\nimport { getPredicateCodec, getPredicateDecoder, getPredicateEncoder } from '../predicate';\n\n// An encoder that encodes any value to [0]\nconst encodeToZero = createEncoder<number>({\n    fixedSize: 1,\n    write: (_value, bytes, offset) => {\n        bytes[offset] = 0;\n        return offset + 1;\n    },\n});\n\n// An encoder that encodes any value to [1]\nconst encodeToOne = createEncoder<number>({\n    fixedSize: 1,\n    write: (_value, bytes, offset) => {\n        bytes[offset] = 1;\n        return offset + 1;\n    },\n});\n\n// A decoder that decodes any byte array to 0\nconst decodeToZero = createDecoder<number>({\n    fixedSize: 1,\n    read() {\n        return [0, 1];\n    },\n});\n\n// A decoder that decodes any byte array to 1\nconst decodeToOne = createDecoder<number>({\n    fixedSize: 1,\n    read() {\n        return [1, 1];\n    },\n});\n\ndescribe('getPredicateEncoder', () => {\n    it('encodes using the true encoder when the predicate is true', () => {\n        const encoder = getPredicateEncoder(() => true, encodeToOne, encodeToZero);\n        expect(encoder.encode(42)).toEqual(new Uint8Array([1]));\n    });\n\n    it('encodes using the false encoder when the predicate is false', () => {\n        const encoder = getPredicateEncoder(() => false, encodeToOne, encodeToZero);\n        expect(encoder.encode(42)).toEqual(new Uint8Array([0]));\n    });\n});\n\ndescribe('getPredicateDecoder', () => {\n    it('decodes using the true decoder when the predicate is true', () => {\n        const decoder = getPredicateDecoder<number>(() => true, decodeToOne, decodeToZero);\n        expect(decoder.decode(new Uint8Array([42]))).toBe(1);\n    });\n\n    it('decodes using the false decoder when the predicate is false', () => {\n        const decoder = getPredicateDecoder<number>(() => false, decodeToOne, decodeToZero);\n        expect(decoder.decode(new Uint8Array([42]))).toBe(0);\n    });\n});\n\ndescribe('getPredicateCodec', () => {\n    const codecZero = combineCodec(encodeToZero, decodeToZero);\n    const codecOne = combineCodec(encodeToOne, decodeToOne);\n\n    it('encodes using the true encoder when the predicate is true', () => {\n        const codec = getPredicateCodec(\n            () => true /* encoder predicate */,\n            () => true /* decoder predicate */,\n            codecOne,\n            codecZero,\n        );\n        expect(codec.encode(42)).toEqual(new Uint8Array([1]));\n    });\n\n    it('encodes using the false encoder when the predicate is false', () => {\n        const codec = getPredicateCodec(\n            () => false /* encoder predicate */,\n            () => true /* decoder predicate */,\n            codecOne,\n            codecZero,\n        );\n        expect(codec.encode(42)).toEqual(new Uint8Array([0]));\n    });\n\n    it('decodes using the true decoder when the predicate is true', () => {\n        const codec = getPredicateCodec(\n            () => true /* encoder predicate */,\n            () => true /* decoder predicate */,\n            codecOne,\n            codecZero,\n        );\n        expect(codec.decode(new Uint8Array([42]))).toBe(1);\n    });\n\n    it('decodes using the false decoder when the predicate is false', () => {\n        const codec = getPredicateCodec(\n            () => true /* encoder predicate */,\n            () => false /* decoder predicate */,\n            codecOne,\n            codecZero,\n        );\n        expect(codec.decode(new Uint8Array([42]))).toBe(0);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/set-test.ts",
    "content": "import { addCodecSizePrefix, fixCodecSize } from '@solana/codecs-core';\nimport { getU8Codec, getU16Codec, getU32Codec, getU64Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, SolanaError } from '@solana/errors';\n\nimport { getSetCodec } from '../set';\nimport { b } from './__setup__';\n\ndescribe('getSetCodec', () => {\n    const set = getSetCodec;\n    const u8 = getU8Codec;\n    const u16 = getU16Codec;\n    const u64 = getU64Codec;\n    const u8String = addCodecSizePrefix(getUtf8Codec(), getU8Codec());\n    const u32String = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n    const fixedString1 = fixCodecSize(getUtf8Codec(), 1);\n\n    it('encodes prefixed sets', () => {\n        // Empty.\n        expect(set(u8()).encode(new Set())).toStrictEqual(b('00000000')); // 4-bytes prefix.\n        expect(set(u8()).read(b('00000000'), 0)).toStrictEqual([new Set(), 4]);\n\n        // Empty with custom prefix.\n        expect(set(u8(), { size: u8() }).encode(new Set())).toStrictEqual(b('00')); // 1-byte prefix.\n        expect(set(u8(), { size: u8() }).read(b('00'), 0)).toStrictEqual([new Set(), 1]);\n\n        // Numbers.\n        expect(set(u8()).encode(new Set([42, 1, 2]))).toStrictEqual(b('030000002a0102'));\n        expect(set(u8()).read(b('030000002a0102'), 0)).toStrictEqual([new Set([42, 1, 2]), 4 + 3]);\n        expect(set(u8()).read(b('ffff030000002a0102'), 2)).toStrictEqual([new Set([42, 1, 2]), 2 + 4 + 3]);\n\n        // Strings.\n        expect(set(u32String).encode(new Set(['a', 'b']))).toStrictEqual(b('0200000001000000610100000062'));\n        expect(set(u32String).read(b('0200000001000000610100000062'), 0)).toStrictEqual([new Set(['a', 'b']), 4 + 10]);\n\n        // Different From and To types.\n        const setU64 = set<bigint | number, bigint>(u64());\n        expect(setU64.encode(new Set([2]))).toStrictEqual(b('010000000200000000000000'));\n        expect(setU64.encode(new Set([2n]))).toStrictEqual(b('010000000200000000000000'));\n        expect(setU64.read(b('010000000200000000000000'), 0)).toStrictEqual([new Set([2n]), 4 + 8]);\n    });\n\n    it('encodes fixed sets', () => {\n        // Empty.\n        expect(set(u8(), { size: 0 }).encode(new Set())).toStrictEqual(b(''));\n        expect(set(u8(), { size: 0 }).read(b(''), 0)).toStrictEqual([new Set(), 0]);\n\n        // Numbers.\n        expect(set(u8(), { size: 3 }).encode(new Set([42, 1, 2]))).toStrictEqual(b('2a0102'));\n        expect(set(u8(), { size: 3 }).read(b('2a0102'), 0)).toStrictEqual([new Set([42, 1, 2]), 3]);\n        expect(set(u8(), { size: 3 }).read(b('ffff2a0102'), 2)).toStrictEqual([new Set([42, 1, 2]), 5]);\n\n        // Strings.\n        expect(set(u32String, { size: 2 }).encode(new Set(['a', 'b']))).toStrictEqual(b('01000000610100000062'));\n        expect(set(u32String, { size: 2 }).read(b('01000000610100000062'), 0)).toStrictEqual([new Set(['a', 'b']), 10]);\n\n        // Different From and To types.\n        const setU64 = set<bigint | number, bigint>(u64(), { size: 1 });\n        expect(setU64.encode(new Set([2]))).toStrictEqual(b('0200000000000000'));\n        expect(setU64.encode(new Set([2n]))).toStrictEqual(b('0200000000000000'));\n        expect(setU64.read(b('0200000000000000'), 0)).toStrictEqual([new Set([2n]), 8]);\n\n        // It fails if the set has a different size.\n        expect(() => set(u32String, { size: 1 }).encode(new Set())).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 0,\n                codecDescription: 'array',\n                expected: 1,\n            }),\n        );\n        expect(() => set(u32String, { size: 2 }).encode(new Set(['a', 'b', 'c']))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 3,\n                codecDescription: 'array',\n                expected: 2,\n            }),\n        );\n    });\n\n    it('encodes remainder sets', () => {\n        const remainder = { size: 'remainder' } as const;\n\n        // Empty.\n        expect(set(u8(), remainder).encode(new Set())).toStrictEqual(b(''));\n        expect(set(u8(), remainder).read(b(''), 0)).toStrictEqual([new Set(), 0]);\n\n        // Numbers.\n        expect(set(u8(), remainder).encode(new Set([42, 1, 2]))).toStrictEqual(b('2a0102'));\n        expect(set(u8(), remainder).read(b('2a0102'), 0)).toStrictEqual([new Set([42, 1, 2]), 3]);\n        expect(set(u8(), remainder).read(b('ffff2a0102'), 2)).toStrictEqual([new Set([42, 1, 2]), 5]);\n\n        // Strings.\n        expect(set(fixedString1, remainder).encode(new Set(['a', 'b']))).toStrictEqual(b('6162'));\n        expect(set(fixedString1, remainder).read(b('6162'), 0)).toStrictEqual([new Set(['a', 'b']), 2]);\n\n        // Variable sized items.\n        expect(set(u8String, remainder).encode(new Set(['a', 'bc']))).toStrictEqual(b('0161026263'));\n        expect(set(u8String, remainder).read(b('0161026263'), 0)).toStrictEqual([new Set(['a', 'bc']), 5]);\n\n        // Different From and To types.\n        const setU64 = set<bigint | number, bigint>(u64(), remainder);\n        expect(setU64.encode(new Set([2]))).toStrictEqual(b('0200000000000000'));\n        expect(setU64.encode(new Set([2n]))).toStrictEqual(b('0200000000000000'));\n        expect(setU64.read(b('0200000000000000'), 0)).toStrictEqual([new Set([2n]), 8]);\n    });\n\n    it('has the right sizes', () => {\n        expect(set(u8()).getSizeFromValue(new Set([1, 2]))).toBe(4 + 2);\n        expect(set(u8()).maxSize).toBeUndefined();\n        expect(set(u8(), { size: u8() }).getSizeFromValue(new Set([1, 2]))).toBe(1 + 2);\n        expect(set(u8(), { size: u8() }).maxSize).toBeUndefined();\n        expect(set(u8(), { size: 'remainder' }).getSizeFromValue(new Set([1, 2]))).toBe(2);\n        expect(set(u8(), { size: 'remainder' }).maxSize).toBeUndefined();\n        expect(set(u8(), { size: 42 }).fixedSize).toBe(42);\n        expect(set(u16(), { size: 42 }).fixedSize).toBe(2 * 42);\n        expect(set(u32String, { size: 42 }).maxSize).toBeUndefined();\n        expect(set(u32String, { size: 0 }).fixedSize).toBe(0);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/struct-test.ts",
    "content": "import { addCodecSentinel, addCodecSizePrefix, fixCodecSize, offsetCodec, resizeCodec } from '@solana/codecs-core';\nimport { getU8Codec, getU32Codec, getU64Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\n\nimport { getNullableCodec } from '../nullable';\nimport { getStructCodec } from '../struct';\nimport { b } from './__setup__';\n\ndescribe('getStructCodec', () => {\n    const struct = getStructCodec;\n    const nullable = getNullableCodec;\n    const u8 = getU8Codec;\n    const u32 = getU32Codec;\n    const u64 = getU64Codec;\n    const u32String = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n    const fixedString8 = fixCodecSize(getUtf8Codec(), 8);\n\n    it('encodes structs', () => {\n        // Empty struct.\n        expect(struct([]).encode({})).toStrictEqual(b(''));\n        expect(struct([]).decode(b(''))).toStrictEqual({});\n\n        // Person struct.\n        const person = struct([\n            ['name', u32String],\n            ['age', u8()],\n        ]);\n        const alice = { age: 32, name: 'Alice' };\n        expect(person.encode(alice)).toStrictEqual(b('05000000416c69636520'));\n        expect(person.read(b('05000000416c69636520'), 0)).toStrictEqual([alice, 10]);\n        expect(person.read(b('ffff05000000416c69636520'), 2)).toStrictEqual([alice, 12]);\n        const bob = { age: 28, dob: '1995-06-01', name: 'Bob' };\n        expect(person.encode(bob)).toStrictEqual(b('03000000426f621c'));\n        expect(person.decode(b('03000000426f621c'))).toStrictEqual({ age: 28, name: 'Bob' });\n\n        // Different From and To types.\n        const structU64 = struct([['value', u64()]]);\n        expect(structU64.encode({ value: 2 })).toStrictEqual(b('0200000000000000'));\n        expect(structU64.encode({ value: 2n })).toStrictEqual(b('0200000000000000'));\n        expect(structU64.decode(b('0200000000000000'))).toStrictEqual({ value: 2n });\n    });\n\n    it('has the right sizes', () => {\n        expect(struct([]).fixedSize).toBe(0);\n        expect(struct([['age', u8()]]).fixedSize).toBe(1);\n        expect(struct([['age', nullable(u8())]]).getSizeFromValue({ age: null })).toBe(1);\n        expect(struct([['age', nullable(u8())]]).maxSize).toBe(2);\n\n        const person = struct([\n            ['name', u32String],\n            ['age', u8()],\n        ]);\n        expect(person.getSizeFromValue({ age: 42, name: 'ABC' })).toBe(8);\n        expect(person.maxSize).toBeUndefined();\n\n        const fixedPerson = struct([\n            ['age', u8()],\n            ['balance', u64()],\n        ]);\n        expect(fixedPerson.fixedSize).toBe(9);\n    });\n\n    it('offsets fields within a struct', () => {\n        const person = struct([\n            ['name', fixedString8],\n            // There is a 4-byte padding between name and age.\n            [\n                'age',\n                offsetCodec(\n                    resizeCodec(u32(), size => size + 4),\n                    { preOffset: ({ preOffset }) => preOffset + 4 },\n                ),\n            ],\n        ]);\n        const alice = { age: 32, name: 'Alice' };\n        expect(person.encode(alice)).toStrictEqual(b('416c6963650000000000000020000000'));\n        expect(person.read(b('416c6963650000000000000020000000'), 0)).toStrictEqual([alice, 16]);\n        expect(person.read(b('ff416c6963650000000000000020000000'), 1)).toStrictEqual([alice, 17]);\n    });\n\n    it('can chain sentinel codecs', () => {\n        const person = struct([\n            ['firstname', addCodecSentinel(getUtf8Codec(), b('ff'))],\n            ['lastname', addCodecSentinel(getUtf8Codec(), b('ff'))],\n            ['age', u8()],\n        ]);\n        const john = { age: 42, firstname: 'John', lastname: 'Doe' };\n        expect(person.encode(john)).toStrictEqual(b('4a6f686eff446f65ff2a'));\n        expect(person.decode(b('4a6f686eff446f65ff2a'))).toStrictEqual(john);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/tuple-test.ts",
    "content": "import { addCodecSentinel, addCodecSizePrefix, fixCodecSize, offsetCodec } from '@solana/codecs-core';\nimport { getI16Codec, getU8Codec, getU32Codec, getU64Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, SolanaError } from '@solana/errors';\n\nimport { getTupleCodec } from '../tuple';\nimport { b } from './__setup__';\n\ndescribe('getTupleCodec', () => {\n    const tuple = getTupleCodec;\n    const i16 = getI16Codec;\n    const u8 = getU8Codec;\n    const u64 = getU64Codec;\n    const u32String = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n    const fixedString8 = fixCodecSize(getUtf8Codec(), 8);\n\n    it('encodes tuples', () => {\n        // Encode.\n        expect(tuple([]).encode([])).toStrictEqual(b(''));\n        expect(tuple([u8()]).encode([42])).toStrictEqual(b('2a'));\n        expect(tuple([u8(), i16()]).encode([0, -42])).toStrictEqual(b('00d6ff'));\n        expect(tuple([u32String, u8()]).encode(['Hello', 42])).toStrictEqual(b('0500000048656c6c6f2a'));\n\n        // Decode.\n        expect(tuple([]).decode(b(''))).toStrictEqual([]);\n        expect(tuple([u8()]).decode(b('2a'))).toStrictEqual([42]);\n        expect(tuple([u8(), i16()]).decode(b('00d6ff'))).toStrictEqual([0, -42]);\n        expect(tuple([u32String, u8()]).decode(b('0500000048656c6c6f2a'))).toStrictEqual(['Hello', 42]);\n\n        // Different From and To types.\n        const tupleU8U64 = tuple([u8(), u64()]);\n        expect(tupleU8U64.encode([1, 2])).toStrictEqual(b('010200000000000000'));\n        expect(tupleU8U64.encode([1, 2n])).toStrictEqual(b('010200000000000000'));\n        expect(tupleU8U64.decode(b('010200000000000000'))).toStrictEqual([1, 2n]);\n        expect(tupleU8U64.encode([1, 2n ** 63n])).toStrictEqual(b('010000000000000080'));\n        expect(tupleU8U64.decode(b('010000000000000080'))).toStrictEqual([1, 2n ** 63n]);\n\n        // Fails if given the wrong number of items.\n        // @ts-expect-error Tuple should have the right number of items.\n        expect(() => tuple([u8(), u8()]).encode([42])).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 1,\n                codecDescription: 'tuple',\n                expected: 2,\n            }),\n        );\n\n        // @ts-expect-error Tuple should have the right number of items.\n        expect(() => tuple([u8(), u8()], { description: 'myDescription' }).encode([42])).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                actual: 1,\n                codecDescription: 'myDescription',\n                expected: 2,\n            }),\n        );\n    });\n\n    it('has the right sizes', () => {\n        expect(tuple([]).fixedSize).toBe(0);\n        expect(tuple([u8()]).fixedSize).toBe(1);\n        expect(tuple([u8(), i16()]).fixedSize).toBe(1 + 2);\n        expect(tuple([u8(), u32String, i16()]).getSizeFromValue([1, 'ABC', 2])).toBe(1 + (4 + 3) + 2);\n        expect(tuple([u8(), u32String, i16()]).maxSize).toBeUndefined();\n        expect(tuple([u32String, u8()]).getSizeFromValue(['Hello', 42])).toBe(4 + 5 + 1);\n    });\n\n    it('offsets items within a tuple', () => {\n        const person = tuple([\n            // Name, pushes 8 bytes forward then handles 8 bytes.\n            offsetCodec(fixedString8, {\n                preOffset: ({ preOffset }) => preOffset + 8,\n            }),\n            // Age, pushes 16 bytes backward then handles 8 bytes.\n            offsetCodec(u64(), {\n                postOffset: ({ preOffset }) => preOffset, // Restores original offset.\n                preOffset: ({ preOffset }) => preOffset - 16,\n            }),\n            // The cursor is now at the end of the buffer.\n        ]);\n        expect(person.encode(['Alice', 32])).toStrictEqual(b('2000000000000000416c696365000000'));\n        expect(person.read(b('2000000000000000416c696365000000'), 0)).toStrictEqual([['Alice', 32n], 16]);\n        expect(person.read(b('ff2000000000000000416c696365000000'), 1)).toStrictEqual([['Alice', 32n], 17]);\n    });\n\n    it('can chain sentinel codecs', () => {\n        const person = tuple([\n            addCodecSentinel(getUtf8Codec(), b('ff')),\n            addCodecSentinel(getUtf8Codec(), b('ff')),\n            u8(),\n        ]);\n        const john = ['John', 'Doe', 42] as const;\n        expect(person.encode(john)).toStrictEqual(b('4a6f686eff446f65ff2a'));\n        expect(person.decode(b('4a6f686eff446f65ff2a'))).toStrictEqual(john);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/union-test.ts",
    "content": "import { assertIsFixedSize, assertIsVariableSize, fixCodecSize, transformCodec } from '@solana/codecs-core';\nimport { getU8Codec, getU16Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE, SolanaError } from '@solana/errors';\n\nimport { getBooleanCodec } from '../boolean';\nimport { getStructCodec } from '../struct';\nimport { getUnionCodec } from '../union';\nimport { b } from './__setup__';\n\ndescribe('getUnionCodec', () => {\n    const codec = getUnionCodec(\n        [\n            fixCodecSize(getUtf8Codec(), 8), // 8 bytes.\n            getU16Codec(), // 2 bytes.\n            getBooleanCodec(), // 1 byte.\n            getStructCodec([\n                // 4 bytes.\n                ['x', getU16Codec()],\n                ['y', getU16Codec()],\n            ]),\n        ],\n        value => {\n            if (value === 999) return 999;\n            if (typeof value === 'string') return 0;\n            if (typeof value === 'number') return 1;\n            if (typeof value === 'boolean') return 2;\n            return 3;\n        },\n        bytes => {\n            if (bytes.length === 3 && [...bytes].every(byte => byte === 255)) return 999;\n            if (bytes.length === 8) return 0;\n            if (bytes.length === 2) return 1;\n            if (bytes.length === 1) return 2;\n            return 3;\n        },\n    );\n\n    it('encodes any valid union variant', () => {\n        expect(codec.encode('hello')).toStrictEqual(b('68656c6c6f000000'));\n        expect(codec.encode(42)).toStrictEqual(b('2a00'));\n        expect(codec.encode(true)).toStrictEqual(b('01'));\n        expect(codec.encode({ x: 1, y: 2 })).toStrictEqual(b('01000200'));\n    });\n\n    it('decodes any valid union variant', () => {\n        expect(codec.decode(b('68656c6c6f000000'))).toBe('hello');\n        expect(codec.decode(b('2a00'))).toBe(42);\n        expect(codec.decode(b('01'))).toBe(true);\n        expect(codec.decode(b('01000200'))).toStrictEqual({ x: 1, y: 2 });\n    });\n\n    it('pushes the offset forward when writing', () => {\n        expect(codec.write(42, new Uint8Array(10), 6)).toBe(8);\n    });\n\n    it('pushes the offset forward when reading', () => {\n        expect(codec.read(b('00'), 0)).toStrictEqual([false, 1]);\n    });\n\n    it('throws when encoding an invalid variant', () => {\n        expect(() => codec.encode(999)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE, {\n                maxRange: 3,\n                minRange: 0,\n                variant: 999,\n            }),\n        );\n    });\n\n    it('throws when decoding an invalid variant', () => {\n        expect(() => codec.decode(b('ffffff'))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE, {\n                maxRange: 3,\n                minRange: 0,\n                variant: 999,\n            }),\n        );\n    });\n\n    it('returns a variable size codec', () => {\n        assertIsVariableSize(codec);\n        expect(codec.getSizeFromValue('hello')).toBe(8);\n        expect(codec.getSizeFromValue(42)).toBe(2);\n        expect(codec.getSizeFromValue(true)).toBe(1);\n        expect(codec.getSizeFromValue({ x: 1, y: 2 })).toBe(4);\n        expect(codec.maxSize).toBe(8);\n    });\n\n    it('returns a fixed size codec when all variants have the same fixed size', () => {\n        const sameSizeCodec = getUnionCodec(\n            [getU8Codec(), getBooleanCodec()],\n            () => 0,\n            () => 0,\n        );\n        assertIsFixedSize(sameSizeCodec);\n        expect(sameSizeCodec.fixedSize).toBe(1);\n    });\n\n    it('can be used to create a zeroable nullable codec', () => {\n        const nullCodec = transformCodec(\n            getU8Codec(),\n            (_value: null) => 0xff,\n            () => null,\n        );\n        const zeroableCodec = getUnionCodec(\n            [nullCodec, getU8Codec()],\n            value => Number(value !== null),\n            (bytes, offset) => Number(bytes[offset] !== 0xff),\n        );\n        expect(zeroableCodec.encode(null)).toStrictEqual(b('ff'));\n        expect(zeroableCodec.encode(42)).toStrictEqual(b('2a'));\n        expect(zeroableCodec.decode(b('ff'))).toBeNull();\n        expect(zeroableCodec.decode(b('2a'))).toBe(42);\n    });\n\n    it('can be used to create a discriminated union codec', () => {\n        const staticU16One = transformCodec(\n            getU16Codec(),\n            (_value: 1) => 1,\n            () => 1 as const,\n        );\n        const staticU16Two = transformCodec(\n            getU16Codec(),\n            (_value: 2) => 2,\n            () => 2 as const,\n        );\n        const discriminatedUnionCodec = getUnionCodec(\n            [\n                getStructCodec([\n                    ['header', getU16Codec()],\n                    ['type', staticU16One],\n                ]),\n                getStructCodec([\n                    ['size', getU16Codec()],\n                    ['type', staticU16Two],\n                ]),\n            ],\n            value => value.type - 1,\n            (bytes, offset) => bytes[offset + 2] - 1,\n        );\n        expect(discriminatedUnionCodec.encode({ header: 42, type: 1 })).toStrictEqual(b('2a000100'));\n        expect(discriminatedUnionCodec.encode({ size: 9, type: 2 })).toStrictEqual(b('09000200'));\n        expect(discriminatedUnionCodec.decode(b('2a000100'))).toStrictEqual({ header: 42, type: 1 });\n        expect(discriminatedUnionCodec.decode(b('09000200'))).toStrictEqual({ size: 9, type: 2 });\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__tests__/unit-test.ts",
    "content": "import { getUnitCodec } from '../unit';\nimport { b } from './__setup__';\n\ndescribe('getUnitCodec', () => {\n    const unit = getUnitCodec;\n\n    it('encodes void', () => {\n        // Encode.\n        expect(unit().encode(undefined)).toStrictEqual(b(''));\n        expect(unit().encode(void 0)).toStrictEqual(b(''));\n\n        // Decode.\n        expect(unit().read(b(''), 0)).toStrictEqual([undefined, 0]);\n        expect(unit().read(b('00'), 0)).toStrictEqual([undefined, 0]);\n        expect(unit().read(b('00'), 1)).toStrictEqual([undefined, 1]);\n    });\n\n    it('has the right sizes', () => {\n        expect(unit().fixedSize).toBe(0);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/array-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getArrayCodec, getArrayDecoder, getArrayEncoder } from '../array';\n\n{\n    // [getArrayEncoder]: It knows if the encoder is fixed size or variable size.\n    getArrayEncoder({} as FixedSizeEncoder<string>) satisfies VariableSizeEncoder<string[]>;\n    getArrayEncoder({} as FixedSizeEncoder<string>, { size: 42 }) satisfies FixedSizeEncoder<string[]>;\n    getArrayEncoder({} as Encoder<string>, { size: 0 }) satisfies FixedSizeEncoder<string[], 0>;\n    getArrayEncoder({} as FixedSizeEncoder<string>, { size: 'remainder' }) satisfies VariableSizeEncoder<string[]>;\n    getArrayEncoder({} as VariableSizeEncoder<string>, { size: 'remainder' }) satisfies VariableSizeEncoder<string[]>;\n}\n\n{\n    // [getArrayDecoder]: It knows if the decoder is fixed size or variable size.\n    getArrayDecoder({} as FixedSizeDecoder<string>) satisfies VariableSizeDecoder<string[]>;\n    getArrayDecoder({} as FixedSizeDecoder<string>, { size: 42 }) satisfies FixedSizeDecoder<string[]>;\n    getArrayDecoder({} as Decoder<string>, { size: 0 }) satisfies FixedSizeDecoder<string[], 0>;\n    getArrayDecoder({} as FixedSizeDecoder<string>, { size: 'remainder' }) satisfies VariableSizeDecoder<string[]>;\n    getArrayDecoder({} as VariableSizeDecoder<string>, { size: 'remainder' }) satisfies VariableSizeDecoder<string[]>;\n}\n\n{\n    // [getArrayCodec]: It knows if the codec is fixed size or variable size.\n    getArrayCodec({} as FixedSizeCodec<string>) satisfies VariableSizeCodec<string[]>;\n    getArrayCodec({} as FixedSizeCodec<string>, { size: 42 }) satisfies FixedSizeCodec<string[]>;\n    getArrayCodec({} as Codec<string>, { size: 0 }) satisfies FixedSizeCodec<string[], string[], 0>;\n    getArrayCodec({} as FixedSizeCodec<string>, { size: 'remainder' }) satisfies VariableSizeCodec<string[]>;\n    getArrayCodec({} as VariableSizeCodec<string>, { size: 'remainder' }) satisfies VariableSizeCodec<string[]>;\n}\n\n{\n    // [getArrayCodec]: It allows passing a description in the config.\n    getArrayCodec({} as FixedSizeCodec<string>, { description: 'myDescription', size: 42 }) satisfies FixedSizeCodec<\n        string[]\n    >;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/bit-array-typetest.ts",
    "content": "import { FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { getBitArrayCodec, getBitArrayDecoder, getBitArrayEncoder } from '../bit-array';\n\n{\n    // [getBitArrayEncoder]: It keeps track of the encoder's fixed size.\n    getBitArrayEncoder(42) satisfies FixedSizeEncoder<boolean[], 42>;\n}\n\n{\n    // [getBitArrayDecoder]: It keeps track of the decoder's fixed size.\n    getBitArrayDecoder(42) satisfies FixedSizeDecoder<boolean[], 42>;\n}\n\n{\n    // [getBitArrayCodec]: It keeps track of the codec's fixed size.\n    getBitArrayCodec(42) satisfies FixedSizeCodec<boolean[], boolean[], 42>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/boolean-typetest.ts",
    "content": "import {\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    getShortU16Codec,\n    getShortU16Decoder,\n    getShortU16Encoder,\n    getU32Codec,\n    getU32Decoder,\n    getU32Encoder,\n} from '@solana/codecs-numbers';\n\nimport { getBooleanCodec, getBooleanDecoder, getBooleanEncoder } from '../boolean';\n\n{\n    // [getBooleanEncoder]: It knows if the encoder is fixed size or variable size.\n    getBooleanEncoder() satisfies FixedSizeEncoder<boolean, 1>;\n    getBooleanEncoder({ size: getU32Encoder() }) satisfies FixedSizeEncoder<boolean, 4>;\n    getBooleanEncoder({ size: getShortU16Encoder() }) satisfies VariableSizeEncoder<boolean>;\n}\n\n{\n    // [getBooleanDecoder]: It knows if the decoder is fixed size or variable size.\n    getBooleanDecoder() satisfies FixedSizeDecoder<boolean, 1>;\n    getBooleanDecoder({ size: getU32Decoder() }) satisfies FixedSizeDecoder<boolean, 4>;\n    getBooleanDecoder({ size: getShortU16Decoder() }) satisfies VariableSizeDecoder<boolean>;\n}\n\n{\n    // [getBooleanCodec]: It knows if the codec is fixed size or variable size.\n    getBooleanCodec() satisfies FixedSizeCodec<boolean, boolean, 1>;\n    getBooleanCodec({ size: getU32Codec() }) satisfies FixedSizeCodec<boolean, boolean, 4>;\n    getBooleanCodec({ size: getShortU16Codec() }) satisfies VariableSizeCodec<boolean>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/bytes-typetest.ts",
    "content": "import { ReadonlyUint8Array, VariableSizeCodec, VariableSizeDecoder, VariableSizeEncoder } from '@solana/codecs-core';\n\nimport { getBytesCodec, getBytesDecoder, getBytesEncoder } from '../bytes';\n\n{\n    // [getBytesEncoder]: It always returns a variable size encoder.\n    getBytesEncoder() satisfies VariableSizeEncoder<ReadonlyUint8Array | Uint8Array>;\n}\n\n{\n    // [getBytesDecoder]: It always returns a variable size decoder.\n    getBytesDecoder() satisfies VariableSizeDecoder<ReadonlyUint8Array>;\n}\n\n{\n    // [getBytesCodec]: It always returns a variable size codec.\n    getBytesCodec() satisfies VariableSizeCodec<ReadonlyUint8Array | Uint8Array, ReadonlyUint8Array>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/constant-typetest.ts",
    "content": "import { FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { getConstantCodec, getConstantDecoder, getConstantEncoder } from '../constant';\n\nconst constant = {} as Uint8Array;\nconst constant3bytes = {} as Uint8Array & { length: 3 };\n\n{\n    // [getConstantEncoder]: It returns a fixed size encoder.\n    getConstantEncoder(constant) satisfies FixedSizeEncoder<void>;\n    getConstantEncoder(constant3bytes) satisfies FixedSizeEncoder<void, 3>;\n}\n\n{\n    // [getConstantDecoder]: It returns a fixed size decoder.\n    getConstantDecoder(constant) satisfies FixedSizeDecoder<void>;\n    getConstantDecoder(constant3bytes) satisfies FixedSizeDecoder<void, 3>;\n}\n\n{\n    // [getConstantCodec]: It returns a fixed size codec.\n    getConstantCodec(constant) satisfies FixedSizeCodec<void>;\n    getConstantCodec(constant3bytes) satisfies FixedSizeCodec<void, void, 3>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/discriminated-union-typetest.ts",
    "content": "import { Codec, Decoder, Encoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\nimport { getU64Codec } from '@solana/codecs-numbers';\n\nimport {\n    getDiscriminatedUnionCodec,\n    getDiscriminatedUnionDecoder,\n    getDiscriminatedUnionEncoder,\n} from '../discriminated-union';\nimport { getStructCodec } from '../struct';\nimport { getUnitCodec } from '../unit';\n\n// [DESCRIBE] getDiscriminatedUnionEncoder.\n{\n    // It constructs discriminated unions from a list of encoder variants.\n    {\n        getDiscriminatedUnionEncoder([\n            ['A', {} as Encoder<{ value: string }>],\n            ['B', {} as Encoder<{ x: number; y: number }>],\n        ]) satisfies Encoder<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n\n    // It can use a custom discriminator property.\n    {\n        getDiscriminatedUnionEncoder(\n            [\n                ['A', {} as Encoder<{ value: string }>],\n                ['B', {} as Encoder<{ x: number; y: number }>],\n            ],\n            { discriminator: 'myType' },\n        ) satisfies Encoder<{ myType: 'A'; value: string } | { myType: 'B'; x: number; y: number }>;\n    }\n\n    // It can use numbers as discriminator values.\n    {\n        getDiscriminatedUnionEncoder([\n            [1, {} as Encoder<{ value: string }>],\n            [2, {} as Encoder<{ x: number; y: number }>],\n        ]) satisfies Encoder<{ __kind: 1; value: string } | { __kind: 2; x: number; y: number }>;\n    }\n\n    // It can use enums as discriminator values.\n    {\n        const enum Event {\n            Click,\n            KeyPress,\n        }\n        getDiscriminatedUnionEncoder([\n            [Event.Click, {} as Encoder<{ x: number; y: number }>],\n            [Event.KeyPress, {} as Encoder<{ key: string }>],\n        ]) satisfies Encoder<{ __kind: Event.Click; x: number; y: number } | { __kind: Event.KeyPress; key: string }>;\n    }\n\n    // It returns a fixed size encoder if all variants are fixed size.\n    {\n        getDiscriminatedUnionEncoder([\n            ['A', {} as FixedSizeEncoder<{ value: string }>],\n            ['B', {} as FixedSizeEncoder<{ x: number; y: number }>],\n        ]) satisfies FixedSizeEncoder<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n\n    // It does not return a fixed size encoder if any variant is variable size.\n    {\n        const encoder = getDiscriminatedUnionEncoder([\n            ['A', {} as Encoder<{ value: string }>],\n            ['B', {} as FixedSizeEncoder<{ x: number; y: number }>],\n        ]);\n        encoder satisfies Encoder<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n        // @ts-expect-error Encoder is not fixed size.\n        encoder satisfies FixedSizeEncoder<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n}\n\n// [DESCRIBE] getDiscriminatedUnionDecoder.\n{\n    // It constructs discriminated unions from a list of decoder variants.\n    {\n        getDiscriminatedUnionDecoder([\n            ['A', {} as Decoder<{ value: string }>],\n            ['B', {} as Decoder<{ x: number; y: number }>],\n        ]) satisfies Decoder<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n\n    // It can use a custom discriminator property.\n    {\n        getDiscriminatedUnionDecoder(\n            [\n                ['A', {} as Decoder<{ value: string }>],\n                ['B', {} as Decoder<{ x: number; y: number }>],\n            ],\n            { discriminator: 'myType' },\n        ) satisfies Decoder<{ myType: 'A'; value: string } | { myType: 'B'; x: number; y: number }>;\n    }\n\n    // It can use numbers as discriminator values.\n    {\n        getDiscriminatedUnionDecoder([\n            [1, {} as Decoder<{ value: string }>],\n            [2, {} as Decoder<{ x: number; y: number }>],\n        ]) satisfies Decoder<{ __kind: 1; value: string } | { __kind: 2; x: number; y: number }>;\n    }\n\n    // It can use enums as discriminator values.\n    {\n        const enum Event {\n            Click,\n            KeyPress,\n        }\n        getDiscriminatedUnionDecoder([\n            [Event.Click, {} as Decoder<{ x: number; y: number }>],\n            [Event.KeyPress, {} as Decoder<{ key: string }>],\n        ]) satisfies Decoder<{ __kind: Event.Click; x: number; y: number } | { __kind: Event.KeyPress; key: string }>;\n    }\n\n    // It returns a fixed size decoder if all variants are fixed size.\n    {\n        getDiscriminatedUnionDecoder([\n            ['A', {} as FixedSizeDecoder<{ value: string }>],\n            ['B', {} as FixedSizeDecoder<{ x: number; y: number }>],\n        ]) satisfies FixedSizeDecoder<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n\n    // It does not return a fixed size decoder if any variant is variable size.\n    {\n        const decoder = getDiscriminatedUnionDecoder([\n            ['A', {} as Decoder<{ value: string }>],\n            ['B', {} as FixedSizeDecoder<{ x: number; y: number }>],\n        ]);\n        decoder satisfies Decoder<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n        // @ts-expect-error Decoder is not fixed size.\n        decoder satisfies FixedSizeDecoder<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n}\n\n// [DESCRIBE] getDiscriminatedUnionCodec.\n{\n    // It constructs discriminated unions from a list of codec variants.\n    {\n        getDiscriminatedUnionCodec([\n            ['A', {} as Codec<{ value: string }>],\n            ['B', {} as Codec<{ x: number; y: number }>],\n        ]) satisfies Codec<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n\n    // It can use a custom discriminator property.\n    {\n        getDiscriminatedUnionCodec(\n            [\n                ['A', {} as Codec<{ value: string }>],\n                ['B', {} as Codec<{ x: number; y: number }>],\n            ],\n            { discriminator: 'myType' },\n        ) satisfies Codec<{ myType: 'A'; value: string } | { myType: 'B'; x: number; y: number }>;\n    }\n\n    // It can use numbers as discriminator values.\n    {\n        getDiscriminatedUnionCodec([\n            [1, {} as Codec<{ value: string }>],\n            [2, {} as Codec<{ x: number; y: number }>],\n        ]) satisfies Codec<{ __kind: 1; value: string } | { __kind: 2; x: number; y: number }>;\n    }\n\n    // It can use enums as discriminator values.\n    {\n        const enum Event {\n            Click,\n            KeyPress,\n        }\n        getDiscriminatedUnionCodec([\n            [Event.Click, {} as Codec<{ x: number; y: number }>],\n            [Event.KeyPress, {} as Codec<{ key: string }>],\n        ]) satisfies Codec<{ __kind: Event.Click; x: number; y: number } | { __kind: Event.KeyPress; key: string }>;\n    }\n\n    // It can infer complex discriminated union types from provided variants.\n    {\n        getDiscriminatedUnionCodec(\n            [\n                ['PageLoad', {} as Codec<void>],\n                [\n                    'Click',\n                    getStructCodec([\n                        ['x', {} as Codec<number>],\n                        ['y', {} as Codec<number>],\n                    ]),\n                ],\n                ['KeyPress', getStructCodec([['fields', {} as Codec<[string]>]])],\n                ['PageUnload', {} as Codec<object>],\n            ],\n            { discriminator: 'event' },\n        ) satisfies Codec<\n            | { event: 'Click'; x: number; y: number }\n            | { event: 'KeyPress'; fields: [string] }\n            | { event: 'PageLoad' }\n            | { event: 'PageUnload' }\n        >;\n    }\n\n    // It can infer codec discriminated union with different from and to types.\n    {\n        getDiscriminatedUnionCodec([\n            ['A', getUnitCodec()],\n            ['B', getStructCodec([['value', getU64Codec()]])],\n        ]) satisfies Codec<\n            { __kind: 'A' } | { __kind: 'B'; value: bigint | number },\n            { __kind: 'A' } | { __kind: 'B'; value: bigint }\n        >;\n    }\n\n    // It returns a fixed size codec if all variants are fixed size.\n    {\n        getDiscriminatedUnionCodec([\n            ['A', {} as FixedSizeCodec<{ value: string }>],\n            ['B', {} as FixedSizeCodec<{ x: number; y: number }>],\n        ]) satisfies FixedSizeCodec<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n\n    // It does not return a fixed size codec if any variant is variable size.\n    {\n        const codec = getDiscriminatedUnionCodec([\n            ['A', {} as Codec<{ value: string }>],\n            ['B', {} as FixedSizeCodec<{ x: number; y: number }>],\n        ]);\n        codec satisfies Codec<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n        // @ts-expect-error Codec is not fixed size.\n        codec satisfies FixedSizeCodec<{ __kind: 'A'; value: string } | { __kind: 'B'; x: number; y: number }>;\n    }\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/enum-typetest.ts",
    "content": "import {\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getU32Codec, getU32Decoder, getU32Encoder } from '@solana/codecs-numbers';\n\nimport { getEnumCodec, getEnumDecoder, getEnumEncoder } from '../enum';\n\nenum Feedback {\n    BAD,\n    GOOD,\n}\ntype FeedbackInput = Feedback | keyof typeof Feedback;\n\nenum Direction {\n    UP = 'Up',\n    DOWN = 'Down',\n    LEFT = 'Left',\n    RIGHT = 'Right',\n}\ntype DirectionInput = Direction | keyof typeof Direction;\n\n{\n    // [getEnumEncoder]: It knows if the encoder is fixed size or variable size.\n    getEnumEncoder(Feedback) satisfies FixedSizeEncoder<FeedbackInput, 1>;\n    getEnumEncoder(Direction) satisfies FixedSizeEncoder<DirectionInput, 1>;\n    getEnumEncoder(Feedback, { size: getU32Encoder() }) satisfies FixedSizeEncoder<FeedbackInput, 4>;\n    getEnumEncoder(Feedback, {\n        size: {} as VariableSizeEncoder<bigint | number>,\n    }) satisfies VariableSizeEncoder<FeedbackInput>;\n}\n\n{\n    // [getEnumDecoder]: It knows if the decoder is fixed size or variable size.\n    getEnumDecoder(Feedback) satisfies FixedSizeDecoder<Feedback, 1>;\n    getEnumDecoder(Direction) satisfies FixedSizeDecoder<Direction, 1>;\n    getEnumDecoder(Feedback, { size: getU32Decoder() }) satisfies FixedSizeDecoder<Feedback, 4>;\n    getEnumDecoder(Feedback, { size: {} as VariableSizeDecoder<number> }) satisfies VariableSizeDecoder<Feedback>;\n}\n\n{\n    // [getEnumCodec]: It knows if the codec is fixed size or variable size.\n    getEnumCodec(Feedback) satisfies FixedSizeCodec<FeedbackInput, Feedback, 1>;\n    getEnumCodec(Direction) satisfies FixedSizeCodec<DirectionInput, Direction, 1>;\n    getEnumCodec(Feedback, { size: getU32Codec() }) satisfies FixedSizeCodec<FeedbackInput, Feedback, 4>;\n    getEnumCodec(Feedback, {\n        size: {} as VariableSizeCodec<bigint | number, number>,\n    }) satisfies VariableSizeCodec<FeedbackInput, Feedback>;\n    getEnumCodec(Feedback, {\n        size: {} as VariableSizeCodec<bigint | number, bigint>,\n    }) satisfies VariableSizeCodec<FeedbackInput, Feedback>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/hidden-prefix-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getHiddenPrefixCodec, getHiddenPrefixDecoder, getHiddenPrefixEncoder } from '../hidden-prefix';\n\n{\n    // [getHiddenPrefixEncoder]: It knows if the encoder is fixed size or variable size.\n    getHiddenPrefixEncoder(\n        {} as FixedSizeEncoder<string>,\n        [] as FixedSizeEncoder<void>[],\n    ) satisfies FixedSizeEncoder<string>;\n    getHiddenPrefixEncoder({} as Encoder<string>, [] as FixedSizeEncoder<void>[]) satisfies VariableSizeEncoder<string>;\n    getHiddenPrefixEncoder({} as FixedSizeEncoder<string>, [] as Encoder<void>[]) satisfies VariableSizeEncoder<string>;\n}\n\n{\n    // [getHiddenPrefixDecoder]: It knows if the decoder is fixed size or variable size.\n    getHiddenPrefixDecoder(\n        {} as FixedSizeDecoder<string>,\n        [] as FixedSizeDecoder<void>[],\n    ) satisfies FixedSizeDecoder<string>;\n    getHiddenPrefixDecoder({} as Decoder<string>, [] as FixedSizeDecoder<void>[]) satisfies VariableSizeDecoder<string>;\n    getHiddenPrefixDecoder({} as FixedSizeDecoder<string>, [] as Decoder<void>[]) satisfies VariableSizeDecoder<string>;\n}\n\n{\n    // [getHiddenPrefixCodec]: It knows if the codec is fixed size or variable size.\n    getHiddenPrefixCodec({} as FixedSizeCodec<string>, [] as FixedSizeCodec<void>[]) satisfies FixedSizeCodec<string>;\n    getHiddenPrefixCodec({} as Codec<string>, [] as FixedSizeCodec<void>[]) satisfies VariableSizeCodec<string>;\n    getHiddenPrefixCodec({} as FixedSizeCodec<string>, [] as Codec<void>[]) satisfies VariableSizeCodec<string>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/hidden-suffix-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getHiddenSuffixCodec, getHiddenSuffixDecoder, getHiddenSuffixEncoder } from '../hidden-suffix';\n\n{\n    // [getHiddenSuffixEncoder]: It knows if the encoder is fixed size or variable size.\n    getHiddenSuffixEncoder(\n        {} as FixedSizeEncoder<string>,\n        [] as FixedSizeEncoder<void>[],\n    ) satisfies FixedSizeEncoder<string>;\n    getHiddenSuffixEncoder({} as Encoder<string>, [] as FixedSizeEncoder<void>[]) satisfies VariableSizeEncoder<string>;\n    getHiddenSuffixEncoder({} as FixedSizeEncoder<string>, [] as Encoder<void>[]) satisfies VariableSizeEncoder<string>;\n}\n\n{\n    // [getHiddenSuffixDecoder]: It knows if the decoder is fixed size or variable size.\n    getHiddenSuffixDecoder(\n        {} as FixedSizeDecoder<string>,\n        [] as FixedSizeDecoder<void>[],\n    ) satisfies FixedSizeDecoder<string>;\n    getHiddenSuffixDecoder({} as Decoder<string>, [] as FixedSizeDecoder<void>[]) satisfies VariableSizeDecoder<string>;\n    getHiddenSuffixDecoder({} as FixedSizeDecoder<string>, [] as Decoder<void>[]) satisfies VariableSizeDecoder<string>;\n}\n\n{\n    // [getHiddenSuffixCodec]: It knows if the codec is fixed size or variable size.\n    getHiddenSuffixCodec({} as FixedSizeCodec<string>, [] as FixedSizeCodec<void>[]) satisfies FixedSizeCodec<string>;\n    getHiddenSuffixCodec({} as Codec<string>, [] as FixedSizeCodec<void>[]) satisfies VariableSizeCodec<string>;\n    getHiddenSuffixCodec({} as FixedSizeCodec<string>, [] as Codec<void>[]) satisfies VariableSizeCodec<string>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/literal-union-typetest.ts",
    "content": "import {\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getU32Codec, getU32Decoder, getU32Encoder } from '@solana/codecs-numbers';\n\nimport { getLiteralUnionCodec, getLiteralUnionDecoder, getLiteralUnionEncoder } from '../literal-union';\n\n{\n    // [getLiteralUnionEncoder]: It knows if the encoder is fixed size or variable size.\n    getLiteralUnionEncoder(['one', 2, 3n]) satisfies FixedSizeEncoder<'one' | 2 | 3n, 1>;\n    getLiteralUnionEncoder(['one', 2, 3n], { size: getU32Encoder() }) satisfies FixedSizeEncoder<'one' | 2 | 3n, 4>;\n    getLiteralUnionEncoder(['one', 2, 3n], {\n        size: {} as VariableSizeEncoder<bigint | number>,\n    }) satisfies VariableSizeEncoder<'one' | 2 | 3n>;\n}\n\n{\n    // [getLiteralUnionDecoder]: It knows if the decoder is fixed size or variable size.\n    getLiteralUnionDecoder(['one', 2, 3n]) satisfies FixedSizeDecoder<'one' | 2 | 3n, 1>;\n    getLiteralUnionDecoder(['one', 2, 3n], { size: getU32Decoder() }) satisfies FixedSizeDecoder<'one' | 2 | 3n, 4>;\n    getLiteralUnionDecoder(['one', 2, 3n], { size: {} as VariableSizeDecoder<number> }) satisfies VariableSizeDecoder<\n        'one' | 2 | 3n\n    >;\n}\n\n{\n    // [getLiteralUnionCodec]: It knows if the codec is fixed size or variable size.\n    getLiteralUnionCodec(['one', 2, 3n]) satisfies FixedSizeCodec<'one' | 2 | 3n, 'one' | 2 | 3n, 1>;\n    getLiteralUnionCodec(['one', 2, 3n], { size: getU32Codec() }) satisfies FixedSizeCodec<\n        'one' | 2 | 3n,\n        'one' | 2 | 3n,\n        4\n    >;\n    getLiteralUnionCodec(['one', 2, 3n], {\n        size: {} as VariableSizeCodec<bigint | number, number>,\n    }) satisfies VariableSizeCodec<'one' | 2 | 3n>;\n    getLiteralUnionCodec(['one', 2, 3n], {\n        size: {} as VariableSizeCodec<bigint | number, bigint>,\n    }) satisfies VariableSizeCodec<'one' | 2 | 3n>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/map-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getMapCodec, getMapDecoder, getMapEncoder } from '../map';\n\n{\n    // [getMapEncoder]: It knows if the encoder is fixed size or variable size.\n    const fixedKeyValue = [{} as FixedSizeEncoder<string>, {} as FixedSizeEncoder<number>] as const;\n    const anyKeyValue = [{} as Encoder<string>, {} as Encoder<number>] as const;\n\n    getMapEncoder(...fixedKeyValue) satisfies VariableSizeEncoder<Map<string, number>>;\n    getMapEncoder(...fixedKeyValue, { size: 42 }) satisfies FixedSizeEncoder<Map<string, number>>;\n    getMapEncoder(...anyKeyValue, { size: 0 }) satisfies FixedSizeEncoder<Map<string, number>, 0>;\n    getMapEncoder(...fixedKeyValue, { size: 'remainder' }) satisfies VariableSizeEncoder<Map<string, number>>;\n    getMapEncoder(...anyKeyValue, { size: 'remainder' }) satisfies VariableSizeEncoder<Map<string, number>>;\n}\n\n{\n    // [getMapDecoder]: It knows if the decoder is fixed size or variable size.\n    const fixedKeyValue = [{} as FixedSizeDecoder<string>, {} as FixedSizeDecoder<number>] as const;\n    const anyKeyValue = [{} as Decoder<string>, {} as Decoder<number>] as const;\n\n    getMapDecoder(...fixedKeyValue) satisfies VariableSizeDecoder<Map<string, number>>;\n    getMapDecoder(...fixedKeyValue, { size: 42 }) satisfies FixedSizeDecoder<Map<string, number>>;\n    getMapDecoder(...anyKeyValue, { size: 0 }) satisfies FixedSizeDecoder<Map<string, number>, 0>;\n    getMapDecoder(...fixedKeyValue, { size: 'remainder' }) satisfies VariableSizeDecoder<Map<string, number>>;\n    getMapDecoder(...anyKeyValue, { size: 'remainder' }) satisfies VariableSizeDecoder<Map<string, number>>;\n}\n\n{\n    // [getMapCodec]: It knows if the Codec is fixed size or variable size.\n    const fixedKeyValue = [{} as FixedSizeCodec<string>, {} as FixedSizeCodec<number>] as const;\n    const anyKeyValue = [{} as Codec<string>, {} as Codec<number>] as const;\n\n    getMapCodec(...fixedKeyValue) satisfies VariableSizeCodec<Map<string, number>>;\n    getMapCodec(...fixedKeyValue, { size: 42 }) satisfies FixedSizeCodec<Map<string, number>>;\n    getMapCodec(...anyKeyValue, { size: 0 }) satisfies FixedSizeCodec<Map<string, number>, Map<string, number>, 0>;\n    getMapCodec(...fixedKeyValue, { size: 'remainder' }) satisfies VariableSizeCodec<Map<string, number>>;\n    getMapCodec(...anyKeyValue, { size: 'remainder' }) satisfies VariableSizeCodec<Map<string, number>>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/nullable-typetest.ts",
    "content": "import {\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getNullableCodec, getNullableDecoder, getNullableEncoder } from '../nullable';\n\n{\n    // [getNullableEncoder]: It knows if the encoder is fixed size or variable size.\n    getNullableEncoder({} as FixedSizeEncoder<string>, { noneValue: 'zeroes' }) satisfies FixedSizeEncoder<\n        string | null\n    >;\n    getNullableEncoder({} as FixedSizeEncoder<string, 42>, {\n        noneValue: 'zeroes',\n        prefix: null,\n    }) satisfies FixedSizeEncoder<string | null, 42>;\n    getNullableEncoder({} as FixedSizeEncoder<string>) satisfies VariableSizeEncoder<string | null>;\n}\n\n{\n    // [getNullableDecoder]: It knows if the decoder is fixed size or variable size.\n    getNullableDecoder({} as FixedSizeDecoder<string>, { noneValue: 'zeroes' }) satisfies FixedSizeDecoder<\n        string | null\n    >;\n    getNullableDecoder({} as FixedSizeDecoder<string, 42>, {\n        noneValue: 'zeroes',\n        prefix: null,\n    }) satisfies FixedSizeDecoder<string | null, 42>;\n    getNullableDecoder({} as FixedSizeDecoder<string>) satisfies VariableSizeDecoder<string | null>;\n}\n\n{\n    // [getNullableCodec]: It knows if the codec is fixed size or variable size.\n    getNullableCodec({} as FixedSizeCodec<string>, { noneValue: 'zeroes' }) satisfies FixedSizeCodec<string | null>;\n    getNullableCodec({} as FixedSizeCodec<string, string, 42>, {\n        noneValue: 'zeroes',\n        prefix: null,\n    }) satisfies FixedSizeCodec<string | null, string | null, 42>;\n    getNullableCodec({} as FixedSizeCodec<string>) satisfies VariableSizeCodec<string | null>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/pattern-match-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getPatternMatchCodec, getPatternMatchDecoder, getPatternMatchEncoder } from '../pattern-match';\n\nconst numberValuePredicate = null as unknown as (value: number) => boolean;\nconst stringValuePredicate = null as unknown as (value: string) => boolean;\nconst bytesPredicate = null as unknown as (bytes: ReadonlyUint8Array) => boolean;\n\nconst numberTypePredicate = null as unknown as (value: number | string) => value is number;\nconst stringTypePredicate = null as unknown as (value: number | string) => value is string;\n\n// [DESCRIBE] getPatternMatchEncoder\n{\n    // [DESCRIBE] For boolean predicates\n    {\n        // It returns an encoder for the same type as the inputs\n        getPatternMatchEncoder([[numberValuePredicate, {} as Encoder<number>]]) satisfies Encoder<number>;\n\n        // It returns a FixedSizeEncoder if all encoders are FixedSizeEncoder\n        getPatternMatchEncoder([\n            [numberValuePredicate, {} as FixedSizeEncoder<number>],\n            [numberValuePredicate, {} as FixedSizeEncoder<number>],\n        ]) satisfies FixedSizeEncoder<number>;\n\n        // It maintains the size if all encoders are FixedSizeEncoder with the same size\n        getPatternMatchEncoder([\n            [stringValuePredicate, {} as FixedSizeEncoder<string, 4>],\n            [stringValuePredicate, {} as FixedSizeEncoder<string, 4>],\n        ]) satisfies FixedSizeEncoder<string, 4>;\n\n        // It returns a VariableSizeEncoder if all encoders are VariableSizeEncoder\n        getPatternMatchEncoder([\n            [numberValuePredicate, {} as VariableSizeEncoder<number>],\n            [numberValuePredicate, {} as VariableSizeEncoder<number>],\n        ]) satisfies VariableSizeEncoder<number>;\n\n        // It returns an Encoder if some input encoders are VariableSizeEncoder\n        getPatternMatchEncoder([\n            [numberValuePredicate, {} as VariableSizeEncoder<number>],\n            [numberValuePredicate, {} as VariableSizeEncoder<number>],\n        ]) satisfies Encoder<number>;\n\n        getPatternMatchEncoder([\n            [numberValuePredicate, {} as FixedSizeEncoder<number>],\n            [numberValuePredicate, {} as VariableSizeEncoder<number>],\n        ]) satisfies Encoder<number>;\n\n        getPatternMatchEncoder([\n            [numberValuePredicate, {} as VariableSizeEncoder<number>],\n            [numberValuePredicate, {} as FixedSizeEncoder<number>],\n        ]) satisfies Encoder<number>;\n    }\n\n    // [DESCRIBE] For type guard predicates\n    {\n        // It returns an encoder for the same type as the inputs\n        getPatternMatchEncoder<number | string>([\n            [numberTypePredicate, {} as Encoder<number>],\n            [stringTypePredicate, {} as Encoder<string>],\n        ]) satisfies Encoder<number | string>;\n\n        // It returns a FixedSizeEncoder if all encoders are FixedSizeEncoder\n        getPatternMatchEncoder<number | string>([\n            [numberTypePredicate, {} as FixedSizeEncoder<number>],\n            [stringTypePredicate, {} as FixedSizeEncoder<string>],\n        ]) satisfies FixedSizeEncoder<number | string>;\n\n        // It maintains the size if all encoders are FixedSizeEncoder with the same size\n        getPatternMatchEncoder<number | string, 4>([\n            [numberTypePredicate, {} as FixedSizeEncoder<number, 4>],\n            [stringTypePredicate, {} as FixedSizeEncoder<string, 4>],\n        ]) satisfies FixedSizeEncoder<number | string, 4>;\n\n        // It returns a VariableSizeEncoder if all encoders are VariableSizeEncoder\n        getPatternMatchEncoder<number | string>([\n            [numberTypePredicate, {} as VariableSizeEncoder<number>],\n            [stringTypePredicate, {} as VariableSizeEncoder<string>],\n        ]) satisfies VariableSizeEncoder<number | string>;\n\n        // It returns an Encoder if some input encoders are VariableSizeEncoder\n        getPatternMatchEncoder<number | string>([\n            [numberTypePredicate, {} as VariableSizeEncoder<number>],\n            [stringTypePredicate, {} as VariableSizeEncoder<string>],\n        ]) satisfies Encoder<number | string>;\n\n        getPatternMatchEncoder<number | string>([\n            [numberTypePredicate, {} as FixedSizeEncoder<number>],\n            [stringTypePredicate, {} as VariableSizeEncoder<string>],\n        ]) satisfies Encoder<number | string>;\n\n        getPatternMatchEncoder<number | string>([\n            [numberTypePredicate, {} as VariableSizeEncoder<number>],\n            [numberTypePredicate, {} as FixedSizeEncoder<number>],\n        ]) satisfies Encoder<number>;\n    }\n}\n\n// [DESCRIBE] getPatternMatchDecoder\n{\n    // It returns a decoder for the same type as the inputs\n    getPatternMatchDecoder([[bytesPredicate, {} as Decoder<number>]]) satisfies Decoder<number>;\n\n    // It returns a FixedSizeDecoder if all decoders are FixedSizeDecoder\n    getPatternMatchDecoder([\n        [bytesPredicate, {} as FixedSizeDecoder<number>],\n        [bytesPredicate, {} as FixedSizeDecoder<number>],\n    ]) satisfies FixedSizeDecoder<number>;\n\n    // It maintains the size if all decoders are FixedSizeDecoder with the same size\n    getPatternMatchDecoder([\n        [bytesPredicate, {} as FixedSizeDecoder<string, 4>],\n        [bytesPredicate, {} as FixedSizeDecoder<string, 4>],\n    ]) satisfies FixedSizeDecoder<string, 4>;\n\n    // It returns a VariableSizeDecoder if all decoders are VariableSizeDecoder\n    getPatternMatchDecoder([\n        [bytesPredicate, {} as VariableSizeDecoder<number>],\n        [bytesPredicate, {} as VariableSizeDecoder<number>],\n    ]) satisfies VariableSizeDecoder<number>;\n\n    // It returns a Decoder if some input decoders are VariableSizeDecoder\n    getPatternMatchDecoder([\n        [bytesPredicate, {} as VariableSizeDecoder<number>],\n        [bytesPredicate, {} as VariableSizeDecoder<number>],\n    ]) satisfies Decoder<number>;\n\n    getPatternMatchDecoder([\n        [bytesPredicate, {} as FixedSizeDecoder<number>],\n        [bytesPredicate, {} as VariableSizeDecoder<number>],\n    ]) satisfies Decoder<number>;\n\n    getPatternMatchDecoder([\n        [bytesPredicate, {} as VariableSizeDecoder<number>],\n        [bytesPredicate, {} as FixedSizeDecoder<number>],\n    ]) satisfies Decoder<number>;\n}\n\n// [DESCRIBE] getPatternMatchCodec\n{\n    // [DESCRIBE] For boolean predicates\n    {\n        // It returns a codec for the same type as the inputs\n        getPatternMatchCodec([[numberValuePredicate, bytesPredicate, {} as Codec<number>]]) satisfies Codec<number>;\n\n        // It returns a FixedSizeCodec if all codecs are FixedSizeCodec\n        getPatternMatchCodec([\n            [numberValuePredicate, bytesPredicate, {} as FixedSizeCodec<number>],\n            [numberValuePredicate, bytesPredicate, {} as FixedSizeCodec<number>],\n        ]) satisfies FixedSizeCodec<number>;\n\n        // It maintains the size if all codecs are FixedSizeCodec with the same size\n        getPatternMatchCodec([\n            [stringValuePredicate, bytesPredicate, {} as FixedSizeCodec<string, string, 4>],\n            [stringValuePredicate, bytesPredicate, {} as FixedSizeCodec<string, string, 4>],\n        ]) satisfies FixedSizeCodec<string, string, 4>;\n\n        // It returns a VariableSizeCodec if all codecs are VariableSizeCodec\n        getPatternMatchCodec([\n            [numberValuePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n            [numberValuePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n        ]) satisfies VariableSizeCodec<number>;\n\n        // It returns a Codec if some input codecs are VariableSizeCodec\n        getPatternMatchCodec([\n            [numberValuePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n            [numberValuePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n        ]) satisfies Codec<number>;\n\n        getPatternMatchCodec([\n            [numberValuePredicate, bytesPredicate, {} as FixedSizeCodec<number>],\n            [numberValuePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n        ]) satisfies Codec<number>;\n\n        getPatternMatchCodec([\n            [numberValuePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n            [numberValuePredicate, bytesPredicate, {} as FixedSizeCodec<number>],\n        ]) satisfies Codec<number>;\n    }\n\n    // [DESCRIBE] For type guard predicates\n    {\n        // It returns a codec for the same type as the inputs\n        getPatternMatchCodec<number | string>([\n            [numberTypePredicate, bytesPredicate, {} as Codec<number>],\n            [stringTypePredicate, bytesPredicate, {} as Codec<string>],\n        ]) satisfies Codec<number | string>;\n\n        // It returns a FixedSizeCodec if all codecs are FixedSizeCodec\n        getPatternMatchCodec<number | string>([\n            [numberTypePredicate, bytesPredicate, {} as FixedSizeCodec<number>],\n            [stringTypePredicate, bytesPredicate, {} as FixedSizeCodec<string>],\n        ]) satisfies FixedSizeCodec<number | string>;\n\n        // It maintains the size if all codecs are FixedSizeCodec with the same size\n        getPatternMatchCodec<number | string, number | string, 4>([\n            [stringTypePredicate, bytesPredicate, {} as FixedSizeCodec<string, string, 4>],\n            [numberTypePredicate, bytesPredicate, {} as FixedSizeCodec<number, number, 4>],\n        ]) satisfies FixedSizeCodec<number | string, number | string, 4>;\n\n        // It returns a VariableSizeCodec if all codecs are VariableSizeCodec\n        getPatternMatchCodec<number | string>([\n            [numberTypePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n            [stringTypePredicate, bytesPredicate, {} as VariableSizeCodec<string>],\n        ]) satisfies VariableSizeCodec<number | string>;\n\n        // It returns a Codec if some input codecs are VariableSizeCodec\n        getPatternMatchCodec<number | string>([\n            [numberTypePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n            [stringTypePredicate, bytesPredicate, {} as VariableSizeCodec<string>],\n        ]) satisfies Codec<number | string>;\n\n        getPatternMatchCodec<number | string>([\n            [numberTypePredicate, bytesPredicate, {} as FixedSizeCodec<number>],\n            [stringTypePredicate, bytesPredicate, {} as VariableSizeCodec<string>],\n        ]) satisfies Codec<number | string>;\n\n        getPatternMatchCodec<number | string>([\n            [numberTypePredicate, bytesPredicate, {} as VariableSizeCodec<number>],\n            [stringTypePredicate, bytesPredicate, {} as FixedSizeCodec<string>],\n        ]) satisfies Codec<number | string>;\n    }\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/predicate-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getPredicateCodec, getPredicateDecoder, getPredicateEncoder } from '../predicate';\n\nconst predicate = null as unknown as () => boolean;\n\n// [DESCRIBE] getPredicateEncoder\n{\n    // It returns an encoder for the same type as the inputs\n    getPredicateEncoder(predicate, {} as Encoder<number>, {} as Encoder<number>) satisfies Encoder<number>;\n\n    // It returns a FixedSizeEncoder if both encoders are FixedSizeEncoder\n    getPredicateEncoder(\n        predicate,\n        {} as FixedSizeEncoder<number>,\n        {} as FixedSizeEncoder<number>,\n    ) satisfies FixedSizeEncoder<number>;\n\n    // It maintains the size if both encoders are FixedSizeEncoder with the same size\n    getPredicateEncoder(\n        predicate,\n        {} as FixedSizeEncoder<string, 4>,\n        {} as FixedSizeEncoder<string, 4>,\n    ) satisfies FixedSizeEncoder<string, 4>;\n\n    // It returns a VariableSizeEncoder if both encoders are VariableSizeEncoder\n    getPredicateEncoder(\n        predicate,\n        {} as VariableSizeEncoder<number>,\n        {} as VariableSizeEncoder<number>,\n    ) satisfies VariableSizeEncoder<number>;\n\n    // It returns an Encoder if some input encoders are VariableSizeEncoder\n    getPredicateEncoder(\n        predicate,\n        {} as VariableSizeEncoder<number>,\n        {} as VariableSizeEncoder<number>,\n    ) satisfies Encoder<number>;\n\n    getPredicateEncoder(\n        predicate,\n        {} as FixedSizeEncoder<number>,\n        {} as VariableSizeEncoder<number>,\n    ) satisfies Encoder<number>;\n\n    getPredicateEncoder(\n        predicate,\n        {} as VariableSizeEncoder<number>,\n        {} as FixedSizeEncoder<number>,\n    ) satisfies Encoder<number>;\n\n    // It does not allow different encoder types\n    {\n        // @ts-expect-error Different encoder types\n        getPredicateEncoder(predicate, {} as Encoder<number>, {} as Encoder<string>);\n    }\n}\n\n// [DESCRIBE] getPredicateDecoder\n{\n    // It returns an encoder for the same type as the inputs\n    getPredicateDecoder(predicate, {} as Decoder<number>, {} as Decoder<number>) satisfies Decoder<number>;\n\n    // It returns a FixedSizeDecoder if both Decoders are FixedSizeDecoder\n    getPredicateDecoder(\n        predicate,\n        {} as FixedSizeDecoder<number>,\n        {} as FixedSizeDecoder<number>,\n    ) satisfies FixedSizeDecoder<number>;\n\n    // It maintains the size if both decoders are FixedSizeDecoder with the same size\n    getPredicateDecoder(\n        predicate,\n        {} as FixedSizeDecoder<string, 4>,\n        {} as FixedSizeDecoder<string, 4>,\n    ) satisfies FixedSizeDecoder<string, 4>;\n\n    // It returns a VariableSizeDecoder if both decoders are VariableSizeDecoder\n    getPredicateDecoder(\n        predicate,\n        {} as VariableSizeDecoder<number>,\n        {} as VariableSizeDecoder<number>,\n    ) satisfies VariableSizeDecoder<number>;\n\n    // It returns an Decoder if some input Decoders are VariableSizeDecoder\n    getPredicateDecoder(\n        predicate,\n        {} as VariableSizeDecoder<number>,\n        {} as VariableSizeDecoder<number>,\n    ) satisfies Decoder<number>;\n\n    getPredicateDecoder(\n        predicate,\n        {} as FixedSizeDecoder<number>,\n        {} as VariableSizeDecoder<number>,\n    ) satisfies Decoder<number>;\n\n    getPredicateDecoder(\n        predicate,\n        {} as VariableSizeDecoder<number>,\n        {} as FixedSizeDecoder<number>,\n    ) satisfies Decoder<number>;\n\n    // It does not allow different Decoder types\n    {\n        // @ts-expect-error Different Decoder types\n        getPredicateDecoder(predicate, {} as Decoder<number>, {} as Decoder<string>);\n    }\n}\n\n// [DESCRIBE] getPredicateCodec\n{\n    // It returns a codec for the same type as the inputs\n    getPredicateCodec(predicate, predicate, {} as Codec<number>, {} as Codec<number>) satisfies Codec<number>;\n\n    // It returns a FixedSizeCodec if both codecs are FixedSizeCodec\n    getPredicateCodec(\n        predicate,\n        predicate,\n        {} as FixedSizeCodec<number>,\n        {} as FixedSizeCodec<number>,\n    ) satisfies FixedSizeCodec<number>;\n\n    // It maintains the size if both codecs are FixedSizeCodec with the same size\n    getPredicateCodec(\n        predicate,\n        predicate,\n        {} as FixedSizeCodec<string, string, 4>,\n        {} as FixedSizeCodec<string, string, 4>,\n    ) satisfies FixedSizeCodec<string, string, 4>;\n\n    // It returns a VariableSizeCodec if both codecs are VariableSizeCodec\n    getPredicateCodec(\n        predicate,\n        predicate,\n        {} as VariableSizeCodec<number>,\n        {} as VariableSizeCodec<number>,\n    ) satisfies VariableSizeCodec<number>;\n\n    // It returns a Codec if some input codecs are VariableSizeCodec\n    getPredicateCodec(\n        predicate,\n        predicate,\n        {} as VariableSizeCodec<number>,\n        {} as VariableSizeCodec<number>,\n    ) satisfies Codec<number>;\n\n    getPredicateCodec(\n        predicate,\n        predicate,\n        {} as FixedSizeCodec<number>,\n        {} as VariableSizeCodec<number>,\n    ) satisfies Codec<number>;\n\n    getPredicateCodec(\n        predicate,\n        predicate,\n        {} as VariableSizeCodec<number>,\n        {} as FixedSizeCodec<number>,\n    ) satisfies Codec<number>;\n\n    // It does not allow different codec types\n    {\n        // @ts-expect-error Different codec types\n        getPredicateCodec(predicate, predicate, {} as Codec<number>, {} as Codec<string>);\n    }\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/set-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getSetCodec, getSetDecoder, getSetEncoder } from '../set';\n\n{\n    // [getSetEncoder]: It knows if the encoder is fixed size or variable size.\n    getSetEncoder({} as FixedSizeEncoder<string>) satisfies VariableSizeEncoder<Set<string>>;\n    getSetEncoder({} as FixedSizeEncoder<string>, { size: 42 }) satisfies FixedSizeEncoder<Set<string>>;\n    getSetEncoder({} as Encoder<string>, { size: 0 }) satisfies FixedSizeEncoder<Set<string>, 0>;\n    getSetEncoder({} as FixedSizeEncoder<string>, { size: 'remainder' }) satisfies VariableSizeEncoder<Set<string>>;\n    getSetEncoder({} as VariableSizeEncoder<string>, { size: 'remainder' }) satisfies VariableSizeEncoder<Set<string>>;\n}\n\n{\n    // [getSetDecoder]: It knows if the decoder is fixed size or variable size.\n    getSetDecoder({} as FixedSizeDecoder<string>) satisfies VariableSizeDecoder<Set<string>>;\n    getSetDecoder({} as FixedSizeDecoder<string>, { size: 42 }) satisfies FixedSizeDecoder<Set<string>>;\n    getSetDecoder({} as Decoder<string>, { size: 0 }) satisfies FixedSizeDecoder<Set<string>, 0>;\n    getSetDecoder({} as FixedSizeDecoder<string>, { size: 'remainder' }) satisfies VariableSizeDecoder<Set<string>>;\n    getSetDecoder({} as VariableSizeDecoder<string>, { size: 'remainder' }) satisfies VariableSizeDecoder<Set<string>>;\n}\n\n{\n    // [getSetCodec]: It knows if the codec is fixed size or variable size.\n    getSetCodec({} as FixedSizeCodec<string>) satisfies VariableSizeCodec<Set<string>>;\n    getSetCodec({} as FixedSizeCodec<string>, { size: 42 }) satisfies FixedSizeCodec<Set<string>>;\n    getSetCodec({} as Codec<string>, { size: 0 }) satisfies FixedSizeCodec<Set<string>, Set<string>, 0>;\n    getSetCodec({} as FixedSizeCodec<string>, { size: 'remainder' }) satisfies VariableSizeCodec<Set<string>>;\n    getSetCodec({} as VariableSizeCodec<string>, { size: 'remainder' }) satisfies VariableSizeCodec<Set<string>>;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/struct-typetest.ts",
    "content": "import {\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getU32Codec, getU32Decoder, getU32Encoder } from '@solana/codecs-numbers';\nimport { getUtf8Codec, getUtf8Decoder, getUtf8Encoder } from '@solana/codecs-strings';\n\nimport { getStructCodec, getStructDecoder, getStructEncoder } from '../struct';\n\n{\n    // [getStructEncoder]: It knows if the encoder is fixed size or variable size.\n    getStructEncoder([\n        ['name', {} as FixedSizeEncoder<string>],\n        ['age', {} as FixedSizeEncoder<number>],\n    ]) satisfies FixedSizeEncoder<{ age: number; name: string }>;\n    getStructEncoder([\n        ['name', {} as VariableSizeEncoder<string>],\n        ['age', {} as FixedSizeEncoder<number>],\n    ]) satisfies VariableSizeEncoder<{ age: number; name: string }>;\n    getStructEncoder([['age', getU32Encoder()]]) satisfies FixedSizeEncoder<{ age: number }>;\n    getStructEncoder([['name', getUtf8Encoder()]]) satisfies VariableSizeEncoder<{ name: string }>;\n}\n\n{\n    // [getStructDecoder]: It knows if the decoder is fixed size or variable size.\n    getStructDecoder([\n        ['name', {} as FixedSizeDecoder<string>],\n        ['age', {} as FixedSizeDecoder<number>],\n    ]) satisfies FixedSizeDecoder<{ age: number; name: string }>;\n    getStructDecoder([\n        ['name', {} as VariableSizeDecoder<string>],\n        ['age', {} as FixedSizeDecoder<number>],\n    ]) satisfies VariableSizeDecoder<{ age: number; name: string }>;\n    getStructDecoder([['age', getU32Decoder()]]) satisfies FixedSizeDecoder<{ age: number }>;\n    getStructDecoder([['name', getUtf8Decoder()]]) satisfies VariableSizeDecoder<{ name: string }>;\n}\n\n{\n    // [getStructCodec]: It knows if the codec is fixed size or variable size.\n    getStructCodec([\n        ['name', {} as FixedSizeCodec<string>],\n        ['age', {} as FixedSizeCodec<number>],\n    ]) satisfies FixedSizeCodec<{ age: number; name: string }>;\n    getStructCodec([\n        ['name', {} as VariableSizeCodec<string>],\n        ['age', {} as FixedSizeCodec<number>],\n    ]) satisfies VariableSizeCodec<{ age: number; name: string }>;\n    getStructCodec([['age', getU32Codec()]]) satisfies FixedSizeCodec<{ age: number }>;\n    getStructCodec([['name', getUtf8Codec()]]) satisfies VariableSizeCodec<{ name: string }>;\n}\n\n{\n    // [getStructEncoder]: It can infer complex struct types from fields.\n    getStructEncoder([\n        ['name', {} as VariableSizeEncoder<string>],\n        ['id', {} as FixedSizeEncoder<bigint | number>],\n        [\n            'address',\n            getStructEncoder([\n                ['street', {} as VariableSizeEncoder<string>],\n                ['city', {} as VariableSizeEncoder<string>],\n                ['country', {} as VariableSizeEncoder<string>],\n            ]),\n        ],\n    ]) satisfies VariableSizeEncoder<{\n        address: { city: string; country: string; street: string };\n        id: bigint | number;\n        name: string;\n    }>;\n}\n\n{\n    // [getStructDecoder]: It can infer complex struct types from fields.\n    getStructDecoder([\n        ['name', {} as VariableSizeDecoder<string>],\n        ['id', {} as FixedSizeDecoder<bigint>],\n        [\n            'address',\n            getStructDecoder([\n                ['street', {} as VariableSizeDecoder<string>],\n                ['city', {} as VariableSizeDecoder<string>],\n                ['country', {} as VariableSizeDecoder<string>],\n            ]),\n        ],\n    ]) satisfies VariableSizeDecoder<{\n        address: { city: string; country: string; street: string };\n        id: bigint;\n        name: string;\n    }>;\n}\n\n{\n    // [getStructCodec]: It can infer complex struct types from fields.\n    getStructCodec([\n        ['name', {} as VariableSizeCodec<string>],\n        ['id', {} as FixedSizeCodec<bigint | number, bigint>],\n        [\n            'address',\n            getStructCodec([\n                ['street', {} as VariableSizeCodec<string>],\n                ['city', {} as VariableSizeCodec<string>],\n                ['country', {} as VariableSizeCodec<string>],\n            ]),\n        ],\n    ]) satisfies VariableSizeCodec<\n        {\n            address: { city: string; country: string; street: string };\n            id: bigint | number;\n            name: string;\n        },\n        {\n            address: { city: string; country: string; street: string };\n            id: bigint;\n            name: string;\n        }\n    >;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/tuple-typetest.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getU8Codec, getU8Decoder, getU8Encoder } from '@solana/codecs-numbers';\nimport { getUtf8Codec, getUtf8Decoder, getUtf8Encoder } from '@solana/codecs-strings';\n\nimport { getTupleCodec, getTupleDecoder, getTupleEncoder } from '../tuple';\n\n{\n    // [getTupleEncoder]: It knows if the encoder is fixed size or variable size.\n    getTupleEncoder([]) satisfies FixedSizeEncoder<readonly []>;\n    getTupleEncoder([getU8Encoder()]) satisfies FixedSizeEncoder<readonly [number]>;\n    getTupleEncoder([getU8Encoder(), getUtf8Encoder()]) satisfies VariableSizeEncoder<readonly [number, string]>;\n}\n\n{\n    // [getTupleEncoder]: It infers the correct tuple type from the encoders.\n    getTupleEncoder([getU8Encoder(), getUtf8Encoder()]) satisfies Encoder<readonly [number, string]>;\n    // @ts-expect-error It does not combine all items into a single union type.\n    getTupleEncoder([getU8Encoder(), getUtf8Encoder()]) satisfies Encoder<readonly (number | string)[]>;\n}\n\n{\n    // [getTupleDecoder]: It knows if the decoder is fixed size or variable size.\n    getTupleDecoder([]) satisfies FixedSizeDecoder<readonly []>;\n    getTupleDecoder([getU8Decoder()]) satisfies FixedSizeDecoder<readonly [number]>;\n    getTupleDecoder([getU8Decoder(), getUtf8Decoder()]) satisfies VariableSizeDecoder<readonly [number, string]>;\n}\n\n{\n    // [getTupleDecoder]: It infers the correct tuple type from the decoders.\n    getTupleDecoder([getU8Decoder(), getUtf8Decoder()]) satisfies Decoder<readonly [number, string]>;\n    // Because decoder types are returned (and not requested), Decoder<[number, string]> does satisfy Decoder<(number | string)[]>.\n    getTupleDecoder([getU8Decoder(), getUtf8Decoder()]) satisfies Decoder<readonly (number | string)[]>;\n    // @ts-expect-error However, we cannot do things like swapping the order of the types.\n    getTupleDecoder([getU8Decoder(), getUtf8Decoder()]) satisfies Decoder<readonly [string, number]>;\n}\n\n{\n    // [getTupleCodec]: It knows if the codec is fixed size or variable size.\n    getTupleCodec([]) satisfies FixedSizeCodec<readonly []>;\n    getTupleCodec([getU8Codec()]) satisfies FixedSizeCodec<readonly [number]>;\n    getTupleCodec([getU8Codec(), getUtf8Codec()]) satisfies VariableSizeCodec<readonly [number, string]>;\n}\n\n{\n    // [getTupleCodec]: It infers the correct tuple type from the codecs.\n    getTupleCodec([getU8Codec(), getUtf8Codec()]) satisfies Codec<readonly [number, string]>;\n    // @ts-expect-error It does not combine all items into a single union type.\n    getTupleCodec([getU8Codec(), getUtf8Codec()]) satisfies Codec<readonly (number | string)[]>;\n}\n\n{\n    // [getTupleCodec]: It allows passing a description in the config.\n    getTupleCodec([getU8Codec(), getUtf8Codec()], { description: 'myDescription' }) satisfies Codec<\n        readonly [number, string]\n    >;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/__typetests__/union-typetest.ts",
    "content": "import { Codec, Decoder, Encoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { getUnionCodec, getUnionDecoder, getUnionEncoder } from '../union';\n\nconst getIndex = () => 0;\n\n// [DESCRIBE] getUnionEncoder.\n{\n    // It constructs unions from a list of encoder variants.\n    {\n        getUnionEncoder(\n            [\n                {} as Encoder<null>,\n                {} as Encoder<bigint | number>,\n                {} as Encoder<{ value: string }>,\n                {} as Encoder<{ x: number; y: number }>,\n            ],\n            getIndex,\n        ) satisfies Encoder<bigint | number | { value: string } | { x: number; y: number } | null>;\n    }\n\n    // It returns a fixed size encoder if all variants are fixed size.\n    {\n        getUnionEncoder(\n            [\n                {} as FixedSizeEncoder<null>,\n                {} as FixedSizeEncoder<bigint | number>,\n                {} as FixedSizeEncoder<{ value: string }>,\n                {} as FixedSizeEncoder<{ x: number; y: number }>,\n            ],\n            getIndex,\n        ) satisfies FixedSizeEncoder<bigint | number | { value: string } | { x: number; y: number } | null>;\n    }\n\n    // It does not return a fixed size encoder if any variant is variable size.\n    {\n        const decoder = getUnionEncoder([{} as Encoder<number>, {} as FixedSizeEncoder<number>], getIndex);\n        decoder satisfies Encoder<number>;\n        // @ts-expect-error Encoder is not fixed size.\n        decoder satisfies FixedSizeEncoder<number>;\n    }\n}\n\n// [DESCRIBE] getUnionDecoder.\n{\n    // It constructs unions from a list of decoder variants.\n    {\n        getUnionDecoder(\n            [\n                {} as Decoder<null>,\n                {} as Decoder<bigint | number>,\n                {} as Decoder<{ value: string }>,\n                {} as Decoder<{ x: number; y: number }>,\n            ],\n            getIndex,\n        ) satisfies Decoder<bigint | number | { value: string } | { x: number; y: number } | null>;\n    }\n\n    // It returns a fixed size decoder if all variants are fixed size.\n    {\n        const decoder = getUnionDecoder(\n            [\n                {} as FixedSizeDecoder<null>,\n                {} as FixedSizeDecoder<bigint | number>,\n                {} as FixedSizeDecoder<{ value: string }>,\n                {} as FixedSizeDecoder<{ x: number; y: number }>,\n            ],\n            getIndex,\n        );\n        decoder satisfies FixedSizeDecoder<bigint | number | { value: string } | { x: number; y: number } | null>;\n    }\n\n    // It does not return a fixed size decoder if any variant is variable size.\n    {\n        const decoder = getUnionDecoder([{} as Decoder<number>, {} as FixedSizeDecoder<number>], getIndex);\n        decoder satisfies Decoder<number>;\n        // @ts-expect-error Decoder is not fixed size.\n        decoder satisfies FixedSizeDecoder<number>;\n    }\n}\n\n// [DESCRIBE] getUnionCodec.\n{\n    // It constructs unions from a list of codec variants.\n    {\n        getUnionCodec(\n            [\n                {} as Codec<null>,\n                {} as Codec<bigint | number>,\n                {} as Codec<{ value: string }>,\n                {} as Codec<{ x: number; y: number }>,\n            ],\n            getIndex,\n            getIndex,\n        ) satisfies Codec<bigint | number | { value: string } | { x: number; y: number } | null>;\n    }\n\n    // It returns a fixed size codec if all variants are fixed size.\n    {\n        getUnionCodec(\n            [\n                {} as FixedSizeCodec<null>,\n                {} as FixedSizeCodec<bigint | number>,\n                {} as FixedSizeCodec<{ value: string }>,\n                {} as FixedSizeCodec<{ x: number; y: number }>,\n            ],\n            getIndex,\n            getIndex,\n        ) satisfies FixedSizeCodec<bigint | number | { value: string } | { x: number; y: number } | null>;\n    }\n\n    // It does not return a fixed size codec if any variant is variable size.\n    {\n        const codec = getUnionCodec([{} as Codec<number>, {} as FixedSizeCodec<number>], getIndex, getIndex);\n        codec satisfies Codec<number>;\n        // @ts-expect-error Codec is not fixed size.\n        codec satisfies FixedSizeCodec<number>;\n    }\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/array.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    getEncodedSize,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getU32Decoder, getU32Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { assertValidNumberOfItemsForCodec } from './assertions';\nimport { getFixedSize, getMaxSize } from './utils';\n\n/**\n * Defines the possible size strategies for array-like codecs (`array`, `map`, and `set`).\n *\n * The size of the collection can be determined using one of the following approaches:\n * - A {@link NumberCodec}, {@link NumberDecoder}, or {@link NumberEncoder} to store a size prefix.\n * - A fixed `number` of items, enforcing an exact length.\n * - The string `\"remainder\"`, which infers the number of items by consuming the rest of the available bytes.\n *\n * @typeParam TPrefix - A number codec, decoder, or encoder used for size prefixing.\n */\nexport type ArrayLikeCodecSize<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> =\n    | TPrefix\n    | number\n    | 'remainder';\n\n/**\n * Defines the configuration options for array codecs.\n *\n * @typeParam TPrefix - A number codec, decoder, or encoder used for size prefixing.\n */\nexport type ArrayCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * An optional description for the codec, that will be used in error messages.\n     */\n    description?: string;\n    /**\n     * Specifies how the size of the array is determined.\n     *\n     * - A {@link NumberCodec}, {@link NumberDecoder}, or {@link NumberEncoder} stores a size prefix before encoding the array.\n     * - A `number` enforces a fixed number of elements.\n     * - `\"remainder\"` uses all remaining bytes to infer the array length (only for fixed-size items).\n     *\n     * @defaultValue A `u32` size prefix.\n     */\n    size?: ArrayLikeCodecSize<TPrefix>;\n};\n\n/**\n * Returns an encoder for arrays of values.\n *\n * This encoder serializes arrays by encoding each element using the provided item encoder.\n * By default, a `u32` size prefix is included to indicate the number of items in the array.\n * The `size` option can be used to modify this behaviour.\n *\n * For more details, see {@link getArrayCodec}.\n *\n * @typeParam TFrom - The type of the elements in the array.\n *\n * @param item - The encoder for each item in the array.\n * @param config - Optional configuration for the size encoding strategy and description.\n * @returns A `VariableSizeEncoder<TFrom[]>` for encoding arrays.\n *\n * @example\n * Encoding an array of `u8` numbers.\n * ```ts\n * const encoder = getArrayEncoder(getU8Encoder());\n * const bytes = encoder.encode([1, 2, 3]);\n * // 0x03000000010203\n * //   |       └-- 3 items of 1 byte each.\n * //   └-- 4-byte prefix telling us to read 3 items.\n * ```\n *\n * @see {@link getArrayCodec}\n */\nexport function getArrayEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config: ArrayCodecConfig<NumberEncoder> & { size: 0 },\n): FixedSizeEncoder<TFrom[], 0>;\nexport function getArrayEncoder<TFrom>(\n    item: FixedSizeEncoder<TFrom>,\n    config: ArrayCodecConfig<NumberEncoder> & { size: number },\n): FixedSizeEncoder<TFrom[]>;\nexport function getArrayEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config?: ArrayCodecConfig<NumberEncoder>,\n): VariableSizeEncoder<TFrom[]>;\nexport function getArrayEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config: ArrayCodecConfig<NumberEncoder> = {},\n): Encoder<TFrom[]> {\n    const size = config.size ?? getU32Encoder();\n    const fixedSize = computeArrayLikeCodecSize(size, getFixedSize(item));\n    const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? undefined;\n\n    return createEncoder({\n        ...(fixedSize !== null\n            ? { fixedSize }\n            : {\n                  getSizeFromValue: (array: TFrom[]) => {\n                      const prefixSize = typeof size === 'object' ? getEncodedSize(array.length, size) : 0;\n                      return prefixSize + [...array].reduce((all, value) => all + getEncodedSize(value, item), 0);\n                  },\n                  maxSize,\n              }),\n        write: (array: TFrom[], bytes, offset) => {\n            if (typeof size === 'number') {\n                assertValidNumberOfItemsForCodec(config.description ?? 'array', size, array.length);\n            }\n            if (typeof size === 'object') {\n                offset = size.write(array.length, bytes, offset);\n            }\n            array.forEach(value => {\n                offset = item.write(value, bytes, offset);\n            });\n            return offset;\n        },\n    });\n}\n\n/**\n * Returns a decoder for arrays of values.\n *\n * This decoder deserializes arrays by decoding each element using the provided item decoder.\n * By default, a `u32` size prefix is expected to indicate the number of items in the array.\n * The `size` option can be used to modify this behaviour.\n *\n * For more details, see {@link getArrayCodec}.\n *\n * @typeParam TTo - The type of the decoded elements in the array.\n *\n * @param item - The decoder for each item in the array.\n * @param config - Optional configuration for the size decoding strategy.\n * @returns A `VariableSizeDecoder<TTo[]>` for decoding arrays.\n *\n * @example\n * Decoding an array of `u8` numbers.\n * ```ts\n * const decoder = getArrayDecoder(getU8Decoder());\n * const array = decoder.decode(new Uint8Array([0x03, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03]));\n * // [1, 2, 3]\n * // 0x03000000010203\n * //   |       └-- 3 items of 1 byte each.\n * //   └-- 4-byte prefix telling us to read 3 items.\n * ```\n *\n * @see {@link getArrayCodec}\n */\nexport function getArrayDecoder<TTo>(\n    item: Decoder<TTo>,\n    config: ArrayCodecConfig<NumberDecoder> & { size: 0 },\n): FixedSizeDecoder<TTo[], 0>;\nexport function getArrayDecoder<TTo>(\n    item: FixedSizeDecoder<TTo>,\n    config: ArrayCodecConfig<NumberDecoder> & { size: number },\n): FixedSizeDecoder<TTo[]>;\nexport function getArrayDecoder<TTo>(\n    item: Decoder<TTo>,\n    config?: ArrayCodecConfig<NumberDecoder>,\n): VariableSizeDecoder<TTo[]>;\nexport function getArrayDecoder<TTo>(item: Decoder<TTo>, config: ArrayCodecConfig<NumberDecoder> = {}): Decoder<TTo[]> {\n    const size = config.size ?? getU32Decoder();\n    const itemSize = getFixedSize(item);\n    const fixedSize = computeArrayLikeCodecSize(size, itemSize);\n    const maxSize = computeArrayLikeCodecSize(size, getMaxSize(item)) ?? undefined;\n\n    return createDecoder({\n        ...(fixedSize !== null ? { fixedSize } : { maxSize }),\n        read: (bytes: ReadonlyUint8Array | Uint8Array, offset) => {\n            const array: TTo[] = [];\n            if (typeof size === 'object' && bytes.slice(offset).length === 0) {\n                return [array, offset];\n            }\n\n            if (size === 'remainder') {\n                while (offset < bytes.length) {\n                    const [value, newOffset] = item.read(bytes, offset);\n                    offset = newOffset;\n                    array.push(value);\n                }\n                return [array, offset];\n            }\n\n            const [resolvedSize, newOffset] = typeof size === 'number' ? [size, offset] : size.read(bytes, offset);\n            offset = newOffset;\n            for (let i = 0; i < resolvedSize; i += 1) {\n                const [value, newOffset] = item.read(bytes, offset);\n                offset = newOffset;\n                array.push(value);\n            }\n            return [array, offset];\n        },\n    });\n}\n\n/**\n * Returns a codec for encoding and decoding arrays of values.\n *\n * This codec serializes arrays by encoding each element using the provided item codec.\n * By default, a `u32` size prefix is included to indicate the number of items in the array.\n * The `size` option can be used to modify this behaviour.\n *\n * @typeParam TFrom - The type of the elements to encode.\n * @typeParam TTo - The type of the decoded elements.\n *\n * @param item - The codec for each item in the array.\n * @param config - Optional configuration for the size encoding/decoding strategy.\n * @returns A `VariableSizeCodec<TFrom[], TTo[]>` for encoding and decoding arrays.\n *\n * @example\n * Encoding and decoding an array of `u8` numbers.\n * ```ts\n * const codec = getArrayCodec(getU8Codec());\n * const bytes = codec.encode([1, 2, 3]);\n * // 0x03000000010203\n * //   |       └-- 3 items of 1 byte each.\n * //   └-- 4-byte prefix telling us to read 3 items.\n *\n * const array = codec.decode(bytes);\n * // [1, 2, 3]\n * ```\n *\n * @example\n * Using a `u16` size prefix instead of `u32`.\n * ```ts\n * const codec = getArrayCodec(getU8Codec(), { size: getU16Codec() });\n * const bytes = codec.encode([1, 2, 3]);\n * // 0x0300010203\n * //   |   └-- 3 items of 1 byte each.\n * //   └-- 2-byte prefix telling us to read 3 items.\n * ```\n *\n * @example\n * Using a fixed-size array of 3 items.\n * ```ts\n * const codec = getArrayCodec(getU8Codec(), { size: 3 });\n * codec.encode([1, 2, 3]);\n * // 0x010203\n * //   └-- 3 items of 1 byte each. There must always be 3 items in the array.\n * ```\n *\n * @example\n * Using the `\"remainder\"` size strategy.\n * ```ts\n * const codec = getArrayCodec(getU8Codec(), { size: 'remainder' });\n * codec.encode([1, 2, 3]);\n * // 0x010203\n * //   └-- 3 items of 1 byte each. The size is inferred from the remainder of the bytes.\n * ```\n *\n * @remarks\n * The size of the array can be controlled using the `size` option:\n * - A `Codec<number>` (e.g. `getU16Codec()`) stores a size prefix before the array.\n * - A `number` enforces a fixed number of elements.\n * - `\"remainder\"` uses all remaining bytes to infer the array length.\n *\n * Separate {@link getArrayEncoder} and {@link getArrayDecoder} functions are available.\n *\n * ```ts\n * const bytes = getArrayEncoder(getU8Encoder()).encode([1, 2, 3]);\n * const array = getArrayDecoder(getU8Decoder()).decode(bytes);\n * ```\n *\n * @see {@link getArrayEncoder}\n * @see {@link getArrayDecoder}\n */\nexport function getArrayCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config: ArrayCodecConfig<NumberCodec> & { size: 0 },\n): FixedSizeCodec<TFrom[], TTo[], 0>;\nexport function getArrayCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: FixedSizeCodec<TFrom, TTo>,\n    config: ArrayCodecConfig<NumberCodec> & { size: number },\n): FixedSizeCodec<TFrom[], TTo[]>;\nexport function getArrayCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config?: ArrayCodecConfig<NumberCodec>,\n): VariableSizeCodec<TFrom[], TTo[]>;\nexport function getArrayCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config: ArrayCodecConfig<NumberCodec> = {},\n): Codec<TFrom[], TTo[]> {\n    return combineCodec(getArrayEncoder(item, config as object), getArrayDecoder(item, config as object));\n}\n\nfunction computeArrayLikeCodecSize(size: number | object | 'remainder', itemSize: number | null): number | null {\n    if (typeof size !== 'number') return null;\n    if (size === 0) return 0;\n    return itemSize === null ? null : itemSize * size;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/assertions.ts",
    "content": "import { SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, SolanaError } from '@solana/errors';\n\n/** Checks the number of items in an array-like structure is expected. */\nexport function assertValidNumberOfItemsForCodec(\n    codecDescription: string,\n    expected: bigint | number,\n    actual: bigint | number,\n) {\n    if (expected !== actual) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n            actual,\n            codecDescription,\n            expected,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/bit-array.ts",
    "content": "import {\n    assertByteArrayHasEnoughBytesForCodec,\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n} from '@solana/codecs-core';\n\n/**\n * Defines the configuration options for bit array codecs.\n *\n * A bit array codec encodes an array of booleans into bits, packing them into bytes.\n * This configuration allows adjusting the bit ordering.\n *\n * @see {@link getBitArrayEncoder}\n * @see {@link getBitArrayDecoder}\n * @see {@link getBitArrayCodec}\n */\nexport type BitArrayCodecConfig = {\n    /**\n     * Determines whether the bits should be read in reverse order.\n     *\n     * - `false` (default): The first boolean is stored in the most significant bit (MSB-first).\n     * - `true`: The first boolean is stored in the least significant bit (LSB-first).\n     *\n     * @defaultValue `false`\n     */\n    backward?: boolean;\n};\n\n/**\n * Returns an encoder that packs an array of booleans into bits.\n *\n * This encoder converts a list of `boolean` values into a compact bit representation,\n * storing 8 booleans per byte.\n *\n * The `backward` config option determines whether the bits are stored in MSB-first (`false`)\n * or LSB-first (`true`).\n *\n * For more details, see {@link getBitArrayCodec}.\n *\n * @typeParam TSize - The number of bytes used to store the bit array.\n *\n * @param size - The number of bytes allocated for the bit array (must be sufficient for the expected boolean count).\n * @param config - Configuration options for encoding the bit array.\n * @returns A `FixedSizeEncoder<boolean[], TSize>` for encoding bit arrays.\n *\n * @example\n * Encoding a bit array.\n * ```ts\n * const encoder = getBitArrayEncoder(1);\n *\n * encoder.encode([true, false, true, false, false, false, false, false]);\n * // 0xa0 (0b10100000)\n * ```\n *\n * @see {@link getBitArrayCodec}\n */\nexport function getBitArrayEncoder<TSize extends number>(\n    size: TSize,\n    config: BitArrayCodecConfig | boolean = {},\n): FixedSizeEncoder<boolean[], TSize> {\n    const parsedConfig: BitArrayCodecConfig = typeof config === 'boolean' ? { backward: config } : config;\n    const backward = parsedConfig.backward ?? false;\n    return createEncoder({\n        fixedSize: size,\n        write(value: boolean[], bytes, offset) {\n            const bytesToAdd: number[] = [];\n\n            for (let i = 0; i < size; i += 1) {\n                let byte = 0;\n                for (let j = 0; j < 8; j += 1) {\n                    const feature = Number(value[i * 8 + j] ?? 0);\n                    byte |= feature << (backward ? j : 7 - j);\n                }\n                if (backward) {\n                    bytesToAdd.unshift(byte);\n                } else {\n                    bytesToAdd.push(byte);\n                }\n            }\n\n            bytes.set(bytesToAdd, offset);\n            return size;\n        },\n    });\n}\n\n/**\n * Returns a decoder that unpacks bits into an array of booleans.\n *\n * This decoder converts a compact bit representation back into a list of `boolean` values.\n * Each byte is expanded into 8 booleans.\n *\n * The `backward` config option determines whether the bits are read in MSB-first (`false`)\n * or LSB-first (`true`).\n *\n * For more details, see {@link getBitArrayCodec}.\n *\n * @typeParam TSize - The number of bytes used to store the bit array.\n *\n * @param size - The number of bytes allocated for the bit array (must be sufficient for the expected boolean count).\n * @param config - Configuration options for decoding the bit array.\n * @returns A `FixedSizeDecoder<boolean[], TSize>` for decoding bit arrays.\n *\n * @example\n * Decoding a bit array.\n * ```ts\n * const decoder = getBitArrayDecoder(1);\n *\n * decoder.decode(new Uint8Array([0xa0]));\n * // [true, false, true, false, false, false, false, false]\n * ```\n *\n * @see {@link getBitArrayCodec}\n */\nexport function getBitArrayDecoder<TSize extends number>(\n    size: TSize,\n    config: BitArrayCodecConfig | boolean = {},\n): FixedSizeDecoder<boolean[], TSize> {\n    const parsedConfig: BitArrayCodecConfig = typeof config === 'boolean' ? { backward: config } : config;\n    const backward = parsedConfig.backward ?? false;\n    return createDecoder({\n        fixedSize: size,\n        read(bytes, offset) {\n            assertByteArrayHasEnoughBytesForCodec('bitArray', size, bytes, offset);\n            const booleans: boolean[] = [];\n            let slice = bytes.slice(offset, offset + size);\n            slice = backward ? slice.reverse() : slice;\n\n            slice.forEach(byte => {\n                for (let i = 0; i < 8; i += 1) {\n                    if (backward) {\n                        booleans.push(Boolean(byte & 1));\n                        byte >>= 1;\n                    } else {\n                        booleans.push(Boolean(byte & 0b1000_0000));\n                        byte <<= 1;\n                    }\n                }\n            });\n\n            return [booleans, offset + size];\n        },\n    });\n}\n\n/**\n * Returns a codec that encodes and decodes boolean arrays as compact bit representations.\n *\n * This codec efficiently stores boolean arrays as bits, packing 8 values per byte.\n * The `backward` config option determines whether bits are stored in MSB-first (`false`)\n * or LSB-first (`true`).\n *\n * @typeParam TSize - The number of bytes used to store the bit array.\n *\n * @param size - The number of bytes allocated for the bit array (must be sufficient for the expected boolean count).\n * @param config - Configuration options for encoding and decoding the bit array.\n * @returns A `FixedSizeCodec<boolean[], boolean[], TSize>` for encoding and decoding bit arrays.\n *\n * @example\n * Encoding and decoding a bit array.\n * ```ts\n * const codec = getBitArrayCodec(1);\n *\n * codec.encode([true, false, true, false, false, false, false, false]);\n * // 0xa0 (0b10100000)\n *\n * codec.decode(new Uint8Array([0xa0]));\n * // [true, false, true, false, false, false, false, false]\n * ```\n *\n * @example\n * Encoding and decoding a bit array backwards.\n * ```ts\n * const codec = getBitArrayCodec(1, { backward: true });\n *\n * codec.encode([true, false, true, false, false, false, false, false]);\n * // 0x05 (0b00000101)\n *\n * codec.decode(new Uint8Array([0x05]));\n * // [true, false, true, false, false, false, false, false]\n * ```\n *\n * @remarks\n * Separate {@link getBitArrayEncoder} and {@link getBitArrayDecoder} functions are available.\n *\n * ```ts\n * const bytes = getBitArrayEncoder(1).encode([true, false, true, false]);\n * const value = getBitArrayDecoder(1).decode(bytes);\n * ```\n *\n * @see {@link getBitArrayEncoder}\n * @see {@link getBitArrayDecoder}\n */\nexport function getBitArrayCodec<TSize extends number>(\n    size: TSize,\n    config: BitArrayCodecConfig | boolean = {},\n): FixedSizeCodec<boolean[], boolean[], TSize> {\n    return combineCodec(getBitArrayEncoder(size, config), getBitArrayDecoder(size, config));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/boolean.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    FixedSizeNumberCodec,\n    FixedSizeNumberDecoder,\n    FixedSizeNumberEncoder,\n    getU8Decoder,\n    getU8Encoder,\n    NumberCodec,\n    NumberDecoder,\n    NumberEncoder,\n} from '@solana/codecs-numbers';\n\n/**\n * Defines the configuration options for boolean codecs.\n *\n * A boolean codec encodes `true` as `1` and `false` as `0`.\n * The `size` option allows customizing the number codec used for storage.\n *\n * @typeParam TSize - A number codec, encoder, or decoder used for boolean representation.\n *\n * @see {@link getBooleanEncoder}\n * @see {@link getBooleanDecoder}\n * @see {@link getBooleanCodec}\n */\nexport type BooleanCodecConfig<TSize extends NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * The number codec used to store boolean values.\n     *\n     * - By default, booleans are stored as a `u8` (`1` for `true`, `0` for `false`).\n     * - A custom number codec can be provided to change the storage size.\n     *\n     * @defaultValue `u8`\n     */\n    size?: TSize;\n};\n\n/**\n * Returns an encoder for boolean values.\n *\n * This encoder converts `true` into `1` and `false` into `0`.\n * The `size` option allows customizing the number codec used for storage.\n *\n * For more details, see {@link getBooleanCodec}.\n *\n * @param config - Configuration options for encoding booleans.\n * @returns A `FixedSizeEncoder<boolean, N>` where `N` is the size of the number codec.\n *\n * @example\n * Encoding booleans.\n * ```ts\n * const encoder = getBooleanEncoder();\n *\n * encoder.encode(false); // 0x00\n * encoder.encode(true);  // 0x01\n * ```\n *\n * @see {@link getBooleanCodec}\n */\nexport function getBooleanEncoder(): FixedSizeEncoder<boolean, 1>;\nexport function getBooleanEncoder<TSize extends number>(\n    config: BooleanCodecConfig<NumberEncoder> & { size: FixedSizeNumberEncoder<TSize> },\n): FixedSizeEncoder<boolean, TSize>;\nexport function getBooleanEncoder(config: BooleanCodecConfig<NumberEncoder>): VariableSizeEncoder<boolean>;\nexport function getBooleanEncoder(config: BooleanCodecConfig<NumberEncoder> = {}): Encoder<boolean> {\n    return transformEncoder(config.size ?? getU8Encoder(), (value: boolean) => (value ? 1 : 0));\n}\n\n/**\n * Returns a decoder for boolean values.\n *\n * This decoder reads a number and interprets `1` as `true` and `0` as `false`.\n * The `size` option allows customizing the number codec used for storage.\n *\n * For more details, see {@link getBooleanCodec}.\n *\n * @param config - Configuration options for decoding booleans.\n * @returns A `FixedSizeDecoder<boolean, N>` where `N` is the size of the number codec.\n *\n * @example\n * Decoding booleans.\n * ```ts\n * const decoder = getBooleanDecoder();\n *\n * decoder.decode(new Uint8Array([0x00])); // false\n * decoder.decode(new Uint8Array([0x01])); // true\n * ```\n *\n * @see {@link getBooleanCodec}\n */\nexport function getBooleanDecoder(): FixedSizeDecoder<boolean, 1>;\nexport function getBooleanDecoder<TSize extends number>(\n    config: BooleanCodecConfig<NumberDecoder> & { size: FixedSizeNumberDecoder<TSize> },\n): FixedSizeDecoder<boolean, TSize>;\nexport function getBooleanDecoder(config: BooleanCodecConfig<NumberDecoder>): VariableSizeDecoder<boolean>;\nexport function getBooleanDecoder(config: BooleanCodecConfig<NumberDecoder> = {}): Decoder<boolean> {\n    return transformDecoder(config.size ?? getU8Decoder(), (value: bigint | number): boolean => Number(value) === 1);\n}\n\n/**\n * Returns a codec for encoding and decoding boolean values.\n *\n * By default, booleans are stored as a `u8` (`1` for `true`, `0` for `false`).\n * The `size` option allows customizing the number codec used for storage.\n *\n * @param config - Configuration options for encoding and decoding booleans.\n * @returns A `FixedSizeCodec<boolean, boolean, N>` where `N` is the size of the number codec.\n *\n * @example\n * Encoding and decoding booleans using a `u8` (default).\n * ```ts\n * const codec = getBooleanCodec();\n *\n * codec.encode(false); // 0x00\n * codec.encode(true);  // 0x01\n *\n * codec.decode(new Uint8Array([0x00])); // false\n * codec.decode(new Uint8Array([0x01])); // true\n * ```\n *\n * @example\n * Encoding and decoding booleans using a custom number codec.\n * ```ts\n * const codec = getBooleanCodec({ size: getU16Codec() });\n *\n * codec.encode(false); // 0x0000\n * codec.encode(true);  // 0x0100\n *\n * codec.decode(new Uint8Array([0x00, 0x00])); // false\n * codec.decode(new Uint8Array([0x01, 0x00])); // true\n * ```\n *\n * @remarks\n * Separate {@link getBooleanEncoder} and {@link getBooleanDecoder} functions are available.\n *\n * ```ts\n * const bytes = getBooleanEncoder().encode(true);\n * const value = getBooleanDecoder().decode(bytes);\n * ```\n *\n * @see {@link getBooleanEncoder}\n * @see {@link getBooleanDecoder}\n */\nexport function getBooleanCodec(): FixedSizeCodec<boolean, boolean, 1>;\nexport function getBooleanCodec<TSize extends number>(\n    config: BooleanCodecConfig<NumberCodec> & { size: FixedSizeNumberCodec<TSize> },\n): FixedSizeCodec<boolean, boolean, TSize>;\nexport function getBooleanCodec(config: BooleanCodecConfig<NumberCodec>): VariableSizeCodec<boolean>;\nexport function getBooleanCodec(config: BooleanCodecConfig<NumberCodec> = {}): Codec<boolean> {\n    return combineCodec(getBooleanEncoder(config), getBooleanDecoder(config));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/bytes.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\n/**\n * Returns an encoder for raw byte arrays.\n *\n * This encoder writes byte arrays exactly as provided without modification.\n *\n * The size of the encoded byte array is determined by the length of the input.\n * - To enforce a fixed size, consider using {@link fixEncoderSize}.\n * - To add a size prefix, use {@link addEncoderSizePrefix}.\n * - To add a sentinel value, use {@link addEncoderSentinel}.\n *\n * For more details, see {@link getBytesCodec}.\n *\n * @returns A `VariableSizeEncoder<ReadonlyUint8Array | Uint8Array>`.\n *\n * @example\n * Encoding a byte array as-is.\n * ```ts\n * const encoder = getBytesEncoder();\n *\n * encoder.encode(new Uint8Array([1, 2, 3])); // 0x010203\n * encoder.encode(new Uint8Array([255, 0, 127])); // 0xff007f\n * ```\n *\n * @see {@link getBytesCodec}\n */\nexport function getBytesEncoder(): VariableSizeEncoder<ReadonlyUint8Array | Uint8Array> {\n    return createEncoder({\n        getSizeFromValue: value => value.length,\n        write: (value, bytes, offset) => {\n            bytes.set(value, offset);\n            return offset + value.length;\n        },\n    });\n}\n\n/**\n * Returns a decoder for raw byte arrays.\n *\n * This decoder reads byte arrays exactly as provided without modification.\n *\n * The decoded byte array extends from the provided offset to the end of the input.\n * - To enforce a fixed size, consider using {@link fixDecoderSize}.\n * - To add a size prefix, use {@link addDecoderSizePrefix}.\n * - To add a sentinel value, use {@link addDecoderSentinel}.\n *\n * For more details, see {@link getBytesCodec}.\n *\n * @returns A `VariableSizeDecoder<ReadonlyUint8Array>`.\n *\n * @example\n * Decoding a byte array as-is.\n * ```ts\n * const decoder = getBytesDecoder();\n *\n * decoder.decode(new Uint8Array([1, 2, 3])); // Uint8Array([1, 2, 3])\n * decoder.decode(new Uint8Array([255, 0, 127])); // Uint8Array([255, 0, 127])\n * ```\n *\n * @see {@link getBytesCodec}\n */\nexport function getBytesDecoder(): VariableSizeDecoder<ReadonlyUint8Array> {\n    return createDecoder({\n        read: (bytes, offset) => {\n            const slice = bytes.slice(offset);\n            return [slice, offset + slice.length];\n        },\n    });\n}\n\n/**\n * Returns a codec for encoding and decoding raw byte arrays.\n *\n * This codec serializes and deserializes byte arrays without modification.\n *\n * The size of the encoded and decoded byte array is determined dynamically.\n * This means, when reading, the codec will consume all remaining bytes in the input.\n * - To enforce a fixed size, consider using {@link fixCodecSize}.\n * - To add a size prefix, use {@link addCodecSizePrefix}.\n * - To add a sentinel value, use {@link addCodecSentinel}.\n *\n * @returns A `VariableSizeCodec<ReadonlyUint8Array | Uint8Array, ReadonlyUint8Array>`.\n *\n * @example\n * Encoding and decoding a byte array.\n * ```ts\n * const codec = getBytesCodec();\n *\n * codec.encode(new Uint8Array([1, 2, 3])); // 0x010203\n * codec.decode(new Uint8Array([255, 0, 127])); // Uint8Array([255, 0, 127])\n * ```\n *\n * @remarks\n * Separate {@link getBytesEncoder} and {@link getBytesDecoder} functions are available.\n *\n * ```ts\n * const bytes = getBytesEncoder().encode(new Uint8Array([1, 2, 3]));\n * const value = getBytesDecoder().decode(bytes);\n * ```\n *\n * @see {@link getBytesEncoder}\n * @see {@link getBytesDecoder}\n */\nexport function getBytesCodec(): VariableSizeCodec<ReadonlyUint8Array | Uint8Array, ReadonlyUint8Array> {\n    return combineCodec(getBytesEncoder(), getBytesDecoder());\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/constant.ts",
    "content": "import {\n    combineCodec,\n    containsBytes,\n    createDecoder,\n    createEncoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    ReadonlyUint8Array,\n} from '@solana/codecs-core';\nimport { getBase16Decoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__CODECS__INVALID_CONSTANT, SolanaError } from '@solana/errors';\n\n/**\n * Returns an encoder that always writes a predefined constant byte sequence.\n *\n * This encoder ensures that encoding always produces the specified byte array,\n * ignoring any input values.\n *\n * For more details, see {@link getConstantCodec}.\n *\n * @typeParam TConstant - The fixed byte sequence that will be written during encoding.\n *\n * @param constant - The predefined byte array to encode.\n * @returns A `FixedSizeEncoder<void, N>` where `N` is the length of the constant.\n *\n * @example\n * Encoding a constant magic number.\n * ```ts\n * const encoder = getConstantEncoder(new Uint8Array([1, 2, 3, 4]));\n *\n * const bytes = encoder.encode();\n * // 0x01020304\n * //   └──────┘ The predefined 4-byte constant.\n * ```\n *\n * @see {@link getConstantCodec}\n */\nexport function getConstantEncoder<TConstant extends ReadonlyUint8Array>(\n    constant: TConstant,\n): FixedSizeEncoder<void, TConstant['length']> {\n    return createEncoder({\n        fixedSize: constant.length,\n        write: (_, bytes, offset) => {\n            bytes.set(constant, offset);\n            return offset + constant.length;\n        },\n    });\n}\n\n/**\n * Returns a decoder that verifies a predefined constant byte sequence.\n *\n * This decoder reads the next bytes and checks that they match the provided constant.\n * If the bytes differ, it throws an error.\n *\n * For more details, see {@link getConstantCodec}.\n *\n * @typeParam TConstant - The fixed byte sequence expected during decoding.\n *\n * @param constant - The predefined byte array to verify.\n * @returns A `FixedSizeDecoder<void, N>` where `N` is the length of the constant.\n *\n * @example\n * Decoding a constant magic number.\n * ```ts\n * const decoder = getConstantDecoder(new Uint8Array([1, 2, 3]));\n *\n * decoder.decode(new Uint8Array([1, 2, 3])); // Passes\n * decoder.decode(new Uint8Array([1, 2, 4])); // Throws an error\n * ```\n *\n * @see {@link getConstantCodec}\n */\nexport function getConstantDecoder<TConstant extends ReadonlyUint8Array>(\n    constant: TConstant,\n): FixedSizeDecoder<void, TConstant['length']> {\n    return createDecoder({\n        fixedSize: constant.length,\n        read: (bytes, offset) => {\n            const base16 = getBase16Decoder();\n            if (!containsBytes(bytes, constant, offset)) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_CONSTANT, {\n                    constant,\n                    data: bytes,\n                    hexConstant: base16.decode(constant),\n                    hexData: base16.decode(bytes),\n                    offset,\n                });\n            }\n            return [undefined, offset + constant.length];\n        },\n    });\n}\n\n/**\n * Returns a codec that encodes and decodes a predefined constant byte sequence.\n *\n * - **Encoding:** Always writes the specified byte array.\n * - **Decoding:** Asserts that the next bytes match the constant, throwing an error if they do not.\n *\n * This is useful for encoding fixed byte patterns required in a binary format or to use in\n * conjunction with other codecs such as {@link getHiddenPrefixCodec} or {@link getHiddenSuffixCodec}.\n *\n * @typeParam TConstant - The fixed byte sequence to encode and verify during decoding.\n *\n * @param constant - The predefined byte array to encode and assert during decoding.\n * @returns A `FixedSizeCodec<void, void, N>` where `N` is the length of the constant.\n *\n * @example\n * Encoding and decoding a constant magic number.\n * ```ts\n * const codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n *\n * codec.encode(); // 0x010203\n * codec.decode(new Uint8Array([1, 2, 3])); // Passes\n * codec.decode(new Uint8Array([1, 2, 4])); // Throws an error\n * ```\n *\n * @remarks\n * Separate {@link getConstantEncoder} and {@link getConstantDecoder} functions are available.\n *\n * ```ts\n * const bytes = getConstantEncoder(new Uint8Array([1, 2, 3])).encode();\n * getConstantDecoder(new Uint8Array([1, 2, 3])).decode(bytes);\n * ```\n *\n * @see {@link getConstantEncoder}\n * @see {@link getConstantDecoder}\n */\nexport function getConstantCodec<TConstant extends ReadonlyUint8Array>(\n    constant: TConstant,\n): FixedSizeCodec<void, void, TConstant['length']> {\n    return combineCodec(getConstantEncoder(constant), getConstantDecoder(constant));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/discriminated-union.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT, SolanaError } from '@solana/errors';\n\nimport { getTupleDecoder, getTupleEncoder } from './tuple';\nimport { getUnionDecoder, getUnionEncoder } from './union';\nimport { DrainOuterGeneric } from './utils';\n\n/**\n * Represents a discriminated union using a specific discriminator property.\n *\n * A discriminated union is a TypeScript-friendly way to represent Rust-like enums.\n * Each variant in the union is distinguished by a shared discriminator property.\n *\n * @typeParam TDiscriminatorProperty - The name of the discriminator property.\n * @typeParam TDiscriminatorValue - The type of the discriminator value.\n *\n * @example\n * ```ts\n * type Message =\n *   | { __kind: 'Quit' } // Empty variant\n *   | { __kind: 'Write'; fields: [string] } // Tuple variant\n *   | { __kind: 'Move'; x: number; y: number }; // Struct variant\n * ```\n */\nexport type DiscriminatedUnion<\n    TDiscriminatorProperty extends string = '__kind',\n    TDiscriminatorValue extends string = string,\n> = {\n    [P in TDiscriminatorProperty]: TDiscriminatorValue;\n};\n\n/**\n * Extracts a variant from a discriminated union based on its discriminator value.\n *\n * @typeParam TUnion - The discriminated union type.\n * @typeParam TDiscriminatorProperty - The property used as the discriminator.\n * @typeParam TDiscriminatorValue - The specific variant to extract.\n *\n * @example\n * ```ts\n * type Message =\n *   | { __kind: 'Quit' }\n *   | { __kind: 'Write'; fields: [string] }\n *   | { __kind: 'Move'; x: number; y: number };\n *\n * type ClickEvent = GetDiscriminatedUnionVariant<Message, '__kind', 'Move'>;\n * // -> { __kind: 'Move'; x: number; y: number }\n * ```\n */\nexport type GetDiscriminatedUnionVariant<\n    TUnion extends DiscriminatedUnion<TDiscriminatorProperty>,\n    TDiscriminatorProperty extends string,\n    TDiscriminatorValue extends TUnion[TDiscriminatorProperty],\n> = Extract<TUnion, DiscriminatedUnion<TDiscriminatorProperty, TDiscriminatorValue>>;\n\n/**\n * Extracts a variant from a discriminated union without its discriminator property.\n *\n * @typeParam TUnion - The discriminated union type.\n * @typeParam TDiscriminatorProperty - The property used as the discriminator.\n * @typeParam TDiscriminatorValue - The specific variant to extract.\n *\n * @example\n * ```ts\n * type Message =\n *   | { __kind: 'Quit' }\n *   | { __kind: 'Write'; fields: [string] }\n *   | { __kind: 'Move'; x: number; y: number };\n *\n * type MoveContent = GetDiscriminatedUnionVariantContent<Message, '__kind', 'Move'>;\n * // -> { x: number; y: number }\n * ```\n */\nexport type GetDiscriminatedUnionVariantContent<\n    TUnion extends DiscriminatedUnion<TDiscriminatorProperty>,\n    TDiscriminatorProperty extends string,\n    TDiscriminatorValue extends TUnion[TDiscriminatorProperty],\n> = Omit<GetDiscriminatedUnionVariant<TUnion, TDiscriminatorProperty, TDiscriminatorValue>, TDiscriminatorProperty>;\n\n/**\n * Defines the configuration for discriminated union codecs.\n *\n * This configuration controls how the discriminator is stored and named.\n *\n * @typeParam TDiscriminatorProperty - The property name of the discriminator.\n * @typeParam TDiscriminatorSize - The codec used for the discriminator prefix.\n */\nexport type DiscriminatedUnionCodecConfig<\n    TDiscriminatorProperty extends string = '__kind',\n    TDiscriminatorSize = NumberCodec | NumberDecoder | NumberEncoder,\n> = {\n    /**\n     * The property name of the discriminator.\n     * @defaultValue `__kind`\n     */\n    discriminator?: TDiscriminatorProperty;\n    /**\n     * The codec used to encode/decode the discriminator prefix.\n     * @defaultValue `u8` prefix\n     */\n    size?: TDiscriminatorSize;\n};\n\ntype DiscriminatorValue = bigint | boolean | number | string | null | undefined;\ntype Variants<T> = readonly (readonly [DiscriminatorValue, T])[];\ntype ArrayIndices<T extends readonly unknown[]> = Exclude<Partial<T>['length'], T['length']> & number;\n\ntype GetEncoderTypeFromVariants<\n    TVariants extends Variants<Encoder<any>>,\n    TDiscriminatorProperty extends string,\n> = DrainOuterGeneric<{\n    [I in ArrayIndices<TVariants>]: (TVariants[I][1] extends Encoder<infer TFrom>\n        ? TFrom extends object\n            ? TFrom\n            : object\n        : never) & { [P in TDiscriminatorProperty]: TVariants[I][0] };\n}>[ArrayIndices<TVariants>];\n\ntype GetDecoderTypeFromVariants<\n    TVariants extends Variants<Decoder<any>>,\n    TDiscriminatorProperty extends string,\n> = DrainOuterGeneric<{\n    [I in ArrayIndices<TVariants>]: (TVariants[I][1] extends Decoder<infer TTo>\n        ? TTo extends object\n            ? TTo\n            : object\n        : never) & { [P in TDiscriminatorProperty]: TVariants[I][0] };\n}>[ArrayIndices<TVariants>];\n\ntype UnionEncoder<TVariants extends Variants<Encoder<unknown>>, TDiscriminatorProperty extends string> =\n    TVariants extends Variants<FixedSizeEncoder<any>>\n        ? FixedSizeEncoder<GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>>\n        : Encoder<GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>>;\n\ntype UnionDecoder<TVariants extends Variants<Decoder<unknown>>, TDiscriminatorProperty extends string> =\n    TVariants extends Variants<FixedSizeDecoder<any>>\n        ? FixedSizeDecoder<GetDecoderTypeFromVariants<TVariants, TDiscriminatorProperty>>\n        : Decoder<GetDecoderTypeFromVariants<TVariants, TDiscriminatorProperty>>;\n\ntype UnionCodec<TVariants extends Variants<Codec<unknown, unknown>>, TDiscriminatorProperty extends string> =\n    TVariants extends Variants<FixedSizeCodec<any, any>>\n        ? FixedSizeCodec<\n              GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>,\n              GetDecoderTypeFromVariants<TVariants, TDiscriminatorProperty> &\n                  GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>\n          >\n        : Codec<\n              GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>,\n              GetDecoderTypeFromVariants<TVariants, TDiscriminatorProperty> &\n                  GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>\n          >;\n\n/**\n * Returns an encoder for discriminated unions.\n *\n * This encoder serializes objects that follow the discriminated union pattern\n * by prefixing them with a numerical discriminator that represents their variant.\n *\n * Unlike {@link getUnionEncoder}, this encoder automatically extracts and processes\n * the discriminator property (default: `__kind`) from each variant.\n *\n * For more details, see {@link getDiscriminatedUnionCodec}.\n *\n * @typeParam TVariants - The variants of the discriminated union.\n * @typeParam TDiscriminatorProperty - The property used as the discriminator.\n *\n * @param variants - The variant encoders as `[discriminator, encoder]` pairs.\n * @param config - Configuration options for encoding.\n * @returns An `Encoder` for encoding discriminated union objects.\n *\n * @example\n * Encoding a discriminated union.\n * ```ts\n * type Message =\n *   | { __kind: 'Quit' } // Empty variant.\n *   | { __kind: 'Write'; fields: [string] } // Tuple variant.\n *   | { __kind: 'Move'; x: number; y: number }; // Struct variant.\n *\n * const messageEncoder = getDiscriminatedUnionEncoder([\n *   ['Quit', getUnitEncoder()],\n *   ['Write', getStructEncoder([['fields', getTupleEncoder([addCodecSizePrefix(getUtf8Encoder(), getU32Encoder())])]])],\n *   ['Move', getStructEncoder([['x', getI32Encoder()], ['y', getI32Encoder()]])]\n * ]);\n *\n * messageEncoder.encode({ __kind: 'Move', x: 5, y: 6 });\n * // 0x020500000006000000\n * //   | |       └── Field y (6)\n * //   | └── Field x (5)\n * //   └── 1-byte discriminator (Index 2 — the \"Move\" variant)\n * ```\n *\n * @see {@link getDiscriminatedUnionCodec}\n */\nexport function getDiscriminatedUnionEncoder<\n    const TVariants extends Variants<Encoder<any>>,\n    const TDiscriminatorProperty extends string = '__kind',\n>(\n    variants: TVariants,\n    config: DiscriminatedUnionCodecConfig<TDiscriminatorProperty, NumberEncoder> = {},\n): UnionEncoder<TVariants, TDiscriminatorProperty> {\n    type TFrom = GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>;\n    const discriminatorProperty = (config.discriminator ?? '__kind') as TDiscriminatorProperty;\n    const prefix = config.size ?? getU8Encoder();\n    return getUnionEncoder(\n        variants.map(([, variant], index) =>\n            transformEncoder(getTupleEncoder([prefix, variant]), (value: TFrom): [number, TFrom] => [index, value]),\n        ),\n        value => getVariantDiscriminator(variants, value[discriminatorProperty]),\n    ) as UnionEncoder<TVariants, TDiscriminatorProperty>;\n}\n\n/**\n * Returns a decoder for discriminated unions.\n *\n * This decoder deserializes objects that follow the discriminated union pattern\n * by **reading a numerical discriminator** and mapping it to the corresponding variant.\n *\n * Unlike {@link getUnionDecoder}, this decoder automatically inserts the discriminator\n * property (default: `__kind`) into the decoded object.\n *\n * For more details, see {@link getDiscriminatedUnionCodec}.\n *\n * @typeParam TVariants - The variants of the discriminated union.\n * @typeParam TDiscriminatorProperty - The property used as the discriminator.\n *\n * @param variants - The variant decoders as `[discriminator, decoder]` pairs.\n * @param config - Configuration options for decoding.\n * @returns A `Decoder` for decoding discriminated union objects.\n *\n * @example\n * Decoding a discriminated union.\n * ```ts\n * type Message =\n *   | { __kind: 'Quit' } // Empty variant.\n *   | { __kind: 'Write'; fields: [string] } // Tuple variant.\n *   | { __kind: 'Move'; x: number; y: number }; // Struct variant.\n *\n * const messageDecoder = getDiscriminatedUnionDecoder([\n *   ['Quit', getUnitDecoder()],\n *   ['Write', getStructDecoder([['fields', getTupleDecoder([addCodecSizePrefix(getUtf8Decoder(), getU32Decoder())])]])],\n *   ['Move', getStructDecoder([['x', getI32Decoder()], ['y', getI32Decoder()]])]\n * ]);\n *\n * messageDecoder.decode(new Uint8Array([0x02,0x05,0x00,0x00,0x00,0x06,0x00,0x00,0x00]));\n * // { __kind: 'Move', x: 5, y: 6 }\n * ```\n *\n * @see {@link getDiscriminatedUnionCodec}\n */\nexport function getDiscriminatedUnionDecoder<\n    const TVariants extends Variants<Decoder<any>>,\n    const TDiscriminatorProperty extends string = '__kind',\n>(\n    variants: TVariants,\n    config: DiscriminatedUnionCodecConfig<TDiscriminatorProperty, NumberDecoder> = {},\n): UnionDecoder<TVariants, TDiscriminatorProperty> {\n    const discriminatorProperty = config.discriminator ?? '__kind';\n    const prefix = config.size ?? getU8Decoder();\n    return getUnionDecoder(\n        variants.map(([discriminator, variant]) =>\n            transformDecoder(getTupleDecoder([prefix, variant]), ([, value]) => ({\n                [discriminatorProperty]: discriminator,\n                ...value,\n            })),\n        ),\n        (bytes, offset) => Number(prefix.read(bytes, offset)[0]),\n    ) as UnionDecoder<TVariants, TDiscriminatorProperty>;\n}\n\n/**\n * Returns a codec for encoding and decoding {@link DiscriminatedUnion}.\n *\n * A {@link DiscriminatedUnion} is a TypeScript representation of Rust-like enums, where\n * each variant is distinguished by a discriminator field (default: `__kind`).\n *\n * This codec inserts a numerical prefix to represent the variant index.\n *\n * @typeParam TVariants - The variants of the discriminated union.\n * @typeParam TDiscriminatorProperty - The property used as the discriminator.\n *\n * @param variants - The variant codecs as `[discriminator, codec]` pairs.\n * @param config - Configuration options for encoding/decoding.\n * @returns A `Codec` for encoding and decoding discriminated union objects.\n *\n * @example\n * Encoding and decoding a discriminated union.\n * ```ts\n * type Message =\n *   | { __kind: 'Quit' } // Empty variant.\n *   | { __kind: 'Write'; fields: [string] } // Tuple variant.\n *   | { __kind: 'Move'; x: number; y: number }; // Struct variant.\n *\n * const messageCodec = getDiscriminatedUnionCodec([\n *   ['Quit', getUnitCodec()],\n *   ['Write', getStructCodec([['fields', getTupleCodec([addCodecSizePrefix(getUtf8Codec(), getU32Codec())])]])],\n *   ['Move', getStructCodec([['x', getI32Codec()], ['y', getI32Codec()]])]\n * ]);\n *\n * messageCodec.encode({ __kind: 'Move', x: 5, y: 6 });\n * // 0x020500000006000000\n * //   | |       └── Field y (6)\n * //   | └── Field x (5)\n * //   └── 1-byte discriminator (Index 2 — the \"Move\" variant)\n *\n * const value = messageCodec.decode(bytes);\n * // { __kind: 'Move', x: 5, y: 6 }\n * ```\n *\n * @example\n * Using a `u32` discriminator instead of `u8`.\n * ```ts\n * const codec = getDiscriminatedUnionCodec([...], { size: getU32Codec() });\n *\n * codec.encode({ __kind: 'Quit' });\n * // 0x00000000\n * //   └------┘ 4-byte discriminator (Index 0)\n *\n * codec.decode(new Uint8Array([0x00, 0x00, 0x00, 0x00]));\n * // { __kind: 'Quit' }\n * ```\n *\n * @example\n * Customizing the discriminator property.\n * ```ts\n * const codec = getDiscriminatedUnionCodec([...], { discriminator: 'message' });\n *\n * codec.encode({ message: 'Quit' }); // 0x00\n * codec.decode(new Uint8Array([0x00])); // { message: 'Quit' }\n * ```\n *\n * @remarks\n * Separate `getDiscriminatedUnionEncoder` and `getDiscriminatedUnionDecoder` functions are available.\n *\n * ```ts\n * const bytes = getDiscriminatedUnionEncoder(variantEncoders).encode({ __kind: 'Quit' });\n * const message = getDiscriminatedUnionDecoder(variantDecoders).decode(bytes);\n * ```\n *\n * @see {@link getDiscriminatedUnionEncoder}\n * @see {@link getDiscriminatedUnionDecoder}\n */\nexport function getDiscriminatedUnionCodec<\n    const TVariants extends Variants<Codec<any, any>>,\n    const TDiscriminatorProperty extends string = '__kind',\n>(\n    variants: TVariants,\n    config: DiscriminatedUnionCodecConfig<TDiscriminatorProperty, NumberCodec> = {},\n): UnionCodec<TVariants, TDiscriminatorProperty> {\n    return combineCodec(\n        getDiscriminatedUnionEncoder(variants, config) as Encoder<\n            GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>\n        >,\n        getDiscriminatedUnionDecoder(variants, config) as Decoder<\n            GetDecoderTypeFromVariants<TVariants, TDiscriminatorProperty> &\n                GetEncoderTypeFromVariants<TVariants, TDiscriminatorProperty>\n        >,\n    ) as UnionCodec<TVariants, TDiscriminatorProperty>;\n}\n\nfunction getVariantDiscriminator<const TVariants extends Variants<Decoder<any> | Encoder<any>>>(\n    variants: TVariants,\n    discriminatorValue: DiscriminatorValue,\n) {\n    const discriminator = variants.findIndex(([key]) => discriminatorValue === key);\n    if (discriminator < 0) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT, {\n            value: discriminatorValue,\n            variants: variants.map(([key]) => key),\n        });\n    }\n    return discriminator;\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/enum-helpers.ts",
    "content": "/**\n * Defines the \"lookup object\" of an enum.\n *\n * @example\n * ```ts\n * enum Direction { Left, Right };\n * ```\n */\nexport type EnumLookupObject = { [key: string]: number | string };\n\n/**\n * Returns the allowed input for an enum.\n *\n * @example\n * ```ts\n * enum Direction { Left, Right };\n * type DirectionInput = GetEnumFrom<Direction>; // \"Left\" | \"Right\" | 0 | 1\n * ```\n */\nexport type GetEnumFrom<TEnum extends EnumLookupObject> = TEnum[keyof TEnum] | keyof TEnum;\n\n/**\n * Returns all the available variants of an enum.\n *\n * @example\n * ```ts\n * enum Direction { Left, Right };\n * type DirectionOutput = GetEnumTo<Direction>; // 0 | 1\n * ```\n */\nexport type GetEnumTo<TEnum extends EnumLookupObject> = TEnum[keyof TEnum];\n\nexport function getEnumStats(constructor: EnumLookupObject) {\n    const numericalValues = [...new Set(Object.values(constructor).filter(v => typeof v === 'number'))].sort();\n    const enumRecord = Object.fromEntries(Object.entries(constructor).slice(numericalValues.length)) as Record<\n        string,\n        number | string\n    >;\n    const enumKeys = Object.keys(enumRecord);\n    const enumValues = Object.values(enumRecord);\n    const stringValues: string[] = [\n        ...new Set([...enumKeys, ...enumValues.filter((v): v is string => typeof v === 'string')]),\n    ];\n\n    return { enumKeys, enumRecord, enumValues, numericalValues, stringValues };\n}\n\nexport function getEnumIndexFromVariant({\n    enumKeys,\n    enumValues,\n    variant,\n}: {\n    enumKeys: string[];\n    enumValues: (number | string)[];\n    variant: number | string | symbol;\n}): number {\n    const valueIndex = findLastIndex(enumValues, value => value === variant);\n    if (valueIndex >= 0) return valueIndex;\n    return enumKeys.findIndex(key => key === variant);\n}\n\nexport function getEnumIndexFromDiscriminator({\n    discriminator,\n    enumKeys,\n    enumValues,\n    useValuesAsDiscriminators,\n}: {\n    discriminator: number;\n    enumKeys: string[];\n    enumValues: (number | string)[];\n    useValuesAsDiscriminators: boolean;\n}): number {\n    if (!useValuesAsDiscriminators) {\n        return discriminator >= 0 && discriminator < enumKeys.length ? discriminator : -1;\n    }\n    return findLastIndex(enumValues, value => value === discriminator);\n}\n\nfunction findLastIndex<T>(array: Array<T>, predicate: (value: T, index: number, obj: T[]) => boolean): number {\n    let l = array.length;\n    while (l--) {\n        if (predicate(array[l], l, array)) return l;\n    }\n    return -1;\n}\n\nexport function formatNumericalValues(values: number[]): string {\n    if (values.length === 0) return '';\n    let range: [number, number] = [values[0], values[0]];\n    const ranges: string[] = [];\n    for (let index = 1; index < values.length; index++) {\n        const value = values[index];\n        if (range[1] + 1 === value) {\n            range[1] = value;\n        } else {\n            ranges.push(range[0] === range[1] ? `${range[0]}` : `${range[0]}-${range[1]}`);\n            range = [value, value];\n        }\n    }\n    ranges.push(range[0] === range[1] ? `${range[0]}` : `${range[0]}-${range[1]}`);\n    return ranges.join(', ');\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/enum.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    FixedSizeNumberCodec,\n    FixedSizeNumberDecoder,\n    FixedSizeNumberEncoder,\n    getU8Decoder,\n    getU8Encoder,\n    NumberCodec,\n    NumberDecoder,\n    NumberEncoder,\n} from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS,\n    SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    EnumLookupObject,\n    formatNumericalValues,\n    GetEnumFrom,\n    getEnumIndexFromDiscriminator,\n    getEnumIndexFromVariant,\n    getEnumStats,\n    GetEnumTo,\n} from './enum-helpers';\n\n/**\n * Defines the configuration options for enum codecs.\n *\n * The `size` option determines the numerical encoding used for the enum's discriminant.\n * By default, enums are stored as a `u8` (1 byte).\n *\n * The `useValuesAsDiscriminators` option allows mapping the actual enum values\n * as discriminators instead of using their positional index.\n *\n * @typeParam TDiscriminator - A number codec, encoder, or decoder used for the discriminant.\n */\nexport type EnumCodecConfig<TDiscriminator extends NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * The codec used to encode/decode the enum discriminator.\n     * @defaultValue `u8` discriminator.\n     */\n    size?: TDiscriminator;\n\n    /**\n     * If set to `true`, the enum values themselves will be used as discriminators.\n     * This is only valid for numerical enum values.\n     *\n     * @defaultValue `false`\n     */\n    useValuesAsDiscriminators?: boolean;\n};\n\n/**\n * Returns an encoder for enums.\n *\n * This encoder serializes enums as a numerical discriminator.\n * By default, the discriminator is based on the positional index of the enum variants.\n *\n * For more details, see {@link getEnumCodec}.\n *\n * @typeParam TEnum - The TypeScript enum or object mapping enum keys to values.\n *\n * @param constructor - The constructor of the enum.\n * @param config - Configuration options for encoding the enum.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding enums.\n *\n * @example\n * Encoding enum values.\n * ```ts\n * enum Direction { Up,  Down, Left, Right }\n * const encoder = getEnumEncoder(Direction);\n *\n * encoder.encode(Direction.Up);    // 0x00\n * encoder.encode(Direction.Down);  // 0x01\n * encoder.encode(Direction.Left);  // 0x02\n * encoder.encode(Direction.Right); // 0x03\n * ```\n *\n * @see {@link getEnumCodec}\n */\nexport function getEnumEncoder<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config?: Omit<EnumCodecConfig<NumberEncoder>, 'size'>,\n): FixedSizeEncoder<GetEnumFrom<TEnum>, 1>;\nexport function getEnumEncoder<TEnum extends EnumLookupObject, TSize extends number>(\n    constructor: TEnum,\n    config: EnumCodecConfig<NumberEncoder> & { size: FixedSizeNumberEncoder<TSize> },\n): FixedSizeEncoder<GetEnumFrom<TEnum>, TSize>;\nexport function getEnumEncoder<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config?: EnumCodecConfig<NumberEncoder>,\n): VariableSizeEncoder<GetEnumFrom<TEnum>>;\nexport function getEnumEncoder<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config: EnumCodecConfig<NumberEncoder> = {},\n): Encoder<GetEnumFrom<TEnum>> {\n    const prefix = config.size ?? getU8Encoder();\n    const useValuesAsDiscriminators = config.useValuesAsDiscriminators ?? false;\n    const { enumKeys, enumValues, numericalValues, stringValues } = getEnumStats(constructor);\n    if (useValuesAsDiscriminators && enumValues.some(value => typeof value === 'string')) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS, {\n            stringValues: enumValues.filter((v): v is string => typeof v === 'string'),\n        });\n    }\n    return transformEncoder(prefix, (variant: GetEnumFrom<TEnum>): number => {\n        const index = getEnumIndexFromVariant({ enumKeys, enumValues, variant });\n        if (index < 0) {\n            throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT, {\n                formattedNumericalValues: formatNumericalValues(numericalValues),\n                numericalValues,\n                stringValues,\n                variant,\n            });\n        }\n        return useValuesAsDiscriminators ? (enumValues[index] as number) : index;\n    });\n}\n\n/**\n * Returns a decoder for enums.\n *\n * This decoder deserializes enums from a numerical discriminator.\n * By default, the discriminator is based on the positional index of the enum variants.\n *\n * For more details, see {@link getEnumCodec}.\n *\n * @typeParam TEnum - The TypeScript enum or object mapping enum keys to values.\n *\n * @param constructor - The constructor of the enum.\n * @param config - Configuration options for decoding the enum.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding enums.\n *\n * @example\n * Decoding enum values.\n * ```ts\n * enum Direction { Up,  Down, Left, Right }\n * const decoder = getEnumDecoder(Direction);\n *\n * decoder.decode(new Uint8Array([0x00])); // Direction.Up\n * decoder.decode(new Uint8Array([0x01])); // Direction.Down\n * decoder.decode(new Uint8Array([0x02])); // Direction.Left\n * decoder.decode(new Uint8Array([0x03])); // Direction.Right\n * ```\n *\n * @see {@link getEnumCodec}\n */\nexport function getEnumDecoder<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config?: Omit<EnumCodecConfig<NumberDecoder>, 'size'>,\n): FixedSizeDecoder<GetEnumTo<TEnum>, 1>;\nexport function getEnumDecoder<TEnum extends EnumLookupObject, TSize extends number>(\n    constructor: TEnum,\n    config: EnumCodecConfig<NumberDecoder> & { size: FixedSizeNumberDecoder<TSize> },\n): FixedSizeDecoder<GetEnumTo<TEnum>, TSize>;\nexport function getEnumDecoder<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config?: EnumCodecConfig<NumberDecoder>,\n): VariableSizeDecoder<GetEnumTo<TEnum>>;\nexport function getEnumDecoder<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config: EnumCodecConfig<NumberDecoder> = {},\n): Decoder<GetEnumTo<TEnum>> {\n    const prefix = config.size ?? getU8Decoder();\n    const useValuesAsDiscriminators = config.useValuesAsDiscriminators ?? false;\n    const { enumKeys, enumValues, numericalValues } = getEnumStats(constructor);\n    if (useValuesAsDiscriminators && enumValues.some(value => typeof value === 'string')) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS, {\n            stringValues: enumValues.filter((v): v is string => typeof v === 'string'),\n        });\n    }\n    return transformDecoder(prefix, (value: bigint | number): GetEnumTo<TEnum> => {\n        const discriminator = Number(value);\n        const index = getEnumIndexFromDiscriminator({\n            discriminator,\n            enumKeys,\n            enumValues,\n            useValuesAsDiscriminators,\n        });\n        if (index < 0) {\n            const validDiscriminators = useValuesAsDiscriminators\n                ? numericalValues\n                : [...Array(enumKeys.length).keys()];\n            throw new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                discriminator,\n                formattedValidDiscriminators: formatNumericalValues(validDiscriminators),\n                validDiscriminators,\n            });\n        }\n        return enumValues[index] as GetEnumTo<TEnum>;\n    });\n}\n\n/**\n * Returns a codec for encoding and decoding enums.\n *\n * This codec serializes enums as a numerical discriminator, allowing them\n * to be efficiently stored and reconstructed from binary data.\n *\n * By default, the discriminator is derived from the positional index\n * of the enum variant, but it can be configured to use the enum's numeric values instead.\n *\n * @typeParam TEnum - The TypeScript enum or object mapping enum keys to values.\n *\n * @param constructor - The constructor of the enum.\n * @param config - Configuration options for encoding and decoding the enum.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding enums.\n *\n * @example\n * Encoding and decoding enums using positional indexes.\n * ```ts\n * enum Direction { Up, Down, Left, Right }\n * const codec = getEnumCodec(Direction);\n *\n * codec.encode(Direction.Up);    // 0x00\n * codec.encode(Direction.Down);  // 0x01\n * codec.encode(Direction.Left);  // 0x02\n * codec.encode(Direction.Right); // 0x03\n *\n * codec.decode(new Uint8Array([0x00])); // Direction.Up\n * codec.decode(new Uint8Array([0x01])); // Direction.Down\n * codec.decode(new Uint8Array([0x02])); // Direction.Left\n * codec.decode(new Uint8Array([0x03])); // Direction.Right\n * ```\n *\n * @example\n * Encoding and decoding enums using their numeric values.\n * ```ts\n * enum GameDifficulty { Easy = 1, Normal = 4, Hard = 7, Expert = 9 }\n * const codec = getEnumCodec(GameDifficulty, { useValuesAsDiscriminators: true });\n *\n * codec.encode(GameDifficulty.Easy);   // 0x01\n * codec.encode(GameDifficulty.Normal); // 0x04\n * codec.encode(GameDifficulty.Hard);   // 0x07\n * codec.encode(GameDifficulty.Expert); // 0x09\n *\n * codec.decode(new Uint8Array([0x01])); // GameDifficulty.Easy\n * codec.decode(new Uint8Array([0x04])); // GameDifficulty.Normal\n * codec.decode(new Uint8Array([0x07])); // GameDifficulty.Hard\n * codec.decode(new Uint8Array([0x09])); // GameDifficulty.Expert\n * ```\n *\n * Note that, when using values as discriminators, the enum values must be numerical.\n * Otherwise, an error will be thrown.\n *\n * ```ts\n * enum GameDifficulty { Easy = 'EASY', Normal = 'NORMAL', Hard = 'HARD' }\n * getEnumCodec(GameDifficulty, { useValuesAsDiscriminators: true }); // Throws an error.\n * ```\n *\n * @example\n * Using a custom discriminator size.\n * ```ts\n * enum Status { Pending, Approved, Rejected }\n * const codec = getEnumCodec(Status, { size: getU16Codec() });\n *\n * codec.encode(Status.Pending);  // 0x0000\n * codec.encode(Status.Approved); // 0x0100\n * codec.encode(Status.Rejected); // 0x0200\n *\n * codec.decode(new Uint8Array([0x00, 0x00])); // Status.Pending\n * codec.decode(new Uint8Array([0x01, 0x00])); // Status.Approved\n * codec.decode(new Uint8Array([0x02, 0x00])); // Status.Rejected\n * ```\n *\n * @remarks\n * Separate {@link getEnumEncoder} and {@link getEnumDecoder} functions are available.\n *\n * ```ts\n * const bytes = getEnumEncoder(Direction).encode(Direction.Up);\n * const value = getEnumDecoder(Direction).decode(bytes);\n * ```\n *\n * @see {@link getEnumEncoder}\n * @see {@link getEnumDecoder}\n */\nexport function getEnumCodec<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config?: Omit<EnumCodecConfig<NumberCodec>, 'size'>,\n): FixedSizeCodec<GetEnumFrom<TEnum>, GetEnumTo<TEnum>, 1>;\nexport function getEnumCodec<TEnum extends EnumLookupObject, TSize extends number>(\n    constructor: TEnum,\n    config: EnumCodecConfig<NumberCodec> & { size: FixedSizeNumberCodec<TSize> },\n): FixedSizeCodec<GetEnumFrom<TEnum>, GetEnumTo<TEnum>, TSize>;\nexport function getEnumCodec<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config?: EnumCodecConfig<NumberCodec>,\n): VariableSizeCodec<GetEnumFrom<TEnum>, GetEnumTo<TEnum>>;\nexport function getEnumCodec<TEnum extends EnumLookupObject>(\n    constructor: TEnum,\n    config: EnumCodecConfig<NumberCodec> = {},\n): Codec<GetEnumFrom<TEnum>, GetEnumTo<TEnum>> {\n    return combineCodec(getEnumEncoder(constructor, config), getEnumDecoder(constructor, config));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/hidden-prefix.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getTupleDecoder, getTupleEncoder } from './tuple';\n\n/**\n * Returns an encoder that prefixes encoded values with hidden data.\n *\n * This encoder applies a list of void encoders before encoding the main value.\n * The prefixed data is encoded before the main value without being exposed to the user.\n *\n * For more details, see {@link getHiddenPrefixCodec}.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n *\n * @param encoder - The encoder for the main value.\n * @param prefixedEncoders - A list of void encoders that produce the hidden prefix.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` that encodes the value with a hidden prefix.\n *\n * @example\n * Prefixing a value with constants.\n * ```ts\n * const encoder = getHiddenPrefixEncoder(getUtf8Encoder(), [\n *   getConstantCodec(new Uint8Array([1, 2, 3])),\n *   getConstantCodec(new Uint8Array([4, 5, 6])),\n * ]);\n *\n * encoder.encode('Hello');\n * // 0x01020304050648656c6c6f\n * //   |     |     └-- Our encoded value (\"Hello\").\n * //   |     └-- Our second hidden prefix.\n * //   └-- Our first hidden prefix.\n * ```\n *\n * @see {@link getHiddenPrefixCodec}\n */\nexport function getHiddenPrefixEncoder<TFrom>(\n    encoder: FixedSizeEncoder<TFrom>,\n    prefixedEncoders: readonly FixedSizeEncoder<void>[],\n): FixedSizeEncoder<TFrom>;\nexport function getHiddenPrefixEncoder<TFrom>(\n    encoder: Encoder<TFrom>,\n    prefixedEncoders: readonly Encoder<void>[],\n): VariableSizeEncoder<TFrom>;\nexport function getHiddenPrefixEncoder<TFrom>(\n    encoder: Encoder<TFrom>,\n    prefixedEncoders: readonly Encoder<void>[],\n): Encoder<TFrom> {\n    return transformEncoder(\n        getTupleEncoder([...prefixedEncoders, encoder]) as Encoder<readonly [...void[], TFrom]>,\n        (value: TFrom) => [...prefixedEncoders.map(() => undefined), value] as const,\n    );\n}\n\n/**\n * Returns a decoder that skips hidden prefixed data before decoding the main value.\n *\n * This decoder applies a list of void decoders before decoding the main value.\n * The prefixed data is skipped during decoding without being exposed to the user.\n *\n * For more details, see {@link getHiddenPrefixCodec}.\n *\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param decoder - The decoder for the main value.\n * @param prefixedDecoders - A list of void decoders that produce the hidden prefix.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` that decodes values while ignoring the hidden prefix.\n *\n * @example\n * Decoding a value with prefixed constants.\n * ```ts\n * const decoder = getHiddenPrefixDecoder(getUtf8Decoder(), [\n *   getConstantCodec(new Uint8Array([1, 2, 3])),\n *   getConstantCodec(new Uint8Array([4, 5, 6])),\n * ]);\n *\n * decoder.decode(new Uint8Array([1, 2, 3, 4, 5, 6, 0x48, 0x65, 0x6C, 0x6C, 0x6F]));\n * // 'Hello'\n * ```\n *\n * @see {@link getHiddenPrefixCodec}\n */\nexport function getHiddenPrefixDecoder<TTo>(\n    decoder: FixedSizeDecoder<TTo>,\n    prefixedDecoders: readonly FixedSizeDecoder<void>[],\n): FixedSizeDecoder<TTo>;\nexport function getHiddenPrefixDecoder<TTo>(\n    decoder: Decoder<TTo>,\n    prefixedDecoders: readonly Decoder<void>[],\n): VariableSizeDecoder<TTo>;\nexport function getHiddenPrefixDecoder<TTo>(\n    decoder: Decoder<TTo>,\n    prefixedDecoders: readonly Decoder<void>[],\n): Decoder<TTo> {\n    return transformDecoder(\n        getTupleDecoder([...prefixedDecoders, decoder]) as Decoder<readonly [...void[], TTo]>,\n        tuple => tuple[tuple.length - 1] as TTo,\n    );\n}\n\n/**\n * Returns a codec that encodes and decodes values with a hidden prefix.\n *\n * - **Encoding:** Prefixes the value with hidden data before encoding.\n * - **Decoding:** Skips the hidden prefix before decoding the main value.\n *\n * This is useful for any implicit metadata that should be present in\n * binary formats but omitted from the API.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param codec - The codec for the main value.\n * @param prefixedCodecs - A list of void codecs that produce the hidden prefix.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding values with a hidden prefix.\n *\n * @example\n * Encoding and decoding a value with prefixed constants.\n * ```ts\n * const codec = getHiddenPrefixCodec(getUtf8Codec(), [\n *   getConstantCodec(new Uint8Array([1, 2, 3])),\n *   getConstantCodec(new Uint8Array([4, 5, 6])),\n * ]);\n *\n * const bytes = codec.encode('Hello');\n * // 0x01020304050648656c6c6f\n * //   |     |     └-- Our encoded value (\"Hello\").\n * //   |     └-- Our second hidden prefix.\n * //   └-- Our first hidden prefix.\n *\n * codec.decode(bytes);\n * // 'Hello'\n * ```\n *\n * @remarks\n * If all you need is padding zeroes before a value, consider using {@link padLeftCodec} instead.\n *\n * Separate {@link getHiddenPrefixEncoder} and {@link getHiddenPrefixDecoder} functions are available.\n *\n * ```ts\n * const bytes = getHiddenPrefixEncoder(getUtf8Encoder(), [\n *   getConstantEncoder(new Uint8Array([1, 2, 3])),\n *   getConstantEncoder(new Uint8Array([4, 5, 6])),\n * ]).encode('Hello');\n *\n * const value = getHiddenPrefixDecoder(getUtf8Decoder(), [\n *   getConstantDecoder(new Uint8Array([1, 2, 3])),\n *   getConstantDecoder(new Uint8Array([4, 5, 6])),\n * ]).decode(bytes);\n * ```\n *\n * @see {@link getHiddenPrefixEncoder}\n * @see {@link getHiddenPrefixDecoder}\n */\nexport function getHiddenPrefixCodec<TFrom, TTo extends TFrom>(\n    codec: FixedSizeCodec<TFrom, TTo>,\n    prefixedCodecs: readonly FixedSizeCodec<void>[],\n): FixedSizeCodec<TFrom, TTo>;\nexport function getHiddenPrefixCodec<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n    prefixedCodecs: readonly Codec<void>[],\n): VariableSizeCodec<TFrom, TTo>;\nexport function getHiddenPrefixCodec<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n    prefixedCodecs: readonly Codec<void>[],\n): Codec<TFrom, TTo> {\n    return combineCodec(getHiddenPrefixEncoder(codec, prefixedCodecs), getHiddenPrefixDecoder(codec, prefixedCodecs));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/hidden-suffix.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getTupleDecoder, getTupleEncoder } from './tuple';\n\n/**\n * Returns an encoder that appends hidden data after the encoded value.\n *\n * This encoder applies a list of void encoders after encoding the main value.\n * The suffixed data is encoded after the main value without being exposed to the user.\n *\n * For more details, see {@link getHiddenSuffixCodec}.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n *\n * @param encoder - The encoder for the main value.\n * @param suffixedEncoders - A list of void encoders that produce the hidden suffix.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` that encodes the value with a hidden suffix.\n *\n * @example\n * Suffixing a value with constants.\n * ```ts\n * const encoder = getHiddenSuffixEncoder(getUtf8Encoder(), [\n *   getConstantCodec(new Uint8Array([1, 2, 3])),\n *   getConstantCodec(new Uint8Array([4, 5, 6])),\n * ]);\n *\n * encoder.encode('Hello');\n * // 0x48656c6c6f010203040506\n * //   |         |     └-- Our second hidden suffix.\n * //   |         └-- Our first hidden suffix.\n * //   └-- Our encoded value (\"Hello\").\n * ```\n *\n * @see {@link getHiddenSuffixCodec}\n */\nexport function getHiddenSuffixEncoder<TFrom>(\n    encoder: FixedSizeEncoder<TFrom>,\n    suffixedEncoders: readonly FixedSizeEncoder<void>[],\n): FixedSizeEncoder<TFrom>;\nexport function getHiddenSuffixEncoder<TFrom>(\n    encoder: Encoder<TFrom>,\n    suffixedEncoders: readonly Encoder<void>[],\n): VariableSizeEncoder<TFrom>;\nexport function getHiddenSuffixEncoder<TFrom>(\n    encoder: Encoder<TFrom>,\n    suffixedEncoders: readonly Encoder<void>[],\n): Encoder<TFrom> {\n    return transformEncoder(\n        getTupleEncoder([encoder, ...suffixedEncoders]) as Encoder<readonly [TFrom, ...void[]]>,\n        (value: TFrom) => [value, ...suffixedEncoders.map(() => undefined)] as const,\n    );\n}\n\n/**\n * Returns a decoder that skips hidden suffixed data after decoding the main value.\n *\n * This decoder applies a list of void decoders after decoding the main value.\n * The suffixed data is skipped during decoding without being exposed to the user.\n *\n * For more details, see {@link getHiddenSuffixCodec}.\n *\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param decoder - The decoder for the main value.\n * @param suffixedDecoders - A list of void decoders that produce the hidden suffix.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` that decodes values while ignoring the hidden suffix.\n *\n * @example\n * Decoding a value with suffixed constants.\n * ```ts\n * const decoder = getHiddenSuffixDecoder(getUtf8Decoder(), [\n *   getConstantCodec(new Uint8Array([1, 2, 3])),\n *   getConstantCodec(new Uint8Array([4, 5, 6])),\n * ]);\n *\n * decoder.decode(new Uint8Array([0x48, 0x65, 0x6C, 0x6C, 0x6F, 1, 2, 3, 4, 5, 6]));\n * // 'Hello'\n * ```\n *\n * @see {@link getHiddenSuffixCodec}\n */\nexport function getHiddenSuffixDecoder<TTo>(\n    decoder: FixedSizeDecoder<TTo>,\n    suffixedDecoders: readonly FixedSizeDecoder<void>[],\n): FixedSizeDecoder<TTo>;\nexport function getHiddenSuffixDecoder<TTo>(\n    decoder: Decoder<TTo>,\n    suffixedDecoders: readonly Decoder<void>[],\n): VariableSizeDecoder<TTo>;\nexport function getHiddenSuffixDecoder<TTo>(\n    decoder: Decoder<TTo>,\n    suffixedDecoders: readonly Decoder<void>[],\n): Decoder<TTo> {\n    return transformDecoder(\n        getTupleDecoder([decoder, ...suffixedDecoders]) as Decoder<readonly [TTo, ...void[]]>,\n        tuple => tuple[0],\n    );\n}\n\n/**\n * Returns a codec that encodes and decodes values with a hidden suffix.\n *\n * - **Encoding:** Appends hidden data after encoding the main value.\n * - **Decoding:** Skips the hidden suffix after decoding the main value.\n *\n * This is useful for any implicit metadata that should be present in\n * binary formats but omitted from the API.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param codec - The codec for the main value.\n * @param suffixedCodecs - A list of void codecs that produce the hidden suffix.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding values with a hidden suffix.\n *\n * @example\n * Encoding and decoding a value with suffixed constants.\n * ```ts\n * const codec = getHiddenSuffixCodec(getUtf8Codec(), [\n *   getConstantCodec(new Uint8Array([1, 2, 3])),\n *   getConstantCodec(new Uint8Array([4, 5, 6])),\n * ]);\n *\n * const bytes = codec.encode('Hello');\n * // 0x48656c6c6f010203040506\n * //   |         |     └-- Our second hidden suffix.\n * //   |         └-- Our first hidden suffix.\n * //   └-- Our encoded value (\"Hello\").\n *\n * codec.decode(bytes);\n * // 'Hello'\n * ```\n *\n * @remarks\n * If all you need is padding zeroes after a value, consider using {@link padRightCodec} instead.\n *\n * Separate {@link getHiddenSuffixEncoder} and {@link getHiddenSuffixDecoder} functions are available.\n *\n * ```ts\n * const bytes = getHiddenSuffixEncoder(getUtf8Encoder(), [\n *   getConstantEncoder(new Uint8Array([1, 2, 3])),\n *   getConstantEncoder(new Uint8Array([4, 5, 6])),\n * ]).encode('Hello');\n *\n * const value = getHiddenSuffixDecoder(getUtf8Decoder(), [\n *   getConstantDecoder(new Uint8Array([1, 2, 3])),\n *   getConstantDecoder(new Uint8Array([4, 5, 6])),\n * ]).decode(bytes);\n * ```\n *\n * @see {@link getHiddenSuffixEncoder}\n * @see {@link getHiddenSuffixDecoder}\n */\nexport function getHiddenSuffixCodec<TFrom, TTo extends TFrom>(\n    codec: FixedSizeCodec<TFrom, TTo>,\n    suffixedCodecs: readonly FixedSizeCodec<void>[],\n): FixedSizeCodec<TFrom, TTo>;\nexport function getHiddenSuffixCodec<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n    suffixedCodecs: readonly Codec<void>[],\n): VariableSizeCodec<TFrom, TTo>;\nexport function getHiddenSuffixCodec<TFrom, TTo extends TFrom>(\n    codec: Codec<TFrom, TTo>,\n    suffixedCodecs: readonly Codec<void>[],\n): Codec<TFrom, TTo> {\n    return combineCodec(getHiddenSuffixEncoder(codec, suffixedCodecs), getHiddenSuffixDecoder(codec, suffixedCodecs));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/index.ts",
    "content": "/**\n * This package contains codecs for various data structures such as arrays, maps, structs, tuples, enums, etc.\n * It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * This package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs)\n * which acts as an entry point for all codec packages as well as for their documentation.\n *\n * @packageDocumentation\n */\nexport * from './array';\nexport * from './assertions';\nexport * from './bit-array';\nexport * from './boolean';\nexport * from './bytes';\nexport * from './constant';\nexport * from './discriminated-union';\nexport * from './enum';\nexport * from './hidden-prefix';\nexport * from './hidden-suffix';\nexport * from './literal-union';\nexport * from './map';\nexport * from './nullable';\nexport * from './pattern-match';\nexport * from './predicate';\nexport * from './set';\nexport * from './struct';\nexport * from './tuple';\nexport * from './union';\nexport * from './unit';\n"
  },
  {
    "path": "packages/codecs-data-structures/src/literal-union.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    FixedSizeNumberCodec,\n    FixedSizeNumberDecoder,\n    FixedSizeNumberEncoder,\n    getU8Decoder,\n    getU8Encoder,\n    NumberCodec,\n    NumberDecoder,\n    NumberEncoder,\n} from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT,\n    SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\n/**\n * Defines the configuration options for literal union codecs.\n *\n * A literal union codec encodes values from a predefined set of literals.\n * The `size` option determines the numerical encoding used for the discriminant.\n * By default, literals are stored as a `u8` (1 byte).\n *\n * @typeParam TDiscriminator - A number codec, encoder, or decoder used for the discriminant.\n */\nexport type LiteralUnionCodecConfig<TDiscriminator = NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * The codec used to encode/decode the discriminator.\n     * @defaultValue `u8` discriminator.\n     */\n    size?: TDiscriminator;\n};\n\ntype Variant = bigint | boolean | number | string | null | undefined;\ntype GetTypeFromVariants<TVariants extends readonly Variant[]> = TVariants[number];\n\n/**\n * Returns an encoder for literal unions.\n *\n * This encoder serializes a value from a predefined set of literals\n * as a numerical index representing its position in the `variants` array.\n *\n * For more details, see {@link getLiteralUnionCodec}.\n *\n * @typeParam TVariants - A tuple of allowed literal values.\n *\n * @param variants - The possible literal values for the union.\n * @param config - Configuration options for encoding the literal union.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding literal unions.\n *\n * @example\n * Encoding a union of string literals.\n * ```ts\n * type Size = 'small' | 'medium' | 'large';\n * const sizeEncoder = getLiteralUnionEncoder(['small', 'medium', 'large']);\n *\n * sizeEncoder.encode('small');  // 0x00\n * sizeEncoder.encode('medium'); // 0x01\n * sizeEncoder.encode('large');  // 0x02\n * ```\n *\n * @see {@link getLiteralUnionCodec}\n */\nexport function getLiteralUnionEncoder<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n): FixedSizeEncoder<GetTypeFromVariants<TVariants>, 1>;\nexport function getLiteralUnionEncoder<const TVariants extends readonly Variant[], TSize extends number>(\n    variants: TVariants,\n    config: LiteralUnionCodecConfig<NumberEncoder> & { size: FixedSizeNumberEncoder<TSize> },\n): FixedSizeEncoder<GetTypeFromVariants<TVariants>, TSize>;\nexport function getLiteralUnionEncoder<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n    config?: LiteralUnionCodecConfig<NumberEncoder>,\n): VariableSizeEncoder<GetTypeFromVariants<TVariants>>;\nexport function getLiteralUnionEncoder<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n    config: LiteralUnionCodecConfig<NumberEncoder> = {},\n): Encoder<GetTypeFromVariants<TVariants>> {\n    const discriminator = config.size ?? getU8Encoder();\n    return transformEncoder(discriminator, variant => {\n        const index = variants.indexOf(variant);\n        if (index < 0) {\n            throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT, {\n                value: variant,\n                variants,\n            });\n        }\n        return index;\n    });\n}\n\n/**\n * Returns a decoder for literal unions.\n *\n * This decoder deserializes a numerical index into a corresponding\n * value from a predefined set of literals.\n *\n * For more details, see {@link getLiteralUnionCodec}.\n *\n * @typeParam TVariants - A tuple of allowed literal values.\n *\n * @param variants - The possible literal values for the union.\n * @param config - Configuration options for decoding the literal union.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding literal unions.\n *\n * @example\n * Decoding a union of string literals.\n * ```ts\n * type Size = 'small' | 'medium' | 'large';\n * const sizeDecoder = getLiteralUnionDecoder(['small', 'medium', 'large']);\n *\n * sizeDecoder.decode(new Uint8Array([0x00])); // 'small'\n * sizeDecoder.decode(new Uint8Array([0x01])); // 'medium'\n * sizeDecoder.decode(new Uint8Array([0x02])); // 'large'\n * ```\n *\n * @see {@link getLiteralUnionCodec}\n */\nexport function getLiteralUnionDecoder<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n): FixedSizeDecoder<GetTypeFromVariants<TVariants>, 1>;\nexport function getLiteralUnionDecoder<const TVariants extends readonly Variant[], TSize extends number>(\n    variants: TVariants,\n    config: LiteralUnionCodecConfig<NumberDecoder> & { size: FixedSizeNumberDecoder<TSize> },\n): FixedSizeDecoder<GetTypeFromVariants<TVariants>, TSize>;\nexport function getLiteralUnionDecoder<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n    config?: LiteralUnionCodecConfig<NumberDecoder>,\n): VariableSizeDecoder<GetTypeFromVariants<TVariants>>;\nexport function getLiteralUnionDecoder<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n    config: LiteralUnionCodecConfig<NumberDecoder> = {},\n): Decoder<GetTypeFromVariants<TVariants>> {\n    const discriminator = config.size ?? getU8Decoder();\n    return transformDecoder(discriminator, (index: bigint | number) => {\n        if (index < 0 || index >= variants.length) {\n            throw new SolanaError(SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE, {\n                discriminator: index,\n                maxRange: variants.length - 1,\n                minRange: 0,\n            });\n        }\n        return variants[Number(index)];\n    });\n}\n\n/**\n * Returns a codec for encoding and decoding literal unions.\n *\n * A literal union codec serializes and deserializes values\n * from a predefined set of literals, using a numerical index\n * to represent each value in the `variants` array.\n *\n * This allows efficient storage and retrieval of common\n * predefined values such as enum-like structures in TypeScript.\n *\n * @typeParam TVariants - A tuple of allowed literal values.\n *\n * @param variants - The possible literal values for the union.\n * @param config - Configuration options for encoding and decoding the literal union.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding literal unions.\n *\n * @example\n * Encoding and decoding a union of string literals.\n * ```ts\n * type Size = 'small' | 'medium' | 'large';\n * const sizeCodec = getLiteralUnionCodec(['small', 'medium', 'large']);\n *\n * sizeCodec.encode('small');  // 0x00\n * sizeCodec.encode('medium'); // 0x01\n * sizeCodec.encode('large');  // 0x02\n *\n * sizeCodec.decode(new Uint8Array([0x00])); // 'small'\n * sizeCodec.decode(new Uint8Array([0x01])); // 'medium'\n * sizeCodec.decode(new Uint8Array([0x02])); // 'large'\n * ```\n *\n * @example\n * Encoding and decoding a union of number literals.\n * ```ts\n * type Level = 10 | 20 | 30;\n * const levelCodec = getLiteralUnionCodec([10, 20, 30]);\n *\n * levelCodec.encode(10);  // 0x00\n * levelCodec.encode(20);  // 0x01\n * levelCodec.encode(30);  // 0x02\n *\n * levelCodec.decode(new Uint8Array([0x00])); // 10\n * levelCodec.decode(new Uint8Array([0x01])); // 20\n * levelCodec.decode(new Uint8Array([0x02])); // 30\n * ```\n *\n * @example\n * Using a custom discriminator size with different variant types.\n * ```ts\n * type MaybeBoolean = false | true | \"either\";\n * const codec = getLiteralUnionCodec([false, true, 'either'], { size: getU16Codec() });\n *\n * codec.encode(false);    // 0x0000\n * codec.encode(true);     // 0x0100\n * codec.encode('either'); // 0x0200\n *\n * codec.decode(new Uint8Array([0x00, 0x00])); // false\n * codec.decode(new Uint8Array([0x01, 0x00])); // true\n * codec.decode(new Uint8Array([0x02, 0x00])); // 'either'\n * ```\n *\n * @remarks\n * Separate {@link getLiteralUnionEncoder} and {@link getLiteralUnionDecoder} functions are available.\n *\n * ```ts\n * const bytes = getLiteralUnionEncoder(['red', 'green', 'blue']).encode('green');\n * const value = getLiteralUnionDecoder(['red', 'green', 'blue']).decode(bytes);\n * ```\n *\n * @see {@link getLiteralUnionEncoder}\n * @see {@link getLiteralUnionDecoder}\n */\nexport function getLiteralUnionCodec<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n): FixedSizeCodec<GetTypeFromVariants<TVariants>, GetTypeFromVariants<TVariants>, 1>;\nexport function getLiteralUnionCodec<const TVariants extends readonly Variant[], TSize extends number>(\n    variants: TVariants,\n    config: LiteralUnionCodecConfig<NumberCodec> & { size: FixedSizeNumberCodec<TSize> },\n): FixedSizeCodec<GetTypeFromVariants<TVariants>, GetTypeFromVariants<TVariants>, TSize>;\nexport function getLiteralUnionCodec<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n    config?: LiteralUnionCodecConfig<NumberCodec>,\n): VariableSizeCodec<GetTypeFromVariants<TVariants>>;\nexport function getLiteralUnionCodec<const TVariants extends readonly Variant[]>(\n    variants: TVariants,\n    config: LiteralUnionCodecConfig<NumberCodec> = {},\n): Codec<GetTypeFromVariants<TVariants>> {\n    return combineCodec(getLiteralUnionEncoder(variants, config), getLiteralUnionDecoder(variants, config));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/map.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { ArrayLikeCodecSize, getArrayDecoder, getArrayEncoder } from './array';\nimport { getTupleDecoder, getTupleEncoder } from './tuple';\n\n/**\n * Defines the configuration options for map codecs.\n *\n * The `size` option determines how the number of entries in the map is stored.\n * It can be:\n * - A {@link NumberCodec} to prefix the map with its size.\n * - A fixed number of entries.\n * - `'remainder'`, which infers the number of entries based on the remaining bytes.\n *   This option is only available for fixed-size keys and values.\n *\n * @typeParam TPrefix - A number codec, encoder, or decoder used for the size prefix.\n */\nexport type MapCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * The size of the map.\n     * @defaultValue u32 prefix.\n     */\n    size?: ArrayLikeCodecSize<TPrefix>;\n};\n\n/**\n * Returns an encoder for maps.\n *\n * This encoder serializes maps where the keys and values are encoded\n * using the provided key and value encoders. The number of entries\n * is determined by the `size` configuration.\n *\n * For more details, see {@link getMapCodec}.\n *\n * @typeParam TFromKey - The type of the keys before encoding.\n * @typeParam TFromValue - The type of the values before encoding.\n *\n * @param key - The encoder for the map's keys.\n * @param value - The encoder for the map's values.\n * @param config - Configuration options for encoding the map.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding maps.\n *\n * @example\n * Encoding a map with a `u32` size prefix.\n * ```ts\n * const encoder = getMapEncoder(fixCodecSize(getUtf8Encoder(), 5), getU8Encoder());\n * const bytes = encoder.encode(new Map([['alice', 42], ['bob', 5]]));\n * // 0x02000000616c6963652a626f62000005\n * //   |       |         | |         └── Value (5)\n * //   |       |         | └── Key (\"bob\", 5 bytes fixed, null-padded)\n * //   |       |         └── Value (42)\n * //   |       └── Key (\"alice\", 5 bytes fixed)\n * //   └── 4-byte prefix (2 entries)\n * ```\n *\n * @see {@link getMapCodec}\n */\nexport function getMapEncoder<TFromKey, TFromValue>(\n    key: Encoder<TFromKey>,\n    value: Encoder<TFromValue>,\n    config: MapCodecConfig<NumberEncoder> & { size: 0 },\n): FixedSizeEncoder<Map<TFromKey, TFromValue>, 0>;\nexport function getMapEncoder<TFromKey, TFromValue>(\n    key: FixedSizeEncoder<TFromKey>,\n    value: FixedSizeEncoder<TFromValue>,\n    config: MapCodecConfig<NumberEncoder> & { size: number },\n): FixedSizeEncoder<Map<TFromKey, TFromValue>>;\nexport function getMapEncoder<TFromKey, TFromValue>(\n    key: Encoder<TFromKey>,\n    value: Encoder<TFromValue>,\n    config?: MapCodecConfig<NumberEncoder>,\n): VariableSizeEncoder<Map<TFromKey, TFromValue>>;\nexport function getMapEncoder<TFromKey, TFromValue>(\n    key: Encoder<TFromKey>,\n    value: Encoder<TFromValue>,\n    config: MapCodecConfig<NumberEncoder> = {},\n): Encoder<Map<TFromKey, TFromValue>> {\n    return transformEncoder(\n        getArrayEncoder(getTupleEncoder([key, value]), config as object),\n        (map: Map<TFromKey, TFromValue>): [TFromKey, TFromValue][] => [...map.entries()],\n    );\n}\n\n/**\n * Returns a decoder for maps.\n *\n * This decoder deserializes maps where the keys and values are decoded\n * using the provided key and value decoders. The number of entries\n * is determined by the `size` configuration.\n *\n * For more details, see {@link getMapCodec}.\n *\n * @typeParam TToKey - The type of the keys after decoding.\n * @typeParam TToValue - The type of the values after decoding.\n *\n * @param key - The decoder for the map's keys.\n * @param value - The decoder for the map's values.\n * @param config - Configuration options for decoding the map.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding maps.\n *\n * @example\n * Decoding a map with a `u32` size prefix.\n * ```ts\n * const decoder = getMapDecoder(fixCodecSize(getUtf8Decoder(), 5), getU8Decoder());\n * const map = decoder.decode(new Uint8Array([\n *   0x02,0x00,0x00,0x00,0x61,0x6c,0x69,0x63,0x65,0x2a,0x62,0x6f,0x62,0x00,0x00,0x05\n * ]));\n * // new Map([['alice', 42], ['bob', 5]])\n * ```\n *\n * @see {@link getMapCodec}\n */\nexport function getMapDecoder<TToKey, TToValue>(\n    key: Decoder<TToKey>,\n    value: Decoder<TToValue>,\n    config: MapCodecConfig<NumberDecoder> & { size: 0 },\n): FixedSizeDecoder<Map<TToKey, TToValue>, 0>;\nexport function getMapDecoder<TToKey, TToValue>(\n    key: FixedSizeDecoder<TToKey>,\n    value: FixedSizeDecoder<TToValue>,\n    config: MapCodecConfig<NumberDecoder> & { size: number },\n): FixedSizeDecoder<Map<TToKey, TToValue>>;\nexport function getMapDecoder<TToKey, TToValue>(\n    key: Decoder<TToKey>,\n    value: Decoder<TToValue>,\n    config?: MapCodecConfig<NumberDecoder>,\n): VariableSizeDecoder<Map<TToKey, TToValue>>;\nexport function getMapDecoder<TToKey, TToValue>(\n    key: Decoder<TToKey>,\n    value: Decoder<TToValue>,\n    config: MapCodecConfig<NumberDecoder> = {},\n): Decoder<Map<TToKey, TToValue>> {\n    return transformDecoder(\n        getArrayDecoder(getTupleDecoder([key, value]), config as object) as Decoder<[TToKey, TToValue][]>,\n        (entries: [TToKey, TToValue][]): Map<TToKey, TToValue> => new Map(entries),\n    );\n}\n\n/**\n * Returns a codec for encoding and decoding maps.\n *\n * This codec serializes maps where the key/value pairs are encoded\n * and decoded one after another using the provided key and value codecs.\n * The number of entries is determined by the `size` configuration and\n * defaults to a `u32` size prefix.\n *\n * @typeParam TFromKey - The type of the keys before encoding.\n * @typeParam TFromValue - The type of the values before encoding.\n * @typeParam TToKey - The type of the keys after decoding.\n * @typeParam TToValue - The type of the values after decoding.\n *\n * @param key - The codec for the map's keys.\n * @param value - The codec for the map's values.\n * @param config - Configuration options for encoding and decoding the map.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding maps.\n *\n * @example\n * Encoding and decoding a map with a `u32` size prefix (default).\n * ```ts\n * const codec = getMapCodec(fixCodecSize(getUtf8Codec(), 5), getU8Codec());\n * const bytes = codec.encode(new Map([['alice', 42], ['bob', 5]]));\n * // 0x02000000616c6963652a626f62000005\n * //   |       |         | |         └── Value (5)\n * //   |       |         | └── Key (\"bob\", 5 bytes fixed, null-padded)\n * //   |       |         └── Value (42)\n * //   |       └── Key (\"alice\", 5 bytes fixed)\n * //   └── 4-byte prefix (2 entries)\n *\n * const map = codec.decode(bytes);\n * // new Map([['alice', 42], ['bob', 5]])\n * ```\n *\n * @example\n * Encoding and decoding a map with a `u16` size prefix.\n * ```ts\n * const codec = getMapCodec(fixCodecSize(getUtf8Codec(), 5), getU8Codec(), { size: getU16Codec() });\n * const bytes = codec.encode(new Map([['alice', 42], ['bob', 5]]));\n * // 0x0200616c6963652a626f62000005\n * //   |   |         | |         └── Value (5)\n * //   |   |         | └── Key (\"bob\", 5 bytes fixed, null-padded)\n * //   |   |         └── Value (42)\n * //   |   └── Key (\"alice\", 5 bytes fixed)\n * //   └── 2-byte prefix (2 entries)\n *\n * const map = codec.decode(bytes);\n * // new Map([['alice', 42], ['bob', 5]])\n * ```\n *\n * @example\n * Encoding and decoding a fixed-size map.\n * ```ts\n * const codec = getMapCodec(fixCodecSize(getUtf8Codec(), 5), getU8Codec(), { size: 2 });\n * const bytes = codec.encode(new Map([['alice', 42], ['bob', 5]]));\n * // 0x616c6963652a626f62000005\n * //   |         | |         └── Value (5)\n * //   |         | └── Key (\"bob\", 5 bytes fixed, null-padded)\n * //   |         └── Value (42)\n * //   └── Key (\"alice\", 5 bytes fixed)\n *\n * const map = codec.decode(bytes);\n * // new Map([['alice', 42], ['bob', 5]])\n * ```\n *\n * @example\n * Encoding and decoding a map with remainder size.\n * ```ts\n * const codec = getMapCodec(fixCodecSize(getUtf8Codec(), 5), getU8Codec(), { size: 'remainder' });\n * const bytes = codec.encode(new Map([['alice', 42], ['bob', 5]]));\n * // 0x616c6963652a626f62000005\n * //   |         | |         └── Value (5)\n * //   |         | └── Key (\"bob\", 5 bytes fixed, null-padded)\n * //   |         └── Value (42)\n * //   └── Key (\"alice\", 5 bytes fixed)\n * // No size prefix, the size is inferred from the remaining bytes.\n *\n * const map = codec.decode(bytes);\n * // new Map([['alice', 42], ['bob', 5]])\n * ```\n *\n * @remarks\n * Separate {@link getMapEncoder} and {@link getMapDecoder} functions are available.\n * ```ts\n * const bytes = getMapEncoder(fixCodecSize(getUtf8Encoder(), 5), getU8Encoder()).encode(new Map([['alice', 42]]));\n * const map = getMapDecoder(fixCodecSize(getUtf8Decoder(), 5), getU8Decoder()).decode(bytes);\n * ```\n *\n * @see {@link getMapEncoder}\n * @see {@link getMapDecoder}\n */\nexport function getMapCodec<\n    TFromKey,\n    TFromValue,\n    TToKey extends TFromKey = TFromKey,\n    TToValue extends TFromValue = TFromValue,\n>(\n    key: Codec<TFromKey, TToKey>,\n    value: Codec<TFromValue, TToValue>,\n    config: MapCodecConfig<NumberCodec> & { size: 0 },\n): FixedSizeCodec<Map<TFromKey, TFromValue>, Map<TToKey, TToValue>, 0>;\nexport function getMapCodec<\n    TFromKey,\n    TFromValue,\n    TToKey extends TFromKey = TFromKey,\n    TToValue extends TFromValue = TFromValue,\n>(\n    key: FixedSizeCodec<TFromKey, TToKey>,\n    value: FixedSizeCodec<TFromValue, TToValue>,\n    config: MapCodecConfig<NumberCodec> & { size: number },\n): FixedSizeCodec<Map<TFromKey, TFromValue>, Map<TToKey, TToValue>>;\nexport function getMapCodec<\n    TFromKey,\n    TFromValue,\n    TToKey extends TFromKey = TFromKey,\n    TToValue extends TFromValue = TFromValue,\n>(\n    key: Codec<TFromKey, TToKey>,\n    value: Codec<TFromValue, TToValue>,\n    config?: MapCodecConfig<NumberCodec>,\n): VariableSizeCodec<Map<TFromKey, TFromValue>, Map<TToKey, TToValue>>;\nexport function getMapCodec<\n    TFromKey,\n    TFromValue,\n    TToKey extends TFromKey = TFromKey,\n    TToValue extends TFromValue = TFromValue,\n>(\n    key: Codec<TFromKey, TToKey>,\n    value: Codec<TFromValue, TToValue>,\n    config: MapCodecConfig<NumberCodec> = {},\n): Codec<Map<TFromKey, TFromValue>, Map<TToKey, TToValue>> {\n    return combineCodec(getMapEncoder(key, value, config as object), getMapDecoder(key, value, config as object));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/nullable.ts",
    "content": "import {\n    assertIsFixedSize,\n    Codec,\n    combineCodec,\n    containsBytes,\n    Decoder,\n    Encoder,\n    fixDecoderSize,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    fixEncoderSize,\n    ReadonlyUint8Array,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    FixedSizeNumberCodec,\n    FixedSizeNumberDecoder,\n    FixedSizeNumberEncoder,\n    getU8Decoder,\n    getU8Encoder,\n    NumberCodec,\n    NumberDecoder,\n    NumberEncoder,\n} from '@solana/codecs-numbers';\n\nimport { getBooleanDecoder, getBooleanEncoder } from './boolean';\nimport { getConstantDecoder, getConstantEncoder } from './constant';\nimport { getTupleDecoder, getTupleEncoder } from './tuple';\nimport { getUnionDecoder, getUnionEncoder } from './union';\nimport { getUnitDecoder, getUnitEncoder } from './unit';\n\n/**\n * Defines the configuration options for nullable codecs.\n *\n * This configuration controls how nullable values are encoded and decoded.\n *\n * By default, nullable values are prefixed with a `u8` (0 = `null`, 1 = present).\n * The `noneValue` and `prefix` options allow customizing this behavior.\n *\n * @typeParam TPrefix - A number codec, encoder, or decoder used as the presence prefix.\n *\n * @see {@link getNullableEncoder}\n * @see {@link getNullableDecoder}\n * @see {@link getNullableCodec}\n */\nexport type NullableCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * Specifies how `null` values are represented in the encoded data.\n     *\n     * - By default, `null` values are omitted from encoding.\n     * - `'zeroes'`: The bytes allocated for the value are filled with zeroes. This requires a fixed-size codec.\n     * - Custom byte array: `null` values are replaced with a predefined byte sequence. This results in a variable-size codec.\n     *\n     * @defaultValue No explicit `noneValue` is used; `null` values are omitted.\n     */\n    noneValue?: ReadonlyUint8Array | 'zeroes';\n\n    /**\n     * The presence prefix used to distinguish between `null` and present values.\n     *\n     * - By default, a `u8` prefix is used (`0 = null`, `1 = present`).\n     * - Custom number codec: Allows defining a different number size for the prefix.\n     * - `null`: No prefix is used; `noneValue` (if provided) determines `null`.\n     *   If no `noneValue` is set, `null` is identified by the absence of bytes.\n     *\n     * @defaultValue `u8` prefix.\n     */\n    prefix?: TPrefix | null;\n};\n\n/**\n * Returns an encoder for optional values, allowing `null` values to be encoded.\n *\n * This encoder serializes an optional value using a configurable approach:\n * - By default, a `u8` prefix is used (0 = `null`, 1 = present). This can be customized or disabled.\n * - If `noneValue: 'zeroes'` is set, `null` values are encoded as zeroes.\n * - If `noneValue` is a byte array, `null` values are replaced with the provided constant.\n *\n * For more details, see {@link getNullableCodec}.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n *\n * @param item - The encoder for the value that may be present.\n * @param config - Configuration options for encoding optional values.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding nullable values.\n *\n * @example\n * Encoding an optional number.\n * ```ts\n * const encoder = getNullableEncoder(getU32Encoder());\n *\n * encoder.encode(null); // 0x00\n * encoder.encode(42);   // 0x012a000000\n * ```\n *\n * @see {@link getNullableCodec}\n */\nexport function getNullableEncoder<TFrom, TSize extends number>(\n    item: FixedSizeEncoder<TFrom, TSize>,\n    config: NullableCodecConfig<NumberEncoder> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeEncoder<TFrom | null, TSize>;\nexport function getNullableEncoder<TFrom>(\n    item: FixedSizeEncoder<TFrom>,\n    config: NullableCodecConfig<FixedSizeNumberEncoder> & { noneValue: 'zeroes' },\n): FixedSizeEncoder<TFrom | null>;\nexport function getNullableEncoder<TFrom>(\n    item: FixedSizeEncoder<TFrom>,\n    config: NullableCodecConfig<NumberEncoder> & { noneValue: 'zeroes' },\n): VariableSizeEncoder<TFrom | null>;\nexport function getNullableEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config?: NullableCodecConfig<NumberEncoder> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeEncoder<TFrom | null>;\nexport function getNullableEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config: NullableCodecConfig<NumberEncoder> = {},\n): Encoder<TFrom | null> {\n    const prefix = (() => {\n        if (config.prefix === null) {\n            return transformEncoder(getUnitEncoder(), (_boolean: boolean) => undefined);\n        }\n        return getBooleanEncoder({ size: config.prefix ?? getU8Encoder() });\n    })();\n    const noneValue = (() => {\n        if (config.noneValue === 'zeroes') {\n            assertIsFixedSize(item);\n            return fixEncoderSize(getUnitEncoder(), item.fixedSize);\n        }\n        if (!config.noneValue) {\n            return getUnitEncoder();\n        }\n        return getConstantEncoder(config.noneValue);\n    })();\n\n    return getUnionEncoder(\n        [\n            transformEncoder(getTupleEncoder([prefix, noneValue]), (_value: null): [boolean, void] => [\n                false,\n                undefined,\n            ]),\n            transformEncoder(getTupleEncoder([prefix, item]), (value: TFrom): [boolean, TFrom] => [true, value]),\n        ],\n        variant => Number(variant !== null),\n    );\n}\n\n/**\n * Returns a decoder for optional values, allowing `null` values to be recognized.\n *\n * This decoder deserializes an optional value using a configurable approach:\n * - By default, a `u8` prefix is used (0 = `null`, 1 = present). This can be customized or disabled.\n * - If `noneValue: 'zeroes'` is set, `null` values are identified by zeroes.\n * - If `noneValue` is a byte array, `null` values match the provided constant.\n *\n * For more details, see {@link getNullableCodec}.\n *\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param item - The decoder for the value that may be present.\n * @param config - Configuration options for decoding optional values.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding nullable values.\n *\n * @example\n * Decoding an optional number.\n * ```ts\n * const decoder = getNullableDecoder(getU32Decoder());\n *\n * decoder.decode(new Uint8Array([0x00])); // null\n * decoder.decode(new Uint8Array([0x01, 0x2a, 0x00, 0x00, 0x00])); // 42\n * ```\n *\n * @see {@link getNullableCodec}\n */\nexport function getNullableDecoder<TTo, TSize extends number>(\n    item: FixedSizeDecoder<TTo, TSize>,\n    config: NullableCodecConfig<NumberDecoder> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeDecoder<TTo | null, TSize>;\nexport function getNullableDecoder<TTo>(\n    item: FixedSizeDecoder<TTo>,\n    config: NullableCodecConfig<FixedSizeNumberDecoder> & { noneValue: 'zeroes' },\n): FixedSizeDecoder<TTo | null>;\nexport function getNullableDecoder<TTo>(\n    item: FixedSizeDecoder<TTo>,\n    config: NullableCodecConfig<NumberDecoder> & { noneValue: 'zeroes' },\n): VariableSizeDecoder<TTo | null>;\nexport function getNullableDecoder<TTo>(\n    item: Decoder<TTo>,\n    config?: NullableCodecConfig<NumberDecoder> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeDecoder<TTo | null>;\nexport function getNullableDecoder<TTo>(\n    item: Decoder<TTo>,\n    config: NullableCodecConfig<NumberDecoder> = {},\n): Decoder<TTo | null> {\n    const prefix = (() => {\n        if (config.prefix === null) {\n            return transformDecoder(getUnitDecoder(), () => false);\n        }\n        return getBooleanDecoder({ size: config.prefix ?? getU8Decoder() });\n    })();\n    const noneValue = (() => {\n        if (config.noneValue === 'zeroes') {\n            assertIsFixedSize(item);\n            return fixDecoderSize(getUnitDecoder(), item.fixedSize);\n        }\n        if (!config.noneValue) {\n            return getUnitDecoder();\n        }\n        return getConstantDecoder(config.noneValue);\n    })();\n\n    return getUnionDecoder(\n        [\n            transformDecoder(getTupleDecoder([prefix, noneValue]), () => null),\n            transformDecoder(getTupleDecoder([prefix, item]), ([, value]): TTo => value),\n        ],\n        (bytes, offset) => {\n            if (config.prefix === null && !config.noneValue) {\n                return Number(offset < bytes.length);\n            }\n            if (config.prefix === null && config.noneValue != null) {\n                const zeroValue =\n                    config.noneValue === 'zeroes' ? new Uint8Array(noneValue.fixedSize).fill(0) : config.noneValue;\n                return containsBytes(bytes, zeroValue, offset) ? 0 : 1;\n            }\n            return Number(prefix.read(bytes, offset)[0]);\n        },\n    );\n}\n\n/**\n * Returns a codec for encoding and decoding optional values, allowing `null` values to be handled.\n *\n * This codec serializes and deserializes optional values using a configurable approach:\n * - By default, a `u8` prefix is used (0 = `null`, 1 = present).\n *    This can be customized using a custom number codec or even disabled by setting\n *    the `prefix` to `null`.\n * - If `noneValue: 'zeroes'` is set, `null` values are encoded/decoded as zeroes.\n * - If `noneValue` is a byte array, `null` values are represented by the provided constant.\n *\n * For more details on the configuration options, see {@link NullableCodecConfig}.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param item - The codec for the value that may be present.\n * @param config - Configuration options for encoding and decoding optional values.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding nullable values.\n *\n * @example\n * Encoding and decoding an optional number using a `u8` prefix (default).\n * ```ts\n * const codec = getNullableCodec(getU32Codec());\n *\n * codec.encode(null); // 0x00\n * codec.encode(42);   // 0x012a000000\n *\n * codec.decode(new Uint8Array([0x00])); // null\n * codec.decode(new Uint8Array([0x01, 0x2a, 0x00, 0x00, 0x00])); // 42\n * ```\n *\n * @example\n * Encoding and decoding an optional number using a fixed-size codec, by filling `null` values with zeroes.\n * ```ts\n * const codec = getNullableCodec(getU32Codec(), { noneValue: 'zeroes' });\n *\n * codec.encode(null); // 0x0000000000\n * codec.encode(42);   // 0x012a000000\n *\n * codec.decode(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00])); // null\n * codec.decode(new Uint8Array([0x01, 0x2a, 0x00, 0x00, 0x00])); // 42\n * ```\n *\n * @example\n * Encoding and decoding `null` values with zeroes and no prefix.\n * ```ts\n * const codec = getNullableCodec(getU32Codec(), {\n *   noneValue: 'zeroes',\n *   prefix: null,\n * });\n *\n * codec.encode(null); // 0x00000000\n * codec.encode(42);   // 0x2a000000\n *\n * codec.decode(new Uint8Array([0x00, 0x00, 0x00, 0x00])); // null\n * codec.decode(new Uint8Array([0x2a, 0x00, 0x00, 0x00])); // 42\n * ```\n *\n * @example\n * Encoding and decoding `null` values with a custom byte sequence and no prefix.\n * ```ts\n * const codec = getNullableCodec(getU16Codec(), {\n *   noneValue: new Uint8Array([0xff, 0xff]),\n *   prefix: null,\n * });\n *\n * codec.encode(null); // 0xffff\n * codec.encode(42); // 0x2a00\n *\n * codec.decode(new Uint8Array([0xff, 0xff])); // null\n * codec.decode(new Uint8Array([0x2a, 0x00])); // 42\n * ```\n *\n * @example\n * Identifying `null` values by the absence of bytes.\n * ```ts\n * const codec = getNullableCodec(getU16Codec(), { prefix: null });\n *\n * codec.encode(null); // Empty bytes\n * codec.encode(42); // 0x2a00\n *\n * codec.decode(new Uint8Array([])); // null\n * codec.decode(new Uint8Array([0x2a, 0x00])); // 42\n * ```\n *\n * @remarks\n * Separate {@link getNullableEncoder} and {@link getNullableDecoder} functions are available.\n *\n * ```ts\n * const bytes = getNullableEncoder(getU32Encoder()).encode(42);\n * const value = getNullableDecoder(getU32Decoder()).decode(bytes);\n * ```\n *\n * @see {@link getNullableEncoder}\n * @see {@link getNullableDecoder}\n */\nexport function getNullableCodec<TFrom, TTo extends TFrom, TSize extends number>(\n    item: FixedSizeCodec<TFrom, TTo, TSize>,\n    config: NullableCodecConfig<NumberCodec> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeCodec<TFrom | null, TTo | null, TSize>;\nexport function getNullableCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: FixedSizeCodec<TFrom, TTo>,\n    config: NullableCodecConfig<FixedSizeNumberCodec> & { noneValue: 'zeroes' },\n): FixedSizeCodec<TFrom | null, TTo | null>;\nexport function getNullableCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: FixedSizeCodec<TFrom, TTo>,\n    config: NullableCodecConfig<NumberCodec> & { noneValue: 'zeroes' },\n): VariableSizeCodec<TFrom | null, TTo | null>;\nexport function getNullableCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config?: NullableCodecConfig<NumberCodec> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeCodec<TFrom | null, TTo | null>;\nexport function getNullableCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config: NullableCodecConfig<NumberCodec> = {},\n): Codec<TFrom | null, TTo | null> {\n    type ConfigCast = NullableCodecConfig<NumberCodec> & { noneValue?: ReadonlyUint8Array };\n    return combineCodec(\n        getNullableEncoder<TFrom>(item, config as ConfigCast),\n        getNullableDecoder<TTo>(item, config as ConfigCast),\n    );\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/pattern-match.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES,\n    SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { getUnionDecoder, getUnionEncoder } from './union';\n\ntype PatternMatchEncoderEntry<TNarrowed, TFrom = TNarrowed> = TNarrowed extends TFrom\n    ? // Boolean predicate with original encoder\n          | readonly [(value: TFrom) => boolean, Encoder<TFrom>]\n          // Type predicate with narrowed encoder\n          | readonly [(value: TFrom) => value is TNarrowed, Encoder<TNarrowed>]\n    : never;\n\ntype FixedSizePatternMatchEncoderEntry<\n    TNarrowed,\n    TFrom = TNarrowed,\n    TSize extends number = number,\n> = TNarrowed extends TFrom\n    ? // Boolean predicate with original encoder\n          | readonly [(value: TFrom) => boolean, FixedSizeEncoder<TFrom, TSize>]\n          // Type predicate with narrowed encoder\n          | readonly [(value: TFrom) => value is TNarrowed, FixedSizeEncoder<TNarrowed, TSize>]\n    : never;\n\ntype VariableSizePatternMatchEncoderEntry<TNarrowed, TFrom = TNarrowed> = TNarrowed extends TFrom\n    ? // Boolean predicate with original encoder\n          | readonly [(value: TFrom) => boolean, VariableSizeEncoder<TFrom>]\n          // Type predicate with narrowed encoder\n          | readonly [(value: TFrom) => value is TNarrowed, VariableSizeEncoder<TNarrowed>]\n    : never;\n\n/**\n * Returns an encoder that selects which variant encoder to use based on pattern matching.\n *\n * This encoder evaluates the value against a series of predicate functions in order,\n * and uses the first matching encoder to encode the value.\n *\n * @typeParam TFrom - The type of the value to encode.\n *\n * @param patterns - An array of `[predicate, encoder]` pairs. Predicates are tested in order\n * and the first matching encoder is used to encode the value. Note that predicates can be either\n * type predicates that narrow the type of the value, or boolean predicates. If using type predicates,\n * the encoder can be for the narrowed type.\n * @returns An encoder that selects the appropriate variant based on the matched pattern.\n *\n * @throws Throws a {@link SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE} error\n * if the value does not match any of the specified patterns.\n *\n * @example\n * Encoding values using pattern matching.\n * ```ts\n * const encoder = getPatternMatchEncoder([\n *   [(n: number) => n < 256, getU8Encoder()],\n *   [(n: number) => n < 2 ** 16, getU16Encoder()],\n *   [(n: number) => n < 2 ** 32, getU32Encoder()]\n * ]);\n *\n * encoder.encode(42);\n * // 0x2a\n * //  └── Small number encoded as u8\n *\n * encoder.encode(1000);\n * // 0xe803\n * //   └── Medium number encoded as u16\n *\n *\n * encoder.encode(100_000);\n * // 0xa0860100\n * //   └── Large number encoded as u32\n *\n * ender.encode(2 ** 32 + 1);\n * // Throws an error because the value does not match any pattern\n * ```\n *\n * @see {@link getPatternMatchCodec}\n */\nexport function getPatternMatchEncoder<TFrom, TSize extends number>(\n    patterns: FixedSizePatternMatchEncoderEntry<TFrom, TFrom, TSize>[],\n): FixedSizeEncoder<TFrom, TSize>;\nexport function getPatternMatchEncoder<TFrom>(\n    patterns: FixedSizePatternMatchEncoderEntry<TFrom>[],\n): FixedSizeEncoder<TFrom>;\nexport function getPatternMatchEncoder<TFrom>(\n    patterns: VariableSizePatternMatchEncoderEntry<TFrom>[],\n): VariableSizeEncoder<TFrom>;\nexport function getPatternMatchEncoder<TFrom>(patterns: PatternMatchEncoderEntry<TFrom>[]): Encoder<TFrom>;\nexport function getPatternMatchEncoder<TFrom>(patterns: PatternMatchEncoderEntry<TFrom>[]): Encoder<TFrom> {\n    return getUnionEncoder(\n        patterns.map(([, encoder]) => encoder),\n        (value: TFrom) => {\n            const index = patterns.findIndex(([predicate]) => predicate(value));\n            if (index === -1) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE);\n            }\n            return index;\n        },\n    );\n}\n\n/**\n * Returns a decoder that selects which variant decoder to use based on pattern matching.\n *\n * This decoder evaluates the byte array against a series of predicate functions in order,\n * and uses the first matching decoder to decode the value.\n *\n * @typeParam TTo - The type of the value to decode.\n *\n * @param patterns - An array of `[predicate, decoder]` pairs. Predicates are tested in order\n * and the first matching decoder is used to decode the byte array.\n * @returns A decoder that selects the appropriate variant based on the matched byte pattern.\n *\n * @throws Throws a {@link SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES} error\n * if the byte array does not match any of the specified patterns.\n *\n * @example\n * Decoding values using pattern matching on bytes.\n * ```ts\n * const decoder = getPatternMatchDecoder([\n *   [(bytes) => bytes.length === 1, getU8Decoder()],\n *   [(bytes) => bytes.length === 2, getU16Decoder()],\n *   [(bytes) => bytes.length <= 4, getU32Decoder()]\n * ]);\n *\n * decoder.decode(new Uint8Array([0x2a])); // 42 (decoded as u8)\n * decoder.decode(new Uint8Array([0xe8, 0x03])) // 1000 (decoded as u16)\n * decoder.decode(new Uint8Array([0xa0, 0x86, 0x01, 0x00])) // 100_000 (decoded as u32)\n * decoder.decode(new Uint8Array([0xa0, 0x86, 0x01, 0x00, 0x00]))\n * // Throws an error because the bytes do not match any pattern\n * ```\n *\n * @see {@link getPatternMatchCodec}\n * @see {@link getPatternMatchEncoder}\n */\nexport function getPatternMatchDecoder<TTo, TSize extends number>(\n    patterns: [(value: ReadonlyUint8Array) => boolean, FixedSizeDecoder<TTo, TSize>][],\n): FixedSizeDecoder<TTo, TSize>;\nexport function getPatternMatchDecoder<TTo>(\n    patterns: [(value: ReadonlyUint8Array) => boolean, FixedSizeDecoder<TTo>][],\n): FixedSizeDecoder<TTo>;\nexport function getPatternMatchDecoder<TTo>(\n    patterns: [(value: ReadonlyUint8Array) => boolean, VariableSizeDecoder<TTo>][],\n): VariableSizeDecoder<TTo>;\nexport function getPatternMatchDecoder<TTo>(\n    patterns: [(value: ReadonlyUint8Array) => boolean, Decoder<TTo>][],\n): Decoder<TTo>;\nexport function getPatternMatchDecoder<TTo>(\n    patterns: [(value: ReadonlyUint8Array) => boolean, Decoder<TTo>][],\n): Decoder<TTo> {\n    return getUnionDecoder(\n        patterns.map(([, decoder]) => decoder),\n        (value: ReadonlyUint8Array) => {\n            const index = patterns.findIndex(([predicate]) => predicate(value));\n            if (index === -1) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES, {\n                    bytes: value,\n                });\n            }\n            return index;\n        },\n    );\n}\n\ntype PatternMatchCodecEntry<TNarrowedFrom, TFrom = TNarrowedFrom, TTo = TNarrowedFrom> = TNarrowedFrom extends TFrom\n    ? TTo extends TNarrowedFrom\n        ?\n              | readonly [\n                    (value: TFrom) => value is TNarrowedFrom,\n                    (bytes: ReadonlyUint8Array) => boolean,\n                    Codec<TNarrowedFrom, TTo>,\n                ]\n              | readonly [(value: TFrom) => boolean, (bytes: ReadonlyUint8Array) => boolean, Codec<TFrom, TTo>]\n        : never\n    : never;\n\ntype FixedSizePatternMatchCodecEntry<\n    TNarrowedFrom,\n    TFrom = TNarrowedFrom,\n    TTo = TNarrowedFrom,\n    TSize extends number = number,\n> = TNarrowedFrom extends TFrom\n    ? TTo extends TNarrowedFrom\n        ?\n              | readonly [\n                    (value: TFrom) => boolean,\n                    (bytes: ReadonlyUint8Array) => boolean,\n                    FixedSizeCodec<TFrom, TTo, TSize>,\n                ]\n              | readonly [\n                    (value: TFrom) => value is TNarrowedFrom,\n                    (bytes: ReadonlyUint8Array) => boolean,\n                    FixedSizeCodec<TNarrowedFrom, TTo, TSize>,\n                ]\n        : never\n    : never;\n\ntype VariableSizePatternMatchCodecEntry<\n    TNarrowedFrom,\n    TFrom = TNarrowedFrom,\n    TTo = TNarrowedFrom,\n> = TNarrowedFrom extends TFrom\n    ? TTo extends TNarrowedFrom\n        ?\n              | readonly [\n                    (value: TFrom) => boolean,\n                    (bytes: ReadonlyUint8Array) => boolean,\n                    VariableSizeCodec<TFrom, TTo>,\n                ]\n              | readonly [\n                    (value: TFrom) => value is TNarrowedFrom,\n                    (bytes: ReadonlyUint8Array) => boolean,\n                    VariableSizeCodec<TNarrowedFrom, TTo>,\n                ]\n        : never\n    : never;\n\n/**\n * Returns a codec that selects which variant codec to use based on pattern matching.\n *\n * This codec evaluates values and byte arrays against a series of predicate functions in order,\n * using the first matching codec for encoding or decoding.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the value to decode.\n *\n * @param patterns - An array of `[valuePredicate, bytesPredicate, codec]` triples. Predicates\n * are tested in order and the first match determines the codec used. During encoding,\n * `valuePredicate` receives the value to encode. During decoding, `bytesPredicate` receives\n * the byte array.\n * @returns A codec that selects the appropriate variant based on the matched pattern.\n *\n * @throws Throws a {@link SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE} error\n * if a value being encoded does not match any of the specified patterns.\n * @throws Throws a {@link SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES} error\n * if a byte array being decoded does not match any of the specified patterns.\n *\n * @example\n * Encoding and decoding using pattern matching.\n * ```ts\n * const codec = getPatternMatchCodec([\n *  [\n *    (n: number) => n < 256,\n *    (bytes) => bytes.length === 1,\n *    getU8Codec(),\n *  ],\n *  [\n *    (n: number) => n < 2 ** 16,\n *    (bytes) => bytes.length === 2,\n *    getU16Codec(),\n *  ],\n *  [\n *    (n: number) => n < 2 ** 32,\n *    (bytes) => bytes.length <= 4,\n *    getU32Codec(),\n *  ]\n * ]);\n *\n * const bytes1 = codec.encode(42);     // 0x2a, encoded as u8\n * const value1 = codec.decode(bytes1); // 42, decoded as u8\n *\n * const bytes2 = codec.encode(1000);   // 0xe803, encoded as u16\n * const value2 = codec.decode(bytes2); // 1000, decoded as u16\n *\n * const bytes3 = codec.encode(100_000); //0xa0860100, encoded as u32\n * const value3 = codec.decode(bytes3); // 100_000, decoded as u32\n *\n * codec.encode(2 ** 32 + 1);\n * // throws, no encode pattern matches\n * codec.decode(new Uint8Array([0xa0, 0x86, 0x01, 0x00, 0x00]))\n * // throws, no decode pattern matches\n * ```\n *\n * @see {@link getPatternMatchEncoder}\n * @see {@link getPatternMatchDecoder}\n * @see {@link getUnionCodec}\n */\nexport function getPatternMatchCodec<TFrom, TTo extends TFrom = TFrom, TSize extends number = number>(\n    patterns: FixedSizePatternMatchCodecEntry<TFrom, TFrom, TTo, TSize>[],\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function getPatternMatchCodec<TFrom, TTo extends TFrom = TFrom>(\n    patterns: FixedSizePatternMatchCodecEntry<TFrom, TFrom, TTo>[],\n): FixedSizeCodec<TFrom, TTo>;\nexport function getPatternMatchCodec<TFrom, TTo extends TFrom = TFrom>(\n    patterns: VariableSizePatternMatchCodecEntry<TFrom, TFrom, TTo>[],\n): VariableSizeCodec<TFrom, TTo>;\nexport function getPatternMatchCodec<TFrom, TTo extends TFrom = TFrom>(\n    patterns: PatternMatchCodecEntry<TFrom, TFrom, TTo>[],\n): Codec<TFrom, TTo>;\nexport function getPatternMatchCodec<TFrom, TTo extends TFrom = TFrom>(\n    patterns: PatternMatchCodecEntry<TFrom, TFrom, TTo>[],\n): Codec<TFrom, TTo> {\n    return combineCodec(\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        getPatternMatchEncoder(patterns.map(([valuePredicate, , codec]) => [valuePredicate, codec]) as any),\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        getPatternMatchDecoder(patterns.map(([, bytesPredicate, codec]) => [bytesPredicate, codec]) as any),\n    );\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/predicate.ts",
    "content": "import {\n    Codec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { getUnionCodec, getUnionDecoder, getUnionEncoder } from './union';\n\n/**\n * Returns an encoder that selects between two encoders based on a predicate.\n *\n * This encoder uses a boolean predicate function to determine which of two\n * encoders to use for a given value. If the predicate returns `true`, the\n * `ifTrue` encoder is used; otherwise, the `ifFalse` encoder is used.\n *\n * @typeParam TFrom - The type of the value to encode.\n *\n * @param predicate - A function that returns `true` or `false` for a given value.\n * @param ifTrue - The encoder to use when the predicate returns `true`.\n * @param ifFalse - The encoder to use when the predicate returns `false`.\n * @returns An `Encoder` based on the provided encoders.\n *\n * @example\n * Encoding small and large numbers differently.\n * ```ts\n * const encoder = getPredicateEncoder(\n *   (n: number) => n < 256,\n *   getU8Encoder(),\n *   getU32Encoder()\n * );\n *\n * encoder.encode(42);\n * // 0x2a\n * //   └── Small number encoded as u8\n *\n * encoder.encode(1000);\n * // 0xe8030000\n * //   └── Large number encoded as u32\n * ```\n *\n * @see {@link getPredicateCodec}\n */\nexport function getPredicateEncoder<TFrom, TSize extends number>(\n    predicate: (value: TFrom) => boolean,\n    ifTrue: FixedSizeEncoder<TFrom, TSize>,\n    ifFalse: FixedSizeEncoder<TFrom, TSize>,\n): FixedSizeEncoder<TFrom, TSize>;\nexport function getPredicateEncoder<TFrom>(\n    predicate: (value: TFrom) => boolean,\n    ifTrue: FixedSizeEncoder<TFrom>,\n    ifFalse: FixedSizeEncoder<TFrom>,\n): FixedSizeEncoder<TFrom>;\nexport function getPredicateEncoder<TFrom>(\n    predicate: (value: TFrom) => boolean,\n    ifTrue: VariableSizeEncoder<TFrom>,\n    ifFalse: VariableSizeEncoder<TFrom>,\n): VariableSizeEncoder<TFrom>;\nexport function getPredicateEncoder<TFrom>(\n    predicate: (value: TFrom) => boolean,\n    ifTrue: Encoder<TFrom>,\n    ifFalse: Encoder<TFrom>,\n): Encoder<TFrom>;\nexport function getPredicateEncoder<TFrom>(\n    predicate: (value: TFrom) => boolean,\n    ifTrue: Encoder<TFrom>,\n    ifFalse: Encoder<TFrom>,\n): Encoder<TFrom> {\n    return getUnionEncoder([ifTrue, ifFalse], (value: TFrom) => (predicate(value) ? 0 : 1));\n}\n\n/**\n * Returns a decoder that selects between two decoders based on a predicate.\n *\n * This decoder uses a boolean predicate function on the raw bytes to determine\n * which of two decoders to use. If the predicate returns `true`, the `ifTrue`\n * decoder is used; otherwise, the `ifFalse` decoder is used.\n *\n * @typeParam TTo - The type of the value to decode.\n *\n * @param predicate - A function that returns `true` or `false` for a given byte array.\n * @param ifTrue - The decoder to use when the predicate returns `true`.\n * @param ifFalse - The decoder to use when the predicate returns `false`.\n * @returns A `Decoder` based on the provided decoders.\n *\n * @example\n * Decoding small and large numbers based on byte length.\n * ```ts\n * const decoder = getPredicateDecoder(\n *   bytes => bytes.length === 1,\n *   getU8Decoder(),\n *   getU32Decoder()\n * );\n *\n * decoder.decode(new Uint8Array([0x2a]));\n * // 42 (decoded as u8)\n *\n * decoder.decode(new Uint8Array([0xe8, 0x03, 0x00, 0x00]));\n * // 1000 (decoded as u32)\n * ```\n *\n * @see {@link getPredicateCodec}\n */\nexport function getPredicateDecoder<TTo, TSize extends number>(\n    predicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: FixedSizeDecoder<TTo, TSize>,\n    ifFalse: FixedSizeDecoder<TTo, TSize>,\n): FixedSizeDecoder<TTo, TSize>;\nexport function getPredicateDecoder<TTo>(\n    predicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: FixedSizeDecoder<TTo>,\n    ifFalse: FixedSizeDecoder<TTo>,\n): FixedSizeDecoder<TTo>;\nexport function getPredicateDecoder<TTo>(\n    predicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: VariableSizeDecoder<TTo>,\n    ifFalse: VariableSizeDecoder<TTo>,\n): VariableSizeDecoder<TTo>;\nexport function getPredicateDecoder<TTo>(\n    predicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: Decoder<TTo>,\n    ifFalse: Decoder<TTo>,\n): Decoder<TTo>;\nexport function getPredicateDecoder<TTo>(\n    predicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: Decoder<TTo>,\n    ifFalse: Decoder<TTo>,\n): Decoder<TTo> {\n    return getUnionDecoder([ifTrue, ifFalse], (value: ReadonlyUint8Array) => (predicate(value) ? 0 : 1));\n}\n\n/**\n * Returns a codec that selects between two codecs based on predicates.\n *\n * This codec uses boolean predicate functions to determine which of two codecs\n * to use for encoding and decoding. If the encoding predicate returns `true`\n * for a value, the `ifTrue` codec is used to encode it; otherwise `ifFalse`.\n * Similarly, if the decoding predicate returns `true` for the bytes, the\n * `ifTrue` codec is used to decode them.\n *\n * @typeParam TFrom - The type of the value to encode.\n * @typeParam TTo - The type of the value to decode.\n *\n * @param encodePredicate - A function that returns `true` or `false` for a given value.\n * @param decodePredicate - A function that returns `true` or `false` for a given byte array.\n * @param ifTrue - The codec to use when the respective predicate returns `true`.\n * @param ifFalse - The codec to use when the respective predicate returns `false`.\n * @returns A `Codec` based on the provided codecs.\n *\n * @example\n * Encoding and decoding small and large numbers differently.\n * ```ts\n * const codec = getPredicateCodec(\n *   (n: number) => n < 256,\n *   bytes => bytes.length === 1,\n *   getU8Codec(),\n *   getU32Codec()\n * );\n *\n * const smallBytes = codec.encode(42);\n * // 0x2a (encoded as u8)\n *\n * const largeBytes = codec.encode(1000);\n * // 0xe8030000 (encoded as u32)\n *\n * codec.decode(smallBytes); // 42\n * codec.decode(largeBytes); // 1000\n * ```\n *\n * @see {@link getPredicateEncoder}\n * @see {@link getPredicateDecoder}\n */\nexport function getPredicateCodec<TFrom, TTo extends TFrom, TSize extends number>(\n    encodePredicate: (value: TFrom) => boolean,\n    decodePredicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: FixedSizeCodec<TFrom, TTo, TSize>,\n    ifFalse: FixedSizeCodec<TFrom, TTo, TSize>,\n): FixedSizeCodec<TFrom, TTo, TSize>;\nexport function getPredicateCodec<TFrom, TTo extends TFrom>(\n    encodePredicate: (value: TFrom) => boolean,\n    decodePredicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: FixedSizeCodec<TFrom, TTo>,\n    ifFalse: FixedSizeCodec<TFrom, TTo>,\n): FixedSizeCodec<TFrom, TTo>;\nexport function getPredicateCodec<TFrom, TTo extends TFrom>(\n    encodePredicate: (value: TFrom) => boolean,\n    decodePredicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: VariableSizeCodec<TFrom, TTo>,\n    ifFalse: VariableSizeCodec<TFrom, TTo>,\n): VariableSizeCodec<TFrom, TTo>;\nexport function getPredicateCodec<TFrom, TTo extends TFrom>(\n    encodePredicate: (value: TFrom) => boolean,\n    decodePredicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: Codec<TFrom, TTo>,\n    ifFalse: Codec<TFrom, TTo>,\n): Codec<TFrom, TTo>;\nexport function getPredicateCodec<TFrom, TTo extends TFrom>(\n    encodePredicate: (value: TFrom) => boolean,\n    decodePredicate: (value: ReadonlyUint8Array) => boolean,\n    ifTrue: Codec<TFrom, TTo>,\n    ifFalse: Codec<TFrom, TTo>,\n): Codec<TFrom, TTo> {\n    return getUnionCodec(\n        [ifTrue, ifFalse],\n        (value: TFrom) => (encodePredicate(value) ? 0 : 1),\n        (value: ReadonlyUint8Array) => (decodePredicate(value) ? 0 : 1),\n    );\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/set.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\n\nimport { ArrayLikeCodecSize, getArrayDecoder, getArrayEncoder } from './array';\n\n/**\n * Defines the configuration options for set codecs.\n *\n * This configuration allows specifying how the size of the set is encoded.\n * The `size` option can be:\n *\n * - A {@link NumberCodec}, {@link NumberEncoder}, or {@link NumberDecoder} to store the size as a prefix.\n * - A fixed number of items, enforcing a strict length.\n * - The string `'remainder'` to infer the set size from the remaining bytes (only for fixed-size items).\n *\n * @typeParam TPrefix - The type used for encoding the size of the set.\n */\nexport type SetCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * The size encoding strategy for the set.\n     * @defaultValue Uses a `u32` prefix.\n     */\n    size?: ArrayLikeCodecSize<TPrefix>;\n};\n\n/**\n * Returns an encoder for sets of items.\n *\n * This encoder serializes `Set<T>` values by encoding each item using the provided item encoder.\n * The number of items is stored as a prefix using a `u32` codec by default.\n *\n * For more details, see {@link getSetCodec}.\n *\n * @typeParam TFrom - The type of the items in the set before encoding.\n *\n * @param item - The encoder to use for each set item.\n * @param config - Optional configuration specifying the size strategy.\n * @returns An `Encoder<Set<TFrom>>` for encoding sets of items.\n *\n * @example\n * Encoding a set of `u8` numbers.\n * ```ts\n * const encoder = getSetEncoder(getU8Encoder());\n * const bytes = encoder.encode(new Set([1, 2, 3]));\n * // 0x03000000010203\n * //   |       └-- 3 items of 1 byte each.\n * //   └-- 4-byte prefix indicating 3 items.\n * ```\n *\n * @see {@link getSetCodec}\n */\nexport function getSetEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config: SetCodecConfig<NumberEncoder> & { size: 0 },\n): FixedSizeEncoder<Set<TFrom>, 0>;\nexport function getSetEncoder<TFrom>(\n    item: FixedSizeEncoder<TFrom>,\n    config: SetCodecConfig<NumberEncoder> & { size: number },\n): FixedSizeEncoder<Set<TFrom>>;\nexport function getSetEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config?: SetCodecConfig<NumberEncoder>,\n): VariableSizeEncoder<Set<TFrom>>;\nexport function getSetEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config: SetCodecConfig<NumberEncoder> = {},\n): Encoder<Set<TFrom>> {\n    return transformEncoder(getArrayEncoder(item, config as object), (set: Set<TFrom>): TFrom[] => [...set]);\n}\n\n/**\n * Returns a decoder for sets of items.\n *\n * This decoder deserializes a `Set<T>` from a byte array by decoding each item using the provided item decoder.\n * The number of items is determined by a `u32` size prefix by default.\n *\n * For more details, see {@link getSetCodec}.\n *\n * @typeParam TTo - The type of the items in the set after decoding.\n *\n * @param item - The decoder to use for each set item.\n * @param config - Optional configuration specifying the size strategy.\n * @returns A `Decoder<Set<TTo>>` for decoding sets of items.\n *\n * @example\n * Decoding a set of `u8` numbers.\n * ```ts\n * const decoder = getSetDecoder(getU8Decoder());\n * const value = decoder.decode(new Uint8Array([0x03, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03]));\n * // new Set([1, 2, 3])\n * ```\n *\n * @see {@link getSetCodec}\n */\nexport function getSetDecoder<TTo>(\n    item: Decoder<TTo>,\n    config: SetCodecConfig<NumberDecoder> & { size: 0 },\n): FixedSizeDecoder<Set<TTo>, 0>;\nexport function getSetDecoder<TTo>(\n    item: FixedSizeDecoder<TTo>,\n    config: SetCodecConfig<NumberDecoder> & { size: number },\n): FixedSizeDecoder<Set<TTo>>;\nexport function getSetDecoder<TTo>(\n    item: Decoder<TTo>,\n    config?: SetCodecConfig<NumberDecoder>,\n): VariableSizeDecoder<Set<TTo>>;\nexport function getSetDecoder<TTo>(item: Decoder<TTo>, config: SetCodecConfig<NumberDecoder> = {}): Decoder<Set<TTo>> {\n    return transformDecoder(getArrayDecoder(item, config as object), (entries: TTo[]): Set<TTo> => new Set(entries));\n}\n\n/**\n * Returns a codec for encoding and decoding sets of items.\n *\n * This codec serializes `Set<T>` values by encoding each item using the provided item codec.\n * The number of items is stored as a prefix using a `u32` codec by default.\n *\n * @typeParam TFrom - The type of the items in the set before encoding.\n * @typeParam TTo - The type of the items in the set after decoding.\n *\n * @param item - The codec to use for each set item.\n * @param config - Optional configuration specifying the size strategy.\n * @returns A `Codec<Set<TFrom>, Set<TTo>>` for encoding and decoding sets.\n *\n * @example\n * Encoding and decoding a set of `u8` numbers.\n * ```ts\n * const codec = getSetCodec(getU8Codec());\n * const bytes = codec.encode(new Set([1, 2, 3]));\n * // 0x03000000010203\n * //   |       └-- 3 items of 1 byte each.\n * //   └-- 4-byte prefix indicating 3 items.\n *\n * const value = codec.decode(bytes);\n * // new Set([1, 2, 3])\n * ```\n *\n * @example\n * Using a `u16` prefix for size.\n * ```ts\n * const codec = getSetCodec(getU8Codec(), { size: getU16Codec() });\n * const bytes = codec.encode(new Set([1, 2, 3]));\n * // 0x0300010203\n * //   |   └-- 3 items of 1 byte each.\n * //   └-- 2-byte prefix indicating 3 items.\n * ```\n *\n * @example\n * Using a fixed-size set.\n * ```ts\n * const codec = getSetCodec(getU8Codec(), { size: 3 });\n * const bytes = codec.encode(new Set([1, 2, 3]));\n * // 0x010203\n * //   └-- Exactly 3 items of 1 byte each.\n * ```\n *\n * @example\n * Using remainder to infer set size.\n * ```ts\n * const codec = getSetCodec(getU8Codec(), { size: 'remainder' });\n * const bytes = codec.encode(new Set([1, 2, 3]));\n * // 0x010203\n * //   └-- 3 items of 1 byte each. The size is inferred from the remaining bytes.\n * ```\n *\n * @remarks\n * Separate {@link getSetEncoder} and {@link getSetDecoder} functions are available.\n *\n * ```ts\n * const bytes = getSetEncoder(getU8Encoder()).encode(new Set([1, 2, 3]));\n * const value = getSetDecoder(getU8Decoder()).decode(bytes);\n * ```\n *\n * @see {@link getSetEncoder}\n * @see {@link getSetDecoder}\n */\nexport function getSetCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config: SetCodecConfig<NumberCodec> & { size: 0 },\n): FixedSizeCodec<Set<TFrom>, Set<TTo>, 0>;\nexport function getSetCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: FixedSizeCodec<TFrom, TTo>,\n    config: SetCodecConfig<NumberCodec> & { size: number },\n): FixedSizeCodec<Set<TFrom>, Set<TTo>>;\nexport function getSetCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config?: SetCodecConfig<NumberCodec>,\n): VariableSizeCodec<Set<TFrom>, Set<TTo>>;\nexport function getSetCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config: SetCodecConfig<NumberCodec> = {},\n): Codec<Set<TFrom>, Set<TTo>> {\n    return combineCodec(getSetEncoder(item, config as object), getSetDecoder(item, config as object));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/struct.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n    Codec,\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    getEncodedSize,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { DrainOuterGeneric, getFixedSize, getMaxSize, sumCodecSizes } from './utils';\n\n/**\n * Represents a collection of named fields used in struct codecs.\n *\n * Each field is defined as a tuple containing:\n * - A string key representing the field name.\n * - A codec used to encode and decode the field's value.\n *\n * @typeParam T - The codec type used for each field.\n */\ntype Fields<T> = readonly (readonly [string, T])[];\n\ntype ArrayIndices<T extends readonly unknown[]> = Exclude<Partial<T>['length'], T['length']> & number;\n\n/**\n * Infers the TypeScript type for an object that can be encoded using a struct codec.\n *\n * This type maps the provided field encoders to their corresponding values.\n *\n * @typeParam TFields - The fields of the struct, each paired with an encoder.\n */\ntype GetEncoderTypeFromFields<TFields extends Fields<Encoder<any>>> = DrainOuterGeneric<{\n    [I in ArrayIndices<TFields> as TFields[I][0]]: TFields[I][1] extends Encoder<infer TFrom> ? TFrom : never;\n}>;\n\n/**\n * Infers the TypeScript type for an object that can be decoded using a struct codec.\n *\n * This type maps the provided field decoders to their corresponding values.\n *\n * @typeParam TFields - The fields of the struct, each paired with a decoder.\n */\ntype GetDecoderTypeFromFields<TFields extends Fields<Decoder<any>>> = DrainOuterGeneric<{\n    [I in ArrayIndices<TFields> as TFields[I][0]]: TFields[I][1] extends Decoder<infer TTo> ? TTo : never;\n}>;\n\n/**\n * Returns an encoder for custom objects.\n *\n * This encoder serializes an object by encoding its fields sequentially,\n * using the provided field encoders.\n *\n * For more details, see {@link getStructCodec}.\n *\n * @typeParam TFields - The fields of the struct, each paired with an encoder.\n *\n * @param fields - The name and encoder of each field.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding custom objects.\n *\n * @example\n * Encoding a custom struct.\n * ```ts\n * const encoder = getStructEncoder([\n *   ['name', fixCodecSize(getUtf8Encoder(), 5)],\n *   ['age', getU8Encoder()]\n * ]);\n *\n * const bytes = encoder.encode({ name: 'Alice', age: 42 });\n * // 0x416c6963652a\n * //   |         └── Age (42)\n * //   └── Name (\"Alice\")\n * ```\n *\n * @see {@link getStructCodec}\n */\nexport function getStructEncoder<const TFields extends Fields<FixedSizeEncoder<any>>>(\n    fields: TFields,\n): FixedSizeEncoder<GetEncoderTypeFromFields<TFields>>;\nexport function getStructEncoder<const TFields extends Fields<Encoder<any>>>(\n    fields: TFields,\n): VariableSizeEncoder<GetEncoderTypeFromFields<TFields>>;\nexport function getStructEncoder<const TFields extends Fields<Encoder<any>>>(\n    fields: TFields,\n): Encoder<GetEncoderTypeFromFields<TFields>> {\n    type TFrom = GetEncoderTypeFromFields<TFields>;\n    const fieldCodecs = fields.map(([, codec]) => codec);\n    const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));\n    const maxSize = sumCodecSizes(fieldCodecs.map(getMaxSize)) ?? undefined;\n\n    return createEncoder({\n        ...(fixedSize === null\n            ? {\n                  getSizeFromValue: (value: TFrom) =>\n                      fields\n                          .map(([key, codec]) => getEncodedSize(value[key as keyof TFrom], codec))\n                          .reduce((all, one) => all + one, 0),\n                  maxSize,\n              }\n            : { fixedSize }),\n        write: (struct: TFrom, bytes, offset) => {\n            fields.forEach(([key, codec]) => {\n                offset = codec.write(struct[key as keyof TFrom], bytes, offset);\n            });\n            return offset;\n        },\n    });\n}\n\n/**\n * Returns a decoder for custom objects.\n *\n * This decoder deserializes an object by decoding its fields sequentially,\n * using the provided field decoders.\n *\n * For more details, see {@link getStructCodec}.\n *\n * @typeParam TFields - The fields of the struct, each paired with a decoder.\n *\n * @param fields - The name and decoder of each field.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding custom objects.\n *\n * @example\n * Decoding a custom struct.\n * ```ts\n * const decoder = getStructDecoder([\n *   ['name', fixCodecSize(getUtf8Decoder(), 5)],\n *   ['age', getU8Decoder()]\n * ]);\n *\n * const struct = decoder.decode(new Uint8Array([\n *   0x41,0x6c,0x69,0x63,0x65,0x2a\n * ]));\n * // { name: 'Alice', age: 42 }\n * ```\n *\n * @see {@link getStructCodec}\n */\nexport function getStructDecoder<const TFields extends Fields<FixedSizeDecoder<any>>>(\n    fields: TFields,\n): FixedSizeDecoder<GetDecoderTypeFromFields<TFields>>;\nexport function getStructDecoder<const TFields extends Fields<Decoder<any>>>(\n    fields: TFields,\n): VariableSizeDecoder<GetDecoderTypeFromFields<TFields>>;\nexport function getStructDecoder<const TFields extends Fields<Decoder<any>>>(\n    fields: TFields,\n): Decoder<GetDecoderTypeFromFields<TFields>> {\n    type TTo = GetDecoderTypeFromFields<TFields>;\n    const fieldCodecs = fields.map(([, codec]) => codec);\n    const fixedSize = sumCodecSizes(fieldCodecs.map(getFixedSize));\n    const maxSize = sumCodecSizes(fieldCodecs.map(getMaxSize)) ?? undefined;\n\n    return createDecoder({\n        ...(fixedSize === null ? { maxSize } : { fixedSize }),\n        read: (bytes: ReadonlyUint8Array | Uint8Array, offset) => {\n            const struct = {} as TTo;\n            fields.forEach(([key, codec]) => {\n                const [value, newOffset] = codec.read(bytes, offset);\n                offset = newOffset;\n                struct[key as keyof TTo] = value;\n            });\n            return [struct, offset];\n        },\n    });\n}\n\n/**\n * Returns a codec for encoding and decoding custom objects.\n *\n * This codec serializes objects by encoding and decoding each field sequentially.\n *\n * @typeParam TFields - The fields of the struct, each paired with a codec.\n *\n * @param fields - The name and codec of each field.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding custom objects.\n *\n * @example\n * Encoding and decoding a custom struct.\n * ```ts\n * const codec = getStructCodec([\n *   ['name', fixCodecSize(getUtf8Codec(), 5)],\n *   ['age', getU8Codec()]\n * ]);\n *\n * const bytes = codec.encode({ name: 'Alice', age: 42 });\n * // 0x416c6963652a\n * //   |         └── Age (42)\n * //   └── Name (\"Alice\")\n *\n * const struct = codec.decode(bytes);\n * // { name: 'Alice', age: 42 }\n * ```\n *\n * @remarks\n * Separate {@link getStructEncoder} and {@link getStructDecoder} functions are available.\n *\n * ```ts\n * const bytes = getStructEncoder([\n *   ['name', fixCodecSize(getUtf8Encoder(), 5)],\n *   ['age', getU8Encoder()]\n * ]).encode({ name: 'Alice', age: 42 });\n *\n * const struct = getStructDecoder([\n *   ['name', fixCodecSize(getUtf8Decoder(), 5)],\n *   ['age', getU8Decoder()]\n * ]).decode(bytes);\n * ```\n *\n * @see {@link getStructEncoder}\n * @see {@link getStructDecoder}\n */\nexport function getStructCodec<const TFields extends Fields<FixedSizeCodec<any>>>(\n    fields: TFields,\n): FixedSizeCodec<\n    GetEncoderTypeFromFields<TFields>,\n    GetDecoderTypeFromFields<TFields> & GetEncoderTypeFromFields<TFields>\n>;\nexport function getStructCodec<const TFields extends Fields<Codec<any>>>(\n    fields: TFields,\n): VariableSizeCodec<\n    GetEncoderTypeFromFields<TFields>,\n    GetDecoderTypeFromFields<TFields> & GetEncoderTypeFromFields<TFields>\n>;\nexport function getStructCodec<const TFields extends Fields<Codec<any>>>(\n    fields: TFields,\n): Codec<GetEncoderTypeFromFields<TFields>, GetDecoderTypeFromFields<TFields> & GetEncoderTypeFromFields<TFields>> {\n    return combineCodec(\n        getStructEncoder(fields),\n        getStructDecoder(fields) as Decoder<GetDecoderTypeFromFields<TFields> & GetEncoderTypeFromFields<TFields>>,\n    );\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/tuple.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n    Codec,\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    getEncodedSize,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidNumberOfItemsForCodec } from './assertions';\nimport { DrainOuterGeneric, getFixedSize, getMaxSize, sumCodecSizes } from './utils';\n\n/**\n * Infers the TypeScript type for a tuple that can be encoded using a tuple codec.\n *\n * This type maps each provided item encoder to its corresponding value type.\n *\n * @typeParam TItems - An array of encoders, each corresponding to a tuple element.\n */\ntype GetEncoderTypeFromItems<TItems extends readonly Encoder<any>[]> = DrainOuterGeneric<{\n    [I in keyof TItems]: TItems[I] extends Encoder<infer TFrom> ? TFrom : never;\n}>;\n\n/**\n * Infers the TypeScript type for a tuple that can be decoded using a tuple codec.\n *\n * This type maps each provided item decoder to its corresponding value type.\n *\n * @typeParam TItems - An array of decoders, each corresponding to a tuple element.\n */\ntype GetDecoderTypeFromItems<TItems extends readonly Decoder<any>[]> = DrainOuterGeneric<{\n    [I in keyof TItems]: TItems[I] extends Decoder<infer TTo> ? TTo : never;\n}>;\n\n/**\n * Defines the configuration options for tuple codecs.\n */\nexport type TupleCodecConfig = {\n    /**\n     * An optional description for the codec, that will be used in error messages.\n     */\n    description?: string;\n};\n\n/**\n * Returns an encoder for tuples.\n *\n * This encoder serializes a fixed-size array (tuple) by encoding its items\n * sequentially using the provided item encoders.\n *\n * For more details, see {@link getTupleCodec}.\n *\n * @typeParam TItems - An array of encoders, each corresponding to a tuple element.\n *\n * @param items - The encoders for each item in the tuple.\n * @param config - Optional configuration for the description.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding tuples.\n *\n * @example\n * Encoding a tuple with 2 items.\n * ```ts\n * const encoder = getTupleEncoder([fixCodecSize(getUtf8Encoder(), 5), getU8Encoder()]);\n *\n * const bytes = encoder.encode(['Alice', 42]);\n * // 0x416c6963652a\n * //   |         └── Second item (42)\n * //   └── First item (\"Alice\")\n * ```\n *\n * @see {@link getTupleCodec}\n */\nexport function getTupleEncoder<const TItems extends readonly FixedSizeEncoder<any>[]>(\n    items: TItems,\n    config?: TupleCodecConfig,\n): FixedSizeEncoder<GetEncoderTypeFromItems<TItems>>;\nexport function getTupleEncoder<const TItems extends readonly Encoder<any>[]>(\n    items: TItems,\n    config?: TupleCodecConfig,\n): VariableSizeEncoder<GetEncoderTypeFromItems<TItems>>;\nexport function getTupleEncoder<const TItems extends readonly Encoder<any>[]>(\n    items: TItems,\n    config?: TupleCodecConfig,\n): Encoder<GetEncoderTypeFromItems<TItems>> {\n    type TFrom = GetEncoderTypeFromItems<TItems>;\n    const fixedSize = sumCodecSizes(items.map(getFixedSize));\n    const maxSize = sumCodecSizes(items.map(getMaxSize)) ?? undefined;\n\n    return createEncoder({\n        ...(fixedSize === null\n            ? {\n                  getSizeFromValue: (value: TFrom) =>\n                      items.map((item, index) => getEncodedSize(value[index], item)).reduce((all, one) => all + one, 0),\n                  maxSize,\n              }\n            : { fixedSize }),\n        write: (value: TFrom, bytes, offset) => {\n            assertValidNumberOfItemsForCodec(config?.description ?? 'tuple', items.length, value.length);\n            items.forEach((item, index) => {\n                offset = item.write(value[index], bytes, offset);\n            });\n            return offset;\n        },\n    });\n}\n\n/**\n * Returns a decoder for tuples.\n *\n * This decoder deserializes a fixed-size array (tuple) by decoding its items\n * sequentially using the provided item decoders.\n *\n * For more details, see {@link getTupleCodec}.\n *\n * @typeParam TItems - An array of decoders, each corresponding to a tuple element.\n *\n * @param items - The decoders for each item in the tuple.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding tuples.\n *\n * @example\n * Decoding a tuple with 2 items.\n * ```ts\n * const decoder = getTupleDecoder([fixCodecSize(getUtf8Decoder(), 5), getU8Decoder()]);\n *\n * const tuple = decoder.decode(new Uint8Array([\n *   0x41,0x6c,0x69,0x63,0x65,0x2a\n * ]));\n * // ['Alice', 42]\n * ```\n *\n * @see {@link getTupleCodec}\n */\nexport function getTupleDecoder<const TItems extends readonly FixedSizeDecoder<any>[]>(\n    items: TItems,\n): FixedSizeDecoder<GetDecoderTypeFromItems<TItems>>;\nexport function getTupleDecoder<const TItems extends readonly Decoder<any>[]>(\n    items: TItems,\n): VariableSizeDecoder<GetDecoderTypeFromItems<TItems>>;\nexport function getTupleDecoder<const TItems extends readonly Decoder<any>[]>(\n    items: TItems,\n): Decoder<GetDecoderTypeFromItems<TItems>> {\n    type TTo = GetDecoderTypeFromItems<TItems>;\n    const fixedSize = sumCodecSizes(items.map(getFixedSize));\n    const maxSize = sumCodecSizes(items.map(getMaxSize)) ?? undefined;\n\n    return createDecoder({\n        ...(fixedSize === null ? { maxSize } : { fixedSize }),\n        read: (bytes: ReadonlyUint8Array | Uint8Array, offset) => {\n            const values = [] as Array<any> & TTo;\n            items.forEach(item => {\n                const [newValue, newOffset] = item.read(bytes, offset);\n                values.push(newValue);\n                offset = newOffset;\n            });\n            return [values, offset];\n        },\n    });\n}\n\n/**\n * Returns a codec for encoding and decoding tuples.\n *\n * This codec serializes tuples by encoding and decoding each item sequentially.\n *\n * Unlike the {@link getArrayCodec} codec, each item in the tuple has its own codec\n * and, therefore, can be of a different type.\n *\n * @typeParam TItems - An array of codecs, each corresponding to a tuple element.\n *\n * @param items - The codecs for each item in the tuple.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding tuples.\n *\n * @example\n * Encoding and decoding a tuple with 2 items.\n * ```ts\n * const codec = getTupleCodec([fixCodecSize(getUtf8Codec(), 5), getU8Codec()]);\n *\n * const bytes = codec.encode(['Alice', 42]);\n * // 0x416c6963652a\n * //   |         └── Second item (42)\n * //   └── First item (\"Alice\")\n *\n * const tuple = codec.decode(bytes);\n * // ['Alice', 42]\n * ```\n *\n * @remarks\n * Separate {@link getTupleEncoder} and {@link getTupleDecoder} functions are available.\n *\n * ```ts\n * const bytes = getTupleEncoder([fixCodecSize(getUtf8Encoder(), 5), getU8Encoder()])\n *   .encode(['Alice', 42]);\n *\n * const tuple = getTupleDecoder([fixCodecSize(getUtf8Decoder(), 5), getU8Decoder()])\n *   .decode(bytes);\n * ```\n *\n * @see {@link getTupleEncoder}\n * @see {@link getTupleDecoder}\n */\nexport function getTupleCodec<const TItems extends readonly FixedSizeCodec<any>[]>(\n    items: TItems,\n    config?: TupleCodecConfig,\n): FixedSizeCodec<GetEncoderTypeFromItems<TItems>, GetDecoderTypeFromItems<TItems> & GetEncoderTypeFromItems<TItems>>;\nexport function getTupleCodec<const TItems extends readonly Codec<any>[]>(\n    items: TItems,\n    config?: TupleCodecConfig,\n): VariableSizeCodec<\n    GetEncoderTypeFromItems<TItems>,\n    GetDecoderTypeFromItems<TItems> & GetEncoderTypeFromItems<TItems>\n>;\nexport function getTupleCodec<const TItems extends readonly Codec<any>[]>(\n    items: TItems,\n    config?: TupleCodecConfig,\n): Codec<GetEncoderTypeFromItems<TItems>, GetDecoderTypeFromItems<TItems> & GetEncoderTypeFromItems<TItems>> {\n    return combineCodec(\n        getTupleEncoder(items, config),\n        getTupleDecoder(items) as Decoder<GetDecoderTypeFromItems<TItems> & GetEncoderTypeFromItems<TItems>>,\n    );\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/union.ts",
    "content": "/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n    Codec,\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    getEncodedSize,\n    isFixedSize,\n    Offset,\n    ReadonlyUint8Array,\n} from '@solana/codecs-core';\nimport { SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE, SolanaError } from '@solana/errors';\n\nimport { DrainOuterGeneric, getMaxSize, maxCodecSizes } from './utils';\n\n/**\n * Infers the TypeScript type for values that can be encoded using a union codec.\n *\n * This type maps the provided variant encoders to their corresponding value types.\n *\n * @typeParam TVariants - An array of encoders, each corresponding to a union variant.\n */\ntype GetEncoderTypeFromVariants<TVariants extends readonly Encoder<any>[]> = DrainOuterGeneric<{\n    [I in keyof TVariants]: TVariants[I] extends Encoder<infer TFrom> ? TFrom : never;\n}>[number];\n\n/**\n * Infers the TypeScript type for values that can be decoded using a union codec.\n *\n * This type maps the provided variant decoders to their corresponding value types.\n *\n * @typeParam TVariants - An array of decoders, each corresponding to a union variant.\n */\ntype GetDecoderTypeFromVariants<TVariants extends readonly Decoder<any>[]> = DrainOuterGeneric<{\n    [I in keyof TVariants]: TVariants[I] extends Decoder<infer TFrom> ? TFrom : never;\n}>[number];\n\ntype UnionEncoder<TVariants extends readonly Encoder<unknown>[]> = TVariants extends readonly FixedSizeEncoder<any>[]\n    ? FixedSizeEncoder<GetEncoderTypeFromVariants<TVariants>>\n    : Encoder<GetEncoderTypeFromVariants<TVariants>>;\n\ntype UnionDecoder<TVariants extends readonly Decoder<unknown>[]> = TVariants extends readonly FixedSizeDecoder<any>[]\n    ? FixedSizeDecoder<GetDecoderTypeFromVariants<TVariants>>\n    : Decoder<GetDecoderTypeFromVariants<TVariants>>;\n\ntype UnionCodec<TVariants extends readonly Codec<unknown>[]> = TVariants extends readonly FixedSizeCodec<any>[]\n    ? FixedSizeCodec<\n          GetEncoderTypeFromVariants<TVariants>,\n          GetDecoderTypeFromVariants<TVariants> & GetEncoderTypeFromVariants<TVariants>\n      >\n    : Codec<\n          GetEncoderTypeFromVariants<TVariants>,\n          GetDecoderTypeFromVariants<TVariants> & GetEncoderTypeFromVariants<TVariants>\n      >;\n\n/**\n * Returns an encoder for union types.\n *\n * This encoder serializes values by selecting the correct variant encoder\n * based on the `getIndexFromValue` function.\n *\n * Unlike other codecs, this encoder does not store the variant index.\n * It is the user's responsibility to manage discriminators separately.\n *\n * For more details, see {@link getUnionCodec}.\n *\n * @typeParam TVariants - An array of encoders, each corresponding to a union variant.\n *\n * @param variants - The encoders for each variant of the union.\n * @param getIndexFromValue - A function that determines the variant index from the provided value.\n * @returns An `Encoder` for encoding union values.\n *\n * @example\n * Encoding a union of numbers and booleans.\n * ```ts\n * const encoder = getUnionEncoder(\n *   [getU16Encoder(), getBooleanEncoder()],\n *   value => (typeof value === 'number' ? 0 : 1)\n * );\n *\n * encoder.encode(42);\n * // 0x2a00\n * //   └── Encoded number (42) as `u16`\n *\n * encoder.encode(true);\n * // 0x01\n * //   └── Encoded boolean (`true`) as `u8`\n * ```\n *\n * @see {@link getUnionCodec}\n */\nexport function getUnionEncoder<const TVariants extends readonly Encoder<any>[]>(\n    variants: TVariants,\n    getIndexFromValue: (value: GetEncoderTypeFromVariants<TVariants>) => number,\n): UnionEncoder<TVariants> {\n    type TFrom = GetEncoderTypeFromVariants<TVariants>;\n    const fixedSize = getUnionFixedSize(variants);\n    const write: Encoder<TFrom>['write'] = (variant, bytes, offset) => {\n        const index = getIndexFromValue(variant);\n        assertValidVariantIndex(variants, index);\n        return variants[index].write(variant, bytes, offset);\n    };\n\n    if (fixedSize !== null) {\n        return createEncoder({ fixedSize, write }) as UnionEncoder<TVariants>;\n    }\n\n    const maxSize = getUnionMaxSize(variants);\n    return createEncoder({\n        ...(maxSize !== null ? { maxSize } : {}),\n        getSizeFromValue: variant => {\n            const index = getIndexFromValue(variant);\n            assertValidVariantIndex(variants, index);\n            return getEncodedSize(variant, variants[index]);\n        },\n        write,\n    }) as UnionEncoder<TVariants>;\n}\n\n/**\n * Returns a decoder for union types.\n *\n * This decoder deserializes values by selecting the correct variant decoder\n * based on the `getIndexFromBytes` function.\n *\n * Unlike other codecs, this decoder does not assume a stored discriminator.\n * It is the user's responsibility to manage discriminators separately.\n *\n * For more details, see {@link getUnionCodec}.\n *\n * @typeParam TVariants - An array of decoders, each corresponding to a union variant.\n *\n * @param variants - The decoders for each variant of the union.\n * @param getIndexFromBytes - A function that determines the variant index from the byte array.\n * @returns A `Decoder` for decoding union values.\n *\n * @example\n * Decoding a union of numbers and booleans.\n * ```ts\n * const decoder = getUnionDecoder(\n *   [getU16Decoder(), getBooleanDecoder()],\n *   (bytes, offset) => (bytes.length - offset > 1 ? 0 : 1)\n * );\n *\n * decoder.decode(new Uint8Array([0x2a, 0x00])); // 42\n * decoder.decode(new Uint8Array([0x01]));       // true\n * // Type is inferred as `number | boolean`\n * ```\n *\n * @see {@link getUnionCodec}\n */\nexport function getUnionDecoder<const TVariants extends readonly Decoder<any>[]>(\n    variants: TVariants,\n    getIndexFromBytes: (bytes: ReadonlyUint8Array, offset: Offset) => number,\n): UnionDecoder<TVariants> {\n    type TTo = GetDecoderTypeFromVariants<TVariants>;\n    const fixedSize = getUnionFixedSize(variants);\n    const read: Decoder<TTo>['read'] = (bytes, offset) => {\n        const index = getIndexFromBytes(bytes, offset);\n        assertValidVariantIndex(variants, index);\n        return variants[index].read(bytes, offset);\n    };\n\n    if (fixedSize !== null) {\n        return createDecoder({ fixedSize, read }) as UnionDecoder<TVariants>;\n    }\n\n    const maxSize = getUnionMaxSize(variants);\n    return createDecoder({ ...(maxSize !== null ? { maxSize } : {}), read }) as UnionDecoder<TVariants>;\n}\n\n/**\n * Returns a codec for encoding and decoding union types.\n *\n * This codec serializes and deserializes union values by selecting the correct variant\n * based on the provided index functions.\n *\n * Unlike the {@link getDiscriminatedUnionCodec}, this codec does not assume a stored\n * discriminator and must be used with an explicit mechanism for managing discriminators.\n *\n * @typeParam TVariants - An array of codecs, each corresponding to a union variant.\n *\n * @param variants - The codecs for each variant of the union.\n * @param getIndexFromValue - A function that determines the variant index from the provided value.\n * @param getIndexFromBytes - A function that determines the variant index from the byte array.\n * @returns A `Codec` for encoding and decoding union values.\n *\n * @example\n * Encoding and decoding a union of numbers and booleans.\n * ```ts\n * const codec = getUnionCodec(\n *   [getU16Codec(), getBooleanCodec()],\n *   value => (typeof value === 'number' ? 0 : 1),\n *   (bytes, offset) => (bytes.length - offset > 1 ? 0 : 1)\n * );\n *\n * const bytes1 = codec.encode(42); // 0x2a00\n * const value1: number | boolean = codec.decode(bytes1); // 42\n *\n * const bytes2 = codec.encode(true); // 0x01\n * const value2: number | boolean = codec.decode(bytes2); // true\n * ```\n *\n * @remarks\n * If you need a codec that includes a stored discriminator,\n * consider using {@link getDiscriminatedUnionCodec}.\n *\n * Separate {@link getUnionEncoder} and {@link getUnionDecoder} functions are also available.\n *\n * ```ts\n * const bytes = getUnionEncoder(variantEncoders, getIndexFromValue).encode(42);\n * const value = getUnionDecoder(variantDecoders, getIndexFromBytes).decode(bytes);\n * ```\n *\n * @see {@link getUnionEncoder}\n * @see {@link getUnionDecoder}\n * @see {@link getDiscriminatedUnionCodec}\n */\nexport function getUnionCodec<const TVariants extends readonly Codec<any>[]>(\n    variants: TVariants,\n    getIndexFromValue: (value: GetEncoderTypeFromVariants<TVariants>) => number,\n    getIndexFromBytes: (bytes: ReadonlyUint8Array, offset: Offset) => number,\n): UnionCodec<TVariants> {\n    return combineCodec(\n        getUnionEncoder(variants, getIndexFromValue),\n        getUnionDecoder(variants as readonly Decoder<any>[], getIndexFromBytes) as Decoder<\n            GetDecoderTypeFromVariants<TVariants> & GetEncoderTypeFromVariants<TVariants>\n        >,\n    ) as UnionCodec<TVariants>;\n}\n\nfunction assertValidVariantIndex(variants: readonly unknown[], index: number) {\n    if (typeof variants[index] === 'undefined') {\n        throw new SolanaError(SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE, {\n            maxRange: variants.length - 1,\n            minRange: 0,\n            variant: index,\n        });\n    }\n}\n\nfunction getUnionFixedSize<const TVariants extends readonly (Decoder<any> | Encoder<any>)[]>(variants: TVariants) {\n    if (variants.length === 0) return 0;\n    if (!isFixedSize(variants[0])) return null;\n    const variantSize = variants[0].fixedSize;\n    const sameSizedVariants = variants.every(variant => isFixedSize(variant) && variant.fixedSize === variantSize);\n    return sameSizedVariants ? variantSize : null;\n}\n\nfunction getUnionMaxSize<const TVariants extends readonly (Decoder<any> | Encoder<any>)[]>(variants: TVariants) {\n    return maxCodecSizes(variants.map(variant => getMaxSize(variant)));\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/unit.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    ReadonlyUint8Array,\n} from '@solana/codecs-core';\n\n/**\n * Returns an encoder for `void` values.\n *\n * This encoder writes nothing to the byte array and has a fixed size of 0 bytes.\n * It is useful when working with structures that require a no-op encoder,\n * such as empty variants in {@link getDiscriminatedUnionEncoder}.\n *\n * For more details, see {@link getUnitCodec}.\n *\n * @returns A `FixedSizeEncoder<void, 0>`, representing an empty encoder.\n *\n * @example\n * Encoding a `void` value.\n * ```ts\n * getUnitEncoder().encode(undefined); // Produces an empty byte array.\n * ```\n *\n * @see {@link getUnitCodec}\n */\nexport function getUnitEncoder(): FixedSizeEncoder<void, 0> {\n    return createEncoder({\n        fixedSize: 0,\n        write: (_value, _bytes, offset) => offset,\n    });\n}\n\n/**\n * Returns a decoder for `void` values.\n *\n * This decoder always returns `undefined` and has a fixed size of 0 bytes.\n * It is useful when working with structures that require a no-op decoder,\n * such as empty variants in {@link getDiscriminatedUnionDecoder}.\n *\n * For more details, see {@link getUnitCodec}.\n *\n * @returns A `FixedSizeDecoder<void, 0>`, representing an empty decoder.\n *\n * @example\n * Decoding a `void` value.\n * ```ts\n * getUnitDecoder().decode(anyBytes); // Returns `undefined`.\n * ```\n *\n * @see {@link getUnitCodec}\n */\nexport function getUnitDecoder(): FixedSizeDecoder<void, 0> {\n    return createDecoder({\n        fixedSize: 0,\n        read: (_bytes: ReadonlyUint8Array | Uint8Array, offset) => [undefined, offset],\n    });\n}\n\n/**\n * Returns a codec for `void` values.\n *\n * This codec does nothing when encoding or decoding and has a fixed size of 0 bytes.\n * Namely, it always returns `undefined` when decoding and produces an empty byte array when encoding.\n *\n * This can be useful when working with structures that require a no-op codec,\n * such as empty variants in {@link getDiscriminatedUnionCodec}.\n *\n * @returns A `FixedSizeCodec<void, void, 0>`, representing an empty codec.\n *\n * @example\n * Encoding and decoding a `void` value.\n * ```ts\n * const codec = getUnitCodec();\n *\n * codec.encode(undefined); // Produces an empty byte array.\n * codec.decode(new Uint8Array([])); // Returns `undefined`.\n * ```\n *\n * @example\n * Using unit codecs as empty variants in a discriminated union.\n * ```ts\n * type Message =\n *   | { __kind: 'Enter' }\n *   | { __kind: 'Leave' }\n *   | { __kind: 'Move'; x: number; y: number };\n *\n * const messageCodec = getDiscriminatedUnionCodec([\n *   ['Enter', getUnitCodec()], // <- No-op codec for empty data\n *   ['Leave', getUnitCodec()], // <- No-op codec for empty data\n *   ['Move', getStructCodec([...])]\n * ]);\n * ```\n *\n * @remarks\n * Separate {@link getUnitEncoder} and {@link getUnitDecoder} functions are available.\n *\n * ```ts\n * const bytes = getUnitEncoder().encode();\n * const value = getUnitDecoder().decode(bytes);\n * ```\n *\n * @see {@link getUnitEncoder}\n * @see {@link getUnitDecoder}\n */\nexport function getUnitCodec(): FixedSizeCodec<void, void, 0> {\n    return combineCodec(getUnitEncoder(), getUnitDecoder());\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/src/utils.ts",
    "content": "import { isFixedSize } from '@solana/codecs-core';\n\n/**\n * Functionally, this type helper is equivalent to the identity type — i.e. `type Identity<T> = T`.\n * However, wrapping generic object mappings in this type significantly reduces the number\n * of instantiation expressions processed, which increases TypeScript performance and\n * prevents \"Type instantiation is excessively deep and possibly infinite\" errors.\n *\n * This works because TypeScript doesn't create a new level of nesting when encountering conditional generic types.\n * @see https://github.com/microsoft/TypeScript/issues/34933\n * @see https://github.com/kysely-org/kysely/pull/483\n */\nexport type DrainOuterGeneric<T> = [T] extends [unknown] ? T : never;\n\nexport function maxCodecSizes(sizes: (number | null)[]): number | null {\n    return sizes.reduce(\n        (all, size) => (all === null || size === null ? null : Math.max(all, size)),\n        0 as number | null,\n    );\n}\n\nexport function sumCodecSizes(sizes: (number | null)[]): number | null {\n    return sizes.reduce((all, size) => (all === null || size === null ? null : all + size), 0 as number | null);\n}\n\nexport function getFixedSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n    return isFixedSize(codec) ? codec.fixedSize : null;\n}\n\nexport function getMaxSize(codec: { fixedSize: number } | { maxSize?: number }): number | null {\n    return isFixedSize(codec) ? codec.fixedSize : (codec.maxSize ?? null);\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/codecs-data-structures\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"],\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2019\", \"ES2022.Error\"]\n    }\n}\n"
  },
  {
    "path": "packages/codecs-data-structures/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/codecs-numbers/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/codecs-numbers/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/codecs-numbers/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/codecs-numbers/CHANGELOG.md",
    "content": "# @solana/codecs-numbers\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/codecs-core@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/codecs-core@6.8.0\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.7.0\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/codecs-core@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.5.0\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.3.1\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/codecs-core@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-core@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/codecs-core@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.1\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.0\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/codecs-core@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/codecs-core@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-core@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.3.0\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- [#1116](https://github.com/anza-xyz/kit/pull/1116) [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549) Thanks [@steveluscher](https://github.com/steveluscher)! - Any `SharedArrayBuffer` that gets passed to a crypto operation like `signBytes` or `verifySignature` will now be copied as non-shared. Crypto operations like `sign` and `verify` reject `SharedArrayBuffers` otherwise\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-core@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/codecs-core@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/codecs-core@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-core@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/codecs-core@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.1\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-core@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/codecs-core@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2414](https://github.com/solana-labs/solana-web3.js/pull/2414) [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Used capitalised variant names for `Endian` enum\n\n    This makes the enum more consistent with other enums in the library.\n\n    ```ts\n    // Before.\n    Endian.BIG;\n    Endian.LITTLE;\n\n    // After.\n    Endian.Big;\n    Endian.Little;\n    ```\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-core@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2414](https://github.com/solana-labs/solana-web3.js/pull/2414) [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Used capitalised variant names for `Endian` enum\n\n    This makes the enum more consistent with other enums in the library.\n\n    ```ts\n    // Before.\n    Endian.BIG;\n    Endian.LITTLE;\n\n    // After.\n    Endian.Big;\n    Endian.Little;\n    ```\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/codecs-numbers/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/codecs-numbers/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/codecs-numbers?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/codecs-numbers?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/codecs-numbers\n\n# @solana/codecs-numbers\n\nThis package contains codecs for numbers of different sizes and endianness. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nThis package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) which acts as an entry point for all codec packages as well as for their documentation.\n\n## Integer codecs\n\nThis package provides ten codecs of five different byte sizes for integers. Five of them store unsigned integers and the other five store signed integers.\n\n```ts\n// Unsigned integers.\ngetU8Codec().encode(42); // 0x2a\ngetU16Codec().encode(42); // 0x2a00\ngetU32Codec().encode(42); // 0x2a000000\ngetU64Codec().encode(42); // 0x2a00000000000000\ngetU128Codec().encode(42); // 0x2a000000000000000000000000000000\n\n// Signed integers.\ngetI8Codec().encode(-42); // 0xd6\ngetI16Codec().encode(-42); // 0xd6ff\ngetI32Codec().encode(-42); // 0xd6ffffff\ngetI64Codec().encode(-42); // 0xd6ffffffffffffff\ngetI128Codec().encode(-42); // 0xd6ffffffffffffffffffffffffffffff\n```\n\nBy default, integers are stored using little endianness but you may change this behaviour via the `endian` option. This option is available for every codec that uses more than a single byte.\n\n```ts\n// Big-endian unsigned integers.\ngetU16Codec({ endian: Endian.Big }).encode(42); // 0x002a\ngetU32Codec({ endian: Endian.Big }).encode(42); // 0x0000002a\ngetU64Codec({ endian: Endian.Big }).encode(42); // 0x000000000000002a\ngetU128Codec({ endian: Endian.Big }).encode(42); // 0x0000000000000000000000000000002a\n\n// Big-endian signed integers.\ngetI16Codec({ endian: Endian.Big }).encode(-42); // 0xffd6\ngetI32Codec({ endian: Endian.Big }).encode(-42); // 0xffffffd6\ngetI64Codec({ endian: Endian.Big }).encode(-42); // 0xffffffffffffffd6\ngetI128Codec({ endian: Endian.Big }).encode(-42); // 0xffffffffffffffffffffffffffffffd6\n```\n\nAll integer codecs are of type `Codec<number>` except for the `u64`, `u128`, `i64` and `i128` codecs which are of type `Codec<number | bigint, bigint>`. This means we can provide either a `number` of a `bigint` value to encode but the decoded value will always be a `bigint`. This is because JavaScript's native `number` type does not support numbers larger than `2^53 - 1` and these large integer codecs have the potential to go over that value.\n\n```ts\nconst bytesFromNumber = getU64Codec().encode(42);\ngetU64Codec().decode(bytesFromNumber); // BigInt(42)\n\n// OR\nconst bytesFromBigInt = getU64Codec().encode(BigInt(42));\ngetU64Codec().decode(bytesFromBigInt); // BigInt(42)\n```\n\nFinally, for each of these `get*Codec` functions, separate `get*Encoder` and `get*Decoder` functions exist to focus on only one side of the serialization and tree-shake the rest of the functions away.\n\n```ts\nconst bytes = getU8Encoder().encode(42);\nconst value = getU8Decoder().decode(bytes);\n```\n\n## Decimal number codecs\n\nThis package also provides two codecs for floating numbers. One using 32 bits and one using 64 bits.\n\n```ts\ngetF32Codec().encode(-1.5); // 0x0000c0bf\ngetF64Codec().encode(-1.5); // 0x000000000000f8bf\n```\n\nSimilarly to the integer codecs, they are stored in little-endian by default but may be stored in big-endian using the `endian` option.\n\n```ts\ngetF32Codec({ endian: Endian.Big }).encode(-1.5); // 0xbfc00000\ngetF64Codec({ endian: Endian.Big }).encode(-1.5); // 0xbff8000000000000\n```\n\nNote that based on the selected codec, some of the precision of the number you are encoding may be lost when decoding it. For instance, when storing `3.1415` using a `f32` codec, you will not get the exact same number back.\n\n```ts\nconst bytes = getF32Codec().encode(3.1415); // 0x560e4940\nconst value = getF32Codec().decode(bytes); // 3.1414999961853027 !== 3.1415\n```\n\nAs usual, separate encoder and decoder functions are available for these codecs.\n\n```ts\ngetF32Encoder().encode(-1.5);\ngetF32Decoder().decode(new Uint8Array([...]));\n\ngetF64Encoder().encode(-1.5);\ngetF64Decoder().decode(new Uint8Array([...]));\n```\n\n## Short u16 codec\n\nThis last integer codec is less common `VariableSizeCodec` that stores an unsigned integer using between 1 to 3 bytes depending on the value of that integer.\n\n```ts\nconst bytes = getShortU16Codec().encode(42); // 0x2a\nconst value = getShortU16Codec().decode(bytes); // 42\n```\n\nIf the provided integer is equal to or lower than `0x7f`, it will be stored as-is, using a single byte. However, if the integer is above `0x7f`, then the top bit is set and the remaining value is stored in the next bytes. Each byte follows the same pattern until the third byte. The third byte, if needed, uses all 8 bits to store the last byte of the original value.\n\nIn other words, this codec provides an extendable size that adapts based on the integer. In the illustration below, you can see the `0` and `1` byte flags for each scenario as well as the available bits to store the integer marked with `X`.\n\n```\n0XXXXXXX <- From 0 to 127.\n1XXXXXXX 0XXXXXXX <- From 128 to 16,383.\n1XXXXXXX 1XXXXXXX XXXXXXXX <- From 16,384 to 4,194,303.\n```\n\nThis codec is mainly used internally when encoding and decoding Solana transactions.\n\nSeparate encoder and decoder functions are also available via `getShortU16Encoder` and `getShortU16Decoder` respectively.\n\n---\n\nTo read more about the available codecs and how to use them, check out the documentation of the main [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs).\n"
  },
  {
    "path": "packages/codecs-numbers/package.json",
    "content": "{\n    \"name\": \"@solana/codecs-numbers\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Codecs for numbers of different sizes and endianness\",\n    \"homepage\": \"https://www.solanakit.com/api#solanacodecs-numbers\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/codecs-numbers/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/__setup__.ts",
    "content": "import { Codec, createCodec, Encoder } from '@solana/codecs-core';\nimport { SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE, SolanaError } from '@solana/errors';\n\nexport const assertValid = <T>(codec: Codec<T>, number: T, bytes: string, decodedNumber?: T): void => {\n    // Encode.\n    const actualBytes = codec.encode(number);\n    const actualBytesBase16 = base16.decode(actualBytes);\n    expect(actualBytesBase16).toBe(bytes);\n\n    // Decode.\n    const deserialization = codec.read(actualBytes, 0);\n    expect(deserialization[0]).toBe(decodedNumber ?? number);\n    expect(deserialization[1]).toBe(actualBytes.length);\n\n    // Decode with offset.\n    const deserializationWithOffset = codec.read(base16.encode(`ffffff${bytes}`), 3);\n    expect(deserializationWithOffset[0]).toBe(decodedNumber ?? number);\n    expect(deserializationWithOffset[1]).toBe(actualBytes.length + 3);\n};\n\nexport const assertValidEncode = <T>(encoder: Encoder<T>, number: T, bytes: string): void => {\n    const actualBytes = encoder.encode(number);\n    const actualBytesBase16 = base16.decode(actualBytes);\n    expect(actualBytesBase16).toBe(bytes);\n};\n\ntype RangeErrorValues = {\n    codecDescription: string;\n    max: bigint | number;\n    min: bigint | number;\n};\n\nexport const assertRangeError = <T extends bigint | number>(\n    config: RangeErrorValues,\n    encoder: Encoder<T>,\n    value: T,\n): void => {\n    const { codecDescription, max, min } = config;\n    expect(() => encoder.encode(value)).toThrow(\n        new SolanaError(SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE, {\n            codecDescription,\n            max,\n            min,\n            value,\n        }),\n    );\n};\n\nexport const base16: Codec<string> = createCodec({\n    getSizeFromValue: (value: string) => Math.ceil(value.length / 2),\n    read(bytes, offset) {\n        const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n        return [value, bytes.length];\n    },\n    write(value: string, bytes, offset) {\n        const matches = value.toLowerCase().match(/.{1,2}/g);\n        const hexBytes = matches ? matches.map((byte: string) => parseInt(byte, 16)) : [];\n        bytes.set(hexBytes, offset);\n        return offset + hexBytes.length;\n    },\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/f32-test.ts",
    "content": "import { Endian } from '../common';\nimport { getF32Codec } from '../f32';\nimport { assertValid, assertValidEncode } from './__setup__';\n\nconst APPROX_PI = 3.1415927410125732;\nconst f32 = getF32Codec;\n\ndescribe('getF32Codec', () => {\n    it('encodes and decodes f32 numbers', () => {\n        expect.hasAssertions();\n        const f32LE = f32();\n        const f32BE = f32({ endian: Endian.Big });\n\n        assertValid(f32LE, 0, '00000000');\n        assertValid(f32BE, 0, '00000000');\n        assertValidEncode(f32LE, 0n, '00000000');\n        assertValidEncode(f32BE, 0n, '00000000');\n\n        assertValid(f32LE, 1, '0000803f');\n        assertValid(f32BE, 1, '3f800000');\n        assertValidEncode(f32LE, 1n, '0000803f');\n        assertValidEncode(f32BE, 1n, '3f800000');\n        assertValid(f32LE, 42, '00002842');\n        assertValid(f32BE, 42, '42280000');\n        assertValidEncode(f32LE, 42n, '00002842');\n        assertValidEncode(f32BE, 42n, '42280000');\n        assertValid(f32LE, Math.PI, 'db0f4940', APPROX_PI);\n        assertValid(f32BE, Math.PI, '40490fdb', APPROX_PI);\n\n        assertValid(f32LE, -1, '000080bf');\n        assertValid(f32BE, -1, 'bf800000');\n        assertValid(f32LE, -42, '000028c2');\n        assertValid(f32BE, -42, 'c2280000');\n        assertValid(f32LE, -Math.PI, 'db0f49c0', -APPROX_PI);\n        assertValid(f32BE, -Math.PI, 'c0490fdb', -APPROX_PI);\n    });\n\n    it('has the right size', () => {\n        expect(f32().fixedSize).toBe(4);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/f64-test.ts",
    "content": "import { Endian } from '../common';\nimport { getF64Codec } from '../f64';\nimport { assertValid, assertValidEncode } from './__setup__';\n\nconst APPROX_PI = 3.141592653589793;\nconst f64 = getF64Codec;\n\ndescribe('getF64Codec', () => {\n    it('encodes and decodes f64 numbers', () => {\n        expect.hasAssertions();\n        const f64LE = f64();\n        const f64BE = f64({ endian: Endian.Big });\n\n        assertValid(f64LE, 0, '0000000000000000');\n        assertValid(f64BE, 0, '0000000000000000');\n        assertValidEncode(f64LE, 0n, '0000000000000000');\n        assertValidEncode(f64BE, 0n, '0000000000000000');\n\n        assertValid(f64LE, 1, '000000000000f03f');\n        assertValid(f64BE, 1, '3ff0000000000000');\n        assertValid(f64LE, 42, '0000000000004540');\n        assertValid(f64BE, 42, '4045000000000000');\n        assertValidEncode(f64LE, 1n, '000000000000f03f');\n        assertValidEncode(f64BE, 1n, '3ff0000000000000');\n        assertValidEncode(f64LE, 42n, '0000000000004540');\n        assertValidEncode(f64BE, 42n, '4045000000000000');\n        assertValid(f64LE, Math.PI, '182d4454fb210940', APPROX_PI);\n        assertValid(f64BE, Math.PI, '400921fb54442d18', APPROX_PI);\n\n        assertValid(f64LE, -1, '000000000000f0bf');\n        assertValid(f64BE, -1, 'bff0000000000000');\n        assertValid(f64LE, -42, '00000000000045c0');\n        assertValid(f64BE, -42, 'c045000000000000');\n        assertValid(f64LE, -Math.PI, '182d4454fb2109c0', -APPROX_PI);\n        assertValid(f64BE, -Math.PI, 'c00921fb54442d18', -APPROX_PI);\n    });\n\n    it('has the right size', () => {\n        expect(f64().fixedSize).toBe(8);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/i128-test.ts",
    "content": "import { Endian } from '../common';\nimport { getI128Codec } from '../i128';\nimport { assertRangeError, assertValid } from './__setup__';\n\nconst MIN = -BigInt('0x7fffffffffffffffffffffffffffffff') - 1n;\nconst MAX = BigInt('0x7fffffffffffffffffffffffffffffff');\nconst i128 = getI128Codec;\nconst rangeErrorValues = {\n    codecDescription: 'i128',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getI128Codec', () => {\n    it('encodes and decodes i128 numbers', () => {\n        expect.hasAssertions();\n        const i128LE = i128();\n        const i128BE = i128({ endian: Endian.Big });\n\n        assertValid(i128LE, 0n, '00000000000000000000000000000000');\n        assertValid(i128BE, 0n, '00000000000000000000000000000000');\n        assertValid(i128LE, 1n, '01000000000000000000000000000000');\n        assertValid(i128BE, 1n, '00000000000000000000000000000001');\n        assertValid(i128LE, 42n, '2a000000000000000000000000000000');\n        assertValid(i128BE, 42n, '0000000000000000000000000000002a');\n        assertValid(i128LE, -1n, 'ffffffffffffffffffffffffffffffff');\n        assertValid(i128BE, -1n, 'ffffffffffffffffffffffffffffffff');\n        assertValid(i128LE, -42n, 'd6ffffffffffffffffffffffffffffff');\n        assertValid(i128BE, -42n, 'ffffffffffffffffffffffffffffffd6');\n\n        // Pre-boundaries.\n        assertValid(i128LE, MIN + 1n, '01000000000000000000000000000080');\n        assertValid(i128BE, MIN + 1n, '80000000000000000000000000000001');\n        assertValid(i128LE, MAX - 1n, 'feffffffffffffffffffffffffffff7f');\n        assertValid(i128BE, MAX - 1n, '7ffffffffffffffffffffffffffffffe');\n\n        // Boundaries.\n        assertValid(i128LE, MIN, '00000000000000000000000000000080');\n        assertValid(i128BE, MIN, '80000000000000000000000000000000');\n        assertValid(i128LE, MAX, 'ffffffffffffffffffffffffffffff7f');\n        assertValid(i128BE, MAX, '7fffffffffffffffffffffffffffffff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, i128LE, MIN - 1n);\n        assertRangeError(rangeErrorValues, i128BE, MIN - 1n);\n        assertRangeError(rangeErrorValues, i128LE, MAX + 1n);\n        assertRangeError(rangeErrorValues, i128BE, MAX + 1n);\n    });\n\n    it('has the right size', () => {\n        expect(i128().fixedSize).toBe(16);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/i16-test.ts",
    "content": "import { Endian } from '../common';\nimport { getI16Codec } from '../i16';\nimport { assertRangeError, assertValid, assertValidEncode } from './__setup__';\n\nconst MIN = -Number('0x7fff') - 1;\nconst MAX = Number('0x7fff');\nconst i16 = getI16Codec;\nconst rangeErrorValues = {\n    codecDescription: 'i16',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getI16Codec', () => {\n    it('encodes and decodes i16 numbers', () => {\n        expect.hasAssertions();\n        const i16LE = i16();\n        const i16BE = i16({ endian: Endian.Big });\n\n        assertValid(i16LE, 0, '0000');\n        assertValid(i16BE, 0, '0000');\n        assertValid(i16LE, 1, '0100');\n        assertValid(i16BE, 1, '0001');\n        assertValid(i16LE, 42, '2a00');\n        assertValid(i16BE, 42, '002a');\n        assertValidEncode(i16LE, 0n, '0000');\n        assertValidEncode(i16BE, 0n, '0000');\n        assertValidEncode(i16LE, 1n, '0100');\n        assertValidEncode(i16BE, 1n, '0001');\n        assertValidEncode(i16LE, 42n, '2a00');\n        assertValidEncode(i16BE, 42n, '002a');\n        assertValid(i16LE, -1, 'ffff');\n        assertValid(i16BE, -1, 'ffff');\n        assertValid(i16LE, -42, 'd6ff');\n        assertValid(i16BE, -42, 'ffd6');\n\n        // Pre-boundaries.\n        assertValid(i16LE, MIN + 1, '0180');\n        assertValid(i16BE, MIN + 1, '8001');\n        assertValid(i16LE, MAX - 1, 'fe7f');\n        assertValid(i16BE, MAX - 1, '7ffe');\n        assertValidEncode(i16LE, BigInt(MIN + 1), '0180');\n        assertValidEncode(i16BE, BigInt(MIN + 1), '8001');\n        assertValidEncode(i16LE, BigInt(MAX - 1), 'fe7f');\n        assertValidEncode(i16BE, BigInt(MAX - 1), '7ffe');\n\n        // Boundaries.\n        assertValid(i16LE, MIN, '0080');\n        assertValid(i16BE, MIN, '8000');\n        assertValid(i16LE, MAX, 'ff7f');\n        assertValid(i16BE, MAX, '7fff');\n        assertValidEncode(i16LE, BigInt(MIN), '0080');\n        assertValidEncode(i16BE, BigInt(MIN), '8000');\n        assertValidEncode(i16LE, BigInt(MAX), 'ff7f');\n        assertValidEncode(i16BE, BigInt(MAX), '7fff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, i16LE, MIN - 1);\n        assertRangeError(rangeErrorValues, i16BE, MIN - 1);\n        assertRangeError(rangeErrorValues, i16LE, MAX + 1);\n        assertRangeError(rangeErrorValues, i16BE, MAX + 1);\n        assertRangeError(rangeErrorValues, i16LE, BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, i16BE, BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, i16LE, BigInt(MAX + 1));\n        assertRangeError(rangeErrorValues, i16BE, BigInt(MAX + 1));\n    });\n\n    it('has the right size', () => {\n        expect(i16().fixedSize).toBe(2);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/i32-test.ts",
    "content": "import { Endian } from '../common';\nimport { getI32Codec } from '../i32';\nimport { assertRangeError, assertValid, assertValidEncode } from './__setup__';\n\nconst MIN = -Number('0x7fffffff') - 1;\nconst MAX = Number('0x7fffffff');\nconst i32 = getI32Codec;\nconst rangeErrorValues = {\n    codecDescription: 'i32',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getI32Codec', () => {\n    it('encodes and decodes i32 numbers', () => {\n        expect.hasAssertions();\n        const i32LE = i32();\n        const i32BE = i32({ endian: Endian.Big });\n\n        assertValid(i32LE, 0, '00000000');\n        assertValid(i32BE, 0, '00000000');\n        assertValid(i32LE, 1, '01000000');\n        assertValid(i32BE, 1, '00000001');\n        assertValid(i32LE, 42, '2a000000');\n        assertValid(i32BE, 42, '0000002a');\n        assertValidEncode(i32LE, 0n, '00000000');\n        assertValidEncode(i32BE, 0n, '00000000');\n        assertValidEncode(i32LE, 1n, '01000000');\n        assertValidEncode(i32BE, 1n, '00000001');\n        assertValidEncode(i32LE, 42n, '2a000000');\n        assertValidEncode(i32BE, 42n, '0000002a');\n        assertValid(i32LE, -1, 'ffffffff');\n        assertValid(i32BE, -1, 'ffffffff');\n        assertValid(i32LE, -42, 'd6ffffff');\n        assertValid(i32BE, -42, 'ffffffd6');\n\n        // Pre-boundaries.\n        assertValid(i32LE, MIN + 1, '01000080');\n        assertValid(i32BE, MIN + 1, '80000001');\n        assertValid(i32LE, MAX - 1, 'feffff7f');\n        assertValid(i32BE, MAX - 1, '7ffffffe');\n        assertValidEncode(i32LE, BigInt(MIN + 1), '01000080');\n        assertValidEncode(i32BE, BigInt(MIN + 1), '80000001');\n        assertValidEncode(i32LE, BigInt(MAX - 1), 'feffff7f');\n        assertValidEncode(i32BE, BigInt(MAX - 1), '7ffffffe');\n\n        // Boundaries.\n        assertValid(i32LE, MIN, '00000080');\n        assertValid(i32BE, MIN, '80000000');\n        assertValid(i32LE, MAX, 'ffffff7f');\n        assertValid(i32BE, MAX, '7fffffff');\n        assertValidEncode(i32LE, BigInt(MIN), '00000080');\n        assertValidEncode(i32BE, BigInt(MIN), '80000000');\n        assertValidEncode(i32LE, BigInt(MAX), 'ffffff7f');\n        assertValidEncode(i32BE, BigInt(MAX), '7fffffff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, i32LE, MIN - 1);\n        assertRangeError(rangeErrorValues, i32BE, MIN - 1);\n        assertRangeError(rangeErrorValues, i32LE, MAX + 1);\n        assertRangeError(rangeErrorValues, i32BE, MAX + 1);\n        assertRangeError(rangeErrorValues, i32LE, BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, i32BE, BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, i32LE, BigInt(MAX + 1));\n        assertRangeError(rangeErrorValues, i32BE, BigInt(MAX + 1));\n    });\n\n    it('has the right size', () => {\n        expect(i32().fixedSize).toBe(4);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/i64-test.ts",
    "content": "import { Endian } from '../common';\nimport { getI64Codec } from '../i64';\nimport { assertRangeError, assertValid } from './__setup__';\n\nconst MIN = -BigInt('0x7fffffffffffffff') - 1n;\nconst MAX = BigInt('0x7fffffffffffffff');\nconst i64 = getI64Codec;\nconst rangeErrorValues = {\n    codecDescription: 'i64',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getI64Codec', () => {\n    it('encodes and decodes i64 numbers', () => {\n        expect.hasAssertions();\n        const i64LE = i64();\n        const i64BE = i64({ endian: Endian.Big });\n\n        assertValid(i64LE, 0n, '0000000000000000');\n        assertValid(i64BE, 0n, '0000000000000000');\n        assertValid(i64LE, 1n, '0100000000000000');\n        assertValid(i64BE, 1n, '0000000000000001');\n        assertValid(i64LE, 42n, '2a00000000000000');\n        assertValid(i64BE, 42n, '000000000000002a');\n        assertValid(i64LE, -1n, 'ffffffffffffffff');\n        assertValid(i64BE, -1n, 'ffffffffffffffff');\n        assertValid(i64LE, -42n, 'd6ffffffffffffff');\n        assertValid(i64BE, -42n, 'ffffffffffffffd6');\n\n        // Pre-boundaries.\n        assertValid(i64LE, MIN + 1n, '0100000000000080');\n        assertValid(i64BE, MIN + 1n, '8000000000000001');\n        assertValid(i64LE, MAX - 1n, 'feffffffffffff7f');\n        assertValid(i64BE, MAX - 1n, '7ffffffffffffffe');\n\n        // Boundaries.\n        assertValid(i64LE, MIN, '0000000000000080');\n        assertValid(i64BE, MIN, '8000000000000000');\n        assertValid(i64LE, MAX, 'ffffffffffffff7f');\n        assertValid(i64BE, MAX, '7fffffffffffffff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, i64LE, MIN - 1n);\n        assertRangeError(rangeErrorValues, i64BE, MIN - 1n);\n        assertRangeError(rangeErrorValues, i64LE, MAX + 1n);\n        assertRangeError(rangeErrorValues, i64BE, MAX + 1n);\n    });\n\n    it('has the right size', () => {\n        expect(i64().fixedSize).toBe(8);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/i8-test.ts",
    "content": "import { getI8Codec } from '../i8';\nimport { assertRangeError, assertValid, assertValidEncode } from './__setup__';\n\nconst MIN = -Number('0x7f') - 1;\nconst MAX = Number('0x7f');\nconst i8 = getI8Codec;\nconst rangeErrorValues = {\n    codecDescription: 'i8',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getI8Codec', () => {\n    it('encodes and decodes i8 numbers', () => {\n        expect.hasAssertions();\n        assertValid(i8(), 0, '00');\n        assertValid(i8(), 1, '01');\n        assertValid(i8(), 42, '2a');\n        assertValidEncode(i8(), 0n, '00');\n        assertValidEncode(i8(), 1n, '01');\n        assertValidEncode(i8(), 42n, '2a');\n        assertValid(i8(), -1, 'ff');\n        assertValid(i8(), -42, 'd6');\n\n        // Pre-boundaries.\n        assertValid(i8(), MIN + 1, '81');\n        assertValid(i8(), MAX - 1, '7e');\n        assertValidEncode(i8(), BigInt(MAX - 1), '7e');\n\n        // Boundaries.\n        assertValid(i8(), MIN, '80');\n        assertValid(i8(), MAX, '7f');\n        assertValidEncode(i8(), BigInt(MAX), '7f');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, i8(), MIN - 1);\n        assertRangeError(rangeErrorValues, i8(), MAX + 1);\n        assertRangeError(rangeErrorValues, i8(), BigInt(MAX + 1));\n    });\n\n    it('has the right size', () => {\n        expect(i8().fixedSize).toBe(1);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/short-u16-test.ts",
    "content": "import { getShortU16Codec } from '../short-u16';\nimport { assertRangeError, assertValid, assertValidEncode } from './__setup__';\n\nconst MIN = 0;\nconst MAX = 65535;\nconst shortU16 = getShortU16Codec;\nconst rangeErrorValues = {\n    codecDescription: 'shortU16',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getShortU16Codec', () => {\n    it('encodes and decodes short u16 numbers', () => {\n        expect.hasAssertions();\n        assertValid(shortU16(), 0, '00');\n        assertValid(shortU16(), 1, '01');\n        assertValid(shortU16(), 42, '2a');\n        assertValid(shortU16(), 127, '7f');\n        assertValid(shortU16(), 128, '8001');\n        assertValid(shortU16(), 16383, 'ff7f');\n        assertValid(shortU16(), 16384, '808001');\n        assertValidEncode(shortU16(), 0n, '00');\n        assertValidEncode(shortU16(), 1n, '01');\n        assertValidEncode(shortU16(), 42n, '2a');\n        assertValidEncode(shortU16(), 127n, '7f');\n        assertValidEncode(shortU16(), 128n, '8001');\n        assertValidEncode(shortU16(), 16383n, 'ff7f');\n        assertValidEncode(shortU16(), 16384n, '808001');\n\n        // Pre-boundaries.\n        assertValid(shortU16(), MIN + 1, '01');\n        assertValid(shortU16(), MAX - 1, 'feff03');\n        assertValidEncode(shortU16(), BigInt(MIN + 1), '01');\n        assertValidEncode(shortU16(), BigInt(MAX - 1), 'feff03');\n\n        // Boundaries.\n        assertValid(shortU16(), MIN, '00');\n        assertValid(shortU16(), MAX, 'ffff03');\n        assertValidEncode(shortU16(), BigInt(MIN), '00');\n        assertValidEncode(shortU16(), BigInt(MAX), 'ffff03');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, shortU16(), MIN - 1);\n        assertRangeError(rangeErrorValues, shortU16(), MAX + 1);\n        assertRangeError(rangeErrorValues, shortU16(), BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, shortU16(), BigInt(MAX + 1));\n\n        // Assert re-serialization.\n        const codec = shortU16();\n        for (let i = 0; i <= 0b1111111111111111; i += 1) {\n            const bytes = codec.encode(i);\n            expect(codec.decode(bytes)).toBe(i);\n        }\n    });\n\n    it('has the right sizes', () => {\n        expect(shortU16().maxSize).toBe(3);\n        expect(shortU16().getSizeFromValue(1)).toBe(1);\n        expect(shortU16().getSizeFromValue(127)).toBe(1);\n        expect(shortU16().getSizeFromValue(128)).toBe(2);\n        expect(shortU16().getSizeFromValue(16383)).toBe(2);\n        expect(shortU16().getSizeFromValue(16384)).toBe(3);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/u128-test.ts",
    "content": "import { Endian } from '../common';\nimport { getU128Codec } from '../u128';\nimport { assertRangeError, assertValid } from './__setup__';\n\nconst MIN = 0n;\nconst MAX = BigInt('0xffffffffffffffffffffffffffffffff');\nconst HALF = BigInt('0xffffffffffffffff');\nconst u128 = getU128Codec;\nconst rangeErrorValues = {\n    codecDescription: 'u128',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getU128Codec', () => {\n    it('encodes and decodes u128 numbers', () => {\n        expect.hasAssertions();\n        const u128LE = u128();\n        const u128BE = u128({ endian: Endian.Big });\n\n        assertValid(u128LE, 1n, '01000000000000000000000000000000');\n        assertValid(u128BE, 1n, '00000000000000000000000000000001');\n        assertValid(u128LE, 42n, '2a000000000000000000000000000000');\n        assertValid(u128BE, 42n, '0000000000000000000000000000002a');\n\n        // Half bytes.\n        assertValid(u128LE, HALF, 'ffffffffffffffff0000000000000000');\n        assertValid(u128BE, HALF, '0000000000000000ffffffffffffffff');\n\n        // Pre-boundaries.\n        assertValid(u128LE, MIN + 1n, '01000000000000000000000000000000');\n        assertValid(u128BE, MIN + 1n, '00000000000000000000000000000001');\n        assertValid(u128LE, MAX - 1n, 'feffffffffffffffffffffffffffffff');\n        assertValid(u128BE, MAX - 1n, 'fffffffffffffffffffffffffffffffe');\n\n        // Boundaries.\n        assertValid(u128LE, MIN, '00000000000000000000000000000000');\n        assertValid(u128BE, MIN, '00000000000000000000000000000000');\n        assertValid(u128LE, MAX, 'ffffffffffffffffffffffffffffffff');\n        assertValid(u128BE, MAX, 'ffffffffffffffffffffffffffffffff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, u128LE, MIN - 1n);\n        assertRangeError(rangeErrorValues, u128BE, MIN - 1n);\n        assertRangeError(rangeErrorValues, u128LE, MAX + 1n);\n        assertRangeError(rangeErrorValues, u128BE, MAX + 1n);\n    });\n\n    it('has the right size', () => {\n        expect(u128().fixedSize).toBe(16);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/u16-test.ts",
    "content": "import { Endian } from '../common';\nimport { getU16Codec } from '../u16';\nimport { assertRangeError, assertValid, assertValidEncode } from './__setup__';\n\nconst MIN = 0;\nconst MAX = Number('0xffff');\nconst HALF = Number('0xff');\nconst u16 = getU16Codec;\nconst rangeErrorValues = {\n    codecDescription: 'u16',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getU16Codec', () => {\n    it('encodes and decodes u16 numbers', () => {\n        expect.hasAssertions();\n        const u16LE = u16();\n        const u16BE = u16({ endian: Endian.Big });\n\n        assertValid(u16LE, 1, '0100');\n        assertValid(u16BE, 1, '0001');\n        assertValid(u16LE, 42, '2a00');\n        assertValid(u16BE, 42, '002a');\n        assertValidEncode(u16LE, 1n, '0100');\n        assertValidEncode(u16BE, 1n, '0001');\n        assertValidEncode(u16LE, 42n, '2a00');\n        assertValidEncode(u16BE, 42n, '002a');\n\n        // Half bytes.\n        assertValid(u16LE, HALF, 'ff00');\n        assertValid(u16BE, HALF, '00ff');\n        assertValidEncode(u16LE, BigInt(HALF), 'ff00');\n        assertValidEncode(u16BE, BigInt(HALF), '00ff');\n\n        // Pre-boundaries.\n        assertValid(u16LE, MIN + 1, '0100');\n        assertValid(u16BE, MIN + 1, '0001');\n        assertValid(u16LE, MAX - 1, 'feff');\n        assertValid(u16BE, MAX - 1, 'fffe');\n        assertValidEncode(u16LE, BigInt(MIN + 1), '0100');\n        assertValidEncode(u16BE, BigInt(MIN + 1), '0001');\n        assertValidEncode(u16LE, BigInt(MAX - 1), 'feff');\n        assertValidEncode(u16BE, BigInt(MAX - 1), 'fffe');\n\n        // Boundaries.\n        assertValid(u16LE, MIN, '0000');\n        assertValid(u16BE, MIN, '0000');\n        assertValid(u16LE, MAX, 'ffff');\n        assertValid(u16BE, MAX, 'ffff');\n        assertValidEncode(u16LE, BigInt(MIN), '0000');\n        assertValidEncode(u16BE, BigInt(MIN), '0000');\n        assertValidEncode(u16LE, BigInt(MAX), 'ffff');\n        assertValidEncode(u16BE, BigInt(MAX), 'ffff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, u16LE, MIN - 1);\n        assertRangeError(rangeErrorValues, u16BE, MIN - 1);\n        assertRangeError(rangeErrorValues, u16LE, MAX + 1);\n        assertRangeError(rangeErrorValues, u16BE, MAX + 1);\n        assertRangeError(rangeErrorValues, u16LE, BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, u16BE, BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, u16LE, BigInt(MAX + 1));\n        assertRangeError(rangeErrorValues, u16BE, BigInt(MAX + 1));\n    });\n\n    it('has the right size', () => {\n        expect(u16().fixedSize).toBe(2);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/u32-test.ts",
    "content": "import { Endian } from '../common';\nimport { getU32Codec } from '../u32';\nimport { assertRangeError, assertValid, assertValidEncode } from './__setup__';\n\nconst MIN = 0;\nconst MAX = Number('0xffffffff');\nconst HALF = Number('0xffff');\nconst u32 = getU32Codec;\nconst rangeErrorValues = {\n    codecDescription: 'u32',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getU32Codec', () => {\n    it('encodes and decodes u32 numbers', () => {\n        expect.hasAssertions();\n        const u32LE = u32();\n        const u32BE = u32({ endian: Endian.Big });\n\n        assertValid(u32LE, 1, '01000000');\n        assertValid(u32BE, 1, '00000001');\n        assertValid(u32LE, 42, '2a000000');\n        assertValid(u32BE, 42, '0000002a');\n        assertValidEncode(u32LE, 1n, '01000000');\n        assertValidEncode(u32BE, 1n, '00000001');\n        assertValidEncode(u32LE, 42n, '2a000000');\n        assertValidEncode(u32BE, 42n, '0000002a');\n\n        // Half bytes.\n        assertValid(u32LE, HALF, 'ffff0000');\n        assertValid(u32BE, HALF, '0000ffff');\n        assertValidEncode(u32LE, BigInt(HALF), 'ffff0000');\n        assertValidEncode(u32BE, BigInt(HALF), '0000ffff');\n\n        // Pre-boundaries.\n        assertValid(u32LE, MIN + 1, '01000000');\n        assertValid(u32BE, MIN + 1, '00000001');\n        assertValid(u32LE, MAX - 1, 'feffffff');\n        assertValid(u32BE, MAX - 1, 'fffffffe');\n        assertValidEncode(u32LE, BigInt(MIN + 1), '01000000');\n        assertValidEncode(u32BE, BigInt(MIN + 1), '00000001');\n        assertValidEncode(u32LE, BigInt(MAX - 1), 'feffffff');\n        assertValidEncode(u32BE, BigInt(MAX - 1), 'fffffffe');\n\n        // Boundaries.\n        assertValid(u32LE, MIN, '00000000');\n        assertValid(u32BE, MIN, '00000000');\n        assertValid(u32LE, MAX, 'ffffffff');\n        assertValid(u32BE, MAX, 'ffffffff');\n        assertValidEncode(u32LE, BigInt(MIN), '00000000');\n        assertValidEncode(u32BE, BigInt(MIN), '00000000');\n        assertValidEncode(u32LE, BigInt(MAX), 'ffffffff');\n        assertValidEncode(u32BE, BigInt(MAX), 'ffffffff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, u32LE, MIN - 1);\n        assertRangeError(rangeErrorValues, u32BE, MIN - 1);\n        assertRangeError(rangeErrorValues, u32LE, MAX + 1);\n        assertRangeError(rangeErrorValues, u32BE, MAX + 1);\n        assertRangeError(rangeErrorValues, u32LE, BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, u32BE, BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, u32LE, BigInt(MAX + 1));\n        assertRangeError(rangeErrorValues, u32BE, BigInt(MAX + 1));\n    });\n\n    it('has the right size', () => {\n        expect(u32().fixedSize).toBe(4);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/u64-test.ts",
    "content": "import { Endian } from '../common';\nimport { getU64Codec } from '../u64';\nimport { assertRangeError, assertValid } from './__setup__';\n\nconst MIN = 0n;\nconst MAX = BigInt('0xffffffffffffffff');\nconst HALF = BigInt('0xffffffff');\nconst u64 = getU64Codec;\nconst rangeErrorValues = {\n    codecDescription: 'u64',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getU64Codec', () => {\n    it('encodes and decodes u64 numbers', () => {\n        expect.hasAssertions();\n        const u64LE = u64();\n        const u64BE = u64({ endian: Endian.Big });\n\n        assertValid(u64LE, 1n, '0100000000000000');\n        assertValid(u64BE, 1n, '0000000000000001');\n        assertValid(u64LE, 42n, '2a00000000000000');\n        assertValid(u64BE, 42n, '000000000000002a');\n\n        // Half bytes.\n        assertValid(u64LE, HALF, 'ffffffff00000000');\n        assertValid(u64BE, HALF, '00000000ffffffff');\n\n        // Pre-boundaries.\n        assertValid(u64LE, MIN + 1n, '0100000000000000');\n        assertValid(u64BE, MIN + 1n, '0000000000000001');\n        assertValid(u64LE, MAX - 1n, 'feffffffffffffff');\n        assertValid(u64BE, MAX - 1n, 'fffffffffffffffe');\n\n        // Boundaries.\n        assertValid(u64LE, MIN, '0000000000000000');\n        assertValid(u64BE, MIN, '0000000000000000');\n        assertValid(u64LE, MAX, 'ffffffffffffffff');\n        assertValid(u64BE, MAX, 'ffffffffffffffff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, u64LE, MIN - 1n);\n        assertRangeError(rangeErrorValues, u64BE, MIN - 1n);\n        assertRangeError(rangeErrorValues, u64LE, MAX + 1n);\n        assertRangeError(rangeErrorValues, u64BE, MAX + 1n);\n    });\n\n    it('has the right size', () => {\n        expect(u64().fixedSize).toBe(8);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__tests__/u8-test.ts",
    "content": "import { getU8Codec } from '../u8';\nimport { assertRangeError, assertValid, assertValidEncode } from './__setup__';\n\nconst MIN = 0;\nconst MAX = Number('0xff');\nconst u8 = getU8Codec;\nconst rangeErrorValues = {\n    codecDescription: 'u8',\n    max: MAX,\n    min: MIN,\n};\n\ndescribe('getU8Codec', () => {\n    it('encodes and decodes u8 numbers', () => {\n        expect.hasAssertions();\n        assertValid(u8(), 1, '01');\n        assertValid(u8(), 42, '2a');\n        assertValidEncode(u8(), 1n, '01');\n        assertValidEncode(u8(), 42n, '2a');\n\n        // Pre-boundaries.\n        assertValid(u8(), MIN + 1, '01');\n        assertValid(u8(), MAX - 1, 'fe');\n        assertValidEncode(u8(), BigInt(MIN + 1), '01');\n        assertValidEncode(u8(), BigInt(MAX - 1), 'fe');\n\n        // Boundaries.\n        assertValid(u8(), MIN, '00');\n        assertValid(u8(), MAX, 'ff');\n        assertValidEncode(u8(), BigInt(MIN), '00');\n        assertValidEncode(u8(), BigInt(MAX), 'ff');\n\n        // Out of range.\n        assertRangeError(rangeErrorValues, u8(), MIN - 1);\n        assertRangeError(rangeErrorValues, u8(), MAX + 1);\n        assertRangeError(rangeErrorValues, u8(), BigInt(MIN - 1));\n        assertRangeError(rangeErrorValues, u8(), BigInt(MAX + 1));\n    });\n\n    it('has the right size', () => {\n        expect(u8().fixedSize).toBe(1);\n    });\n});\n"
  },
  {
    "path": "packages/codecs-numbers/src/__typetests__/codecs-typetest.ts",
    "content": "import type {\n    FixedSizeNumberCodec,\n    FixedSizeNumberDecoder,\n    FixedSizeNumberEncoder,\n    NumberCodec,\n    NumberDecoder,\n    NumberEncoder,\n} from '../common';\nimport { getF32Codec, getF32Decoder, getF32Encoder } from '../f32';\nimport { getF64Codec, getF64Decoder, getF64Encoder } from '../f64';\nimport { getI8Codec, getI8Decoder, getI8Encoder } from '../i8';\nimport { getI16Codec, getI16Decoder, getI16Encoder } from '../i16';\nimport { getI32Codec, getI32Decoder, getI32Encoder } from '../i32';\nimport { getI64Codec, getI64Decoder, getI64Encoder } from '../i64';\nimport { getI128Codec, getI128Decoder, getI128Encoder } from '../i128';\nimport { getShortU16Codec, getShortU16Decoder, getShortU16Encoder } from '../short-u16';\nimport { getU8Codec, getU8Decoder, getU8Encoder } from '../u8';\nimport { getU16Codec, getU16Decoder, getU16Encoder } from '../u16';\nimport { getU32Codec, getU32Decoder, getU32Encoder } from '../u32';\nimport { getU64Codec, getU64Decoder, getU64Encoder } from '../u64';\nimport { getU128Codec, getU128Decoder, getU128Encoder } from '../u128';\n\ngetF32Encoder() satisfies NumberEncoder;\ngetF32Encoder() satisfies FixedSizeNumberEncoder;\ngetF32Decoder() satisfies NumberDecoder;\ngetF32Decoder() satisfies FixedSizeNumberDecoder;\ngetF32Codec() satisfies NumberCodec;\ngetF32Codec() satisfies FixedSizeNumberCodec;\ngetF32Codec() satisfies NumberEncoder;\ngetF32Codec() satisfies FixedSizeNumberEncoder;\ngetF32Codec() satisfies NumberDecoder;\ngetF32Codec() satisfies FixedSizeNumberDecoder;\n\ngetF64Encoder() satisfies NumberEncoder;\ngetF64Encoder() satisfies FixedSizeNumberEncoder;\ngetF64Decoder() satisfies NumberDecoder;\ngetF64Decoder() satisfies FixedSizeNumberDecoder;\ngetF64Codec() satisfies NumberCodec;\ngetF64Codec() satisfies FixedSizeNumberCodec;\ngetF64Codec() satisfies NumberEncoder;\ngetF64Codec() satisfies FixedSizeNumberEncoder;\ngetF64Codec() satisfies NumberDecoder;\ngetF64Codec() satisfies FixedSizeNumberDecoder;\n\ngetI8Encoder() satisfies NumberEncoder;\ngetI8Encoder() satisfies FixedSizeNumberEncoder;\ngetI8Decoder() satisfies NumberDecoder;\ngetI8Decoder() satisfies FixedSizeNumberDecoder;\ngetI8Codec() satisfies NumberCodec;\ngetI8Codec() satisfies FixedSizeNumberCodec;\ngetI8Codec() satisfies NumberEncoder;\ngetI8Codec() satisfies FixedSizeNumberEncoder;\ngetI8Codec() satisfies NumberDecoder;\ngetI8Codec() satisfies FixedSizeNumberDecoder;\n\ngetI16Encoder() satisfies NumberEncoder;\ngetI16Encoder() satisfies FixedSizeNumberEncoder;\ngetI16Decoder() satisfies NumberDecoder;\ngetI16Decoder() satisfies FixedSizeNumberDecoder;\ngetI16Codec() satisfies NumberCodec;\ngetI16Codec() satisfies FixedSizeNumberCodec;\ngetI16Codec() satisfies NumberEncoder;\ngetI16Codec() satisfies FixedSizeNumberEncoder;\ngetI16Codec() satisfies NumberDecoder;\ngetI16Codec() satisfies FixedSizeNumberDecoder;\n\ngetI32Encoder() satisfies NumberEncoder;\ngetI32Encoder() satisfies FixedSizeNumberEncoder;\ngetI32Decoder() satisfies NumberDecoder;\ngetI32Decoder() satisfies FixedSizeNumberDecoder;\ngetI32Codec() satisfies NumberCodec;\ngetI32Codec() satisfies FixedSizeNumberCodec;\ngetI32Codec() satisfies NumberEncoder;\ngetI32Codec() satisfies FixedSizeNumberEncoder;\ngetI32Codec() satisfies NumberDecoder;\ngetI32Codec() satisfies FixedSizeNumberDecoder;\n\ngetI64Encoder() satisfies NumberEncoder;\ngetI64Encoder() satisfies FixedSizeNumberEncoder;\ngetI64Decoder() satisfies NumberDecoder;\ngetI64Decoder() satisfies FixedSizeNumberDecoder;\ngetI64Codec() satisfies NumberCodec;\ngetI64Codec() satisfies FixedSizeNumberCodec;\ngetI64Codec() satisfies NumberEncoder;\ngetI64Codec() satisfies FixedSizeNumberEncoder;\ngetI64Codec() satisfies NumberDecoder;\ngetI64Codec() satisfies FixedSizeNumberDecoder;\n\ngetI128Encoder() satisfies NumberEncoder;\ngetI128Encoder() satisfies FixedSizeNumberEncoder;\ngetI128Decoder() satisfies NumberDecoder;\ngetI128Decoder() satisfies FixedSizeNumberDecoder;\ngetI128Codec() satisfies NumberCodec;\ngetI128Codec() satisfies FixedSizeNumberCodec;\ngetI128Codec() satisfies NumberEncoder;\ngetI128Codec() satisfies FixedSizeNumberEncoder;\ngetI128Codec() satisfies NumberDecoder;\ngetI128Codec() satisfies FixedSizeNumberDecoder;\n\ngetShortU16Encoder() satisfies NumberEncoder;\n// @ts-expect-error variable size encoder\ngetShortU16Encoder() satisfies FixedSizeNumberEncoder;\ngetShortU16Decoder() satisfies NumberDecoder;\n// @ts-expect-error variable size decoder\ngetShortU16Decoder() satisfies FixedSizeNumberDecoder;\ngetShortU16Codec() satisfies NumberCodec;\n// @ts-expect-error variable size codec\ngetShortU16Codec() satisfies FixedSizeNumberCodec;\ngetShortU16Codec() satisfies NumberEncoder;\n// @ts-expect-error variable size encoder\ngetShortU16Codec() satisfies FixedSizeNumberEncoder;\ngetShortU16Codec() satisfies NumberDecoder;\n// @ts-expect-error variable size decoder\ngetShortU16Codec() satisfies FixedSizeNumberDecoder;\n\ngetU8Encoder() satisfies NumberEncoder;\ngetU8Encoder() satisfies FixedSizeNumberEncoder;\ngetU8Decoder() satisfies NumberDecoder;\ngetU8Decoder() satisfies FixedSizeNumberDecoder;\ngetU8Codec() satisfies NumberCodec;\ngetU8Codec() satisfies FixedSizeNumberCodec;\ngetU8Codec() satisfies NumberEncoder;\ngetU8Codec() satisfies FixedSizeNumberEncoder;\ngetU8Codec() satisfies NumberDecoder;\ngetU8Codec() satisfies FixedSizeNumberDecoder;\n\ngetU16Encoder() satisfies NumberEncoder;\ngetU16Encoder() satisfies FixedSizeNumberEncoder;\ngetU16Decoder() satisfies NumberDecoder;\ngetU16Decoder() satisfies FixedSizeNumberDecoder;\ngetU16Codec() satisfies NumberCodec;\ngetU16Codec() satisfies FixedSizeNumberCodec;\ngetU16Codec() satisfies NumberEncoder;\ngetU16Codec() satisfies FixedSizeNumberEncoder;\ngetU16Codec() satisfies NumberDecoder;\ngetU16Codec() satisfies FixedSizeNumberDecoder;\n\ngetU32Encoder() satisfies NumberEncoder;\ngetU32Encoder() satisfies FixedSizeNumberEncoder;\ngetU32Decoder() satisfies NumberDecoder;\ngetU32Decoder() satisfies FixedSizeNumberDecoder;\ngetU32Codec() satisfies NumberCodec;\ngetU32Codec() satisfies FixedSizeNumberCodec;\ngetU32Codec() satisfies NumberEncoder;\ngetU32Codec() satisfies FixedSizeNumberEncoder;\ngetU32Codec() satisfies NumberDecoder;\ngetU32Codec() satisfies FixedSizeNumberDecoder;\n\ngetU64Encoder() satisfies NumberEncoder;\ngetU64Encoder() satisfies FixedSizeNumberEncoder;\ngetU64Decoder() satisfies NumberDecoder;\ngetU64Decoder() satisfies FixedSizeNumberDecoder;\ngetU64Codec() satisfies NumberCodec;\ngetU64Codec() satisfies FixedSizeNumberCodec;\ngetU64Codec() satisfies NumberEncoder;\ngetU64Codec() satisfies FixedSizeNumberEncoder;\ngetU64Codec() satisfies NumberDecoder;\ngetU64Codec() satisfies FixedSizeNumberDecoder;\n\ngetU128Encoder() satisfies NumberEncoder;\ngetU128Encoder() satisfies FixedSizeNumberEncoder;\ngetU128Decoder() satisfies NumberDecoder;\ngetU128Decoder() satisfies FixedSizeNumberDecoder;\ngetU128Codec() satisfies NumberCodec;\ngetU128Codec() satisfies FixedSizeNumberCodec;\ngetU128Codec() satisfies NumberEncoder;\ngetU128Codec() satisfies FixedSizeNumberEncoder;\ngetU128Codec() satisfies NumberDecoder;\ngetU128Codec() satisfies FixedSizeNumberDecoder;\n"
  },
  {
    "path": "packages/codecs-numbers/src/assertions.ts",
    "content": "import { SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE, SolanaError } from '@solana/errors';\n\n/**\n * Ensures that a given number falls within a specified range.\n *\n * If the number is outside the allowed range, an error is thrown.\n * This function is primarily used to validate values before encoding them in a codec.\n *\n * @param codecDescription - A string describing the codec that is performing the validation.\n * @param min - The minimum allowed value (inclusive).\n * @param max - The maximum allowed value (inclusive).\n * @param value - The number to validate.\n *\n * @throws {@link SolanaError} if the value is out of range.\n *\n * @example\n * Validating a number within range.\n * ```ts\n * assertNumberIsBetweenForCodec('u8', 0, 255, 42); // Passes\n * ```\n *\n * @example\n * Throwing an error for an out-of-range value.\n * ```ts\n * assertNumberIsBetweenForCodec('u8', 0, 255, 300); // Throws\n * ```\n */\nexport function assertNumberIsBetweenForCodec(\n    codecDescription: string,\n    min: bigint | number,\n    max: bigint | number,\n    value: bigint | number,\n) {\n    if (value < min || value > max) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE, {\n            codecDescription,\n            max,\n            min,\n            value,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/codecs-numbers/src/common.ts",
    "content": "import { Codec, Decoder, Encoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n/**\n * Represents an encoder for numbers and bigints.\n *\n * This type allows encoding values that are either `number` or `bigint`.\n * Depending on the specific implementation, the encoded output may have a fixed or variable size.\n *\n * @see {@link FixedSizeNumberEncoder}\n */\nexport type NumberEncoder = Encoder<bigint | number>;\n\n/**\n * Represents a fixed-size encoder for numbers and bigints.\n *\n * This encoder serializes values using an exact number of bytes, defined by `TSize`.\n *\n * @typeParam TSize - The number of bytes used for encoding.\n *\n * @see {@link NumberEncoder}\n */\nexport type FixedSizeNumberEncoder<TSize extends number = number> = FixedSizeEncoder<bigint | number, TSize>;\n\n/**\n * Represents a decoder for numbers and bigints.\n *\n * This type supports decoding values as either `number` or `bigint`, depending on the implementation.\n *\n * @see {@link FixedSizeNumberDecoder}\n */\nexport type NumberDecoder = Decoder<bigint> | Decoder<number>;\n\n/**\n * Represents a fixed-size decoder for numbers and bigints.\n *\n * This decoder reads a fixed number of bytes (`TSize`) and converts them into a `number` or `bigint`.\n *\n * @typeParam TSize - The number of bytes expected for decoding.\n *\n * @see {@link NumberDecoder}\n */\nexport type FixedSizeNumberDecoder<TSize extends number = number> =\n    | FixedSizeDecoder<bigint, TSize>\n    | FixedSizeDecoder<number, TSize>;\n\n/**\n * Represents a codec for encoding and decoding numbers and bigints.\n *\n * - The encoded value can be either a `number` or a `bigint`.\n * - The decoded value will always be either a `number` or `bigint`, depending on the implementation.\n *\n * @see {@link FixedSizeNumberCodec}\n */\nexport type NumberCodec = Codec<bigint | number, bigint> | Codec<bigint | number, number>;\n\n/**\n * Represents a fixed-size codec for encoding and decoding numbers and bigints.\n *\n * This codec uses a specific number of bytes (`TSize`) for serialization.\n * The encoded value can be either a `number` or `bigint`, but the decoded value will always be a `number` or `bigint`,\n * depending on the implementation.\n *\n * @typeParam TSize - The number of bytes used for encoding and decoding.\n *\n * @see {@link NumberCodec}\n */\nexport type FixedSizeNumberCodec<TSize extends number = number> =\n    | FixedSizeCodec<bigint | number, bigint, TSize>\n    | FixedSizeCodec<bigint | number, number, TSize>;\n\n/**\n * Configuration options for number codecs that use more than one byte.\n *\n * This configuration applies to all number codecs except `u8` and `i8`,\n * allowing the user to specify the endianness of serialization.\n */\nexport type NumberCodecConfig = {\n    /**\n     * Specifies whether numbers should be encoded in little-endian or big-endian format.\n     *\n     * @defaultValue `Endian.Little`\n     */\n    endian?: Endian;\n};\n\n/**\n * Defines the byte order used for number serialization.\n *\n * - `Little`: The least significant byte is stored first.\n * - `Big`: The most significant byte is stored first.\n */\nexport enum Endian {\n    Little,\n    Big,\n}\n"
  },
  {
    "path": "packages/codecs-numbers/src/f32.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 32-bit floating-point numbers (`f32`).\n *\n * This encoder serializes `f32` values using 4 bytes.\n * Floating-point values may lose precision when encoded.\n *\n * For more details, see {@link getF32Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeEncoder<number, 4>` for encoding `f32` values.\n *\n * @example\n * Encoding an `f32` value.\n * ```ts\n * const encoder = getF32Encoder();\n * const bytes = encoder.encode(-1.5); // 0x0000c0bf\n * ```\n *\n * @see {@link getF32Codec}\n */\nexport const getF32Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 4> =>\n    numberEncoderFactory({\n        config,\n        name: 'f32',\n        set: (view, value, le) => view.setFloat32(0, Number(value), le),\n        size: 4,\n    });\n\n/**\n * Returns a decoder for 32-bit floating-point numbers (`f32`).\n *\n * This decoder deserializes `f32` values from 4 bytes.\n * Some precision may be lost during decoding due to floating-point representation.\n *\n * For more details, see {@link getF32Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeDecoder<number, 4>` for decoding `f32` values.\n *\n * @example\n * Decoding an `f32` value.\n * ```ts\n * const decoder = getF32Decoder();\n * const value = decoder.decode(new Uint8Array([0x00, 0x00, 0xc0, 0xbf])); // -1.5\n * ```\n *\n * @see {@link getF32Codec}\n */\nexport const getF32Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<number, 4> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => view.getFloat32(0, le),\n        name: 'f32',\n        size: 4,\n    });\n\n/**\n * Returns a codec for encoding and decoding 32-bit floating-point numbers (`f32`).\n *\n * This codec serializes `f32` values using 4 bytes.\n * Due to the IEEE 754 floating-point representation, some precision loss may occur.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeCodec<number, number, 4>` for encoding and decoding `f32` values.\n *\n * @example\n * Encoding and decoding an `f32` value.\n * ```ts\n * const codec = getF32Codec();\n * const bytes = codec.encode(-1.5); // 0x0000c0bf\n * const value = codec.decode(bytes); // -1.5\n * ```\n *\n * @example\n * Using big-endian encoding.\n * ```ts\n * const codec = getF32Codec({ endian: Endian.Big });\n * const bytes = codec.encode(-1.5); // 0xbfc00000\n * ```\n *\n * @remarks\n * `f32` values follow the IEEE 754 single-precision floating-point standard.\n * Precision loss may occur for certain values.\n *\n * - If you need higher precision, consider using {@link getF64Codec}.\n * - If you need integer values, consider using {@link getI32Codec} or {@link getU32Codec}.\n *\n * Separate {@link getF32Encoder} and {@link getF32Decoder} functions are available.\n *\n * ```ts\n * const bytes = getF32Encoder().encode(-1.5);\n * const value = getF32Decoder().decode(bytes);\n * ```\n *\n * @see {@link getF32Encoder}\n * @see {@link getF32Decoder}\n */\nexport const getF32Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, number, 4> =>\n    combineCodec(getF32Encoder(config), getF32Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/f64.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 64-bit floating-point numbers (`f64`).\n *\n * This encoder serializes `f64` values using 8 bytes.\n * Floating-point values may lose precision when encoded.\n *\n * For more details, see {@link getF64Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeEncoder<number, 8>` for encoding `f64` values.\n *\n * @example\n * Encoding an `f64` value.\n * ```ts\n * const encoder = getF64Encoder();\n * const bytes = encoder.encode(-1.5); // 0x000000000000f8bf\n * ```\n *\n * @see {@link getF64Codec}\n */\nexport const getF64Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 8> =>\n    numberEncoderFactory({\n        config,\n        name: 'f64',\n        set: (view, value, le) => view.setFloat64(0, Number(value), le),\n        size: 8,\n    });\n\n/**\n * Returns a decoder for 64-bit floating-point numbers (`f64`).\n *\n * This decoder deserializes `f64` values from 8 bytes.\n * Some precision may be lost during decoding due to floating-point representation.\n *\n * For more details, see {@link getF64Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeDecoder<number, 8>` for decoding `f64` values.\n *\n * @example\n * Decoding an `f64` value.\n * ```ts\n * const decoder = getF64Decoder();\n * const value = decoder.decode(new Uint8Array([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbf])); // -1.5\n * ```\n *\n * @see {@link getF64Codec}\n */\nexport const getF64Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<number, 8> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => view.getFloat64(0, le),\n        name: 'f64',\n        size: 8,\n    });\n\n/**\n * Returns a codec for encoding and decoding 64-bit floating-point numbers (`f64`).\n *\n * This codec serializes `f64` values using 8 bytes.\n * Due to the IEEE 754 floating-point representation, some precision loss may occur.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeCodec<number, number, 8>` for encoding and decoding `f64` values.\n *\n * @example\n * Encoding and decoding an `f64` value.\n * ```ts\n * const codec = getF64Codec();\n * const bytes = codec.encode(-1.5); // 0x000000000000f8bf\n * const value = codec.decode(bytes); // -1.5\n * ```\n *\n * @example\n * Using big-endian encoding.\n * ```ts\n * const codec = getF64Codec({ endian: Endian.Big });\n * const bytes = codec.encode(-1.5); // 0xbff8000000000000\n * ```\n *\n * @remarks\n * `f64` values follow the IEEE 754 double-precision floating-point standard.\n * Precision loss may still occur but is significantly lower than `f32`.\n *\n * - If you need smaller floating-point values, consider using {@link getF32Codec}.\n * - If you need integer values, consider using {@link getI64Codec} or {@link getU64Codec}.\n *\n * Separate {@link getF64Encoder} and {@link getF64Decoder} functions are available.\n *\n * ```ts\n * const bytes = getF64Encoder().encode(-1.5);\n * const value = getF64Decoder().decode(bytes);\n * ```\n *\n * @see {@link getF64Encoder}\n * @see {@link getF64Decoder}\n */\nexport const getF64Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, number, 8> =>\n    combineCodec(getF64Encoder(config), getF64Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/i128.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 128-bit signed integers (`i128`).\n *\n * This encoder serializes `i128` values using 16 bytes.\n * Values can be provided as either `number` or `bigint`.\n *\n * For more details, see {@link getI128Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeEncoder<number | bigint, 16>` for encoding `i128` values.\n *\n * @example\n * Encoding an `i128` value.\n * ```ts\n * const encoder = getI128Encoder();\n * const bytes = encoder.encode(-42n); // 0xd6ffffffffffffffffffffffffffffff\n * ```\n *\n * @see {@link getI128Codec}\n */\nexport const getI128Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 16> =>\n    numberEncoderFactory({\n        config,\n        name: 'i128',\n        range: [-BigInt('0x7fffffffffffffffffffffffffffffff') - 1n, BigInt('0x7fffffffffffffffffffffffffffffff')],\n        set: (view, value, le) => {\n            const leftOffset = le ? 8 : 0;\n            const rightOffset = le ? 0 : 8;\n            const rightMask = 0xffffffffffffffffn;\n            view.setBigInt64(leftOffset, BigInt(value) >> 64n, le);\n            view.setBigUint64(rightOffset, BigInt(value) & rightMask, le);\n        },\n        size: 16,\n    });\n\n/**\n * Returns a decoder for 128-bit signed integers (`i128`).\n *\n * This decoder deserializes `i128` values from 16 bytes.\n * The decoded value is always a `bigint`.\n *\n * For more details, see {@link getI128Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeDecoder<bigint, 16>` for decoding `i128` values.\n *\n * @example\n * Decoding an `i128` value.\n * ```ts\n * const decoder = getI128Decoder();\n * const value = decoder.decode(new Uint8Array([\n *   0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n *   0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff\n * ])); // -42n\n * ```\n *\n * @see {@link getI128Codec}\n */\nexport const getI128Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<bigint, 16> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => {\n            const leftOffset = le ? 8 : 0;\n            const rightOffset = le ? 0 : 8;\n            const left = view.getBigInt64(leftOffset, le);\n            const right = view.getBigUint64(rightOffset, le);\n            return (left << 64n) + right;\n        },\n        name: 'i128',\n        size: 16,\n    });\n\n/**\n * Returns a codec for encoding and decoding 128-bit signed integers (`i128`).\n *\n * This codec serializes `i128` values using 16 bytes.\n * Values can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeCodec<number | bigint, bigint, 16>` for encoding and decoding `i128` values.\n *\n * @example\n * Encoding and decoding an `i128` value.\n * ```ts\n * const codec = getI128Codec();\n * const bytes = codec.encode(-42n); // 0xd6ffffffffffffffffffffffffffffff\n * const value = codec.decode(bytes); // -42n\n * ```\n *\n * @example\n * Using big-endian encoding.\n * ```ts\n * const codec = getI128Codec({ endian: Endian.Big });\n * const bytes = codec.encode(-42n); // 0xffffffffffffffffffffffffffffd6\n * ```\n *\n * @remarks\n * This codec supports values between `-2^127` and `2^127 - 1`.\n * Since JavaScript `number` cannot safely represent values beyond `2^53 - 1`, the decoded value is always a `bigint`.\n *\n * - If you need a smaller signed integer, consider using {@link getI64Codec} or {@link getI32Codec}.\n * - If you need a larger signed integer, consider using a custom codec.\n * - If you need unsigned integers, consider using {@link getU128Codec}.\n *\n * Separate {@link getI128Encoder} and {@link getI128Decoder} functions are available.\n *\n * ```ts\n * const bytes = getI128Encoder().encode(-42);\n * const value = getI128Decoder().decode(bytes);\n * ```\n *\n * @see {@link getI128Encoder}\n * @see {@link getI128Decoder}\n */\nexport const getI128Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, bigint, 16> =>\n    combineCodec(getI128Encoder(config), getI128Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/i16.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 16-bit signed integers (`i16`).\n *\n * This encoder serializes `i16` values using 2 bytes.\n * Values can be provided as either `number` or `bigint`.\n *\n * For more details, see {@link getI16Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeEncoder<number | bigint, 2>` for encoding `i16` values.\n *\n * @example\n * Encoding an `i16` value.\n * ```ts\n * const encoder = getI16Encoder();\n * const bytes = encoder.encode(-42); // 0xd6ff\n * ```\n *\n * @see {@link getI16Codec}\n */\nexport const getI16Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 2> =>\n    numberEncoderFactory({\n        config,\n        name: 'i16',\n        range: [-Number('0x7fff') - 1, Number('0x7fff')],\n        set: (view, value, le) => view.setInt16(0, Number(value), le),\n        size: 2,\n    });\n\n/**\n * Returns a decoder for 16-bit signed integers (`i16`).\n *\n * This decoder deserializes `i16` values from 2 bytes.\n * The decoded value is always a `number`.\n *\n * For more details, see {@link getI16Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeDecoder<number, 2>` for decoding `i16` values.\n *\n * @example\n * Decoding an `i16` value.\n * ```ts\n * const decoder = getI16Decoder();\n * const value = decoder.decode(new Uint8Array([0xd6, 0xff])); // -42\n * ```\n *\n * @see {@link getI16Codec}\n */\nexport const getI16Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<number, 2> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => view.getInt16(0, le),\n        name: 'i16',\n        size: 2,\n    });\n\n/**\n * Returns a codec for encoding and decoding 16-bit signed integers (`i16`).\n *\n * This codec serializes `i16` values using 2 bytes.\n * Values can be provided as either `number` or `bigint`, but the decoded value is always a `number`.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeCodec<number | bigint, number, 2>` for encoding and decoding `i16` values.\n *\n * @example\n * Encoding and decoding an `i16` value.\n * ```ts\n * const codec = getI16Codec();\n * const bytes = codec.encode(-42); // 0xd6ff\n * const value = codec.decode(bytes); // -42\n * ```\n *\n * @example\n * Using big-endian encoding.\n * ```ts\n * const codec = getI16Codec({ endian: Endian.Big });\n * const bytes = codec.encode(-42); // 0xffd6\n * ```\n *\n * @remarks\n * This codec supports values between `-2^15` (`-32,768`) and `2^15 - 1` (`32,767`).\n *\n * - If you need a smaller signed integer, consider using {@link getI8Codec}.\n * - If you need a larger signed integer, consider using {@link getI32Codec}.\n * - If you need unsigned integers, consider using {@link getU16Codec}.\n *\n * Separate {@link getI16Encoder} and {@link getI16Decoder} functions are available.\n *\n * ```ts\n * const bytes = getI16Encoder().encode(-42);\n * const value = getI16Decoder().decode(bytes);\n * ```\n *\n * @see {@link getI16Encoder}\n * @see {@link getI16Decoder}\n */\nexport const getI16Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, number, 2> =>\n    combineCodec(getI16Encoder(config), getI16Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/i32.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 32-bit signed integers (`i32`).\n *\n * This encoder serializes `i32` values using 4 bytes.\n * Values can be provided as either `number` or `bigint`.\n *\n * For more details, see {@link getI32Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeEncoder<number | bigint, 4>` for encoding `i32` values.\n *\n * @example\n * Encoding an `i32` value.\n * ```ts\n * const encoder = getI32Encoder();\n * const bytes = encoder.encode(-42); // 0xd6ffffff\n * ```\n *\n * @see {@link getI32Codec}\n */\nexport const getI32Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 4> =>\n    numberEncoderFactory({\n        config,\n        name: 'i32',\n        range: [-Number('0x7fffffff') - 1, Number('0x7fffffff')],\n        set: (view, value, le) => view.setInt32(0, Number(value), le),\n        size: 4,\n    });\n\n/**\n * Returns a decoder for 32-bit signed integers (`i32`).\n *\n * This decoder deserializes `i32` values from 4 bytes.\n * The decoded value is always a `number`.\n *\n * For more details, see {@link getI32Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeDecoder<number, 4>` for decoding `i32` values.\n *\n * @example\n * Decoding an `i32` value.\n * ```ts\n * const decoder = getI32Decoder();\n * const value = decoder.decode(new Uint8Array([0xd6, 0xff, 0xff, 0xff])); // -42\n * ```\n *\n * @see {@link getI32Codec}\n */\nexport const getI32Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<number, 4> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => view.getInt32(0, le),\n        name: 'i32',\n        size: 4,\n    });\n\n/**\n * Returns a codec for encoding and decoding 32-bit signed integers (`i32`).\n *\n * This codec serializes `i32` values using 4 bytes.\n * Values can be provided as either `number` or `bigint`, but the decoded value is always a `number`.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeCodec<number | bigint, number, 4>` for encoding and decoding `i32` values.\n *\n * @example\n * Encoding and decoding an `i32` value.\n * ```ts\n * const codec = getI32Codec();\n * const bytes = codec.encode(-42); // 0xd6ffffff\n * const value = codec.decode(bytes); // -42\n * ```\n *\n * @example\n * Using big-endian encoding.\n * ```ts\n * const codec = getI32Codec({ endian: Endian.Big });\n * const bytes = codec.encode(-42); // 0xffffffd6\n * ```\n *\n * @remarks\n * This codec supports values between `-2^31` (`-2,147,483,648`) and `2^31 - 1` (`2,147,483,647`).\n *\n * - If you need a smaller signed integer, consider using {@link getI16Codec} or {@link getI8Codec}.\n * - If you need a larger signed integer, consider using {@link getI64Codec}.\n * - If you need unsigned integers, consider using {@link getU32Codec}.\n *\n * Separate {@link getI32Encoder} and {@link getI32Decoder} functions are available.\n *\n * ```ts\n * const bytes = getI32Encoder().encode(-42);\n * const value = getI32Decoder().decode(bytes);\n * ```\n *\n * @see {@link getI32Encoder}\n * @see {@link getI32Decoder}\n */\nexport const getI32Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, number, 4> =>\n    combineCodec(getI32Encoder(config), getI32Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/i64.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 64-bit signed integers (`i64`).\n *\n * This encoder serializes `i64` values using 8 bytes.\n * Values can be provided as either `number` or `bigint`.\n *\n * For more details, see {@link getI64Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeEncoder<number | bigint, 8>` for encoding `i64` values.\n *\n * @example\n * Encoding an `i64` value.\n * ```ts\n * const encoder = getI64Encoder();\n * const bytes = encoder.encode(-42n); // 0xd6ffffffffffffff\n * ```\n *\n * @see {@link getI64Codec}\n */\nexport const getI64Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 8> =>\n    numberEncoderFactory({\n        config,\n        name: 'i64',\n        range: [-BigInt('0x7fffffffffffffff') - 1n, BigInt('0x7fffffffffffffff')],\n        set: (view, value, le) => view.setBigInt64(0, BigInt(value), le),\n        size: 8,\n    });\n\n/**\n * Returns a decoder for 64-bit signed integers (`i64`).\n *\n * This decoder deserializes `i64` values from 8 bytes.\n * The decoded value is always a `bigint`.\n *\n * For more details, see {@link getI64Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeDecoder<bigint, 8>` for decoding `i64` values.\n *\n * @example\n * Decoding an `i64` value.\n * ```ts\n * const decoder = getI64Decoder();\n * const value = decoder.decode(new Uint8Array([\n *   0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff\n * ])); // -42n\n * ```\n *\n * @see {@link getI64Codec}\n */\nexport const getI64Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<bigint, 8> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => view.getBigInt64(0, le),\n        name: 'i64',\n        size: 8,\n    });\n\n/**\n * Returns a codec for encoding and decoding 64-bit signed integers (`i64`).\n *\n * This codec serializes `i64` values using 8 bytes.\n * Values can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeCodec<number | bigint, bigint, 8>` for encoding and decoding `i64` values.\n *\n * @example\n * Encoding and decoding an `i64` value.\n * ```ts\n * const codec = getI64Codec();\n * const bytes = codec.encode(-42n); // 0xd6ffffffffffffff\n * const value = codec.decode(bytes); // -42n\n * ```\n *\n * @example\n * Using big-endian encoding.\n * ```ts\n * const codec = getI64Codec({ endian: Endian.Big });\n * const bytes = codec.encode(-42n); // 0xffffffffffffffd6\n * ```\n *\n * @remarks\n * This codec supports values between `-2^63` and `2^63 - 1`.\n * Since JavaScript `number` cannot safely represent values beyond `2^53 - 1`, the decoded value is always a `bigint`.\n *\n * - If you need a smaller signed integer, consider using {@link getI32Codec} or {@link getI16Codec}.\n * - If you need a larger signed integer, consider using {@link getI128Codec}.\n * - If you need unsigned integers, consider using {@link getU64Codec}.\n *\n * Separate {@link getI64Encoder} and {@link getI64Decoder} functions are available.\n *\n * ```ts\n * const bytes = getI64Encoder().encode(-42);\n * const value = getI64Decoder().decode(bytes);\n * ```\n *\n * @see {@link getI64Encoder}\n * @see {@link getI64Decoder}\n */\nexport const getI64Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, bigint, 8> =>\n    combineCodec(getI64Encoder(config), getI64Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/i8.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 8-bit signed integers (`i8`).\n *\n * This encoder serializes `i8` values using 1 byte.\n * Values can be provided as either `number` or `bigint`.\n *\n * For more details, see {@link getI8Codec}.\n *\n * @returns A `FixedSizeEncoder<number | bigint, 1>` for encoding `i8` values.\n *\n * @example\n * Encoding an `i8` value.\n * ```ts\n * const encoder = getI8Encoder();\n * const bytes = encoder.encode(-42); // 0xd6\n * ```\n *\n * @see {@link getI8Codec}\n */\nexport const getI8Encoder = (): FixedSizeEncoder<bigint | number, 1> =>\n    numberEncoderFactory({\n        name: 'i8',\n        range: [-Number('0x7f') - 1, Number('0x7f')],\n        set: (view, value) => view.setInt8(0, Number(value)),\n        size: 1,\n    });\n\n/**\n * Returns a decoder for 8-bit signed integers (`i8`).\n *\n * This decoder deserializes `i8` values from 1 byte.\n * The decoded value is always a `number`.\n *\n * For more details, see {@link getI8Codec}.\n *\n * @returns A `FixedSizeDecoder<number, 1>` for decoding `i8` values.\n *\n * @example\n * Decoding an `i8` value.\n * ```ts\n * const decoder = getI8Decoder();\n * const value = decoder.decode(new Uint8Array([0xd6])); // -42\n * ```\n *\n * @see {@link getI8Codec}\n */\nexport const getI8Decoder = (): FixedSizeDecoder<number, 1> =>\n    numberDecoderFactory({\n        get: view => view.getInt8(0),\n        name: 'i8',\n        size: 1,\n    });\n\n/**\n * Returns a codec for encoding and decoding 8-bit signed integers (`i8`).\n *\n * This codec serializes `i8` values using 1 byte.\n * Values can be provided as either `number` or `bigint`, but the decoded value is always a `number`.\n *\n * @returns A `FixedSizeCodec<number | bigint, number, 1>` for encoding and decoding `i8` values.\n *\n * @example\n * Encoding and decoding an `i8` value.\n * ```ts\n * const codec = getI8Codec();\n * const bytes = codec.encode(-42); // 0xd6\n * const value = codec.decode(bytes); // -42\n * ```\n *\n * @remarks\n * This codec supports values between `-2^7` (`-128`) and `2^7 - 1` (`127`).\n *\n * - If you need a larger signed integer, consider using {@link getI16Codec}.\n * - If you need an unsigned integer, consider using {@link getU8Codec}.\n *\n * Separate {@link getI8Encoder} and {@link getI8Decoder} functions are available.\n *\n * ```ts\n * const bytes = getI8Encoder().encode(-42);\n * const value = getI8Decoder().decode(bytes);\n * ```\n *\n * @see {@link getI8Encoder}\n * @see {@link getI8Decoder}\n */\nexport const getI8Codec = (): FixedSizeCodec<bigint | number, number, 1> =>\n    combineCodec(getI8Encoder(), getI8Decoder());\n"
  },
  {
    "path": "packages/codecs-numbers/src/index.ts",
    "content": "/**\n * This package contains codecs for numbers of different sizes and endianness.\n * It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * This package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs)\n * which acts as an entry point for all codec packages as well as for their documentation.\n *\n * @packageDocumentation\n */\nexport * from './assertions';\nexport * from './common';\nexport * from './f32';\nexport * from './f64';\nexport * from './i128';\nexport * from './i16';\nexport * from './i32';\nexport * from './i64';\nexport * from './i8';\nexport * from './short-u16';\nexport * from './u128';\nexport * from './u16';\nexport * from './u32';\nexport * from './u64';\nexport * from './u8';\n"
  },
  {
    "path": "packages/codecs-numbers/src/short-u16.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    Offset,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertNumberIsBetweenForCodec } from './assertions';\n\n/**\n * Returns an encoder for `shortU16` values.\n *\n * This encoder serializes `shortU16` values using **1 to 3 bytes**.\n * Smaller values use fewer bytes, while larger values take up more space.\n *\n * For more details, see {@link getShortU16Codec}.\n *\n * @returns A `VariableSizeEncoder<number | bigint>` for encoding `shortU16` values.\n *\n * @example\n * Encoding a `shortU16` value.\n * ```ts\n * const encoder = getShortU16Encoder();\n * encoder.encode(42);    // 0x2a\n * encoder.encode(128);   // 0x8001\n * encoder.encode(16384); // 0x808001\n * ```\n *\n * @see {@link getShortU16Codec}\n */\nexport const getShortU16Encoder = (): VariableSizeEncoder<bigint | number> =>\n    createEncoder({\n        getSizeFromValue: (value: bigint | number): number => {\n            if (value <= 0b01111111) return 1;\n            if (value <= 0b0011111111111111) return 2;\n            return 3;\n        },\n        maxSize: 3,\n        write: (value: bigint | number, bytes: Uint8Array, offset: Offset): Offset => {\n            assertNumberIsBetweenForCodec('shortU16', 0, 65535, value);\n            const shortU16Bytes = [0];\n            for (let ii = 0; ; ii += 1) {\n                // Shift the bits of the value over such that the next 7 bits are at the right edge.\n                const alignedValue = Number(value) >> (ii * 7);\n                if (alignedValue === 0) {\n                    // No more bits to consume.\n                    break;\n                }\n                // Extract those 7 bits using a mask.\n                const nextSevenBits = 0b1111111 & alignedValue;\n                shortU16Bytes[ii] = nextSevenBits;\n                if (ii > 0) {\n                    // Set the continuation bit of the previous slice.\n                    shortU16Bytes[ii - 1] |= 0b10000000;\n                }\n            }\n            bytes.set(shortU16Bytes, offset);\n            return offset + shortU16Bytes.length;\n        },\n    });\n\n/**\n * Returns a decoder for `shortU16` values.\n *\n * This decoder deserializes `shortU16` values from **1 to 3 bytes**.\n * The number of bytes used depends on the encoded value.\n *\n * For more details, see {@link getShortU16Codec}.\n *\n * @returns A `VariableSizeDecoder<number>` for decoding `shortU16` values.\n *\n * @example\n * Decoding a `shortU16` value.\n * ```ts\n * const decoder = getShortU16Decoder();\n * decoder.decode(new Uint8Array([0x2a]));             // 42\n * decoder.decode(new Uint8Array([0x80, 0x01]));       // 128\n * decoder.decode(new Uint8Array([0x80, 0x80, 0x01])); // 16384\n * ```\n *\n * @see {@link getShortU16Codec}\n */\nexport const getShortU16Decoder = (): VariableSizeDecoder<number> =>\n    createDecoder({\n        maxSize: 3,\n        read: (bytes: ReadonlyUint8Array | Uint8Array, offset): [number, Offset] => {\n            let value = 0;\n            let byteCount = 0;\n            while (++byteCount) {\n                const byteIndex = byteCount - 1;\n                const currentByte = bytes[offset + byteIndex];\n                const nextSevenBits = 0b1111111 & currentByte;\n                // Insert the next group of seven bits into the correct slot of the output value.\n                value |= nextSevenBits << (byteIndex * 7);\n                if ((currentByte & 0b10000000) === 0) {\n                    // This byte does not have its continuation bit set. We're done.\n                    break;\n                }\n            }\n            return [value, offset + byteCount];\n        },\n    });\n\n/**\n * Returns a codec for encoding and decoding `shortU16` values.\n *\n * It serializes unsigned integers using **1 to 3 bytes** based on the encoded value.\n * The larger the value, the more bytes it uses.\n *\n * - If the value is `<= 0x7f` (127), it is stored in a **single byte**\n *   and the first bit is set to `0` to indicate the end of the value.\n * - Otherwise, the first bit is set to `1` to indicate that the value continues in the next byte, which follows the same pattern.\n * - This process repeats until the value is fully encoded in up to 3 bytes. The third and last byte, if needed, uses all 8 bits to store the remaining value.\n *\n * In other words, the encoding scheme follows this structure:\n *\n * ```txt\n * 0XXXXXXX                   <- Values 0 to 127 (1 byte)\n * 1XXXXXXX 0XXXXXXX          <- Values 128 to 16,383 (2 bytes)\n * 1XXXXXXX 1XXXXXXX XXXXXXXX <- Values 16,384 to 4,194,303 (3 bytes)\n * ```\n *\n * @returns A `VariableSizeCodec<number | bigint, number>` for encoding and decoding `shortU16` values.\n *\n * @example\n * Encoding and decoding `shortU16` values.\n * ```ts\n * const codec = getShortU16Codec();\n * const bytes1 = codec.encode(42);    // 0x2a\n * const bytes2 = codec.encode(128);   // 0x8001\n * const bytes3 = codec.encode(16384); // 0x808001\n *\n * codec.decode(bytes1); // 42\n * codec.decode(bytes2); // 128\n * codec.decode(bytes3); // 16384\n * ```\n *\n * @remarks\n * This codec efficiently stores small numbers, making it useful for transactions and compact representations.\n *\n * If you need a fixed-size `u16` codec, consider using {@link getU16Codec}.\n *\n * Separate {@link getShortU16Encoder} and {@link getShortU16Decoder} functions are available.\n *\n * ```ts\n * const bytes = getShortU16Encoder().encode(42);\n * const value = getShortU16Decoder().decode(bytes);\n * ```\n *\n * @see {@link getShortU16Encoder}\n * @see {@link getShortU16Decoder}\n */\nexport const getShortU16Codec = (): VariableSizeCodec<bigint | number, number> =>\n    combineCodec(getShortU16Encoder(), getShortU16Decoder());\n"
  },
  {
    "path": "packages/codecs-numbers/src/u128.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 128-bit unsigned integers (`u128`).\n *\n * This encoder serializes `u128` values using sixteen bytes in little-endian format by default.\n * You may specify big-endian storage using the `endian` option.\n *\n * For more details, see {@link getU128Codec}.\n *\n * @param config - Optional settings for endianness.\n * @returns A `FixedSizeEncoder<number | bigint, 16>` for encoding `u128` values.\n *\n * @example\n * Encoding a `u128` value.\n * ```ts\n * const encoder = getU128Encoder();\n * const bytes = encoder.encode(42n); // 0x2a000000000000000000000000000000\n * ```\n *\n * @see {@link getU128Codec}\n */\nexport const getU128Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 16> =>\n    numberEncoderFactory({\n        config,\n        name: 'u128',\n        range: [0n, BigInt('0xffffffffffffffffffffffffffffffff')],\n        set: (view, value, le) => {\n            const leftOffset = le ? 8 : 0;\n            const rightOffset = le ? 0 : 8;\n            const rightMask = 0xffffffffffffffffn;\n            view.setBigUint64(leftOffset, BigInt(value) >> 64n, le);\n            view.setBigUint64(rightOffset, BigInt(value) & rightMask, le);\n        },\n        size: 16,\n    });\n\n/**\n * Returns a decoder for 128-bit unsigned integers (`u128`).\n *\n * This decoder deserializes `u128` values from sixteen bytes in little-endian format by default.\n * You may specify big-endian storage using the `endian` option.\n *\n * For more details, see {@link getU128Codec}.\n *\n * @param config - Optional settings for endianness.\n * @returns A `FixedSizeDecoder<bigint, 16>` for decoding `u128` values.\n *\n * @example\n * Decoding a `u128` value.\n * ```ts\n * const decoder = getU128Decoder();\n * const value = decoder.decode(new Uint8Array([0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); // 42n\n * ```\n *\n * @see {@link getU128Codec}\n */\nexport const getU128Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<bigint, 16> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => {\n            const leftOffset = le ? 8 : 0;\n            const rightOffset = le ? 0 : 8;\n            const left = view.getBigUint64(leftOffset, le);\n            const right = view.getBigUint64(rightOffset, le);\n            return (left << 64n) + right;\n        },\n        name: 'u128',\n        size: 16,\n    });\n\n/**\n * Returns a codec for encoding and decoding 128-bit unsigned integers (`u128`).\n *\n * This codec serializes `u128` values using 16 bytes.\n * Values can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeCodec<number | bigint, bigint, 16>` for encoding and decoding `u128` values.\n *\n * @example\n * Encoding and decoding a `u128` value.\n * ```ts\n * const codec = getU128Codec();\n * const bytes = codec.encode(42); // 0x2a000000000000000000000000000000\n * const value = codec.decode(bytes); // 42n\n * ```\n *\n * @example\n * Using big-endian encoding.\n * ```ts\n * const codec = getU128Codec({ endian: Endian.Big });\n * const bytes = codec.encode(42); // 0x0000000000000000000000000000002a\n * ```\n *\n * @remarks\n * This codec supports values between `0` and `2^128 - 1`.\n * Since JavaScript `number` cannot safely represent values beyond `2^53 - 1`, the decoded value is always a `bigint`.\n *\n * - If you need a smaller unsigned integer, consider using {@link getU64Codec} or {@link getU32Codec}.\n * - If you need signed integers, consider using {@link getI128Codec}.\n *\n * Separate {@link getU128Encoder} and {@link getU128Decoder} functions are available.\n *\n * ```ts\n * const bytes = getU128Encoder().encode(42);\n * const value = getU128Decoder().decode(bytes);\n * ```\n *\n * @see {@link getU128Encoder}\n * @see {@link getU128Decoder}\n */\nexport const getU128Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, bigint, 16> =>\n    combineCodec(getU128Encoder(config), getU128Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/u16.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 16-bit unsigned integers (`u16`).\n *\n * This encoder serializes `u16` values using two bytes in little-endian format by default.\n * You may specify big-endian storage using the `endian` option.\n *\n * For more details, see {@link getU16Codec}.\n *\n * @param config - Optional settings for endianness.\n * @returns A `FixedSizeEncoder<number | bigint, 2>` for encoding `u16` values.\n *\n * @example\n * Encoding a `u16` value.\n * ```ts\n * const encoder = getU16Encoder();\n * const bytes = encoder.encode(42); // 0x2a00\n * ```\n *\n * @see {@link getU16Codec}\n */\nexport const getU16Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 2> =>\n    numberEncoderFactory({\n        config,\n        name: 'u16',\n        range: [0, Number('0xffff')],\n        set: (view, value, le) => view.setUint16(0, Number(value), le),\n        size: 2,\n    });\n\n/**\n * Returns a decoder for 16-bit unsigned integers (`u16`).\n *\n * This decoder deserializes `u16` values from two bytes in little-endian format by default.\n * You may specify big-endian storage using the `endian` option.\n *\n * For more details, see {@link getU16Codec}.\n *\n * @param config - Optional settings for endianness.\n * @returns A `FixedSizeDecoder<number, 2>` for decoding `u16` values.\n *\n * @example\n * Decoding a `u16` value.\n * ```ts\n * const decoder = getU16Decoder();\n * const value = decoder.decode(new Uint8Array([0x2a, 0x00])); // 42\n * ```\n *\n * @see {@link getU16Codec}\n */\nexport const getU16Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<number, 2> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => view.getUint16(0, le),\n        name: 'u16',\n        size: 2,\n    });\n\n/**\n * Returns a codec for encoding and decoding 16-bit unsigned integers (`u16`).\n *\n * This codec serializes `u16` values using two bytes in little-endian format by default.\n * You may specify big-endian storage using the `endian` option.\n *\n * @param config - Optional settings for endianness.\n * @returns A `FixedSizeCodec<number | bigint, number, 2>` for encoding and decoding `u16` values.\n *\n * @example\n * Encoding and decoding a `u16` value.\n * ```ts\n * const codec = getU16Codec();\n * const bytes = codec.encode(42); // 0x2a00 (little-endian)\n * const value = codec.decode(bytes); // 42\n * ```\n *\n * @example\n * Storing values in big-endian format.\n * ```ts\n * const codec = getU16Codec({ endian: Endian.Big });\n * const bytes = codec.encode(42); // 0x002a\n * ```\n *\n * @remarks\n * This codec supports values between `0` and `2^16 - 1`.\n * If you need a larger range, consider using {@link getU32Codec} or {@link getU64Codec}.\n * For signed integers, use {@link getI16Codec}.\n *\n * Separate {@link getU16Encoder} and {@link getU16Decoder} functions are available.\n *\n * ```ts\n * const bytes = getU16Encoder().encode(42);\n * const value = getU16Decoder().decode(bytes);\n * ```\n *\n * @see {@link getU16Encoder}\n * @see {@link getU16Decoder}\n */\nexport const getU16Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, number, 2> =>\n    combineCodec(getU16Encoder(config), getU16Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/u32.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 32-bit unsigned integers (`u32`).\n *\n * This encoder serializes `u32` values using four bytes in little-endian format by default.\n * You may specify big-endian storage using the `endian` option.\n *\n * For more details, see {@link getU32Codec}.\n *\n * @param config - Optional settings for endianness.\n * @returns A `FixedSizeEncoder<bigint | number, 4>` for encoding `u32` values.\n *\n * @example\n * Encoding a `u32` value.\n * ```ts\n * const encoder = getU32Encoder();\n * const bytes = encoder.encode(42); // 0x2a000000\n * ```\n *\n * @see {@link getU32Codec}\n */\nexport const getU32Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 4> =>\n    numberEncoderFactory({\n        config,\n        name: 'u32',\n        range: [0, Number('0xffffffff')],\n        set: (view, value, le) => view.setUint32(0, Number(value), le),\n        size: 4,\n    });\n\n/**\n * Returns a decoder for 32-bit unsigned integers (`u32`).\n *\n * This decoder deserializes `u32` values from four bytes in little-endian format by default.\n * You may specify big-endian storage using the `endian` option.\n *\n * For more details, see {@link getU32Codec}.\n *\n * @param config - Optional settings for endianness.\n * @returns A `FixedSizeDecoder<number, 4>` for decoding `u32` values.\n *\n * @example\n * Decoding a `u32` value.\n * ```ts\n * const decoder = getU32Decoder();\n * const value = decoder.decode(new Uint8Array([0x2a, 0x00, 0x00, 0x00])); // 42\n * ```\n *\n * @see {@link getU32Codec}\n */\nexport const getU32Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<number, 4> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => view.getUint32(0, le),\n        name: 'u32',\n        size: 4,\n    });\n\n/**\n * Returns a codec for encoding and decoding 32-bit unsigned integers (`u32`).\n *\n * This codec serializes `u32` values using four bytes in little-endian format by default.\n * You may specify big-endian storage using the `endian` option.\n *\n * @param config - Optional settings for endianness.\n * @returns A `FixedSizeCodec<bigint | number, number, 4>` for encoding and decoding `u32` values.\n *\n * @example\n * Encoding and decoding a `u32` value.\n * ```ts\n * const codec = getU32Codec();\n * const bytes = codec.encode(42); // 0x2a000000 (little-endian)\n * const value = codec.decode(bytes); // 42\n * ```\n *\n * @example\n * Storing values in big-endian format.\n * ```ts\n * const codec = getU32Codec({ endian: Endian.Big });\n * const bytes = codec.encode(42); // 0x0000002a\n * ```\n *\n * @remarks\n * This codec only supports values between `0` and `2^32 - 1`.\n * If you need a larger range, consider using {@link getU64Codec} or {@link getU128Codec}.\n * For signed integers, use {@link getI32Codec}.\n *\n * Separate {@link getU32Encoder} and {@link getU32Decoder} functions are available.\n *\n * ```ts\n * const bytes = getU32Encoder().encode(42);\n * const value = getU32Decoder().decode(bytes);\n * ```\n *\n * @see {@link getU32Encoder}\n * @see {@link getU32Decoder}\n */\nexport const getU32Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, number, 4> =>\n    combineCodec(getU32Encoder(config), getU32Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/u64.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { NumberCodecConfig } from './common';\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 64-bit unsigned integers (`u64`).\n *\n * This encoder serializes `u64` values using 8 bytes.\n * Values can be provided as either `number` or `bigint`.\n *\n * For more details, see {@link getU64Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeEncoder<number | bigint, 8>` for encoding `u64` values.\n *\n * @example\n * Encoding a `u64` value.\n * ```ts\n * const encoder = getU64Encoder();\n * const bytes = encoder.encode(42); // 0x2a00000000000000\n * ```\n *\n * @see {@link getU64Codec}\n */\nexport const getU64Encoder = (config: NumberCodecConfig = {}): FixedSizeEncoder<bigint | number, 8> =>\n    numberEncoderFactory({\n        config,\n        name: 'u64',\n        range: [0n, BigInt('0xffffffffffffffff')],\n        set: (view, value, le) => view.setBigUint64(0, BigInt(value), le),\n        size: 8,\n    });\n\n/**\n * Returns a decoder for 64-bit unsigned integers (`u64`).\n *\n * This decoder deserializes `u64` values from 8 bytes.\n * The decoded value is always a `bigint`.\n *\n * For more details, see {@link getU64Codec}.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeDecoder<bigint, 8>` for decoding `u64` values.\n *\n * @example\n * Decoding a `u64` value.\n * ```ts\n * const decoder = getU64Decoder();\n * const value = decoder.decode(new Uint8Array([0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])); // 42n\n * ```\n *\n * @see {@link getU64Codec}\n */\nexport const getU64Decoder = (config: NumberCodecConfig = {}): FixedSizeDecoder<bigint, 8> =>\n    numberDecoderFactory({\n        config,\n        get: (view, le) => view.getBigUint64(0, le),\n        name: 'u64',\n        size: 8,\n    });\n\n/**\n * Returns a codec for encoding and decoding 64-bit unsigned integers (`u64`).\n *\n * This codec serializes `u64` values using 8 bytes.\n * Values can be provided as either `number` or `bigint`, but the decoded value is always a `bigint`.\n *\n * @param config - Optional configuration to specify endianness (little by default).\n * @returns A `FixedSizeCodec<number | bigint, bigint, 8>` for encoding and decoding `u64` values.\n *\n * @example\n * Encoding and decoding a `u64` value.\n * ```ts\n * const codec = getU64Codec();\n * const bytes = codec.encode(42); // 0x2a00000000000000\n * const value = codec.decode(bytes); // 42n\n * ```\n *\n * @example\n * Using big-endian encoding.\n * ```ts\n * const codec = getU64Codec({ endian: Endian.Big });\n * const bytes = codec.encode(42); // 0x000000000000002a\n * ```\n *\n * @remarks\n * This codec supports values between `0` and `2^64 - 1`.\n * Since JavaScript `number` cannot safely represent values beyond `2^53 - 1`, the decoded value is always a `bigint`.\n *\n * - If you need a smaller unsigned integer, consider using {@link getU32Codec} or {@link getU16Codec}.\n * - If you need a larger unsigned integer, consider using {@link getU128Codec}.\n * - If you need signed integers, consider using {@link getI64Codec}.\n *\n * Separate {@link getU64Encoder} and {@link getU64Decoder} functions are available.\n *\n * ```ts\n * const bytes = getU64Encoder().encode(42);\n * const value = getU64Decoder().decode(bytes);\n * ```\n *\n * @see {@link getU64Encoder}\n * @see {@link getU64Decoder}\n */\nexport const getU64Codec = (config: NumberCodecConfig = {}): FixedSizeCodec<bigint | number, bigint, 8> =>\n    combineCodec(getU64Encoder(config), getU64Decoder(config));\n"
  },
  {
    "path": "packages/codecs-numbers/src/u8.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport { numberDecoderFactory, numberEncoderFactory } from './utils';\n\n/**\n * Returns an encoder for 8-bit unsigned integers (`u8`).\n *\n * This encoder serializes `u8` values using a single byte.\n *\n * For more details, see {@link getU8Codec}.\n *\n * @returns A `FixedSizeEncoder<number | bigint, 1>` for encoding `u8` values.\n *\n * @example\n * Encoding a `u8` value.\n * ```ts\n * const encoder = getU8Encoder();\n * const bytes = encoder.encode(42); // 0x2a\n * ```\n *\n * @see {@link getU8Codec}\n */\nexport const getU8Encoder = (): FixedSizeEncoder<bigint | number, 1> =>\n    numberEncoderFactory({\n        name: 'u8',\n        range: [0, Number('0xff')],\n        set: (view, value) => view.setUint8(0, Number(value)),\n        size: 1,\n    });\n\n/**\n * Returns a decoder for 8-bit unsigned integers (`u8`).\n *\n * This decoder deserializes `u8` values from a single byte.\n *\n * For more details, see {@link getU8Codec}.\n *\n * @returns A `FixedSizeDecoder<number, 1>` for decoding `u8` values.\n *\n * @example\n * Decoding a `u8` value.\n * ```ts\n * const decoder = getU8Decoder();\n * const value = decoder.decode(new Uint8Array([0xff])); // 255\n * ```\n *\n * @see {@link getU8Codec}\n */\nexport const getU8Decoder = (): FixedSizeDecoder<number, 1> =>\n    numberDecoderFactory({\n        get: view => view.getUint8(0),\n        name: 'u8',\n        size: 1,\n    });\n\n/**\n * Returns a codec for encoding and decoding 8-bit unsigned integers (`u8`).\n *\n * This codec serializes `u8` values using a single byte.\n *\n * @returns A `FixedSizeCodec<number | bigint, number, 1>` for encoding and decoding `u8` values.\n *\n * @example\n * Encoding and decoding a `u8` value.\n * ```ts\n * const codec = getU8Codec();\n * const bytes = codec.encode(255); // 0xff\n * const value = codec.decode(bytes); // 255\n * ```\n *\n * @remarks\n * This codec supports values between `0` and `2^8 - 1` (0 to 255).\n * If you need larger integers, consider using {@link getU16Codec}, {@link getU32Codec}, or {@link getU64Codec}.\n * For signed integers, use {@link getI8Codec}.\n *\n * Separate {@link getU8Encoder} and {@link getU8Decoder} functions are available.\n *\n * ```ts\n * const bytes = getU8Encoder().encode(42);\n * const value = getU8Decoder().decode(bytes);\n * ```\n *\n * @see {@link getU8Encoder}\n * @see {@link getU8Decoder}\n */\nexport const getU8Codec = (): FixedSizeCodec<bigint | number, number, 1> =>\n    combineCodec(getU8Encoder(), getU8Decoder());\n"
  },
  {
    "path": "packages/codecs-numbers/src/utils.ts",
    "content": "import {\n    assertByteArrayHasEnoughBytesForCodec,\n    assertByteArrayIsNotEmptyForCodec,\n    createDecoder,\n    createEncoder,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    Offset,\n    toArrayBuffer,\n} from '@solana/codecs-core';\n\nimport { assertNumberIsBetweenForCodec } from './assertions';\nimport { Endian, NumberCodecConfig } from './common';\n\ntype NumberFactorySharedInput<TSize extends number> = {\n    config?: NumberCodecConfig;\n    name: string;\n    size: TSize;\n};\n\ntype NumberFactoryEncoderInput<TFrom, TSize extends number> = NumberFactorySharedInput<TSize> & {\n    range?: [bigint | number, bigint | number];\n    set: (view: DataView, value: TFrom, littleEndian?: boolean) => void;\n};\n\ntype NumberFactoryDecoderInput<TTo, TSize extends number> = NumberFactorySharedInput<TSize> & {\n    get: (view: DataView, littleEndian?: boolean) => TTo;\n};\n\nfunction isLittleEndian(config?: NumberCodecConfig): boolean {\n    return config?.endian === Endian.Big ? false : true;\n}\n\nexport function numberEncoderFactory<TFrom extends bigint | number, TSize extends number>(\n    input: NumberFactoryEncoderInput<TFrom, TSize>,\n): FixedSizeEncoder<TFrom, TSize> {\n    return createEncoder({\n        fixedSize: input.size,\n        write(value: TFrom, bytes: Uint8Array, offset: Offset): Offset {\n            if (input.range) {\n                assertNumberIsBetweenForCodec(input.name, input.range[0], input.range[1], value);\n            }\n            const arrayBuffer = new ArrayBuffer(input.size);\n            input.set(new DataView(arrayBuffer), value, isLittleEndian(input.config));\n            bytes.set(new Uint8Array(arrayBuffer), offset);\n            return offset + input.size;\n        },\n    });\n}\n\nexport function numberDecoderFactory<TTo extends bigint | number, TSize extends number>(\n    input: NumberFactoryDecoderInput<TTo, TSize>,\n): FixedSizeDecoder<TTo, TSize> {\n    return createDecoder({\n        fixedSize: input.size,\n        read(bytes, offset = 0): [TTo, number] {\n            assertByteArrayIsNotEmptyForCodec(input.name, bytes, offset);\n            assertByteArrayHasEnoughBytesForCodec(input.name, input.size, bytes, offset);\n            const view = new DataView(toArrayBuffer(bytes, offset, input.size));\n            return [input.get(view, isLittleEndian(input.config)), offset + input.size];\n        },\n    });\n}\n"
  },
  {
    "path": "packages/codecs-numbers/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/codecs-numbers/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/codecs-numbers\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"],\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2017.String\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    }\n}\n"
  },
  {
    "path": "packages/codecs-numbers/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/codecs-strings/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/codecs-strings/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/codecs-strings/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/codecs-strings/CHANGELOG.md",
    "content": "# @solana/codecs-strings\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-numbers@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-numbers@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- [#1391](https://github.com/anza-xyz/kit/pull/1391) [`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c) Thanks [@holps-7](https://github.com/holps-7)! - Fix unnecessary array slicing/cloning when using negative offsets matching the array length.\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-numbers@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-numbers@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-numbers@6.0.1\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-numbers@6.0.0\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-numbers@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-numbers@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-numbers@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-numbers@5.3.0\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- [#1116](https://github.com/anza-xyz/kit/pull/1116) [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549) Thanks [@steveluscher](https://github.com/steveluscher)! - Any `SharedArrayBuffer` that gets passed to a crypto operation like `signBytes` or `verifySignature` will now be copied as non-shared. Crypto operations like `sign` and `verify` reject `SharedArrayBuffers` otherwise\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-numbers@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#999](https://github.com/anza-xyz/kit/pull/999) [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97) Thanks [@tmm](https://github.com/tmm)! - Some npm packages are needed for specific runtimes only (eg. React Native, Node). To prevent package managers from unconditionally installing these packages when they have `auto-install-peers` enabled, we are marking them as optional in `peerDependenciesMeta`. When running in React Native, be sure to explicitly install `fastestsmallesttextencoderdecoder`. When running in Node, be sure to explicitly install `ws`. When using `@solana/react`, we will presume that you have already installed `react`.\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/codecs-numbers@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-numbers@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/codecs-numbers@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/codecs-numbers@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-numbers@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-numbers@2.2.1\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-numbers@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-numbers@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-numbers@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2397](https://github.com/solana-labs/solana-web3.js/pull/2397) [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `addCodecSizePrefix` primitive\n\n    ```ts\n    const codec = addCodecSizePrefix(getBase58Codec(), getU32Codec());\n\n    codec.encode('hello world');\n    // 0x0b00000068656c6c6f20776f726c64\n    //   |       └-- Our encoded base-58 string.\n    //   └-- Our encoded u32 size prefix.\n    ```\n\n- [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7) Thanks [@steveluscher](https://github.com/steveluscher)! - Converting a base16 string to a byte buffer is now between 2-3x faster (Thanks @tibi77!)\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/codecs-numbers@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-numbers@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-numbers@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-numbers@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-numbers@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-numbers@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7) Thanks [@steveluscher](https://github.com/steveluscher)! - Converting a base16 string to a byte buffer is now between 2-3x faster (Thanks @tibi77!)\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/codecs-numbers@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2397](https://github.com/solana-labs/solana-web3.js/pull/2397) [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `addCodecSizePrefix` primitive\n\n    ```ts\n    const codec = addCodecSizePrefix(getBase58Codec(), getU32Codec());\n\n    codec.encode('hello world');\n    // 0x0b00000068656c6c6f20776f726c64\n    //   |       └-- Our encoded base-58 string.\n    //   └-- Our encoded u32 size prefix.\n    ```\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/codecs-numbers@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-numbers@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/codecs-strings/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/codecs-strings/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/codecs-strings?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/codecs-strings?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/codecs-strings\n\n# @solana/codecs-strings\n\nThis package contains codecs for strings of different sizes and encodings. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nThis package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) which acts as an entry point for all codec packages as well as for their documentation.\n\n## Sizing string codecs\n\nThe `@solana/codecs-strings` package offers a variety of string codecs such as `utf8`, `base58`, `base64`, etc — which we will discuss in more detail below. However, before digging into the available string codecs, it's important to understand the different sizing strategies available for string codecs.\n\nBy default, all available string codecs will return a `VariableSizeCodec<string>` meaning that:\n\n- When encoding a string, all bytes necessary to encode the string will be used.\n- When decoding a byte array at a given offset, all bytes starting from that offset will be decoded as a string.\n\nFor instance, here's how you can encode/decode `utf8` strings without any size boundary:\n\n```ts\nconst codec = getUtf8Codec();\n\ncodec.encode('hello');\n// 0x68656c6c6f\n//   └-- Any bytes necessary to encode our content.\n\ncodec.decode(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f]));\n// 'hello'\n```\n\nThis might be what you want — e.g. when having a string at the end of a data structure — but in many cases, you might want to have a size boundary for your string. You may achieve this by composing your string codec with the [`fixCodecSize`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#fixing-the-size-of-codecs) or [`addCodecSizePrefix`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#prefixing-the-size-of-codecs) functions.\n\nThe `fixCodecSize` function accepts a fixed byte length and returns a `FixedSizeCodec<string>` that will always use that amount of bytes to encode and decode a string. Any string longer or smaller than that size will be truncated or padded respectively. Here's how you can use it with a `utf8` codec:\n\n```ts\nconst codec = fixCodecSize(getUtf8Codec(), 5);\n\ncodec.encode('hello');\n// 0x68656c6c6f\n//   └-- The exact 5 bytes of content.\n\ncodec.encode('hello world');\n// 0x68656c6c6f\n//   └-- The truncated 5 bytes of content.\n\ncodec.encode('hell');\n// 0x68656c6c00\n//   └-- The padded 5 bytes of content.\n\ncodec.decode(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xff, 0xff, 0xff, 0xff]));\n// 'hello'\n```\n\nThe `addCodecSizePrefix` function accepts an additional number codec that will be used to encode and decode a size prefix for the string. This prefix allows us to know when to stop reading the string when decoding a given byte array. Here's how you can use it with a `utf8` codec:\n\n```ts\nconst codec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n\ncodec.encode('hello');\n// 0x0500000068656c6c6f\n//   |       └-- The 5 bytes of content.\n//   └-- 4-byte prefix telling us to read 5 bytes.\n\ncodec.decode(new Uint8Array([0x05, 0x00, 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xff, 0xff, 0xff, 0xff]));\n// \"hello\"\n```\n\nNow, let's take a look at the available string encodings. Just remember that you can use the `fixSizeCodec` or `prefixSizeCodec` functions on any of these encodings to add a size boundary to them.\n\n## Utf8 codec\n\nThe `getUtf8Codec` function encodes and decodes a UTF-8 string to and from a byte array.\n\n```ts\nconst bytes = getUtf8Codec().encode('hello'); // 0x68656c6c6f\nconst value = getUtf8Codec().decode(bytes); // \"hello\"\n```\n\nAs usual, separate `getUtf8Encoder` and `getUtf8Decoder` functions are also available.\n\n```ts\nconst bytes = getUtf8Encoder().encode('hello'); // 0x68656c6c6f\nconst value = getUtf8Decoder().decode(bytes); // \"hello\"\n```\n\n## Base 64 codec\n\nThe `getBase64Codec` function encodes and decodes a base-64 string to and from a byte array.\n\n```ts\nconst bytes = getBase64Codec().encode('hello+world'); // 0x85e965a3ec28ae57\nconst value = getBase64Codec().decode(bytes); // \"hello+world\"\n```\n\nAs usual, separate `getBase64Encoder` and `getBase64Decoder` functions are also available.\n\n```ts\nconst bytes = getBase64Encoder().encode('hello+world'); // 0x85e965a3ec28ae57\nconst value = getBase64Decoder().decode(bytes); // \"hello+world\"\n```\n\n## Base 58 codec\n\nThe `getBase58Codec` function encodes and decodes a base-58 string to and from a byte array.\n\n```ts\nconst bytes = getBase58Codec().encode('heLLo'); // 0x1b6a3070\nconst value = getBase58Codec().decode(bytes); // \"heLLo\"\n```\n\nAs usual, separate `getBase58Encoder` and `getBase58Decoder` functions are also available.\n\n```ts\nconst bytes = getBase58Encoder().encode('heLLo'); // 0x1b6a3070\nconst value = getBase58Decoder().decode(bytes); // \"heLLo\"\n```\n\n## Base 16 codec\n\nThe `getBase16Codec` function encodes and decodes a base-16 string to and from a byte array.\n\n```ts\nconst bytes = getBase16Codec().encode('deadface'); // 0xdeadface\nconst value = getBase16Codec().decode(bytes); // \"deadface\"\n```\n\nAs usual, separate `getBase16Encoder` and `getBase16Decoder` functions are also available.\n\n```ts\nconst bytes = getBase16Encoder().encode('deadface'); // 0xdeadface\nconst value = getBase16Decoder().decode(bytes); // \"deadface\"\n```\n\n## Base 10 codec\n\nThe `getBase10Codec` function encodes and decodes a base-10 string to and from a byte array.\n\n```ts\nconst bytes = getBase10Codec().encode('1024'); // 0x0400\nconst value = getBase10Codec().decode(bytes); // \"1024\"\n```\n\nAs usual, separate `getBase10Encoder` and `getBase10Decoder` functions are also available.\n\n```ts\nconst bytes = getBase10Encoder().encode('1024'); // 0x0400\nconst value = getBase10Decoder().decode(bytes); // \"1024\"\n```\n\n## Base X codec\n\nThe `getBaseXCodec` accepts a custom `alphabet` of `X` characters and creates a base-X codec using that alphabet. It does so by iteratively dividing by `X` and handling leading zeros.\n\nThe base-10 and base-58 codecs use this base-x codec under the hood.\n\n```ts\nconst alphabet = '0ehlo';\nconst bytes = getBaseXCodec(alphabet).encode('hello'); // 0x05bd\nconst value = getBaseXCodec(alphabet).decode(bytes); // \"hello\"\n```\n\nAs usual, separate `getBaseXEncoder` and `getBaseXDecoder` functions are also available.\n\n```ts\nconst bytes = getBaseXEncoder(alphabet).encode('hello'); // 0x05bd\nconst value = getBaseXDecoder(alphabet).decode(bytes); // \"hello\"\n```\n\n## Re-slicing base X codec\n\nThe `getBaseXResliceCodec` also creates a base-x codec but uses a different strategy. It re-slices bytes into custom chunks of bits that are then mapped to a provided `alphabet`. The number of bits per chunk is also provided and should typically be set to `log2(alphabet.length)`.\n\nThis is typically used to create codecs whose alphabet’s length is a power of 2 such as base-16 or base-64.\n\n```ts\nconst bytes = getBaseXResliceCodec('elho', 2).encode('hellolol'); // 0x4aee\nconst value = getBaseXResliceCodec('elho', 2).decode(bytes); // \"hellolol\"\n```\n\nAs usual, separate `getBaseXResliceEncoder` and `getBaseXResliceDecoder` functions are also available.\n\n```ts\nconst bytes = getBaseXResliceEncoder('elho', 2).encode('hellolol'); // 0x4aee\nconst value = getBaseXResliceDecoder('elho', 2).decode(bytes); // \"hellolol\"\n```\n\n---\n\nTo read more about the available codecs and how to use them, check out the documentation of the main [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs).\n"
  },
  {
    "path": "packages/codecs-strings/package.json",
    "content": "{\n    \"name\": \"@solana/codecs-strings\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Codecs for strings of different sizes and encodings\",\n    \"homepage\": \"https://www.solanakit.com/api#solanacodecs-strings\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"benchmark\": \"./src/__benchmarks__/run.ts\",\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/text-encoding-impl\": \"workspace:*\",\n        \"tinybench\": \"^6.0.0\"\n    },\n    \"peerDependencies\": {\n        \"fastestsmallesttextencoderdecoder\": \"^1.0.22\",\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"fastestsmallesttextencoderdecoder\": {\n            \"optional\": true\n        },\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/codecs-strings/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/codecs-strings/src/__benchmarks__/run.ts",
    "content": "#!/usr/bin/env -S pnpm dlx tsx -r ../build-scripts/register-node-globals.cjs\n\nimport { webcrypto as crypto } from 'node:crypto';\n\nimport { Bench } from 'tinybench';\n\nimport { getBase16Codec } from '../base16';\nimport { getBase58Codec } from '../base58';\n\nconst bench = new Bench({\n    throws: true,\n});\n\nconst bytes32 = new Uint8Array(32);\nconst bytes16 = new Uint8Array(16);\nlet base58EncodedString: string;\nlet base16EncodedString: string;\nfunction randomizeBytes() {\n    crypto.getRandomValues(bytes32);\n    crypto.getRandomValues(bytes16);\n}\nconst base58Codec = getBase58Codec();\nconst base16Codec = getBase16Codec();\n\nbench\n    .add(\n        'Base58 decode',\n        () => {\n            base58Codec.decode(bytes32);\n        },\n        { beforeEach: randomizeBytes },\n    )\n    .add(\n        'Base58 encode',\n        () => {\n            base58Codec.encode(base58EncodedString);\n        },\n        {\n            beforeEach() {\n                randomizeBytes();\n                base58EncodedString = base58Codec.decode(bytes32);\n            },\n        },\n    )\n    .add(\n        'Base16 encode',\n        () => {\n            base16Codec.encode(base16EncodedString);\n        },\n        {\n            beforeEach() {\n                randomizeBytes();\n                base16EncodedString = base16Codec.decode(bytes16);\n            },\n        },\n    );\n\nvoid (async () => {\n    await bench.run();\n\n    console.table(bench.table());\n})();\n"
  },
  {
    "path": "packages/codecs-strings/src/__tests__/base10-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\nimport { getBase10Codec } from '../base10';\n\ndescribe('getBase10Codec', () => {\n    it('can encode base 10 strings', () => {\n        const base10 = getBase10Codec();\n\n        expect(base10.encode('')).toStrictEqual(new Uint8Array([]));\n        expect(base10.read(new Uint8Array([]), 0)).toStrictEqual(['', 0]);\n\n        expect(base10.encode('0')).toStrictEqual(new Uint8Array([0]));\n        expect(base10.read(new Uint8Array([0]), 0)).toStrictEqual(['0', 1]);\n\n        expect(base10.encode('000')).toStrictEqual(new Uint8Array([0, 0, 0]));\n        expect(base10.read(new Uint8Array([0, 0, 0]), 0)).toStrictEqual(['000', 3]);\n\n        expect(base10.encode('1')).toStrictEqual(new Uint8Array([1]));\n        expect(base10.read(new Uint8Array([1]), 0)).toStrictEqual(['1', 1]);\n\n        expect(base10.encode('42')).toStrictEqual(new Uint8Array([42]));\n        expect(base10.read(new Uint8Array([42]), 0)).toStrictEqual(['42', 1]);\n\n        expect(base10.encode('1024')).toStrictEqual(new Uint8Array([4, 0]));\n        expect(base10.read(new Uint8Array([4, 0]), 0)).toStrictEqual(['1024', 2]);\n\n        expect(base10.encode('65535')).toStrictEqual(new Uint8Array([255, 255]));\n        expect(base10.read(new Uint8Array([255, 255]), 0)).toStrictEqual(['65535', 2]);\n\n        expect(() => base10.encode('INVALID_INPUT')).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                alphabet: '0123456789',\n                base: 10,\n                value: 'INVALID_INPUT',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/codecs-strings/src/__tests__/base16-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\nimport { getBase16Codec } from '../base16';\n\ndescribe('getBase16Codec', () => {\n    it('can encode base 16 strings', () => {\n        const base16 = getBase16Codec();\n\n        expect(base16.encode('')).toStrictEqual(new Uint8Array([]));\n        expect(base16.read(new Uint8Array([]), 0)).toStrictEqual(['', 0]);\n\n        expect(base16.encode('0')).toStrictEqual(new Uint8Array([0]));\n        expect(base16.encode('00')).toStrictEqual(new Uint8Array([0]));\n        expect(base16.read(new Uint8Array([0]), 0)).toStrictEqual(['00', 1]);\n\n        expect(base16.encode('1')).toStrictEqual(new Uint8Array([1]));\n        expect(base16.encode('01')).toStrictEqual(new Uint8Array([1]));\n        expect(base16.read(new Uint8Array([1]), 0)).toStrictEqual(['01', 1]);\n\n        expect(base16.encode('2a')).toStrictEqual(new Uint8Array([42]));\n        expect(base16.read(new Uint8Array([42]), 0)).toStrictEqual(['2a', 1]);\n\n        expect(base16.encode('0400')).toStrictEqual(new Uint8Array([4, 0]));\n        expect(base16.read(new Uint8Array([4, 0]), 0)).toStrictEqual(['0400', 2]);\n\n        expect(base16.encode('ffff')).toStrictEqual(new Uint8Array([255, 255]));\n        expect(base16.read(new Uint8Array([255, 255]), 0)).toStrictEqual(['ffff', 2]);\n\n        expect(() => base16.encode('INVALID_INPUT')).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                alphabet: '0123456789abcdef',\n                base: 16,\n                value: 'INVALID_INPUT',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/codecs-strings/src/__tests__/base58-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\nimport { getBase58Codec } from '../base58';\n\ndescribe('getBase58Codec', () => {\n    it('can encode base 58 strings', () => {\n        const base58 = getBase58Codec();\n\n        expect(base58.encode('')).toStrictEqual(new Uint8Array([]));\n        expect(base58.read(new Uint8Array([]), 0)).toStrictEqual(['', 0]);\n\n        expect(base58.encode('1')).toStrictEqual(new Uint8Array([0]));\n        expect(base58.read(new Uint8Array([0]), 0)).toStrictEqual(['1', 1]);\n\n        expect(base58.encode('2')).toStrictEqual(new Uint8Array([1]));\n        expect(base58.read(new Uint8Array([1]), 0)).toStrictEqual(['2', 1]);\n\n        expect(base58.encode('11')).toStrictEqual(new Uint8Array([0, 0]));\n        expect(base58.read(new Uint8Array([0, 0]), 0)).toStrictEqual(['11', 2]);\n\n        const zeroes32 = new Uint8Array(Array(32).fill(0));\n        expect(base58.encode('1'.repeat(32))).toStrictEqual(zeroes32);\n        expect(base58.read(zeroes32, 0)).toStrictEqual(['1'.repeat(32), 32]);\n\n        expect(base58.encode('j')).toStrictEqual(new Uint8Array([42]));\n        expect(base58.read(new Uint8Array([42]), 0)).toStrictEqual(['j', 1]);\n\n        expect(base58.encode('Jf')).toStrictEqual(new Uint8Array([4, 0]));\n        expect(base58.read(new Uint8Array([4, 0]), 0)).toStrictEqual(['Jf', 2]);\n\n        expect(base58.encode('LUv')).toStrictEqual(new Uint8Array([255, 255]));\n        expect(base58.read(new Uint8Array([255, 255]), 0)).toStrictEqual(['LUv', 2]);\n\n        const pubkey = 'LorisCg1FTs89a32VSrFskYDgiRbNQzct1WxyZb7nuA';\n        const bytes = new Uint8Array([\n            5, 19, 4, 94, 5, 47, 73, 25, 182, 8, 150, 61, 231, 60, 102, 110, 6, 114, 224, 110, 40, 20, 10, 184, 65, 191,\n            241, 204, 131, 161, 120, 181,\n        ]);\n        expect(base58.encode(pubkey)).toStrictEqual(bytes);\n        expect(base58.read(bytes, 0)).toStrictEqual([pubkey, 32]);\n\n        expect(() => base58.encode('INVALID_INPUT')).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',\n                base: 58,\n                value: 'INVALID_INPUT',\n            }),\n        );\n    });\n\n    it('computes the buffer size of base 58 strings', () => {\n        const base58 = getBase58Codec();\n\n        // Empty.\n        expect(base58.getSizeFromValue('')).toBe(0);\n\n        // Simple strings.\n        expect(base58.getSizeFromValue('2')).toBe(1);\n        expect(base58.getSizeFromValue('Jf')).toBe(2);\n\n        // Leading zeroes.\n        expect(base58.getSizeFromValue('1')).toBe(1);\n        expect(base58.getSizeFromValue('11')).toBe(2);\n        expect(base58.getSizeFromValue('11111')).toBe(5);\n        expect(base58.getSizeFromValue('1'.repeat(32))).toBe(32);\n        expect(base58.getSizeFromValue('11111LUv')).toBe(5 + 2);\n\n        // Boundaries.\n        expect(base58.getSizeFromValue('5Q')).toBe(1);\n        expect(base58.getSizeFromValue('5R')).toBe(2);\n        expect(base58.getSizeFromValue('LUv')).toBe(2);\n        expect(base58.getSizeFromValue('LUw')).toBe(3);\n        expect(base58.getSizeFromValue('2UzHL')).toBe(3);\n        expect(base58.getSizeFromValue('2UzHM')).toBe(4);\n        expect(base58.getSizeFromValue('4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofL')).toBe(31);\n        expect(base58.getSizeFromValue('4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM')).toBe(32);\n        expect(base58.getSizeFromValue('JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG')).toBe(32);\n        expect(base58.getSizeFromValue('JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFH')).toBe(33);\n\n        // Addresses.\n        expect(base58.getSizeFromValue('LorisCg1FTs89a32VSrFskYDgiRbNQzct1WxyZb7nuA')).toBe(32);\n    });\n\n    it('produces the same result when offset equals negative byteLength', () => {\n        const base58 = getBase58Codec();\n        const bytes = new Uint8Array([\n            5, 19, 4, 94, 5, 47, 73, 25, 182, 8, 150, 61, 231, 60, 102, 110, 6, 114, 224, 110, 40, 20, 10, 184, 65, 191,\n            241, 204, 131, 161, 120, 181,\n        ]);\n        expect(base58.read(bytes, -bytes.byteLength)).toStrictEqual(base58.read(bytes, 0));\n    });\n\n    it('produces the same result when offset is negative greater than byteLength', () => {\n        const base58 = getBase58Codec();\n        const bytes = new Uint8Array([\n            5, 19, 4, 94, 5, 47, 73, 25, 182, 8, 150, 61, 231, 60, 102, 110, 6, 114, 224, 110, 40, 20, 10, 184, 65, 191,\n            241, 204, 131, 161, 120, 181,\n        ]);\n        expect(base58.read(bytes, -(bytes.byteLength + 1))).toStrictEqual(base58.read(bytes, 0));\n    });\n});\n"
  },
  {
    "path": "packages/codecs-strings/src/__tests__/base64-test.ts",
    "content": "import { SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\nimport { getBase16Codec } from '../base16';\nimport { getBase64Codec } from '../base64';\n\ndescribe('getBase64Codec', () => {\n    const base64 = getBase64Codec();\n    const base16 = getBase16Codec();\n\n    it('can encode base 64 strings', () => {\n        expect(base64.encode('')).toStrictEqual(new Uint8Array([]));\n        expect(base64.read(new Uint8Array([]), 0)).toStrictEqual(['', 0]);\n\n        expect(base64.encode('AA')).toStrictEqual(new Uint8Array([0]));\n        expect(base64.encode('AA==')).toStrictEqual(new Uint8Array([0]));\n        expect(base64.read(new Uint8Array([0]), 0)).toStrictEqual(['AA==', 1]);\n\n        expect(base64.encode('AQ==')).toStrictEqual(new Uint8Array([1]));\n        expect(base64.read(new Uint8Array([1]), 0)).toStrictEqual(['AQ==', 1]);\n\n        expect(base64.encode('Kg')).toStrictEqual(new Uint8Array([42]));\n        expect(base64.read(new Uint8Array([42]), 0)).toStrictEqual(['Kg==', 1]);\n\n        const sentence = 'TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu';\n        const bytes = new Uint8Array([\n            77, 97, 110, 121, 32, 104, 97, 110, 100, 115, 32, 109, 97, 107, 101, 32, 108, 105, 103, 104, 116, 32, 119,\n            111, 114, 107, 46,\n        ]);\n        expect(base64.encode(sentence)).toStrictEqual(bytes);\n        expect(base64.read(bytes, 0)).toStrictEqual([sentence, 27]);\n\n        expect(() => base64.encode('INVALID_INPUT')).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n                base: 64,\n                value: 'INVALID_INPUT',\n            }),\n        );\n\n        const base64TokenData =\n            'AShNrkm2joOHhfQnRCzfSbrtDUkUcJSS7PJryR4PPjsnyyIWxL0ESVFoE7QWBowtz2B/iTtUGdb2EEyKbLuN5gEAAAAAAAAAAQAAAGCtpnOhgF7t+dM8By+nG51mKI9Dgb0RtO/6xvPX1w52AgAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';\n        const base16TokenData =\n            '01284dae49b68e838785f427442cdf49baed0d4914709492ecf26bc91e0f3e3b27cb2216c4bd0449516813b416068c2dcf607f893b5419d6f6104c8a6cbb8de601000000000000000100000060ada673a1805eedf9d33c072fa71b9d66288f4381bd11b4effac6f3d7d70e76020000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000';\n\n        expect(base16.decode(base64.encode(base64TokenData))).toStrictEqual(base16TokenData);\n        expect(base64.decode(base16.encode(base16TokenData))).toStrictEqual(base64TokenData);\n    });\n\n    if (__BROWSER__) {\n        it('fails if base64 strings do not have the expected padding', () => {\n            // This is because atob is not tolerant to missing padding.\n            expect(() => base64.encode('A')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n                    base: 64,\n                    value: 'A',\n                }),\n            );\n            expect(() => base64.encode('AA=')).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                    alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',\n                    base: 64,\n                    value: 'AA=',\n                }),\n            );\n        });\n    } else {\n        it('tolerate base64 string with less padding than expected', () => {\n            expect(base64.encode('A')).toStrictEqual(new Uint8Array([]));\n            expect(base64.encode('AA=')).toStrictEqual(new Uint8Array([0]));\n        });\n    }\n});\n"
  },
  {
    "path": "packages/codecs-strings/src/__tests__/baseX-reslice-test.ts",
    "content": "import { getBase16Encoder } from '../base16';\nimport { getBaseXResliceCodec } from '../baseX-reslice';\n\ndescribe('getBaseXResliceCodec', () => {\n    const base8 = getBaseXResliceCodec('01234567', 3);\n    const b = (s: string) => getBase16Encoder().encode(s);\n\n    it('can encode strings by reslicing bits', () => {\n        // 8 times 3 bits gives us 3 bytes.\n        expect(base8.encode('77777777')).toStrictEqual(b('ffffff'));\n        expect(base8.read(b('ffffff'), 0)).toStrictEqual(['77777777', 3]);\n        expect(base8.read(b('00ffffff'), 1)).toStrictEqual(['77777777', 4]);\n\n        // Empty byte array.\n        expect(base8.encode('')).toStrictEqual(b(''));\n        expect(base8.read(b(''), 0)).toStrictEqual(['', 0]);\n        expect(base8.read(b('ff'), 1)).toStrictEqual(['', 1]);\n\n        // Single byte little-endian.\n        expect(base8.encode('000')).toStrictEqual(b('00'));\n        expect(base8.decode(b('00'))).toBe('000');\n        expect(base8.encode('100')).toStrictEqual(b('20'));\n        expect(base8.decode(b('20'))).toBe('100');\n        expect(base8.encode('200')).toStrictEqual(b('40'));\n        expect(base8.decode(b('40'))).toBe('200');\n        expect(base8.encode('300')).toStrictEqual(b('60'));\n        expect(base8.decode(b('60'))).toBe('300');\n        expect(base8.encode('400')).toStrictEqual(b('80'));\n        expect(base8.decode(b('80'))).toBe('400');\n        expect(base8.encode('500')).toStrictEqual(b('a0'));\n        expect(base8.decode(b('a0'))).toBe('500');\n        expect(base8.encode('600')).toStrictEqual(b('c0'));\n        expect(base8.decode(b('c0'))).toBe('600');\n        expect(base8.encode('700')).toStrictEqual(b('e0'));\n        expect(base8.decode(b('e0'))).toBe('700');\n\n        // Single byte big-endian.\n        expect(base8.encode('000')).toStrictEqual(b('00'));\n        expect(base8.decode(b('00'))).toBe('000');\n        expect(base8.encode('002')).toStrictEqual(b('01'));\n        expect(base8.decode(b('01'))).toBe('002');\n        expect(base8.encode('004')).toStrictEqual(b('02'));\n        expect(base8.decode(b('02'))).toBe('004');\n        expect(base8.encode('006')).toStrictEqual(b('03'));\n        expect(base8.decode(b('03'))).toBe('006');\n        expect(base8.encode('010')).toStrictEqual(b('04'));\n        expect(base8.decode(b('04'))).toBe('010');\n        expect(base8.encode('012')).toStrictEqual(b('05'));\n        expect(base8.decode(b('05'))).toBe('012');\n        expect(base8.encode('014')).toStrictEqual(b('06'));\n        expect(base8.decode(b('06'))).toBe('014');\n        expect(base8.encode('016')).toStrictEqual(b('07'));\n        expect(base8.decode(b('07'))).toBe('016');\n    });\n\n    it('produces the same result when offset equals negative byteLength', () => {\n        const bytes = b('ffffff');\n        expect(base8.read(bytes, -bytes.byteLength)).toStrictEqual(base8.read(bytes, 0));\n    });\n\n    it('produces the same result when offset is negative greater than byteLength', () => {\n        const bytes = b('ffffff');\n        expect(base8.read(bytes, -(bytes.byteLength + 1))).toStrictEqual(base8.read(bytes, 0));\n    });\n});\n"
  },
  {
    "path": "packages/codecs-strings/src/__tests__/string-test.ts",
    "content": "import { addCodecSizePrefix, fixCodecSize, offsetCodec } from '@solana/codecs-core';\nimport { getU8Codec, getU32Codec } from '@solana/codecs-numbers';\n\nimport { getBase16Codec } from '../base16';\nimport { getBase58Codec } from '../base58';\nimport { getUtf8Codec } from '../utf8';\n\ndescribe('sized string encodings', () => {\n    const b = (value: string) => getBase16Codec().encode(value);\n\n    it('encodes prefixed strings', () => {\n        const u32PrefixedString = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n\n        // Empty string.\n        expect(u32PrefixedString.encode('')).toStrictEqual(b('00000000'));\n        expect(u32PrefixedString.decode(b('00000000'))).toBe('');\n\n        // Hello World!\n        expect(u32PrefixedString.encode('Hello World!')).toStrictEqual(b('0c00000048656c6c6f20576f726c6421'));\n        expect(u32PrefixedString.decode(b('0c00000048656c6c6f20576f726c6421'), 0)).toBe('Hello World!');\n\n        // Characters with different byte lengths.\n        expect(u32PrefixedString.encode('語')).toStrictEqual(b('03000000e8aa9e'));\n        expect(u32PrefixedString.read(b('03000000e8aa9e'), 0)).toStrictEqual(['語', 7]);\n        expect(u32PrefixedString.read(b('ff03000000e8aa9e'), 1)).toStrictEqual(['語', 8]);\n\n        // Different prefix lengths.\n        const u8PrefixedString = addCodecSizePrefix(getUtf8Codec(), getU8Codec());\n        expect(u8PrefixedString.encode('ABC')).toStrictEqual(b('03414243'));\n        expect(u8PrefixedString.decode(b('03414243'))).toBe('ABC');\n\n        // Not enough bytes.\n        expect(() => u8PrefixedString.decode(b('0341'))).toThrow();\n    });\n\n    it('encodes fixed strings', () => {\n        const string5 = fixCodecSize(getUtf8Codec(), 5);\n        const string12 = fixCodecSize(getUtf8Codec(), 12);\n\n        // Hello World! (exact size).\n        expect(string12.encode('Hello World!')).toStrictEqual(b('48656c6c6f20576f726c6421'));\n        expect(string12.read(b('48656c6c6f20576f726c6421'), 0)).toStrictEqual(['Hello World!', 12]);\n\n        // Empty string (padded).\n        expect(string5.encode('')).toStrictEqual(b('0000000000'));\n        expect(string5.read(b('0000000000'), 0)).toStrictEqual(['', 5]);\n\n        // Characters with different byte lengths (padded).\n        expect(string5.encode('語')).toStrictEqual(b('e8aa9e0000'));\n        expect(string5.read(b('e8aa9e0000'), 0)).toStrictEqual(['語', 5]);\n\n        // Hello World! (truncated).\n        expect(string5.encode('Hello World!')).toStrictEqual(b('48656c6c6f'));\n        expect(string5.read(b('48656c6c6f'), 0)).toStrictEqual(['Hello', 5]);\n    });\n\n    it('encodes variable strings', () => {\n        const variableString = getUtf8Codec();\n\n        // Empty string.\n        expect(variableString.encode('')).toStrictEqual(b(''));\n        expect(variableString.decode(b(''))).toBe('');\n\n        // Hello World!\n        expect(variableString.encode('Hello World!')).toStrictEqual(b('48656c6c6f20576f726c6421'));\n        expect(variableString.decode(b('48656c6c6f20576f726c6421'))).toBe('Hello World!');\n\n        // Characters with different byte lengths.\n        expect(variableString.encode('語')).toStrictEqual(b('e8aa9e'));\n        expect(variableString.decode(b('e8aa9e'))).toBe('語');\n    });\n\n    it('encodes strings using custom encodings', () => {\n        // Prefixed.\n        const prefixedString = addCodecSizePrefix(getBase58Codec(), getU8Codec());\n        expect(prefixedString.encode('ABC')).toStrictEqual(b('027893'));\n        expect(prefixedString.decode(b('027893'))).toBe('ABC');\n\n        // Fixed.\n        const fixedString = fixCodecSize(getBase58Codec(), 5);\n        expect(fixedString.encode('ABC')).toStrictEqual(b('7893000000'));\n        expect(fixedString.decode(b('7893000000'))).toBe('EbzinYo'); // <- Base58 expect left padding.\n        expect(fixedString.decode(b('0000007893'))).toBe('111ABC'); // <- And uses 1s for padding.\n\n        // Variable.\n        const variableString = getBase58Codec();\n        expect(variableString.encode('ABC')).toStrictEqual(b('7893'));\n        expect(variableString.decode(b('7893'))).toBe('ABC');\n    });\n\n    it('has the right sizes', () => {\n        expect(addCodecSizePrefix(getUtf8Codec(), getU8Codec()).getSizeFromValue('ABC')).toBe(1 + 3);\n        expect(addCodecSizePrefix(getUtf8Codec(), getU8Codec()).maxSize).toBeUndefined();\n        expect(getUtf8Codec().getSizeFromValue('ABC')).toBe(3);\n        expect(getUtf8Codec().maxSize).toBeUndefined();\n        expect(fixCodecSize(getUtf8Codec(), 42).fixedSize).toBe(42);\n    });\n\n    it('offsets prefixed strings', () => {\n        const codec = addCodecSizePrefix(\n            getUtf8Codec(),\n            offsetCodec(getU8Codec(), {\n                postOffset: () => 0,\n                preOffset: ({ wrapBytes }) => wrapBytes(-1),\n            }),\n        );\n        expect(codec.encode('ABC')).toStrictEqual(b('41424303'));\n        expect(codec.decode(b('41424303'))).toBe('ABC');\n    });\n});\n"
  },
  {
    "path": "packages/codecs-strings/src/__tests__/utf8-test.ts",
    "content": "import { getUtf8Codec } from '../utf8';\n\ndescribe('getUtf8Codec', () => {\n    it('can encode UTF-8 strings', () => {\n        const utf8 = getUtf8Codec();\n\n        expect(utf8.encode('')).toStrictEqual(new Uint8Array([]));\n        expect(utf8.decode(new Uint8Array([]))).toBe('');\n\n        expect(utf8.encode('0')).toStrictEqual(new Uint8Array([48]));\n        expect(utf8.decode(new Uint8Array([48]))).toBe('0');\n\n        expect(utf8.encode('ABC')).toStrictEqual(new Uint8Array([65, 66, 67]));\n        expect(utf8.decode(new Uint8Array([65, 66, 67]))).toBe('ABC');\n\n        const encodedHelloWorld = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]);\n        expect(utf8.encode('Hello World!')).toStrictEqual(encodedHelloWorld);\n        expect(utf8.decode(encodedHelloWorld)).toBe('Hello World!');\n\n        expect(utf8.encode('語')).toStrictEqual(new Uint8Array([232, 170, 158]));\n        expect(utf8.decode(new Uint8Array([232, 170, 158]))).toBe('語');\n    });\n});\n"
  },
  {
    "path": "packages/codecs-strings/src/assertions.ts",
    "content": "import { SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\n/**\n * Asserts that a given string contains only characters from the specified alphabet.\n *\n * This function validates whether a string consists exclusively of characters\n * from the provided `alphabet`. If the validation fails, it throws an error\n * indicating the invalid base string.\n *\n * @param alphabet - The allowed set of characters for the base encoding.\n * @param testValue - The string to validate against the given alphabet.\n * @param givenValue - The original string provided by the user (defaults to `testValue`).\n *\n * @throws {SolanaError} If `testValue` contains characters not present in `alphabet`.\n *\n * @example\n * Validating a base-8 encoded string.\n * ```ts\n * assertValidBaseString('01234567', '123047'); // Passes\n * assertValidBaseString('01234567', '128');    // Throws error\n * ```\n */\nexport function assertValidBaseString(alphabet: string, testValue: string, givenValue = testValue) {\n    if (!testValue.match(new RegExp(`^[${alphabet}]*$`))) {\n        throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n            alphabet,\n            base: alphabet.length,\n            value: givenValue,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/codecs-strings/src/base10.ts",
    "content": "import { getBaseXCodec, getBaseXDecoder, getBaseXEncoder } from './baseX';\n\nconst alphabet = '0123456789';\n\n/**\n * Returns an encoder for base-10 strings.\n *\n * This encoder serializes strings using a base-10 encoding scheme.\n * The output consists of bytes representing the numerical values of the input string.\n *\n * For more details, see {@link getBase10Codec}.\n *\n * @returns A `VariableSizeEncoder<string>` for encoding base-10 strings.\n *\n * @example\n * Encoding a base-10 string.\n * ```ts\n * const encoder = getBase10Encoder();\n * const bytes = encoder.encode('1024'); // 0x0400\n * ```\n *\n * @see {@link getBase10Codec}\n */\nexport const getBase10Encoder = () => getBaseXEncoder(alphabet);\n\n/**\n * Returns a decoder for base-10 strings.\n *\n * This decoder deserializes base-10 encoded strings from a byte array.\n *\n * For more details, see {@link getBase10Codec}.\n *\n * @returns A `VariableSizeDecoder<string>` for decoding base-10 strings.\n *\n * @example\n * Decoding a base-10 string.\n * ```ts\n * const decoder = getBase10Decoder();\n * const value = decoder.decode(new Uint8Array([0x04, 0x00])); // \"1024\"\n * ```\n *\n * @see {@link getBase10Codec}\n */\nexport const getBase10Decoder = () => getBaseXDecoder(alphabet);\n\n/**\n * Returns a codec for encoding and decoding base-10 strings.\n *\n * This codec serializes strings using a base-10 encoding scheme.\n * The output consists of bytes representing the numerical values of the input string.\n *\n * @returns A `VariableSizeCodec<string>` for encoding and decoding base-10 strings.\n *\n * @example\n * Encoding and decoding a base-10 string.\n * ```ts\n * const codec = getBase10Codec();\n * const bytes = codec.encode('1024'); // 0x0400\n * const value = codec.decode(bytes);  // \"1024\"\n * ```\n *\n * @remarks\n * This codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string.\n *\n * If you need a fixed-size base-10 codec, consider using {@link fixCodecSize}.\n *\n * ```ts\n * const codec = fixCodecSize(getBase10Codec(), 5);\n * ```\n *\n * If you need a size-prefixed base-10 codec, consider using {@link addCodecSizePrefix}.\n *\n * ```ts\n * const codec = addCodecSizePrefix(getBase10Codec(), getU32Codec());\n * ```\n *\n * Separate {@link getBase10Encoder} and {@link getBase10Decoder} functions are available.\n *\n * ```ts\n * const bytes = getBase10Encoder().encode('1024');\n * const value = getBase10Decoder().decode(bytes);\n * ```\n *\n * @see {@link getBase10Encoder}\n * @see {@link getBase10Decoder}\n */\nexport const getBase10Codec = () => getBaseXCodec(alphabet);\n"
  },
  {
    "path": "packages/codecs-strings/src/base16.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\nconst enum HexC {\n    ZERO = 48, // 0\n    NINE = 57, // 9\n    A_UP = 65, // A\n    F_UP = 70, // F\n    A_LO = 97, // a\n    F_LO = 102, // f\n}\n\nconst INVALID_STRING_ERROR_BASE_CONFIG = {\n    alphabet: '0123456789abcdef',\n    base: 16,\n} as const;\n\nfunction charCodeToBase16(char: number) {\n    if (char >= HexC.ZERO && char <= HexC.NINE) return char - HexC.ZERO;\n    if (char >= HexC.A_UP && char <= HexC.F_UP) return char - (HexC.A_UP - 10);\n    if (char >= HexC.A_LO && char <= HexC.F_LO) return char - (HexC.A_LO - 10);\n}\n\n/**\n * Returns an encoder for base-16 (hexadecimal) strings.\n *\n * This encoder serializes strings using a base-16 encoding scheme.\n * The output consists of bytes representing the hexadecimal values of the input string.\n *\n * For more details, see {@link getBase16Codec}.\n *\n * @returns A `VariableSizeEncoder<string>` for encoding base-16 strings.\n *\n * @example\n * Encoding a base-16 string.\n * ```ts\n * const encoder = getBase16Encoder();\n * const bytes = encoder.encode('deadface'); // 0xdeadface\n * ```\n *\n * @see {@link getBase16Codec}\n */\nexport const getBase16Encoder = (): VariableSizeEncoder<string> =>\n    createEncoder({\n        getSizeFromValue: (value: string) => Math.ceil(value.length / 2),\n        write(value: string, bytes, offset) {\n            const len = value.length;\n            const al = len / 2;\n            if (len === 1) {\n                const c = value.charCodeAt(0);\n                const n = charCodeToBase16(c);\n                if (n === undefined) {\n                    throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                        ...INVALID_STRING_ERROR_BASE_CONFIG,\n                        value,\n                    });\n                }\n                bytes.set([n], offset);\n                return 1 + offset;\n            }\n            const hexBytes = new Uint8Array(al);\n            for (let i = 0, j = 0; i < al; i++) {\n                const c1 = value.charCodeAt(j++);\n                const c2 = value.charCodeAt(j++);\n\n                const n1 = charCodeToBase16(c1);\n                const n2 = charCodeToBase16(c2);\n                if (n1 === undefined || (n2 === undefined && !Number.isNaN(c2))) {\n                    throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                        ...INVALID_STRING_ERROR_BASE_CONFIG,\n                        value,\n                    });\n                }\n                hexBytes[i] = !Number.isNaN(c2) ? (n1 << 4) | (n2 ?? 0) : n1;\n            }\n\n            bytes.set(hexBytes, offset);\n            return hexBytes.length + offset;\n        },\n    });\n\n/**\n * Returns a decoder for base-16 (hexadecimal) strings.\n *\n * This decoder deserializes base-16 encoded strings from a byte array.\n *\n * For more details, see {@link getBase16Codec}.\n *\n * @returns A `VariableSizeDecoder<string>` for decoding base-16 strings.\n *\n * @example\n * Decoding a base-16 string.\n * ```ts\n * const decoder = getBase16Decoder();\n * const value = decoder.decode(new Uint8Array([0xde, 0xad, 0xfa, 0xce])); // \"deadface\"\n * ```\n *\n * @see {@link getBase16Codec}\n */\nexport const getBase16Decoder = (): VariableSizeDecoder<string> =>\n    createDecoder({\n        read(bytes, offset) {\n            const value = bytes.slice(offset).reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');\n            return [value, bytes.length];\n        },\n    });\n\n/**\n * Returns a codec for encoding and decoding base-16 (hexadecimal) strings.\n *\n * This codec serializes strings using a base-16 encoding scheme.\n * The output consists of bytes representing the hexadecimal values of the input string.\n *\n * @returns A `VariableSizeCodec<string>` for encoding and decoding base-16 strings.\n *\n * @example\n * Encoding and decoding a base-16 string.\n * ```ts\n * const codec = getBase16Codec();\n * const bytes = codec.encode('deadface'); // 0xdeadface\n * const value = codec.decode(bytes);      // \"deadface\"\n * ```\n *\n * @remarks\n * This codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string.\n *\n * If you need a fixed-size base-16 codec, consider using {@link fixCodecSize}.\n *\n * ```ts\n * const codec = fixCodecSize(getBase16Codec(), 8);\n * ```\n *\n * If you need a size-prefixed base-16 codec, consider using {@link addCodecSizePrefix}.\n *\n * ```ts\n * const codec = addCodecSizePrefix(getBase16Codec(), getU32Codec());\n * ```\n *\n * Separate {@link getBase16Encoder} and {@link getBase16Decoder} functions are available.\n *\n * ```ts\n * const bytes = getBase16Encoder().encode('deadface');\n * const value = getBase16Decoder().decode(bytes);\n * ```\n *\n * @see {@link getBase16Encoder}\n * @see {@link getBase16Decoder}\n */\nexport const getBase16Codec = (): VariableSizeCodec<string> => combineCodec(getBase16Encoder(), getBase16Decoder());\n"
  },
  {
    "path": "packages/codecs-strings/src/base58.ts",
    "content": "import { getBaseXCodec, getBaseXDecoder, getBaseXEncoder } from './baseX';\n\nconst alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\n/**\n * Returns an encoder for base-58 strings.\n *\n * This encoder serializes strings using a base-58 encoding scheme,\n * commonly used in cryptocurrency addresses and other compact representations.\n *\n * For more details, see {@link getBase58Codec}.\n *\n * @returns A `VariableSizeEncoder<string>` for encoding base-58 strings.\n *\n * @example\n * Encoding a base-58 string.\n * ```ts\n * const encoder = getBase58Encoder();\n * const bytes = encoder.encode('heLLo'); // 0x1b6a3070\n * ```\n *\n * @see {@link getBase58Codec}\n */\nexport const getBase58Encoder = () => getBaseXEncoder(alphabet);\n\n/**\n * Returns a decoder for base-58 strings.\n *\n * This decoder deserializes base-58 encoded strings from a byte array.\n *\n * For more details, see {@link getBase58Codec}.\n *\n * @returns A `VariableSizeDecoder<string>` for decoding base-58 strings.\n *\n * @example\n * Decoding a base-58 string.\n * ```ts\n * const decoder = getBase58Decoder();\n * const value = decoder.decode(new Uint8Array([0x1b, 0x6a, 0x30, 0x70])); // \"heLLo\"\n * ```\n *\n * @see {@link getBase58Codec}\n */\nexport const getBase58Decoder = () => getBaseXDecoder(alphabet);\n\n/**\n * Returns a codec for encoding and decoding base-58 strings.\n *\n * This codec serializes strings using a base-58 encoding scheme,\n * commonly used in cryptocurrency addresses and other compact representations.\n *\n * @returns A `VariableSizeCodec<string>` for encoding and decoding base-58 strings.\n *\n * @example\n * Encoding and decoding a base-58 string.\n * ```ts\n * const codec = getBase58Codec();\n * const bytes = codec.encode('heLLo'); // 0x1b6a3070\n * const value = codec.decode(bytes);   // \"heLLo\"\n * ```\n *\n * @remarks\n * This codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string.\n *\n * If you need a fixed-size base-58 codec, consider using {@link fixCodecSize}.\n *\n * ```ts\n * const codec = fixCodecSize(getBase58Codec(), 8);\n * ```\n *\n * If you need a size-prefixed base-58 codec, consider using {@link addCodecSizePrefix}.\n *\n * ```ts\n * const codec = addCodecSizePrefix(getBase58Codec(), getU32Codec());\n * ```\n *\n * Separate {@link getBase58Encoder} and {@link getBase58Decoder} functions are available.\n *\n * ```ts\n * const bytes = getBase58Encoder().encode('heLLo');\n * const value = getBase58Decoder().decode(bytes);\n * ```\n *\n * @see {@link getBase58Encoder}\n * @see {@link getBase58Decoder}\n */\nexport const getBase58Codec = () => getBaseXCodec(alphabet);\n"
  },
  {
    "path": "packages/codecs-strings/src/base64.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    toArrayBuffer,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, SolanaError } from '@solana/errors';\n\nimport { assertValidBaseString } from './assertions';\nimport { getBaseXResliceDecoder, getBaseXResliceEncoder } from './baseX-reslice';\n\nconst alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n/**\n * Returns an encoder for base-64 strings.\n *\n * This encoder serializes strings using a base-64 encoding scheme,\n * commonly used for data encoding in URLs, cryptographic keys, and binary-to-text encoding.\n *\n * For more details, see {@link getBase64Codec}.\n *\n * @returns A `VariableSizeEncoder<string>` for encoding base-64 strings.\n *\n * @example\n * Encoding a base-64 string.\n * ```ts\n * const encoder = getBase64Encoder();\n * const bytes = encoder.encode('hello+world'); // 0x85e965a3ec28ae57\n * ```\n *\n * @see {@link getBase64Codec}\n */\nexport const getBase64Encoder = (): VariableSizeEncoder<string> => {\n    if (__BROWSER__) {\n        return createEncoder({\n            getSizeFromValue: (value: string) => {\n                try {\n                    return (atob as Window['atob'])(value).length;\n                } catch {\n                    throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                        alphabet,\n                        base: 64,\n                        value,\n                    });\n                }\n            },\n            write(value: string, bytes, offset) {\n                try {\n                    const bytesToAdd = (atob as Window['atob'])(value)\n                        .split('')\n                        .map(c => c.charCodeAt(0));\n                    bytes.set(bytesToAdd, offset);\n                    return bytesToAdd.length + offset;\n                } catch {\n                    throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                        alphabet,\n                        base: 64,\n                        value,\n                    });\n                }\n            },\n        });\n    }\n\n    if (__NODEJS__) {\n        return createEncoder({\n            getSizeFromValue: (value: string) => Buffer.from(value, 'base64').length,\n            write(value: string, bytes, offset) {\n                assertValidBaseString(alphabet, value.replace(/=/g, ''));\n                const buffer = Buffer.from(value, 'base64');\n                bytes.set(buffer, offset);\n                return buffer.length + offset;\n            },\n        });\n    }\n\n    return transformEncoder(getBaseXResliceEncoder(alphabet, 6), (value: string): string => value.replace(/=/g, ''));\n};\n\n/**\n * Returns a decoder for base-64 strings.\n *\n * This decoder deserializes base-64 encoded strings from a byte array.\n *\n * For more details, see {@link getBase64Codec}.\n *\n * @returns A `VariableSizeDecoder<string>` for decoding base-64 strings.\n *\n * @example\n * Decoding a base-64 string.\n * ```ts\n * const decoder = getBase64Decoder();\n * const value = decoder.decode(new Uint8Array([0x85, 0xe9, 0x65, 0xa3, 0xec, 0x28, 0xae, 0x57])); // \"hello+world\"\n * ```\n *\n * @see {@link getBase64Codec}\n */\nexport const getBase64Decoder = (): VariableSizeDecoder<string> => {\n    if (__BROWSER__) {\n        return createDecoder({\n            read(bytes, offset = 0) {\n                const slice = bytes.slice(offset);\n                const value = (btoa as Window['btoa'])(String.fromCharCode(...slice));\n                return [value, bytes.length];\n            },\n        });\n    }\n\n    if (__NODEJS__) {\n        return createDecoder({\n            read: (bytes, offset = 0) => [Buffer.from(toArrayBuffer(bytes), offset).toString('base64'), bytes.length],\n        });\n    }\n\n    return transformDecoder(getBaseXResliceDecoder(alphabet, 6), (value: string): string =>\n        value.padEnd(Math.ceil(value.length / 4) * 4, '='),\n    );\n};\n\n/**\n * Returns a codec for encoding and decoding base-64 strings.\n *\n * This codec serializes strings using a base-64 encoding scheme,\n * commonly used for data encoding in URLs, cryptographic keys, and binary-to-text encoding.\n *\n * @returns A `VariableSizeCodec<string>` for encoding and decoding base-64 strings.\n *\n * @example\n * Encoding and decoding a base-64 string.\n * ```ts\n * const codec = getBase64Codec();\n * const bytes = codec.encode('hello+world'); // 0x85e965a3ec28ae57\n * const value = codec.decode(bytes);         // \"hello+world\"\n * ```\n *\n * @remarks\n * This codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string.\n *\n * If you need a fixed-size base-64 codec, consider using {@link fixCodecSize}.\n *\n * ```ts\n * const codec = fixCodecSize(getBase64Codec(), 8);\n * ```\n *\n * If you need a size-prefixed base-64 codec, consider using {@link addCodecSizePrefix}.\n *\n * ```ts\n * const codec = addCodecSizePrefix(getBase64Codec(), getU32Codec());\n * ```\n *\n * Separate {@link getBase64Encoder} and {@link getBase64Decoder} functions are available.\n *\n * ```ts\n * const bytes = getBase64Encoder().encode('hello+world');\n * const value = getBase64Decoder().decode(bytes);\n * ```\n *\n * @see {@link getBase64Encoder}\n * @see {@link getBase64Decoder}\n */\nexport const getBase64Codec = (): VariableSizeCodec<string> => combineCodec(getBase64Encoder(), getBase64Decoder());\n"
  },
  {
    "path": "packages/codecs-strings/src/baseX-reslice.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/**\n * Returns an encoder for base-X encoded strings using bit re-slicing.\n *\n * This encoder serializes strings by dividing the input into custom-sized bit chunks,\n * mapping them to an alphabet, and encoding the result into a byte array.\n * This approach is commonly used for encoding schemes where the alphabet's length is a power of 2,\n * such as base-16 or base-64.\n *\n * For more details, see {@link getBaseXResliceCodec}.\n *\n * @param alphabet - The set of characters defining the base-X encoding.\n * @param bits - The number of bits per encoded chunk, typically `log2(alphabet.length)`.\n * @returns A `VariableSizeEncoder<string>` for encoding base-X strings using bit re-slicing.\n *\n * @example\n * Encoding a base-X string using bit re-slicing.\n * ```ts\n * const encoder = getBaseXResliceEncoder('elho', 2);\n * const bytes = encoder.encode('hellolol'); // 0x4aee\n * ```\n *\n * @see {@link getBaseXResliceCodec}\n */\nexport const getBaseXResliceEncoder = (alphabet: string, bits: number): VariableSizeEncoder<string> =>\n    createEncoder({\n        getSizeFromValue: (value: string) => Math.floor((value.length * bits) / 8),\n        write(value: string, bytes, offset) {\n            assertValidBaseString(alphabet, value);\n            if (value === '') return offset;\n            const charIndices = [...value].map(c => alphabet.indexOf(c));\n            const reslicedBytes = reslice(charIndices, bits, 8, false);\n            bytes.set(reslicedBytes, offset);\n            return reslicedBytes.length + offset;\n        },\n    });\n\n/**\n * Returns a decoder for base-X encoded strings using bit re-slicing.\n *\n * This decoder deserializes base-X encoded strings by re-slicing the bits of a byte array into\n * custom-sized chunks and mapping them to a specified alphabet.\n * This is typically used for encoding schemes where the alphabet's length is a power of 2,\n * such as base-16 or base-64.\n *\n * For more details, see {@link getBaseXResliceCodec}.\n *\n * @param alphabet - The set of characters defining the base-X encoding.\n * @param bits - The number of bits per encoded chunk, typically `log2(alphabet.length)`.\n * @returns A `VariableSizeDecoder<string>` for decoding base-X strings using bit re-slicing.\n *\n * @example\n * Decoding a base-X string using bit re-slicing.\n * ```ts\n * const decoder = getBaseXResliceDecoder('elho', 2);\n * const value = decoder.decode(new Uint8Array([0x4a, 0xee])); // \"hellolol\"\n * ```\n *\n * @see {@link getBaseXResliceCodec}\n */\nexport const getBaseXResliceDecoder = (alphabet: string, bits: number): VariableSizeDecoder<string> =>\n    createDecoder({\n        read(rawBytes, offset = 0): [string, number] {\n            const bytes = offset === 0 || offset <= -rawBytes.byteLength ? rawBytes : rawBytes.slice(offset);\n            if (bytes.length === 0) return ['', rawBytes.length];\n            const charIndices = reslice([...bytes], 8, bits, true);\n            return [charIndices.map(i => alphabet[i]).join(''), rawBytes.length];\n        },\n    });\n\n/**\n * Returns a codec for encoding and decoding base-X strings using bit re-slicing.\n *\n * This codec serializes strings by dividing the input into custom-sized bit chunks,\n * mapping them to a given alphabet, and encoding the result into bytes.\n * It is particularly suited for encoding schemes where the alphabet's length is a power of 2,\n * such as base-16 or base-64.\n *\n * @param alphabet - The set of characters defining the base-X encoding.\n * @param bits - The number of bits per encoded chunk, typically `log2(alphabet.length)`.\n * @returns A `VariableSizeCodec<string>` for encoding and decoding base-X strings using bit re-slicing.\n *\n * @example\n * Encoding and decoding a base-X string using bit re-slicing.\n * ```ts\n * const codec = getBaseXResliceCodec('elho', 2);\n * const bytes = codec.encode('hellolol'); // 0x4aee\n * const value = codec.decode(bytes);      // \"hellolol\"\n * ```\n *\n * @remarks\n * This codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string.\n *\n * If you need a fixed-size base-X codec, consider using {@link fixCodecSize}.\n *\n * ```ts\n * const codec = fixCodecSize(getBaseXResliceCodec('elho', 2), 8);\n * ```\n *\n * If you need a size-prefixed base-X codec, consider using {@link addCodecSizePrefix}.\n *\n * ```ts\n * const codec = addCodecSizePrefix(getBaseXResliceCodec('elho', 2), getU32Codec());\n * ```\n *\n * Separate {@link getBaseXResliceEncoder} and {@link getBaseXResliceDecoder} functions are available.\n *\n * ```ts\n * const bytes = getBaseXResliceEncoder('elho', 2).encode('hellolol');\n * const value = getBaseXResliceDecoder('elho', 2).decode(bytes);\n * ```\n *\n * @see {@link getBaseXResliceEncoder}\n * @see {@link getBaseXResliceDecoder}\n */\nexport const getBaseXResliceCodec = (alphabet: string, bits: number): VariableSizeCodec<string> =>\n    combineCodec(getBaseXResliceEncoder(alphabet, bits), getBaseXResliceDecoder(alphabet, bits));\n\n/** Helper function to reslice the bits inside bytes. */\nfunction reslice(input: number[], inputBits: number, outputBits: number, useRemainder: boolean): number[] {\n    const output = [];\n    let accumulator = 0;\n    let bitsInAccumulator = 0;\n    const mask = (1 << outputBits) - 1;\n    for (const value of input) {\n        accumulator = (accumulator << inputBits) | value;\n        bitsInAccumulator += inputBits;\n        while (bitsInAccumulator >= outputBits) {\n            bitsInAccumulator -= outputBits;\n            output.push((accumulator >> bitsInAccumulator) & mask);\n        }\n    }\n    if (useRemainder && bitsInAccumulator > 0) {\n        output.push((accumulator << (outputBits - bitsInAccumulator)) & mask);\n    }\n    return output;\n}\n"
  },
  {
    "path": "packages/codecs-strings/src/baseX.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { assertValidBaseString } from './assertions';\n\n/**\n * Returns an encoder for base-X encoded strings.\n *\n * This encoder serializes strings using a custom alphabet, treating the length of the alphabet as the base.\n * The encoding process involves converting the input string to a numeric value in base-X, then\n * encoding that value into bytes while preserving leading zeroes.\n *\n * For more details, see {@link getBaseXCodec}.\n *\n * @param alphabet - The set of characters defining the base-X encoding.\n * @returns A `VariableSizeEncoder<string>` for encoding base-X strings.\n *\n * @example\n * Encoding a base-X string using a custom alphabet.\n * ```ts\n * const encoder = getBaseXEncoder('0123456789abcdef');\n * const bytes = encoder.encode('deadface'); // 0xdeadface\n * ```\n *\n * @see {@link getBaseXCodec}\n */\nexport const getBaseXEncoder = (alphabet: string): VariableSizeEncoder<string> => {\n    return createEncoder({\n        getSizeFromValue: (value: string): number => {\n            const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n            if (!tailChars) return value.length;\n\n            const base10Number = getBigIntFromBaseX(tailChars, alphabet);\n            return leadingZeroes.length + Math.ceil(base10Number.toString(16).length / 2);\n        },\n        write(value: string, bytes, offset) {\n            // Check if the value is valid.\n            assertValidBaseString(alphabet, value);\n            if (value === '') return offset;\n\n            // Handle leading zeroes.\n            const [leadingZeroes, tailChars] = partitionLeadingZeroes(value, alphabet[0]);\n            if (!tailChars) {\n                bytes.set(new Uint8Array(leadingZeroes.length).fill(0), offset);\n                return offset + leadingZeroes.length;\n            }\n\n            // From baseX to base10.\n            let base10Number = getBigIntFromBaseX(tailChars, alphabet);\n\n            // From base10 to bytes.\n            const tailBytes: number[] = [];\n            while (base10Number > 0n) {\n                tailBytes.unshift(Number(base10Number % 256n));\n                base10Number /= 256n;\n            }\n\n            const bytesToAdd = [...Array(leadingZeroes.length).fill(0), ...tailBytes];\n            bytes.set(bytesToAdd, offset);\n            return offset + bytesToAdd.length;\n        },\n    });\n};\n\n/**\n * Returns a decoder for base-X encoded strings.\n *\n * This decoder deserializes base-X encoded strings from a byte array using a custom alphabet.\n * The decoding process converts the byte array into a numeric value in base-10, then\n * maps that value back to characters in the specified base-X alphabet.\n *\n * For more details, see {@link getBaseXCodec}.\n *\n * @param alphabet - The set of characters defining the base-X encoding.\n * @returns A `VariableSizeDecoder<string>` for decoding base-X strings.\n *\n * @example\n * Decoding a base-X string using a custom alphabet.\n * ```ts\n * const decoder = getBaseXDecoder('0123456789abcdef');\n * const value = decoder.decode(new Uint8Array([0xde, 0xad, 0xfa, 0xce])); // \"deadface\"\n * ```\n *\n * @see {@link getBaseXCodec}\n */\nexport const getBaseXDecoder = (alphabet: string): VariableSizeDecoder<string> => {\n    return createDecoder({\n        read(rawBytes, offset): [string, number] {\n            const bytes = offset === 0 || offset <= -rawBytes.byteLength ? rawBytes : rawBytes.slice(offset);\n            if (bytes.length === 0) return ['', 0];\n\n            // Handle leading zeroes.\n            let trailIndex = bytes.findIndex(n => n !== 0);\n            trailIndex = trailIndex === -1 ? bytes.length : trailIndex;\n            const leadingZeroes = alphabet[0].repeat(trailIndex);\n            if (trailIndex === bytes.length) return [leadingZeroes, rawBytes.length];\n\n            // From bytes to base10.\n            const base10Number = bytes.slice(trailIndex).reduce((sum, byte) => sum * 256n + BigInt(byte), 0n);\n\n            // From base10 to baseX.\n            const tailChars = getBaseXFromBigInt(base10Number, alphabet);\n\n            return [leadingZeroes + tailChars, rawBytes.length];\n        },\n    });\n};\n\n/**\n * Returns a codec for encoding and decoding base-X strings.\n *\n * This codec serializes strings using a custom alphabet, treating the length of the alphabet as the base.\n * The encoding process converts the input string into a numeric value in base-X, which is then encoded as bytes.\n * The decoding process reverses this transformation to reconstruct the original string.\n *\n * This codec supports leading zeroes by treating the first character of the alphabet as the zero character.\n *\n * @param alphabet - The set of characters defining the base-X encoding.\n * @returns A `VariableSizeCodec<string>` for encoding and decoding base-X strings.\n *\n * @example\n * Encoding and decoding a base-X string using a custom alphabet.\n * ```ts\n * const codec = getBaseXCodec('0123456789abcdef');\n * const bytes = codec.encode('deadface'); // 0xdeadface\n * const value = codec.decode(bytes);      // \"deadface\"\n * ```\n *\n * @remarks\n * This codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string.\n *\n * If you need a fixed-size base-X codec, consider using {@link fixCodecSize}.\n *\n * ```ts\n * const codec = fixCodecSize(getBaseXCodec('0123456789abcdef'), 8);\n * ```\n *\n * If you need a size-prefixed base-X codec, consider using {@link addCodecSizePrefix}.\n *\n * ```ts\n * const codec = addCodecSizePrefix(getBaseXCodec('0123456789abcdef'), getU32Codec());\n * ```\n *\n * Separate {@link getBaseXEncoder} and {@link getBaseXDecoder} functions are available.\n *\n * ```ts\n * const bytes = getBaseXEncoder('0123456789abcdef').encode('deadface');\n * const value = getBaseXDecoder('0123456789abcdef').decode(bytes);\n * ```\n *\n * @see {@link getBaseXEncoder}\n * @see {@link getBaseXDecoder}\n */\nexport const getBaseXCodec = (alphabet: string): VariableSizeCodec<string> =>\n    combineCodec(getBaseXEncoder(alphabet), getBaseXDecoder(alphabet));\n\nfunction partitionLeadingZeroes(\n    value: string,\n    zeroCharacter: string,\n): [leadingZeros: string, tailChars: string | undefined] {\n    const [leadingZeros, tailChars] = value.split(new RegExp(`((?!${zeroCharacter}).*)`));\n    return [leadingZeros, tailChars];\n}\n\nfunction getBigIntFromBaseX(value: string, alphabet: string): bigint {\n    const base = BigInt(alphabet.length);\n    let sum = 0n;\n    for (const char of value) {\n        sum *= base;\n        sum += BigInt(alphabet.indexOf(char));\n    }\n    return sum;\n}\n\nfunction getBaseXFromBigInt(value: bigint, alphabet: string): string {\n    const base = BigInt(alphabet.length);\n    const tailChars = [];\n    while (value > 0n) {\n        tailChars.unshift(alphabet[Number(value % base)]);\n        value /= base;\n    }\n    return tailChars.join('');\n}\n"
  },
  {
    "path": "packages/codecs-strings/src/index.ts",
    "content": "/**\n * This package contains codecs for strings of different sizes and encodings.\n * It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * This package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs)\n * which acts as an entry point for all codec packages as well as for their documentation.\n *\n * ## Sizing string codecs\n *\n * The `@solana/codecs-strings` package offers a variety of string codecs such as `utf8`, `base58`, `base64`, etc —\n * which we will discuss in more detail below. However, before digging into the available string codecs,\n * it's important to understand the different sizing strategies available for string codecs.\n *\n * By default, all available string codecs will return a `VariableSizeCodec<string>` meaning that:\n *\n * - When encoding a string, all bytes necessary to encode the string will be used.\n * - When decoding a byte array at a given offset, all bytes starting from that offset will be decoded as a string.\n *\n * For instance, here's how you can encode/decode `utf8` strings without any size boundary:\n *\n * ```ts\n * const codec = getUtf8Codec();\n *\n * codec.encode('hello');\n * // 0x68656c6c6f\n * //   └-- Any bytes necessary to encode our content.\n *\n * codec.decode(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f]));\n * // 'hello'\n * ```\n *\n * This might be what you want — e.g. when having a string at the end of a data structure — but in many cases,\n * you might want to have a size boundary for your string. You may achieve this by composing your string codec\n * with the [`fixCodecSize`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#fixing-the-size-of-codecs)\n * or [`addCodecSizePrefix`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-core#prefixing-the-size-of-codecs) functions.\n *\n * The `fixCodecSize` function accepts a fixed byte length and returns a `FixedSizeCodec<string>` that will always use\n * that amount of bytes to encode and decode a string. Any string longer or smaller than that size will be truncated\n * or padded respectively. Here's how you can use it with a `utf8` codec:\n *\n * ```ts\n * const codec = fixCodecSize(getUtf8Codec(), 5);\n *\n * codec.encode('hello');\n * // 0x68656c6c6f\n * //   └-- The exact 5 bytes of content.\n *\n * codec.encode('hello world');\n * // 0x68656c6c6f\n * //   └-- The truncated 5 bytes of content.\n *\n * codec.encode('hell');\n * // 0x68656c6c00\n * //   └-- The padded 5 bytes of content.\n *\n * codec.decode(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xff, 0xff, 0xff, 0xff]));\n * // 'hello'\n * ```\n *\n * The `addCodecSizePrefix` function accepts an additional number codec that will be used to encode and\n * decode a size prefix for the string. This prefix allows us to know when to stop reading the string when\n * decoding a given byte array. Here's how you can use it with a `utf8` codec:\n *\n * ```ts\n * const codec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n *\n * codec.encode('hello');\n * // 0x0500000068656c6c6f\n * //   |       └-- The 5 bytes of content.\n * //   └-- 4-byte prefix telling us to read 5 bytes.\n *\n * codec.decode(new Uint8Array([0x05, 0x00, 0x00, 0x00, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0xff, 0xff, 0xff, 0xff]));\n * // \"hello\"\n * ```\n *\n * Now, let's take a look at the available string encodings. Just remember that you can use\n * the `fixSizeCodec` or `prefixSizeCodec` functions on any of these encodings to add a size boundary to them.\n *\n * ## Utf8 codec\n *\n * The `getUtf8Codec` function encodes and decodes a UTF-8 string to and from a byte array.\n *\n * ```ts\n * const bytes = getUtf8Codec().encode('hello'); // 0x68656c6c6f\n * const value = getUtf8Codec().decode(bytes); // \"hello\"\n * ```\n *\n * As usual, separate `getUtf8Encoder` and `getUtf8Decoder` functions are also available.\n *\n * ```ts\n * const bytes = getUtf8Encoder().encode('hello'); // 0x68656c6c6f\n * const value = getUtf8Decoder().decode(bytes); // \"hello\"\n * ```\n *\n * ## Base 64 codec\n *\n * The `getBase64Codec` function encodes and decodes a base-64 string to and from a byte array.\n *\n * ```ts\n * const bytes = getBase64Codec().encode('hello+world'); // 0x85e965a3ec28ae57\n * const value = getBase64Codec().decode(bytes); // \"hello+world\"\n * ```\n *\n * As usual, separate `getBase64Encoder` and `getBase64Decoder` functions are also available.\n *\n * ```ts\n * const bytes = getBase64Encoder().encode('hello+world'); // 0x85e965a3ec28ae57\n * const value = getBase64Decoder().decode(bytes); // \"hello+world\"\n * ```\n *\n * ## Base 58 codec\n *\n * The `getBase58Codec` function encodes and decodes a base-58 string to and from a byte array.\n *\n * ```ts\n * const bytes = getBase58Codec().encode('heLLo'); // 0x1b6a3070\n * const value = getBase58Codec().decode(bytes); // \"heLLo\"\n * ```\n *\n * As usual, separate `getBase58Encoder` and `getBase58Decoder` functions are also available.\n *\n * ```ts\n * const bytes = getBase58Encoder().encode('heLLo'); // 0x1b6a3070\n * const value = getBase58Decoder().decode(bytes); // \"heLLo\"\n * ```\n *\n * ## Base 16 codec\n *\n * The `getBase16Codec` function encodes and decodes a base-16 string to and from a byte array.\n *\n * ```ts\n * const bytes = getBase16Codec().encode('deadface'); // 0xdeadface\n * const value = getBase16Codec().decode(bytes); // \"deadface\"\n * ```\n *\n * As usual, separate `getBase16Encoder` and `getBase16Decoder` functions are also available.\n *\n * ```ts\n * const bytes = getBase16Encoder().encode('deadface'); // 0xdeadface\n * const value = getBase16Decoder().decode(bytes); // \"deadface\"\n * ```\n *\n * ## Base 10 codec\n *\n * The `getBase10Codec` function encodes and decodes a base-10 string to and from a byte array.\n *\n * ```ts\n * const bytes = getBase10Codec().encode('1024'); // 0x0400\n * const value = getBase10Codec().decode(bytes); // \"1024\"\n * ```\n *\n * As usual, separate `getBase10Encoder` and `getBase10Decoder` functions are also available.\n *\n * ```ts\n * const bytes = getBase10Encoder().encode('1024'); // 0x0400\n * const value = getBase10Decoder().decode(bytes); // \"1024\"\n * ```\n *\n * ## Base X codec\n *\n * The `getBaseXCodec` accepts a custom `alphabet` of `X` characters and creates a base-X codec using that alphabet.\n * It does so by iteratively dividing by `X` and handling leading zeros.\n *\n * The base-10 and base-58 codecs use this base-x codec under the hood.\n *\n * ```ts\n * const alphabet = '0ehlo';\n * const bytes = getBaseXCodec(alphabet).encode('hello'); // 0x05bd\n * const value = getBaseXCodec(alphabet).decode(bytes); // \"hello\"\n * ```\n *\n * As usual, separate `getBaseXEncoder` and `getBaseXDecoder` functions are also available.\n *\n * ```ts\n * const bytes = getBaseXEncoder(alphabet).encode('hello'); // 0x05bd\n * const value = getBaseXDecoder(alphabet).decode(bytes); // \"hello\"\n * ```\n *\n * ## Re-slicing base X codec\n *\n * The `getBaseXResliceCodec` also creates a base-x codec but uses a different strategy.\n * It re-slices bytes into custom chunks of bits that are then mapped to a provided `alphabet`.\n * The number of bits per chunk is also provided and should typically be set to `log2(alphabet.length)`.\n *\n * This is typically used to create codecs whose alphabet’s length is a power of 2 such as base-16 or base-64.\n *\n * ```ts\n * const bytes = getBaseXResliceCodec('elho', 2).encode('hellolol'); // 0x4aee\n * const value = getBaseXResliceCodec('elho', 2).decode(bytes); // \"hellolol\"\n * ```\n *\n * As usual, separate `getBaseXResliceEncoder` and `getBaseXResliceDecoder` functions are also available.\n *\n * ```ts\n * const bytes = getBaseXResliceEncoder('elho', 2).encode('hellolol'); // 0x4aee\n * const value = getBaseXResliceDecoder('elho', 2).decode(bytes); // \"hellolol\"\n * ```\n *\n * @packageDocumentation\n */\nexport * from './assertions';\nexport * from './base10';\nexport * from './base16';\nexport * from './base58';\nexport * from './base64';\nexport * from './baseX';\nexport * from './baseX-reslice';\nexport * from './null-characters';\nexport * from './utf8';\n"
  },
  {
    "path": "packages/codecs-strings/src/null-characters.ts",
    "content": "/**\n * Removes all null characters (`\\u0000`) from a string.\n *\n * This function cleans a string by stripping out any null characters,\n * which are often used as padding in fixed-size string encodings.\n *\n * @param value - The string to process.\n * @returns The input string with all null characters removed.\n *\n * @example\n * Removing null characters from a string.\n * ```ts\n * removeNullCharacters('hello\\u0000\\u0000'); // \"hello\"\n * ```\n */\nexport const removeNullCharacters = (value: string) =>\n    // eslint-disable-next-line no-control-regex\n    value.replace(/\\u0000/g, '');\n\n/**\n * Pads a string with null characters (`\\u0000`) at the end to reach a fixed length.\n *\n * If the input string is shorter than the specified length, it is padded with null characters\n * until it reaches the desired size. If it is already long enough, it remains unchanged.\n *\n * @param value - The string to pad.\n * @param chars - The total length of the resulting string, including padding.\n * @returns The input string padded with null characters up to the specified length.\n *\n * @example\n * Padding a string with null characters.\n * ```ts\n * padNullCharacters('hello', 8); // \"hello\\u0000\\u0000\\u0000\"\n * ```\n */\nexport const padNullCharacters = (value: string, chars: number) => value.padEnd(chars, '\\u0000');\n"
  },
  {
    "path": "packages/codecs-strings/src/utf8.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { TextDecoder, TextEncoder } from '@solana/text-encoding-impl';\n\nimport { removeNullCharacters } from './null-characters';\n\n/**\n * Returns an encoder for UTF-8 strings.\n *\n * This encoder serializes strings using UTF-8 encoding.\n * The encoded output contains as many bytes as needed to represent the string.\n *\n * For more details, see {@link getUtf8Codec}.\n *\n * @returns A `VariableSizeEncoder<string>` for encoding UTF-8 strings.\n *\n * @example\n * Encoding a UTF-8 string.\n * ```ts\n * const encoder = getUtf8Encoder();\n * const bytes = encoder.encode('hello'); // 0x68656c6c6f\n * ```\n *\n * @see {@link getUtf8Codec}\n */\nexport const getUtf8Encoder = (): VariableSizeEncoder<string> => {\n    let textEncoder: TextEncoder;\n    return createEncoder({\n        getSizeFromValue: value => (textEncoder ||= new TextEncoder()).encode(value).length,\n        write: (value: string, bytes, offset) => {\n            const bytesToAdd = (textEncoder ||= new TextEncoder()).encode(value);\n            bytes.set(bytesToAdd, offset);\n            return offset + bytesToAdd.length;\n        },\n    });\n};\n\n/**\n * Returns a decoder for UTF-8 strings.\n *\n * This decoder deserializes UTF-8 encoded strings from a byte array.\n * It reads all available bytes starting from the given offset.\n *\n * For more details, see {@link getUtf8Codec}.\n *\n * @returns A `VariableSizeDecoder<string>` for decoding UTF-8 strings.\n *\n * @example\n * Decoding a UTF-8 string.\n * ```ts\n * const decoder = getUtf8Decoder();\n * const value = decoder.decode(new Uint8Array([0x68, 0x65, 0x6c, 0x6c, 0x6f])); // \"hello\"\n * ```\n *\n * @see {@link getUtf8Codec}\n */\nexport const getUtf8Decoder = (): VariableSizeDecoder<string> => {\n    let textDecoder: TextDecoder;\n    return createDecoder({\n        read(bytes, offset) {\n            const value = (textDecoder ||= new TextDecoder()).decode(bytes.slice(offset));\n            return [removeNullCharacters(value), bytes.length];\n        },\n    });\n};\n\n/**\n * Returns a codec for encoding and decoding UTF-8 strings.\n *\n * This codec serializes strings using UTF-8 encoding.\n * The encoded output contains as many bytes as needed to represent the string.\n *\n * @returns A `VariableSizeCodec<string>` for encoding and decoding UTF-8 strings.\n *\n * @example\n * Encoding and decoding a UTF-8 string.\n * ```ts\n * const codec = getUtf8Codec();\n * const bytes = codec.encode('hello'); // 0x68656c6c6f\n * const value = codec.decode(bytes);   // \"hello\"\n * ```\n *\n * @remarks\n * This codec does not enforce a size boundary. It will encode and decode all bytes necessary to represent the string.\n *\n * If you need a fixed-size UTF-8 codec, consider using {@link fixCodecSize}.\n *\n * ```ts\n * const codec = fixCodecSize(getUtf8Codec(), 5);\n * ```\n *\n * If you need a size-prefixed UTF-8 codec, consider using {@link addCodecSizePrefix}.\n *\n * ```ts\n * const codec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * ```\n *\n * Separate {@link getUtf8Encoder} and {@link getUtf8Decoder} functions are available.\n *\n * ```ts\n * const bytes = getUtf8Encoder().encode('hello');\n * const value = getUtf8Decoder().decode(bytes);\n * ```\n *\n * @see {@link getUtf8Encoder}\n * @see {@link getUtf8Decoder}\n */\nexport const getUtf8Codec = (): VariableSizeCodec<string> => combineCodec(getUtf8Encoder(), getUtf8Decoder());\n"
  },
  {
    "path": "packages/codecs-strings/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/codecs-strings/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2020\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/codecs-strings\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/codecs-strings/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/compat/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/compat/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/compat/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/compat/CHANGELOG.md",
    "content": "# @solana/compat\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/instructions@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/instructions@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/instructions@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/transactions@6.6.0\n    - @solana/errors@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/instructions@6.6.0\n    - @solana/keys@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/instructions@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/instructions@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/instructions@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/transactions@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/instructions@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/transactions@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/instructions@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/transactions@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/transactions@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/instructions@6.1.0\n    - @solana/keys@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/transactions@6.0.1\n    - @solana/addresses@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/instructions@6.0.1\n    - @solana/keys@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/transactions@6.0.0\n    - @solana/addresses@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/instructions@6.0.0\n    - @solana/keys@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/instructions@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/transactions@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/instructions@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/transactions@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/instructions@5.4.0\n    - @solana/transactions@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/instructions@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/transactions@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- [#1116](https://github.com/anza-xyz/kit/pull/1116) [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549) Thanks [@steveluscher](https://github.com/steveluscher)! - Any `SharedArrayBuffer` that gets passed to a crypto operation like `signBytes` or `verifySignature` will now be copied as non-shared. Crypto operations like `sign` and `verify` reject `SharedArrayBuffers` otherwise\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/transactions@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/instructions@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951)]:\n    - @solana/errors@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/transactions@5.1.0\n    - @solana/instructions@5.1.0\n    - @solana/keys@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/transactions@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/instructions@5.0.0\n    - @solana/keys@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#906](https://github.com/anza-xyz/kit/pull/906) [`eabeb3a`](https://github.com/anza-xyz/kit/commit/eabeb3ac3e0a4550f22e2a1906d19b4c3146cc8a) Thanks [@guibescos](https://github.com/guibescos)! - Fixed a bug where calling `fromVersionedTransaction()` with a `VersionedTransaction` that uses address table lookups would result in a runtime fatal\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/transactions@4.0.0\n    - @solana/errors@4.0.0\n    - @solana/keys@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/instructions@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0), [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845), [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf)]:\n    - @solana/instructions@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/transactions@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/keys@3.0.0\n\n## 2.3.0\n\n### Minor Changes\n\n- [#488](https://github.com/anza-xyz/kit/pull/488) [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove the `I` prefix on the following types: `IInstruction`, `IInstructionWithAccounts`, `IInstructionWithData`, `IInstructionWithSigners`, `IAccountMeta`, `IAccountLookupMeta` and `IAccountSignerMeta`. The old names are kept as aliases but marked as deprecated.\n\n### Patch Changes\n\n- Updated dependencies [[`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a), [`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`bbcb913`](https://github.com/anza-xyz/kit/commit/bbcb913839d33abc746f38d6e65e7bfd30cd2ac6), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/transactions@2.3.0\n    - @solana/errors@2.3.0\n    - @solana/instructions@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/keys@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/instructions@2.2.1\n    - @solana/keys@2.2.1\n    - @solana/transactions@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/addresses@2.2.0\n    - @solana/keys@2.2.0\n    - @solana/transactions@2.2.0\n    - @solana/instructions@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/instructions@2.1.1\n    - @solana/transactions@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/errors@2.1.1\n    - @solana/keys@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- [#40](https://github.com/anza-xyz/kit/pull/40) [`790b050`](https://github.com/anza-xyz/kit/commit/790b0506d7d87b66120611cc8e7fe21a3981a00b) Thanks [@steveluscher](https://github.com/steveluscher)! - yAdded a helper to convert legacy `TransactionInstruction` objects to modern `IInstruction` objects\n\n- [#57](https://github.com/anza-xyz/kit/pull/57) [`9029dc1`](https://github.com/anza-xyz/kit/commit/9029dc18684ef9e823b1af803022f3829df58c83) Thanks [@nickfrosty](https://github.com/nickfrosty)! - updated readme to include instruction compat functions\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/keys@2.1.0\n    - @solana/instructions@2.1.0\n    - @solana/transactions@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/transactions@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/keys@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/keys@2.0.0-rc.4\n    - @solana/transactions@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/keys@2.0.0-rc.3\n    - @solana/transactions@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/transactions@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n    - @solana/keys@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies [[`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302)]:\n    - @solana/keys@2.0.0-rc.1\n    - @solana/transactions@2.0.0-rc.1\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/transactions@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/keys@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/keys@2.0.0-preview.4\n    - @solana/transactions@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/transactions@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/keys@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n    - @solana/functional@2.0.0-preview.2\n    - @solana/instructions@2.0.0-preview.2\n    - @solana/keys@2.0.0-preview.2\n    - @solana/transactions@2.0.0-preview.2\n"
  },
  {
    "path": "packages/compat/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/compat/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/compat?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/compat?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/compat\n\n# @solana/compat\n\nThis package contains utilities for converting from legacy web3js classes to the new data structures in Kit. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Functions\n\n### `fromLegacyPublicKey()`\n\nThis can be used to convert a legacy `PublicKey` object to an `Address` type\n\n```ts\nimport { fromLegacyPublicKey } from '@solana/compat';\nconst address = fromLegacyPublicKey(new PublicKey('49XBVQsvSW44ULKL9qufS9YqQPbdcps1TQRijx4FQ9sH'));\n```\n\n### `fromLegacyKeypair()`\n\nThis can be used to convert a legacy `Keypair` object to a native Ed25519 `CryptoKeyPair` object\n\n```ts\nimport { fromLegacyKeypair } from '@solana/compat';\nconst { privateKey, publicKey } = await fromLegacyKeypair(Keypair.generate());\n```\n\n### `fromVersionedTransaction()`\n\nThis can be used to convert a legacy `VersionedTransaction` object to a `Transaction` object.\n\n```ts\nimport { fromVersionedTransaction } from '@solana/compat';\n\n// imagine a function that returns a legacy `VersionedTransaction`\nconst legacyVersionedTransaction = getMyLegacyVersionedTransaction();\nconst transaction = fromVersionedTransaction(legacyVersionedTransaction);\n```\n\n### `fromLegacyTransactionInstruction()`\n\nThis can be used to convert a legacy `TransactionInstruction` object to a `Instruction` object.\n\n```ts\nimport { fromLegacyTransactionInstruction } from '@solana/compat';\n\n// imagine a function that returns a legacy `TransactionInstruction`\nconst legacyInstruction = getMyLegacyInstruction();\nconst instruction = fromLegacyTransactionInstruction(legacyInstruction);\n```\n"
  },
  {
    "path": "packages/compat/package.json",
    "content": "{\n    \"name\": \"@solana/compat\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for converting from legacy web3js classes\",\n    \"homepage\": \"https://www.solanakit.com/api#solanacompat\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.node.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.native.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/instructions\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/web3.js\": \"^1\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/compat/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/compat/src/__tests__/address-test.ts",
    "content": "import { Keypair } from '@solana/web3.js';\n\nimport { fromLegacyPublicKey } from '../address';\n\ndescribe('fromLegacyPublicKey', () => {\n    it('should convert from a Legacy Web3 JS PublicKey to an `Address`', () => {\n        const publicKey = Keypair.generate().publicKey;\n        expect(publicKey.toBase58()).toEqual(fromLegacyPublicKey(publicKey));\n    });\n});\n"
  },
  {
    "path": "packages/compat/src/__tests__/instruction-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { address } from '@solana/addresses';\nimport { AccountRole, Instruction } from '@solana/instructions';\nimport { PublicKey, TransactionInstruction } from '@solana/web3.js';\n\nimport { fromLegacyPublicKey } from '../address';\nimport { fromLegacyTransactionInstruction } from '../instruction';\n\nfunction toLegacyByteArrayAppropriateForPlatform<TArrayBuffer extends ArrayBuffer>(data: Uint8Array<TArrayBuffer>) {\n    if (__NODEJS__) {\n        return Buffer.from(data);\n    } else {\n        return new Uint8Array(data) as Buffer<TArrayBuffer>;\n    }\n}\n\ndescribe('fromLegacyTransactionInstruction', () => {\n    it('converts a basic TransactionInstruction', () => {\n        const programId = new Uint8Array([1, 2, 3, 4]);\n        const keys = [\n            {\n                isSigner: false,\n                isWritable: true,\n                pubkey: new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n            },\n        ];\n        const data = new Uint8Array([10, 20, 30]);\n\n        const instruction = new TransactionInstruction({\n            data: toLegacyByteArrayAppropriateForPlatform(data),\n            keys,\n            programId: new PublicKey(programId),\n        });\n\n        const converted = fromLegacyTransactionInstruction(instruction);\n\n        expect(converted).toStrictEqual<Instruction>({\n            accounts: [\n                {\n                    address: address('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n                    role: AccountRole.WRITABLE,\n                },\n            ],\n            data,\n            programAddress: fromLegacyPublicKey(new PublicKey(programId)),\n        });\n    });\n\n    it('freezes the accounts array', () => {\n        const programId = new Uint8Array([1, 2, 3, 4]);\n        const keys = [\n            {\n                isSigner: false,\n                isWritable: true,\n                pubkey: new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n            },\n        ];\n        const data = new Uint8Array([10, 20, 30]);\n\n        const instruction = new TransactionInstruction({\n            data: toLegacyByteArrayAppropriateForPlatform(data),\n            keys,\n            programId: new PublicKey(programId),\n        });\n\n        const converted = fromLegacyTransactionInstruction(instruction);\n\n        expect(converted.accounts).toBeFrozenObject();\n    });\n\n    it('freezes each account', () => {\n        const programId = new Uint8Array([1, 2, 3, 4]);\n        const keys = [\n            {\n                isSigner: false,\n                isWritable: true,\n                pubkey: new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n            },\n        ];\n        const data = new Uint8Array([10, 20, 30]);\n\n        const instruction = new TransactionInstruction({\n            data: toLegacyByteArrayAppropriateForPlatform(data),\n            keys,\n            programId: new PublicKey(programId),\n        });\n\n        const converted = fromLegacyTransactionInstruction(instruction);\n\n        expect(converted.accounts?.[0]).toBeFrozenObject();\n    });\n\n    it('freezes the instruction', () => {\n        const programId = new Uint8Array([1, 2, 3, 4]);\n        const keys = [\n            {\n                isSigner: false,\n                isWritable: true,\n                pubkey: new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n            },\n        ];\n        const data = new Uint8Array([10, 20, 30]);\n\n        const instruction = new TransactionInstruction({\n            data: toLegacyByteArrayAppropriateForPlatform(data),\n            keys,\n            programId: new PublicKey(programId),\n        });\n\n        const converted = fromLegacyTransactionInstruction(instruction);\n\n        expect(converted).toBeFrozenObject();\n    });\n\n    it('applies no accounts given an instruction with no keys', () => {\n        const programId = new Uint8Array([5, 6, 7, 8]);\n        const data = new Uint8Array([40, 50, 60]);\n\n        const instruction = new TransactionInstruction({\n            data: toLegacyByteArrayAppropriateForPlatform(data),\n            keys: [],\n            programId: new PublicKey(programId),\n        });\n\n        const converted = fromLegacyTransactionInstruction(instruction);\n\n        expect(converted).toStrictEqual<Instruction>({\n            data,\n            programAddress: fromLegacyPublicKey(new PublicKey(programId)),\n        });\n    });\n\n    it('handles an instruction with multiple keys', () => {\n        const programId = new Uint8Array([9, 10, 11, 12]);\n        const keys = [\n            { isSigner: true, isWritable: true, pubkey: new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK') },\n            {\n                isSigner: false,\n                isWritable: false,\n                pubkey: new PublicKey('9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw'),\n            },\n        ];\n        const data = new Uint8Array([70, 80, 90]);\n\n        const instruction = new TransactionInstruction({\n            data: toLegacyByteArrayAppropriateForPlatform(data),\n            keys,\n            programId: new PublicKey(programId),\n        });\n\n        const converted = fromLegacyTransactionInstruction(instruction);\n\n        expect(converted).toStrictEqual<Instruction>({\n            accounts: [\n                {\n                    address: address('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n                    role: AccountRole.WRITABLE_SIGNER,\n                },\n                {\n                    address: address('9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw'),\n                    role: AccountRole.READONLY,\n                },\n            ],\n            data,\n            programAddress: fromLegacyPublicKey(new PublicKey(programId)),\n        });\n    });\n\n    it('applies no data field if the data is zero-length', () => {\n        const programId = new Uint8Array([13, 14, 15, 16]);\n        const keys = [\n            {\n                isSigner: true,\n                isWritable: false,\n                pubkey: new PublicKey('F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT'),\n            },\n        ];\n\n        const instruction = new TransactionInstruction({\n            data: toLegacyByteArrayAppropriateForPlatform(new Uint8Array()),\n            keys,\n            programId: new PublicKey(programId),\n        });\n\n        const converted = fromLegacyTransactionInstruction(instruction);\n\n        expect(converted).toStrictEqual<Instruction>({\n            accounts: [\n                {\n                    address: address('F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT'),\n                    role: AccountRole.READONLY_SIGNER,\n                },\n            ],\n            programAddress: fromLegacyPublicKey(new PublicKey(programId)),\n        });\n    });\n\n    it('applies no data field if the data is missing', () => {\n        const programId = new Uint8Array([13, 14, 15, 16]);\n        const keys = [\n            {\n                isSigner: true,\n                isWritable: false,\n                pubkey: new PublicKey('F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT'),\n            },\n        ];\n\n        const instruction = new TransactionInstruction({\n            keys,\n            programId: new PublicKey(programId),\n        });\n\n        const converted = fromLegacyTransactionInstruction(instruction);\n\n        expect(converted).toStrictEqual<Instruction>({\n            accounts: [\n                {\n                    address: address('F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT'),\n                    role: AccountRole.READONLY_SIGNER,\n                },\n            ],\n            programAddress: fromLegacyPublicKey(new PublicKey(programId)),\n        });\n    });\n\n    it.each`\n        isSigner | isWritable | expected\n        ${false} | ${false}   | ${AccountRole.READONLY}\n        ${false} | ${true}    | ${AccountRole.WRITABLE}\n        ${true}  | ${false}   | ${AccountRole.READONLY_SIGNER}\n        ${true}  | ${true}    | ${AccountRole.WRITABLE_SIGNER}\n    `(\n        'converts keys with isSigner: $isSigner, isWritable: $isWritable to $expected',\n        ({\n            isSigner,\n            isWritable,\n            expected,\n        }: {\n            expected: keyof typeof AccountRole;\n            isSigner: boolean;\n            isWritable: boolean;\n        }) => {\n            expect(\n                fromLegacyTransactionInstruction(\n                    new TransactionInstruction({\n                        keys: [{ isSigner, isWritable, pubkey: PublicKey.default }],\n                        programId: PublicKey.default,\n                    }),\n                ),\n            ).toHaveProperty('accounts', expect.arrayContaining([expect.objectContaining({ role: expected })]));\n        },\n    );\n});\n"
  },
  {
    "path": "packages/compat/src/__tests__/keypair-test.ts",
    "content": "import { Keypair } from '@solana/web3.js';\n\nimport { fromLegacyKeypair } from '../keypair';\n\ndescribe('fromLegacyKeypair', () => {\n    const legacyKeypair = Keypair.generate();\n    describe.each(['public', 'private'])('%s key', type => {\n        let keyPair: CryptoKeyPair;\n        beforeEach(async () => {\n            keyPair = await fromLegacyKeypair(legacyKeypair);\n        });\n        it(`has the algorithm \"Ed25519\"`, () => {\n            expect(keyPair).toHaveProperty([`${type}Key`, 'algorithm', 'name'], 'Ed25519');\n        });\n        it('has the string tag \"CryptoKey\"', () => {\n            expect(keyPair).toHaveProperty([`${type}Key`, Symbol.toStringTag], 'CryptoKey');\n        });\n        it(`has the type \"${type}\"`, () => {\n            expect(keyPair).toHaveProperty([`${type}Key`, 'type'], type);\n        });\n    });\n    it.each([true, false])(\n        \"sets the private key's `extractable` accordingly when generating a key pair with the extractability `%s`\",\n        async extractable => {\n            expect.assertions(1);\n            const keyPair = await fromLegacyKeypair(legacyKeypair, extractable);\n            expect(keyPair.privateKey).toHaveProperty('extractable', extractable);\n        },\n    );\n});\n"
  },
  {
    "path": "packages/compat/src/__tests__/transaction-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport { PublicKey, VersionedTransaction } from '@solana/web3.js';\n\nimport { fromVersionedTransaction } from '../transaction';\n\ndescribe('fromVersionedTransaction', () => {\n    it('returns a transaction containing the serialized message bytes', () => {\n        const messageBytes = new Uint8Array([1, 2, 3, 4]);\n        const transaction = {\n            message: {\n                header: {\n                    numRequiredSignatures: 0,\n                },\n                serialize() {\n                    return messageBytes;\n                },\n                staticAccountKeys: [],\n            },\n            signatures: [],\n        } as unknown as VersionedTransaction;\n\n        const converted = fromVersionedTransaction(transaction);\n        expect(converted.messageBytes).toStrictEqual(messageBytes);\n    });\n\n    it('freezes the signature map', () => {\n        const transaction = {\n            message: {\n                header: {\n                    numRequiredSignatures: 0,\n                },\n                serialize() {\n                    return new Uint8Array();\n                },\n                staticAccountKeys: [],\n            },\n            signatures: [],\n        } as unknown as VersionedTransaction;\n\n        const converted = fromVersionedTransaction(transaction);\n        expect(converted.signatures).toBeFrozenObject();\n    });\n\n    it('converts a transaction with a single signature', () => {\n        const signature = new Uint8Array([1, 2, 3, 4]);\n        const transaction = {\n            message: {\n                header: {\n                    numRequiredSignatures: 1,\n                },\n                serialize() {\n                    return new Uint8Array();\n                },\n                staticAccountKeys: [new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK')],\n            },\n            signatures: [signature],\n        } as unknown as VersionedTransaction;\n\n        const converted = fromVersionedTransaction(transaction);\n        expect(converted.signatures).toStrictEqual({\n            '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK': signature,\n        });\n    });\n\n    it('converts an unsigned transaction with a single expected signer', () => {\n        const nullSignature = new Uint8Array(64).fill(0);\n        const transaction = {\n            message: {\n                header: {\n                    numRequiredSignatures: 1,\n                },\n                serialize() {\n                    return new Uint8Array();\n                },\n                staticAccountKeys: [new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK')],\n            },\n            signatures: [nullSignature],\n        } as unknown as VersionedTransaction;\n\n        const converted = fromVersionedTransaction(transaction);\n        expect(converted.signatures).toStrictEqual({\n            '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK': null,\n        });\n    });\n\n    it('converts a transaction with multiple signatures', () => {\n        const signature1 = new Uint8Array(64).fill(1);\n        const signature2 = new Uint8Array(64).fill(2);\n        const signature3 = new Uint8Array(64).fill(3);\n        const transaction = {\n            message: {\n                header: {\n                    numRequiredSignatures: 3,\n                },\n                serialize() {\n                    return new Uint8Array();\n                },\n                staticAccountKeys: [\n                    new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n                    new PublicKey('9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw'),\n                    new PublicKey('F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT'),\n                ],\n            },\n            signatures: [signature1, signature2, signature3],\n        } as unknown as VersionedTransaction;\n\n        const converted = fromVersionedTransaction(transaction);\n        expect(converted.signatures).toStrictEqual({\n            '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK': signature1,\n            '9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw': signature2,\n            F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT: signature3,\n        });\n    });\n\n    it('converts an unsigned transaction with multiple expected signers', () => {\n        const nullSignature = new Uint8Array(64).fill(0);\n        const transaction = {\n            message: {\n                header: {\n                    numRequiredSignatures: 3,\n                },\n                serialize() {\n                    return new Uint8Array();\n                },\n                staticAccountKeys: [\n                    new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n                    new PublicKey('9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw'),\n                    new PublicKey('F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT'),\n                ],\n            },\n            signatures: [nullSignature, nullSignature, nullSignature],\n        } as unknown as VersionedTransaction;\n\n        const converted = fromVersionedTransaction(transaction);\n        expect(converted.signatures).toStrictEqual({\n            '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK': null,\n            '9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw': null,\n            F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT: null,\n        });\n    });\n\n    it('converts a partially signed transaction with multiple expected signers', () => {\n        const nullSignature = new Uint8Array(64).fill(0);\n        const signature1 = new Uint8Array(64).fill(1);\n        const signature3 = new Uint8Array(64).fill(3);\n        const transaction = {\n            message: {\n                header: {\n                    numRequiredSignatures: 3,\n                },\n                serialize() {\n                    return new Uint8Array();\n                },\n                staticAccountKeys: [\n                    new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n                    new PublicKey('9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw'),\n                    new PublicKey('F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT'),\n                ],\n            },\n            signatures: [signature1, nullSignature, signature3],\n        } as unknown as VersionedTransaction;\n\n        const converted = fromVersionedTransaction(transaction);\n        expect(converted.signatures).toStrictEqual({\n            '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK': signature1,\n            '9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw': null,\n            F7Kzv7G6p1PvHXL1xXLPTm4myKWpLjnVphCV8ABZJfgT: signature3,\n        });\n    });\n\n    it('throws if the signatures are not the same length as the number of signers', () => {\n        const messageBytes = new Uint8Array([1, 2, 3, 4]);\n        const transaction = {\n            message: {\n                header: {\n                    numRequiredSignatures: 2,\n                },\n                serialize() {\n                    return messageBytes;\n                },\n                staticAccountKeys: [\n                    new PublicKey('7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK'),\n                    new PublicKey('9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw'),\n                ],\n            },\n            signatures: [new Uint8Array(64).fill(1)],\n        } as unknown as VersionedTransaction;\n\n        expect(() => fromVersionedTransaction(transaction)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n                numRequiredSignatures: 2,\n                signaturesLength: 1,\n                signerAddresses: [\n                    '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK',\n                    '9A87Qt8sxxLMe7hcrjC4cPnho1CwWKRpk84ZTRPyvWNw',\n                ],\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/compat/src/__typetests__/address-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { PublicKey } from '@solana/web3.js';\n\nimport { fromLegacyPublicKey } from '../address';\n\n{\n    const publicKey = null as unknown as PublicKey;\n    fromLegacyPublicKey(publicKey) satisfies Address;\n    fromLegacyPublicKey(publicKey) satisfies Address<ReturnType<typeof publicKey.toBase58>>;\n}\n\n{\n    const publicKey = { toBase58: () => 'test' } as unknown as PublicKey;\n    fromLegacyPublicKey(publicKey) satisfies Address;\n    fromLegacyPublicKey(publicKey) satisfies Address<'test'>;\n}\n\n{\n    // Randomly generated\n    const publicKey = new PublicKey('B3piXWBQLLRuk56XG5VihxR4oe2PSsDM8nTF6s1DeVF5');\n    fromLegacyPublicKey(publicKey) satisfies Address;\n    fromLegacyPublicKey(publicKey) satisfies Address<'B3piXWBQLLRuk56XG5VihxR4oe2PSsDM8nTF6s1DeVF5'>;\n}\n"
  },
  {
    "path": "packages/compat/src/__typetests__/instruction-typetest.ts",
    "content": "import { Instruction } from '@solana/instructions';\nimport { TransactionInstruction } from '@solana/web3.js';\n\nimport { fromLegacyTransactionInstruction } from '../instruction';\n\nconst legacyInstruction = null as unknown as TransactionInstruction;\n\nfromLegacyTransactionInstruction(legacyInstruction) satisfies Instruction;\n"
  },
  {
    "path": "packages/compat/src/__typetests__/keypair-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { Keypair } from '@solana/web3.js';\n\nimport { fromLegacyKeypair } from '../keypair';\n\n{\n    const keypair = null as unknown as Keypair;\n    fromLegacyKeypair(keypair) satisfies Promise<CryptoKeyPair>;\n}\n"
  },
  {
    "path": "packages/compat/src/__typetests__/transaction-typetest.ts",
    "content": "import { Transaction } from '@solana/transactions';\nimport { VersionedTransaction } from '@solana/web3.js';\n\nimport { fromVersionedTransaction } from '../transaction';\n\nconst transaction = null as unknown as VersionedTransaction;\nfromVersionedTransaction(transaction) satisfies Transaction;\n"
  },
  {
    "path": "packages/compat/src/address.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { PublicKey } from '@solana/web3.js';\n\n/**\n * Converts a legacy [PublicKey](https://solana-foundation.github.io/solana-web3.js/classes/PublicKey.html)\n * object to an {@link Address}.\n *\n * @example\n * ```ts\n * import { fromLegacyPublicKey } from '@solana/compat';\n *\n * const legacyPublicKey = new PublicKey('49XBVQsvSW44ULKL9qufS9YqQPbdcps1TQRijx4FQ9sH');\n * const address = fromLegacyPublicKey(legacyPublicKey);\n * ```\n */\nexport function fromLegacyPublicKey<TAddress extends string>(publicKey: PublicKey): Address<TAddress> {\n    return publicKey.toBase58() as Address<TAddress>;\n}\n"
  },
  {
    "path": "packages/compat/src/index.ts",
    "content": "/**\n * This package contains utilities for converting from legacy web3.js classes to the data\n * structures in Kit. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './address';\nexport * from './instruction';\nexport * from './keypair';\nexport * from './transaction';\n"
  },
  {
    "path": "packages/compat/src/instruction.ts",
    "content": "import { AccountRole, Instruction } from '@solana/instructions';\nimport { TransactionInstruction } from '@solana/web3.js';\n\nimport { fromLegacyPublicKey } from './address';\n\n/**\n * This can be used to convert a legacy [`TransactionInstruction`](https://solana-foundation.github.io/solana-web3.js/classes/TransactionInstruction.html)\n * object to an {@link Instruction}.\n *\n * @example\n * ```ts\n * import { fromLegacyTransactionInstruction } from '@solana/compat';\n *\n * // Imagine a function that returns a legacy `TransactionInstruction`\n * const legacyInstruction = getMyLegacyInstruction();\n * const instruction = fromLegacyTransactionInstruction(legacyInstruction);\n * ```\n */\nexport function fromLegacyTransactionInstruction(legacyInstruction: TransactionInstruction): Instruction {\n    const data = legacyInstruction.data?.byteLength > 0 ? Uint8Array.from(legacyInstruction.data) : undefined;\n    const accounts = legacyInstruction.keys.map(accountMeta =>\n        Object.freeze({\n            address: fromLegacyPublicKey(accountMeta.pubkey),\n            role: determineRole(accountMeta.isSigner, accountMeta.isWritable),\n        }),\n    );\n    const programAddress = fromLegacyPublicKey(legacyInstruction.programId);\n    return Object.freeze({\n        ...(accounts.length ? { accounts: Object.freeze(accounts) } : null),\n        ...(data ? { data } : null),\n        programAddress,\n    });\n}\n\nfunction determineRole(isSigner: boolean, isWritable: boolean): AccountRole {\n    if (isSigner && isWritable) return AccountRole.WRITABLE_SIGNER;\n    if (isSigner) return AccountRole.READONLY_SIGNER;\n    if (isWritable) return AccountRole.WRITABLE;\n    return AccountRole.READONLY;\n}\n"
  },
  {
    "path": "packages/compat/src/keypair.ts",
    "content": "import { createKeyPairFromBytes } from '@solana/keys';\nimport { Keypair } from '@solana/web3.js';\n\n/**\n * Converts a legacy [Keypair](https://solana-foundation.github.io/solana-web3.js/classes/Keypair.html)\n * object to a native Ed25519 {@link CryptoKeyPair} object.\n *\n * @example\n * ```ts\n * import { fromLegacyKeypair } from '@solana/compat';\n *\n * const legacyKeyPair = Keypair.generate();\n * const { privateKey, publicKey } = await fromLegacyKeypair(legacyKeyPair);\n * ```\n */\nexport async function fromLegacyKeypair(keypair: Keypair, extractable?: boolean): Promise<CryptoKeyPair> {\n    const bytes = new Uint8Array(64);\n    bytes.set(keypair.secretKey);\n    bytes.set(keypair.publicKey.toBytes(), /* offset */ 32);\n    return await createKeyPairFromBytes(bytes, extractable);\n}\n"
  },
  {
    "path": "packages/compat/src/transaction.ts",
    "content": "import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, SolanaError } from '@solana/errors';\nimport type { SignatureBytes } from '@solana/keys';\nimport { type SignaturesMap, Transaction, TransactionMessageBytes } from '@solana/transactions';\nimport type { PublicKey, VersionedTransaction } from '@solana/web3.js';\n\nfunction convertSignatures(transaction: VersionedTransaction, staticAccountKeys: PublicKey[]): SignaturesMap {\n    return Object.fromEntries(\n        transaction.signatures.map((sig, index) => {\n            const address = staticAccountKeys[index];\n            if (sig.every(b => b === 0)) {\n                // all-0 signatures are stored as null\n                return [address, null];\n            } else {\n                return [address, sig as ReadonlyUint8Array as SignatureBytes];\n            }\n        }),\n    );\n}\n\n/**\n * This can be used to convert a legacy [VersionedTransaction](https://solana-foundation.github.io/solana-web3.js/classes/VersionedTransaction.html)\n * object to a {@link Transaction}.\n *\n * @example\n * ```ts\n * import { fromVersionedTransaction } from '@solana/compat';\n *\n * // Imagine a function that returns a legacy `VersionedTransaction`\n * const legacyVersionedTransaction = getMyLegacyVersionedTransaction();\n * const transaction = fromVersionedTransaction(legacyVersionedTransaction);\n * ```\n */\nexport function fromVersionedTransaction(transaction: VersionedTransaction): Transaction {\n    const { message } = transaction;\n    const staticAccountKeys = message.staticAccountKeys;\n\n    const { numRequiredSignatures } = message.header;\n    if (numRequiredSignatures !== transaction.signatures.length) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n            numRequiredSignatures: transaction.message.header.numRequiredSignatures,\n            signaturesLength: transaction.signatures.length,\n            signerAddresses: staticAccountKeys.slice(0, numRequiredSignatures).map(p => p.toBase58()),\n        });\n    }\n\n    const messageBytes = message.serialize() as ReadonlyUint8Array as TransactionMessageBytes;\n    const signatures = convertSignatures(transaction, staticAccountKeys);\n\n    return {\n        messageBytes,\n        signatures: Object.freeze(signatures),\n    };\n}\n"
  },
  {
    "path": "packages/compat/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/compat/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2017\", \"ES2019.Array\", \"ES2020.BigInt\", \"ES2022.Error\"],\n        \"resolveJsonModule\": true\n    },\n    \"display\": \"@solana/compat\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/compat/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/crypto-impl/.gitignore",
    "content": "dist/\n"
  },
  {
    "path": "packages/crypto-impl/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/crypto-impl/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/crypto-impl/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/crypto-impl/package.json",
    "content": "{\n    \"name\": \"@solana/crypto-impl\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"exports\": {\n        \"edge-light\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        }\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"types\": \"./dist/types/index.browser.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\"\n    ],\n    \"sideEffects\": false,\n    \"scripts\": {\n        \"compile:js\": \"tsup\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/crypto-impl/src/index.browser.ts",
    "content": "export default globalThis.crypto;\n"
  },
  {
    "path": "packages/crypto-impl/src/index.node.ts",
    "content": "// When building the browser bundle, this import gets replaced by `globalThis.crypto`.\nimport crypto from 'node:crypto';\n\nexport default crypto;\n"
  },
  {
    "path": "packages/crypto-impl/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"isolatedModules\": false,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.browser.ts\"]\n}\n"
  },
  {
    "path": "packages/crypto-impl/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\"]\n    },\n    \"display\": \"Crypto Implementation\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/crypto-impl/tsup.config.ts",
    "content": "import { defineConfig } from 'tsup';\n\nexport default defineConfig(_options =>\n    (['browser', 'node'] as const).map(platform => ({\n        entry: [`./src/index.${platform}.ts`],\n        format: ['cjs', 'esm'],\n        minify: true,\n        name: platform,\n        outExtension({ format }) {\n            return { js: `.${format === 'cjs' ? 'cjs' : 'mjs'}` };\n        },\n        platform,\n        sourcemap: true,\n        treeshake: true,\n    })),\n);\n"
  },
  {
    "path": "packages/errors/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/errors/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/errors/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/errors/CHANGELOG.md",
    "content": "# @solana/errors\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1542](https://github.com/anza-xyz/kit/pull/1542) [`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `SOLANA_ERROR__WALLET__NO_SIGNER_CONNECTED` and `SOLANA_ERROR__WALLET__SIGNER_NOT_AVAILABLE` error codes for wallet-signer availability checks.\n\n- [#1559](https://github.com/anza-xyz/kit/pull/1559) [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add 13 new error codes in the `[8090000, 8090999]` range for the upcoming `@solana/fixed-points` package: `INVALID_TOTAL_BITS`, `INVALID_FRACTIONAL_BITS`, `INVALID_DECIMALS`, `FRACTIONAL_BITS_EXCEED_TOTAL_BITS`, `VALUE_OUT_OF_RANGE`, `INVALID_STRING`, `INVALID_ZERO_DENOMINATOR_RATIO`, `ARITHMETIC_OVERFLOW`, `SHAPE_MISMATCH`, `DIVISION_BY_ZERO`, `STRICT_MODE_PRECISION_LOSS`, `MALFORMED_RAW_VALUE`, and `TOTAL_BITS_NOT_BYTE_ALIGNED`.\n\n- [#1544](https://github.com/anza-xyz/kit/pull/1544) [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update RPC types for Agave v3.x validator compatibility.\n\n    **`@solana/rpc-parsed-types`**: `JsonParsedVoteAccount` now includes `blockRevenueCollector`, `blockRevenueCommissionBps`, `blsPubkeyCompressed`, `inflationRewardsCollector`, `inflationRewardsCommissionBps`, `pendingDelegatorRewards`, and a `latency` field on each vote entry.\n\n    **`@solana/rpc-api`**: `SimulateTransactionApiResponseBase` now includes `fee`, `loadedAddresses`, `preBalances`, `postBalances`, `preTokenBalances`, and `postTokenBalances`.\n\n    **`@solana/errors`**: `RpcSimulateTransactionResult` updated with the same new fields.\n\n    **Note on `replacementBlockhash`**: Agave v3.x validators now always return `replacementBlockhash` in `simulateTransaction` responses (as `null` when `replaceRecentBlockhash` is not set). Kit's types still model this field as conditionally present based on config. A future breaking change will move it to the base response type as `TransactionBlockhashLifetime | null` to match v3.x behavior. Consumers using v3.x validators may see this field at runtime even when Kit's types don't surface it.\n\n    **Note on Agave v3.x validator behavior**: Validators running Agave v3.x no longer return a dedicated `TRANSACTION_SIGNATURE_VERIFICATION_FAILURE` RPC error for invalid signatures in `simulateTransaction` or `sendTransaction`. Instead, `simulateTransaction` returns a result with `err: \"SignatureFailure\"`, and `sendTransaction` returns a preflight failure with the signature error as the cause. This is a validator-level change and does not affect Kit's API surface.\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n## 6.8.0\n\n### Minor Changes\n\n- [#1534](https://github.com/anza-xyz/kit/pull/1534) [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `grindKeyPair`, `grindKeyPairs`, `grindKeyPairSigner`, and `grindKeyPairSigners` for mining vanity key pairs whose base58-encoded public key matches a `RegExp` or a custom predicate. Supports `amount` for mining multiple key pairs, `extractable` for forwarding to the underlying `generateKeyPair` call, `concurrency` (defaulting to `32`) for batched parallel key generation, and `abortSignal` for cancellation. Regex matchers are statically checked for base58-alphabet violations at runtime (after stripping escapes, character classes, quantifiers, and groups) to catch common typos like `/^sol0/`.\n\n- [#1526](https://github.com/anza-xyz/kit/pull/1526) [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `SOLANA_ERROR__WALLET__NOT_CONNECTED` error code for when a wallet operation is attempted without a connected wallet.\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n## 6.6.0\n\n### Minor Changes\n\n- [#1496](https://github.com/anza-xyz/kit/pull/1496) [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad) Thanks [@mcintyre94](https://github.com/mcintyre94)! - `compileTransactionMessage` now enforces four Solana protocol limits at compile time, throwing a typed `SolanaError` instead of silently producing a transaction that would be rejected by the network:\n    - More than 64 unique account addresses → `SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES`\n    - More than 12 unique signer addresses → `SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES`\n    - More than 64 instructions → `SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS`\n    - More than 255 accounts in a single instruction → `SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION`\n\n    All four error codes (and their context types / human-readable messages) are exported from `@solana/errors`.\n\n## 6.5.0\n\n## 6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n### Minor Changes\n\n- [#1444](https://github.com/anza-xyz/kit/pull/1444) [`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Enrich the `SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT` error context with the full simulation result (`Omit<RpcSimulateTransactionResult, 'err'>`) and add it to `SolanaErrorCodeWithCause`, aligning it with the `SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE` error.\n\n## 6.2.0\n\n### Patch Changes\n\n- [#1440](https://github.com/anza-xyz/kit/pull/1440) [`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Append the instruction index to all instruction error messages (e.g. `(instruction #1)`) and add a human-readable message for unknown instruction errors.\n\n- [#1432](https://github.com/anza-xyz/kit/pull/1432) [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION` and `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS` error codes for high-level transaction sending wrappers.\n\n- [#1442](https://github.com/anza-xyz/kit/pull/1442) [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove stale `$encodedData` interpolation from the `BORSH_IO_ERROR` message. The `encodedData` context property was removed in v5.0.0 but the message template was not updated, causing the literal `$encodedData` to appear in the rendered error message.\n\n- [#1433](https://github.com/anza-xyz/kit/pull/1433) [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `abortReason` to the `SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN` error context so consumers can access the abort reason when converting this error to higher-level error types.\n\n## 6.1.0\n\n### Patch Changes\n\n- [#1344](https://github.com/anza-xyz/kit/pull/1344) [`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new error codes for program clients: `SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS`, `SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE`, `SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION`, `SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE`, and `SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL`.\n\n- [#1366](https://github.com/anza-xyz/kit/pull/1366) [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add two new `SolanaError` codes for program clients: `SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_ACCOUNT_TYPE` and `SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT`.\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- [#1264](https://github.com/anza-xyz/kit/pull/1264) [`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Exports missing helpers in errors and instruction-plans\n\n## 5.5.0\n\n### Minor Changes\n\n- [#1253](https://github.com/anza-xyz/kit/pull/1253) [`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `isX` and `assertIsX` type guard helpers for instruction plans, transaction plans, and transaction plan results\n\n- [#1260](https://github.com/anza-xyz/kit/pull/1260) [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Mark the `cause` deprecated for `SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN` error\n\n- [#1254](https://github.com/anza-xyz/kit/pull/1254) [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `SuccessfulTransactionPlanResult` type with `isSuccessfulTransactionPlanResult` and `assertIsSuccessfulTransactionPlanResult` type guards\n\n- [#1236](https://github.com/anza-xyz/kit/pull/1236) [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `getFirstFailedSingleTransactionPlanResult`, which you can use to get the first failed transaction plan result from a transaction plan result, or throw if none failed\n\n- [#1230](https://github.com/anza-xyz/kit/pull/1230) [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function `unwrapSimulationError`, which will return the cause of an error if it is a simulation error. Otherwise it is returned unchanged.\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- [#1186](https://github.com/anza-xyz/kit/pull/1186) [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix type of error in sendTransaction preflight error\n\n    Some fields in `RpcSimulateTransactionResult` were incorrectly typed as number when they should have been bigint. At runtime these were bigint because of a bug.\n\n    At runtime all numeric fields in `RpcSimulateTransactionResult` were a bigint, but those typed as number are now correct.\n\n## 5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- [#1155](https://github.com/anza-xyz/kit/pull/1155) [`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Throw early when the default transaction plan executor encounters a non-divisible transaction plan.\n\n## 5.1.0\n\n### Minor Changes\n\n- [#880](https://github.com/anza-xyz/kit/pull/880) [`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Added codecs for encoding and decoding Solana Offchain Messages (see https://github.com/solana-foundation/SRFCs/discussions/3)\n\n- [#984](https://github.com/anza-xyz/kit/pull/984) [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df) Thanks [@steveluscher](https://github.com/steveluscher)! - Added the capability to sign Solana Offchain Messages using a `CryptoKey`\n\n## 5.0.0\n\n### Major Changes\n\n- [#974](https://github.com/anza-xyz/kit/pull/974) [`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389) Thanks [@joncinque](https://github.com/joncinque)! - `BorshIoErrors` from the RPC no longer contain an `encodedData` property. This property used to hold the underlying error from the serialization library used on the server. This message was always subject to changes in the version of that library, or changes in the choice of library itself. New versions of the server no longer throw the underlying error, so for consistency it has been removed everywhere in Kit.\n\n## 4.0.0\n\n### Patch Changes\n\n- [#918](https://github.com/anza-xyz/kit/pull/918) [`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function to extract the lifetime from a CompiledTransactionMessage\n\n- [#871](https://github.com/anza-xyz/kit/pull/871) [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Do not allow decoding transactions with an unsupported version\n\n- [#873](https://github.com/anza-xyz/kit/pull/873) [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768) Thanks [@steveluscher](https://github.com/steveluscher)! - When you use the `@solana/errors` CLI you will now _always_ get version 5.6.2 of `chalk` and version 14.0.0 of `commander`, which themselves are zero-dependency.\n\n- [#944](https://github.com/anza-xyz/kit/pull/944) [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function to create a decoder that checks the size of the input bytes\n\n- [#919](https://github.com/anza-xyz/kit/pull/919) [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update useWalletAccountTransactionSigner to return a LifetimeConstraint for the updated transaction\n\n## 3.0.0\n\n### Minor Changes\n\n- [#664](https://github.com/anza-xyz/kit/pull/664) [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `createTransactionPlanExecutor` implementation for the `TransactionPlanExecutor` type.\n\n- [#648](https://github.com/anza-xyz/kit/pull/648) [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `createTransactionPlanner` implementation for the `TransactionPlanner` type.\n\n### Patch Changes\n\n- [#674](https://github.com/anza-xyz/kit/pull/674) [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Allow `SolanaError` context objects to use non-enumerable properties. This is useful when it's appropriate for an object to appear in the error context at runtime, but when that object can't be serialized for use by the production mode error decoder. Prior to this, non-enumerable properties would be deleted from context objects when creating new `SolanaErrors`.\n\n- [#658](https://github.com/anza-xyz/kit/pull/658) [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052) Thanks [@steveluscher](https://github.com/steveluscher)! - Added three missing error messages/contexts\n    - `JSON_RPC_SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE`: -32017\n    - `JSON_RPC_SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY`: -32018\n    - `JSON_RPC_SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE`: -32019\n\n## 2.3.0\n\n### Minor Changes\n\n- [#426](https://github.com/anza-xyz/kit/pull/426) [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate the `I` prefix of four transaction message types to stay consistent with the rest of them. Namely, the following types are renamed and their old names are marked as deprecated:\n    - `ITransactionMessageWithFeePayer` -> `TransactionMessageWithFeePayer`\n    - `ITransactionMessageWithFeePayerSigner` -> `TransactionMessageWithFeePayerSigner`\n    - `ITransactionMessageWithSigners` -> `TransactionMessageWithSigners`\n    - `ITransactionMessageWithSingleSendingSigner` -> `TransactionMessageWithSingleSendingSigner`\n\n### Patch Changes\n\n- [#566](https://github.com/anza-xyz/kit/pull/566) [`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df) Thanks [@steveluscher](https://github.com/steveluscher)! - The `unitsConsumed` property in simulation result errors was incorrectly marked as a `number` when it is in fact a `bigint`\n\n- [#567](https://github.com/anza-xyz/kit/pull/567) [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4) Thanks [@steveluscher](https://github.com/steveluscher)! - Added `replacementBlockhash` to the simulation result type. This field materializes in cases where simulation was performed with the `replaceRecentBlockhash` param set to `true`.\n\n- [#425](https://github.com/anza-xyz/kit/pull/425) [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a variety of types, constants and functions to help with transaction sizes and their limits\n\n## 2.2.1\n\n## 2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n## 2.1.0\n\n### Minor Changes\n\n- [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c) Thanks [@steveluscher](https://github.com/steveluscher)! - When the HTTP transport throws an error, you can now access the response headers through `e.context.headers`. This can be useful, for instance, if the HTTP error is a 429 Rate Limit error, and the response contains a `Retry-After` header.\n\n    ```ts\n    try {\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n    } catch (e) {\n        if (isSolanaError(e, SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR)) {\n            if (e.context.code === 429 /* rate limit error */) {\n                const retryAfterHeaderValue = e.context.headers.get('Retry-After');\n                if (retryAfterHeaderValue != null) {\n                    // ...\n                }\n            }\n        }\n    }\n    ```\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- [#130](https://github.com/anza-xyz/kit/pull/130) [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Gracefully handle JSON RPC errors that do not provide a `code` attribute in their response\n\n- [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Change `data` field of transaction message instructions to use `ReadonlyUint8Array`\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2376](https://github.com/solana-labs/solana-web3.js/pull/2376) [`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug that prevented the production error decoder from decoding negative error codes\n\n- [#2419](https://github.com/solana-labs/solana-web3.js/pull/2419) [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `addCodecSentinel` primitive\n\n    The `addCodecSentinel` function provides a new way of delimiting the size of a codec. It allows us to add a sentinel to the end of the encoded data and to read until that sentinel is found when decoding. It accepts any codec and a `Uint8Array` sentinel responsible for delimiting the encoded data.\n\n    ```ts\n    const codec = addCodecSentinel(getUtf8Codec(), new Uint8Array([255, 255]));\n    codec.encode('hello');\n    // 0x68656c6c6fffff\n    //   |        └-- Our sentinel.\n    //   └-- Our encoded string.\n    ```\n\n- [#2400](https://github.com/solana-labs/solana-web3.js/pull/2400) [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `containsBytes` and `getConstantCodec` helpers\n\n    The `containsBytes` helper checks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n\n    ```ts\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n    ```\n\n    The `getConstantCodec` function accepts any `Uint8Array` and returns a `Codec<void>`. When encoding, it will set the provided `Uint8Array` as-is. When decoding, it will assert that the next bytes contain the provided `Uint8Array` and move the offset forward.\n\n    ```ts\n    const codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n\n    codec.encode(undefined); // 0x010203\n    codec.decode(new Uint8Array([1, 2, 3])); // undefined\n    codec.decode(new Uint8Array([1, 2, 4])); // Throws an error.\n    ```\n\n- [#2383](https://github.com/solana-labs/solana-web3.js/pull/2383) [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getScalarEnumCodec` is now called `getEnumCodec`\n\n- [#2430](https://github.com/solana-labs/solana-web3.js/pull/2430) [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added `useValuesAsDiscriminators` option to `getEnumCodec`\n\n    When dealing with numerical enums that have explicit values, you may now use the `useValuesAsDiscriminators` option to encode the value of the enum variant instead of its index.\n\n    ```ts\n    enum Numbers {\n        One,\n        Five = 5,\n        Six,\n        Nine = 9,\n    }\n\n    const codec = getEnumCodec(Numbers, { useValuesAsDiscriminators: true });\n    codec.encode(Direction.One); // 0x00\n    codec.encode(Direction.Five); // 0x05\n    codec.encode(Direction.Six); // 0x06\n    codec.encode(Direction.Nine); // 0x09\n    ```\n\n    Note that when using the `useValuesAsDiscriminators` option on an enum that contains a lexical value, an error will be thrown.\n\n    ```ts\n    enum Lexical {\n        One,\n        Two = 'two',\n    }\n    getEnumCodec(Lexical, { useValuesAsDiscriminators: true }); // Throws an error.\n    ```\n\n- [#2358](https://github.com/solana-labs/solana-web3.js/pull/2358) [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199) Thanks [@steveluscher](https://github.com/steveluscher)! - The encoded `SolanaError` context that is thrown in production is now base64-encoded for compatibility with more terminal shells\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2398](https://github.com/solana-labs/solana-web3.js/pull/2398) [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `getUnionCodec` helper that can be used to encode/decode any TypeScript union.\n\n    ```ts\n    const codec: Codec<number | boolean> = getUnionCodec(\n        [getU16Codec(), getBooleanCodec()],\n        value => (typeof value === 'number' ? 0 : 1),\n        (bytes, offset) => (bytes.slice(offset).length > 1 ? 0 : 1),\n    );\n\n    codec.encode(42); // 0x2a00\n    codec.encode(true); // 0x01\n    ```\n\n- [#2382](https://github.com/solana-labs/solana-web3.js/pull/2382) [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getDataEnumCodec` is now called `getDiscriminatedUnionCodec`\n\n- [#2785](https://github.com/solana-labs/solana-web3.js/pull/2785) [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df) Thanks [@steveluscher](https://github.com/steveluscher)! - The development mode error message printer no longer fatals on Safari < 16.4.\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#3519](https://github.com/solana-labs/solana-web3.js/pull/3519) [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Accept bigints in RPC error factories, fixing functions such as `isProgramError`\n\n- [#2867](https://github.com/solana-labs/solana-web3.js/pull/2867) [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418) Thanks [@steveluscher](https://github.com/steveluscher)! - The `innerInstructions` property of JSON-RPC errors used snake case rather than camelCase for `stackHeight` and `programId`. This has been corrected.\n\n- [#2394](https://github.com/solana-labs/solana-web3.js/pull/2394) [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `getLiteralUnionCodec`\n\n    ```ts\n    const codec = getLiteralUnionCodec(['left', 'right', 'up', 'down']);\n    // ^? FixedSizeCodec<\"left\" | \"right\" | \"up\" | \"down\">\n\n    const bytes = codec.encode('left'); // 0x00\n    const value = codec.decode(bytes); // 'left'\n    ```\n\n- [#2410](https://github.com/solana-labs/solana-web3.js/pull/2410) [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `getZeroableNullableCodec` and `getZeroableOptionCodec` functions\n\n    These functions rely on a zero value to represent `None` or `null` values as opposed to using a boolean prefix.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec());\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0x0000\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.encode(new Uint8Array([0, 0])); // null\n    ```\n\n    Both functions can also be provided with a custom definition of the zero value using the `zeroValue` option.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec(), {\n        zeroValue: new Uint8Array([255, 255]),\n    });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0xfffff\n    codec.encode(new Uint8Array([0, 0])); // 0\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([255, 255])); // null\n    ```\n\n- [#2329](https://github.com/solana-labs/solana-web3.js/pull/2329) [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8) Thanks [@luu-alex](https://github.com/luu-alex)! - `createKeyPairFromBytes()` now validates that the public key imported is the one that would be derived from the private key imported\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- [#3519](https://github.com/solana-labs/solana-web3.js/pull/3519) [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Accept bigints in RPC error factories, fixing functions such as `isProgramError`\n\n## 2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2785](https://github.com/solana-labs/solana-web3.js/pull/2785) [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df) Thanks [@steveluscher](https://github.com/steveluscher)! - The development mode error message printer no longer fatals on Safari < 16.4.\n\n- [#2867](https://github.com/solana-labs/solana-web3.js/pull/2867) [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418) Thanks [@steveluscher](https://github.com/steveluscher)! - The `innerInstructions` property of JSON-RPC errors used snake case rather than camelCase for `stackHeight` and `programId`. This has been corrected.\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2376](https://github.com/solana-labs/solana-web3.js/pull/2376) [`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug that prevented the production error decoder from decoding negative error codes\n\n- [#2419](https://github.com/solana-labs/solana-web3.js/pull/2419) [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `addCodecSentinel` primitive\n\n    The `addCodecSentinel` function provides a new way of delimiting the size of a codec. It allows us to add a sentinel to the end of the encoded data and to read until that sentinel is found when decoding. It accepts any codec and a `Uint8Array` sentinel responsible for delimiting the encoded data.\n\n    ```ts\n    const codec = addCodecSentinel(getUtf8Codec(), new Uint8Array([255, 255]));\n    codec.encode('hello');\n    // 0x68656c6c6fffff\n    //   |        └-- Our sentinel.\n    //   └-- Our encoded string.\n    ```\n\n- [#2400](https://github.com/solana-labs/solana-web3.js/pull/2400) [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `containsBytes` and `getConstantCodec` helpers\n\n    The `containsBytes` helper checks if a `Uint8Array` contains another `Uint8Array` at a given offset.\n\n    ```ts\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 1); // true\n    containsBytes(new Uint8Array([1, 2, 3, 4]), new Uint8Array([2, 3]), 2); // false\n    ```\n\n    The `getConstantCodec` function accepts any `Uint8Array` and returns a `Codec<void>`. When encoding, it will set the provided `Uint8Array` as-is. When decoding, it will assert that the next bytes contain the provided `Uint8Array` and move the offset forward.\n\n    ```ts\n    const codec = getConstantCodec(new Uint8Array([1, 2, 3]));\n\n    codec.encode(undefined); // 0x010203\n    codec.decode(new Uint8Array([1, 2, 3])); // undefined\n    codec.decode(new Uint8Array([1, 2, 4])); // Throws an error.\n    ```\n\n- [#2383](https://github.com/solana-labs/solana-web3.js/pull/2383) [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getScalarEnumCodec` is now called `getEnumCodec`\n\n- [#2430](https://github.com/solana-labs/solana-web3.js/pull/2430) [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added `useValuesAsDiscriminators` option to `getEnumCodec`\n\n    When dealing with numerical enums that have explicit values, you may now use the `useValuesAsDiscriminators` option to encode the value of the enum variant instead of its index.\n\n    ```ts\n    enum Numbers {\n        One,\n        Five = 5,\n        Six,\n        Nine = 9,\n    }\n\n    const codec = getEnumCodec(Numbers, { useValuesAsDiscriminators: true });\n    codec.encode(Direction.One); // 0x00\n    codec.encode(Direction.Five); // 0x05\n    codec.encode(Direction.Six); // 0x06\n    codec.encode(Direction.Nine); // 0x09\n    ```\n\n    Note that when using the `useValuesAsDiscriminators` option on an enum that contains a lexical value, an error will be thrown.\n\n    ```ts\n    enum Lexical {\n        One,\n        Two = 'two',\n    }\n    getEnumCodec(Lexical, { useValuesAsDiscriminators: true }); // Throws an error.\n    ```\n\n- [#2358](https://github.com/solana-labs/solana-web3.js/pull/2358) [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199) Thanks [@steveluscher](https://github.com/steveluscher)! - The encoded `SolanaError` context that is thrown in production is now base64-encoded for compatibility with more terminal shells\n\n- [#2398](https://github.com/solana-labs/solana-web3.js/pull/2398) [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `getUnionCodec` helper that can be used to encode/decode any TypeScript union.\n\n    ```ts\n    const codec: Codec<number | boolean> = getUnionCodec(\n        [getU16Codec(), getBooleanCodec()],\n        value => (typeof value === 'number' ? 0 : 1),\n        (bytes, offset) => (bytes.slice(offset).length > 1 ? 0 : 1),\n    );\n\n    codec.encode(42); // 0x2a00\n    codec.encode(true); // 0x01\n    ```\n\n- [#2382](https://github.com/solana-labs/solana-web3.js/pull/2382) [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `getDataEnumCodec` is now called `getDiscriminatedUnionCodec`\n\n- [#2394](https://github.com/solana-labs/solana-web3.js/pull/2394) [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added a new `getLiteralUnionCodec`\n\n    ```ts\n    const codec = getLiteralUnionCodec(['left', 'right', 'up', 'down']);\n    // ^? FixedSizeCodec<\"left\" | \"right\" | \"up\" | \"down\">\n\n    const bytes = codec.encode('left'); // 0x00\n    const value = codec.decode(bytes); // 'left'\n    ```\n\n- [#2410](https://github.com/solana-labs/solana-web3.js/pull/2410) [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `getZeroableNullableCodec` and `getZeroableOptionCodec` functions\n\n    These functions rely on a zero value to represent `None` or `null` values as opposed to using a boolean prefix.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec());\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0x0000\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.encode(new Uint8Array([0, 0])); // null\n    ```\n\n    Both functions can also be provided with a custom definition of the zero value using the `zeroValue` option.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec(), {\n        zeroValue: new Uint8Array([255, 255]),\n    });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0xfffff\n    codec.encode(new Uint8Array([0, 0])); // 0\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([255, 255])); // null\n    ```\n\n- [#2329](https://github.com/solana-labs/solana-web3.js/pull/2329) [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8) Thanks [@luu-alex](https://github.com/luu-alex)! - `createKeyPairFromBytes()` now validates that the public key imported is the one that would be derived from the private key imported\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n"
  },
  {
    "path": "packages/errors/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/errors/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/errors?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/errors?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/errors\n\n# @solana/errors\n\nThis package brings together every error message across all Solana JavaScript modules.\n\n## Reading error messages\n\n### In development mode\n\nWhen your bundler sets the constant `__DEV__` to `true`, every error message will be included in the bundle. As such, you will be able to read them in plain language wherever they appear.\n\n> [!WARNING]\n> The size of your JavaScript bundle will increase significantly with the inclusion of every error message in development mode. Be sure to build your bundle with `__DEV__` set to `false` when you go to production.\n\n### In production mode\n\nWhen your bundler sets the constant `__DEV__` to `false`, error messages will be stripped from the bundle to save space. Only the error code will appear when an error is encountered. Follow the instructions in the error message to convert the error code back to the human-readable error message.\n\nFor instance, to recover the error text for the error with code `123`:\n\n```shell\nnpx @solana/errors decode -- 123\n```\n\n## Adding a new error\n\n1. Add a new exported error code constant to `src/codes.ts`.\n2. Add that new constant to the `SolanaErrorCode` union in `src/codes.ts`.\n3. If you would like the new error to encapsulate context about the error itself (eg. the public keys for which a transaction is missing signatures) define the shape of that context in `src/context.ts`.\n4. Add the error's message to `src/messages.ts`. Any context values that you defined above will be interpolated into the message wherever you write `$key`, where `key` is the index of a value in the context (eg. ``'Missing a signature for account `$address`'``).\n5. Publish a new version of `@solana/errors`.\n6. Bump the version of `@solana/errors` in the package from which the error is thrown.\n\n## Removing an error message\n\n- Don't remove errors.\n- Don't change the meaning of an error message.\n- Don't change or reorder error codes.\n- Don't change or remove members of an error's context.\n\nWhen an older client throws an error, we want to make sure that they can always decode the error. If you make any of the changes above, old clients will, by definition, not have received your changes. This could make the errors that they throw impossible to decode going forward.\n\n## Catching errors\n\nWhen you catch a `SolanaError` and assert its error code using `isSolanaError()`, TypeScript will refine the error's context to the type associated with that error code. You can use that context to render useful error messages, or to make context-aware decisions that help your application to recover from the error.\n\n```ts\nimport {\n    SOLANA_ERROR__TRANSACTION__MISSING_SIGNATURE,\n    SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n    isSolanaError,\n} from '@solana/errors';\nimport { assertIsFullySignedTransaction, getSignatureFromTransaction } from '@solana/transactions';\n\ntry {\n    const transactionSignature = getSignatureFromTransaction(tx);\n    assertIsFullySignedTransaction(tx);\n    /* ... */\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n        displayError(\n            \"We can't send this transaction without signatures for these addresses:\\n- %s\",\n            // The type of the `context` object is now refined to contain `addresses`.\n            e.context.addresses.join('\\n- '),\n        );\n        return;\n    } else if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING)) {\n        if (!tx.feePayer) {\n            displayError('Choose a fee payer for this transaction before sending it');\n        } else {\n            displayError('The fee payer still needs to sign for this transaction');\n        }\n        return;\n    }\n    throw e;\n}\n```\n"
  },
  {
    "path": "packages/errors/bin/cli.mjs",
    "content": "#!/usr/bin/env -S node\n\nimport process from 'node:process';\n\nimport { run } from '../dist/cli.mjs';\n\nrun(process.argv);\n"
  },
  {
    "path": "packages/errors/package.json",
    "content": "{\n    \"name\": \"@solana/errors\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Throw, identify, and decode Solana JavaScript errors\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaerrors\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"bin\": \"./bin/cli.mjs\",\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts && tsup src/cli.ts --define.__NODEJS__ true --format esm --treeshake\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"chalk\": \"5.6.2\",\n        \"commander\": \"14.0.3\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/errors/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/errors/src/__tests__/RPC_INTEGER_OVERFLOW-test.ts",
    "content": "import { SOLANA_ERROR__RPC__INTEGER_OVERFLOW } from '../codes';\nimport { SolanaError } from '../error';\n\ndescribe('SOLANA_ERROR__RPC__INTEGER_OVERFLOW', () => {\n    beforeEach(() => {\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        (globalThis as any).__DEV__ = true;\n    });\n    it('features an informative error message for a path-less violation', () => {\n        expect(\n            new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n                argumentLabel: '3rd',\n                keyPath: [2 /* third argument */],\n                methodName: 'someMethod',\n                optionalPathLabel: '',\n                value: 1n,\n            }),\n        ).toHaveProperty(\n            'message',\n            'The 3rd argument to the `someMethod` RPC method was `1`. This number is unsafe for use with the Solana JSON-RPC because it exceeds `Number.MAX_SAFE_INTEGER`.',\n        );\n    });\n    it('features an informative error message for a violation with a deep path', () => {\n        expect(\n            new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n                argumentLabel: '1st',\n                keyPath: [0 /* first argument */, 'foo', 'bar'],\n                methodName: 'someMethod',\n                optionalPathLabel: ' at path `foo.bar`',\n                path: 'foo.bar',\n                value: 1n,\n            }),\n        ).toHaveProperty(\n            'message',\n            'The 1st argument to the `someMethod` RPC method at path `foo.bar` was `1`. This number is unsafe for use with the Solana JSON-RPC because it exceeds `Number.MAX_SAFE_INTEGER`.',\n        );\n    });\n});\n"
  },
  {
    "path": "packages/errors/src/__tests__/context-test.ts",
    "content": "import { decodeEncodedContext, encodeContextObject } from '../context';\n\nasync function getTestContext() {\n    return {\n        a: 1n,\n        b: '\"bar\"',\n        c: \"'baz'\",\n        d: '!=$&ymbo;s\\\\',\n        e: [1, [\"'2a'\", '\"2b\"', '2c'], 3],\n        f: Symbol('hi'),\n        g: { foo: 'bar' },\n        h: new URL('http://anza.xyz'),\n        i: (await crypto.subtle.generateKey('Ed25519', false /* extractable */, ['sign', 'verify'])).privateKey,\n        j: Object.create(null),\n        k: null,\n        l: undefined,\n        m: \"'\",\n        n: \"\\\\'\",\n        o: \"\\\\\\\\'\",\n        p: '🚀',\n        q: 'حب',\n        r: 'प्यार',\n        s: '爱',\n    } as const;\n}\nconst EXPECTED_URL_ENCODED_CONTEXT =\n    'a=1n&' +\n    'b=%22bar%22&' +\n    \"c='baz'&\" +\n    'd=!%3D%24%26ymbo%3Bs%5C&' +\n    \"e=%5B1%2C%20%5B'2a'%2C%20%222b%22%2C%202c%5D%2C%203%5D&\" +\n    'f=Symbol(hi)&' +\n    'g=%5Bobject%20Object%5D&' +\n    'h=http%3A%2F%2Fanza.xyz%2F&' +\n    'i=%5Bobject%20CryptoKey%5D&' +\n    'j=%5Bobject%20Object%5D&' +\n    'k=null&' +\n    'l=undefined&' +\n    \"m='&\" +\n    \"n=%5C'&\" +\n    \"o=%5C%5C'&\" +\n    'p=%F0%9F%9A%80&' +\n    'q=%D8%AD%D8%A8&' +\n    'r=%E0%A4%AA%E0%A5%8D%E0%A4%AF%E0%A4%BE%E0%A4%B0&' +\n    's=%E7%88%B1';\n\ndescribe('decodeEncodedContext', () => {\n    it('produces the expected context object from a URL-encoded search string', () => {\n        const encodedContext = btoa(EXPECTED_URL_ENCODED_CONTEXT);\n        expect(decodeEncodedContext(encodedContext)).toStrictEqual({\n            a: '1n',\n            b: '\"bar\"',\n            c: \"'baz'\",\n            d: '!=$&ymbo;s\\\\',\n            e: '[1, [\\'2a\\', \"2b\", 2c], 3]',\n            f: 'Symbol(hi)',\n            g: '[object Object]',\n            h: 'http://anza.xyz/',\n            i: '[object CryptoKey]',\n            j: '[object Object]',\n            k: 'null',\n            l: 'undefined',\n            m: \"'\",\n            n: \"\\\\'\",\n            o: \"\\\\\\\\'\",\n            p: '🚀',\n            q: 'حب',\n            r: 'प्यार',\n            s: '爱',\n        });\n    });\n});\n\ndescribe('encodeContextObject', () => {\n    let context: object;\n    beforeEach(async () => {\n        context = await getTestContext();\n    });\n    it('produces a string with no single quotes in it', () => {\n        const encodedContext = encodeContextObject(context);\n        expect(encodedContext).not.toContain(\"'\");\n    });\n    it('produces encoded context that base64 decodes to the expected URL-encoded search string', () => {\n        const encodedContext = encodeContextObject(context);\n        expect(atob(encodedContext)).toBe(EXPECTED_URL_ENCODED_CONTEXT);\n    });\n    it('does not encode non-enumerable properties', () => {\n        const context = { a: 1, c: 3 };\n        Object.defineProperty(context, 'b', { enumerable: false, value: 2 });\n\n        const encodedContext = encodeContextObject(context);\n        expect(atob(encodedContext)).toBe('a=1&c=3');\n    });\n});\n"
  },
  {
    "path": "packages/errors/src/__tests__/error-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { isSolanaError, SolanaError } from '../error';\nimport { getErrorMessage } from '../message-formatter';\n\njest.mock('../message-formatter');\n\ndescribe('SolanaError', () => {\n    describe('given an error with context', () => {\n        let errorWithContext: SolanaError;\n        beforeEach(() => {\n            errorWithContext = new SolanaError(\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n                { foo: 'bar' },\n            );\n        });\n        it('exposes its error code', () => {\n            expect(errorWithContext.context).toHaveProperty('__code', 123);\n        });\n        it('exposes its context', () => {\n            expect(errorWithContext.context).toHaveProperty('foo', 'bar');\n        });\n        it('exposes no cause', () => {\n            expect(errorWithContext.cause).toBeUndefined();\n        });\n        it('calls the message formatter with the code and context', () => {\n            expect(getErrorMessage).toHaveBeenCalledWith(123, expect.objectContaining({ foo: 'bar' }));\n        });\n        it('freezes the context object', () => {\n            expect(errorWithContext.context).toBeFrozenObject();\n        });\n    });\n    describe('given an error with no context', () => {\n        beforeEach(() => {\n            new SolanaError(\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n                undefined,\n            );\n        });\n        it('calls the message formatter with undefined context', () => {\n            expect(getErrorMessage).toHaveBeenCalledWith(123, undefined);\n        });\n    });\n    describe('given an error with a cause', () => {\n        let errorWithCause: SolanaError;\n        let cause: unknown;\n        beforeEach(() => {\n            cause = {};\n            errorWithCause = new SolanaError(\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n                { cause },\n            );\n        });\n        it('exposes its cause', () => {\n            expect(errorWithCause.cause).toBe(cause);\n        });\n    });\n    describe.each(['cause'])('given an error with only the `%s` property from `ErrorOptions` present', propName => {\n        let errorOptionValue: unknown;\n        let errorWithOption: SolanaError;\n        beforeEach(() => {\n            errorOptionValue = Symbol();\n            errorWithOption = new SolanaError(\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n                { [propName]: errorOptionValue },\n            );\n        });\n        it('omits the error option from its context', () => {\n            expect(errorWithOption.context).not.toHaveProperty(propName);\n        });\n        it('calls the message formatter with the error option omitted', () => {\n            expect(getErrorMessage).toHaveBeenCalledWith(123, undefined);\n        });\n    });\n    it('sets its message to the output of the message formatter', async () => {\n        expect.assertions(1);\n        jest.mocked(getErrorMessage).mockReturnValue('o no');\n        await jest.isolateModulesAsync(async () => {\n            const SolanaErrorModule =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                await import('../error');\n            // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n            const error456 = new SolanaErrorModule.SolanaError(456);\n            expect(error456).toHaveProperty('message', 'o no');\n        });\n    });\n});\n\ndescribe('isSolanaError()', () => {\n    let error123: SolanaError;\n    beforeEach(() => {\n        // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n        error123 = new SolanaError(123);\n    });\n    it('returns `true` for an instance of `SolanaError`', () => {\n        expect(isSolanaError(error123)).toBe(true);\n    });\n    it('returns `false` for an instance of `Error`', () => {\n        expect(isSolanaError(new Error('bad thing'))).toBe(false);\n    });\n    it('returns `true` when the error code matches', () => {\n        expect(\n            isSolanaError(\n                error123,\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n            ),\n        ).toBe(true);\n    });\n    it('returns `false` when the error code does not match', () => {\n        expect(\n            isSolanaError(\n                error123,\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                456,\n            ),\n        ).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/errors/src/__tests__/instruction-error-test.ts",
    "content": "import {\n    SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR,\n    SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN,\n    SolanaErrorCode,\n} from '../codes';\nimport { SolanaError } from '../error';\nimport { getSolanaErrorFromInstructionError } from '../instruction-error';\n\nconst EXPECTED_ERROR_CODES = [\n    ['GenericError', 4615001],\n    ['InvalidArgument', 4615002],\n    ['InvalidInstructionData', 4615003],\n    ['InvalidAccountData', 4615004],\n    ['AccountDataTooSmall', 4615005],\n    ['InsufficientFunds', 4615006],\n    ['IncorrectProgramId', 4615007],\n    ['MissingRequiredSignature', 4615008],\n    ['AccountAlreadyInitialized', 4615009],\n    ['UninitializedAccount', 4615010],\n    ['UnbalancedInstruction', 4615011],\n    ['ModifiedProgramId', 4615012],\n    ['ExternalAccountLamportSpend', 4615013],\n    ['ExternalAccountDataModified', 4615014],\n    ['ReadonlyLamportChange', 4615015],\n    ['ReadonlyDataModified', 4615016],\n    ['DuplicateAccountIndex', 4615017],\n    ['ExecutableModified', 4615018],\n    ['RentEpochModified', 4615019],\n    ['NotEnoughAccountKeys', 4615020],\n    ['AccountDataSizeChanged', 4615021],\n    ['AccountNotExecutable', 4615022],\n    ['AccountBorrowFailed', 4615023],\n    ['AccountBorrowOutstanding', 4615024],\n    ['DuplicateAccountOutOfSync', 4615025],\n    ['InvalidError', 4615027],\n    ['ExecutableDataModified', 4615028],\n    ['ExecutableLamportChange', 4615029],\n    ['ExecutableAccountNotRentExempt', 4615030],\n    ['UnsupportedProgramId', 4615031],\n    ['CallDepth', 4615032],\n    ['MissingAccount', 4615033],\n    ['ReentrancyNotAllowed', 4615034],\n    ['MaxSeedLengthExceeded', 4615035],\n    ['InvalidSeeds', 4615036],\n    ['InvalidRealloc', 4615037],\n    ['ComputationalBudgetExceeded', 4615038],\n    ['PrivilegeEscalation', 4615039],\n    ['ProgramEnvironmentSetupFailure', 4615040],\n    ['ProgramFailedToComplete', 4615041],\n    ['ProgramFailedToCompile', 4615042],\n    ['Immutable', 4615043],\n    ['IncorrectAuthority', 4615044],\n    ['BorshIoError', 4615045],\n    ['AccountNotRentExempt', 4615046],\n    ['InvalidAccountOwner', 4615047],\n    ['ArithmeticOverflow', 4615048],\n    ['UnsupportedSysvar', 4615049],\n    ['IllegalOwner', 4615050],\n    ['MaxAccountsDataAllocationsExceeded', 4615051],\n    ['MaxAccountsExceeded', 4615052],\n    ['MaxInstructionTraceLengthExceeded', 4615053],\n    ['BuiltinProgramsMustConsumeComputeUnits', 4615054],\n] as const;\n\ndescribe('getSolanaErrorFromInstructionError', () => {\n    it.each(EXPECTED_ERROR_CODES)(\n        'produces the correct `SolanaError` for a `%s` error',\n        (transactionError, expectedCode) => {\n            const error = getSolanaErrorFromInstructionError(123, transactionError);\n            expect(error).toEqual(new SolanaError(expectedCode as SolanaErrorCode, { index: 123 }));\n        },\n    );\n    it.each(EXPECTED_ERROR_CODES)(\n        'produces the correct `SolanaError` for a `%s` error with a bigint index',\n        (transactionError, expectedCode) => {\n            const error = getSolanaErrorFromInstructionError(123n, transactionError);\n            expect(error).toEqual(new SolanaError(expectedCode as SolanaErrorCode, { index: 123 }));\n        },\n    );\n    it('produces the correct `SolanaError` for a `Custom` error', () => {\n        const error = getSolanaErrorFromInstructionError(123, { Custom: 789 });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, {\n                code: 789,\n                index: 123,\n            }),\n        );\n    });\n    it('produces the correct `SolanaError` for a `Custom` error with a bigint code', () => {\n        const error = getSolanaErrorFromInstructionError(123, { Custom: 789n });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, {\n                code: 789,\n                index: 123,\n            }),\n        );\n    });\n    it('produces the correct `SolanaError` for a `BorshIoError` error (pre SDK 3.0 newtype style)', () => {\n        const error = getSolanaErrorFromInstructionError(123, { BorshIoError: 'abc' });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR, {\n                index: 123,\n            }),\n        );\n    });\n    it(\"returns the unknown error when encountering an enum name that's missing from the map\", () => {\n        const error = getSolanaErrorFromInstructionError(123, 'ThisDoesNotExist');\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN, {\n                errorName: 'ThisDoesNotExist',\n                index: 123,\n            }),\n        );\n    });\n    it(\"returns the unknown error when encountering an enum struct that's missing from the map\", () => {\n        const expectedContext = {} as const;\n        const error = getSolanaErrorFromInstructionError(123, { ThisDoesNotExist: expectedContext });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN, {\n                errorName: 'ThisDoesNotExist',\n                index: 123,\n                instructionErrorContext: expectedContext,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/errors/src/__tests__/json-rpc-error-test.ts",
    "content": "import {\n    SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR,\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__INVALID_REQUEST,\n    SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND,\n    SOLANA_ERROR__JSON_RPC__PARSE_ERROR,\n    SOLANA_ERROR__JSON_RPC__SCAN_ERROR,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NO_SNAPSHOT,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_LEN_MISMATCH,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION,\n    SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR,\n    SolanaErrorCode,\n} from '../codes';\nimport { SolanaErrorContext } from '../context';\nimport { SolanaError } from '../error';\nimport { getSolanaErrorFromJsonRpcError } from '../json-rpc-error';\nimport { getSolanaErrorFromTransactionError } from '../transaction-error';\n\njest.mock('../transaction-error.ts');\n\ndescribe('getSolanaErrorFromJsonRpcError', () => {\n    it('produces a `SolanaError` with the same code as the one given', () => {\n        const code = 123 as SolanaErrorCode;\n        const error = getSolanaErrorFromJsonRpcError({ code, message: 'o no' });\n        expect(error).toHaveProperty('context.__code', 123);\n    });\n    it('converts bigint codes to numbers', () => {\n        const code = 123n;\n        const error = getSolanaErrorFromJsonRpcError({ code, message: 'o no' });\n        expect(error).toHaveProperty('context.__code', 123);\n    });\n    it('produces a `SOLANA_ERROR__UNRECOGNIZED_JSON_RPC_ERROR` when no code is given', () => {\n        const error = getSolanaErrorFromJsonRpcError({ foo: 'bar', message: 'o no' });\n        expect(error).toHaveProperty('context.__code', SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR);\n        expect(error).toHaveProperty('context.error', { foo: 'bar', message: 'o no' });\n        expect(error).toHaveProperty('context.message', 'o no');\n    });\n    it('produces a `SOLANA_ERROR__UNRECOGNIZED_JSON_RPC_ERROR` with a fallback message when none is provided', () => {\n        const error = getSolanaErrorFromJsonRpcError(null);\n        expect(error).toHaveProperty('context.__code', SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR);\n        expect(error).toHaveProperty('context.error', null);\n        expect(error).toHaveProperty('context.message', 'Malformed JSON-RPC error with no message attribute');\n    });\n    describe.each([\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY,\n    ])('given a %s JSON-RPC error known to have data', jsonRpcErrorCode => {\n        const expectedData = { baz: 'bat', foo: 'bar' } as unknown as SolanaErrorContext[SolanaErrorCode];\n        it('does not set the server message on context', () => {\n            const error = getSolanaErrorFromJsonRpcError({\n                code: jsonRpcErrorCode,\n                data: expectedData,\n                message: 'o no',\n            });\n            expect(error).not.toHaveProperty('context.__serverMessage');\n        });\n        it('produces a `SolanaError` with that data as context', () => {\n            const error = getSolanaErrorFromJsonRpcError({\n                code: jsonRpcErrorCode,\n                data: expectedData,\n                message: 'o no',\n            });\n            expect(error).toHaveProperty('context', expect.objectContaining(expectedData));\n        });\n    });\n    describe.each([\n        SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR,\n        SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n        SOLANA_ERROR__JSON_RPC__INVALID_REQUEST,\n        SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND,\n        SOLANA_ERROR__JSON_RPC__PARSE_ERROR,\n        SOLANA_ERROR__JSON_RPC__SCAN_ERROR,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION,\n    ])(\n        'given a %s JSON-RPC error known to have no data but important context in the server message',\n        jsonRpcErrorCode => {\n            it('produces a `SolanaError` with the server message on the context', () => {\n                const error = getSolanaErrorFromJsonRpcError({ code: jsonRpcErrorCode, message: 'o no' });\n                expect(error).toHaveProperty('context.__serverMessage', 'o no');\n            });\n        },\n    );\n    describe.each([\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NO_SNAPSHOT,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_LEN_MISMATCH,\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE,\n    ])(\n        'given a %s JSON-RPC error known to have neither data nor important context in the server message',\n        jsonRpcErrorCode => {\n            it('produces a `SolanaError` without the server message on the context', () => {\n                const error = getSolanaErrorFromJsonRpcError({ code: jsonRpcErrorCode, message: 'o no' });\n                expect(error).not.toHaveProperty('context.__serverMessage', 'o no');\n            });\n        },\n    );\n    describe.each([[1, 2, 3], Symbol('a symbol'), 1, 1n, true, false])('when given non-object data like `%s`', data => {\n        it('does not add the data to `context`', () => {\n            const error = getSolanaErrorFromJsonRpcError({\n                code: 123,\n                data,\n                message: 'o no',\n            });\n            expect(error).toHaveProperty(\n                'context',\n                // Implies exact match; `context` contains nothing but the `__code`\n                { __code: 123 },\n            );\n        });\n    });\n    describe('when passed a preflight failure', () => {\n        it('produces a `SolanaError` with the transaction error as the `cause`', () => {\n            const mockErrorResult = Symbol() as unknown as SolanaError;\n            jest.mocked(getSolanaErrorFromTransactionError).mockReturnValue(mockErrorResult);\n            const error = getSolanaErrorFromJsonRpcError({\n                code: SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n                data: { err: Symbol() },\n                message: 'o no',\n            });\n            expect(error.cause).toBe(mockErrorResult);\n        });\n        it('produces a `SolanaError` with the preflight failure data (minus the `err` property) as the context', () => {\n            const preflightErrorData = { bar: 2, baz: 3, foo: 1 };\n            const error = getSolanaErrorFromJsonRpcError({\n                code: SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n                data: { ...preflightErrorData, err: Symbol() },\n                message: 'o no',\n            });\n            expect(error.context).toEqual({\n                __code: SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n                ...preflightErrorData,\n            });\n        });\n        it('delegates `err` to the transaction error getter', () => {\n            const transactionError = Symbol();\n            getSolanaErrorFromJsonRpcError({\n                code: SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n                data: { err: transactionError },\n                message: 'o no',\n            });\n            expect(getSolanaErrorFromTransactionError).toHaveBeenCalledWith(transactionError);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/errors/src/__tests__/message-formatter-test.ts",
    "content": "import { SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN, SolanaErrorCode } from '../codes';\nimport { encodeContextObject } from '../context';\nimport { getErrorMessage } from '../message-formatter';\nimport * as MessagesModule from '../messages';\n\njest.mock('../context');\njest.mock('../messages', () => ({\n    get SolanaErrorMessages() {\n        return {};\n    },\n    __esModule: true,\n}));\n\ndescribe('getErrorMessage', () => {\n    describe('in production mode', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/no-explicit-any\n            (globalThis as any).__DEV__ = false;\n        });\n        it('renders advice on where to decode a context-less error', () => {\n            const message = getErrorMessage(\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n            );\n            expect(message).toBe('Solana error #123; Decode this error by running `npx @solana/errors decode -- 123`');\n        });\n        it('does not call the context encoder when the error has no context', () => {\n            getErrorMessage(\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n            );\n            expect(encodeContextObject).not.toHaveBeenCalled();\n        });\n        it('does not call the context encoder when the error context has no keys', () => {\n            const context = {};\n            getErrorMessage(\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n                context,\n            );\n            expect(encodeContextObject).not.toHaveBeenCalled();\n        });\n        it('calls the context encoder with the context', () => {\n            const context = { foo: 'bar' };\n            getErrorMessage(\n                // @ts-expect-error Mock error codes don't conform to `SolanaErrorCode`\n                123,\n                context,\n            );\n            expect(encodeContextObject).toHaveBeenCalledWith(context);\n        });\n        it('renders advice on where to decode an error with encoded context', () => {\n            jest.mocked(encodeContextObject).mockReturnValue('ENCODED_CONTEXT');\n            const context = { foo: 'bar' };\n            const message = getErrorMessage(123 as SolanaErrorCode, context);\n            expect(message).toBe(\n                \"Solana error #123; Decode this error by running `npx @solana/errors decode -- 123 'ENCODED_CONTEXT'`\",\n            );\n        });\n        it('renders no encoded context in the decoding advice when the context has no keys', () => {\n            jest.mocked(encodeContextObject).mockReturnValue('ENCODED_CONTEXT');\n            const context = {};\n            const message = getErrorMessage(123 as SolanaErrorCode, context);\n            expect(message).toBe('Solana error #123; Decode this error by running `npx @solana/errors decode -- 123`');\n        });\n    });\n    describe('in dev mode', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/no-explicit-any\n            (globalThis as any).__DEV__ = true;\n        });\n        it('renders static error messages', () => {\n            const messagesSpy = jest.spyOn(MessagesModule, 'SolanaErrorMessages', 'get');\n            messagesSpy.mockReturnValue({\n                // @ts-expect-error Mock error config doesn't conform to exported config.\n                123: 'static error message',\n            });\n            const message = getErrorMessage(\n                // @ts-expect-error Mock error config doesn't conform to exported config.\n                123,\n            );\n            expect(message).toBe('static error message');\n        });\n        it.each([\n            {\n                expected: \"Something awful happened: 'bar'. How awful!\",\n                input: \"Something $severity happened: '$foo'. How $severity!\",\n            },\n            // Literal backslashes, escaped dollar signs\n            {\n                expected: 'How \\\\awful\\\\ is the $severity?',\n                input: 'How \\\\\\\\$severity\\\\\\\\ is the \\\\$severity?',\n            },\n            // Variable at beginning of sequence\n            { expected: 'awful times!', input: '$severity times!' },\n            // Variable at end of sequence\n            { expected: \"Isn't it awful?\", input: \"Isn't it $severity?\" },\n            // Variable in middle of text sequence\n            { expected: '~awful~', input: '~$severity~' },\n            // Variable interpolation with no value in the lookup\n            { expected: 'Is $thing a sandwich?', input: 'Is $thing a sandwich?' },\n            // Variable that has, as a substring, some other value in the lookup\n            { expected: '$fool', input: '$fool' },\n            // Trick for butting a variable up against regular text\n            { expected: 'barl', input: '$foo\\\\l' },\n            // Escaped variable marker\n            { expected: \"It's the $severity, ya hear?\", input: \"It's the \\\\$severity, ya hear?\" },\n            // Single dollar sign\n            { expected: ' $ ', input: ' $ ' },\n            // Single dollar sign at start\n            { expected: '$ ', input: '$ ' },\n            // Single dollar sign at end\n            { expected: ' $', input: ' $' },\n            // Double dollar sign with legitimate variable name\n            { expected: ' $bar ', input: ' $$foo ' },\n            // Double dollar sign with legitimate variable name at start\n            { expected: '$bar ', input: '$$foo ' },\n            // Double dollar sign with legitimate variable name at end\n            { expected: ' $bar', input: ' $$foo' },\n            // Single escape sequence\n            { expected: '  ', input: ' \\\\ ' },\n            // Single escape sequence at start\n            { expected: ' ', input: '\\\\ ' },\n            // Single escape sequence at end\n            { expected: ' ', input: ' \\\\' },\n            // Double escape sequence\n            { expected: ' \\\\ ', input: ' \\\\\\\\ ' },\n            // Double escape sequence at start\n            { expected: '\\\\ ', input: '\\\\\\\\ ' },\n            // Double escape sequence at end\n            { expected: ' \\\\', input: ' \\\\\\\\' },\n            // Just text\n            { expected: 'Some unencumbered text.', input: 'Some unencumbered text.' },\n            // Empty string\n            { expected: '', input: '' },\n        ])('interpolates variables into the error message format string `\"$input\"`', ({ input, expected }) => {\n            const messagesSpy = jest.spyOn(MessagesModule, 'SolanaErrorMessages', 'get');\n            messagesSpy.mockReturnValue({\n                // @ts-expect-error Mock error config doesn't conform to exported config.\n                123: input,\n            });\n            const message = getErrorMessage(\n                // @ts-expect-error Mock error context doesn't conform to exported context.\n                123,\n                { foo: 'bar', severity: 'awful' },\n            );\n            expect(message).toBe(expected);\n        });\n        it('interpolates a Uint8Array variable into a error message format string', () => {\n            const messagesSpy = jest.spyOn(MessagesModule, 'SolanaErrorMessages', 'get');\n            messagesSpy.mockReturnValue({\n                // @ts-expect-error Mock error config doesn't conform to exported config.\n                123: 'Here is some data: $data',\n            });\n            const message = getErrorMessage(\n                // @ts-expect-error Mock error context doesn't conform to exported context.\n                123,\n                { data: new Uint8Array([1, 2, 3, 4]) },\n            );\n            expect(message).toBe('Here is some data: 1,2,3,4');\n        });\n        it('interpolates an undefined variable into a error message format string', () => {\n            const messagesSpy = jest.spyOn(MessagesModule, 'SolanaErrorMessages', 'get');\n            messagesSpy.mockReturnValue({\n                // @ts-expect-error Mock error config doesn't conform to exported config.\n                123: 'Here is a variable: $variable',\n            });\n            const message = getErrorMessage(\n                // @ts-expect-error Mock error context doesn't conform to exported context.\n                123,\n                { variable: undefined },\n            );\n            expect(message).toBe('Here is a variable: undefined');\n        });\n        it('appends the instruction number to instruction error messages', () => {\n            const messagesSpy = jest.spyOn(MessagesModule, 'SolanaErrorMessages', 'get');\n            // @ts-expect-error Mock error config doesn't conform to exported config.\n            messagesSpy.mockReturnValue({\n                [SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN]: 'Some instruction error',\n            });\n            const message = getErrorMessage(SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN, { index: 0 });\n            expect(message).toBe('Some instruction error (instruction #1)');\n        });\n        it('uses one-based instruction numbering', () => {\n            const messagesSpy = jest.spyOn(MessagesModule, 'SolanaErrorMessages', 'get');\n            // @ts-expect-error Mock error config doesn't conform to exported config.\n            messagesSpy.mockReturnValue({\n                [SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN]: 'Some instruction error',\n            });\n            const message = getErrorMessage(SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN, { index: 5 });\n            expect(message).toBe('Some instruction error (instruction #6)');\n        });\n        it('appends the instruction number to error codes at the end of the instruction error range', () => {\n            const lastInstructionErrorCode = SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN + 999;\n            const messagesSpy = jest.spyOn(MessagesModule, 'SolanaErrorMessages', 'get');\n            // @ts-expect-error Mock error config doesn't conform to exported config.\n            messagesSpy.mockReturnValue({\n                [lastInstructionErrorCode]: 'Some instruction error',\n            });\n            const message = getErrorMessage(\n                // @ts-expect-error Mock error code doesn't conform to exported config.\n                lastInstructionErrorCode,\n                { index: 2 },\n            );\n            expect(message).toBe('Some instruction error (instruction #3)');\n        });\n        it('does not append the instruction number to non-instruction error messages', () => {\n            const messagesSpy = jest.spyOn(MessagesModule, 'SolanaErrorMessages', 'get');\n            messagesSpy.mockReturnValue({\n                // @ts-expect-error Mock error config doesn't conform to exported config.\n                123: 'some other error',\n            });\n            const message = getErrorMessage(\n                // @ts-expect-error Mock error context doesn't conform to exported context.\n                123,\n                { index: 0 },\n            );\n            expect(message).toBe('some other error');\n        });\n    });\n});\n"
  },
  {
    "path": "packages/errors/src/__tests__/simulation-errors-test.ts",
    "content": "import {\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE,\n    SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n} from '../codes';\nimport { SolanaError } from '../error';\nimport { RpcSimulateTransactionResult, unwrapSimulationError } from '../index';\n\nconst rpcSimulationError: Omit<RpcSimulateTransactionResult, 'err'> = {\n    accounts: null,\n    fee: null,\n    loadedAccountsDataSize: null,\n    loadedAddresses: { readonly: [], writable: [] },\n    logs: null,\n    postBalances: null,\n    postTokenBalances: null,\n    preBalances: null,\n    preTokenBalances: null,\n    replacementBlockhash: null,\n    returnData: null,\n    unitsConsumed: null,\n};\n\ndescribe('unwrapSimulationError', () => {\n    describe('given a preflight failure error', () => {\n        it('returns the cause of the error', () => {\n            const cause = new Error('underlying error');\n            const error = new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE, {\n                ...rpcSimulationError,\n                cause,\n            });\n            expect(unwrapSimulationError(error)).toBe(cause);\n        });\n    });\n\n    describe('given a preflight failure error without a cause', () => {\n        it('returns the original error unchanged', () => {\n            const error = new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE, {\n                ...rpcSimulationError,\n            });\n            expect(unwrapSimulationError(error)).toBe(error);\n        });\n    });\n\n    describe('given a simulation compute limit estimation failure error', () => {\n        it('returns the cause of the error', () => {\n            const cause = new Error('underlying error');\n            const error = new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT, {\n                ...rpcSimulationError,\n                cause,\n            });\n            expect(unwrapSimulationError(error)).toBe(cause);\n        });\n    });\n\n    describe('given a simulation compute limit estimation failure error without a cause', () => {\n        it('returns the original error unchanged', () => {\n            const error = new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT, {\n                ...rpcSimulationError,\n            });\n            expect(unwrapSimulationError(error)).toBe(error);\n        });\n    });\n\n    describe('given a non-simulation SolanaError', () => {\n        it('returns the original error unchanged', () => {\n            const error = new SolanaError(SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE);\n            expect(unwrapSimulationError(error)).toBe(error);\n        });\n    });\n\n    describe('given a regular Error', () => {\n        it('returns the original error unchanged', () => {\n            const error = new Error('regular error');\n            expect(unwrapSimulationError(error)).toBe(error);\n        });\n    });\n\n    describe('given a non-error value', () => {\n        it('returns the original value unchanged when given a string', () => {\n            const value = 'error string';\n            expect(unwrapSimulationError(value)).toBe(value);\n        });\n\n        it('returns the original value unchanged when given null', () => {\n            expect(unwrapSimulationError(null)).toBeNull();\n        });\n\n        it('returns the original value unchanged when given undefined', () => {\n            expect(unwrapSimulationError(undefined)).toBeUndefined();\n        });\n\n        it('returns the original value unchanged when given an object', () => {\n            const value = { message: 'error' };\n            expect(unwrapSimulationError(value)).toBe(value);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/errors/src/__tests__/transaction-error-test.ts",
    "content": "import {\n    SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT,\n    SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED,\n    SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN,\n    SolanaErrorCode,\n} from '../codes';\nimport { SolanaError } from '../error';\nimport { getSolanaErrorFromInstructionError } from '../instruction-error';\nimport { getSolanaErrorFromTransactionError } from '../transaction-error';\n\njest.mock('../instruction-error.ts');\n\ndescribe('getSolanaErrorFromTransactionError', () => {\n    it.each([\n        ['AccountInUse', 7050001],\n        ['AccountLoadedTwice', 7050002],\n        ['AccountNotFound', 7050003],\n        ['ProgramAccountNotFound', 7050004],\n        ['InsufficientFundsForFee', 7050005],\n        ['InvalidAccountForFee', 7050006],\n        ['AlreadyProcessed', 7050007],\n        ['BlockhashNotFound', 7050008],\n        ['CallChainTooDeep', 7050009],\n        ['MissingSignatureForFee', 7050010],\n        ['InvalidAccountIndex', 7050011],\n        ['SignatureFailure', 7050012],\n        ['InvalidProgramForExecution', 7050013],\n        ['SanitizeFailure', 7050014],\n        ['ClusterMaintenance', 7050015],\n        ['AccountBorrowOutstanding', 7050016],\n        ['WouldExceedMaxBlockCostLimit', 7050017],\n        ['UnsupportedVersion', 7050018],\n        ['InvalidWritableAccount', 7050019],\n        ['WouldExceedMaxAccountCostLimit', 7050020],\n        ['WouldExceedAccountDataBlockLimit', 7050021],\n        ['TooManyAccountLocks', 7050022],\n        ['AddressLookupTableNotFound', 7050023],\n        ['InvalidAddressLookupTableOwner', 7050024],\n        ['InvalidAddressLookupTableData', 7050025],\n        ['InvalidAddressLookupTableIndex', 7050026],\n        ['InvalidRentPayingAccount', 7050027],\n        ['WouldExceedMaxVoteCostLimit', 7050028],\n        ['WouldExceedAccountDataTotalLimit', 7050029],\n        ['MaxLoadedAccountsDataSizeExceeded', 7050032],\n        ['InvalidLoadedAccountsDataSizeLimit', 7050033],\n        ['ResanitizationNeeded', 7050034],\n        ['UnbalancedTransaction', 7050036],\n    ])('produces the correct `SolanaError` for a `%s` error', (transactionError, expectedCode) => {\n        const error = getSolanaErrorFromTransactionError(transactionError);\n        expect(error).toEqual(new SolanaError(expectedCode as SolanaErrorCode, undefined));\n    });\n    it('produces the correct `SolanaError` for a `DuplicateInstruction` error', () => {\n        const error = getSolanaErrorFromTransactionError({ DuplicateInstruction: 1 });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION, {\n                index: 1,\n            }),\n        );\n    });\n    it('produces the correct `SolanaError` for a `DuplicateInstruction` error with a bigint index', () => {\n        const error = getSolanaErrorFromTransactionError({ DuplicateInstruction: 1n });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION, {\n                index: 1,\n            }),\n        );\n    });\n    it('produces the correct `SolanaError` for a `InsufficientFundsForRent` error', () => {\n        const error = getSolanaErrorFromTransactionError({ InsufficientFundsForRent: { account_index: 1 } });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT, {\n                accountIndex: 1,\n            }),\n        );\n    });\n    it('produces the correct `SolanaError` for a `InsufficientFundsForRent` error with a bigint index', () => {\n        const error = getSolanaErrorFromTransactionError({ InsufficientFundsForRent: { account_index: 1n } });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT, {\n                accountIndex: 1,\n            }),\n        );\n    });\n    it('produces the correct `SolanaError` for a `ProgramExecutionTemporarilyRestricted` error', () => {\n        const error = getSolanaErrorFromTransactionError({\n            ProgramExecutionTemporarilyRestricted: { account_index: 1 },\n        });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED, {\n                accountIndex: 1,\n            }),\n        );\n    });\n    it('produces the correct `SolanaError` for a `ProgramExecutionTemporarilyRestricted` error with a bigint index', () => {\n        const error = getSolanaErrorFromTransactionError({\n            ProgramExecutionTemporarilyRestricted: { account_index: 1n },\n        });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED, {\n                accountIndex: 1,\n            }),\n        );\n    });\n    it(\"returns the unknown error when encountering an enum name that's missing from the map\", () => {\n        const error = getSolanaErrorFromTransactionError('ThisDoesNotExist');\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN, {\n                errorName: 'ThisDoesNotExist',\n            }),\n        );\n    });\n    it(\"returns the unknown error when encountering an enum struct that's missing from the map\", () => {\n        const expectedContext = {} as const;\n        const error = getSolanaErrorFromTransactionError({ ThisDoesNotExist: expectedContext });\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN, {\n                errorName: 'ThisDoesNotExist',\n                transactionErrorContext: expectedContext,\n            }),\n        );\n    });\n    it('delegates `InstructionError` to the instruction error getter', () => {\n        const instructionError = Symbol();\n        const mockErrorResult = Symbol() as unknown as SolanaError;\n        jest.mocked(getSolanaErrorFromInstructionError).mockReturnValue(mockErrorResult);\n        const error = getSolanaErrorFromTransactionError({ InstructionError: [123, instructionError] });\n        expect(getSolanaErrorFromInstructionError).toHaveBeenCalledWith(123, instructionError);\n        expect(error).toBe(mockErrorResult);\n    });\n});\n"
  },
  {
    "path": "packages/errors/src/__typetests__/error-typetest.ts",
    "content": "import * as SolanaErrorCodeModule from '../codes';\nimport { SolanaErrorCode, SolanaErrorCodeWithCause } from '../codes';\nimport { SolanaErrorContext } from '../context';\nimport { isSolanaError, SolanaError, SolanaErrorWithDeprecatedCause } from '../error';\n\nconst { SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING } =\n    SolanaErrorCodeModule;\n\n// If this line raises a type error, you might have forgotten to add a new error to the\n// `SolanaErrorCode` union in `src/codes.ts`.\nObject.values(SolanaErrorCodeModule) satisfies SolanaErrorCode[];\n\nconst transactionMissingSignaturesError = new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n    addresses: ['123', '456'],\n});\n\n{\n    const code = transactionMissingSignaturesError.context.__code;\n    code satisfies typeof SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING;\n    // @ts-expect-error Wrong error code.\n    code satisfies typeof SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING;\n}\n\ntransactionMissingSignaturesError.context satisfies SolanaErrorContext[typeof SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING];\n// @ts-expect-error Non existent context property.\nvoid transactionMissingSignaturesError.context.feePayer;\n\nnew SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING);\n// @ts-expect-error Missing context property (`addresses`)\nnew SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING);\n\nconst unknownError = null as unknown as SolanaError;\nif (unknownError.context.__code === SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING) {\n    unknownError.context satisfies SolanaErrorContext[typeof SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING];\n    // @ts-expect-error Context belongs to another error code\n    unknownError.context satisfies SolanaErrorContext[typeof SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING];\n}\n\nconst e = null as unknown;\nif (isSolanaError(e)) {\n    e.context satisfies Readonly<{ __code: SolanaErrorCode }>;\n    // @ts-expect-error Code is read-only\n    e.context.__code = SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING;\n}\nif (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n    e.context satisfies SolanaErrorContext[typeof SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING];\n    // @ts-expect-error Context belongs to another error code\n    e.context satisfies SolanaErrorContext[typeof SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING];\n    // @ts-expect-error Context is read-only\n    e.context.addresses = [] as unknown as typeof e.context.addresses;\n    // @ts-expect-error Objects in context are read-only\n    e.context.addresses.push('abc' as unknown as (typeof e.context.addresses)[number]);\n}\n\n// `SolanaErrorContext` must not contain any keys reserved by `ErrorOptions` (eg. `cause`)\nnull as unknown as SolanaErrorContext satisfies {\n    [Code in keyof SolanaErrorContext]: SolanaErrorContext[Code] extends undefined\n        ? undefined\n        : {\n              [PP in keyof SolanaErrorContext[Code]]: PP extends keyof ErrorOptions\n                  ? never\n                  : SolanaErrorContext[Code][PP];\n          };\n};\n\n// Special errors have a nested `cause` property that is an optional `SolanaError`\nconst errorWithCause = null as unknown as SolanaError<SolanaErrorCodeWithCause>;\nerrorWithCause.cause satisfies SolanaError | undefined;\n\n// Errors that have a deprecated `cause` property should satisfy `SolanaErrorWithDeprecatedCause`\n// when narrowed with `isSolanaError`\n{\n    const e = null as unknown;\n    if (isSolanaError(e)) {\n        // @ts-expect-error Not all SolanaErrors have deprecated cause\n        e satisfies SolanaErrorWithDeprecatedCause;\n    }\n    // This one does\n    if (isSolanaError(e, SolanaErrorCodeModule.SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN)) {\n        e satisfies SolanaErrorWithDeprecatedCause;\n        // context still works\n        e.context.transactionPlanResult satisfies unknown;\n    }\n}\n"
  },
  {
    "path": "packages/errors/src/cli.ts",
    "content": "import chalk from 'chalk';\nimport { Command, InvalidArgumentError } from 'commander';\n\nimport { version } from '../package.json';\nimport { SolanaErrorCode } from './codes';\nimport { decodeEncodedContext } from './context';\nimport { getHumanReadableErrorMessage } from './message-formatter';\nimport { SolanaErrorMessages } from './messages';\n\nconst program = new Command();\n\nprogram.name('@solana/errors').description('Decode Solana JavaScript errors thrown in production').version(version);\n\nprogram\n    .command('decode')\n    .description('Decode a `SolanaErrorCode` to a human-readable message')\n    .argument('<code>', 'numeric error code to decode', rawCode => {\n        const code = parseInt(rawCode, 10);\n        if (isNaN(code) || `${code}` !== rawCode) {\n            throw new InvalidArgumentError('It must be an integer');\n        }\n        if (!(code in SolanaErrorMessages)) {\n            throw new InvalidArgumentError('There exists no error with that code');\n        }\n        return code;\n    })\n    .argument('[encodedContext]', 'encoded context to interpolate into the error message', encodedContext => {\n        try {\n            return decodeEncodedContext(encodedContext);\n        } catch {\n            throw new InvalidArgumentError('Encoded context malformed');\n        }\n    })\n    .action((code: number, context: object) => {\n        const message = getHumanReadableErrorMessage(code as SolanaErrorCode, context);\n        console.log(`\n${\n    chalk.bold(\n        chalk.rgb(154, 71, 255)('[') +\n            chalk.rgb(144, 108, 244)('D') +\n            chalk.rgb(134, 135, 233)('e') +\n            chalk.rgb(122, 158, 221)('c') +\n            chalk.rgb(110, 178, 209)('o') +\n            chalk.rgb(95, 195, 196)('d') +\n            chalk.rgb(79, 212, 181)('e') +\n            chalk.rgb(57, 227, 166)('d') +\n            chalk.rgb(19, 241, 149)(']'),\n    ) + chalk.rgb(19, 241, 149)(' Solana error code #' + code)\n}\n    - ${message}`);\n        if (context) {\n            console.log(`\n${chalk.yellowBright(chalk.bold('[Context]'))}\n    ${JSON.stringify(context, null, 4).split('\\n').join('\\n    ')}`);\n        }\n    });\n\nexport function run(argv: readonly string[]) {\n    program.parse(argv);\n}\n"
  },
  {
    "path": "packages/errors/src/codes.ts",
    "content": "/**\n * To add a new error, follow the instructions at\n * https://github.com/anza-xyz/kit/tree/main/packages/errors/#adding-a-new-error\n *\n * @module\n * @privateRemarks\n * WARNING:\n *   - Don't remove error codes\n *   - Don't change or reorder error codes.\n *\n * Good naming conventions:\n *   - Prefixing common errors — e.g. under the same package — can be a good way to namespace them. E.g. All codec-related errors start with `SOLANA_ERROR__CODECS__`.\n *   - Use consistent names — e.g. choose `PDA` or `PROGRAM_DERIVED_ADDRESS` and stick with it. Ensure your names are consistent with existing error codes. The decision might have been made for you.\n *   - Recommended prefixes and suffixes:\n *     - `MALFORMED_`: Some input was not constructed properly. E.g. `MALFORMED_BASE58_ENCODED_ADDRESS`.\n *     - `INVALID_`: Some input is invalid (other than because it was MALFORMED). E.g. `INVALID_NUMBER_OF_BYTES`.\n *     - `EXPECTED_`: Some input was different than expected, no need to specify the \"GOT\" part unless necessary. E.g. `EXPECTED_DECODED_ACCOUNT`.\n *     - `_CANNOT_`: Some operation cannot be performed or some input cannot be used due to some condition. E.g. `CANNOT_DECODE_EMPTY_BYTE_ARRAY` or `PDA_CANNOT_END_WITH_PDA_MARKER`.\n *     - `_MUST_BE_`: Some condition must be true. E.g. `NONCE_TRANSACTION_FIRST_INSTRUCTION_MUST_BE_ADVANCE_NONCE`.\n *     - `_FAILED_TO_`: Tried to perform some operation and failed. E.g. `FAILED_TO_DECODE_ACCOUNT`.\n *     - `_NOT_FOUND`: Some operation lead to not finding something. E.g. `ACCOUNT_NOT_FOUND`.\n *     - `_OUT_OF_RANGE`: Some value is out of range. E.g. `ENUM_DISCRIMINATOR_OUT_OF_RANGE`.\n *     - `_EXCEEDED`: Some limit was exceeded. E.g. `PDA_MAX_SEED_LENGTH_EXCEEDED`.\n *     - `_MISMATCH`: Some elements do not match. E.g. `ENCODER_DECODER_FIXED_SIZE_MISMATCH`.\n *     - `_MISSING`: Some required input is missing. E.g. `TRANSACTION_FEE_PAYER_MISSING`.\n *     - `_UNIMPLEMENTED`: Some required component is not available in the environment. E.g. `SUBTLE_CRYPTO_VERIFY_FUNCTION_UNIMPLEMENTED`.\n */\nexport const SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED = 1;\nexport const SOLANA_ERROR__INVALID_NONCE = 2;\nexport const SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND = 3;\nexport const SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE = 4;\nexport const SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH = 5;\nexport const SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE = 6;\nexport const SOLANA_ERROR__MALFORMED_BIGINT_STRING = 7;\nexport const SOLANA_ERROR__MALFORMED_NUMBER_STRING = 8;\nexport const SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE = 9;\nexport const SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR = 10;\nexport const SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION = 11;\nexport const SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS = 12;\n\n// JSON-RPC-related errors.\n// Reserve error codes in the range [-32768, -32000]\n// Keep in sync with https://github.com/anza-xyz/agave/blob/master/rpc-client-api/src/custom_error.rs\nexport const SOLANA_ERROR__JSON_RPC__PARSE_ERROR = -32700;\nexport const SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR = -32603;\nexport const SOLANA_ERROR__JSON_RPC__INVALID_PARAMS = -32602;\nexport const SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND = -32601;\nexport const SOLANA_ERROR__JSON_RPC__INVALID_REQUEST = -32600;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE = -32019;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY = -32018;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE = -32017;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED = -32016;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION = -32015;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET = -32014;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_LEN_MISMATCH = -32013;\nexport const SOLANA_ERROR__JSON_RPC__SCAN_ERROR = -32012;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE = -32011;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX = -32010;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED = -32009;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NO_SNAPSHOT = -32008;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED = -32007;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE = -32006;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY = -32005;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE = -32004;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE = -32003;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE = -32002;\nexport const SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP = -32001;\n\n// Addresses-related errors.\n// Reserve error codes in the range [2800000-2800999].\nexport const SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH = 2800000;\nexport const SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE = 2800001;\nexport const SOLANA_ERROR__ADDRESSES__INVALID_BASE58_ENCODED_ADDRESS = 2800002;\nexport const SOLANA_ERROR__ADDRESSES__INVALID_ED25519_PUBLIC_KEY = 2800003;\nexport const SOLANA_ERROR__ADDRESSES__MALFORMED_PDA = 2800004;\nexport const SOLANA_ERROR__ADDRESSES__PDA_BUMP_SEED_OUT_OF_RANGE = 2800005;\nexport const SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED = 2800006;\nexport const SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED = 2800007;\nexport const SOLANA_ERROR__ADDRESSES__INVALID_SEEDS_POINT_ON_CURVE = 2800008;\nexport const SOLANA_ERROR__ADDRESSES__FAILED_TO_FIND_VIABLE_PDA_BUMP_SEED = 2800009;\nexport const SOLANA_ERROR__ADDRESSES__PDA_ENDS_WITH_PDA_MARKER = 2800010;\nexport const SOLANA_ERROR__ADDRESSES__INVALID_OFF_CURVE_ADDRESS = 2800011;\n\n// Account-related errors.\n// Reserve error codes in the range [3230000-3230999].\nexport const SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND = 3230000;\nexport const SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND = 32300001;\nexport const SOLANA_ERROR__ACCOUNTS__FAILED_TO_DECODE_ACCOUNT = 3230002;\nexport const SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT = 3230003;\nexport const SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED = 3230004;\n\n// Subtle-Crypto-related errors.\n// Reserve error codes in the range [3610000-3610999].\nexport const SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT = 3610000;\nexport const SOLANA_ERROR__SUBTLE_CRYPTO__DIGEST_UNIMPLEMENTED = 3610001;\nexport const SOLANA_ERROR__SUBTLE_CRYPTO__ED25519_ALGORITHM_UNIMPLEMENTED = 3610002;\nexport const SOLANA_ERROR__SUBTLE_CRYPTO__EXPORT_FUNCTION_UNIMPLEMENTED = 3610003;\nexport const SOLANA_ERROR__SUBTLE_CRYPTO__GENERATE_FUNCTION_UNIMPLEMENTED = 3610004;\nexport const SOLANA_ERROR__SUBTLE_CRYPTO__SIGN_FUNCTION_UNIMPLEMENTED = 3610005;\nexport const SOLANA_ERROR__SUBTLE_CRYPTO__VERIFY_FUNCTION_UNIMPLEMENTED = 3610006;\nexport const SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY = 3610007;\n\n// Crypto-related errors.\n// Reserve error codes in the range [3611000-3611050].\nexport const SOLANA_ERROR__CRYPTO__RANDOM_VALUES_FUNCTION_UNIMPLEMENTED = 3611000;\n\n// Key-related errors.\n// Reserve error codes in the range [3704000-3704999].\nexport const SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH = 3704000;\nexport const SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH = 3704001;\nexport const SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH = 3704002;\nexport const SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE = 3704003;\nexport const SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY = 3704004;\nexport const SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX = 3704005;\nexport const SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT = 3704006;\n\n// Filesystem-related errors.\n// Reserve error codes in the range [3712000-3712999].\nexport const SOLANA_ERROR__FS__UNSUPPORTED_ENVIRONMENT = 3712000;\n\n// Instruction-related errors.\n// Reserve error codes in the range [4128000-4128999].\nexport const SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_ACCOUNTS = 4128000;\nexport const SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_DATA = 4128001;\nexport const SOLANA_ERROR__INSTRUCTION__PROGRAM_ID_MISMATCH = 4128002;\n\n// Instruction errors.\n// Reserve error codes starting with [4615000-4615999] for the Rust enum `InstructionError`.\n// Error names here are dictated by the RPC (see ./instruction-error.ts).\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN = 4615000;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__GENERIC_ERROR = 4615001;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT = 4615002;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_INSTRUCTION_DATA = 4615003;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_DATA = 4615004;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_TOO_SMALL = 4615005;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS = 4615006;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_PROGRAM_ID = 4615007;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_REQUIRED_SIGNATURE = 4615008;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_ALREADY_INITIALIZED = 4615009;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__UNINITIALIZED_ACCOUNT = 4615010;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__UNBALANCED_INSTRUCTION = 4615011;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__MODIFIED_PROGRAM_ID = 4615012;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_LAMPORT_SPEND = 4615013;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_DATA_MODIFIED = 4615014;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_LAMPORT_CHANGE = 4615015;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_DATA_MODIFIED = 4615016;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_INDEX = 4615017;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_MODIFIED = 4615018;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__RENT_EPOCH_MODIFIED = 4615019;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__NOT_ENOUGH_ACCOUNT_KEYS = 4615020;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_SIZE_CHANGED = 4615021;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_EXECUTABLE = 4615022;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_FAILED = 4615023;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_OUTSTANDING = 4615024;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_OUT_OF_SYNC = 4615025;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM = 4615026;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ERROR = 4615027;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_DATA_MODIFIED = 4615028;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_LAMPORT_CHANGE = 4615029;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT = 4615030;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_PROGRAM_ID = 4615031;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__CALL_DEPTH = 4615032;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_ACCOUNT = 4615033;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__REENTRANCY_NOT_ALLOWED = 4615034;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__MAX_SEED_LENGTH_EXCEEDED = 4615035;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_SEEDS = 4615036;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_REALLOC = 4615037;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__COMPUTATIONAL_BUDGET_EXCEEDED = 4615038;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__PRIVILEGE_ESCALATION = 4615039;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_ENVIRONMENT_SETUP_FAILURE = 4615040;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPLETE = 4615041;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPILE = 4615042;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__IMMUTABLE = 4615043;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_AUTHORITY = 4615044;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR = 4615045;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_RENT_EXEMPT = 4615046;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_OWNER = 4615047;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ARITHMETIC_OVERFLOW = 4615048;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_SYSVAR = 4615049;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__ILLEGAL_OWNER = 4615050;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED = 4615051;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_EXCEEDED = 4615052;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED = 4615053;\nexport const SOLANA_ERROR__INSTRUCTION_ERROR__BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS = 4615054;\n\n// Signer-related errors.\n// Reserve error codes in the range [5508000-5508999].\nexport const SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS = 5508000;\nexport const SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER = 5508001;\nexport const SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER = 5508002;\nexport const SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER = 5508003;\nexport const SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER = 5508004;\nexport const SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER = 5508005;\nexport const SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER = 5508006;\nexport const SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER = 5508007;\nexport const SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER = 5508008;\nexport const SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS = 5508009;\nexport const SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING = 5508010;\nexport const SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED = 5508011;\nexport const SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION = 5508012;\n\n// Offchain-message-related errors.\n// Reserve error codes in the range [5607000-5607999].\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED = 5607000;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE = 5607001;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE = 5607002;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH = 5607003;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH = 5607004;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO = 5607005;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED = 5607006;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH = 5607007;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH = 5607008;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY = 5607009;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO = 5607010;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING = 5607011;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH = 5607012;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE = 5607013;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION = 5607014;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_SORTED = 5607015;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE = 5607016;\nexport const SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE = 5607017;\n\n// Transaction-related errors.\n// Reserve error codes in the range [5663000-5663999].\nexport const SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES = 5663000;\nexport const SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE = 5663001;\nexport const SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME = 5663002;\nexport const SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME = 5663003;\nexport const SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE = 5663004;\nexport const SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING = 5663005;\nexport const SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE = 5663006;\nexport const SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND = 5663007;\nexport const SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING = 5663008;\nexport const SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING = 5663009;\nexport const SOLANA_ERROR__TRANSACTION__ADDRESS_MISSING = 5663010;\nexport const SOLANA_ERROR__TRANSACTION__FEE_PAYER_MISSING = 5663011;\nexport const SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING = 5663012;\nexport const SOLANA_ERROR__TRANSACTION__INVALID_NONCE_TRANSACTION_INSTRUCTIONS_MISSING = 5663013;\nexport const SOLANA_ERROR__TRANSACTION__INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_MUST_BE_ADVANCE_NONCE = 5663014;\nexport const SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION = 5663015;\nexport const SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES = 5663016;\nexport const SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH = 5663017;\nexport const SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT = 5663018;\nexport const SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT = 5663019;\nexport const SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT = 5663020;\nexport const SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED = 5663021;\nexport const SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE = 5663022;\nexport const SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES = 5663023;\nexport const SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_MESSAGE_BYTES = 5663024;\nexport const SOLANA_ERROR__TRANSACTION__CANNOT_DECODE_EMPTY_TRANSACTION_BYTES = 5663025;\nexport const SOLANA_ERROR__TRANSACTION__VERSION_ZERO_MUST_BE_ENCODED_WITH_SIGNATURES_FIRST = 5663026;\nexport const SOLANA_ERROR__TRANSACTION__SIGNATURE_COUNT_TOO_HIGH_FOR_TRANSACTION_BYTES = 5663027;\nexport const SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS = 5663028;\nexport const SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX = 5663029;\nexport const SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND = 5663030;\nexport const SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH = 5663031;\nexport const SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES = 5663032;\nexport const SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES = 5663033;\nexport const SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS = 5663034;\nexport const SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION = 5663035;\n\n// Transaction errors.\n// Reserve error codes starting with [7050000-7050999] for the Rust enum `TransactionError`.\n// Error names here are dictated by the RPC (see ./transaction-error.ts).\nexport const SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN = 7050000;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_IN_USE = 7050001;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_LOADED_TWICE = 7050002;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_NOT_FOUND = 7050003;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_ACCOUNT_NOT_FOUND = 7050004;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE = 7050005;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ACCOUNT_FOR_FEE = 7050006;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__ALREADY_PROCESSED = 7050007;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND = 7050008;\n// `InstructionError` intentionally omitted.\nexport const SOLANA_ERROR__TRANSACTION_ERROR__CALL_CHAIN_TOO_DEEP = 7050009;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__MISSING_SIGNATURE_FOR_FEE = 7050010;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ACCOUNT_INDEX = 7050011;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__SIGNATURE_FAILURE = 7050012;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_PROGRAM_FOR_EXECUTION = 7050013;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__SANITIZE_FAILURE = 7050014;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__CLUSTER_MAINTENANCE = 7050015;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_BORROW_OUTSTANDING = 7050016;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_BLOCK_COST_LIMIT = 7050017;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__UNSUPPORTED_VERSION = 7050018;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_WRITABLE_ACCOUNT = 7050019;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_ACCOUNT_COST_LIMIT = 7050020;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT = 7050021;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__TOO_MANY_ACCOUNT_LOCKS = 7050022;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__ADDRESS_LOOKUP_TABLE_NOT_FOUND = 7050023;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_OWNER = 7050024;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_DATA = 7050025;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_INDEX = 7050026;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_RENT_PAYING_ACCOUNT = 7050027;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_VOTE_COST_LIMIT = 7050028;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT = 7050029;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION = 7050030;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT = 7050031;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__MAX_LOADED_ACCOUNTS_DATA_SIZE_EXCEEDED = 7050032;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__INVALID_LOADED_ACCOUNTS_DATA_SIZE_LIMIT = 7050033;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__RESANITIZATION_NEEDED = 7050034;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED = 7050035;\nexport const SOLANA_ERROR__TRANSACTION_ERROR__UNBALANCED_TRANSACTION = 7050036;\n\n// Instruction plan related errors.\n// Reserve error codes in the range [7618000-7618999].\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN = 7618000;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE = 7618001;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN = 7618002;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN = 7618003;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED = 7618004;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND = 7618005;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN = 7618006;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN = 7618007;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT = 7618008;\nexport const SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT = 7618009;\n\n// Codec-related errors.\n// Reserve error codes in the range [8078000-8078999].\nexport const SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY = 8078000;\nexport const SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH = 8078001;\nexport const SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH = 8078002;\nexport const SOLANA_ERROR__CODECS__EXPECTED_VARIABLE_LENGTH = 8078003;\nexport const SOLANA_ERROR__CODECS__ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH = 8078004;\nexport const SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH = 8078005;\nexport const SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH = 8078006;\nexport const SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS = 8078007;\nexport const SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE = 8078008;\nexport const SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT = 8078009;\nexport const SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT = 8078010;\nexport const SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE = 8078011;\nexport const SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE = 8078012;\nexport const SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH = 8078013;\nexport const SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE = 8078014;\nexport const SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT = 8078015;\nexport const SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE = 8078016;\nexport const SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE = 8078017;\nexport const SOLANA_ERROR__CODECS__INVALID_CONSTANT = 8078018;\nexport const SOLANA_ERROR__CODECS__EXPECTED_ZERO_VALUE_TO_MATCH_ITEM_FIXED_SIZE = 8078019;\nexport const SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL = 8078020;\nexport const SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES = 8078021;\nexport const SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS = 8078022;\nexport const SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY = 8078023;\nexport const SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE = 8078024;\nexport const SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES = 8078025;\n\n// Fixed-point-related errors.\n// Reserve error codes in the range [8090000-8090999].\nexport const SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS = 8090000;\nexport const SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS = 8090001;\nexport const SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS = 8090002;\nexport const SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS = 8090003;\nexport const SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE = 8090004;\nexport const SOLANA_ERROR__FIXED_POINTS__INVALID_STRING = 8090005;\nexport const SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO = 8090006;\nexport const SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW = 8090007;\nexport const SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH = 8090008;\nexport const SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO = 8090009;\nexport const SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS = 8090010;\nexport const SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE = 8090011;\nexport const SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED = 8090012;\n\n// RPC-related errors.\n// Reserve error codes in the range [8100000-8100999].\nexport const SOLANA_ERROR__RPC__INTEGER_OVERFLOW = 8100000;\nexport const SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN = 8100001;\nexport const SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR = 8100002;\nexport const SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD = 8100003;\n\n// RPC-Subscriptions-related errors.\n// Reserve error codes in the range [8190000-8190999].\nexport const SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN = 8190000;\nexport const SOLANA_ERROR__RPC_SUBSCRIPTIONS__EXPECTED_SERVER_SUBSCRIPTION_ID = 8190001;\nexport const SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED = 8190002;\nexport const SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED = 8190003;\nexport const SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT = 8190004;\n\n// Subscribable-related errors.\n// Reserve error codes in the range [8195000-8195999].\nexport const SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED = 8195000;\n\n// Program-client-related errors.\n// Reserve error codes in the range [8500000-8500999].\nexport const SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS = 8500000;\nexport const SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE = 8500001;\nexport const SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION = 8500002;\nexport const SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE = 8500003;\nexport const SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL = 8500004;\nexport const SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_ACCOUNT_TYPE = 8500005;\nexport const SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT = 8500006;\n\n// Wallet-related errors.\n// Reserve error codes in the range [8900000-8900999].\nexport const SOLANA_ERROR__WALLET__NOT_CONNECTED = 8900000;\nexport const SOLANA_ERROR__WALLET__NO_SIGNER_CONNECTED = 8900001;\nexport const SOLANA_ERROR__WALLET__SIGNER_NOT_AVAILABLE = 8900002;\n\n// Invariant violation errors.\n// Reserve error codes in the range [9900000-9900999].\n// These errors should only be thrown when there is a bug with the\n// library itself and should, in theory, never reach the end user.\nexport const SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING = 9900000;\nexport const SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE = 9900001;\nexport const SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING = 9900002;\nexport const SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE = 9900003;\nexport const SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED = 9900004;\nexport const SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND = 9900005;\nexport const SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND = 9900006;\n\n/**\n * A union of every Solana error code\n *\n * @privateRemarks\n * You might be wondering why this is not a TypeScript enum or const enum.\n *\n * One of the goals of this library is to enable people to use some or none of it without having to\n * bundle all of it.\n *\n * If we made the set of error codes an enum then anyone who imported it (even if to only use a\n * single error code) would be forced to bundle every code and its label.\n *\n * Const enums appear to solve this problem by letting the compiler inline only the codes that are\n * actually used. Unfortunately exporting ambient (const) enums from a library like `@solana/errors`\n * is not safe, for a variety of reasons covered here: https://stackoverflow.com/a/28818850\n */\nexport type SolanaErrorCode =\n    | typeof SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND\n    | typeof SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED\n    | typeof SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT\n    | typeof SOLANA_ERROR__ACCOUNTS__FAILED_TO_DECODE_ACCOUNT\n    | typeof SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND\n    | typeof SOLANA_ERROR__ADDRESSES__FAILED_TO_FIND_VIABLE_PDA_BUMP_SEED\n    | typeof SOLANA_ERROR__ADDRESSES__INVALID_BASE58_ENCODED_ADDRESS\n    | typeof SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH\n    | typeof SOLANA_ERROR__ADDRESSES__INVALID_ED25519_PUBLIC_KEY\n    | typeof SOLANA_ERROR__ADDRESSES__INVALID_OFF_CURVE_ADDRESS\n    | typeof SOLANA_ERROR__ADDRESSES__INVALID_SEEDS_POINT_ON_CURVE\n    | typeof SOLANA_ERROR__ADDRESSES__MALFORMED_PDA\n    | typeof SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED\n    | typeof SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED\n    | typeof SOLANA_ERROR__ADDRESSES__PDA_BUMP_SEED_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__ADDRESSES__PDA_ENDS_WITH_PDA_MARKER\n    | typeof SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED\n    | typeof SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY\n    | typeof SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS\n    | typeof SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL\n    | typeof SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH\n    | typeof SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH\n    | typeof SOLANA_ERROR__CODECS__ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH\n    | typeof SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY\n    | typeof SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH\n    | typeof SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH\n    | typeof SOLANA_ERROR__CODECS__EXPECTED_VARIABLE_LENGTH\n    | typeof SOLANA_ERROR__CODECS__EXPECTED_ZERO_VALUE_TO_MATCH_ITEM_FIXED_SIZE\n    | typeof SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH\n    | typeof SOLANA_ERROR__CODECS__INVALID_CONSTANT\n    | typeof SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT\n    | typeof SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT\n    | typeof SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT\n    | typeof SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS\n    | typeof SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES\n    | typeof SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE\n    | typeof SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE\n    | typeof SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES\n    | typeof SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__CRYPTO__RANDOM_VALUES_FUNCTION_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION\n    | typeof SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS\n    | typeof SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW\n    | typeof SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO\n    | typeof SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS\n    | typeof SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS\n    | typeof SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS\n    | typeof SOLANA_ERROR__FIXED_POINTS__INVALID_STRING\n    | typeof SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS\n    | typeof SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO\n    | typeof SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE\n    | typeof SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH\n    | typeof SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS\n    | typeof SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED\n    | typeof SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__FS__UNSUPPORTED_ENVIRONMENT\n    | typeof SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_ACCOUNTS\n    | typeof SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_DATA\n    | typeof SOLANA_ERROR__INSTRUCTION__PROGRAM_ID_MISMATCH\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_ALREADY_INITIALIZED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_FAILED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_OUTSTANDING\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_SIZE_CHANGED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_TOO_SMALL\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_EXECUTABLE\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_RENT_EXEMPT\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ARITHMETIC_OVERFLOW\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__CALL_DEPTH\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__COMPUTATIONAL_BUDGET_EXCEEDED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_INDEX\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_OUT_OF_SYNC\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_DATA_MODIFIED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_LAMPORT_CHANGE\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_MODIFIED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_DATA_MODIFIED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_LAMPORT_SPEND\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__GENERIC_ERROR\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ILLEGAL_OWNER\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__IMMUTABLE\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_AUTHORITY\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_PROGRAM_ID\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_DATA\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_OWNER\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ERROR\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_INSTRUCTION_DATA\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_REALLOC\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_SEEDS\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_EXCEEDED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MAX_SEED_LENGTH_EXCEEDED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_ACCOUNT\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_REQUIRED_SIGNATURE\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MODIFIED_PROGRAM_ID\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__NOT_ENOUGH_ACCOUNT_KEYS\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__PRIVILEGE_ESCALATION\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_ENVIRONMENT_SETUP_FAILURE\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPILE\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPLETE\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_DATA_MODIFIED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_LAMPORT_CHANGE\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__REENTRANCY_NOT_ALLOWED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__RENT_EPOCH_MODIFIED\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNBALANCED_INSTRUCTION\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNINITIALIZED_ACCOUNT\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_PROGRAM_ID\n    | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_SYSVAR\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN\n    | typeof SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT\n    | typeof SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH\n    | typeof SOLANA_ERROR__INVALID_NONCE\n    | typeof SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING\n    | typeof SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND\n    | typeof SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND\n    | typeof SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE\n    | typeof SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING\n    | typeof SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE\n    | typeof SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR\n    | typeof SOLANA_ERROR__JSON_RPC__INVALID_PARAMS\n    | typeof SOLANA_ERROR__JSON_RPC__INVALID_REQUEST\n    | typeof SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND\n    | typeof SOLANA_ERROR__JSON_RPC__PARSE_ERROR\n    | typeof SOLANA_ERROR__JSON_RPC__SCAN_ERROR\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NO_SNAPSHOT\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_LEN_MISMATCH\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION\n    | typeof SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX\n    | typeof SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH\n    | typeof SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH\n    | typeof SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH\n    | typeof SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY\n    | typeof SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT\n    | typeof SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__MALFORMED_BIGINT_STRING\n    | typeof SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR\n    | typeof SOLANA_ERROR__MALFORMED_NUMBER_STRING\n    | typeof SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_SORTED\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION\n    | typeof SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED\n    | typeof SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT\n    | typeof SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION\n    | typeof SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS\n    | typeof SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL\n    | typeof SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE\n    | typeof SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_ACCOUNT_TYPE\n    | typeof SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE\n    | typeof SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD\n    | typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW\n    | typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR\n    | typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN\n    | typeof SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN\n    | typeof SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED\n    | typeof SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED\n    | typeof SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT\n    | typeof SOLANA_ERROR__RPC_SUBSCRIPTIONS__EXPECTED_SERVER_SUBSCRIPTION_ID\n    | typeof SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS\n    | typeof SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER\n    | typeof SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER\n    | typeof SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER\n    | typeof SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER\n    | typeof SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER\n    | typeof SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER\n    | typeof SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER\n    | typeof SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER\n    | typeof SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS\n    | typeof SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING\n    | typeof SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION\n    | typeof SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED\n    | typeof SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY\n    | typeof SOLANA_ERROR__SUBTLE_CRYPTO__DIGEST_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT\n    | typeof SOLANA_ERROR__SUBTLE_CRYPTO__ED25519_ALGORITHM_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__SUBTLE_CRYPTO__EXPORT_FUNCTION_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__SUBTLE_CRYPTO__GENERATE_FUNCTION_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__SUBTLE_CRYPTO__SIGN_FUNCTION_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__SUBTLE_CRYPTO__VERIFY_FUNCTION_UNIMPLEMENTED\n    | typeof SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__TRANSACTION__ADDRESS_MISSING\n    | typeof SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION\n    | typeof SOLANA_ERROR__TRANSACTION__CANNOT_DECODE_EMPTY_TRANSACTION_BYTES\n    | typeof SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_MESSAGE_BYTES\n    | typeof SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES\n    | typeof SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT\n    | typeof SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME\n    | typeof SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME\n    | typeof SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING\n    | typeof SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING\n    | typeof SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND\n    | typeof SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT\n    | typeof SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT\n    | typeof SOLANA_ERROR__TRANSACTION__FEE_PAYER_MISSING\n    | typeof SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING\n    | typeof SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH\n    | typeof SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS\n    | typeof SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND\n    | typeof SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX\n    | typeof SOLANA_ERROR__TRANSACTION__INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_MUST_BE_ADVANCE_NONCE\n    | typeof SOLANA_ERROR__TRANSACTION__INVALID_NONCE_TRANSACTION_INSTRUCTIONS_MISSING\n    | typeof SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES\n    | typeof SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE\n    | typeof SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES\n    | typeof SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH\n    | typeof SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE\n    | typeof SOLANA_ERROR__TRANSACTION__SIGNATURE_COUNT_TOO_HIGH_FOR_TRANSACTION_BYTES\n    | typeof SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING\n    | typeof SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES\n    | typeof SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION\n    | typeof SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS\n    | typeof SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES\n    | typeof SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED\n    | typeof SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE\n    | typeof SOLANA_ERROR__TRANSACTION__VERSION_ZERO_MUST_BE_ENCODED_WITH_SIGNATURES_FIRST\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_BORROW_OUTSTANDING\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_IN_USE\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_LOADED_TWICE\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_NOT_FOUND\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__ADDRESS_LOOKUP_TABLE_NOT_FOUND\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__ALREADY_PROCESSED\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__CALL_CHAIN_TOO_DEEP\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__CLUSTER_MAINTENANCE\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ACCOUNT_FOR_FEE\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ACCOUNT_INDEX\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_DATA\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_INDEX\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_OWNER\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_LOADED_ACCOUNTS_DATA_SIZE_LIMIT\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_PROGRAM_FOR_EXECUTION\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_RENT_PAYING_ACCOUNT\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__INVALID_WRITABLE_ACCOUNT\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__MAX_LOADED_ACCOUNTS_DATA_SIZE_EXCEEDED\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__MISSING_SIGNATURE_FOR_FEE\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_ACCOUNT_NOT_FOUND\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__RESANITIZATION_NEEDED\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__SANITIZE_FAILURE\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__SIGNATURE_FAILURE\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__TOO_MANY_ACCOUNT_LOCKS\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__UNBALANCED_TRANSACTION\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__UNSUPPORTED_VERSION\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_ACCOUNT_COST_LIMIT\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_BLOCK_COST_LIMIT\n    | typeof SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_VOTE_COST_LIMIT\n    | typeof SOLANA_ERROR__WALLET__NO_SIGNER_CONNECTED\n    | typeof SOLANA_ERROR__WALLET__NOT_CONNECTED\n    | typeof SOLANA_ERROR__WALLET__SIGNER_NOT_AVAILABLE;\n\n/**\n * Errors of this type are understood to have an optional {@link SolanaError} nested inside as\n * `cause`.\n */\nexport type SolanaErrorCodeWithCause =\n    | typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE\n    | typeof SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT;\n\n/**\n * Errors of this type have a deprecated `cause` property. Consumers should use the error's\n * `context` instead to access relevant error information.\n */\nexport type SolanaErrorCodeWithDeprecatedCause =\n    typeof SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN;\n"
  },
  {
    "path": "packages/errors/src/context.ts",
    "content": "/**\n * To add a new error, follow the instructions at\n * https://github.com/anza-xyz/kit/tree/main/packages/errors/#adding-a-new-error\n *\n * @privateRemarks\n * WARNING:\n *   - Don't change or remove members of an error's context.\n */\nimport {\n    SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED,\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT,\n    SOLANA_ERROR__ACCOUNTS__FAILED_TO_DECODE_ACCOUNT,\n    SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND,\n    SOLANA_ERROR__ADDRESSES__INVALID_BASE58_ENCODED_ADDRESS,\n    SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED,\n    SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED,\n    SOLANA_ERROR__ADDRESSES__PDA_BUMP_SEED_OUT_OF_RANGE,\n    SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED,\n    SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY,\n    SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS,\n    SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL,\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH,\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH,\n    SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY,\n    SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH,\n    SOLANA_ERROR__CODECS__EXPECTED_ZERO_VALUE_TO_MATCH_ITEM_FIXED_SIZE,\n    SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__CODECS__INVALID_CONSTANT,\n    SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT,\n    SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT,\n    SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT,\n    SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS,\n    SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES,\n    SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE,\n    SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES,\n    SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS,\n    SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO,\n    SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_STRING,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO,\n    SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SOLANA_ERROR__FS__UNSUPPORTED_ENVIRONMENT,\n    SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_ACCOUNTS,\n    SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_DATA,\n    SOLANA_ERROR__INSTRUCTION__PROGRAM_ID_MISMATCH,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_ALREADY_INITIALIZED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_FAILED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_OUTSTANDING,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_SIZE_CHANGED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_TOO_SMALL,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_EXECUTABLE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_RENT_EXEMPT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR,\n    SOLANA_ERROR__INSTRUCTION_ERROR__BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS,\n    SOLANA_ERROR__INSTRUCTION_ERROR__CALL_DEPTH,\n    SOLANA_ERROR__INSTRUCTION_ERROR__COMPUTATIONAL_BUDGET_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM,\n    SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_INDEX,\n    SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_OUT_OF_SYNC,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_DATA_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_LAMPORT_CHANGE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_DATA_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_LAMPORT_SPEND,\n    SOLANA_ERROR__INSTRUCTION_ERROR__GENERIC_ERROR,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ILLEGAL_OWNER,\n    SOLANA_ERROR__INSTRUCTION_ERROR__IMMUTABLE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_AUTHORITY,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_PROGRAM_ID,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_DATA,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_OWNER,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ERROR,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_INSTRUCTION_DATA,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_REALLOC,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_SEEDS,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MAX_SEED_LENGTH_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_ACCOUNT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_REQUIRED_SIGNATURE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MODIFIED_PROGRAM_ID,\n    SOLANA_ERROR__INSTRUCTION_ERROR__NOT_ENOUGH_ACCOUNT_KEYS,\n    SOLANA_ERROR__INSTRUCTION_ERROR__PRIVILEGE_ESCALATION,\n    SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_ENVIRONMENT_SETUP_FAILURE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPILE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPLETE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_DATA_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_LAMPORT_CHANGE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__REENTRANCY_NOT_ALLOWED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__RENT_EPOCH_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNBALANCED_INSTRUCTION,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNINITIALIZED_ACCOUNT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_PROGRAM_ID,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_SYSVAR,\n    SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT,\n    SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH,\n    SOLANA_ERROR__INVALID_NONCE,\n    SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING,\n    SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED,\n    SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND,\n    SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND,\n    SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE,\n    SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR,\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__INVALID_REQUEST,\n    SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND,\n    SOLANA_ERROR__JSON_RPC__PARSE_ERROR,\n    SOLANA_ERROR__JSON_RPC__SCAN_ERROR,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION,\n    SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX,\n    SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__MALFORMED_BIGINT_STRING,\n    SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR,\n    SOLANA_ERROR__MALFORMED_NUMBER_STRING,\n    SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED,\n    SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT,\n    SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION,\n    SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS,\n    SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL,\n    SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE,\n    SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_ACCOUNT_TYPE,\n    SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE,\n    SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD,\n    SOLANA_ERROR__RPC__INTEGER_OVERFLOW,\n    SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR,\n    SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n    SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS,\n    SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER,\n    SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION,\n    SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY,\n    SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE,\n    SOLANA_ERROR__TRANSACTION__ADDRESS_MISSING,\n    SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,\n    SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n    SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH,\n    SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS,\n    SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND,\n    SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX,\n    SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES,\n    SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,\n    SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES,\n    SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH,\n    SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n    SOLANA_ERROR__TRANSACTION__SIGNATURE_COUNT_TOO_HIGH_FOR_TRANSACTION_BYTES,\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE,\n    SOLANA_ERROR__TRANSACTION__VERSION_ZERO_MUST_BE_ENCODED_WITH_SIGNATURES_FIRST,\n    SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT,\n    SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED,\n    SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN,\n    SOLANA_ERROR__WALLET__NO_SIGNER_CONNECTED,\n    SOLANA_ERROR__WALLET__NOT_CONNECTED,\n    SolanaErrorCode,\n} from './codes';\nimport { RpcSimulateTransactionResult } from './json-rpc-error';\n\ntype BasicInstructionErrorContext<T extends SolanaErrorCode> = { [P in T]: { index: number } };\n\ntype DefaultUnspecifiedErrorContextToUndefined<T> = {\n    [P in SolanaErrorCode]: P extends keyof T ? T[P] : undefined;\n};\n\ntype ReadonlyContextValue<T> = {\n    [P in keyof T]: Readonly<T[P]>;\n};\n\ntype TypedArrayMutableProperties = 'copyWithin' | 'fill' | 'reverse' | 'set' | 'sort';\ninterface ReadonlyUint8Array extends Omit<Uint8Array, TypedArrayMutableProperties> {\n    readonly [n: number]: number;\n}\n\n/** A amount of bytes. */\ntype Bytes = number;\n\n/**\n * A map of every {@link SolanaError} code to the type of its `context` property.\n */\nexport type SolanaErrorContext = ReadonlyContextValue<\n    DefaultUnspecifiedErrorContextToUndefined<\n        BasicInstructionErrorContext<\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_ALREADY_INITIALIZED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_FAILED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_OUTSTANDING\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_SIZE_CHANGED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_TOO_SMALL\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_EXECUTABLE\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_RENT_EXEMPT\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ARITHMETIC_OVERFLOW\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__CALL_DEPTH\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__COMPUTATIONAL_BUDGET_EXCEEDED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_INDEX\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_OUT_OF_SYNC\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_DATA_MODIFIED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_LAMPORT_CHANGE\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_MODIFIED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_DATA_MODIFIED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_LAMPORT_SPEND\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__GENERIC_ERROR\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__ILLEGAL_OWNER\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__IMMUTABLE\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_AUTHORITY\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_PROGRAM_ID\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_DATA\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_OWNER\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ERROR\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_INSTRUCTION_DATA\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_REALLOC\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_SEEDS\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_EXCEEDED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MAX_SEED_LENGTH_EXCEEDED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_ACCOUNT\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_REQUIRED_SIGNATURE\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__MODIFIED_PROGRAM_ID\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__NOT_ENOUGH_ACCOUNT_KEYS\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__PRIVILEGE_ESCALATION\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_ENVIRONMENT_SETUP_FAILURE\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPILE\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPLETE\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_DATA_MODIFIED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_LAMPORT_CHANGE\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__REENTRANCY_NOT_ALLOWED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__RENT_EPOCH_MODIFIED\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNBALANCED_INSTRUCTION\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNINITIALIZED_ACCOUNT\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_PROGRAM_ID\n            | typeof SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_SYSVAR\n        > & {\n            [SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND]: {\n                address: string;\n            };\n            [SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED]: {\n                addresses: readonly string[];\n            };\n            [SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT]: {\n                address: string;\n            };\n            [SOLANA_ERROR__ACCOUNTS__FAILED_TO_DECODE_ACCOUNT]: {\n                address: string;\n            };\n            [SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND]: {\n                addresses: readonly string[];\n            };\n            [SOLANA_ERROR__ADDRESSES__INVALID_BASE58_ENCODED_ADDRESS]: {\n                putativeAddress: string;\n            };\n            [SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED]: {\n                actual: number;\n                maxSeeds: number;\n            };\n            [SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED]: {\n                actual: number;\n                index: number;\n                maxSeedLength: number;\n            };\n            [SOLANA_ERROR__ADDRESSES__PDA_BUMP_SEED_OUT_OF_RANGE]: {\n                bump: number;\n            };\n            [SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED]: {\n                currentBlockHeight: bigint;\n                lastValidBlockHeight: bigint;\n            };\n            [SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY]: {\n                codecDescription: string;\n            };\n            [SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS]: {\n                stringValues: readonly string[];\n            };\n            [SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL]: {\n                encodedBytes: ReadonlyUint8Array;\n                hexEncodedBytes: string;\n                hexSentinel: string;\n                sentinel: ReadonlyUint8Array;\n            };\n            [SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH]: {\n                decoderFixedSize: number;\n                encoderFixedSize: number;\n            };\n            [SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH]: {\n                decoderMaxSize: number | undefined;\n                encoderMaxSize: number | undefined;\n            };\n            [SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE]: {\n                discriminator: bigint | number;\n                formattedValidDiscriminators: string;\n                validDiscriminators: readonly number[];\n            };\n            [SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY]: {\n                expectedLength: number;\n                numExcessBytes: number;\n            };\n            [SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH]: {\n                bytesLength: number;\n                codecDescription: string;\n            };\n            [SOLANA_ERROR__CODECS__EXPECTED_ZERO_VALUE_TO_MATCH_ITEM_FIXED_SIZE]: {\n                codecDescription: string;\n                expectedSize: number;\n                hexZeroValue: string;\n                zeroValue: ReadonlyUint8Array;\n            };\n            [SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH]: {\n                bytesLength: number;\n                codecDescription: string;\n                expected: number;\n            };\n            [SOLANA_ERROR__CODECS__INVALID_CONSTANT]: {\n                constant: ReadonlyUint8Array;\n                data: ReadonlyUint8Array;\n                hexConstant: string;\n                hexData: string;\n                offset: number;\n            };\n            [SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT]: {\n                value: bigint | boolean | number | string | null | undefined;\n                variants: readonly (bigint | boolean | number | string | null | undefined)[];\n            };\n            [SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT]: {\n                formattedNumericalValues: string;\n                numericalValues: readonly number[];\n                stringValues: readonly string[];\n                variant: number | string | symbol;\n            };\n            [SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT]: {\n                value: bigint | boolean | number | string | null | undefined;\n                variants: readonly (bigint | boolean | number | string | null | undefined)[];\n            };\n            [SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS]: {\n                actual: bigint | number;\n                codecDescription: string;\n                expected: bigint | number;\n            };\n            [SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES]: {\n                bytes: ReadonlyUint8Array;\n            };\n            [SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE]: {\n                alphabet: string;\n                base: number;\n                value: string;\n            };\n            [SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE]: {\n                discriminator: bigint | number;\n                maxRange: number;\n                minRange: number;\n            };\n            [SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE]: {\n                codecDescription: string;\n                max: bigint | number;\n                min: bigint | number;\n                value: bigint | number;\n            };\n            [SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE]: {\n                bytesLength: number;\n                codecDescription: string;\n                offset: number;\n            };\n            [SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES]: {\n                decodedBytes: ReadonlyUint8Array;\n                hexDecodedBytes: string;\n                hexSentinel: string;\n                sentinel: ReadonlyUint8Array;\n            };\n            [SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE]: {\n                maxRange: number;\n                minRange: number;\n                variant: number;\n            };\n            [SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION]: {\n                causeMessage: string;\n                logs?: readonly string[];\n                preflightData?: Omit<RpcSimulateTransactionResult, 'err'>;\n                transactionPlanResult: unknown;\n            };\n            [SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS]: {\n                causeMessages: string;\n                failedTransactions: ReadonlyArray<{\n                    error: Error;\n                    index: number;\n                    logs?: readonly string[];\n                    preflightData?: Omit<RpcSimulateTransactionResult, 'err'>;\n                }>;\n                transactionPlanResult: unknown;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW]: {\n                kind: string;\n                max: bigint;\n                min: bigint;\n                operation: string;\n                result: bigint;\n                signedness: string;\n                totalBits: number;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO]: {\n                kind: string;\n                signedness: string;\n                totalBits: number;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS]: {\n                fractionalBits: number;\n                totalBits: number;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS]: {\n                decimals: unknown;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS]: {\n                fractionalBits: unknown;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__INVALID_STRING]: {\n                input: string;\n                kind: string;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS]: {\n                kind: string;\n                totalBits: unknown;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO]: {\n                denominator: bigint;\n                kind: string;\n                numerator: bigint;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE]: {\n                kind: string;\n                raw: unknown;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH]: {\n                actualKind: string;\n                actualScale: number;\n                actualScaleLabel: string;\n                actualSignedness: string;\n                actualTotalBits: number;\n                expectedKind: string;\n                expectedScale: number;\n                expectedScaleLabel: string;\n                expectedSignedness: string;\n                expectedTotalBits: number;\n                operation: string;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS]: {\n                kind: string;\n                operation: string;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED]: {\n                kind: string;\n                totalBits: number;\n            };\n            [SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE]: {\n                kind: string;\n                max: bigint;\n                min: bigint;\n                raw: bigint;\n                signedness: string;\n                totalBits: number;\n            };\n            [SOLANA_ERROR__FS__UNSUPPORTED_ENVIRONMENT]: {\n                operation: string;\n            };\n            [SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR]: {\n                index: number;\n            };\n            [SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM]: {\n                code: number;\n                index: number;\n            };\n            [SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN]: {\n                errorName: string;\n                index: number;\n                instructionErrorContext?: unknown;\n            };\n            [SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT]: {\n                transactionPlanResult: unknown;\n            };\n            [SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND]: {\n                transactionPlanResult: unknown;\n            };\n            [SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN]: {\n                abortReason?: unknown;\n                transactionPlanResult: unknown;\n            };\n            [SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN]: {\n                numBytesRequired: number;\n                numFreeBytes: number;\n            };\n            [SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN]: {\n                actualKind: string;\n                expectedKind: string;\n                instructionPlan: unknown;\n            };\n            [SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN]: {\n                actualKind: string;\n                expectedKind: string;\n                transactionPlan: unknown;\n            };\n            [SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT]: {\n                actualKind: string;\n                expectedKind: string;\n                transactionPlanResult: unknown;\n            };\n            [SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_ACCOUNTS]: {\n                data?: ReadonlyUint8Array;\n                programAddress: string;\n            };\n            [SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_DATA]: {\n                accountAddresses?: readonly string[];\n                programAddress: string;\n            };\n            [SOLANA_ERROR__INSTRUCTION__PROGRAM_ID_MISMATCH]: {\n                actualProgramAddress: string;\n                expectedProgramAddress: string;\n            };\n            [SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__INVALID_NONCE]: {\n                actualNonceValue: string;\n                expectedNonceValue: string;\n            };\n            [SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING]: {\n                cacheKey: string;\n            };\n            [SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED]: {\n                channelName: string;\n                supportedChannelNames: readonly string[];\n            };\n            [SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND]: {\n                kind: string;\n            };\n            [SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND]: {\n                kind: string;\n            };\n            [SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE]: {\n                unexpectedValue: unknown;\n            };\n            [SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__INVALID_PARAMS]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__INVALID_REQUEST]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__PARSE_ERROR]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SCAN_ERROR]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE]: {\n                currentBlockHeight: bigint;\n                rewardsCompleteBlockHeight: bigint;\n                slot: bigint;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED]: {\n                contextSlot: bigint;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY]: {\n                numSlotsBehind?: number;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE]: Omit<\n                RpcSimulateTransactionResult,\n                'err'\n            >;\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY]: {\n                slot: bigint;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION]: {\n                __serverMessage: string;\n            };\n            [SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX]: {\n                character: string;\n                source: string;\n            };\n            [SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH]: {\n                byteLength: number;\n            };\n            [SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__MALFORMED_BIGINT_STRING]: {\n                value: string;\n            };\n            [SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR]: {\n                error: unknown;\n                message: string;\n            };\n            [SOLANA_ERROR__MALFORMED_NUMBER_STRING]: {\n                value: string;\n            };\n            [SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND]: {\n                nonceAccountAddress: string;\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE]: {\n                expectedAddresses: readonly string[];\n                unexpectedAddresses: readonly string[];\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH]: {\n                missingRequiredSigners: readonly string[];\n                unexpectedSigners: readonly string[];\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH]: {\n                actualLength: number;\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED]: {\n                actualBytes: number;\n                maxBytes: number;\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH]: {\n                actualMessageFormat: number;\n                expectedMessageFormat: number;\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH]: {\n                actualLength: number;\n                specifiedLength: number;\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH]: {\n                numRequiredSignatures: number;\n                signatoryAddresses: readonly string[];\n                signaturesLength: number;\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING]: {\n                addresses: readonly string[];\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE]: {\n                signatoriesWithInvalidSignatures: readonly string[];\n                signatoriesWithMissingSignatures: readonly string[];\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION]: {\n                actualVersion: number;\n                expectedVersion: number;\n            };\n            [SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED]: {\n                unsupportedVersion: number;\n            };\n            [SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT]: {\n                accountData: ReadonlyUint8Array;\n                programName: string;\n            };\n            [SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION]: {\n                instructionData: ReadonlyUint8Array;\n                programName: string;\n            };\n            [SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS]: {\n                actualAccountMetas: number;\n                expectedAccountMetas: number;\n            };\n            [SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL]: {\n                inputName: string;\n            };\n            [SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE]: {\n                expectedType: string;\n                inputName: string;\n            };\n            [SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_ACCOUNT_TYPE]: {\n                accountType: number | string;\n                programName: string;\n            };\n            [SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE]: {\n                instructionType: number | string;\n                programName: string;\n            };\n            [SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN]: {\n                notificationName: string;\n            };\n            [SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT]: {\n                errorEvent: Event;\n            };\n            [SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD]: {\n                method: string;\n                params: readonly unknown[];\n            };\n            [SOLANA_ERROR__RPC__INTEGER_OVERFLOW]: {\n                argumentLabel: string;\n                keyPath: readonly (number | string | symbol)[];\n                methodName: string;\n                optionalPathLabel: string;\n                path?: string;\n                value: bigint;\n            };\n            [SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR]: {\n                headers: Headers;\n                message: string;\n                statusCode: number;\n            };\n            [SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN]: {\n                headers: readonly string[];\n            };\n            [SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER]: {\n                address: string;\n            };\n            [SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION]: {\n                address: string;\n                supportedFeatures: string[];\n            };\n            [SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY]: {\n                key: CryptoKey;\n            };\n            [SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE]: {\n                value: bigint;\n            };\n            [SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION]: {\n                index: number;\n            };\n            [SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT]: {\n                accountIndex: number;\n            };\n            [SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED]: {\n                accountIndex: number;\n            };\n            [SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN]: {\n                errorName: string;\n                transactionErrorContext?: unknown;\n            };\n            [SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION]: {\n                expectedAddresses: readonly string[];\n                unexpectedAddresses: readonly string[];\n            };\n            [SOLANA_ERROR__TRANSACTION__ADDRESS_MISSING]: {\n                index: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT]: {\n                transactionSize: Bytes;\n                transactionSizeLimit: Bytes;\n            };\n            [SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING]: {\n                lookupTableAddresses: readonly string[];\n            };\n            [SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE]: {\n                highestKnownIndex: number;\n                highestRequestedIndex: number;\n                lookupTableAddress: string;\n            };\n            [SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND]: {\n                index: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT]: Omit<\n                RpcSimulateTransactionResult,\n                'err'\n            >;\n            [SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH]: {\n                numInstructionHeaders: number;\n                numInstructionPayloads: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS]: {\n                mask: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND]: {\n                actualKind: 'u32' | 'u64';\n                configName: string;\n                expectedKind: 'u32' | 'u64';\n            };\n            [SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX]: {\n                nonce: string;\n                nonceAccountIndex: number;\n                numberOfStaticAccounts: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES]: {\n                programAddress: string;\n            };\n            [SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE]: {\n                programAddress: string;\n            };\n            [SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES]: {\n                messageBytes: ReadonlyUint8Array;\n            };\n            [SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH]: {\n                numRequiredSignatures: number;\n                signaturesLength: number;\n                signerAddresses: readonly string[];\n            };\n            [SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE]: {\n                nonce: string;\n            };\n            [SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING]: {\n                addresses: readonly string[];\n            };\n            [SOLANA_ERROR__TRANSACTION__SIGNATURE_COUNT_TOO_HIGH_FOR_TRANSACTION_BYTES]: {\n                numExpectedSignatures: number;\n                transactionBytes: ReadonlyUint8Array;\n                transactionBytesLength: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION]: {\n                actualCount: number;\n                instructionIndex: number;\n                maxAllowed: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES]: {\n                actualCount: number;\n                maxAllowed: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS]: {\n                actualCount: number;\n                maxAllowed: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES]: {\n                actualCount: number;\n                maxAllowed: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED]: {\n                unsupportedVersion: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE]: {\n                actualVersion: number;\n            };\n            [SOLANA_ERROR__TRANSACTION__VERSION_ZERO_MUST_BE_ENCODED_WITH_SIGNATURES_FIRST]: {\n                firstByte: number;\n                transactionBytes: ReadonlyUint8Array;\n            };\n            [SOLANA_ERROR__WALLET__NOT_CONNECTED]: {\n                operation: string;\n            };\n            [SOLANA_ERROR__WALLET__NO_SIGNER_CONNECTED]: {\n                status: string;\n            };\n        }\n    >\n>;\n\nexport function decodeEncodedContext(encodedContext: string): object {\n    const decodedUrlString = __NODEJS__ ? Buffer.from(encodedContext, 'base64').toString('utf8') : atob(encodedContext);\n    return Object.fromEntries(new URLSearchParams(decodedUrlString).entries());\n}\n\nfunction encodeValue(value: unknown): string {\n    if (Array.isArray(value)) {\n        const commaSeparatedValues = value.map(encodeValue).join('%2C%20' /* \", \" */);\n        return '%5B' /* \"[\" */ + commaSeparatedValues + /* \"]\" */ '%5D';\n    } else if (typeof value === 'bigint') {\n        return `${value}n`;\n    } else {\n        return encodeURIComponent(\n            String(\n                value != null && Object.getPrototypeOf(value) === null\n                    ? // Plain objects with no prototype don't have a `toString` method.\n                      // Convert them before stringifying them.\n                      { ...(value as object) }\n                    : value,\n            ),\n        );\n    }\n}\n\nfunction encodeObjectContextEntry([key, value]: [string, unknown]): `${typeof key}=${string}` {\n    return `${key}=${encodeValue(value)}`;\n}\n\nexport function encodeContextObject(context: object): string {\n    const searchParamsString = Object.entries(context).map(encodeObjectContextEntry).join('&');\n    return __NODEJS__ ? Buffer.from(searchParamsString, 'utf8').toString('base64') : btoa(searchParamsString);\n}\n"
  },
  {
    "path": "packages/errors/src/error.ts",
    "content": "import { SolanaErrorCode, SolanaErrorCodeWithCause, SolanaErrorCodeWithDeprecatedCause } from './codes';\nimport { SolanaErrorContext } from './context';\nimport { getErrorMessage } from './message-formatter';\n\n/**\n * A variant of {@link SolanaError} where the `cause` property is deprecated.\n *\n * This type is returned by {@link isSolanaError} when checking for error codes in\n * {@link SolanaErrorCodeWithDeprecatedCause}. Accessing `cause` on these errors will show\n * a deprecation warning in IDEs that support JSDoc `@deprecated` tags.\n */\nexport interface SolanaErrorWithDeprecatedCause<\n    TErrorCode extends SolanaErrorCodeWithDeprecatedCause = SolanaErrorCodeWithDeprecatedCause,\n> extends Omit<SolanaError<TErrorCode>, 'cause'> {\n    /**\n     * @deprecated The `cause` property is deprecated for this error code.\n     * Use the error's `context` property instead to access relevant error information.\n     */\n    readonly cause?: unknown;\n}\n\n/**\n * A type guard that returns `true` if the input is a {@link SolanaError}, optionally with a\n * particular error code.\n *\n * When the `code` argument is supplied and the input is a {@link SolanaError}, TypeScript will\n * refine the error's {@link SolanaError#context | `context`} property to the type associated with\n * that error code. You can use that context to render useful error messages, or to make\n * context-aware decisions that help your application to recover from the error.\n *\n * @example\n * ```ts\n * import {\n *     SOLANA_ERROR__TRANSACTION__MISSING_SIGNATURE,\n *     SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n *     isSolanaError,\n * } from '@solana/errors';\n * import { assertIsFullySignedTransaction, getSignatureFromTransaction } from '@solana/transactions';\n *\n * try {\n *     const transactionSignature = getSignatureFromTransaction(tx);\n *     assertIsFullySignedTransaction(tx);\n *     /* ... *\\/\n * } catch (e) {\n *     if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n *         displayError(\n *             \"We can't send this transaction without signatures for these addresses:\\n- %s\",\n *             // The type of the `context` object is now refined to contain `addresses`.\n *             e.context.addresses.join('\\n- '),\n *         );\n *         return;\n *     } else if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING)) {\n *         if (!tx.feePayer) {\n *             displayError('Choose a fee payer for this transaction before sending it');\n *         } else {\n *             displayError('The fee payer still needs to sign for this transaction');\n *         }\n *         return;\n *     }\n *     throw e;\n * }\n * ```\n */\nexport function isSolanaError<TErrorCode extends SolanaErrorCodeWithDeprecatedCause>(\n    e: unknown,\n    code: TErrorCode,\n): e is SolanaErrorWithDeprecatedCause<TErrorCode>;\nexport function isSolanaError<TErrorCode extends SolanaErrorCode>(\n    e: unknown,\n    code?: TErrorCode,\n): e is SolanaError<TErrorCode>;\nexport function isSolanaError<TErrorCode extends SolanaErrorCode>(\n    e: unknown,\n    /**\n     * When supplied, this function will require that the input is a {@link SolanaError} _and_ that\n     * its error code is exactly this value.\n     */\n    code?: TErrorCode,\n): e is SolanaError<TErrorCode> {\n    const isSolanaError = e instanceof Error && e.name === 'SolanaError';\n    if (isSolanaError) {\n        if (code !== undefined) {\n            return (e as SolanaError<TErrorCode>).context.__code === code;\n        }\n        return true;\n    }\n    return false;\n}\n\ntype SolanaErrorCodedContext = {\n    [P in SolanaErrorCode]: Readonly<{\n        __code: P;\n    }> &\n        (SolanaErrorContext[P] extends undefined ? object : SolanaErrorContext[P]);\n};\n\n/**\n * Encapsulates an error's stacktrace, a Solana-specific numeric code that indicates what went\n * wrong, and optional context if the type of error indicated by the code supports it.\n */\nexport class SolanaError<TErrorCode extends SolanaErrorCode = SolanaErrorCode> extends Error {\n    /**\n     * Indicates the root cause of this {@link SolanaError}, if any.\n     *\n     * For example, a transaction error might have an instruction error as its root cause. In this\n     * case, you will be able to access the instruction error on the transaction error as `cause`.\n     */\n    readonly cause?: TErrorCode extends SolanaErrorCodeWithCause ? SolanaError : unknown = this.cause;\n    /**\n     * Contains context that can assist in understanding or recovering from a {@link SolanaError}.\n     */\n    readonly context: SolanaErrorCodedContext[TErrorCode];\n    constructor(\n        ...[code, contextAndErrorOptions]: SolanaErrorContext[TErrorCode] extends undefined\n            ? [code: TErrorCode, errorOptions?: ErrorOptions | undefined]\n            : [code: TErrorCode, contextAndErrorOptions: SolanaErrorContext[TErrorCode] & (ErrorOptions | undefined)]\n    ) {\n        let context: SolanaErrorContext[TErrorCode] | undefined;\n        let errorOptions: ErrorOptions | undefined;\n        if (contextAndErrorOptions) {\n            Object.entries(Object.getOwnPropertyDescriptors(contextAndErrorOptions)).forEach(([name, descriptor]) => {\n                // If the `ErrorOptions` type ever changes, update this code.\n                if (name === 'cause') {\n                    errorOptions = { cause: descriptor.value };\n                } else {\n                    if (context === undefined) {\n                        context = {\n                            __code: code,\n                        } as unknown as SolanaErrorContext[TErrorCode];\n                    }\n                    Object.defineProperty(context, name, descriptor);\n                }\n            });\n        }\n        const message = getErrorMessage(code, context);\n        super(message, errorOptions);\n        this.context = Object.freeze(\n            context === undefined\n                ? {\n                      __code: code,\n                  }\n                : context,\n        ) as SolanaErrorCodedContext[TErrorCode];\n        // This is necessary so that `isSolanaError()` can identify a `SolanaError` without having\n        // to import the class for use in an `instanceof` check.\n        this.name = 'SolanaError';\n    }\n}\n"
  },
  {
    "path": "packages/errors/src/index.ts",
    "content": "/**\n * This package brings together every error message across all Solana JavaScript modules.\n *\n * # Reading error messages\n *\n * ## In development mode\n *\n * When your bundler sets the constant `__DEV__` to `true`, every error message will be included in\n * the bundle. As such, you will be able to read them in plain language wherever they appear.\n *\n * > [!WARNING]\n * > The size of your JavaScript bundle will increase significantly with the inclusion of every\n * > error message in development mode. Be sure to build your bundle with `__DEV__` set to `false`\n * > when you go to production.\n *\n * ## In production mode\n *\n * When your bundler sets the constant `__DEV__` to `false`, error messages will be stripped from\n * the bundle to save space. Only the error code will appear when an error is encountered. Follow\n * the instructions in the error message to convert the error code back to the human-readable error\n * message.\n *\n * For instance, to recover the error text for the error with code `123`:\n *\n * ```package-install\n * npx @solana/errors decode -- 123\n * ```\n *\n * > [!IMPORTANT]\n * > The string representation of a {@link SolanaError} should not be shown to users. Developers\n * > should use {@link isSolanaError} to distinguish the type of a thrown error, then show a custom,\n * > localized error message appropriate for their application's audience. Custom error messages\n * > should use the error's {@link SolanaError#context | `context`} if it would help the reader\n * > understand what happened and/or what to do next.\n *\n * # Adding a new error\n *\n * 1. Add a new exported error code constant to `src/codes.ts`.\n * 2. Add that new constant to the {@link SolanaErrorCode} union in `src/codes.ts`.\n * 3. If you would like the new error to encapsulate context about the error itself (eg. the public\n *    keys for which a transaction is missing signatures) define the shape of that context in\n *    `src/context.ts`.\n * 4. Add the error's message to `src/messages.ts`. Any context values that you defined above will\n *    be interpolated into the message wherever you write `$key`, where `key` is the index of a\n *    value in the context (eg. ``'Missing a signature for account `$address`'``).\n * 5. Publish a new version of `@solana/errors`.\n * 6. Bump the version of `@solana/errors` in the package from which the error is thrown.\n *\n * # Removing an error message\n *\n * -   Don't remove errors.\n * -   Don't change the meaning of an error message.\n * -   Don't change or reorder error codes.\n * -   Don't change or remove members of an error's context.\n *\n * When an older client throws an error, we want to make sure that they can always decode the error.\n * If you make any of the changes above, old clients will, by definition, not have received your\n * changes. This could make the errors that they throw impossible to decode going forward.\n *\n * # Catching errors\n *\n * See {@link isSolanaError} for an example of how to handle a caught {@link SolanaError}.\n *\n * @packageDocumentation\n */\nexport * from './codes';\nexport * from './error';\nexport * from './instruction-error';\nexport * from './json-rpc-error';\nexport * from './simulation-errors';\nexport * from './stack-trace';\nexport * from './transaction-error';\n"
  },
  {
    "path": "packages/errors/src/instruction-error.ts",
    "content": "import { SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN } from './codes';\nimport { SolanaError } from './error';\nimport { getSolanaErrorFromRpcError } from './rpc-enum-errors';\n\nconst ORDERED_ERROR_NAMES = [\n    // Keep synced with RPC source: https://github.com/anza-xyz/solana-sdk/blob/master/instruction-error/src/lib.rs\n    // If this list ever gets too large, consider implementing a compression strategy like this:\n    // https://gist.github.com/steveluscher/aaa7cbbb5433b1197983908a40860c47\n    'GenericError',\n    'InvalidArgument',\n    'InvalidInstructionData',\n    'InvalidAccountData',\n    'AccountDataTooSmall',\n    'InsufficientFunds',\n    'IncorrectProgramId',\n    'MissingRequiredSignature',\n    'AccountAlreadyInitialized',\n    'UninitializedAccount',\n    'UnbalancedInstruction',\n    'ModifiedProgramId',\n    'ExternalAccountLamportSpend',\n    'ExternalAccountDataModified',\n    'ReadonlyLamportChange',\n    'ReadonlyDataModified',\n    'DuplicateAccountIndex',\n    'ExecutableModified',\n    'RentEpochModified',\n    'NotEnoughAccountKeys',\n    'AccountDataSizeChanged',\n    'AccountNotExecutable',\n    'AccountBorrowFailed',\n    'AccountBorrowOutstanding',\n    'DuplicateAccountOutOfSync',\n    'Custom',\n    'InvalidError',\n    'ExecutableDataModified',\n    'ExecutableLamportChange',\n    'ExecutableAccountNotRentExempt',\n    'UnsupportedProgramId',\n    'CallDepth',\n    'MissingAccount',\n    'ReentrancyNotAllowed',\n    'MaxSeedLengthExceeded',\n    'InvalidSeeds',\n    'InvalidRealloc',\n    'ComputationalBudgetExceeded',\n    'PrivilegeEscalation',\n    'ProgramEnvironmentSetupFailure',\n    'ProgramFailedToComplete',\n    'ProgramFailedToCompile',\n    'Immutable',\n    'IncorrectAuthority',\n    'BorshIoError',\n    'AccountNotRentExempt',\n    'InvalidAccountOwner',\n    'ArithmeticOverflow',\n    'UnsupportedSysvar',\n    'IllegalOwner',\n    'MaxAccountsDataAllocationsExceeded',\n    'MaxAccountsExceeded',\n    'MaxInstructionTraceLengthExceeded',\n    'BuiltinProgramsMustConsumeComputeUnits',\n];\n\nexport function getSolanaErrorFromInstructionError(\n    /**\n     * The index of the instruction inside the transaction.\n     */\n    index: bigint | number,\n    instructionError: string | { [key: string]: unknown },\n): SolanaError {\n    const numberIndex = Number(index);\n    return getSolanaErrorFromRpcError(\n        {\n            errorCodeBaseOffset: 4615001,\n            getErrorContext(errorCode, rpcErrorName, rpcErrorContext) {\n                if (errorCode === SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN) {\n                    return {\n                        errorName: rpcErrorName,\n                        index: numberIndex,\n                        ...(rpcErrorContext !== undefined ? { instructionErrorContext: rpcErrorContext } : null),\n                    };\n                } else if (errorCode === SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM) {\n                    return {\n                        code: Number(rpcErrorContext as bigint | number),\n                        index: numberIndex,\n                    };\n                }\n                return { index: numberIndex };\n            },\n            orderedErrorNames: ORDERED_ERROR_NAMES,\n            rpcEnumError: instructionError,\n        },\n        getSolanaErrorFromInstructionError,\n    );\n}\n"
  },
  {
    "path": "packages/errors/src/json-rpc-error.ts",
    "content": "import {\n    SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR,\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__INVALID_REQUEST,\n    SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND,\n    SOLANA_ERROR__JSON_RPC__PARSE_ERROR,\n    SOLANA_ERROR__JSON_RPC__SCAN_ERROR,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION,\n    SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR,\n    SolanaErrorCode,\n} from './codes';\nimport { SolanaErrorContext } from './context';\nimport { SolanaError } from './error';\nimport { safeCaptureStackTrace } from './stack-trace';\nimport { getSolanaErrorFromTransactionError } from './transaction-error';\n\ninterface RpcErrorResponse {\n    code: bigint | number;\n    data?: unknown;\n    message: string;\n}\n\ntype TransactionError = string | { [key: string]: unknown };\n\n/**\n * Keep in sync with https://github.com/anza-xyz/agave/blob/master/rpc-client-types/src/response.rs\n * @hidden\n */\nexport interface RpcSimulateTransactionResult {\n    accounts:\n        | ({\n              data:\n                  | string // LegacyBinary\n                  | {\n                        // Json\n                        parsed: unknown;\n                        program: string;\n                        space: bigint;\n                    }\n                  // Binary\n                  | [encodedBytes: string, encoding: 'base58' | 'base64' | 'base64+zstd' | 'binary' | 'jsonParsed'];\n              executable: boolean;\n              lamports: bigint;\n              owner: string;\n              rentEpoch: bigint;\n              space?: bigint;\n          } | null)[]\n        | null;\n    err: TransactionError | null;\n    fee: bigint | null;\n    // Enabled by `enable_cpi_recording`\n    innerInstructions?:\n        | {\n              index: number;\n              instructions: (\n                  | {\n                        // Compiled\n                        accounts: number[];\n                        data: string;\n                        programIdIndex: number;\n                        stackHeight?: number;\n                    }\n                  | {\n                        // Parsed\n                        parsed: unknown;\n                        program: string;\n                        programId: string;\n                        stackHeight?: number;\n                    }\n                  | {\n                        // PartiallyDecoded\n                        accounts: string[];\n                        data: string;\n                        programId: string;\n                        stackHeight?: number;\n                    }\n              )[];\n          }[]\n        | null;\n    loadedAccountsDataSize: number | null;\n    loadedAddresses: {\n        readonly: readonly string[];\n        writable: readonly string[];\n    } | null;\n    logs: string[] | null;\n    postBalances: bigint[] | null;\n    postTokenBalances: unknown[] | null;\n    preBalances: bigint[] | null;\n    preTokenBalances: unknown[] | null;\n    replacementBlockhash: string | null;\n    returnData: {\n        data: [string, 'base64'];\n        programId: string;\n    } | null;\n    unitsConsumed: bigint | null;\n}\n\nexport function getSolanaErrorFromJsonRpcError(putativeErrorResponse: unknown): SolanaError {\n    let out: SolanaError;\n    if (isRpcErrorResponse(putativeErrorResponse)) {\n        const { code: rawCode, data, message } = putativeErrorResponse;\n        const code = Number(rawCode);\n        if (code === SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE) {\n            const { err, ...preflightErrorContext } = data as RpcSimulateTransactionResult;\n            const causeObject = err ? { cause: getSolanaErrorFromTransactionError(err) } : null;\n            out = new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE, {\n                ...preflightErrorContext,\n                ...causeObject,\n            });\n        } else {\n            let errorContext;\n            switch (code) {\n                case SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR:\n                case SOLANA_ERROR__JSON_RPC__INVALID_PARAMS:\n                case SOLANA_ERROR__JSON_RPC__INVALID_REQUEST:\n                case SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND:\n                case SOLANA_ERROR__JSON_RPC__PARSE_ERROR:\n                case SOLANA_ERROR__JSON_RPC__SCAN_ERROR:\n                case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP:\n                case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE:\n                case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET:\n                case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX:\n                case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED:\n                case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED:\n                case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE:\n                case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION:\n                    // The server supplies no structured data, but rather a pre-formatted message. Put\n                    // the server message in `context` so as not to completely lose the data. The long\n                    // term fix for this is to add data to the server responses and modify the\n                    // messages in `@solana/errors` to be actual format strings.\n                    errorContext = { __serverMessage: message };\n                    break;\n                default:\n                    if (typeof data === 'object' && !Array.isArray(data)) {\n                        errorContext = data;\n                    }\n            }\n            out = new SolanaError(code as SolanaErrorCode, errorContext as SolanaErrorContext[SolanaErrorCode]);\n        }\n    } else {\n        const message =\n            typeof putativeErrorResponse === 'object' &&\n            putativeErrorResponse !== null &&\n            'message' in putativeErrorResponse &&\n            typeof putativeErrorResponse.message === 'string'\n                ? putativeErrorResponse.message\n                : 'Malformed JSON-RPC error with no message attribute';\n        out = new SolanaError(SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR, { error: putativeErrorResponse, message });\n    }\n    safeCaptureStackTrace(out, getSolanaErrorFromJsonRpcError);\n    return out;\n}\n\nfunction isRpcErrorResponse(value: unknown): value is RpcErrorResponse {\n    return (\n        typeof value === 'object' &&\n        value !== null &&\n        'code' in value &&\n        'message' in value &&\n        (typeof value.code === 'number' || typeof value.code === 'bigint') &&\n        typeof value.message === 'string'\n    );\n}\n"
  },
  {
    "path": "packages/errors/src/message-formatter.ts",
    "content": "import { SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN, SolanaErrorCode } from './codes';\nimport { encodeContextObject } from './context';\nimport { SolanaErrorMessages } from './messages';\n\nconst INSTRUCTION_ERROR_RANGE_SIZE = 1000;\n\nconst enum StateType {\n    EscapeSequence,\n    Text,\n    Variable,\n}\ntype State = Readonly<{\n    [START_INDEX]: number;\n    [TYPE]: StateType;\n}>;\nconst START_INDEX = 'i';\nconst TYPE = 't';\n\nexport function getHumanReadableErrorMessage<TErrorCode extends SolanaErrorCode>(\n    code: TErrorCode,\n    context: object = {},\n): string {\n    const messageFormatString = SolanaErrorMessages[code];\n    if (messageFormatString.length === 0) {\n        return '';\n    }\n    let state: State;\n    function commitStateUpTo(endIndex?: number) {\n        if (state[TYPE] === StateType.Variable) {\n            const variableName = messageFormatString.slice(state[START_INDEX] + 1, endIndex);\n\n            fragments.push(\n                variableName in context\n                    ? // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n                      `${context[variableName as keyof typeof context]}`\n                    : `$${variableName}`,\n            );\n        } else if (state[TYPE] === StateType.Text) {\n            fragments.push(messageFormatString.slice(state[START_INDEX], endIndex));\n        }\n    }\n    const fragments: string[] = [];\n    messageFormatString.split('').forEach((char, ii) => {\n        if (ii === 0) {\n            state = {\n                [START_INDEX]: 0,\n                [TYPE]:\n                    messageFormatString[0] === '\\\\'\n                        ? StateType.EscapeSequence\n                        : messageFormatString[0] === '$'\n                          ? StateType.Variable\n                          : StateType.Text,\n            };\n            return;\n        }\n        let nextState;\n        switch (state[TYPE]) {\n            case StateType.EscapeSequence:\n                nextState = { [START_INDEX]: ii, [TYPE]: StateType.Text };\n                break;\n            case StateType.Text:\n                if (char === '\\\\') {\n                    nextState = { [START_INDEX]: ii, [TYPE]: StateType.EscapeSequence };\n                } else if (char === '$') {\n                    nextState = { [START_INDEX]: ii, [TYPE]: StateType.Variable };\n                }\n                break;\n            case StateType.Variable:\n                if (char === '\\\\') {\n                    nextState = { [START_INDEX]: ii, [TYPE]: StateType.EscapeSequence };\n                } else if (char === '$') {\n                    nextState = { [START_INDEX]: ii, [TYPE]: StateType.Variable };\n                } else if (!char.match(/\\w/)) {\n                    nextState = { [START_INDEX]: ii, [TYPE]: StateType.Text };\n                }\n                break;\n        }\n        if (nextState) {\n            if (state !== nextState) {\n                commitStateUpTo(ii);\n            }\n            state = nextState;\n        }\n    });\n    commitStateUpTo();\n    let message = fragments.join('');\n    if (\n        code >= SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN &&\n        code < SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN + INSTRUCTION_ERROR_RANGE_SIZE &&\n        'index' in context\n    ) {\n        message += ` (instruction #${(context as { index: number }).index + 1})`;\n    }\n    return message;\n}\n\nexport function getErrorMessage<TErrorCode extends SolanaErrorCode>(\n    code: TErrorCode,\n    context: Record<string, unknown> = {},\n): string {\n    if (__DEV__) {\n        return getHumanReadableErrorMessage(code, context);\n    } else {\n        let decodingAdviceMessage = `Solana error #${code}; Decode this error by running \\`npx @solana/errors decode -- ${code}`;\n        if (Object.keys(context).length) {\n            /**\n             * DANGER: Be sure that the shell command is escaped in such a way that makes it\n             *         impossible for someone to craft malicious context values that would result in\n             *         an exploit against anyone who bindly copy/pastes it into their terminal.\n             */\n            decodingAdviceMessage += ` '${encodeContextObject(context)}'`;\n        }\n        return `${decodingAdviceMessage}\\``;\n    }\n}\n"
  },
  {
    "path": "packages/errors/src/messages.ts",
    "content": "/* eslint-disable sort-keys-fix/sort-keys-fix */\n/**\n * To add a new error, follow the instructions at\n * https://github.com/anza-xyz/kit/tree/main/packages/errors#adding-a-new-error\n *\n * WARNING:\n *   - Don't change the meaning of an error message.\n */\nimport {\n    SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED,\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT,\n    SOLANA_ERROR__ACCOUNTS__FAILED_TO_DECODE_ACCOUNT,\n    SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND,\n    SOLANA_ERROR__ADDRESSES__FAILED_TO_FIND_VIABLE_PDA_BUMP_SEED,\n    SOLANA_ERROR__ADDRESSES__INVALID_BASE58_ENCODED_ADDRESS,\n    SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__ADDRESSES__INVALID_ED25519_PUBLIC_KEY,\n    SOLANA_ERROR__ADDRESSES__INVALID_OFF_CURVE_ADDRESS,\n    SOLANA_ERROR__ADDRESSES__INVALID_SEEDS_POINT_ON_CURVE,\n    SOLANA_ERROR__ADDRESSES__MALFORMED_PDA,\n    SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED,\n    SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED,\n    SOLANA_ERROR__ADDRESSES__PDA_BUMP_SEED_OUT_OF_RANGE,\n    SOLANA_ERROR__ADDRESSES__PDA_ENDS_WITH_PDA_MARKER,\n    SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED,\n    SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY,\n    SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS,\n    SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL,\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH,\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH,\n    SOLANA_ERROR__CODECS__ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH,\n    SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY,\n    SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH,\n    SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH,\n    SOLANA_ERROR__CODECS__EXPECTED_VARIABLE_LENGTH,\n    SOLANA_ERROR__CODECS__EXPECTED_ZERO_VALUE_TO_MATCH_ITEM_FIXED_SIZE,\n    SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__CODECS__INVALID_CONSTANT,\n    SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT,\n    SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT,\n    SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT,\n    SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS,\n    SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES,\n    SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE,\n    SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE,\n    SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES,\n    SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE,\n    SOLANA_ERROR__CRYPTO__RANDOM_VALUES_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS,\n    SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO,\n    SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_STRING,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO,\n    SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SOLANA_ERROR__FS__UNSUPPORTED_ENVIRONMENT,\n    SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_ACCOUNTS,\n    SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_DATA,\n    SOLANA_ERROR__INSTRUCTION__PROGRAM_ID_MISMATCH,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_ALREADY_INITIALIZED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_FAILED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_OUTSTANDING,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_SIZE_CHANGED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_TOO_SMALL,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_EXECUTABLE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_RENT_EXEMPT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR,\n    SOLANA_ERROR__INSTRUCTION_ERROR__BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS,\n    SOLANA_ERROR__INSTRUCTION_ERROR__CALL_DEPTH,\n    SOLANA_ERROR__INSTRUCTION_ERROR__COMPUTATIONAL_BUDGET_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM,\n    SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_INDEX,\n    SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_OUT_OF_SYNC,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_DATA_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_LAMPORT_CHANGE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_DATA_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_LAMPORT_SPEND,\n    SOLANA_ERROR__INSTRUCTION_ERROR__GENERIC_ERROR,\n    SOLANA_ERROR__INSTRUCTION_ERROR__ILLEGAL_OWNER,\n    SOLANA_ERROR__INSTRUCTION_ERROR__IMMUTABLE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_AUTHORITY,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_PROGRAM_ID,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_DATA,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_OWNER,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ERROR,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_INSTRUCTION_DATA,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_REALLOC,\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_SEEDS,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MAX_SEED_LENGTH_EXCEEDED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_ACCOUNT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_REQUIRED_SIGNATURE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__MODIFIED_PROGRAM_ID,\n    SOLANA_ERROR__INSTRUCTION_ERROR__NOT_ENOUGH_ACCOUNT_KEYS,\n    SOLANA_ERROR__INSTRUCTION_ERROR__PRIVILEGE_ESCALATION,\n    SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_ENVIRONMENT_SETUP_FAILURE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPILE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPLETE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_DATA_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_LAMPORT_CHANGE,\n    SOLANA_ERROR__INSTRUCTION_ERROR__REENTRANCY_NOT_ALLOWED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__RENT_EPOCH_MODIFIED,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNBALANCED_INSTRUCTION,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNINITIALIZED_ACCOUNT,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_PROGRAM_ID,\n    SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_SYSVAR,\n    SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE,\n    SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED,\n    SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT,\n    SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH,\n    SOLANA_ERROR__INVALID_NONCE,\n    SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING,\n    SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED,\n    SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND,\n    SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND,\n    SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n    SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n    SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE,\n    SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR,\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__INVALID_REQUEST,\n    SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND,\n    SOLANA_ERROR__JSON_RPC__PARSE_ERROR,\n    SOLANA_ERROR__JSON_RPC__SCAN_ERROR,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NO_SNAPSHOT,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_LEN_MISMATCH,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION,\n    SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX,\n    SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n    SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT,\n    SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE,\n    SOLANA_ERROR__MALFORMED_BIGINT_STRING,\n    SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR,\n    SOLANA_ERROR__MALFORMED_NUMBER_STRING,\n    SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_SORTED,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED,\n    SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT,\n    SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION,\n    SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS,\n    SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL,\n    SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE,\n    SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_ACCOUNT_TYPE,\n    SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE,\n    SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD,\n    SOLANA_ERROR__RPC__INTEGER_OVERFLOW,\n    SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR,\n    SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__EXPECTED_SERVER_SUBSCRIPTION_ID,\n    SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS,\n    SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER,\n    SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER,\n    SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS,\n    SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING,\n    SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION,\n    SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY,\n    SOLANA_ERROR__SUBTLE_CRYPTO__DIGEST_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT,\n    SOLANA_ERROR__SUBTLE_CRYPTO__ED25519_ALGORITHM_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__EXPORT_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__GENERATE_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__SIGN_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__SUBTLE_CRYPTO__VERIFY_FUNCTION_UNIMPLEMENTED,\n    SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE,\n    SOLANA_ERROR__TRANSACTION__ADDRESS_MISSING,\n    SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,\n    SOLANA_ERROR__TRANSACTION__CANNOT_DECODE_EMPTY_TRANSACTION_BYTES,\n    SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_MESSAGE_BYTES,\n    SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES,\n    SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT,\n    SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME,\n    SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT,\n    SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n    SOLANA_ERROR__TRANSACTION__FEE_PAYER_MISSING,\n    SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n    SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH,\n    SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS,\n    SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND,\n    SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX,\n    SOLANA_ERROR__TRANSACTION__INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_MUST_BE_ADVANCE_NONCE,\n    SOLANA_ERROR__TRANSACTION__INVALID_NONCE_TRANSACTION_INSTRUCTIONS_MISSING,\n    SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES,\n    SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,\n    SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES,\n    SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH,\n    SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n    SOLANA_ERROR__TRANSACTION__SIGNATURE_COUNT_TOO_HIGH_FOR_TRANSACTION_BYTES,\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE,\n    SOLANA_ERROR__TRANSACTION__VERSION_ZERO_MUST_BE_ENCODED_WITH_SIGNATURES_FIRST,\n    SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_BORROW_OUTSTANDING,\n    SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_IN_USE,\n    SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_LOADED_TWICE,\n    SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION_ERROR__ADDRESS_LOOKUP_TABLE_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION_ERROR__ALREADY_PROCESSED,\n    SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION_ERROR__CALL_CHAIN_TOO_DEEP,\n    SOLANA_ERROR__TRANSACTION_ERROR__CLUSTER_MAINTENANCE,\n    SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ACCOUNT_FOR_FEE,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ACCOUNT_INDEX,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_DATA,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_INDEX,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_OWNER,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_LOADED_ACCOUNTS_DATA_SIZE_LIMIT,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_PROGRAM_FOR_EXECUTION,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_RENT_PAYING_ACCOUNT,\n    SOLANA_ERROR__TRANSACTION_ERROR__INVALID_WRITABLE_ACCOUNT,\n    SOLANA_ERROR__TRANSACTION_ERROR__MAX_LOADED_ACCOUNTS_DATA_SIZE_EXCEEDED,\n    SOLANA_ERROR__TRANSACTION_ERROR__MISSING_SIGNATURE_FOR_FEE,\n    SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED,\n    SOLANA_ERROR__TRANSACTION_ERROR__RESANITIZATION_NEEDED,\n    SOLANA_ERROR__TRANSACTION_ERROR__SANITIZE_FAILURE,\n    SOLANA_ERROR__TRANSACTION_ERROR__SIGNATURE_FAILURE,\n    SOLANA_ERROR__TRANSACTION_ERROR__TOO_MANY_ACCOUNT_LOCKS,\n    SOLANA_ERROR__TRANSACTION_ERROR__UNBALANCED_TRANSACTION,\n    SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN,\n    SOLANA_ERROR__TRANSACTION_ERROR__UNSUPPORTED_VERSION,\n    SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT,\n    SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT,\n    SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_ACCOUNT_COST_LIMIT,\n    SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_BLOCK_COST_LIMIT,\n    SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_VOTE_COST_LIMIT,\n    SOLANA_ERROR__WALLET__NO_SIGNER_CONNECTED,\n    SOLANA_ERROR__WALLET__NOT_CONNECTED,\n    SOLANA_ERROR__WALLET__SIGNER_NOT_AVAILABLE,\n    SolanaErrorCode,\n} from './codes';\n\n/**\n * A map of every {@link SolanaError} code to the error message shown to developers in development\n * mode.\n */\nexport const SolanaErrorMessages: Readonly<{\n    // This type makes this data structure exhaustive with respect to `SolanaErrorCode`.\n    // TypeScript will fail to build this project if add an error code without a message.\n    [P in SolanaErrorCode]: string;\n}> = {\n    [SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND]: 'Account not found at address: $address',\n    [SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED]:\n        'Not all accounts were decoded. Encoded accounts found at addresses: $addresses.',\n    [SOLANA_ERROR__ACCOUNTS__EXPECTED_DECODED_ACCOUNT]: 'Expected decoded account at address: $address',\n    [SOLANA_ERROR__ACCOUNTS__FAILED_TO_DECODE_ACCOUNT]: 'Failed to decode account data at address: $address',\n    [SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND]: 'Accounts not found at addresses: $addresses',\n    [SOLANA_ERROR__ADDRESSES__FAILED_TO_FIND_VIABLE_PDA_BUMP_SEED]:\n        'Unable to find a viable program address bump seed.',\n    [SOLANA_ERROR__ADDRESSES__INVALID_BASE58_ENCODED_ADDRESS]: '$putativeAddress is not a base58-encoded address.',\n    [SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH]:\n        'Expected base58 encoded address to decode to a byte array of length 32. Actual length: $actualLength.',\n    [SOLANA_ERROR__ADDRESSES__INVALID_ED25519_PUBLIC_KEY]: 'The `CryptoKey` must be an `Ed25519` public key.',\n    [SOLANA_ERROR__ADDRESSES__INVALID_OFF_CURVE_ADDRESS]:\n        '$putativeOffCurveAddress is not a base58-encoded off-curve address.',\n    [SOLANA_ERROR__ADDRESSES__INVALID_SEEDS_POINT_ON_CURVE]: 'Invalid seeds; point must fall off the Ed25519 curve.',\n    [SOLANA_ERROR__ADDRESSES__MALFORMED_PDA]:\n        'Expected given program derived address to have the following format: [Address, ProgramDerivedAddressBump].',\n    [SOLANA_ERROR__ADDRESSES__MAX_NUMBER_OF_PDA_SEEDS_EXCEEDED]:\n        'A maximum of $maxSeeds seeds, including the bump seed, may be supplied when creating an address. Received: $actual.',\n    [SOLANA_ERROR__ADDRESSES__MAX_PDA_SEED_LENGTH_EXCEEDED]:\n        'The seed at index $index with length $actual exceeds the maximum length of $maxSeedLength bytes.',\n    [SOLANA_ERROR__ADDRESSES__PDA_BUMP_SEED_OUT_OF_RANGE]:\n        'Expected program derived address bump to be in the range [0, 255], got: $bump.',\n    [SOLANA_ERROR__ADDRESSES__PDA_ENDS_WITH_PDA_MARKER]: 'Program address cannot end with PDA marker.',\n    [SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE]:\n        'Expected base58-encoded address string of length in the range [32, 44]. Actual length: $actualLength.',\n    [SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE]:\n        'Expected base58-encoded blockhash string of length in the range [32, 44]. Actual length: $actualLength.',\n    [SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED]:\n        'The network has progressed past the last block for which this transaction could have been committed.',\n    [SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY]:\n        'Codec [$codecDescription] cannot decode empty byte arrays.',\n    [SOLANA_ERROR__CODECS__CANNOT_USE_LEXICAL_VALUES_AS_ENUM_DISCRIMINATORS]:\n        'Enum codec cannot use lexical values [$stringValues] as discriminators. Either remove all lexical values or set `useValuesAsDiscriminators` to `false`.',\n    [SOLANA_ERROR__CODECS__ENCODED_BYTES_MUST_NOT_INCLUDE_SENTINEL]:\n        'Sentinel [$hexSentinel] must not be present in encoded bytes [$hexEncodedBytes].',\n    [SOLANA_ERROR__CODECS__ENCODER_DECODER_FIXED_SIZE_MISMATCH]:\n        'Encoder and decoder must have the same fixed size, got [$encoderFixedSize] and [$decoderFixedSize].',\n    [SOLANA_ERROR__CODECS__ENCODER_DECODER_MAX_SIZE_MISMATCH]:\n        'Encoder and decoder must have the same max size, got [$encoderMaxSize] and [$decoderMaxSize].',\n    [SOLANA_ERROR__CODECS__ENCODER_DECODER_SIZE_COMPATIBILITY_MISMATCH]:\n        'Encoder and decoder must either both be fixed-size or variable-size.',\n    [SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE]:\n        'Enum discriminator out of range. Expected a number in [$formattedValidDiscriminators], got $discriminator.',\n    [SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH]: 'Expected a fixed-size codec, got a variable-size one.',\n    [SOLANA_ERROR__CODECS__EXPECTED_POSITIVE_BYTE_LENGTH]:\n        'Codec [$codecDescription] expected a positive byte length, got $bytesLength.',\n    [SOLANA_ERROR__CODECS__EXPECTED_VARIABLE_LENGTH]: 'Expected a variable-size codec, got a fixed-size one.',\n    [SOLANA_ERROR__CODECS__EXPECTED_ZERO_VALUE_TO_MATCH_ITEM_FIXED_SIZE]:\n        'Codec [$codecDescription] expected zero-value [$hexZeroValue] to have the same size as the provided fixed-size item [$expectedSize bytes].',\n    [SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH]:\n        'Codec [$codecDescription] expected $expected bytes, got $bytesLength.',\n    [SOLANA_ERROR__CODECS__INVALID_CONSTANT]:\n        'Expected byte array constant [$hexConstant] to be present in data [$hexData] at offset [$offset].',\n    [SOLANA_ERROR__CODECS__INVALID_DISCRIMINATED_UNION_VARIANT]:\n        'Invalid discriminated union variant. Expected one of [$variants], got $value.',\n    [SOLANA_ERROR__CODECS__INVALID_ENUM_VARIANT]:\n        'Invalid enum variant. Expected one of [$stringValues] or a number in [$formattedNumericalValues], got $variant.',\n    [SOLANA_ERROR__CODECS__INVALID_LITERAL_UNION_VARIANT]:\n        'Invalid literal union variant. Expected one of [$variants], got $value.',\n    [SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS]:\n        'Expected [$codecDescription] to have $expected items, got $actual.',\n    [SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE]: 'Invalid value $value for base $base with alphabet $alphabet.',\n    [SOLANA_ERROR__CODECS__LITERAL_UNION_DISCRIMINATOR_OUT_OF_RANGE]:\n        'Literal union discriminator out of range. Expected a number between $minRange and $maxRange, got $discriminator.',\n    [SOLANA_ERROR__CODECS__NUMBER_OUT_OF_RANGE]:\n        'Codec [$codecDescription] expected number to be in the range [$min, $max], got $value.',\n    [SOLANA_ERROR__CODECS__OFFSET_OUT_OF_RANGE]:\n        'Codec [$codecDescription] expected offset to be in the range [0, $bytesLength], got $offset.',\n    [SOLANA_ERROR__CODECS__SENTINEL_MISSING_IN_DECODED_BYTES]:\n        'Expected sentinel [$hexSentinel] to be present in decoded bytes [$hexDecodedBytes].',\n    [SOLANA_ERROR__CODECS__UNION_VARIANT_OUT_OF_RANGE]:\n        'Union variant out of range. Expected an index between $minRange and $maxRange, got $variant.',\n    [SOLANA_ERROR__CODECS__EXPECTED_DECODER_TO_CONSUME_ENTIRE_BYTE_ARRAY]:\n        'This decoder expected a byte array of exactly $expectedLength bytes, but $numExcessBytes unexpected excess bytes remained after decoding. Are you sure that you have chosen the correct decoder for this data?',\n    [SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_VALUE]:\n        'Invalid pattern match value. The provided value does not match any of the specified patterns.',\n    [SOLANA_ERROR__CODECS__INVALID_PATTERN_MATCH_BYTES]:\n        'Invalid pattern match bytes. The provided byte array does not match any of the specified patterns.',\n    [SOLANA_ERROR__CRYPTO__RANDOM_VALUES_FUNCTION_UNIMPLEMENTED]: 'No random values implementation could be found.',\n    [SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION]: 'Failed to send transaction$causeMessage',\n    [SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS]: 'Failed to send transactions$causeMessages',\n    [SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW]:\n        'Fixed-point operation `$operation` of kind `$kind` overflowed. Expected a raw bigint in [$min, $max], got $result.',\n    [SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO]:\n        'Fixed-point division by zero for value of kind `$kind` ($signedness, $totalBits bits).',\n    [SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS]:\n        '`fractionalBits` ($fractionalBits) must not exceed `totalBits` ($totalBits).',\n    [SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS]:\n        'Invalid `decimals`. Expected a non-negative integer, got $decimals.',\n    [SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS]:\n        'Invalid `fractionalBits`. Expected a non-negative integer, got $fractionalBits.',\n    [SOLANA_ERROR__FIXED_POINTS__INVALID_STRING]: 'Invalid string `$input` for fixed-point value of kind `$kind`.',\n    [SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS]:\n        'Invalid `totalBits`. Expected a positive integer, got $totalBits.',\n    [SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO]:\n        'Invalid ratio $numerator/$denominator for fixed-point value of kind `$kind`. Denominator must be non-zero.',\n    [SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE]:\n        'Fixed-point value of kind `$kind` has a malformed `raw` field. Expected a bigint, got `$raw`.',\n    [SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH]:\n        'Fixed-point `$operation` operation expected $expectedKind ($expectedSignedness, $expectedTotalBits bits, $expectedScale $expectedScaleLabel); got $actualKind ($actualSignedness, $actualTotalBits bits, $actualScale $actualScaleLabel).',\n    [SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS]:\n        'Fixed-point operation `$operation` of kind `$kind` cannot be performed exactly; pass a rounding mode other than `strict` to allow a rounded result.',\n    [SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED]:\n        'Fixed-point codec of kind `$kind` requires `totalBits` to be a multiple of 8; got $totalBits.',\n    [SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE]:\n        'Fixed-point value of kind `$kind` is out of range for $signedness $totalBits-bit storage. Expected a raw bigint in [$min, $max], got $raw.',\n    [SOLANA_ERROR__FS__UNSUPPORTED_ENVIRONMENT]:\n        'Filesystem operation `$operation` is not supported in this environment.',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_ALREADY_INITIALIZED]: 'Instruction requires an uninitialized account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_FAILED]:\n        'Instruction tries to borrow reference for an account which is already borrowed',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_BORROW_OUTSTANDING]:\n        'Instruction left account with an outstanding borrowed reference',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_SIZE_CHANGED]:\n        \"Program other than the account's owner changed the size of the account data\",\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_DATA_TOO_SMALL]: 'Account data too small for instruction',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_EXECUTABLE]: 'Instruction expected an executable account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ACCOUNT_NOT_RENT_EXEMPT]:\n        'An account does not have enough lamports to be rent-exempt',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ARITHMETIC_OVERFLOW]: 'Program arithmetic overflowed',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__BORSH_IO_ERROR]: 'Failed to serialize or deserialize account data',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__BUILTIN_PROGRAMS_MUST_CONSUME_COMPUTE_UNITS]:\n        'Builtin programs must consume compute units',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__CALL_DEPTH]: 'Cross-program invocation call depth too deep',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__COMPUTATIONAL_BUDGET_EXCEEDED]: 'Computational budget exceeded',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM]: 'Custom program error: #$code',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_INDEX]: 'Instruction contains duplicate accounts',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__DUPLICATE_ACCOUNT_OUT_OF_SYNC]:\n        'Instruction modifications of multiply-passed account differ',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_ACCOUNT_NOT_RENT_EXEMPT]: 'Executable accounts must be rent exempt',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_DATA_MODIFIED]: 'Instruction changed executable accounts data',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_LAMPORT_CHANGE]:\n        'Instruction changed the balance of an executable account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__EXECUTABLE_MODIFIED]: 'Instruction changed executable bit of an account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_DATA_MODIFIED]:\n        'Instruction modified data of an account it does not own',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__EXTERNAL_ACCOUNT_LAMPORT_SPEND]:\n        'Instruction spent from the balance of an account it does not own',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__GENERIC_ERROR]: 'Generic instruction error',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__ILLEGAL_OWNER]: 'Provided owner is not allowed',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__IMMUTABLE]: 'Account is immutable',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_AUTHORITY]: 'Incorrect authority provided',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INCORRECT_PROGRAM_ID]: 'Incorrect program id for instruction',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS]: 'Insufficient funds for instruction',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_DATA]: 'Invalid account data for instruction',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ACCOUNT_OWNER]: 'Invalid account owner',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT]: 'Invalid program argument',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ERROR]: 'Program returned invalid error code',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_INSTRUCTION_DATA]: 'Invalid instruction data',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_REALLOC]: 'Failed to reallocate account data',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_SEEDS]: 'Provided seeds do not result in a valid address',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_DATA_ALLOCATIONS_EXCEEDED]:\n        'Accounts data allocations exceeded the maximum allowed per transaction',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__MAX_ACCOUNTS_EXCEEDED]: 'Max accounts exceeded',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__MAX_INSTRUCTION_TRACE_LENGTH_EXCEEDED]: 'Max instruction trace length exceeded',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__MAX_SEED_LENGTH_EXCEEDED]:\n        'Length of the seed is too long for address generation',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_ACCOUNT]: 'An account required by the instruction is missing',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__MISSING_REQUIRED_SIGNATURE]: 'Missing required signature for instruction',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__MODIFIED_PROGRAM_ID]:\n        'Instruction illegally modified the program id of an account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__NOT_ENOUGH_ACCOUNT_KEYS]: 'Insufficient account keys for instruction',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__PRIVILEGE_ESCALATION]:\n        'Cross-program invocation with unauthorized signer or writable account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_ENVIRONMENT_SETUP_FAILURE]:\n        'Failed to create program execution environment',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPILE]: 'Program failed to compile',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__PROGRAM_FAILED_TO_COMPLETE]: 'Program failed to complete',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_DATA_MODIFIED]: 'Instruction modified data of a read-only account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__READONLY_LAMPORT_CHANGE]:\n        'Instruction changed the balance of a read-only account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__REENTRANCY_NOT_ALLOWED]:\n        'Cross-program invocation reentrancy not allowed for this instruction',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__RENT_EPOCH_MODIFIED]: 'Instruction modified rent epoch of an account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__UNBALANCED_INSTRUCTION]:\n        'Sum of account balances before and after instruction do not match',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__UNINITIALIZED_ACCOUNT]: 'Instruction requires an initialized account',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__UNKNOWN]: 'The instruction failed with the error: $errorName',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_PROGRAM_ID]: 'Unsupported program id',\n    [SOLANA_ERROR__INSTRUCTION_ERROR__UNSUPPORTED_SYSVAR]: 'Unsupported sysvar',\n    [SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND]: 'Invalid instruction plan kind: $kind.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN]: 'The provided instruction plan is empty.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND]:\n        'No failed transaction plan result was found in the provided transaction plan result.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED]:\n        'This transaction plan executor does not support non-divisible sequential plans. To support them, you may create your own executor such that multi-transaction atomicity is preserved — e.g. by targetting RPCs that support transaction bundles.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN]:\n        'The provided transaction plan failed to execute. See the `transactionPlanResult` attribute for more details. Note that the `cause` property is deprecated, and a future version will not set it.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN]:\n        'The provided message has insufficient capacity to accommodate the next instruction(s) in this plan. Expected at least $numBytesRequired free byte(s), got $numFreeBytes byte(s).',\n    [SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND]: 'Invalid transaction plan kind: $kind.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE]:\n        'No more instructions to pack; the message packer has completed the instruction plan.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN]:\n        'Unexpected instruction plan. Expected $expectedKind plan, got $actualKind plan.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN]:\n        'Unexpected transaction plan. Expected $expectedKind plan, got $actualKind plan.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT]:\n        'Unexpected transaction plan result. Expected $expectedKind plan, got $actualKind plan.',\n    [SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT]:\n        'Expected a successful transaction plan result. I.e. there is at least one failed or cancelled transaction in the plan.',\n    [SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_ACCOUNTS]: 'The instruction does not have any accounts.',\n    [SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_DATA]: 'The instruction does not have any data.',\n    [SOLANA_ERROR__INSTRUCTION__PROGRAM_ID_MISMATCH]:\n        'Expected instruction to have progress address $expectedProgramAddress, got $actualProgramAddress.',\n    [SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH]:\n        'Expected base58 encoded blockhash to decode to a byte array of length 32. Actual length: $actualLength.',\n    [SOLANA_ERROR__INVALID_NONCE]:\n        'The nonce `$expectedNonceValue` is no longer valid. It has advanced to `$actualNonceValue`',\n    [SOLANA_ERROR__INVARIANT_VIOLATION__CACHED_ABORTABLE_ITERABLE_CACHE_ENTRY_MISSING]:\n        'Invariant violation: Found no abortable iterable cache entry for key `$cacheKey`. It ' +\n        'should be impossible to hit this error; please file an issue at ' +\n        'https://sola.na/web3invariant',\n    [SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED]:\n        'Invariant violation: This data publisher does not publish to the channel named ' +\n        '`$channelName`. Supported channels include $supportedChannelNames.',\n    [SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE]:\n        'Invariant violation: WebSocket message iterator state is corrupt; iterated without first ' +\n        'resolving existing message promise. It should be impossible to hit this error; please ' +\n        'file an issue at https://sola.na/web3invariant',\n    [SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING]:\n        'Invariant violation: WebSocket message iterator is missing state storage. It should be ' +\n        'impossible to hit this error; please file an issue at https://sola.na/web3invariant',\n    [SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE]:\n        'Invariant violation: Switch statement non-exhaustive. Received unexpected value ' +\n        '`$unexpectedValue`. It should be impossible to hit this error; please file an issue at ' +\n        'https://sola.na/web3invariant',\n    [SOLANA_ERROR__JSON_RPC__INTERNAL_ERROR]: 'JSON-RPC error: Internal JSON-RPC error ($__serverMessage)',\n    [SOLANA_ERROR__JSON_RPC__INVALID_PARAMS]: 'JSON-RPC error: Invalid method parameter(s) ($__serverMessage)',\n    [SOLANA_ERROR__JSON_RPC__INVALID_REQUEST]:\n        'JSON-RPC error: The JSON sent is not a valid `Request` object ($__serverMessage)',\n    [SOLANA_ERROR__JSON_RPC__METHOD_NOT_FOUND]:\n        'JSON-RPC error: The method does not exist / is not available ($__serverMessage)',\n    [SOLANA_ERROR__JSON_RPC__PARSE_ERROR]:\n        'JSON-RPC error: An error occurred on the server while parsing the JSON text ($__serverMessage)',\n    [SOLANA_ERROR__JSON_RPC__SCAN_ERROR]: '$__serverMessage',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_CLEANED_UP]: '$__serverMessage',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE]: '$__serverMessage',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET]: '$__serverMessage',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_EPOCH_REWARDS_PERIOD_ACTIVE]:\n        'Epoch rewards period still active at slot $slot',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX]: '$__serverMessage',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED]: '$__serverMessage',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_LONG_TERM_STORAGE_UNREACHABLE]:\n        'Failed to query long-term storage; please try again',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED]: 'Minimum context slot has not been reached',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY]: 'Node is unhealthy; behind by $numSlotsBehind slots',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NO_SNAPSHOT]: 'No snapshot',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE]: 'Transaction simulation failed',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_NOT_EPOCH_BOUNDARY]:\n        \"Rewards cannot be found because slot $slot is not the epoch boundary. This may be due to gap in the queried node's local ledger or long-term storage\",\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SLOT_SKIPPED]: '$__serverMessage',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE]:\n        'Transaction history is not available from this node',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE]: '$__serverMessage',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_LEN_MISMATCH]: 'Transaction signature length mismatch',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE]:\n        'Transaction signature verification failure',\n    [SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION]: '$__serverMessage',\n    [SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX]:\n        'The grind regex `/$source/` contains the character `$character`, which is not in the base58 alphabet and can never match a Solana address.',\n    [SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH]: 'Key pair bytes must be of length 64, got $byteLength.',\n    [SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH]:\n        'Expected private key bytes with length 32. Actual length: $actualLength.',\n    [SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH]:\n        'Expected base58-encoded signature to decode to a byte array of length 64. Actual length: $actualLength.',\n    [SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY]:\n        'The provided private key does not match the provided public key.',\n    [SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE]:\n        'Expected base58-encoded signature string of length in the range [64, 88]. Actual length: $actualLength.',\n    [SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT]:\n        'Writing a key pair to disk is not supported in this environment.',\n    [SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE]: 'Lamports value must be in the range [0, 2e64-1]',\n    [SOLANA_ERROR__MALFORMED_BIGINT_STRING]: '`$value` cannot be parsed as a `BigInt`',\n    [SOLANA_ERROR__MALFORMED_JSON_RPC_ERROR]: '$message',\n    [SOLANA_ERROR__MALFORMED_NUMBER_STRING]: '`$value` cannot be parsed as a `Number`',\n    [SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND]: 'No nonce account could be found at address `$nonceAccountAddress`',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH]:\n        'Expected base58 encoded application domain to decode to a byte array of length 32. Actual length: $actualLength.',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE]:\n        'Attempted to sign an offchain message with an address that is not a signer for it',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE]:\n        'Expected base58-encoded application domain string of length in the range [32, 44]. Actual length: $actualLength.',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH]:\n        'The signer addresses in this offchain message envelope do not match the list of ' +\n        'required signers in the message preamble. These unexpected signers were present in the ' +\n        'envelope: `[$unexpectedSigners]`. These required signers were missing from the envelope ' +\n        '`[$missingSigners]`.',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED]:\n        'The message body provided has a byte-length of $actualBytes. The maximum allowable ' +\n        'byte-length is $maxBytes',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH]:\n        'Expected message format $expectedMessageFormat, got $actualMessageFormat',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH]:\n        'The message length specified in the message preamble is $specifiedLength bytes. The actual length of the message is $actualLength bytes.',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY]: 'Offchain message content must be non-empty',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO]:\n        'Offchain message must specify the address of at least one required signer',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO]:\n        'Offchain message envelope must reserve space for at least one signature',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH]:\n        'The offchain message preamble specifies $numRequiredSignatures required signature(s), got $signaturesLength.',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_SORTED]:\n        'The signatories of this offchain message must be listed in lexicographical order',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE]:\n        'An address must be listed no more than once among the signatories of an offchain message',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING]:\n        'Offchain message is missing signatures for addresses: $addresses.',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE]:\n        'Offchain message signature verification failed. Signature mismatch for required ' +\n        'signatories [$signatoriesWithInvalidSignatures]. Missing signatures for signatories ' +\n        '[$signatoriesWithMissingSignatures]',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE]:\n        'The message body provided contains characters whose codes fall outside the allowed ' +\n        'range. In order to ensure clear-signing compatiblity with hardware wallets, the message ' +\n        'may only contain line feeds and characters in the range [\\\\x20-\\\\x7e].',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION]:\n        'Expected offchain message version $expectedVersion. Got $actualVersion.',\n    [SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED]:\n        'This version of Kit does not support decoding offchain messages with version ' +\n        '$unsupportedVersion. The current max supported version is 0.',\n    [SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT]:\n        'The provided account could not be identified as an account from the $programName program.',\n    [SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION]:\n        'The provided instruction could not be identified as an instruction from the $programName program.',\n    [SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS]:\n        'The provided instruction is missing some accounts. Expected at least $expectedAccountMetas account(s), got $actualAccountMetas.',\n    [SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL]:\n        \"Expected resolved instruction input '$inputName' to be non-null.\",\n    [SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE]:\n        \"Expected resolved instruction input '$inputName' to be of type `$expectedType`.\",\n    [SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_ACCOUNT_TYPE]:\n        \"Unrecognized account type '$accountType' for the $programName program.\",\n    [SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE]:\n        \"Unrecognized instruction type '$instructionType' for the $programName program.\",\n    [SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN]:\n        \"The notification name must end in 'Notifications' and the API must supply a \" +\n        \"subscription plan creator function for the notification '$notificationName'.\",\n    [SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED]:\n        'WebSocket was closed before payload could be added to the send buffer',\n    [SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED]: 'WebSocket connection closed',\n    [SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT]: 'WebSocket failed to connect',\n    [SOLANA_ERROR__RPC_SUBSCRIPTIONS__EXPECTED_SERVER_SUBSCRIPTION_ID]:\n        'Failed to obtain a subscription id from the server',\n    [SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD]: 'Could not find an API plan for RPC method: `$method`',\n    [SOLANA_ERROR__RPC__INTEGER_OVERFLOW]:\n        'The $argumentLabel argument to the `$methodName` RPC method$optionalPathLabel was ' +\n        '`$value`. This number is unsafe for use with the Solana JSON-RPC because it exceeds ' +\n        '`Number.MAX_SAFE_INTEGER`.',\n    [SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR]: 'HTTP error ($statusCode): $message',\n    [SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN]:\n        'HTTP header(s) forbidden: $headers. Learn more at ' +\n        'https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name.',\n    [SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS]:\n        'Multiple distinct signers were identified for address `$address`. Please ensure that ' +\n        'you are using the same signer instance for each address.',\n    [SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER]:\n        'The provided value does not implement the `KeyPairSigner` interface',\n    [SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER]:\n        'The provided value does not implement the `MessageModifyingSigner` interface',\n    [SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER]:\n        'The provided value does not implement the `MessagePartialSigner` interface',\n    [SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER]:\n        'The provided value does not implement any of the `MessageSigner` interfaces',\n    [SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER]:\n        'The provided value does not implement the `TransactionModifyingSigner` interface',\n    [SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER]:\n        'The provided value does not implement the `TransactionPartialSigner` interface',\n    [SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER]:\n        'The provided value does not implement the `TransactionSendingSigner` interface',\n    [SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER]:\n        'The provided value does not implement any of the `TransactionSigner` interfaces',\n    [SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS]:\n        'More than one `TransactionSendingSigner` was identified.',\n    [SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING]:\n        'No `TransactionSendingSigner` was identified. Please provide a valid ' +\n        '`TransactionWithSingleSendingSigner` transaction.',\n    [SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION]:\n        'The wallet account $address cannot be used to create a transaction signer because it does not ' +\n        'implement either the `solana:signTransaction` or `solana:signAndSendTransaction` feature. ' +\n        'At least one of these features is required. ' +\n        'The account supports the following features: $supportedFeatures.',\n    [SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED]:\n        'Wallet account signers do not support signing multiple messages/transactions in a single operation',\n    [SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED]:\n        'This `ReactiveStreamStore` does not support retry. Use `createReactiveStoreFromDataPublisherFactory` ' +\n        'to construct a retryable store.',\n    [SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY]: 'Cannot export a non-extractable key.',\n    [SOLANA_ERROR__SUBTLE_CRYPTO__DIGEST_UNIMPLEMENTED]: 'No digest implementation could be found.',\n    [SOLANA_ERROR__SUBTLE_CRYPTO__DISALLOWED_IN_INSECURE_CONTEXT]:\n        'Cryptographic operations are only allowed in secure browser contexts. Read more ' +\n        'here: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts.',\n    [SOLANA_ERROR__SUBTLE_CRYPTO__ED25519_ALGORITHM_UNIMPLEMENTED]:\n        'This runtime does not support the generation of Ed25519 key pairs.\\n\\nInstall ' +\n        '@solana/webcrypto-ed25519-polyfill and call its `install` function before generating keys in ' +\n        'environments that do not support Ed25519.\\n\\nFor a list of runtimes that ' +\n        'currently support Ed25519 operations, visit ' +\n        'https://github.com/WICG/webcrypto-secure-curves/issues/20.',\n    [SOLANA_ERROR__SUBTLE_CRYPTO__EXPORT_FUNCTION_UNIMPLEMENTED]: 'No key export implementation could be found.',\n    [SOLANA_ERROR__SUBTLE_CRYPTO__GENERATE_FUNCTION_UNIMPLEMENTED]: 'No key generation implementation could be found.',\n    [SOLANA_ERROR__SUBTLE_CRYPTO__SIGN_FUNCTION_UNIMPLEMENTED]: 'No signing implementation could be found.',\n    [SOLANA_ERROR__SUBTLE_CRYPTO__VERIFY_FUNCTION_UNIMPLEMENTED]:\n        'No signature verification implementation could be found.',\n    [SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE]:\n        'Timestamp value must be in the range [-(2n ** 63n), (2n ** 63n) - 1]. `$value` given',\n    [SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_BORROW_OUTSTANDING]:\n        'Transaction processing left an account with an outstanding borrowed reference',\n    [SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_IN_USE]: 'Account in use',\n    [SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_LOADED_TWICE]: 'Account loaded twice',\n    [SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_NOT_FOUND]:\n        'Attempt to debit an account but found no record of a prior credit.',\n    [SOLANA_ERROR__TRANSACTION_ERROR__ADDRESS_LOOKUP_TABLE_NOT_FOUND]:\n        \"Transaction loads an address table account that doesn't exist\",\n    [SOLANA_ERROR__TRANSACTION_ERROR__ALREADY_PROCESSED]: 'This transaction has already been processed',\n    [SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND]: 'Blockhash not found',\n    [SOLANA_ERROR__TRANSACTION_ERROR__CALL_CHAIN_TOO_DEEP]: 'Loader call chain is too deep',\n    [SOLANA_ERROR__TRANSACTION_ERROR__CLUSTER_MAINTENANCE]:\n        'Transactions are currently disabled due to cluster maintenance',\n    [SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION]:\n        'Transaction contains a duplicate instruction ($index) that is not allowed',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE]: 'Insufficient funds for fee',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT]:\n        'Transaction results in an account ($accountIndex) with insufficient funds for rent',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ACCOUNT_FOR_FEE]: 'This account may not be used to pay transaction fees',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ACCOUNT_INDEX]: 'Transaction contains an invalid account reference',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_DATA]:\n        'Transaction loads an address table account with invalid data',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_INDEX]:\n        'Transaction address table lookup uses an invalid index',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_ADDRESS_LOOKUP_TABLE_OWNER]:\n        'Transaction loads an address table account with an invalid owner',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_LOADED_ACCOUNTS_DATA_SIZE_LIMIT]:\n        'LoadedAccountsDataSizeLimit set for transaction must be greater than 0.',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_PROGRAM_FOR_EXECUTION]:\n        'This program may not be used for executing instructions',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_RENT_PAYING_ACCOUNT]:\n        'Transaction leaves an account with a lower balance than rent-exempt minimum',\n    [SOLANA_ERROR__TRANSACTION_ERROR__INVALID_WRITABLE_ACCOUNT]:\n        'Transaction loads a writable account that cannot be written',\n    [SOLANA_ERROR__TRANSACTION_ERROR__MAX_LOADED_ACCOUNTS_DATA_SIZE_EXCEEDED]:\n        'Transaction exceeded max loaded accounts data size cap',\n    [SOLANA_ERROR__TRANSACTION_ERROR__MISSING_SIGNATURE_FOR_FEE]:\n        'Transaction requires a fee but has no signature present',\n    [SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_ACCOUNT_NOT_FOUND]: 'Attempt to load a program that does not exist',\n    [SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED]:\n        'Execution of the program referenced by account at index $accountIndex is temporarily restricted.',\n    [SOLANA_ERROR__TRANSACTION_ERROR__RESANITIZATION_NEEDED]: 'ResanitizationNeeded',\n    [SOLANA_ERROR__TRANSACTION_ERROR__SANITIZE_FAILURE]: 'Transaction failed to sanitize accounts offsets correctly',\n    [SOLANA_ERROR__TRANSACTION_ERROR__SIGNATURE_FAILURE]: 'Transaction did not pass signature verification',\n    [SOLANA_ERROR__TRANSACTION_ERROR__TOO_MANY_ACCOUNT_LOCKS]: 'Transaction locked too many accounts',\n    [SOLANA_ERROR__TRANSACTION_ERROR__UNBALANCED_TRANSACTION]:\n        'Sum of account balances before and after transaction do not match',\n    [SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN]: 'The transaction failed with the error `$errorName`',\n    [SOLANA_ERROR__TRANSACTION_ERROR__UNSUPPORTED_VERSION]: 'Transaction version is unsupported',\n    [SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_ACCOUNT_DATA_BLOCK_LIMIT]:\n        'Transaction would exceed account data limit within the block',\n    [SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_ACCOUNT_DATA_TOTAL_LIMIT]:\n        'Transaction would exceed total account data limit',\n    [SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_ACCOUNT_COST_LIMIT]:\n        'Transaction would exceed max account limit within the block',\n    [SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_BLOCK_COST_LIMIT]:\n        'Transaction would exceed max Block Cost Limit',\n    [SOLANA_ERROR__TRANSACTION_ERROR__WOULD_EXCEED_MAX_VOTE_COST_LIMIT]: 'Transaction would exceed max Vote Cost Limit',\n    [SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION]:\n        'Attempted to sign a transaction with an address that is not a signer for it',\n    [SOLANA_ERROR__TRANSACTION__ADDRESS_MISSING]: 'Transaction is missing an address at index: $index.',\n    [SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES]:\n        'Transaction has no expected signers therefore it cannot be encoded',\n    [SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT]:\n        'Transaction size $transactionSize exceeds limit of $transactionSizeLimit bytes',\n    [SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME]: 'Transaction does not have a blockhash lifetime',\n    [SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME]: 'Transaction is not a durable nonce transaction',\n    [SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING]:\n        'Contents of these address lookup tables unknown: $lookupTableAddresses',\n    [SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE]:\n        'Lookup of address at index $highestRequestedIndex failed for lookup table ' +\n        '`$lookupTableAddress`. Highest known index is $highestKnownIndex. The lookup table ' +\n        'may have been extended since its contents were retrieved',\n    [SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING]: 'No fee payer set in CompiledTransaction',\n    [SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND]:\n        'Could not find program address at index $index',\n    [SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT]:\n        'Failed to estimate the compute unit consumption for this transaction message. This is ' +\n        'likely because simulating the transaction failed. Inspect the `cause` property of this ' +\n        'error to learn more',\n    [SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT]:\n        'Transaction failed when it was simulated in order to estimate the compute unit consumption. ' +\n        'The compute unit estimate provided is for a transaction that failed when simulated and may not ' +\n        'be representative of the compute units this transaction would consume if successful. Inspect the ' +\n        '`cause` property of this error to learn more',\n    [SOLANA_ERROR__TRANSACTION__FEE_PAYER_MISSING]: 'Transaction is missing a fee payer.',\n    [SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING]:\n        \"Could not determine this transaction's signature. Make sure that the transaction has \" +\n        'been signed by its fee payer.',\n    [SOLANA_ERROR__TRANSACTION__INVALID_NONCE_TRANSACTION_FIRST_INSTRUCTION_MUST_BE_ADVANCE_NONCE]:\n        'Transaction first instruction is not advance nonce account instruction.',\n    [SOLANA_ERROR__TRANSACTION__INVALID_NONCE_TRANSACTION_INSTRUCTIONS_MISSING]:\n        'Transaction with no instructions cannot be durable nonce transaction.',\n    [SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES]:\n        'This transaction includes an address (`$programAddress`) which is both ' +\n        'invoked and set as the fee payer. Program addresses may not pay fees',\n    [SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE]:\n        'This transaction includes an address (`$programAddress`) which is both invoked and ' +\n        'marked writable. Program addresses may not be writable',\n    [SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH]:\n        'The transaction message expected the transaction to have $numRequiredSignatures signatures, got $signaturesLength.',\n    [SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING]: 'Transaction is missing signatures for addresses: $addresses.',\n    [SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE]:\n        'Transaction version must be in the range [0, 127]. `$actualVersion` given',\n    [SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED]:\n        'This version of Kit does not support decoding transactions with version $unsupportedVersion. The current max supported version is 1.',\n    [SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE]:\n        'The transaction has a durable nonce lifetime (with nonce `$nonce`), but the nonce account address is in a lookup table. The lifetime constraint cannot be constructed without fetching the lookup tables for the transaction.',\n    [SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS]:\n        'Invalid transaction config mask: $mask. Bits 0 and 1 must match (both set or both unset)',\n    [SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES]: 'Transaction message bytes are malformed: $messageBytes',\n    [SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_MESSAGE_BYTES]:\n        'Transaction message bytes are empty, so the transaction cannot be encoded',\n    [SOLANA_ERROR__TRANSACTION__CANNOT_DECODE_EMPTY_TRANSACTION_BYTES]:\n        'Transaction bytes are empty, so no transaction can be decoded',\n    [SOLANA_ERROR__TRANSACTION__VERSION_ZERO_MUST_BE_ENCODED_WITH_SIGNATURES_FIRST]:\n        'Transaction version 0 must be encoded with signatures first. This transaction was encoded with first byte $firstByte, which is expected to be a signature count for v0 transactions.',\n    [SOLANA_ERROR__TRANSACTION__SIGNATURE_COUNT_TOO_HIGH_FOR_TRANSACTION_BYTES]:\n        'The provided transaction bytes expect that there should be $numExpectedSignatures signatures, but the bytes are not long enough to contain a transaction message with this many signatures. The provided bytes are $transactionBytesLength bytes long.',\n    [SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX]:\n        'The transaction has a durable nonce lifetime, but the nonce account index is invalid. Expected a nonce account index less than $numberOfStaticAccounts, got $nonceAccountIndex.',\n    [SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND]:\n        'The transaction config value for $configName has the incorrect kind. Expected $expectedKind, got $actualKind.',\n    [SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH]:\n        'The transaction does not have the same number of instruction headers and instruction payloads. Got $numInstructionHeaders instruction headers, and $numInstructionPayloads instruction payloads.',\n    [SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES]:\n        'Transaction has $actualCount unique signer addresses but the maximum allowed is $maxAllowed',\n    [SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES]:\n        'Transaction has $actualCount unique account addresses but the maximum allowed is $maxAllowed',\n    [SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS]:\n        'Transaction has $actualCount instructions but the maximum allowed is $maxAllowed',\n    [SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION]:\n        'The instruction at index $instructionIndex has $actualCount account references but the maximum allowed is $maxAllowed',\n    [SOLANA_ERROR__WALLET__NOT_CONNECTED]: 'Cannot $operation: no wallet connected',\n    [SOLANA_ERROR__WALLET__NO_SIGNER_CONNECTED]: 'No signing wallet connected (status: $status)',\n    [SOLANA_ERROR__WALLET__SIGNER_NOT_AVAILABLE]: 'Connected wallet does not support signing',\n};\n"
  },
  {
    "path": "packages/errors/src/rpc-enum-errors.ts",
    "content": "import { SolanaErrorCode } from './codes';\nimport { SolanaErrorContext } from './context';\nimport { SolanaError } from './error';\nimport { safeCaptureStackTrace } from './stack-trace';\n\ntype Config = Readonly<{\n    /**\n     * Oh, hello. You might wonder what in tarnation is going on here. Allow us to explain.\n     *\n     * One of the goals of `@solana/errors` is to allow errors that are not interesting to your\n     * application to shake out of your app bundle in production. This means that we must never\n     * export large hardcoded maps of error codes/messages.\n     *\n     * Unfortunately, where instruction and transaction errors from the RPC are concerned, we have\n     * no choice but to keep a map between the RPC `rpcEnumError` enum name and its corresponding\n     * `SolanaError` code. In the interest of implementing that map in as few bytes of source code\n     * as possible, we do the following:\n     *\n     *   1. Reserve a block of sequential error codes for the enum in question\n     *   2. Hardcode the list of enum names in that same order\n     *   3. Match the enum error name from the RPC with its index in that list, and reconstruct the\n     *      `SolanaError` code by adding the `errorCodeBaseOffset` to that index\n     */\n    errorCodeBaseOffset: number;\n    getErrorContext: (\n        errorCode: SolanaErrorCode,\n        rpcErrorName: string,\n        rpcErrorContext?: unknown,\n    ) => SolanaErrorContext[SolanaErrorCode];\n    orderedErrorNames: string[];\n    rpcEnumError: string | { [key: string]: unknown };\n}>;\n\nexport function getSolanaErrorFromRpcError(\n    { errorCodeBaseOffset, getErrorContext, orderedErrorNames, rpcEnumError }: Config,\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n    constructorOpt: Function,\n): SolanaError {\n    let rpcErrorName;\n    let rpcErrorContext;\n    if (typeof rpcEnumError === 'string') {\n        rpcErrorName = rpcEnumError;\n    } else {\n        rpcErrorName = Object.keys(rpcEnumError)[0];\n        rpcErrorContext = rpcEnumError[rpcErrorName];\n    }\n    const codeOffset = orderedErrorNames.indexOf(rpcErrorName);\n    const errorCode = (errorCodeBaseOffset + codeOffset) as SolanaErrorCode;\n    const errorContext = getErrorContext(errorCode, rpcErrorName, rpcErrorContext);\n    const err = new SolanaError(errorCode, errorContext);\n    safeCaptureStackTrace(err, constructorOpt);\n    return err;\n}\n"
  },
  {
    "path": "packages/errors/src/simulation-errors.ts",
    "content": "import {\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n    SolanaErrorCode,\n} from './codes';\nimport { isSolanaError } from './error';\n\n/**\n * Extracts the underlying cause from a simulation-related error.\n *\n * When a transaction simulation fails, the error is often wrapped in a\n * simulation-specific {@link SolanaError}. This function unwraps such errors\n * by returning the `cause` property, giving you access to the actual error\n * that triggered the simulation failure.\n *\n * If the provided error is not a simulation-related error, it is returned unchanged.\n *\n * The following error codes are considered simulation errors:\n * - {@link SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE}\n * - {@link SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT}\n *\n * @param error - The error to unwrap.\n * @return The underlying cause if the error is a simulation error, otherwise the original error.\n *\n * @example\n * Unwrapping a preflight failure to access the root cause.\n * ```ts\n * import { unwrapSimulationError } from '@solana/errors';\n *\n * try {\n *     await sendTransaction(signedTransaction);\n * } catch (e) {\n *     const cause = unwrapSimulationError(e);\n *     console.log('Send transaction failed due to:', cause);\n * }\n * ```\n */\nexport function unwrapSimulationError(error: unknown): unknown {\n    const simulationCodes: SolanaErrorCode[] = [\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n        SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n    ];\n    if (isSolanaError(error) && !!error.cause && simulationCodes.includes(error.context.__code)) {\n        return error.cause;\n    }\n    return error;\n}\n"
  },
  {
    "path": "packages/errors/src/stack-trace.ts",
    "content": "export function safeCaptureStackTrace(...args: Parameters<typeof Error.captureStackTrace>): void {\n    if ('captureStackTrace' in Error && typeof Error.captureStackTrace === 'function') {\n        Error.captureStackTrace(...args);\n    }\n}\n"
  },
  {
    "path": "packages/errors/src/transaction-error.ts",
    "content": "import {\n    SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT,\n    SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED,\n    SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN,\n} from './codes';\nimport { SolanaError } from './error';\nimport { getSolanaErrorFromInstructionError } from './instruction-error';\nimport { getSolanaErrorFromRpcError } from './rpc-enum-errors';\n\n/**\n * How to add an error when an entry is added to the RPC `TransactionError` enum:\n *\n *   1. Follow the instructions in `./codes.ts` to add a corresponding Solana error code\n *   2. Add the `TransactionError` enum name in the same order as it appears in `./codes.ts`\n *   3. Add the new error name/code mapping to `./__tests__/transaction-error-test.ts`\n */\nconst ORDERED_ERROR_NAMES = [\n    // Keep synced with RPC source: https://github.com/anza-xyz/agave/blob/master/sdk/src/transaction/error.rs\n    // If this list ever gets too large, consider implementing a compression strategy like this:\n    // https://gist.github.com/steveluscher/aaa7cbbb5433b1197983908a40860c47\n    'AccountInUse',\n    'AccountLoadedTwice',\n    'AccountNotFound',\n    'ProgramAccountNotFound',\n    'InsufficientFundsForFee',\n    'InvalidAccountForFee',\n    'AlreadyProcessed',\n    'BlockhashNotFound',\n    // `InstructionError` intentionally omitted; delegated to `getSolanaErrorFromInstructionError`\n    'CallChainTooDeep',\n    'MissingSignatureForFee',\n    'InvalidAccountIndex',\n    'SignatureFailure',\n    'InvalidProgramForExecution',\n    'SanitizeFailure',\n    'ClusterMaintenance',\n    'AccountBorrowOutstanding',\n    'WouldExceedMaxBlockCostLimit',\n    'UnsupportedVersion',\n    'InvalidWritableAccount',\n    'WouldExceedMaxAccountCostLimit',\n    'WouldExceedAccountDataBlockLimit',\n    'TooManyAccountLocks',\n    'AddressLookupTableNotFound',\n    'InvalidAddressLookupTableOwner',\n    'InvalidAddressLookupTableData',\n    'InvalidAddressLookupTableIndex',\n    'InvalidRentPayingAccount',\n    'WouldExceedMaxVoteCostLimit',\n    'WouldExceedAccountDataTotalLimit',\n    'DuplicateInstruction',\n    'InsufficientFundsForRent',\n    'MaxLoadedAccountsDataSizeExceeded',\n    'InvalidLoadedAccountsDataSizeLimit',\n    'ResanitizationNeeded',\n    'ProgramExecutionTemporarilyRestricted',\n    'UnbalancedTransaction',\n];\n\nexport function getSolanaErrorFromTransactionError(transactionError: string | { [key: string]: unknown }): SolanaError {\n    if (typeof transactionError === 'object' && 'InstructionError' in transactionError) {\n        return getSolanaErrorFromInstructionError(\n            ...(transactionError.InstructionError as Parameters<typeof getSolanaErrorFromInstructionError>),\n        );\n    }\n    return getSolanaErrorFromRpcError(\n        {\n            errorCodeBaseOffset: 7050001,\n            getErrorContext(errorCode, rpcErrorName, rpcErrorContext) {\n                if (errorCode === SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN) {\n                    return {\n                        errorName: rpcErrorName,\n                        ...(rpcErrorContext !== undefined ? { transactionErrorContext: rpcErrorContext } : null),\n                    };\n                } else if (errorCode === SOLANA_ERROR__TRANSACTION_ERROR__DUPLICATE_INSTRUCTION) {\n                    return {\n                        index: Number(rpcErrorContext as bigint | number),\n                    };\n                } else if (\n                    errorCode === SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_RENT ||\n                    errorCode === SOLANA_ERROR__TRANSACTION_ERROR__PROGRAM_EXECUTION_TEMPORARILY_RESTRICTED\n                ) {\n                    return {\n                        accountIndex: Number((rpcErrorContext as { account_index: bigint | number }).account_index),\n                    };\n                }\n            },\n            orderedErrorNames: ORDERED_ERROR_NAMES,\n            rpcEnumError: transactionError,\n        },\n        getSolanaErrorFromTransactionError,\n    );\n}\n"
  },
  {
    "path": "packages/errors/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/errors/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2022.Error\"],\n        \"resolveJsonModule\": true\n    },\n    \"display\": \"@solana/errors\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"bin\", \"src\"]\n}\n"
  },
  {
    "path": "packages/errors/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/eslint-config/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/eslint-config/eslint.config.mjs",
    "content": "import solanaConfig from '@solana/eslint-config-solana';\nimport solanaJestConfig from '@solana/eslint-config-solana/jest';\n\nexport default [\n    ...solanaConfig,\n    ...solanaJestConfig,\n    {\n        rules: {\n            '@typescript-eslint/no-base-to-string': 'off',\n            '@typescript-eslint/no-unsafe-argument': 'off',\n            '@typescript-eslint/no-unsafe-assignment': 'off',\n            '@typescript-eslint/no-unsafe-call': 'off',\n            '@typescript-eslint/no-unsafe-enum-comparison': 'off',\n            '@typescript-eslint/no-unsafe-member-access': 'off',\n            '@typescript-eslint/no-unsafe-return': 'off',\n            '@typescript-eslint/only-throw-error': 'off',\n            '@typescript-eslint/unbound-method': 'off',\n            'jest/expect-expect': [\n                'error',\n                {\n                    assertFunctionNames: ['expect', 'expectNewPreOffset', 'expectNewPostOffset'],\n                },\n            ],\n        },\n    },\n];\n"
  },
  {
    "path": "packages/eslint-config/eslint.config.react.mjs",
    "content": "import solanaReactConfig from '@solana/eslint-config-solana/react';\nimport baseConfig from './eslint.config.mjs';\n\nexport default [...solanaReactConfig, ...baseConfig];\n"
  },
  {
    "path": "packages/eslint-config/package.json",
    "content": "{\n    \"name\": \"@solana/eslint-config\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"files\": [\n        \"eslint.config.mjs\",\n        \"eslint.config.react.mjs\"\n    ],\n    \"devDependencies\": {\n        \"@eslint/js\": \"^9.39.2\",\n        \"@eslint/json\": \"^1.0.0\",\n        \"@solana/eslint-config-solana\": \"^6.0.0\",\n        \"@typescript-eslint/eslint-plugin\": \"^8.54.0\",\n        \"@typescript-eslint/parser\": \"^8.54.0\",\n        \"eslint-plugin-jest\": \"^29.2.1\",\n        \"eslint-plugin-react-hooks\": \"^7.0.1\",\n        \"eslint-plugin-simple-import-sort\": \"^12.1.1\",\n        \"eslint-plugin-sort-keys-fix\": \"^1.1.2\",\n        \"eslint-plugin-typescript-sort-keys\": \"^3.3.0\"\n    },\n    \"peerDependencies\": {\n        \"eslint\": \"^9.39.1\"\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/eslint-config/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"ESLint Config\",\n    \"extends\": \"../tsconfig/base.json\"\n}\n"
  },
  {
    "path": "packages/event-target-impl/.gitignore",
    "content": "dist/\n"
  },
  {
    "path": "packages/event-target-impl/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/event-target-impl/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/event-target-impl/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/event-target-impl/package.json",
    "content": "{\n    \"name\": \"@solana/event-target-impl\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"exports\": {\n        \"edge-light\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        }\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"types\": \"./dist/types/index.browser.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\"\n    ],\n    \"sideEffects\": false,\n    \"scripts\": {\n        \"compile:js\": \"tsup\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/event-target-impl/src/index.browser.ts",
    "content": "export const AbortController = globalThis.AbortController;\nexport const EventTarget = globalThis.EventTarget;\n"
  },
  {
    "path": "packages/event-target-impl/src/index.node.ts",
    "content": "import { setMaxListeners } from 'node:events';\n\nexport const AbortController = class extends globalThis.AbortController {\n    constructor(...args: ConstructorParameters<typeof globalThis.AbortController>) {\n        super(...args);\n        setMaxListeners(Number.MAX_SAFE_INTEGER, this.signal);\n    }\n};\n\nexport const EventTarget = class extends globalThis.EventTarget {\n    constructor(...args: ConstructorParameters<typeof globalThis.EventTarget>) {\n        super(...args);\n        setMaxListeners(Number.MAX_SAFE_INTEGER, this);\n    }\n};\n"
  },
  {
    "path": "packages/event-target-impl/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"isolatedModules\": false,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.browser.ts\"]\n}\n"
  },
  {
    "path": "packages/event-target-impl/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\"]\n    },\n    \"display\": \"EventTarget Implementation\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/event-target-impl/tsup.config.ts",
    "content": "import { defineConfig } from 'tsup';\n\nexport default defineConfig(_options =>\n    (['browser', 'node'] as const).map(platform => ({\n        entry: [`./src/index.${platform}.ts`],\n        format: ['cjs', 'esm'],\n        minify: true,\n        name: platform,\n        outExtension({ format }) {\n            return { js: `.${format === 'cjs' ? 'cjs' : 'mjs'}` };\n        },\n        platform,\n        sourcemap: true,\n        treeshake: true,\n    })),\n);\n"
  },
  {
    "path": "packages/fast-stable-stringify/.gitignore",
    "content": "dist/"
  },
  {
    "path": "packages/fast-stable-stringify/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/fast-stable-stringify/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\nnode_modules/"
  },
  {
    "path": "packages/fast-stable-stringify/CHANGELOG.md",
    "content": "# @solana/fast-stable-stringify\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n## 6.6.0\n\n## 6.5.0\n\n## 6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n## 6.1.0\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n## 5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n## 5.3.0\n\n## 5.2.0\n\n## 5.1.0\n\n## 5.0.0\n\n## 4.0.0\n\n## 3.0.0\n\n## 2.3.0\n\n## 2.2.1\n\n## 2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n## 2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2502](https://github.com/solana-labs/solana-web3.js/pull/2502) [`5ed19c6`](https://github.com/solana-labs/solana-web3.js/commit/5ed19c6c3c6e7a1bacde8c23c438ecb85454b126) Thanks [@steveluscher](https://github.com/steveluscher)! - Added TypeScript types to `@solana/fast-stable-stringify`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2502](https://github.com/solana-labs/solana-web3.js/pull/2502) [`5ed19c6`](https://github.com/solana-labs/solana-web3.js/commit/5ed19c6c3c6e7a1bacde8c23c438ecb85454b126) Thanks [@steveluscher](https://github.com/steveluscher)! - Added TypeScript types to `@solana/fast-stable-stringify`\n"
  },
  {
    "path": "packages/fast-stable-stringify/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\nCopyright (c) 2017 Nicolaas Johannes Out\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/fast-stable-stringify/README.md",
    "content": "# fast-stable-stringify\n\nThis project is a fork of [nickyout/fast-stable-stringify](https://github.com/nickyout/fast-stable-stringify)\n\nThe most popular repository providing this feature is [substack's json-stable-stringify](https://www.npmjs.com/package/json-stable-stringify). The intent of this library is to provide a faster alternative for when performance is more important than features. It assumes you provide basic javascript values without circular references, and returns a non-indented string.\n\nUsage:\n\n```javascript\nimport stringify from '@solana/fast-stable-stringify';\nstringify({ d: 0, c: 1, a: 2, b: 3, e: 4 }); // '{\"a\":2,\"b\":3,\"c\":1,\"d\":0,\"e\":4}'\n```\n\nJust like substack's, it:\n\n- handles all variations of all basic javascript values (number, string, boolean, array, object, null, Date, BigInt)\n- handles undefined _and_ function in the same way as `JSON.stringify`\n- **does not support ie8 (and below) with complete certainty**.\n\nUnlike substack's, it:\n\n- does not implement the 'replacer' or 'space' arguments of the JSON.stringify method\n- does not check for circular references\n\n## Running tests\n\n```\nnpm run test:unit:browser\nnpm run test:unit:node\n```\n"
  },
  {
    "path": "packages/fast-stable-stringify/package.json",
    "content": "{\n    \"name\": \"@solana/fast-stable-stringify\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Deterministic stringification for when performance and bundle size matters\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"JSON\",\n        \"stable\",\n        \"deterministic\",\n        \"stringify\",\n        \"fast\",\n        \"BigInt\"\n    ],\n    \"scripts\": {\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"devDependencies\": {\n        \"@types/json-stable-stringify\": \"^1.2.0\",\n        \"json-stable-stringify\": \"^1.3.0\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/fast-stable-stringify/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/fast-stable-stringify/src/__tests__/index-test.ts",
    "content": "import jsonStableStringify from 'json-stable-stringify';\n\nimport stringify from '../index';\n\nclass ImplementingToJSON {\n    toJSON() {\n        return 'dummy!';\n    }\n}\n\nclass NotImplementingToJSON {}\n\ndescribe('fastStableStringify', function () {\n    it.each([\n        [\n            'strings',\n            {\n                BACKSPACE: '\\b',\n                CARRIAGE_RETURN: '\\r',\n                EMPTY_STRING: '',\n                ESCAPE_RANGE: '\\u0000\\u001F',\n                FORM_FEED: '\\f',\n                LINE_FEED: '\\n',\n                LOWERCASE: 'abc',\n                MIXED: 'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b',\n                NON_ESCAPE_RANGE: '\\u0020\\uFFFF',\n                NUMBER_ONLY: '123',\n                QUOTATION_MARK: '\"',\n                REVERSE_SOLIDUS: '\\\\',\n                SOLIDUS: '/',\n                TAB: '\\t',\n                UPPERCASE: 'ABC',\n                UTF16: '☃',\n                VALUES_WITH_SPACES: 'a b c',\n            },\n        ],\n        [\n            'object keys',\n            {\n                '': 'EMPTY_STRING',\n                '\\u0000\\u001F': 'ESCAPE_RANGE',\n                '\\b': 'BACKSPACE',\n                '\\t': 'TAB',\n                '\\n': 'LINE_FEED',\n                '\\f': 'FORM_FEED',\n                '\\r': 'CARRIAGE_RETURN',\n                '\\u0020\\uFFFF': 'NON_ESCAPE_RANGE',\n                '\"': 'QUOTATION_MARK',\n                '/': 'SOLIDUS',\n                ABC: 'UPPERCASE',\n                'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b': 'MIXED',\n                NUMBER_ONLY: '123',\n                '\\\\': 'REVERSE_SOLIDUS',\n                'a b c': 'VALUES_WITH_SPACES',\n                abc: 'LOWERCASE',\n                '☃': 'UTF16',\n            },\n        ],\n        [\n            'numbers',\n            {\n                FALSY: 0,\n                FLOAT: 0.1234567,\n                INFINITY: Infinity,\n                MAX_SAFE_INTEGER: 9007199254740991,\n                MAX_VALUE: 1.7976931348623157e308,\n                MIN_SAFE_INTEGER: -9007199254740991,\n                MIN_VALUE: 5e-324,\n                NAN: NaN,\n                NEGATIVE: -1,\n                NEGATIVE_FLOAT: -0.9876543,\n                NEGATIVE_MAX_VALUE: -1.7976931348623157e308,\n                NEGATIVE_MIN_VALUE: -5e-324,\n                NEG_INFINITY: -Infinity,\n            },\n        ],\n        ['true', true],\n        ['false', false],\n        ['undefined', undefined],\n        ['null', null],\n        ['objects of undefineds', { ONE: undefined, THREE: undefined, TWO: undefined }],\n        ['objects of null', { NULL: null }],\n        ['a Date instance', new Date('2017')],\n        ['a function', function () {}],\n        ['object that implements `toJSON`', new ImplementingToJSON()],\n        ['objects that does not implements `toJSON`', new NotImplementingToJSON()],\n        [\n            'objects of mixed values',\n            {\n                'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b': 'MIXED',\n                FALSE: false,\n                MAX_VALUE: 1.7976931348623157e308,\n                MIN_VALUE: 5e-324,\n                MIXED: 'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b',\n                NEGATIVE_MAX_VALUE: -1.7976931348623157e308,\n                NEGATIVE_MIN_VALUE: -5e-324,\n                NULL: null,\n                TRUE: true,\n                UNDEFINED: undefined,\n                zzz: 'ending',\n            },\n        ],\n        [\n            'arrays of numbers',\n            [\n                9007199254740991,\n                -9007199254740991,\n                0,\n                -1,\n                0.1234567,\n                -0.9876543,\n                1.7976931348623157e308,\n                5e-324,\n                -1.7976931348623157e308,\n                -5e-324,\n                Infinity,\n                -Infinity,\n                NaN,\n            ],\n        ],\n        [\n            'arrays of strings',\n            [\n                'a b c',\n                'abc',\n                'ABC',\n                'NUMBER_ONLY',\n                '',\n                '\\u0000\\u001F',\n                '\\u0020\\uFFFF',\n                '☃',\n                '\"',\n                '\\\\',\n                '/',\n                '\\f',\n                '\\n',\n                '\\r',\n                '\\t',\n                '\\b',\n                'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b',\n            ],\n        ],\n        ['arrays of booleans ', [true, false]],\n        ['arrays of null', [null]],\n        ['arrays of undefined', [undefined]],\n        ['arrays of Date instances', [new Date('2017')]],\n        ['arrays of instances that implement `toJSON`', [new ImplementingToJSON()]],\n        ['arrays of instances that do not implement `toJSON`', [new NotImplementingToJSON()]],\n        ['arrays of functions', [function () {}]],\n        [\n            'arrays of mixed values',\n            [\n                -1.7976931348623157e308,\n                -5e-324,\n                'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b',\n                true,\n                false,\n                null,\n                undefined,\n            ],\n        ],\n        [\n            'mixed values',\n            [\n                {\n                    'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b': 'MIXED',\n                    DATE: new Date('2017'),\n                    FALSE: false,\n                    FUNCTION: function () {},\n                    IMPLEMENTING_TO_JSON: new ImplementingToJSON(),\n                    MAX_VALUE: 1.7976931348623157e308,\n                    MIN_VALUE: 5e-324,\n                    MIXED: 'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b',\n                    NEGATIVE_MAX_VALUE: -1.7976931348623157e308,\n                    NEGATIVE_MIN_VALUE: -5e-324,\n                    NOT_IMPLEMENTING_TO_JSON: new NotImplementingToJSON(),\n                    NULL: null,\n                    TRUE: true,\n                    UNDEFINED: undefined,\n                    zzz: 'ending',\n                },\n                -1.7976931348623157e308,\n                -5e-324,\n                'Aa1 Bb2 Cc3 \\u0000\\u001F\\u0020\\uFFFF☃\"\\\\/\\f\\n\\r\\t\\b',\n                true,\n                false,\n                null,\n                undefined,\n                new Date('2017'),\n                function () {},\n                new ImplementingToJSON(),\n                new NotImplementingToJSON(),\n            ],\n        ],\n    ])('matches the output of `json-stable-stringify` when hashing %s (`%s`)', (_, value) => {\n        expect(stringify(value)).toBe(jsonStableStringify(value));\n    });\n    it('hashes bigints', function () {\n        expect(stringify(200n)).toMatch('200n');\n        expect(stringify({ foo: 100n, goo: '100n' })).toMatch('{\"foo\":100n,\"goo\":\"100n\"}');\n        expect(stringify({ age: BigInt(100n), name: 'Hrushi' })).toMatch('{\"age\":100n,\"name\":\"Hrushi\"}');\n        expect(stringify({ age: [BigInt(100n), BigInt(200n), BigInt(300n)] })).toMatch('{\"age\":[100n,200n,300n]}');\n    });\n});\n"
  },
  {
    "path": "packages/fast-stable-stringify/src/__typetests__/index-typetest.ts",
    "content": "import fastStableStringify from '../index';\n\nfastStableStringify(undefined) satisfies undefined;\nfastStableStringify(function () {}) satisfies undefined;\nfastStableStringify(() => {}) satisfies undefined;\nfastStableStringify(class Foo {}) satisfies undefined;\n\nfastStableStringify({ UNDEFINED: undefined }) satisfies string;\nfastStableStringify({ foo: 'bar' }) satisfies string;\nfastStableStringify([1, 2, 3]) satisfies string;\nfastStableStringify(1n) satisfies string;\nfastStableStringify(BigInt(1)) satisfies string;\nfastStableStringify(1) satisfies string;\nfastStableStringify(5e-324) satisfies string;\nfastStableStringify(0xdeadbeef) satisfies string;\nfastStableStringify(true) satisfies string;\nfastStableStringify(false) satisfies string;\nfastStableStringify('string') satisfies string;\nfastStableStringify(new Date()) satisfies string;\nfastStableStringify(null) satisfies string;\n"
  },
  {
    "path": "packages/fast-stable-stringify/src/index.ts",
    "content": "/**\n * This project is a fork of [nickyout/fast-stable-stringify](https://github.com/nickyout/fast-stable-stringify)\n *\n * The most popular repository providing this feature is [substack's json-stable-stringify](https://www.npmjs.com/package/json-stable-stringify). The intent of this library is to provide a faster alternative for when performance is more important than features. It assumes you provide basic javascript values without circular references, and returns a non-indented string.\n *\n * Just like substack's, it:\n *\n * - handles all variations of all basic javascript values (number, string, boolean, array, object, null, Date, BigInt)\n * - handles undefined _and_ function in the same way as `JSON.stringify`\n * - **does not support ie8 (and below) with complete certainty**.\n *\n * Unlike substack's, it:\n *\n * - does not implement the 'replacer' or 'space' arguments of the JSON.stringify method\n * - does not check for circular references\n *\n * @example\n * ```js\n * import stringify from '@solana/fast-stable-stringify';\n * stringify({ d: 0, c: 1, a: 2, b: 3, e: 4 }); // '{\"a\":2,\"b\":3,\"c\":1,\"d\":0,\"e\":4}'\n * ```\n *\n * @packageDocumentation\n */\nconst objToString = Object.prototype.toString;\nconst objKeys =\n    Object.keys ||\n    function (obj) {\n        const keys = [];\n        for (const name in obj) {\n            keys.push(name);\n        }\n        return keys;\n    };\n\nfunction stringify(val: unknown, isArrayProp: boolean) {\n    let i, max, str, keys, key, propVal, toStr;\n    if (val === true) {\n        return 'true';\n    }\n    if (val === false) {\n        return 'false';\n    }\n    switch (typeof val) {\n        case 'object':\n            if (val === null) {\n                return null;\n            } else if ('toJSON' in val && typeof val.toJSON === 'function') {\n                return stringify(val.toJSON(), isArrayProp);\n            } else {\n                toStr = objToString.call(val);\n                if (toStr === '[object Array]') {\n                    str = '[';\n                    max = (val as unknown[]).length - 1;\n                    for (i = 0; i < max; i++) {\n                        // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n                        str += stringify((val as unknown[])[i], true) + ',';\n                    }\n                    if (max > -1) {\n                        // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n                        str += stringify((val as unknown[])[i], true);\n                    }\n                    return str + ']';\n                } else if (toStr === '[object Object]') {\n                    // only object is left\n                    keys = objKeys(val).sort();\n                    max = keys.length;\n                    str = '';\n                    i = 0;\n                    while (i < max) {\n                        key = keys[i];\n                        propVal = stringify((val as Record<typeof key, unknown>)[key], false);\n                        if (propVal !== undefined) {\n                            if (str) {\n                                str += ',';\n                            }\n                            // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n                            str += JSON.stringify(key) + ':' + propVal;\n                        }\n                        i++;\n                    }\n                    return '{' + str + '}';\n                } else {\n                    return JSON.stringify(val);\n                }\n            }\n        case 'function':\n        case 'undefined':\n            return isArrayProp ? null : undefined;\n        case 'bigint':\n            return `${val.toString()}n`;\n        case 'string':\n            return JSON.stringify(val);\n        default:\n            return isFinite(val as number) ? val : null;\n    }\n}\n\nexport default function (\n    val:\n        | Function // eslint-disable-line @typescript-eslint/no-unsafe-function-type\n        | undefined,\n): undefined;\nexport default function (val: unknown): string;\nexport default function (val: unknown): string | undefined {\n    const returnVal = stringify(val, false);\n    if (returnVal !== undefined) {\n        // eslint-disable-next-line @typescript-eslint/restrict-plus-operands\n        return '' + returnVal;\n    }\n}\n"
  },
  {
    "path": "packages/fast-stable-stringify/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/fast-stable-stringify/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2020\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/fast-stable-stringify\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/fetch-impl/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/fetch-impl/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/fetch-impl/package.json",
    "content": "{\n    \"name\": \"@solana/fetch-impl\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"scripts\": {\n        \"benchmark\": \"./src/__benchmarks__/run.ts\"\n    },\n    \"devDependencies\": {\n        \"tinybench\": \"^6.0.0\",\n        \"undici\": \"^8.2.0\"\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/fetch-impl/src/__benchmarks__/run.ts",
    "content": "#!/usr/bin/env -S pnpm dlx tsx -r ../build-scripts/register-node-globals.cjs\n\nimport { ok } from 'node:assert';\nimport process from 'node:process';\n\nimport { Bench } from 'tinybench';\nimport { Agent, Dispatcher, fetch } from 'undici';\n\nconst NUM_CONCURRENT_REQUESTS = 1024;\nconst URL = process.argv[2];\nok(URL, 'You must supply the URL of a rate-limit-free Solana JSON-RPC server as the first argument to this script');\n\nconst bench = new Bench({\n    throws: true,\n});\n\nlet dispatcher: Dispatcher | undefined;\nfunction createDispatcher(options: Agent.Options) {\n    dispatcher = new Agent({\n        ...options,\n        // One second fewer than the Solana RPC's keepalive timeout.\n        // Read more: https://github.com/solana-labs/solana/issues/27859#issuecomment-1340097889\n        keepAliveTimeout: 19000,\n    });\n}\n\nlet id = 0;\nfunction getTestInit() {\n    return {\n        body: JSON.stringify({\n            id: ++id,\n            jsonrpc: '2.0',\n            method: 'getLatestBlockhash',\n        }),\n        headers: {\n            'content-type': 'application/json',\n        },\n        method: 'POST',\n    };\n}\n\nasync function makeConcurrentRequests(num: number = NUM_CONCURRENT_REQUESTS) {\n    await Promise.all(\n        Array.from({ length: num }).map(() =>\n            fetch(URL, {\n                dispatcher,\n                ...getTestInit(),\n            }),\n        ),\n    );\n}\n\nbench\n    .add('no dispatcher', () => makeConcurrentRequests(), {\n        beforeEach() {\n            dispatcher = undefined;\n        },\n    })\n    .add('unlimited connections http/2', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { allowH2: true, connections: null }),\n    })\n    .add('unlimited connections', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: null }),\n    })\n    .add('16 connections', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 16 }),\n    })\n    .add('16 connections, http/2', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { allowH2: true, connections: 16 }),\n    })\n    .add('16 connections, pipeline 2 wide', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 16, pipelining: 2 }),\n    })\n    .add('32 connections', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 32 }),\n    })\n    .add('32 connections, http/2', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { allowH2: true, connections: 32 }),\n    })\n    .add('32 connections, pipeline 2 wide', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 32, pipelining: 2 }),\n    })\n    .add('64 connections', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 64 }),\n    })\n    .add('64 connections, http/2', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { allowH2: true, connections: 64 }),\n    })\n    .add('64 connections, pipeline 2 wide', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 64, pipelining: 2 }),\n    });\n\nvoid (async () => {\n    await bench.run();\n\n    console.table(bench.table());\n})();\n"
  },
  {
    "path": "packages/fetch-impl/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"esModuleInterop\": true,\n        \"lib\": [\"DOM\", \"ES5\"]\n    },\n    \"display\": \"Fetch Implementation\",\n    \"extends\": \"@solana/tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/fixed-points/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/fixed-points/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/fixed-points/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/fixed-points/CHANGELOG.md",
    "content": "# @solana/fixed-points\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1570](https://github.com/anza-xyz/kit/pull/1570) [`c5e0e14`](https://github.com/anza-xyz/kit/commit/c5e0e1444ae420390047d5e37a13650edf042954) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a new `@solana/fixed-points` package providing precise fixed-point number types for Solana, both decimal (power-of-10 scale) and binary (power-of-2 scale), in signed and unsigned flavors with arbitrary bit widths. The package includes factories, guards, arithmetic, comparisons, signedness conversions, rescaling, string/number formatting, and byte-level codecs. Also re-exported from `@solana/codecs` and `@solana/kit`.\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/codecs-core@6.9.0\n"
  },
  {
    "path": "packages/fixed-points/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/fixed-points/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/fixed-points?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/fixed-points?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/fixed-points\n\n# @solana/fixed-points\n\nThis package provides fixed-point number types for JavaScript without relying on floating-point arithmetic. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nThis package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) which acts as an entry point for all codec packages as well as for their documentation.\n\nTwo flavors are provided: **decimal** fixed-points (scale is a power of 10) and **binary** fixed-points (scale is a power of 2). Use decimal fixed-points to represent prices, token amounts, and any quantity whose precision aligns with decimal digits. Use binary fixed-points when the scale can align with bits — such as audio samples, graphics, or probabilities — and you want to trade base-10 ergonomics for faster arithmetic.\n\n```ts\n// Track a USDC balance without losing pennies to floating-point rounding.\nconst usdc = decimalFixedPoint('unsigned', 64, 6);\nconst balance = addDecimalFixedPoint(usdc('1234.56'), usdc('10.00'));\ndecimalFixedPointToString(balance); // \"1244.56\"\n```\n\nBoth kinds share the same mental model. A value is a frozen object carrying a `bigint` `raw` and some shape metadata (signedness, total bits, scale). A decimal fixed-point represents `raw / 10 ** decimals`; a binary fixed-point represents `raw / 2 ** fractionalBits`.\n\n## Creating fixed-points\n\nThe `decimalFixedPoint` and `binaryFixedPoint` functions each validate a shape once and return a factory you can call many times to build values of that shape.\n\n```ts\nconst usdc = decimalFixedPoint('unsigned', 64, 6); // u64 with 6 decimals\nusdc('42.5'); // raw === 42_500_000n, exact\nusdc('0.1234567'); // throws STRICT_MODE_PRECISION_LOSS (8th decimal is lossy)\n\nconst audioSample = binaryFixedPoint('signed', 16, 15); // Q1.15\naudioSample('0.5'); // raw === 16384n, exact\naudioSample('0.1', 'round'); // raw === 3277n, rounded\n```\n\nUse the `raw*` factories when the raw bigint is already known — for instance when you already have the value stored in its lowest denomination.\n\n```ts\nconst cents = rawDecimalFixedPoint('unsigned', 32, 2);\ncents(4250n); // represents 42.50\n```\n\nUse the `ratio*` factories for values defined as a numerator over a denominator.\n\n```ts\nconst probability = ratioBinaryFixedPoint('signed', 16, 15);\nprobability(1n, 4n); // represents 0.25 exactly\nprobability(1n, 3n, 'round'); // represents ~0.333, rounded\n```\n\n## Rounding modes\n\nAny operation that could lose precision accepts a `RoundingMode`.\n\n| Mode     | Behavior                                                          |\n| -------- | ----------------------------------------------------------------- |\n| `strict` | Throws `STRICT_MODE_PRECISION_LOSS` when the result is not exact. |\n| `floor`  | Rounds towards negative infinity.                                 |\n| `ceil`   | Rounds towards positive infinity.                                 |\n| `trunc`  | Rounds towards zero.                                              |\n| `round`  | Rounds half values away from zero.                                |\n\nThe default is `'strict'`, so precision loss is always explicit. Pass a mode whenever you are willing to accept a rounded result.\n\n## Arithmetic\n\nEvery arithmetic helper preserves the shape of its first operand and throws `ARITHMETIC_OVERFLOW` if the result doesn't fit.\n\n```ts\naddDecimalFixedPoint(usdc('10'), usdc('3.25')); // represents 13.25\nsubtractDecimalFixedPoint(usdc('10'), usdc('3.25')); // represents 6.75\nnegateBinaryFixedPoint(audioSample('0.5')); // represents -0.5 (signed only)\nabsoluteBinaryFixedPoint(audioSample('-0.5')); // represents 0.5\n```\n\n`multiply` and `divide` accept either another fixed-point of the same signedness (any total bits or scale) or a bare `bigint`. The result always has the first operand's shape. They consult the rounding mode when the operation is inexact; `divide` throws `DIVISION_BY_ZERO` on a zero denominator.\n\n```ts\nmultiplyBinaryFixedPoint(audioSample('0.6'), audioSample('0.8')); // ~0.48\ndivideDecimalFixedPoint(usdc('100'), 4n); // represents 25\ndivideDecimalFixedPoint(usdc('1'), usdc('3'), 'floor'); // represents 0.333333\n```\n\n## Comparisons\n\nComparison helpers return a `boolean`, or `-1 | 0 | 1` for `cmp`. Only `kind` and scale must match; `signedness` and `totalBits` may differ.\n\n```ts\ncmpBinaryFixedPoint(audioSample('0.25'), audioSample('0.5')); // -1\neqBinaryFixedPoint(audioSample('0.5'), audioSample('0.5')); // true\nltDecimalFixedPoint(usdc('10'), usdc('20')); // true\nlteDecimalFixedPoint(usdc('20'), usdc('20')); // true\ngtDecimalFixedPoint(usdc('20'), usdc('10')); // true\ngteDecimalFixedPoint(usdc('20'), usdc('20')); // true\n```\n\n## Shape conversions\n\nUse `toSigned*` and `toUnsigned*` to change a value's signedness without touching its total bits or scale.\n\n```ts\nconst signedByte = rawBinaryFixedPoint('signed', 8, 4);\nconst unsignedByte = rawBinaryFixedPoint('unsigned', 8, 4);\n\ntoUnsignedBinaryFixedPoint(signedByte(100n)); // unsigned, raw === 100n\ntoSignedBinaryFixedPoint(unsignedByte(200n)); // throws: 200 > i8 max\n```\n\nUse `rescale*` to change the total bits and scale in one call. Scale-up is always exact; scale-down consults the rounding mode.\n\n```ts\n// Bridge EVM USDC (u128 with 18 decimals) down to SPL USDC (u64 with 6 decimals).\nconst evmUsdc = decimalFixedPoint('unsigned', 128, 18);\nrescaleDecimalFixedPoint(evmUsdc('100.123456789012345678'), 64, 6, 'floor');\n// represents 100.123456\n```\n\n## Formatting\n\n`*ToString` returns the canonical decimal string. Trailing zeros are trimmed by default.\n\n```ts\ndecimalFixedPointToString(usdc('42.5')); // \"42.5\"\ndecimalFixedPointToString(usdc('-0.05')); // \"-0.05\"\nbinaryFixedPointToString(audioSample('0.5')); // \"0.5\"\n```\n\nBinary fixed-points always have a finite decimal expansion, but that expansion can be long (up to `fractionalBits` digits). Pass `options.decimals` with a `RoundingMode` to cap the output.\n\n```ts\nbinaryFixedPointToString(audioSample('0.1')); // \"0.0999755859375\"\nbinaryFixedPointToString(audioSample('0.1'), { decimals: 4, rounding: 'round' }); // \"0.1\"\n```\n\nSet `options.padTrailingZeros` to emit exactly that many fractional digits.\n\n```ts\ndecimalFixedPointToString(usdc('42.5'), { padTrailingZeros: true }); // \"42.500000\"\n```\n\n`*ToNumber` returns a JavaScript `number`. It is inherently lossy — prefer `*ToString` when exactness matters.\n\n```ts\ndecimalFixedPointToNumber(usdc('42.5')); // 42.5\n```\n\nFor locale-aware output, pass any `Intl.NumberFormat` instance to `formatDecimalFixedPoint` or `formatBinaryFixedPoint`. The helpers route the raw bigint through string scientific notation so precision is preserved beyond JavaScript's `number` mantissa.\n\n```ts\nconst eurc = decimalFixedPoint('unsigned', 64, 6);\nconst eurFormatter = new Intl.NumberFormat('de-DE', { currency: 'EUR', style: 'currency' });\nformatDecimalFixedPoint(eurFormatter, eurc('1234.5')); // \"1.234,50 €\"\n```\n\nThe same helper exists for binary fixed-points.\n\n```ts\nconst fr = new Intl.NumberFormat('fr-FR', { maximumFractionDigits: 4 });\nformatBinaryFixedPoint(fr, audioSample('0.1')); // \"0,1\"\n```\n\nTo plug a binary fixed-point into a custom formatter, convert it to its exact base-10 representation with `binaryFixedPointToBase10` first. Decimal fixed-points already carry `raw` and `decimals` directly on the value object, so no equivalent helper is needed for them.\n\n```ts\nbinaryFixedPointToBase10(audioSample('0.5')); // { raw: 500000000000000n, decimals: 15 }\n```\n\n## Type guards\n\nThe `is*` and `assertIs*` guards narrow an unknown value to a fixed-point. All shape arguments are optional — pass `undefined` for any dimension you don't care about.\n\n```ts\nisDecimalFixedPoint(value); // any decimal fixed-point?\nisBinaryFixedPoint(value, 'signed', 16, 15); // specifically an `audioSample`?\nassertIsDecimalFixedPoint(value); // throws SHAPE_MISMATCH if not a decimal fixed-point\n```\n\n## Codecs\n\nFixed-points also come with byte-level codecs compatible with the rest of the [`@solana/codecs`](https://github.com/anza-xyz/kit/tree/main/packages/codecs) ecosystem. The codec is a `FixedSizeCodec` whose size is `totalBits / 8` — `totalBits` must therefore be a multiple of 8.\n\n```ts\nconst codec = getBinaryFixedPointCodec('signed', 16, 15);\nconst bytes = codec.encode(audioSample('0.5')); // 0x0040\ncodec.decode(bytes); // represents 0.5\n```\n\nValues serialize in little-endian by default. Pass `{ endian: 'be' }` for big-endian.\n\n```ts\ngetDecimalFixedPointCodec('unsigned', 64, 6, { endian: 'be' }).encode(usdc('42.5'));\n// 0x0000000002879b9a\n```\n\nSigned values use two's-complement and the codec accepts any byte-aligned width, including non-standard ones like 24, 40, 72, or 136 bits.\n\nSeparate `get*Encoder` and `get*Decoder` functions are also available.\n\n```ts\nconst bytes = getDecimalFixedPointEncoder('unsigned', 64, 6).encode(usdc('42.5'));\nconst value = getDecimalFixedPointDecoder('unsigned', 64, 6).decode(bytes);\n```\n\n## Types\n\n- `BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>` — a binary fixed-point with mathematical value `raw / 2 ** fractionalBits`.\n- `DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>` — a decimal fixed-point with mathematical value `raw / 10 ** decimals`.\n- `Signedness` — `'signed' | 'unsigned'`.\n- `RoundingMode` — `'ceil' | 'floor' | 'round' | 'strict' | 'trunc'`.\n- `FixedPointToStringOptions` — options accepted by `*ToString` (`decimals`, `padTrailingZeros`, `rounding`).\n- `FixedPointCodecConfig` — options accepted by the codec factories (`endian`).\n"
  },
  {
    "path": "packages/fixed-points/package.json",
    "content": "{\n    \"name\": \"@solana/fixed-points\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Fixed-point number types for JavaScript\",\n    \"homepage\": \"https://www.solanakit.com/api#solanafixed-points\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.node.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.native.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/assertions-test.ts",
    "content": "import { getRawRange } from '../assertions';\n\ndescribe('getRawRange', () => {\n    it('returns the range for signed widths', () => {\n        expect(getRawRange('signed', 8)).toEqual({ max: 127n, min: -128n });\n        expect(getRawRange('signed', 16)).toEqual({ max: 32767n, min: -32768n });\n        expect(getRawRange('signed', 64)).toEqual({\n            max: 9223372036854775807n,\n            min: -9223372036854775808n,\n        });\n    });\n\n    it('returns the range for unsigned widths', () => {\n        expect(getRawRange('unsigned', 8)).toEqual({ max: 255n, min: 0n });\n        expect(getRawRange('unsigned', 16)).toEqual({ max: 65535n, min: 0n });\n        expect(getRawRange('unsigned', 64)).toEqual({\n            max: 18446744073709551615n,\n            min: 0n,\n        });\n    });\n\n    it('supports any arbitrary bit widths', () => {\n        expect(getRawRange('unsigned', 123)).toEqual({\n            max: (1n << 123n) - 1n,\n            min: 0n,\n        });\n        expect(getRawRange('signed', 123)).toEqual({\n            max: (1n << 122n) - 1n,\n            min: -(1n << 122n),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/binary-arithmetics-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    absoluteBinaryFixedPoint,\n    addBinaryFixedPoint,\n    binaryFixedPoint,\n    divideBinaryFixedPoint,\n    multiplyBinaryFixedPoint,\n    negateBinaryFixedPoint,\n    rawBinaryFixedPoint,\n    subtractBinaryFixedPoint,\n} from '../binary';\n\ndescribe('addBinaryFixedPoint', () => {\n    it('adds two values of the same shape', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(addBinaryFixedPoint(q1_15('0.25'), q1_15('0.5')).raw).toBe(2n ** 13n + 2n ** 14n);\n    });\n\n    it('returns a frozen value', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(addBinaryFixedPoint(q1_15('0.25'), q1_15('0.5'))).toBeFrozenObject();\n    });\n\n    it('throws SHAPE_MISMATCH when the operands have different shapes', () => {\n        const q1_15 = rawBinaryFixedPoint('signed', 16, 15);\n        const q8_8 = rawBinaryFixedPoint('signed', 16, 8);\n        expect(() =>\n            // @ts-expect-error Operands must share the same shape.\n            addBinaryFixedPoint(q1_15(1n), q8_8(1n)),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'binaryFixedPoint',\n                actualScale: 8,\n                actualScaleLabel: 'fractional bits',\n                actualSignedness: 'signed',\n                actualTotalBits: 16,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 15,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'signed',\n                expectedTotalBits: 16,\n                operation: 'addBinaryFixedPoint',\n            }),\n        );\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when the sum exceeds the upper bound', () => {\n        const factory = rawBinaryFixedPoint('signed', 8, 0);\n        expect(() => addBinaryFixedPoint(factory(100n), factory(50n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                operation: 'add',\n                result: 150n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('subtractBinaryFixedPoint', () => {\n    it('subtracts two values of the same shape', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(subtractBinaryFixedPoint(q1_15('0.75'), q1_15('0.5')).raw).toBe(2n ** 13n);\n    });\n\n    it('returns a frozen value', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(subtractBinaryFixedPoint(q1_15('0.75'), q1_15('0.5'))).toBeFrozenObject();\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when the difference is below the lower bound', () => {\n        const factory = rawBinaryFixedPoint('unsigned', 8, 0);\n        expect(() => subtractBinaryFixedPoint(factory(1n), factory(2n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'binaryFixedPoint',\n                max: 255n,\n                min: 0n,\n                operation: 'subtract',\n                result: -1n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('multiplyBinaryFixedPoint', () => {\n    it('multiplies two values of the same shape', () => {\n        // 0.5 × 0.5 = 0.25 at Q1.15 → raw = 2^13\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(multiplyBinaryFixedPoint(q1_15('0.5'), q1_15('0.5')).raw).toBe(2n ** 13n);\n    });\n\n    it('multiplies by a fixed-point operand with a different totalBits and fractionalBits', () => {\n        // 0.5 (raw 16384 at 15 fractional bits) × 0.25 (raw 4 at 4 fractional bits)\n        // rescales back to 15 fractional bits: (16384 × 4) / 2^4 = 65536 / 16 = 4096 = 2^12.\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        const q4_4 = rawBinaryFixedPoint('signed', 8, 4);\n        expect(multiplyBinaryFixedPoint(q1_15('0.5'), q4_4(4n)).raw).toBe(2n ** 12n);\n    });\n\n    it('multiplies by a bigint scalar', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(multiplyBinaryFixedPoint(q1_15('0.25'), 2n).raw).toBe(2n ** 14n);\n        expect(multiplyBinaryFixedPoint(q1_15('0.25'), -2n).raw).toBe(-(2n ** 14n));\n    });\n\n    it('returns a frozen value', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(multiplyBinaryFixedPoint(q1_15('0.25'), 2n)).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when the product is inexact', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        // 1/3 × 1/3 in Q1.15 requires rounding.\n        expect(() => multiplyBinaryFixedPoint(q1_15('0.25'), rawBinaryFixedPoint('signed', 16, 15)(1n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'binaryFixedPoint',\n                operation: 'multiply',\n            }),\n        );\n    });\n\n    it('rounds an inexact product when a non-strict rounding mode is supplied', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        const tiny = rawBinaryFixedPoint('signed', 16, 15)(1n);\n        expect(multiplyBinaryFixedPoint(q1_15('0.25'), tiny, 'floor').raw).toBe(0n);\n        expect(multiplyBinaryFixedPoint(q1_15('0.25'), tiny, 'ceil').raw).toBe(1n);\n    });\n\n    it('throws SHAPE_MISMATCH when the fixed-point operand has a different signedness', () => {\n        const signed = binaryFixedPoint('signed', 16, 15);\n        const unsigned = rawBinaryFixedPoint('unsigned', 16, 15);\n        expect(() =>\n            // @ts-expect-error Second operand must share the first operand's signedness.\n            multiplyBinaryFixedPoint(signed('0.25'), unsigned(1n)),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'binaryFixedPoint',\n                actualScale: 15,\n                actualScaleLabel: 'fractional bits',\n                actualSignedness: 'unsigned',\n                actualTotalBits: 16,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 15,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'signed',\n                expectedTotalBits: 16,\n                operation: 'multiplyBinaryFixedPoint',\n            }),\n        );\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when the product does not fit the target shape', () => {\n        const int8 = rawBinaryFixedPoint('signed', 8, 0);\n        expect(() => multiplyBinaryFixedPoint(int8(100n), 2n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                operation: 'multiply',\n                result: 200n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('divideBinaryFixedPoint', () => {\n    it('divides by a fixed-point operand of the same shape', () => {\n        // 0.5 ÷ 0.25 = 2.0; 3 integer bits provide enough headroom for the result.\n        const q3_13 = binaryFixedPoint('signed', 16, 13);\n        expect(divideBinaryFixedPoint(q3_13('0.5'), q3_13('0.25')).raw).toBe(2n ** 14n);\n    });\n\n    it('divides by a fixed-point operand with a different totalBits and fractionalBits', () => {\n        // 0.5 (raw 4096 at 13 fractional bits) ÷ 0.25 (raw 4 at 4 fractional bits)\n        // rescales back to 13 fractional bits: (4096 × 2^4) / 4 = 65536 / 4 = 16384.\n        const q3_13 = binaryFixedPoint('signed', 16, 13);\n        const q4_4 = rawBinaryFixedPoint('signed', 8, 4);\n        expect(divideBinaryFixedPoint(q3_13('0.5'), q4_4(4n)).raw).toBe(2n ** 14n);\n    });\n\n    it('divides by a bigint scalar', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(divideBinaryFixedPoint(q1_15('0.5'), 2n).raw).toBe(2n ** 13n);\n    });\n\n    it('returns a frozen value', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(divideBinaryFixedPoint(q1_15('0.5'), 2n)).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when the division is inexact', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() => divideBinaryFixedPoint(q1_15('0.5'), 3n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'binaryFixedPoint',\n                operation: 'divide',\n            }),\n        );\n    });\n\n    it('rounds an inexact division when a non-strict rounding mode is supplied', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        // 16384 / 3 = 5461.33…\n        expect(divideBinaryFixedPoint(q1_15('0.5'), 3n, 'floor').raw).toBe(5461n);\n        expect(divideBinaryFixedPoint(q1_15('0.5'), 3n, 'ceil').raw).toBe(5462n);\n    });\n\n    it('throws DIVISION_BY_ZERO when dividing by a bigint zero', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() => divideBinaryFixedPoint(q1_15('0.5'), 0n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO, {\n                kind: 'binaryFixedPoint',\n                signedness: 'signed',\n                totalBits: 16,\n            }),\n        );\n    });\n\n    it('throws DIVISION_BY_ZERO when dividing by a fixed-point zero', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() => divideBinaryFixedPoint(q1_15('0.5'), q1_15('0'))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO, {\n                kind: 'binaryFixedPoint',\n                signedness: 'signed',\n                totalBits: 16,\n            }),\n        );\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when the quotient does not fit the target shape', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() => divideBinaryFixedPoint(q1_15('0.5'), q1_15('0.25'))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'binaryFixedPoint',\n                max: 32767n,\n                min: -32768n,\n                operation: 'divide',\n                result: 65536n,\n                signedness: 'signed',\n                totalBits: 16,\n            }),\n        );\n    });\n});\n\ndescribe('negateBinaryFixedPoint', () => {\n    it('negates a signed value', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(negateBinaryFixedPoint(q1_15('0.5')).raw).toBe(-(2n ** 14n));\n        expect(negateBinaryFixedPoint(q1_15('-0.5')).raw).toBe(2n ** 14n);\n    });\n\n    it('returns a frozen value', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(negateBinaryFixedPoint(q1_15('0.5'))).toBeFrozenObject();\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when negating the minimum signed value', () => {\n        const factory = rawBinaryFixedPoint('signed', 8, 0);\n        expect(() => negateBinaryFixedPoint(factory(-128n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                operation: 'negate',\n                result: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when called on an unsigned value at runtime', () => {\n        const unsigned = rawBinaryFixedPoint('unsigned', 16, 15)(1n);\n        expect(() =>\n            // @ts-expect-error Only signed values can be negated.\n            negateBinaryFixedPoint(unsigned),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'binaryFixedPoint',\n                actualScale: 15,\n                actualScaleLabel: 'fractional bits',\n                actualSignedness: 'unsigned',\n                actualTotalBits: 16,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 15,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'signed',\n                expectedTotalBits: 16,\n                operation: 'negateBinaryFixedPoint',\n            }),\n        );\n    });\n});\n\ndescribe('absoluteBinaryFixedPoint', () => {\n    it('returns the absolute value of a signed negative', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(absoluteBinaryFixedPoint(q1_15('-0.5')).raw).toBe(2n ** 14n);\n    });\n\n    it('returns the signed positive unchanged', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(absoluteBinaryFixedPoint(q1_15('0.5')).raw).toBe(2n ** 14n);\n    });\n\n    it('returns the unsigned input unchanged', () => {\n        const unsigned = binaryFixedPoint('unsigned', 16, 15);\n        expect(absoluteBinaryFixedPoint(unsigned('0.5')).raw).toBe(2n ** 14n);\n    });\n\n    it('returns a frozen value', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(absoluteBinaryFixedPoint(q1_15('-0.5'))).toBeFrozenObject();\n    });\n\n    it('throws ARITHMETIC_OVERFLOW on the minimum signed value', () => {\n        const factory = rawBinaryFixedPoint('signed', 8, 0);\n        expect(() => absoluteBinaryFixedPoint(factory(-128n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                operation: 'absolute',\n                result: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/binary-codec-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY,\n    SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    binaryFixedPoint,\n    getBinaryFixedPointCodec,\n    getBinaryFixedPointDecoder,\n    getBinaryFixedPointEncoder,\n    rawBinaryFixedPoint,\n} from '../binary';\n\ndescribe('getBinaryFixedPointEncoder', () => {\n    it('encodes an unsigned 8-bit value', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 8, 0);\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 8, 0)(42n))).toEqual(new Uint8Array([0x2a]));\n    });\n\n    it(\"encodes a signed 8-bit negative value using two's-complement\", () => {\n        const encoder = getBinaryFixedPointEncoder('signed', 8, 0);\n        expect(encoder.encode(rawBinaryFixedPoint('signed', 8, 0)(-1n))).toEqual(new Uint8Array([0xff]));\n    });\n\n    it('encodes a signed 16-bit value at 15 fractional bits in little-endian by default', () => {\n        const encoder = getBinaryFixedPointEncoder('signed', 16, 15);\n        expect(encoder.encode(binaryFixedPoint('signed', 16, 15)('0.5'))).toEqual(new Uint8Array([0x00, 0x40]));\n    });\n\n    it('encodes a signed 16-bit negative value at 15 fractional bits in little-endian', () => {\n        const encoder = getBinaryFixedPointEncoder('signed', 16, 15);\n        expect(encoder.encode(binaryFixedPoint('signed', 16, 15)('-0.5'))).toEqual(new Uint8Array([0x00, 0xc0]));\n    });\n\n    it('encodes in big-endian when configured', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 16, 0, { endian: 'be' });\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 16, 0)(0x1234n))).toEqual(new Uint8Array([0x12, 0x34]));\n    });\n\n    it('encodes an unsigned 24-bit value (byte-aligned width without a matching number codec)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 24, 0);\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 24, 0)(0xabcdefn))).toEqual(\n            new Uint8Array([0xef, 0xcd, 0xab]),\n        );\n    });\n\n    it('encodes an unsigned 24-bit value in big-endian (exercises residual positioning)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 24, 0, { endian: 'be' });\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 24, 0)(0xabcdefn))).toEqual(\n            new Uint8Array([0xab, 0xcd, 0xef]),\n        );\n    });\n\n    it('encodes an unsigned 72-bit value in little-endian (exercises one full chunk + one residual byte)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 72, 0);\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 72, 0)(0x112233445566778899n))).toEqual(\n            new Uint8Array([0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]),\n        );\n    });\n\n    it('encodes an unsigned 72-bit value in big-endian (exercises one full chunk + one residual byte)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 72, 0, { endian: 'be' });\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 72, 0)(0x112233445566778899n))).toEqual(\n            new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99]),\n        );\n    });\n\n    it('encodes an unsigned 40-bit value in little-endian (residual = 32-bit + 8-bit)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 40, 0);\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 40, 0)(0x1122334455n))).toEqual(\n            new Uint8Array([0x55, 0x44, 0x33, 0x22, 0x11]),\n        );\n    });\n\n    it('encodes an unsigned 40-bit value in big-endian (residual = 32-bit + 8-bit)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 40, 0, { endian: 'be' });\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 40, 0)(0x1122334455n))).toEqual(\n            new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55]),\n        );\n    });\n\n    it('encodes an unsigned 48-bit value in little-endian (residual = 32-bit + 16-bit)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 48, 0);\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 48, 0)(0x112233445566n))).toEqual(\n            new Uint8Array([0x66, 0x55, 0x44, 0x33, 0x22, 0x11]),\n        );\n    });\n\n    it('encodes an unsigned 48-bit value in big-endian (residual = 32-bit + 16-bit)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 48, 0, { endian: 'be' });\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 48, 0)(0x112233445566n))).toEqual(\n            new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66]),\n        );\n    });\n\n    it('encodes an unsigned 56-bit value in little-endian (residual = 32-bit + 16-bit + 8-bit)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 56, 0);\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 56, 0)(0x11223344556677n))).toEqual(\n            new Uint8Array([0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11]),\n        );\n    });\n\n    it('encodes an unsigned 56-bit value in big-endian (residual = 32-bit + 16-bit + 8-bit)', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 56, 0, { endian: 'be' });\n        expect(encoder.encode(rawBinaryFixedPoint('unsigned', 56, 0)(0x11223344556677n))).toEqual(\n            new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77]),\n        );\n    });\n\n    it('encodes an unsigned 128-bit value in little-endian', () => {\n        const encoder = getBinaryFixedPointEncoder('unsigned', 128, 0);\n        const bytes = encoder.encode(rawBinaryFixedPoint('unsigned', 128, 0)(0x0102030405060708090a0b0c0d0e0f10n));\n        expect(bytes).toEqual(\n            new Uint8Array([\n                0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01,\n            ]),\n        );\n    });\n\n    it('reports the correct fixed size', () => {\n        expect(getBinaryFixedPointEncoder('signed', 16, 15).fixedSize).toBe(2);\n        expect(getBinaryFixedPointEncoder('unsigned', 128, 0).fixedSize).toBe(16);\n    });\n\n    it('throws TOTAL_BITS_NOT_BYTE_ALIGNED for a non-byte-aligned total bits', () => {\n        expect(() => getBinaryFixedPointEncoder('unsigned', 12, 4)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED, {\n                kind: 'binaryFixedPoint',\n                totalBits: 12,\n            }),\n        );\n    });\n\n    it('throws INVALID_TOTAL_BITS for a non-positive total bits', () => {\n        expect(() => getBinaryFixedPointEncoder('unsigned', 0, 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n                kind: 'binaryFixedPoint',\n                totalBits: 0,\n            }),\n        );\n    });\n\n    it('throws INVALID_FRACTIONAL_BITS for a negative fractional bits', () => {\n        expect(() => getBinaryFixedPointEncoder('signed', 16, -1)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS, {\n                fractionalBits: -1,\n            }),\n        );\n    });\n\n    it('throws FRACTIONAL_BITS_EXCEED_TOTAL_BITS when fractional bits exceed total bits', () => {\n        expect(() => getBinaryFixedPointEncoder('signed', 8, 16)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS, {\n                fractionalBits: 16,\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when encoding a value whose shape does not match the codec', () => {\n        const encoder = getBinaryFixedPointEncoder('signed', 16, 15);\n        const mismatched = rawBinaryFixedPoint('signed', 16, 8)(1n);\n        expect(() =>\n            // @ts-expect-error The value's shape does not match the codec's shape.\n            encoder.encode(mismatched),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'binaryFixedPoint',\n                actualScale: 8,\n                actualScaleLabel: 'fractional bits',\n                actualSignedness: 'signed',\n                actualTotalBits: 16,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 15,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'signed',\n                expectedTotalBits: 16,\n                operation: 'getBinaryFixedPointEncoder',\n            }),\n        );\n    });\n});\n\ndescribe('getBinaryFixedPointDecoder', () => {\n    it('decodes an unsigned 8-bit value', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 8, 0);\n        expect(decoder.decode(new Uint8Array([0x2a]))).toEqual({\n            fractionalBits: 0,\n            kind: 'binaryFixedPoint',\n            raw: 42n,\n            signedness: 'unsigned',\n            totalBits: 8,\n        });\n    });\n\n    it(\"decodes a signed 8-bit negative value via two's-complement\", () => {\n        const decoder = getBinaryFixedPointDecoder('signed', 8, 0);\n        expect(decoder.decode(new Uint8Array([0xff])).raw).toBe(-1n);\n    });\n\n    it('decodes a signed 16-bit value at 15 fractional bits in little-endian', () => {\n        const decoder = getBinaryFixedPointDecoder('signed', 16, 15);\n        expect(decoder.decode(new Uint8Array([0x00, 0x40])).raw).toBe(16384n);\n    });\n\n    it('decodes a signed 16-bit negative value at 15 fractional bits in little-endian', () => {\n        const decoder = getBinaryFixedPointDecoder('signed', 16, 15);\n        expect(decoder.decode(new Uint8Array([0x00, 0xc0])).raw).toBe(-16384n);\n    });\n\n    it('decodes in big-endian when configured', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 16, 0, { endian: 'be' });\n        expect(decoder.decode(new Uint8Array([0x12, 0x34])).raw).toBe(0x1234n);\n    });\n\n    it('decodes an unsigned 24-bit value', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 24, 0);\n        expect(decoder.decode(new Uint8Array([0xef, 0xcd, 0xab])).raw).toBe(0xabcdefn);\n    });\n\n    it('decodes an unsigned 72-bit value in little-endian (exercises one full chunk + one residual byte)', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 72, 0);\n        expect(decoder.decode(new Uint8Array([0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])).raw).toBe(\n            0x112233445566778899n,\n        );\n    });\n\n    it('decodes an unsigned 72-bit value in big-endian (exercises one full chunk + one residual byte)', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 72, 0, { endian: 'be' });\n        expect(decoder.decode(new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99])).raw).toBe(\n            0x112233445566778899n,\n        );\n    });\n\n    it('decodes an unsigned 40-bit value in little-endian (residual = 32-bit + 8-bit)', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 40, 0);\n        expect(decoder.decode(new Uint8Array([0x55, 0x44, 0x33, 0x22, 0x11])).raw).toBe(0x1122334455n);\n    });\n\n    it('decodes an unsigned 40-bit value in big-endian (residual = 32-bit + 8-bit)', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 40, 0, { endian: 'be' });\n        expect(decoder.decode(new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55])).raw).toBe(0x1122334455n);\n    });\n\n    it('decodes an unsigned 48-bit value in little-endian (residual = 32-bit + 16-bit)', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 48, 0);\n        expect(decoder.decode(new Uint8Array([0x66, 0x55, 0x44, 0x33, 0x22, 0x11])).raw).toBe(0x112233445566n);\n    });\n\n    it('decodes an unsigned 48-bit value in big-endian (residual = 32-bit + 16-bit)', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 48, 0, { endian: 'be' });\n        expect(decoder.decode(new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66])).raw).toBe(0x112233445566n);\n    });\n\n    it('decodes an unsigned 56-bit value in little-endian (residual = 32-bit + 16-bit + 8-bit)', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 56, 0);\n        expect(decoder.decode(new Uint8Array([0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11])).raw).toBe(0x11223344556677n);\n    });\n\n    it('decodes an unsigned 56-bit value in big-endian (residual = 32-bit + 16-bit + 8-bit)', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 56, 0, { endian: 'be' });\n        expect(decoder.decode(new Uint8Array([0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77])).raw).toBe(0x11223344556677n);\n    });\n\n    it('returns a frozen value', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 8, 0);\n        expect(decoder.decode(new Uint8Array([0x2a]))).toBeFrozenObject();\n    });\n\n    it('throws TOTAL_BITS_NOT_BYTE_ALIGNED for a non-byte-aligned total bits', () => {\n        expect(() => getBinaryFixedPointDecoder('unsigned', 12, 4)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED, {\n                kind: 'binaryFixedPoint',\n                totalBits: 12,\n            }),\n        );\n    });\n\n    it('throws CANNOT_DECODE_EMPTY_BYTE_ARRAY when decoding from an empty buffer', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 16, 0);\n        expect(() => decoder.decode(new Uint8Array([]))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY, {\n                codecDescription: 'getBinaryFixedPointDecoder',\n            }),\n        );\n    });\n\n    it('throws INVALID_BYTE_LENGTH when decoding from a too-short buffer', () => {\n        const decoder = getBinaryFixedPointDecoder('unsigned', 32, 0);\n        expect(() => decoder.decode(new Uint8Array([0x01, 0x02]))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n                bytesLength: 2,\n                codecDescription: 'getBinaryFixedPointDecoder',\n                expected: 4,\n            }),\n        );\n    });\n});\n\ndescribe('getBinaryFixedPointCodec', () => {\n    describe.each([{ endian: 'le' as const }, { endian: 'be' as const }])('under $endian endianness', ({ endian }) => {\n        it.each([\n            { fractionalBits: 0, raw: 42n, signedness: 'signed' as const, totalBits: 8 },\n            { fractionalBits: 0, raw: -42n, signedness: 'signed' as const, totalBits: 8 },\n            { fractionalBits: 15, raw: 16384n, signedness: 'signed' as const, totalBits: 16 },\n            { fractionalBits: 15, raw: -16384n, signedness: 'signed' as const, totalBits: 16 },\n            // 24 bits exercises the all-residual path (no full 8-byte chunks).\n            { fractionalBits: 0, raw: 0xabcdefn, signedness: 'unsigned' as const, totalBits: 24 },\n            { fractionalBits: 0, raw: -0xabcden, signedness: 'signed' as const, totalBits: 24 },\n            { fractionalBits: 0, raw: 0xffffffffn, signedness: 'unsigned' as const, totalBits: 32 },\n            // 40/48/56 bits exercise the greedy residual (32+8, 32+16, 32+16+8).\n            { fractionalBits: 0, raw: 0x1122334455n, signedness: 'unsigned' as const, totalBits: 40 },\n            { fractionalBits: 0, raw: 0x112233445566n, signedness: 'unsigned' as const, totalBits: 48 },\n            { fractionalBits: 0, raw: 0x11223344556677n, signedness: 'unsigned' as const, totalBits: 56 },\n            { fractionalBits: 0, raw: 0x0123456789abcdefn, signedness: 'signed' as const, totalBits: 64 },\n            // 72 bits exercises one full chunk + one residual byte.\n            { fractionalBits: 0, raw: 0x112233445566778899n, signedness: 'unsigned' as const, totalBits: 72 },\n            {\n                fractionalBits: 0,\n                raw: 0x00112233445566778899aabbccddeeffn,\n                signedness: 'unsigned' as const,\n                totalBits: 128,\n            },\n            // 136 bits exercises two full chunks + one residual byte.\n            {\n                fractionalBits: 0,\n                raw: 0x0102030405060708091011121314151617n,\n                signedness: 'unsigned' as const,\n                totalBits: 136,\n            },\n        ])(\n            'round-trips $signedness $totalBits-bit values with $fractionalBits fractional bits (raw $raw)',\n            ({ signedness, totalBits, fractionalBits, raw }) => {\n                const codec = getBinaryFixedPointCodec(signedness, totalBits, fractionalBits, { endian });\n                const value = rawBinaryFixedPoint(signedness, totalBits, fractionalBits)(raw);\n                const decoded = codec.decode(codec.encode(value));\n                expect(decoded.raw).toBe(raw);\n                expect(decoded.signedness).toBe(signedness);\n                expect(decoded.totalBits).toBe(totalBits);\n                expect(decoded.fractionalBits).toBe(fractionalBits);\n            },\n        );\n    });\n\n    it('produces the same bytes as a straightforward u16 serialization for unsigned 16-bit values', () => {\n        // This interop check ensures the codec is wire-compatible with standard u16 little-endian layouts.\n        const codec = getBinaryFixedPointCodec('unsigned', 16, 0);\n        const encoded = codec.encode(rawBinaryFixedPoint('unsigned', 16, 0)(0xbeefn));\n        expect(encoded).toEqual(new Uint8Array([0xef, 0xbe]));\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/binary-comparisons-test.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, SolanaError } from '@solana/errors';\n\nimport {\n    binaryFixedPoint,\n    cmpBinaryFixedPoint,\n    eqBinaryFixedPoint,\n    gtBinaryFixedPoint,\n    gteBinaryFixedPoint,\n    ltBinaryFixedPoint,\n    lteBinaryFixedPoint,\n    rawBinaryFixedPoint,\n} from '../binary';\n\ndescribe('cmpBinaryFixedPoint', () => {\n    it('returns -1 when the first operand is smaller', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(cmpBinaryFixedPoint(q1_15('0.25'), q1_15('0.5'))).toBe(-1);\n    });\n\n    it('returns 0 when the two operands are equal', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(cmpBinaryFixedPoint(q1_15('0.5'), q1_15('0.5'))).toBe(0);\n    });\n\n    it('returns 1 when the first operand is greater', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(cmpBinaryFixedPoint(q1_15('0.75'), q1_15('0.5'))).toBe(1);\n    });\n\n    it('compares negative and positive signed values correctly', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(cmpBinaryFixedPoint(q1_15('-0.5'), q1_15('0.5'))).toBe(-1);\n        expect(cmpBinaryFixedPoint(q1_15('-0.5'), q1_15('-0.5'))).toBe(0);\n        expect(cmpBinaryFixedPoint(q1_15('-0.25'), q1_15('-0.5'))).toBe(1);\n    });\n\n    it('treats zero as equal to zero', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(cmpBinaryFixedPoint(q1_15('0'), q1_15('0'))).toBe(0);\n    });\n\n    it('treats minus zero as equal to zero', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(cmpBinaryFixedPoint(q1_15('-0'), q1_15('0'))).toBe(0);\n    });\n\n    it('allows operands with different signedness', () => {\n        const signed = rawBinaryFixedPoint('signed', 16, 15);\n        const unsigned = rawBinaryFixedPoint('unsigned', 16, 15);\n        expect(cmpBinaryFixedPoint(signed(-1n), unsigned(1n))).toBe(-1);\n        expect(cmpBinaryFixedPoint(signed(1n), unsigned(1n))).toBe(0);\n        expect(cmpBinaryFixedPoint(signed(2n), unsigned(1n))).toBe(1);\n    });\n\n    it('allows operands with different totalBits', () => {\n        const small = rawBinaryFixedPoint('unsigned', 8, 4);\n        const large = rawBinaryFixedPoint('unsigned', 32, 4);\n        expect(cmpBinaryFixedPoint(small(16n), large(16n))).toBe(0);\n        expect(cmpBinaryFixedPoint(small(16n), large(32n))).toBe(-1);\n    });\n\n    it('allows operands with different signedness and totalBits combined', () => {\n        const signed8 = rawBinaryFixedPoint('signed', 8, 0);\n        const unsigned32 = rawBinaryFixedPoint('unsigned', 32, 0);\n        expect(cmpBinaryFixedPoint(signed8(5n), unsigned32(5n))).toBe(0);\n    });\n\n    it('throws SHAPE_MISMATCH when fractionalBits differ', () => {\n        const q1_15 = rawBinaryFixedPoint('signed', 16, 15);\n        const q8_8 = rawBinaryFixedPoint('signed', 16, 8);\n        expect(() =>\n            // @ts-expect-error Operands must share the same fractionalBits.\n            cmpBinaryFixedPoint(q1_15(1n), q8_8(1n)),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'binaryFixedPoint',\n                actualScale: 8,\n                actualScaleLabel: 'fractional bits',\n                actualSignedness: 'signed',\n                actualTotalBits: 16,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 15,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'signed',\n                expectedTotalBits: 16,\n                operation: 'cmpBinaryFixedPoint',\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when the second operand is not a fixed-point value', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() =>\n            // @ts-expect-error Second operand must be a BinaryFixedPoint.\n            cmpBinaryFixedPoint(q1_15('0.5'), 42),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'unknown',\n                actualScale: 0,\n                actualScaleLabel: 'unknown',\n                actualSignedness: 'unknown',\n                actualTotalBits: 0,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 15,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'unknown',\n                expectedTotalBits: 0,\n                operation: 'cmpBinaryFixedPoint',\n            }),\n        );\n    });\n});\n\ndescribe('eqBinaryFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(eqBinaryFixedPoint(q1_15('0.25'), q1_15('0.5'))).toBe(false);\n        expect(eqBinaryFixedPoint(q1_15('0.5'), q1_15('0.5'))).toBe(true);\n        expect(eqBinaryFixedPoint(q1_15('0.75'), q1_15('0.5'))).toBe(false);\n    });\n});\n\ndescribe('ltBinaryFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(ltBinaryFixedPoint(q1_15('0.25'), q1_15('0.5'))).toBe(true);\n        expect(ltBinaryFixedPoint(q1_15('0.5'), q1_15('0.5'))).toBe(false);\n        expect(ltBinaryFixedPoint(q1_15('0.75'), q1_15('0.5'))).toBe(false);\n    });\n});\n\ndescribe('lteBinaryFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(lteBinaryFixedPoint(q1_15('0.25'), q1_15('0.5'))).toBe(true);\n        expect(lteBinaryFixedPoint(q1_15('0.5'), q1_15('0.5'))).toBe(true);\n        expect(lteBinaryFixedPoint(q1_15('0.75'), q1_15('0.5'))).toBe(false);\n    });\n});\n\ndescribe('gtBinaryFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(gtBinaryFixedPoint(q1_15('0.25'), q1_15('0.5'))).toBe(false);\n        expect(gtBinaryFixedPoint(q1_15('0.5'), q1_15('0.5'))).toBe(false);\n        expect(gtBinaryFixedPoint(q1_15('0.75'), q1_15('0.5'))).toBe(true);\n    });\n});\n\ndescribe('gteBinaryFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(gteBinaryFixedPoint(q1_15('0.25'), q1_15('0.5'))).toBe(false);\n        expect(gteBinaryFixedPoint(q1_15('0.5'), q1_15('0.5'))).toBe(true);\n        expect(gteBinaryFixedPoint(q1_15('0.75'), q1_15('0.5'))).toBe(true);\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/binary-conversions-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    binaryFixedPoint,\n    binaryFixedPointToBase10,\n    rawBinaryFixedPoint,\n    rescaleBinaryFixedPoint,\n    toSignedBinaryFixedPoint,\n    toUnsignedBinaryFixedPoint,\n} from '../binary';\n\ndescribe('binaryFixedPointToBase10', () => {\n    it('returns a zero raw and the value fractionalBits as decimals for zero', () => {\n        const value = rawBinaryFixedPoint('signed', 16, 15)(0n);\n        expect(binaryFixedPointToBase10(value)).toStrictEqual({ decimals: 15, raw: 0n });\n    });\n\n    it('returns the input raw unchanged when fractionalBits is zero', () => {\n        const value = rawBinaryFixedPoint('signed', 8, 0)(-42n);\n        expect(binaryFixedPointToBase10(value)).toStrictEqual({ decimals: 0, raw: -42n });\n    });\n\n    it('scales the raw by 5 ** fractionalBits to reach base 10', () => {\n        // raw 1 at QX.1 represents 0.5 → (1 * 5) / 10 = 0.5.\n        const value = rawBinaryFixedPoint('unsigned', 8, 1)(1n);\n        expect(binaryFixedPointToBase10(value)).toStrictEqual({ decimals: 1, raw: 5n });\n    });\n\n    it('preserves the sign of negative values', () => {\n        // raw -16384 at Q1.15 represents -0.5 → (-16384 * 5 ** 15) / 10 ** 15.\n        const value = rawBinaryFixedPoint('signed', 16, 15)(-16384n);\n        const base10 = binaryFixedPointToBase10(value);\n        expect(base10.decimals).toBe(15);\n        expect(base10.raw).toBe(-500000000000000n);\n    });\n\n    it('produces the full exact decimal expansion for a smallest-unit value', () => {\n        // 1 / 2 ** 15 = 0.000030517578125 = 30517578125 / 10 ** 15.\n        const value = rawBinaryFixedPoint('unsigned', 16, 15)(1n);\n        expect(binaryFixedPointToBase10(value)).toStrictEqual({ decimals: 15, raw: 30517578125n });\n    });\n\n    it('handles raw values that exceed Number.MAX_SAFE_INTEGER', () => {\n        // raw 2 ** 60 at QX.20 represents 2 ** 40 → (2 ** 60) * 5 ** 20 / 10 ** 20.\n        const raw = 1n << 60n;\n        const value = rawBinaryFixedPoint('unsigned', 128, 20)(raw);\n        const base10 = binaryFixedPointToBase10(value);\n        expect(base10.decimals).toBe(20);\n        expect(base10.raw).toBe(raw * 5n ** 20n);\n        // Sanity-check the round trip: dividing by 10 ** 20 yields 2 ** 40.\n        expect(base10.raw / 10n ** 20n).toBe(1n << 40n);\n    });\n});\n\ndescribe('toUnsignedBinaryFixedPoint', () => {\n    it('converts a signed non-negative value to unsigned', () => {\n        const signed = rawBinaryFixedPoint('signed', 8, 4)(100n);\n        const unsigned = toUnsignedBinaryFixedPoint(signed);\n        expect(unsigned.signedness).toBe('unsigned');\n        expect(unsigned.raw).toBe(100n);\n    });\n\n    it('returns the same reference when the input is already unsigned', () => {\n        const unsigned = rawBinaryFixedPoint('unsigned', 8, 4)(100n);\n        expect(toUnsignedBinaryFixedPoint(unsigned)).toBe(unsigned);\n    });\n\n    it('preserves totalBits and fractionalBits', () => {\n        const signed = rawBinaryFixedPoint('signed', 16, 15)(1n);\n        const unsigned = toUnsignedBinaryFixedPoint(signed);\n        expect(unsigned.totalBits).toBe(16);\n        expect(unsigned.fractionalBits).toBe(15);\n    });\n\n    it('returns a frozen value', () => {\n        const signed = rawBinaryFixedPoint('signed', 8, 4)(100n);\n        expect(toUnsignedBinaryFixedPoint(signed)).toBeFrozenObject();\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when converting a negative value', () => {\n        const signed = rawBinaryFixedPoint('signed', 8, 4)(-1n);\n        expect(() => toUnsignedBinaryFixedPoint(signed)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'binaryFixedPoint',\n                max: 255n,\n                min: 0n,\n                raw: -1n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('toSignedBinaryFixedPoint', () => {\n    it('converts an unsigned value that fits the signed range', () => {\n        const unsigned = rawBinaryFixedPoint('unsigned', 8, 4)(100n);\n        const signed = toSignedBinaryFixedPoint(unsigned);\n        expect(signed.signedness).toBe('signed');\n        expect(signed.raw).toBe(100n);\n    });\n\n    it('returns the same reference when the input is already signed', () => {\n        const signed = rawBinaryFixedPoint('signed', 8, 4)(-50n);\n        expect(toSignedBinaryFixedPoint(signed)).toBe(signed);\n    });\n\n    it('preserves totalBits and fractionalBits', () => {\n        const unsigned = rawBinaryFixedPoint('unsigned', 16, 15)(1n);\n        const signed = toSignedBinaryFixedPoint(unsigned);\n        expect(signed.totalBits).toBe(16);\n        expect(signed.fractionalBits).toBe(15);\n    });\n\n    it('returns a frozen value', () => {\n        const unsigned = rawBinaryFixedPoint('unsigned', 8, 4)(100n);\n        expect(toSignedBinaryFixedPoint(unsigned)).toBeFrozenObject();\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the unsigned value exceeds the signed upper bound', () => {\n        const unsigned = rawBinaryFixedPoint('unsigned', 8, 4)(200n);\n        expect(() => toSignedBinaryFixedPoint(unsigned)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: 200n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('rescaleBinaryFixedPoint', () => {\n    it('returns the same reference when the requested shape matches', () => {\n        const value = binaryFixedPoint('signed', 16, 15)('0.5');\n        expect(rescaleBinaryFixedPoint(value, 16, 15)).toBe(value);\n    });\n\n    it('scales up fractionalBits exactly', () => {\n        // raw 1 at Q?.2 represents 0.25; moving to Q?.4 scales raw to 4.\n        const source = rawBinaryFixedPoint('unsigned', 8, 2)(1n);\n        const rescaled = rescaleBinaryFixedPoint(source, 8, 4);\n        expect(rescaled.raw).toBe(4n);\n        expect(rescaled.fractionalBits).toBe(4);\n        expect(rescaled.totalBits).toBe(8);\n    });\n\n    it('scales down fractionalBits exactly', () => {\n        // raw 16 at Q?.4 represents 1.0; moving to Q?.2 scales raw to 4.\n        const source = rawBinaryFixedPoint('unsigned', 8, 4)(16n);\n        expect(rescaleBinaryFixedPoint(source, 8, 2).raw).toBe(4n);\n    });\n\n    it('widens totalBits while preserving fractionalBits and raw', () => {\n        const source = rawBinaryFixedPoint('unsigned', 8, 4)(10n);\n        const rescaled = rescaleBinaryFixedPoint(source, 16, 4);\n        expect(rescaled.raw).toBe(10n);\n        expect(rescaled.totalBits).toBe(16);\n        expect(rescaled.fractionalBits).toBe(4);\n    });\n\n    it('narrows totalBits when the value fits', () => {\n        const source = rawBinaryFixedPoint('unsigned', 16, 0)(100n);\n        expect(rescaleBinaryFixedPoint(source, 8, 0).raw).toBe(100n);\n    });\n\n    it('preserves signedness', () => {\n        const source = rawBinaryFixedPoint('signed', 8, 0)(-1n);\n        expect(rescaleBinaryFixedPoint(source, 16, 0).signedness).toBe('signed');\n    });\n\n    it('returns a frozen value when the shape changes', () => {\n        const source = rawBinaryFixedPoint('unsigned', 8, 2)(1n);\n        expect(rescaleBinaryFixedPoint(source, 8, 4)).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when scale-down is inexact', () => {\n        // raw 1 at Q?.2 represents 0.25; moving to Q?.1 would halve it (0.5 / 0.5 = 0 or 1).\n        const source = rawBinaryFixedPoint('unsigned', 8, 2)(1n);\n        expect(() => rescaleBinaryFixedPoint(source, 8, 1)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'binaryFixedPoint',\n                operation: 'rescale',\n            }),\n        );\n    });\n\n    it('rounds an inexact scale-down when a non-strict rounding mode is supplied', () => {\n        const source = rawBinaryFixedPoint('unsigned', 8, 2)(1n);\n        expect(rescaleBinaryFixedPoint(source, 8, 1, 'floor').raw).toBe(0n);\n        expect(rescaleBinaryFixedPoint(source, 8, 1, 'ceil').raw).toBe(1n);\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when narrowing totalBits overflows the target range', () => {\n        const source = rawBinaryFixedPoint('unsigned', 16, 0)(300n);\n        expect(() => rescaleBinaryFixedPoint(source, 8, 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'binaryFixedPoint',\n                max: 255n,\n                min: 0n,\n                operation: 'rescale',\n                result: 300n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when scaling up fractionalBits overflows the target totalBits', () => {\n        // raw 100 at Q?.0 → scaling up to Q?.4 multiplies by 16 → 1600 which exceeds signed 8-bit max 127.\n        const source = rawBinaryFixedPoint('signed', 8, 0)(100n);\n        expect(() => rescaleBinaryFixedPoint(source, 8, 4)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                operation: 'rescale',\n                result: 1600n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws INVALID_TOTAL_BITS for a non-positive target totalBits', () => {\n        const source = rawBinaryFixedPoint('unsigned', 8, 4)(1n);\n        expect(() => rescaleBinaryFixedPoint(source, 0, 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n                kind: 'binaryFixedPoint',\n                totalBits: 0,\n            }),\n        );\n    });\n\n    it('throws INVALID_FRACTIONAL_BITS for a negative target fractionalBits', () => {\n        const source = rawBinaryFixedPoint('unsigned', 8, 4)(1n);\n        expect(() => rescaleBinaryFixedPoint(source, 8, -1)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS, {\n                fractionalBits: -1,\n            }),\n        );\n    });\n\n    it('throws FRACTIONAL_BITS_EXCEED_TOTAL_BITS when the target fractionalBits exceeds totalBits', () => {\n        const source = rawBinaryFixedPoint('unsigned', 16, 4)(1n);\n        expect(() => rescaleBinaryFixedPoint(source, 8, 16)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS, {\n                fractionalBits: 16,\n                totalBits: 8,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/binary-core-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_STRING,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO,\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { binaryFixedPoint, ratioBinaryFixedPoint, rawBinaryFixedPoint } from '../binary/core';\n\ndescribe('binaryFixedPoint', () => {\n    it('constructs values from decimal strings that are exactly representable in binary', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(q1_15('0').raw).toBe(0n);\n        expect(q1_15('0.5').raw).toBe(2n ** 14n);\n        expect(q1_15('0.25').raw).toBe(2n ** 13n);\n        expect(q1_15('-0.5').raw).toBe(-(2n ** 14n));\n    });\n\n    it('returns values whose fields match the shape and kind', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(q1_15('0.5')).toEqual({\n            fractionalBits: 15,\n            kind: 'binaryFixedPoint',\n            raw: 2n ** 14n,\n            signedness: 'signed',\n            totalBits: 16,\n        });\n    });\n\n    it('returns frozen values', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(q1_15('0.5')).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when the string cannot be represented exactly in binary', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() => q1_15('0.1')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'binaryFixedPoint',\n                operation: 'fromString',\n            }),\n        );\n    });\n\n    it('rounds inexact strings when a non-strict rounding mode is supplied', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        // 0.1 × 2^15 = 3276.8\n        expect(q1_15('0.1', 'floor').raw).toBe(3276n);\n        expect(q1_15('0.1', 'ceil').raw).toBe(3277n);\n        expect(q1_15('0.1', 'round').raw).toBe(3277n);\n        expect(q1_15('0.1', 'trunc').raw).toBe(3276n);\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the result does not fit the target shape', () => {\n        // 1 × 2^7 = 128, which overflows a signed 8-bit range [-128, 127].\n        const q1_7 = binaryFixedPoint('signed', 8, 7);\n        expect(() => q1_7('1')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('accepts the largest representable value for a given shape', () => {\n        // 0.9921875 = 127/128, the largest value representable as signed Q1.7.\n        const q1_7 = binaryFixedPoint('signed', 8, 7);\n        expect(q1_7('0.9921875').raw).toBe(127n);\n    });\n\n    it('throws INVALID_STRING on malformed inputs', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() => q1_15('abc')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_STRING, {\n                input: 'abc',\n                kind: 'binaryFixedPoint',\n            }),\n        );\n    });\n\n    it('throws INVALID_TOTAL_BITS when totalBits is not a positive integer', () => {\n        expect(() => binaryFixedPoint('signed', 0, 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n                kind: 'binaryFixedPoint',\n                totalBits: 0,\n            }),\n        );\n    });\n\n    it('throws INVALID_FRACTIONAL_BITS when fractionalBits is not a non-negative integer', () => {\n        expect(() => binaryFixedPoint('signed', 16, -1)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS, { fractionalBits: -1 }),\n        );\n    });\n\n    it('throws FRACTIONAL_BITS_EXCEED_TOTAL_BITS when fractionalBits exceeds totalBits', () => {\n        expect(() => binaryFixedPoint('signed', 16, 32)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS, {\n                fractionalBits: 32,\n                totalBits: 16,\n            }),\n        );\n    });\n\n    it('allows fractionalBits equal to totalBits', () => {\n        // Q0.16 can represent values in [0, 1), so `0` fits and proves the\n        // factory was accepted even at the fractionalBits=totalBits boundary.\n        const factory = binaryFixedPoint('unsigned', 16, 16);\n        expect(factory('0').raw).toBe(0n);\n    });\n});\n\ndescribe('rawBinaryFixedPoint', () => {\n    it('constructs values directly from a raw bigint', () => {\n        const q1_15 = rawBinaryFixedPoint('signed', 16, 15);\n        expect(q1_15(2n ** 14n)).toEqual({\n            fractionalBits: 15,\n            kind: 'binaryFixedPoint',\n            raw: 2n ** 14n,\n            signedness: 'signed',\n            totalBits: 16,\n        });\n    });\n\n    it('returns frozen values', () => {\n        const q1_15 = rawBinaryFixedPoint('signed', 16, 15);\n        expect(q1_15(2n ** 14n)).toBeFrozenObject();\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the raw value does not fit the shape', () => {\n        const q1_7 = rawBinaryFixedPoint('signed', 8, 7);\n        expect(() => q1_7(128n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('ratioBinaryFixedPoint', () => {\n    it('constructs values from exact ratios', () => {\n        const q1_15 = ratioBinaryFixedPoint('signed', 16, 15);\n        // 0.25 × 2^15\n        expect(q1_15(1n, 4n).raw).toBe(2n ** 13n);\n        // 0.5 × 2^15\n        expect(q1_15(1n, 2n).raw).toBe(2n ** 14n);\n    });\n\n    it('returns frozen values', () => {\n        const q1_15 = ratioBinaryFixedPoint('signed', 16, 15);\n        expect(q1_15(1n, 4n)).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when the ratio is inexact', () => {\n        const q1_15 = ratioBinaryFixedPoint('signed', 16, 15);\n        expect(() => q1_15(1n, 3n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'binaryFixedPoint',\n                operation: 'fromRatio',\n            }),\n        );\n    });\n\n    it('rounds inexact ratios when a non-strict rounding mode is supplied', () => {\n        const q1_15 = ratioBinaryFixedPoint('signed', 16, 15);\n        // 1/3 × 2^15 = 10922.666…\n        expect(q1_15(1n, 3n, 'floor').raw).toBe(10922n);\n        expect(q1_15(1n, 3n, 'ceil').raw).toBe(10923n);\n        expect(q1_15(1n, 3n, 'round').raw).toBe(10923n);\n    });\n\n    it('throws INVALID_ZERO_DENOMINATOR_RATIO when the denominator is zero', () => {\n        const q1_15 = ratioBinaryFixedPoint('signed', 16, 15);\n        expect(() => q1_15(1n, 0n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO, {\n                denominator: 0n,\n                kind: 'binaryFixedPoint',\n                numerator: 1n,\n            }),\n        );\n    });\n});\n\ndescribe('binary factory shape validation', () => {\n    it('rejects zero totalBits up front from every binary factory', () => {\n        for (const factory of [binaryFixedPoint, rawBinaryFixedPoint, ratioBinaryFixedPoint]) {\n            expect(() => factory('signed', 0, 0)).toThrow(\n                new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n                    kind: 'binaryFixedPoint',\n                    totalBits: 0,\n                }),\n            );\n        }\n    });\n\n    it('rejects negative fractionalBits up front from every binary factory', () => {\n        for (const factory of [binaryFixedPoint, rawBinaryFixedPoint, ratioBinaryFixedPoint]) {\n            expect(() => factory('signed', 16, -1)).toThrow(\n                new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS, { fractionalBits: -1 }),\n            );\n        }\n    });\n\n    it('rejects fractionalBits that exceed totalBits up front from every binary factory', () => {\n        for (const factory of [binaryFixedPoint, rawBinaryFixedPoint, ratioBinaryFixedPoint]) {\n            expect(() => factory('signed', 16, 32)).toThrow(\n                new SolanaError(SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS, {\n                    fractionalBits: 32,\n                    totalBits: 16,\n                }),\n            );\n        }\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/binary-formatting-test.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, SolanaError } from '@solana/errors';\n\nimport {\n    binaryFixedPoint,\n    binaryFixedPointToNumber,\n    binaryFixedPointToString,\n    formatBinaryFixedPoint,\n    ratioBinaryFixedPoint,\n    rawBinaryFixedPoint,\n} from '../binary';\n\ndescribe('binaryFixedPointToString', () => {\n    it('renders zero', () => {\n        expect(binaryFixedPointToString(rawBinaryFixedPoint('signed', 16, 15)(0n))).toBe('0');\n    });\n\n    it('renders a simple one-half fraction', () => {\n        expect(binaryFixedPointToString(rawBinaryFixedPoint('unsigned', 8, 1)(1n))).toBe('0.5');\n    });\n\n    it('renders a simple one-quarter fraction', () => {\n        expect(binaryFixedPointToString(rawBinaryFixedPoint('unsigned', 8, 2)(1n))).toBe('0.25');\n    });\n\n    it('renders a negative half', () => {\n        expect(binaryFixedPointToString(rawBinaryFixedPoint('signed', 16, 15)(-16384n))).toBe('-0.5');\n    });\n\n    it('renders an integer when fractionalBits is zero', () => {\n        expect(binaryFixedPointToString(rawBinaryFixedPoint('unsigned', 8, 0)(42n))).toBe('42');\n    });\n\n    it('renders a negative integer when fractionalBits is zero', () => {\n        expect(binaryFixedPointToString(rawBinaryFixedPoint('signed', 8, 0)(-42n))).toBe('-42');\n    });\n\n    it('emits the full exact decimal expansion by default', () => {\n        // 1 / 2 ** 15 = 0.000030517578125 exactly.\n        expect(binaryFixedPointToString(rawBinaryFixedPoint('unsigned', 16, 15)(1n))).toBe('0.000030517578125');\n    });\n\n    it('renders a ratio-built value cleanly', () => {\n        const probability = ratioBinaryFixedPoint('signed', 16, 15);\n        expect(binaryFixedPointToString(probability(1n, 4n))).toBe('0.25');\n    });\n\n    it('caps the fractional output at the requested decimals using the given rounding mode', () => {\n        // The raw value represents 0.480010986328125 exactly; rounded to 2 decimals → 0.48.\n        const ugly = rawBinaryFixedPoint('signed', 16, 15)(15729n);\n        expect(binaryFixedPointToString(ugly, { decimals: 2, rounding: 'round' })).toBe('0.48');\n    });\n\n    it('trims trailing zeros even when the requested decimals is larger than necessary', () => {\n        const value = rawBinaryFixedPoint('unsigned', 8, 1)(1n); // 0.5\n        expect(binaryFixedPointToString(value, { decimals: 6 })).toBe('0.5');\n    });\n\n    it('pads trailing zeros up to the requested decimals when padTrailingZeros is true', () => {\n        const value = rawBinaryFixedPoint('unsigned', 8, 1)(1n); // 0.5\n        expect(binaryFixedPointToString(value, { decimals: 6, padTrailingZeros: true })).toBe('0.500000');\n    });\n\n    it('pads trailing zeros up to the native fractionalBits when padTrailingZeros is true and decimals is omitted', () => {\n        const value = rawBinaryFixedPoint('unsigned', 8, 1)(1n); // 0.5 with a single fractional bit.\n        expect(binaryFixedPointToString(value, { padTrailingZeros: true })).toBe('0.5');\n    });\n\n    it('pads trailing zeros up to fractionalBits for a longer native scale', () => {\n        const value = binaryFixedPoint('signed', 16, 15)('0.5');\n        expect(binaryFixedPointToString(value, { padTrailingZeros: true })).toBe('0.500000000000000');\n    });\n\n    it('pads whole numbers with trailing zeros when padTrailingZeros is true', () => {\n        const value = rawBinaryFixedPoint('unsigned', 8, 1)(0n);\n        expect(binaryFixedPointToString(value, { decimals: 3, padTrailingZeros: true })).toBe('0.000');\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS when a lossy cap is requested without a rounding mode', () => {\n        // 1 / 2 ** 15 cannot be represented at 2 decimals without loss.\n        const value = rawBinaryFixedPoint('unsigned', 16, 15)(1n);\n        expect(() => binaryFixedPointToString(value, { decimals: 2 })).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'binaryFixedPoint',\n                operation: 'toString',\n            }),\n        );\n    });\n\n    it('does not throw when capping at the same number of decimals as the native expansion', () => {\n        const value = rawBinaryFixedPoint('unsigned', 16, 15)(1n);\n        expect(binaryFixedPointToString(value, { decimals: 15 })).toBe('0.000030517578125');\n    });\n});\n\ndescribe('formatBinaryFixedPoint', () => {\n    it('formats zero with a default formatter', () => {\n        const formatter = new Intl.NumberFormat('en-US');\n        const value = rawBinaryFixedPoint('signed', 16, 15)(0n);\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('0');\n    });\n\n    it('formats a simple fraction with a default formatter', () => {\n        const formatter = new Intl.NumberFormat('en-US');\n        const value = binaryFixedPoint('signed', 16, 15)('0.5');\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('0.5');\n    });\n\n    it('formats negative values with the formatter sign convention', () => {\n        const formatter = new Intl.NumberFormat('en-US');\n        const value = rawBinaryFixedPoint('signed', 16, 15)(-16384n);\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('-0.5');\n    });\n\n    it('respects a non-default locale', () => {\n        const formatter = new Intl.NumberFormat('fr-FR');\n        const value = binaryFixedPoint('signed', 16, 15)('0.5');\n        // French uses ',' as the decimal separator.\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('0,5');\n    });\n\n    it('honours the formatter rounding via maximumFractionDigits', () => {\n        // 1 / 2 ** 15 = 0.000030517578125 — capped to 4 fractional digits → '0'.\n        const formatter = new Intl.NumberFormat('en-US', { maximumFractionDigits: 4 });\n        const value = rawBinaryFixedPoint('unsigned', 16, 15)(1n);\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('0');\n    });\n\n    it('pads trailing zeros via minimumFractionDigits', () => {\n        const formatter = new Intl.NumberFormat('en-US', { minimumFractionDigits: 4 });\n        const value = binaryFixedPoint('signed', 16, 15)('0.5');\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('0.5000');\n    });\n\n    it('renders the full exact decimal expansion when minimumFractionDigits matches fractionalBits', () => {\n        const formatter = new Intl.NumberFormat('en-US', {\n            maximumFractionDigits: 15,\n            minimumFractionDigits: 15,\n            useGrouping: false,\n        });\n        const value = rawBinaryFixedPoint('unsigned', 16, 15)(1n);\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('0.000030517578125');\n    });\n\n    it('preserves precision when the raw value exceeds Number.MAX_SAFE_INTEGER', () => {\n        // raw 2 ** 60 at QX.20 represents exactly 2 ** 40 = 1099511627776.\n        const formatter = new Intl.NumberFormat('en-US', { useGrouping: false });\n        const value = rawBinaryFixedPoint('unsigned', 128, 20)(1n << 60n);\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('1099511627776');\n    });\n\n    it('combines locale, currency style, grouping, and fraction digits', () => {\n        const formatter = new Intl.NumberFormat('de-DE', {\n            currency: 'EUR',\n            maximumFractionDigits: 2,\n            minimumFractionDigits: 2,\n            style: 'currency',\n            useGrouping: true,\n        });\n        // raw 32_768_000 at QX.15 represents exactly 1000.0 (32_768_000 / 2 ** 15 = 1000).\n        const value = rawBinaryFixedPoint('unsigned', 32, 15)(32_768_000n);\n        // German uses '.' for grouping, ',' as the decimal separator, and '€' as the currency suffix.\n        // ICU emits a no-break space (U+00A0) between the number and the currency symbol.\n        expect(formatBinaryFixedPoint(formatter, value)).toBe('1.000,00\\u00A0€');\n    });\n});\n\ndescribe('binaryFixedPointToNumber', () => {\n    it('returns zero for zero', () => {\n        expect(binaryFixedPointToNumber(rawBinaryFixedPoint('signed', 16, 15)(0n))).toBe(0);\n    });\n\n    it('returns one half for a raw value halfway to one', () => {\n        expect(binaryFixedPointToNumber(rawBinaryFixedPoint('unsigned', 8, 1)(1n))).toBe(0.5);\n    });\n\n    it('returns one quarter for a raw value a quarter of the way to one', () => {\n        expect(binaryFixedPointToNumber(rawBinaryFixedPoint('unsigned', 8, 2)(1n))).toBe(0.25);\n    });\n\n    it('returns negative one half for a negative half raw value', () => {\n        expect(binaryFixedPointToNumber(rawBinaryFixedPoint('signed', 16, 15)(-16384n))).toBe(-0.5);\n    });\n\n    it('returns the unscaled raw as a number when fractionalBits is zero', () => {\n        expect(binaryFixedPointToNumber(rawBinaryFixedPoint('signed', 8, 0)(-42n))).toBe(-42);\n    });\n\n    it('returns a very small but finite number for large fractionalBits', () => {\n        expect(binaryFixedPointToNumber(rawBinaryFixedPoint('unsigned', 64, 53)(1n))).toBe(2 ** -53);\n    });\n\n    it('preserves low-order bits when the raw value exceeds Number.MAX_SAFE_INTEGER but the result fits', () => {\n        // raw = 2 ** 60 + (2 ** 20 - 1) at fractionalBits = 20 represents\n        // 2 ** 40 + (2 ** 20 - 1) / 2 ** 20, which fits within 53 bits of mantissa.\n        // A naive `Number(raw) / 2 ** 20` would round `raw` at bit level 8 and\n        // return 2 ** 40 + 1; the split preserves the fractional part.\n        const raw = (1n << 60n) + ((1n << 20n) - 1n);\n        const value = rawBinaryFixedPoint('unsigned', 128, 20)(raw);\n        expect(binaryFixedPointToNumber(value)).toBe(2 ** 40 + (2 ** 20 - 1) / 2 ** 20);\n    });\n\n    it('preserves low-order bits for negative values that exceed Number.MAX_SAFE_INTEGER', () => {\n        const raw = -((1n << 60n) + ((1n << 20n) - 1n));\n        const value = rawBinaryFixedPoint('signed', 128, 20)(raw);\n        expect(binaryFixedPointToNumber(value)).toBe(-(2 ** 40 + (2 ** 20 - 1) / 2 ** 20));\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/binary-guards-test.ts",
    "content": "import {\n    SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { binaryFixedPoint, rawBinaryFixedPoint } from '../binary/core';\nimport { assertIsBinaryFixedPoint, isBinaryFixedPoint } from '../binary/guards';\n\ndescribe('isBinaryFixedPoint', () => {\n    it('returns true for valid binary fixed-point values', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(isBinaryFixedPoint(q1_15('0.5'))).toBe(true);\n        const unsigned = rawBinaryFixedPoint('unsigned', 8, 4);\n        expect(isBinaryFixedPoint(unsigned(42n))).toBe(true);\n    });\n\n    it('returns false for non-objects and wrong kinds', () => {\n        expect(isBinaryFixedPoint(42)).toBe(false);\n        expect(isBinaryFixedPoint(null)).toBe(false);\n        expect(isBinaryFixedPoint(undefined)).toBe(false);\n        expect(isBinaryFixedPoint({})).toBe(false);\n        expect(isBinaryFixedPoint({ kind: 'decimalFixedPoint' })).toBe(false);\n    });\n\n    it('returns false when required fields are missing or malformed', () => {\n        const base = {\n            fractionalBits: 15,\n            kind: 'binaryFixedPoint',\n            raw: 0n,\n            signedness: 'signed',\n            totalBits: 16,\n        };\n        expect(isBinaryFixedPoint({ ...base, signedness: 'weird' })).toBe(false);\n        expect(isBinaryFixedPoint({ ...base, totalBits: 0 })).toBe(false);\n        expect(isBinaryFixedPoint({ ...base, fractionalBits: -1 })).toBe(false);\n        expect(isBinaryFixedPoint({ ...base, fractionalBits: 32 })).toBe(false); // exceeds totalBits\n        expect(isBinaryFixedPoint({ ...base, raw: 1 })).toBe(false);\n    });\n\n    it('returns false when the raw value does not fit the claimed range', () => {\n        expect(\n            isBinaryFixedPoint({\n                fractionalBits: 0,\n                kind: 'binaryFixedPoint',\n                raw: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        ).toBe(false);\n    });\n\n    it('narrows to the specific shape when parameters are provided', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        const value = q1_15('0.5');\n        expect(isBinaryFixedPoint(value, 'signed', 16, 15)).toBe(true);\n        expect(isBinaryFixedPoint(value, 'unsigned', 16, 15)).toBe(false);\n        expect(isBinaryFixedPoint(value, 'signed', 32, 15)).toBe(false);\n        expect(isBinaryFixedPoint(value, 'signed', 16, 14)).toBe(false);\n    });\n\n    it('accepts partial positional arguments, constraining only the fields that are provided', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        const value = q1_15('0.5');\n        expect(isBinaryFixedPoint(value, 'signed')).toBe(true);\n        expect(isBinaryFixedPoint(value, 'unsigned')).toBe(false);\n        expect(isBinaryFixedPoint(value, 'signed', 16)).toBe(true);\n        expect(isBinaryFixedPoint(value, 'signed', 32)).toBe(false);\n    });\n\n    it('treats `undefined` as \"don’t care\" for any skipped field', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        const value = q1_15('0.5');\n        expect(isBinaryFixedPoint(value, undefined, 16)).toBe(true);\n        expect(isBinaryFixedPoint(value, undefined, undefined, 15)).toBe(true);\n        expect(isBinaryFixedPoint(value, undefined, 32)).toBe(false);\n    });\n});\n\ndescribe('assertIsBinaryFixedPoint', () => {\n    it('passes silently for valid values', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() => assertIsBinaryFixedPoint(q1_15('0.5'))).not.toThrow();\n        expect(() => assertIsBinaryFixedPoint(q1_15('0.5'), 'signed', 16, 15)).not.toThrow();\n    });\n\n    it('throws SHAPE_MISMATCH for non-object inputs', () => {\n        expect(() => assertIsBinaryFixedPoint(42)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'unknown',\n                actualScale: 0,\n                actualScaleLabel: 'unknown',\n                actualSignedness: 'unknown',\n                actualTotalBits: 0,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 0,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'unknown',\n                expectedTotalBits: 0,\n                operation: 'assertIsBinaryFixedPoint',\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when the value is a decimal fixed-point', () => {\n        expect(() => assertIsBinaryFixedPoint({ kind: 'decimalFixedPoint' })).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'decimalFixedPoint',\n                actualScale: 0,\n                actualScaleLabel: 'decimals',\n                actualSignedness: 'unknown',\n                actualTotalBits: 0,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 0,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'unknown',\n                expectedTotalBits: 0,\n                operation: 'assertIsBinaryFixedPoint',\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when a binary value has the wrong signedness', () => {\n        const q1_15 = binaryFixedPoint('signed', 16, 15);\n        expect(() => assertIsBinaryFixedPoint(q1_15('0.5'), 'unsigned', 16, 15)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'binaryFixedPoint',\n                actualScale: 15,\n                actualScaleLabel: 'fractional bits',\n                actualSignedness: 'signed',\n                actualTotalBits: 16,\n                expectedKind: 'binaryFixedPoint',\n                expectedScale: 15,\n                expectedScaleLabel: 'fractional bits',\n                expectedSignedness: 'unsigned',\n                expectedTotalBits: 16,\n                operation: 'assertIsBinaryFixedPoint',\n            }),\n        );\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the raw value does not fit the claimed range', () => {\n        const malformed = {\n            fractionalBits: 0,\n            kind: 'binaryFixedPoint' as const,\n            raw: 128n,\n            signedness: 'signed' as const,\n            totalBits: 8,\n        };\n        expect(() => assertIsBinaryFixedPoint(malformed)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'binaryFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws MALFORMED_RAW_VALUE when the raw field is not a bigint', () => {\n        const malformed = {\n            fractionalBits: 15,\n            kind: 'binaryFixedPoint' as const,\n            raw: 42,\n            signedness: 'signed' as const,\n            totalBits: 16,\n        };\n        expect(() => assertIsBinaryFixedPoint(malformed)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE, {\n                kind: 'binaryFixedPoint',\n                raw: 42,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/decimal-arithmetics-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    absoluteDecimalFixedPoint,\n    addDecimalFixedPoint,\n    decimalFixedPoint,\n    divideDecimalFixedPoint,\n    multiplyDecimalFixedPoint,\n    negateDecimalFixedPoint,\n    rawDecimalFixedPoint,\n    subtractDecimalFixedPoint,\n} from '../decimal';\n\ndescribe('addDecimalFixedPoint', () => {\n    it('adds two values of the same shape', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(addDecimalFixedPoint(usd('1.50'), usd('2.25')).raw).toBe(375n);\n    });\n\n    it('returns a frozen value', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(addDecimalFixedPoint(usd('1.50'), usd('2.25'))).toBeFrozenObject();\n    });\n\n    it('throws SHAPE_MISMATCH when the operands have different decimals', () => {\n        const usd = rawDecimalFixedPoint('unsigned', 64, 2);\n        const rate = rawDecimalFixedPoint('unsigned', 64, 4);\n        expect(() =>\n            // @ts-expect-error Operands must share the same shape.\n            addDecimalFixedPoint(usd(1n), rate(1n)),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'decimalFixedPoint',\n                actualScale: 4,\n                actualScaleLabel: 'decimals',\n                actualSignedness: 'unsigned',\n                actualTotalBits: 64,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 2,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'unsigned',\n                expectedTotalBits: 64,\n                operation: 'addDecimalFixedPoint',\n            }),\n        );\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when the sum exceeds the upper bound', () => {\n        const factory = rawDecimalFixedPoint('unsigned', 8, 0);\n        expect(() => addDecimalFixedPoint(factory(200n), factory(100n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                operation: 'add',\n                result: 300n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('subtractDecimalFixedPoint', () => {\n    it('subtracts two values of the same shape', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(subtractDecimalFixedPoint(usd('10'), usd('3.5')).raw).toBe(650n);\n    });\n\n    it('returns a frozen value', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(subtractDecimalFixedPoint(usd('10'), usd('3.5'))).toBeFrozenObject();\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when the difference is below the lower bound', () => {\n        const factory = rawDecimalFixedPoint('unsigned', 8, 0);\n        expect(() => subtractDecimalFixedPoint(factory(1n), factory(2n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                operation: 'subtract',\n                result: -1n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('multiplyDecimalFixedPoint', () => {\n    it('multiplies two values of the same shape', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        // 1.50 × 2.00 = 3.00 → raw 300n\n        expect(multiplyDecimalFixedPoint(usd('1.50'), usd('2.00')).raw).toBe(300n);\n    });\n\n    it('multiplies by a fixed-point operand with a different totalBits and decimals', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        const rate = decimalFixedPoint('unsigned', 32, 4);\n        // 100.00 × 0.0025 = 0.25 → raw 25n at 2 decimals\n        expect(multiplyDecimalFixedPoint(usd('100'), rate('0.0025')).raw).toBe(25n);\n    });\n\n    it('multiplies by a bigint scalar', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(multiplyDecimalFixedPoint(usd('1.50'), 3n).raw).toBe(450n);\n    });\n\n    it('returns a frozen value', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(multiplyDecimalFixedPoint(usd('1.50'), 3n)).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when the product is inexact', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        const rate = rawDecimalFixedPoint('unsigned', 64, 4);\n        // 100n × 1n / 10000 = 0.01 at 2 decimals is inexact (0.0001 precision lost).\n        expect(() => multiplyDecimalFixedPoint(usd('1'), rate(1n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'decimalFixedPoint',\n                operation: 'multiply',\n            }),\n        );\n    });\n\n    it('rounds an inexact product when a non-strict rounding mode is supplied', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        const rate = rawDecimalFixedPoint('unsigned', 64, 4);\n        // 100n × 1n / 10000 = 0.01, floor → 0\n        expect(multiplyDecimalFixedPoint(usd('1'), rate(1n), 'floor').raw).toBe(0n);\n        expect(multiplyDecimalFixedPoint(usd('1'), rate(1n), 'ceil').raw).toBe(1n);\n    });\n\n    it('throws SHAPE_MISMATCH when the fixed-point operand has a different signedness', () => {\n        const signed = decimalFixedPoint('signed', 64, 2);\n        const unsigned = rawDecimalFixedPoint('unsigned', 64, 2);\n        expect(() =>\n            // @ts-expect-error Second operand must share the first operand's signedness.\n            multiplyDecimalFixedPoint(signed('1'), unsigned(1n)),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'decimalFixedPoint',\n                actualScale: 2,\n                actualScaleLabel: 'decimals',\n                actualSignedness: 'unsigned',\n                actualTotalBits: 64,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 2,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'signed',\n                expectedTotalBits: 64,\n                operation: 'multiplyDecimalFixedPoint',\n            }),\n        );\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when the product does not fit the target shape', () => {\n        const tiny = rawDecimalFixedPoint('unsigned', 8, 0);\n        expect(() => multiplyDecimalFixedPoint(tiny(100n), 3n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                operation: 'multiply',\n                result: 300n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('divideDecimalFixedPoint', () => {\n    it('divides by a fixed-point operand of the same shape', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        // 10.00 ÷ 5.00 = 2.00 → raw 200n\n        expect(divideDecimalFixedPoint(usd('10'), usd('5')).raw).toBe(200n);\n    });\n\n    it('divides by a fixed-point operand with a different totalBits and decimals', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        const rate = decimalFixedPoint('unsigned', 32, 4);\n        // 10.00 ÷ 0.05 = 200.00 → raw 20000n at 2 decimals\n        expect(divideDecimalFixedPoint(usd('10'), rate('0.05')).raw).toBe(20000n);\n    });\n\n    it('divides by a bigint scalar', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(divideDecimalFixedPoint(usd('10.50'), 3n, 'round').raw).toBe(350n);\n    });\n\n    it('returns a frozen value', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(divideDecimalFixedPoint(usd('10'), 2n)).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when the division is inexact', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(() => divideDecimalFixedPoint(usd('10'), 3n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'decimalFixedPoint',\n                operation: 'divide',\n            }),\n        );\n    });\n\n    it('rounds an inexact division when a non-strict rounding mode is supplied', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        // 1000 / 3 = 333.33…\n        expect(divideDecimalFixedPoint(usd('10'), 3n, 'floor').raw).toBe(333n);\n        expect(divideDecimalFixedPoint(usd('10'), 3n, 'ceil').raw).toBe(334n);\n        expect(divideDecimalFixedPoint(usd('10'), 3n, 'round').raw).toBe(333n);\n    });\n\n    it('throws DIVISION_BY_ZERO when dividing by a bigint zero', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(() => divideDecimalFixedPoint(usd('10'), 0n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO, {\n                kind: 'decimalFixedPoint',\n                signedness: 'unsigned',\n                totalBits: 64,\n            }),\n        );\n    });\n\n    it('throws DIVISION_BY_ZERO when dividing by a fixed-point zero', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(() => divideDecimalFixedPoint(usd('10'), usd('0'))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO, {\n                kind: 'decimalFixedPoint',\n                signedness: 'unsigned',\n                totalBits: 64,\n            }),\n        );\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when the quotient does not fit the target shape', () => {\n        const tiny = rawDecimalFixedPoint('unsigned', 8, 0);\n        const rate = decimalFixedPoint('unsigned', 64, 4);\n        expect(() => divideDecimalFixedPoint(tiny(100n), rate('0.1'))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                operation: 'divide',\n                result: 1000n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('negateDecimalFixedPoint', () => {\n    it('negates a signed value', () => {\n        const signed = decimalFixedPoint('signed', 32, 2);\n        expect(negateDecimalFixedPoint(signed('1.5')).raw).toBe(-150n);\n        expect(negateDecimalFixedPoint(signed('-1.5')).raw).toBe(150n);\n    });\n\n    it('returns a frozen value', () => {\n        const signed = decimalFixedPoint('signed', 32, 2);\n        expect(negateDecimalFixedPoint(signed('1.5'))).toBeFrozenObject();\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when negating the minimum signed value', () => {\n        const factory = rawDecimalFixedPoint('signed', 8, 0);\n        expect(() => negateDecimalFixedPoint(factory(-128n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'decimalFixedPoint',\n                max: 127n,\n                min: -128n,\n                operation: 'negate',\n                result: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when called on an unsigned value at runtime', () => {\n        const unsigned = rawDecimalFixedPoint('unsigned', 64, 6)(1n);\n        expect(() =>\n            // @ts-expect-error Only signed values can be negated.\n            negateDecimalFixedPoint(unsigned),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'decimalFixedPoint',\n                actualScale: 6,\n                actualScaleLabel: 'decimals',\n                actualSignedness: 'unsigned',\n                actualTotalBits: 64,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 6,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'signed',\n                expectedTotalBits: 64,\n                operation: 'negateDecimalFixedPoint',\n            }),\n        );\n    });\n});\n\ndescribe('absoluteDecimalFixedPoint', () => {\n    it('returns the absolute value of a signed negative', () => {\n        const signed = decimalFixedPoint('signed', 32, 2);\n        expect(absoluteDecimalFixedPoint(signed('-1.5')).raw).toBe(150n);\n    });\n\n    it('returns the signed positive unchanged', () => {\n        const signed = decimalFixedPoint('signed', 32, 2);\n        expect(absoluteDecimalFixedPoint(signed('1.5')).raw).toBe(150n);\n    });\n\n    it('returns the unsigned input unchanged', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(absoluteDecimalFixedPoint(usd('1.5')).raw).toBe(150n);\n    });\n\n    it('returns a frozen value', () => {\n        const signed = decimalFixedPoint('signed', 32, 2);\n        expect(absoluteDecimalFixedPoint(signed('-1.5'))).toBeFrozenObject();\n    });\n\n    it('throws ARITHMETIC_OVERFLOW on the minimum signed value', () => {\n        const factory = rawDecimalFixedPoint('signed', 8, 0);\n        expect(() => absoluteDecimalFixedPoint(factory(-128n))).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'decimalFixedPoint',\n                max: 127n,\n                min: -128n,\n                operation: 'absolute',\n                result: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/decimal-codec-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY,\n    SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    decimalFixedPoint,\n    getDecimalFixedPointCodec,\n    getDecimalFixedPointDecoder,\n    getDecimalFixedPointEncoder,\n    rawDecimalFixedPoint,\n} from '../decimal';\n\ndescribe('getDecimalFixedPointEncoder', () => {\n    it('encodes an unsigned 8-bit value', () => {\n        const encoder = getDecimalFixedPointEncoder('unsigned', 8, 0);\n        expect(encoder.encode(rawDecimalFixedPoint('unsigned', 8, 0)(42n))).toEqual(new Uint8Array([0x2a]));\n    });\n\n    it(\"encodes a signed 8-bit negative value using two's-complement\", () => {\n        const encoder = getDecimalFixedPointEncoder('signed', 8, 0);\n        expect(encoder.encode(rawDecimalFixedPoint('signed', 8, 0)(-1n))).toEqual(new Uint8Array([0xff]));\n    });\n\n    it('encodes an unsigned 64-bit value at 2 decimals in little-endian by default', () => {\n        const encoder = getDecimalFixedPointEncoder('unsigned', 64, 2);\n        // 42.50 has raw 4250n → 0x0000000000000019a in LE → [0x9a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]\n        expect(encoder.encode(decimalFixedPoint('unsigned', 64, 2)('42.50'))).toEqual(\n            new Uint8Array([0x9a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),\n        );\n    });\n\n    it('encodes in big-endian when configured', () => {\n        const encoder = getDecimalFixedPointEncoder('unsigned', 16, 0, { endian: 'be' });\n        expect(encoder.encode(rawDecimalFixedPoint('unsigned', 16, 0)(0x1234n))).toEqual(new Uint8Array([0x12, 0x34]));\n    });\n\n    it('encodes an unsigned 24-bit value (byte-aligned width without a matching number codec)', () => {\n        const encoder = getDecimalFixedPointEncoder('unsigned', 24, 0);\n        expect(encoder.encode(rawDecimalFixedPoint('unsigned', 24, 0)(0xabcdefn))).toEqual(\n            new Uint8Array([0xef, 0xcd, 0xab]),\n        );\n    });\n\n    it('reports the correct fixed size', () => {\n        expect(getDecimalFixedPointEncoder('unsigned', 64, 2).fixedSize).toBe(8);\n        expect(getDecimalFixedPointEncoder('unsigned', 128, 18).fixedSize).toBe(16);\n    });\n\n    it('throws TOTAL_BITS_NOT_BYTE_ALIGNED for a non-byte-aligned total bits', () => {\n        expect(() => getDecimalFixedPointEncoder('unsigned', 12, 2)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED, {\n                kind: 'decimalFixedPoint',\n                totalBits: 12,\n            }),\n        );\n    });\n\n    it('throws INVALID_TOTAL_BITS for a non-positive total bits', () => {\n        expect(() => getDecimalFixedPointEncoder('unsigned', 0, 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n                kind: 'decimalFixedPoint',\n                totalBits: 0,\n            }),\n        );\n    });\n\n    it('throws INVALID_DECIMALS for a negative decimals', () => {\n        expect(() => getDecimalFixedPointEncoder('unsigned', 64, -1)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS, {\n                decimals: -1,\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when encoding a value whose shape does not match the codec', () => {\n        const encoder = getDecimalFixedPointEncoder('unsigned', 64, 6);\n        const mismatched = rawDecimalFixedPoint('unsigned', 64, 2)(1n);\n        expect(() =>\n            // @ts-expect-error The value's shape does not match the codec's shape.\n            encoder.encode(mismatched),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'decimalFixedPoint',\n                actualScale: 2,\n                actualScaleLabel: 'decimals',\n                actualSignedness: 'unsigned',\n                actualTotalBits: 64,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 6,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'unsigned',\n                expectedTotalBits: 64,\n                operation: 'getDecimalFixedPointEncoder',\n            }),\n        );\n    });\n});\n\ndescribe('getDecimalFixedPointDecoder', () => {\n    it('decodes an unsigned 8-bit value', () => {\n        const decoder = getDecimalFixedPointDecoder('unsigned', 8, 0);\n        expect(decoder.decode(new Uint8Array([0x2a]))).toEqual({\n            decimals: 0,\n            kind: 'decimalFixedPoint',\n            raw: 42n,\n            signedness: 'unsigned',\n            totalBits: 8,\n        });\n    });\n\n    it(\"decodes a signed 8-bit negative value via two's-complement\", () => {\n        const decoder = getDecimalFixedPointDecoder('signed', 8, 0);\n        expect(decoder.decode(new Uint8Array([0xff])).raw).toBe(-1n);\n    });\n\n    it('decodes an unsigned 64-bit value at 2 decimals in little-endian', () => {\n        const decoder = getDecimalFixedPointDecoder('unsigned', 64, 2);\n        expect(decoder.decode(new Uint8Array([0x9a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])).raw).toBe(4250n);\n    });\n\n    it('decodes in big-endian when configured', () => {\n        const decoder = getDecimalFixedPointDecoder('unsigned', 16, 0, { endian: 'be' });\n        expect(decoder.decode(new Uint8Array([0x12, 0x34])).raw).toBe(0x1234n);\n    });\n\n    it('returns a frozen value', () => {\n        const decoder = getDecimalFixedPointDecoder('unsigned', 8, 0);\n        expect(decoder.decode(new Uint8Array([0x2a]))).toBeFrozenObject();\n    });\n\n    it('throws TOTAL_BITS_NOT_BYTE_ALIGNED for a non-byte-aligned total bits', () => {\n        expect(() => getDecimalFixedPointDecoder('unsigned', 12, 2)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED, {\n                kind: 'decimalFixedPoint',\n                totalBits: 12,\n            }),\n        );\n    });\n\n    it('throws CANNOT_DECODE_EMPTY_BYTE_ARRAY when decoding from an empty buffer', () => {\n        const decoder = getDecimalFixedPointDecoder('unsigned', 16, 2);\n        expect(() => decoder.decode(new Uint8Array([]))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__CANNOT_DECODE_EMPTY_BYTE_ARRAY, {\n                codecDescription: 'getDecimalFixedPointDecoder',\n            }),\n        );\n    });\n\n    it('throws INVALID_BYTE_LENGTH when decoding from a too-short buffer', () => {\n        const decoder = getDecimalFixedPointDecoder('unsigned', 64, 6);\n        expect(() => decoder.decode(new Uint8Array([0x01, 0x02]))).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n                bytesLength: 2,\n                codecDescription: 'getDecimalFixedPointDecoder',\n                expected: 8,\n            }),\n        );\n    });\n});\n\ndescribe('getDecimalFixedPointCodec', () => {\n    describe.each([{ endian: 'le' as const }, { endian: 'be' as const }])('under $endian endianness', ({ endian }) => {\n        it.each([\n            { decimals: 0, raw: 42n, signedness: 'signed' as const, totalBits: 8 },\n            { decimals: 0, raw: -42n, signedness: 'signed' as const, totalBits: 8 },\n            { decimals: 2, raw: 4250n, signedness: 'unsigned' as const, totalBits: 64 },\n            { decimals: 6, raw: 100_123_456n, signedness: 'unsigned' as const, totalBits: 64 },\n            { decimals: 18, raw: 100_123_456_789_012_345_678n, signedness: 'unsigned' as const, totalBits: 128 },\n            { decimals: 2, raw: -1234567n, signedness: 'signed' as const, totalBits: 64 },\n        ])(\n            'round-trips $signedness $totalBits-bit values with $decimals decimals (raw $raw)',\n            ({ signedness, totalBits, decimals, raw }) => {\n                const codec = getDecimalFixedPointCodec(signedness, totalBits, decimals, { endian });\n                const value = rawDecimalFixedPoint(signedness, totalBits, decimals)(raw);\n                const decoded = codec.decode(codec.encode(value));\n                expect(decoded.raw).toBe(raw);\n                expect(decoded.signedness).toBe(signedness);\n                expect(decoded.totalBits).toBe(totalBits);\n                expect(decoded.decimals).toBe(decimals);\n            },\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/decimal-comparisons-test.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, SolanaError } from '@solana/errors';\n\nimport {\n    cmpDecimalFixedPoint,\n    decimalFixedPoint,\n    eqDecimalFixedPoint,\n    gtDecimalFixedPoint,\n    gteDecimalFixedPoint,\n    ltDecimalFixedPoint,\n    lteDecimalFixedPoint,\n    rawDecimalFixedPoint,\n} from '../decimal';\n\ndescribe('cmpDecimalFixedPoint', () => {\n    it('returns -1 when the first operand is smaller', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(cmpDecimalFixedPoint(usd('1.25'), usd('2.50'))).toBe(-1);\n    });\n\n    it('returns 0 when the two operands are equal', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(cmpDecimalFixedPoint(usd('2.50'), usd('2.50'))).toBe(0);\n    });\n\n    it('returns 1 when the first operand is greater', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(cmpDecimalFixedPoint(usd('3.75'), usd('2.50'))).toBe(1);\n    });\n\n    it('compares negative and positive signed values correctly', () => {\n        const signed = decimalFixedPoint('signed', 64, 2);\n        expect(cmpDecimalFixedPoint(signed('-2.50'), signed('2.50'))).toBe(-1);\n        expect(cmpDecimalFixedPoint(signed('-2.50'), signed('-2.50'))).toBe(0);\n        expect(cmpDecimalFixedPoint(signed('-1.25'), signed('-2.50'))).toBe(1);\n    });\n\n    it('treats zero as equal to zero', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(cmpDecimalFixedPoint(usd('0'), usd('0'))).toBe(0);\n    });\n\n    it('treats minus zero as equal to zero', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(cmpDecimalFixedPoint(usd('-0'), usd('0'))).toBe(0);\n    });\n\n    it('allows operands with different signedness', () => {\n        const signed = rawDecimalFixedPoint('signed', 16, 2);\n        const unsigned = rawDecimalFixedPoint('unsigned', 16, 2);\n        expect(cmpDecimalFixedPoint(signed(-1n), unsigned(1n))).toBe(-1);\n        expect(cmpDecimalFixedPoint(signed(1n), unsigned(1n))).toBe(0);\n        expect(cmpDecimalFixedPoint(signed(2n), unsigned(1n))).toBe(1);\n    });\n\n    it('allows operands with different totalBits', () => {\n        const small = rawDecimalFixedPoint('unsigned', 8, 2);\n        const large = rawDecimalFixedPoint('unsigned', 32, 2);\n        expect(cmpDecimalFixedPoint(small(100n), large(100n))).toBe(0);\n        expect(cmpDecimalFixedPoint(small(100n), large(200n))).toBe(-1);\n    });\n\n    it('allows operands with different signedness and totalBits combined', () => {\n        const signed8 = rawDecimalFixedPoint('signed', 8, 0);\n        const unsigned32 = rawDecimalFixedPoint('unsigned', 32, 0);\n        expect(cmpDecimalFixedPoint(signed8(5n), unsigned32(5n))).toBe(0);\n    });\n\n    it('throws SHAPE_MISMATCH when decimals differ', () => {\n        const twoDecimals = rawDecimalFixedPoint('unsigned', 64, 2);\n        const fourDecimals = rawDecimalFixedPoint('unsigned', 64, 4);\n        expect(() =>\n            // @ts-expect-error Operands must share the same decimals.\n            cmpDecimalFixedPoint(twoDecimals(1n), fourDecimals(1n)),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'decimalFixedPoint',\n                actualScale: 4,\n                actualScaleLabel: 'decimals',\n                actualSignedness: 'unsigned',\n                actualTotalBits: 64,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 2,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'unsigned',\n                expectedTotalBits: 64,\n                operation: 'cmpDecimalFixedPoint',\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when the second operand is not a fixed-point value', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(() =>\n            // @ts-expect-error Second operand must be a DecimalFixedPoint.\n            cmpDecimalFixedPoint(usd('2.50'), 42),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'unknown',\n                actualScale: 0,\n                actualScaleLabel: 'unknown',\n                actualSignedness: 'unknown',\n                actualTotalBits: 0,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 2,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'unknown',\n                expectedTotalBits: 0,\n                operation: 'cmpDecimalFixedPoint',\n            }),\n        );\n    });\n});\n\ndescribe('eqDecimalFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(eqDecimalFixedPoint(usd('1.25'), usd('2.50'))).toBe(false);\n        expect(eqDecimalFixedPoint(usd('2.50'), usd('2.50'))).toBe(true);\n        expect(eqDecimalFixedPoint(usd('3.75'), usd('2.50'))).toBe(false);\n    });\n});\n\ndescribe('ltDecimalFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(ltDecimalFixedPoint(usd('1.25'), usd('2.50'))).toBe(true);\n        expect(ltDecimalFixedPoint(usd('2.50'), usd('2.50'))).toBe(false);\n        expect(ltDecimalFixedPoint(usd('3.75'), usd('2.50'))).toBe(false);\n    });\n});\n\ndescribe('lteDecimalFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(lteDecimalFixedPoint(usd('1.25'), usd('2.50'))).toBe(true);\n        expect(lteDecimalFixedPoint(usd('2.50'), usd('2.50'))).toBe(true);\n        expect(lteDecimalFixedPoint(usd('3.75'), usd('2.50'))).toBe(false);\n    });\n});\n\ndescribe('gtDecimalFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(gtDecimalFixedPoint(usd('1.25'), usd('2.50'))).toBe(false);\n        expect(gtDecimalFixedPoint(usd('2.50'), usd('2.50'))).toBe(false);\n        expect(gtDecimalFixedPoint(usd('3.75'), usd('2.50'))).toBe(true);\n    });\n});\n\ndescribe('gteDecimalFixedPoint', () => {\n    it('returns the expected boolean for less, equal, and greater', () => {\n        const usd = decimalFixedPoint('unsigned', 64, 2);\n        expect(gteDecimalFixedPoint(usd('1.25'), usd('2.50'))).toBe(false);\n        expect(gteDecimalFixedPoint(usd('2.50'), usd('2.50'))).toBe(true);\n        expect(gteDecimalFixedPoint(usd('3.75'), usd('2.50'))).toBe(true);\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/decimal-conversions-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    decimalFixedPoint,\n    rawDecimalFixedPoint,\n    rescaleDecimalFixedPoint,\n    toSignedDecimalFixedPoint,\n    toUnsignedDecimalFixedPoint,\n} from '../decimal';\n\ndescribe('toUnsignedDecimalFixedPoint', () => {\n    it('converts a signed non-negative value to unsigned', () => {\n        const signed = rawDecimalFixedPoint('signed', 8, 2)(100n);\n        const unsigned = toUnsignedDecimalFixedPoint(signed);\n        expect(unsigned.signedness).toBe('unsigned');\n        expect(unsigned.raw).toBe(100n);\n    });\n\n    it('returns the same reference when the input is already unsigned', () => {\n        const unsigned = rawDecimalFixedPoint('unsigned', 8, 2)(100n);\n        expect(toUnsignedDecimalFixedPoint(unsigned)).toBe(unsigned);\n    });\n\n    it('preserves totalBits and decimals', () => {\n        const signed = rawDecimalFixedPoint('signed', 64, 6)(1n);\n        const unsigned = toUnsignedDecimalFixedPoint(signed);\n        expect(unsigned.totalBits).toBe(64);\n        expect(unsigned.decimals).toBe(6);\n    });\n\n    it('returns a frozen value', () => {\n        const signed = rawDecimalFixedPoint('signed', 8, 2)(100n);\n        expect(toUnsignedDecimalFixedPoint(signed)).toBeFrozenObject();\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when converting a negative value', () => {\n        const signed = rawDecimalFixedPoint('signed', 8, 2)(-1n);\n        expect(() => toUnsignedDecimalFixedPoint(signed)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                raw: -1n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('toSignedDecimalFixedPoint', () => {\n    it('converts an unsigned value that fits the signed range', () => {\n        const unsigned = rawDecimalFixedPoint('unsigned', 8, 2)(100n);\n        const signed = toSignedDecimalFixedPoint(unsigned);\n        expect(signed.signedness).toBe('signed');\n        expect(signed.raw).toBe(100n);\n    });\n\n    it('returns the same reference when the input is already signed', () => {\n        const signed = rawDecimalFixedPoint('signed', 8, 2)(-50n);\n        expect(toSignedDecimalFixedPoint(signed)).toBe(signed);\n    });\n\n    it('preserves totalBits and decimals', () => {\n        const unsigned = rawDecimalFixedPoint('unsigned', 64, 6)(1n);\n        const signed = toSignedDecimalFixedPoint(unsigned);\n        expect(signed.totalBits).toBe(64);\n        expect(signed.decimals).toBe(6);\n    });\n\n    it('returns a frozen value', () => {\n        const unsigned = rawDecimalFixedPoint('unsigned', 8, 2)(100n);\n        expect(toSignedDecimalFixedPoint(unsigned)).toBeFrozenObject();\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the unsigned value exceeds the signed upper bound', () => {\n        const unsigned = rawDecimalFixedPoint('unsigned', 8, 2)(200n);\n        expect(() => toSignedDecimalFixedPoint(unsigned)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: 200n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('rescaleDecimalFixedPoint', () => {\n    it('returns the same reference when the requested shape matches', () => {\n        const value = decimalFixedPoint('unsigned', 64, 2)('1.50');\n        expect(rescaleDecimalFixedPoint(value, 64, 2)).toBe(value);\n    });\n\n    it('scales up decimals exactly', () => {\n        // raw 1 at d2 represents 0.01; moving to d4 scales raw to 100.\n        const source = rawDecimalFixedPoint('unsigned', 64, 2)(1n);\n        const rescaled = rescaleDecimalFixedPoint(source, 64, 4);\n        expect(rescaled.raw).toBe(100n);\n        expect(rescaled.decimals).toBe(4);\n        expect(rescaled.totalBits).toBe(64);\n    });\n\n    it('scales down decimals exactly', () => {\n        // raw 100 at d4 represents 0.01; moving to d2 scales raw to 1.\n        const source = rawDecimalFixedPoint('unsigned', 64, 4)(100n);\n        expect(rescaleDecimalFixedPoint(source, 64, 2).raw).toBe(1n);\n    });\n\n    it('widens totalBits while preserving decimals and raw', () => {\n        const source = rawDecimalFixedPoint('unsigned', 16, 2)(100n);\n        const rescaled = rescaleDecimalFixedPoint(source, 64, 2);\n        expect(rescaled.raw).toBe(100n);\n        expect(rescaled.totalBits).toBe(64);\n        expect(rescaled.decimals).toBe(2);\n    });\n\n    it('narrows totalBits when the value fits', () => {\n        const source = rawDecimalFixedPoint('unsigned', 16, 0)(100n);\n        expect(rescaleDecimalFixedPoint(source, 8, 0).raw).toBe(100n);\n    });\n\n    it('preserves signedness', () => {\n        const source = rawDecimalFixedPoint('signed', 16, 2)(-100n);\n        expect(rescaleDecimalFixedPoint(source, 32, 2).signedness).toBe('signed');\n    });\n\n    it('returns a frozen value when the shape changes', () => {\n        const source = rawDecimalFixedPoint('unsigned', 64, 2)(1n);\n        expect(rescaleDecimalFixedPoint(source, 64, 4)).toBeFrozenObject();\n    });\n\n    it('bridges EVM USDC (u128 d18) down to SPL USDC (u64 d6) with floor rounding', () => {\n        const evmUsdc = decimalFixedPoint('unsigned', 128, 18);\n        const bridged = rescaleDecimalFixedPoint(evmUsdc('100.123456789012345678'), 64, 6, 'floor');\n        expect(bridged.raw).toBe(100_123_456n);\n        expect(bridged.totalBits).toBe(64);\n        expect(bridged.decimals).toBe(6);\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when scale-down is inexact', () => {\n        // raw 1 at d4 represents 0.0001; moving to d2 requires dividing by 100 which is lossy.\n        const source = rawDecimalFixedPoint('unsigned', 64, 4)(1n);\n        expect(() => rescaleDecimalFixedPoint(source, 64, 2)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'decimalFixedPoint',\n                operation: 'rescale',\n            }),\n        );\n    });\n\n    it('rounds an inexact scale-down when a non-strict rounding mode is supplied', () => {\n        const source = rawDecimalFixedPoint('unsigned', 64, 4)(1n);\n        expect(rescaleDecimalFixedPoint(source, 64, 2, 'floor').raw).toBe(0n);\n        expect(rescaleDecimalFixedPoint(source, 64, 2, 'ceil').raw).toBe(1n);\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when narrowing totalBits overflows the target range', () => {\n        const source = rawDecimalFixedPoint('unsigned', 16, 0)(300n);\n        expect(() => rescaleDecimalFixedPoint(source, 8, 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                operation: 'rescale',\n                result: 300n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws ARITHMETIC_OVERFLOW when scaling up decimals overflows the target totalBits', () => {\n        // raw 100 at d0 → scaling up to d2 multiplies by 100 → 10000 which exceeds signed 8-bit max 127.\n        const source = rawDecimalFixedPoint('signed', 8, 0)(100n);\n        expect(() => rescaleDecimalFixedPoint(source, 8, 2)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n                kind: 'decimalFixedPoint',\n                max: 127n,\n                min: -128n,\n                operation: 'rescale',\n                result: 10000n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws INVALID_TOTAL_BITS for a non-positive target totalBits', () => {\n        const source = rawDecimalFixedPoint('unsigned', 8, 2)(1n);\n        expect(() => rescaleDecimalFixedPoint(source, 0, 0)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n                kind: 'decimalFixedPoint',\n                totalBits: 0,\n            }),\n        );\n    });\n\n    it('throws INVALID_DECIMALS for a negative target decimals', () => {\n        const source = rawDecimalFixedPoint('unsigned', 8, 2)(1n);\n        expect(() => rescaleDecimalFixedPoint(source, 8, -1)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS, {\n                decimals: -1,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/decimal-core-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_STRING,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO,\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { decimalFixedPoint, ratioDecimalFixedPoint, rawDecimalFixedPoint } from '../decimal/core';\n\ndescribe('decimalFixedPoint', () => {\n    it('constructs values from decimal strings', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        expect(usdc('0').raw).toBe(0n);\n        expect(usdc('1').raw).toBe(1000000n);\n        expect(usdc('42.5').raw).toBe(42500000n);\n        expect(usdc('0.000001').raw).toBe(1n);\n        expect(usdc('1234567890.123456').raw).toBe(1234567890123456n);\n    });\n\n    it('accepts negative values for signed shapes', () => {\n        const signed = decimalFixedPoint('signed', 32, 2);\n        expect(signed('-1.5').raw).toBe(-150n);\n        expect(signed('-0').raw).toBe(0n);\n    });\n\n    it('returns values whose fields match the shape and kind', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        expect(usdc('1.5')).toEqual({\n            decimals: 6,\n            kind: 'decimalFixedPoint',\n            raw: 1500000n,\n            signedness: 'unsigned',\n            totalBits: 64,\n        });\n    });\n\n    it('returns frozen values', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        expect(usdc('1.5')).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when the input has more precision than the target', () => {\n        const cents = decimalFixedPoint('unsigned', 16, 2);\n        expect(() => cents('1.234')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'decimalFixedPoint',\n                operation: 'fromString',\n            }),\n        );\n    });\n\n    it('rounds excess precision when a non-strict rounding mode is supplied', () => {\n        const cents = decimalFixedPoint('unsigned', 16, 2);\n        expect(cents('1.234', 'floor').raw).toBe(123n);\n        expect(cents('1.234', 'ceil').raw).toBe(124n);\n        expect(cents('1.235', 'round').raw).toBe(124n); // tie away from zero\n        expect(cents('1.234', 'trunc').raw).toBe(123n);\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the result exceeds the unsigned upper bound', () => {\n        const tiny = decimalFixedPoint('unsigned', 8, 0);\n        expect(() => tiny('256')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                raw: 256n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the result exceeds the signed upper bound', () => {\n        const signed = decimalFixedPoint('signed', 8, 0);\n        expect(() => signed('128')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the result is below the signed lower bound', () => {\n        const signed = decimalFixedPoint('signed', 8, 0);\n        expect(() => signed('-129')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: -129n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws INVALID_STRING on malformed inputs', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        expect(() => usdc('abc')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_STRING, {\n                input: 'abc',\n                kind: 'decimalFixedPoint',\n            }),\n        );\n    });\n\n    it('throws INVALID_TOTAL_BITS when totalBits is not a positive integer', () => {\n        for (const bad of [0, -1, 1.5, Number.NaN, '64' as unknown as number]) {\n            expect(() => decimalFixedPoint('unsigned', bad, 6)).toThrow(\n                new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n                    kind: 'decimalFixedPoint',\n                    totalBits: bad,\n                }),\n            );\n        }\n    });\n\n    it('throws INVALID_DECIMALS when decimals is not a non-negative integer', () => {\n        for (const bad of [-1, 1.5, Number.NaN, '6' as unknown as number]) {\n            expect(() => decimalFixedPoint('unsigned', 64, bad)).toThrow(\n                new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS, { decimals: bad }),\n            );\n        }\n    });\n\n    it('allows decimals to exceed totalBits, since decimal shapes do not enforce that constraint', () => {\n        // decimal(unsigned, 8, 10) with raw=0n represents 0, which fits fine\n        // — decimal fixed-points with many decimals and few bits are valid.\n        const tiny = decimalFixedPoint('unsigned', 8, 10);\n        expect(tiny('0').raw).toBe(0n);\n    });\n});\n\ndescribe('rawDecimalFixedPoint', () => {\n    it('constructs values directly from a raw bigint', () => {\n        const cents = rawDecimalFixedPoint('unsigned', 16, 2);\n        expect(cents(425n)).toEqual({\n            decimals: 2,\n            kind: 'decimalFixedPoint',\n            raw: 425n,\n            signedness: 'unsigned',\n            totalBits: 16,\n        });\n    });\n\n    it('returns frozen values', () => {\n        const cents = rawDecimalFixedPoint('unsigned', 16, 2);\n        expect(cents(425n)).toBeFrozenObject();\n    });\n\n    it('accepts negative raw values for signed shapes', () => {\n        const signed = rawDecimalFixedPoint('signed', 8, 2);\n        expect(signed(-128n).raw).toBe(-128n);\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the raw value exceeds the unsigned upper bound', () => {\n        const tiny = rawDecimalFixedPoint('unsigned', 8, 0);\n        expect(() => tiny(256n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                raw: 256n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the raw value exceeds the signed upper bound', () => {\n        const signed = rawDecimalFixedPoint('signed', 8, 0);\n        expect(() => signed(128n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: 128n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the raw value is below the signed lower bound', () => {\n        const signed = rawDecimalFixedPoint('signed', 8, 0);\n        expect(() => signed(-129n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 127n,\n                min: -128n,\n                raw: -129n,\n                signedness: 'signed',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('ratioDecimalFixedPoint', () => {\n    it('constructs values from exact ratios', () => {\n        const prob = ratioDecimalFixedPoint('unsigned', 64, 4);\n        expect(prob(1n, 4n).raw).toBe(2500n); // 0.2500\n        expect(prob(1n, 2n).raw).toBe(5000n); // 0.5000\n    });\n\n    it('returns frozen values', () => {\n        const prob = ratioDecimalFixedPoint('unsigned', 64, 4);\n        expect(prob(1n, 4n)).toBeFrozenObject();\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS under the default rounding when the ratio is inexact', () => {\n        const prob = ratioDecimalFixedPoint('unsigned', 64, 4);\n        expect(() => prob(1n, 3n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'decimalFixedPoint',\n                operation: 'fromRatio',\n            }),\n        );\n    });\n\n    it('rounds inexact ratios when a non-strict rounding mode is supplied', () => {\n        const prob = ratioDecimalFixedPoint('unsigned', 64, 4);\n        expect(prob(1n, 3n, 'floor').raw).toBe(3333n);\n        expect(prob(1n, 3n, 'ceil').raw).toBe(3334n);\n        expect(prob(1n, 3n, 'round').raw).toBe(3333n);\n    });\n\n    it('throws INVALID_ZERO_DENOMINATOR_RATIO when the denominator is zero', () => {\n        const prob = ratioDecimalFixedPoint('unsigned', 64, 4);\n        expect(() => prob(1n, 0n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO, {\n                denominator: 0n,\n                kind: 'decimalFixedPoint',\n                numerator: 1n,\n            }),\n        );\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the ratio overflows the target shape', () => {\n        const tiny = ratioDecimalFixedPoint('unsigned', 8, 0);\n        expect(() => tiny(256n, 1n)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                raw: 256n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n});\n\ndescribe('decimal factory shape validation', () => {\n    it('rejects zero totalBits up front from every decimal factory', () => {\n        for (const factory of [decimalFixedPoint, rawDecimalFixedPoint, ratioDecimalFixedPoint]) {\n            expect(() => factory('unsigned', 0, 6)).toThrow(\n                new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n                    kind: 'decimalFixedPoint',\n                    totalBits: 0,\n                }),\n            );\n        }\n    });\n\n    it('rejects negative decimals up front from every decimal factory', () => {\n        for (const factory of [decimalFixedPoint, rawDecimalFixedPoint, ratioDecimalFixedPoint]) {\n            expect(() => factory('unsigned', 64, -1)).toThrow(\n                new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS, { decimals: -1 }),\n            );\n        }\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/decimal-formatting-test.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, SolanaError } from '@solana/errors';\n\nimport {\n    decimalFixedPoint,\n    decimalFixedPointToNumber,\n    decimalFixedPointToString,\n    formatDecimalFixedPoint,\n    rawDecimalFixedPoint,\n} from '../decimal';\n\ndescribe('decimalFixedPointToString', () => {\n    it('renders zero', () => {\n        expect(decimalFixedPointToString(rawDecimalFixedPoint('unsigned', 64, 2)(0n))).toBe('0');\n    });\n\n    it('renders a whole number with trailing zeros trimmed', () => {\n        expect(decimalFixedPointToString(rawDecimalFixedPoint('unsigned', 64, 6)(42_000_000n))).toBe('42');\n    });\n\n    it('renders a clean fractional value with trailing zeros trimmed', () => {\n        expect(decimalFixedPointToString(rawDecimalFixedPoint('unsigned', 64, 6)(42_500_000n))).toBe('42.5');\n    });\n\n    it('renders a sub-unit fraction with a leading zero padding', () => {\n        expect(decimalFixedPointToString(rawDecimalFixedPoint('unsigned', 16, 2)(5n))).toBe('0.05');\n    });\n\n    it('renders a negative value with a leading sign', () => {\n        expect(decimalFixedPointToString(rawDecimalFixedPoint('signed', 16, 2)(-5n))).toBe('-0.05');\n    });\n\n    it('renders an integer when decimals is zero', () => {\n        expect(decimalFixedPointToString(rawDecimalFixedPoint('unsigned', 8, 0)(42n))).toBe('42');\n    });\n\n    it('renders values whose raw exceeds Number.MAX_SAFE_INTEGER correctly', () => {\n        // 10 ** 20 / 10 ** 6 = 10 ** 14 = 100000000000000.\n        const value = rawDecimalFixedPoint('unsigned', 128, 6)(10n ** 20n);\n        expect(decimalFixedPointToString(value)).toBe('100000000000000');\n    });\n\n    it('caps the fractional output at the requested decimals using the given rounding mode', () => {\n        // 42.678 at d3 → 2 decimals with floor → 42.67.\n        const value = rawDecimalFixedPoint('unsigned', 64, 3)(42_678n);\n        expect(decimalFixedPointToString(value, { decimals: 2, rounding: 'floor' })).toBe('42.67');\n    });\n\n    it('rounds half values away from zero under the round mode', () => {\n        const value = rawDecimalFixedPoint('unsigned', 64, 1)(425n); // 42.5\n        expect(decimalFixedPointToString(value, { decimals: 0, rounding: 'round' })).toBe('43');\n    });\n\n    it('trims trailing zeros even when the requested decimals is larger than the native scale', () => {\n        const value = rawDecimalFixedPoint('unsigned', 64, 2)(4250n); // 42.5\n        expect(decimalFixedPointToString(value, { decimals: 10 })).toBe('42.5');\n    });\n\n    it('pads trailing zeros up to the requested decimals when padTrailingZeros is true', () => {\n        const value = rawDecimalFixedPoint('unsigned', 64, 2)(4250n); // 42.5\n        expect(decimalFixedPointToString(value, { decimals: 6, padTrailingZeros: true })).toBe('42.500000');\n    });\n\n    it('pads trailing zeros up to the native decimals when padTrailingZeros is true and decimals is omitted', () => {\n        const value = rawDecimalFixedPoint('unsigned', 64, 6)(42_500_000n); // 42.5 at d6\n        expect(decimalFixedPointToString(value, { padTrailingZeros: true })).toBe('42.500000');\n    });\n\n    it('pads whole numbers with trailing zeros when padTrailingZeros is true', () => {\n        const value = rawDecimalFixedPoint('unsigned', 64, 6)(0n);\n        expect(decimalFixedPointToString(value, { padTrailingZeros: true })).toBe('0.000000');\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS when a lossy cap is requested without a rounding mode', () => {\n        const value = rawDecimalFixedPoint('unsigned', 64, 1)(425n); // 42.5\n        expect(() => decimalFixedPointToString(value, { decimals: 0 })).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'decimalFixedPoint',\n                operation: 'toString',\n            }),\n        );\n    });\n\n    it('does not throw when capping at the same number of decimals as the native scale', () => {\n        const value = rawDecimalFixedPoint('unsigned', 64, 2)(4250n);\n        expect(decimalFixedPointToString(value, { decimals: 2 })).toBe('42.5');\n    });\n});\n\ndescribe('formatDecimalFixedPoint', () => {\n    it('formats zero with a default formatter', () => {\n        const formatter = new Intl.NumberFormat('en-US');\n        const value = rawDecimalFixedPoint('unsigned', 64, 6)(0n);\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('0');\n    });\n\n    it('formats a simple value with a default formatter', () => {\n        const formatter = new Intl.NumberFormat('en-US');\n        const value = decimalFixedPoint('unsigned', 64, 6)('42.5');\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('42.5');\n    });\n\n    it('formats negative values with the formatter sign convention', () => {\n        const formatter = new Intl.NumberFormat('en-US');\n        const value = decimalFixedPoint('signed', 64, 2)('-0.05');\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('-0.05');\n    });\n\n    it('respects a non-default locale', () => {\n        const formatter = new Intl.NumberFormat('de-DE');\n        const value = decimalFixedPoint('unsigned', 64, 2)('1234.5');\n        // German uses '.' for grouping and ',' as the decimal separator.\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('1.234,5');\n    });\n\n    it('renders currency formatting', () => {\n        const formatter = new Intl.NumberFormat('en-US', { currency: 'USD', style: 'currency' });\n        const value = decimalFixedPoint('unsigned', 64, 6)('1234.5');\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('$1,234.50');\n    });\n\n    it('honours the formatter rounding via maximumFractionDigits', () => {\n        // raw 42678 at d3 represents 42.678; formatter caps to 2 fractional digits with default rounding → '42.68'.\n        const formatter = new Intl.NumberFormat('en-US', { maximumFractionDigits: 2, useGrouping: false });\n        const value = rawDecimalFixedPoint('unsigned', 64, 3)(42_678n);\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('42.68');\n    });\n\n    it('disables grouping separators when useGrouping is false', () => {\n        const formatter = new Intl.NumberFormat('en-US', { useGrouping: false });\n        const value = decimalFixedPoint('unsigned', 64, 2)('1234567.89');\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('1234567.89');\n    });\n\n    it('preserves precision when the raw value exceeds Number.MAX_SAFE_INTEGER', () => {\n        // raw 10 ** 20 at d6 represents 10 ** 14 = 100000000000000.\n        const formatter = new Intl.NumberFormat('en-US', { useGrouping: false });\n        const value = rawDecimalFixedPoint('unsigned', 128, 6)(10n ** 20n);\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('100000000000000');\n    });\n\n    it('combines locale, currency style, grouping, and fraction digits', () => {\n        const formatter = new Intl.NumberFormat('de-DE', {\n            currency: 'EUR',\n            maximumFractionDigits: 2,\n            minimumFractionDigits: 2,\n            style: 'currency',\n            useGrouping: true,\n        });\n        const value = decimalFixedPoint('unsigned', 64, 6)('1234567.891');\n        // German uses '.' for grouping, ',' as the decimal separator, and '€' as the currency suffix.\n        // ICU emits a no-break space (U+00A0) between the number and the currency symbol.\n        expect(formatDecimalFixedPoint(formatter, value)).toBe('1.234.567,89\\u00A0€');\n    });\n});\n\ndescribe('decimalFixedPointToNumber', () => {\n    it('returns zero for zero', () => {\n        expect(decimalFixedPointToNumber(rawDecimalFixedPoint('unsigned', 64, 2)(0n))).toBe(0);\n    });\n\n    it('returns 42.5 for raw 4250 at d2', () => {\n        expect(decimalFixedPointToNumber(rawDecimalFixedPoint('unsigned', 64, 2)(4250n))).toBe(42.5);\n    });\n\n    it('returns -0.05 for raw -5 at d2', () => {\n        expect(decimalFixedPointToNumber(rawDecimalFixedPoint('signed', 16, 2)(-5n))).toBe(-0.05);\n    });\n\n    it('returns the unscaled raw as a number when decimals is zero', () => {\n        expect(decimalFixedPointToNumber(rawDecimalFixedPoint('signed', 8, 0)(-42n))).toBe(-42);\n    });\n\n    it('returns an approximate finite number when the raw exceeds Number.MAX_SAFE_INTEGER', () => {\n        // 10 ** 20 / 10 ** 6 = 10 ** 14 = 100000000000000; the exact value fits Number cleanly.\n        const value = rawDecimalFixedPoint('unsigned', 128, 6)(10n ** 20n);\n        expect(decimalFixedPointToNumber(value)).toBeCloseTo(1e14, -2);\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/decimal-guards-test.ts",
    "content": "import {\n    SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { decimalFixedPoint, rawDecimalFixedPoint } from '../decimal/core';\nimport { assertIsDecimalFixedPoint, isDecimalFixedPoint } from '../decimal/guards';\n\ndescribe('isDecimalFixedPoint', () => {\n    it('returns true for valid decimal fixed-point values', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        expect(isDecimalFixedPoint(usdc('1.5'))).toBe(true);\n        expect(isDecimalFixedPoint(usdc('0'))).toBe(true);\n        const signed = rawDecimalFixedPoint('signed', 8, 2);\n        expect(isDecimalFixedPoint(signed(-128n))).toBe(true);\n    });\n\n    it('returns false for non-objects and wrong kinds', () => {\n        expect(isDecimalFixedPoint(42)).toBe(false);\n        expect(isDecimalFixedPoint('1.5')).toBe(false);\n        expect(isDecimalFixedPoint(null)).toBe(false);\n        expect(isDecimalFixedPoint(undefined)).toBe(false);\n        expect(isDecimalFixedPoint({})).toBe(false);\n        expect(isDecimalFixedPoint({ kind: 'binaryFixedPoint' })).toBe(false);\n    });\n\n    it('returns false when required fields are missing or malformed', () => {\n        const base = {\n            decimals: 6,\n            kind: 'decimalFixedPoint',\n            raw: 0n,\n            signedness: 'unsigned',\n            totalBits: 64,\n        };\n        expect(isDecimalFixedPoint({ ...base, signedness: 'weird' })).toBe(false);\n        expect(isDecimalFixedPoint({ ...base, totalBits: -1 })).toBe(false);\n        expect(isDecimalFixedPoint({ ...base, totalBits: 1.5 })).toBe(false);\n        expect(isDecimalFixedPoint({ ...base, decimals: -1 })).toBe(false);\n        expect(isDecimalFixedPoint({ ...base, raw: 1 })).toBe(false); // number instead of bigint\n    });\n\n    it('returns false when the raw value does not fit the claimed range', () => {\n        expect(\n            isDecimalFixedPoint({\n                decimals: 0,\n                kind: 'decimalFixedPoint',\n                raw: 256n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        ).toBe(false);\n    });\n\n    it('narrows to the specific shape when parameters are provided', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        const value = usdc('1.5');\n        expect(isDecimalFixedPoint(value, 'unsigned', 64, 6)).toBe(true);\n        expect(isDecimalFixedPoint(value, 'signed', 64, 6)).toBe(false);\n        expect(isDecimalFixedPoint(value, 'unsigned', 32, 6)).toBe(false);\n        expect(isDecimalFixedPoint(value, 'unsigned', 64, 9)).toBe(false);\n    });\n\n    it('accepts partial positional arguments, constraining only the fields that are provided', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        const value = usdc('1.5');\n        expect(isDecimalFixedPoint(value, 'unsigned')).toBe(true);\n        expect(isDecimalFixedPoint(value, 'signed')).toBe(false);\n        expect(isDecimalFixedPoint(value, 'unsigned', 64)).toBe(true);\n        expect(isDecimalFixedPoint(value, 'unsigned', 32)).toBe(false);\n    });\n\n    it('treats `undefined` as \"don’t care\" for any skipped field', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        const value = usdc('1.5');\n        expect(isDecimalFixedPoint(value, undefined, 64)).toBe(true);\n        expect(isDecimalFixedPoint(value, undefined, undefined, 6)).toBe(true);\n        expect(isDecimalFixedPoint(value, undefined, 32)).toBe(false);\n    });\n});\n\ndescribe('assertIsDecimalFixedPoint', () => {\n    it('passes silently for valid values', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        expect(() => assertIsDecimalFixedPoint(usdc('1.5'))).not.toThrow();\n        expect(() => assertIsDecimalFixedPoint(usdc('1.5'), 'unsigned', 64, 6)).not.toThrow();\n    });\n\n    it('throws SHAPE_MISMATCH for non-object inputs', () => {\n        expect(() => assertIsDecimalFixedPoint(42)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'unknown',\n                actualScale: 0,\n                actualScaleLabel: 'unknown',\n                actualSignedness: 'unknown',\n                actualTotalBits: 0,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 0,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'unknown',\n                expectedTotalBits: 0,\n                operation: 'assertIsDecimalFixedPoint',\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when the value is a binary fixed-point', () => {\n        expect(() => assertIsDecimalFixedPoint({ kind: 'binaryFixedPoint' })).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'binaryFixedPoint',\n                actualScale: 0,\n                actualScaleLabel: 'fractional bits',\n                actualSignedness: 'unknown',\n                actualTotalBits: 0,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 0,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'unknown',\n                expectedTotalBits: 0,\n                operation: 'assertIsDecimalFixedPoint',\n            }),\n        );\n    });\n\n    it('throws SHAPE_MISMATCH when a decimal value has the wrong totalBits', () => {\n        const usdc = decimalFixedPoint('unsigned', 64, 6);\n        expect(() => assertIsDecimalFixedPoint(usdc('1.5'), 'unsigned', 32, 6)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n                actualKind: 'decimalFixedPoint',\n                actualScale: 6,\n                actualScaleLabel: 'decimals',\n                actualSignedness: 'unsigned',\n                actualTotalBits: 64,\n                expectedKind: 'decimalFixedPoint',\n                expectedScale: 6,\n                expectedScaleLabel: 'decimals',\n                expectedSignedness: 'unsigned',\n                expectedTotalBits: 32,\n                operation: 'assertIsDecimalFixedPoint',\n            }),\n        );\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the raw value does not fit the claimed range', () => {\n        const malformed = {\n            decimals: 0,\n            kind: 'decimalFixedPoint' as const,\n            raw: 256n,\n            signedness: 'unsigned' as const,\n            totalBits: 8,\n        };\n        expect(() => assertIsDecimalFixedPoint(malformed)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 255n,\n                min: 0n,\n                raw: 256n,\n                signedness: 'unsigned',\n                totalBits: 8,\n            }),\n        );\n    });\n\n    it('throws MALFORMED_RAW_VALUE when the raw field is not a bigint', () => {\n        const malformed = {\n            decimals: 6,\n            kind: 'decimalFixedPoint' as const,\n            raw: 42,\n            signedness: 'unsigned' as const,\n            totalBits: 64,\n        };\n        expect(() => assertIsDecimalFixedPoint(malformed)).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE, {\n                kind: 'decimalFixedPoint',\n                raw: 42,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/parsing-test.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__INVALID_STRING, SolanaError } from '@solana/errors';\n\nimport { parseDecimalString } from '../parsing';\n\ndescribe('parseDecimalString', () => {\n    it('parses positive integers', () => {\n        expect(parseDecimalString('decimalFixedPoint', '0')).toEqual({ decimals: 0, raw: 0n });\n        expect(parseDecimalString('decimalFixedPoint', '42')).toEqual({ decimals: 0, raw: 42n });\n        expect(parseDecimalString('decimalFixedPoint', '007')).toEqual({ decimals: 0, raw: 7n });\n    });\n\n    it('parses negative integers', () => {\n        expect(parseDecimalString('decimalFixedPoint', '-42')).toEqual({ decimals: 0, raw: -42n });\n        expect(parseDecimalString('decimalFixedPoint', '-0')).toEqual({ decimals: 0, raw: 0n });\n    });\n\n    it('parses numbers with a fractional part', () => {\n        expect(parseDecimalString('decimalFixedPoint', '1.5')).toEqual({ decimals: 1, raw: 15n });\n        expect(parseDecimalString('decimalFixedPoint', '42.500')).toEqual({ decimals: 3, raw: 42500n });\n        expect(parseDecimalString('decimalFixedPoint', '-0.25')).toEqual({ decimals: 2, raw: -25n });\n    });\n\n    it('parses numbers with an implicit leading or trailing zero', () => {\n        expect(parseDecimalString('decimalFixedPoint', '.5')).toEqual({ decimals: 1, raw: 5n });\n        expect(parseDecimalString('decimalFixedPoint', '-.25')).toEqual({ decimals: 2, raw: -25n });\n        expect(parseDecimalString('decimalFixedPoint', '5.')).toEqual({ decimals: 0, raw: 5n });\n    });\n\n    it('rejects malformed inputs', () => {\n        const badInputs = ['', '-', '.', 'abc', '1e3', '+1', ' 1', '1 ', '1.2.3', '1,5', '0x10'];\n        for (const input of badInputs) {\n            expect(() => parseDecimalString('decimalFixedPoint', input)).toThrow(\n                new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_STRING, {\n                    input,\n                    kind: 'decimalFixedPoint',\n                }),\n            );\n        }\n    });\n\n    it('preserves the provided kind in the error context', () => {\n        expect(() => parseDecimalString('binaryFixedPoint', 'abc')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_STRING, {\n                input: 'abc',\n                kind: 'binaryFixedPoint',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__tests__/rounding-test.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, SolanaError } from '@solana/errors';\n\nimport { roundDivision, type RoundingMode } from '../rounding';\n\ndescribe('roundDivision', () => {\n    const div = (numerator: bigint, denominator: bigint, mode: RoundingMode) =>\n        roundDivision('decimalFixedPoint', 'test', numerator, denominator, mode);\n\n    it('returns the exact quotient when the division has no remainder', () => {\n        for (const mode of ['ceil', 'floor', 'round', 'strict', 'trunc'] as const) {\n            expect(div(10n, 2n, mode)).toBe(5n);\n            expect(div(-10n, 2n, mode)).toBe(-5n);\n            expect(div(0n, 7n, mode)).toBe(0n);\n        }\n    });\n\n    it('throws under strict mode when division is inexact', () => {\n        expect(() => div(10n, 3n, 'strict')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'decimalFixedPoint',\n                operation: 'test',\n            }),\n        );\n    });\n\n    it('truncates toward zero under trunc', () => {\n        expect(div(10n, 3n, 'trunc')).toBe(3n);\n        expect(div(-10n, 3n, 'trunc')).toBe(-3n);\n        expect(div(10n, -3n, 'trunc')).toBe(-3n);\n        expect(div(-10n, -3n, 'trunc')).toBe(3n);\n    });\n\n    it('rounds toward negative infinity under floor', () => {\n        expect(div(10n, 3n, 'floor')).toBe(3n);\n        expect(div(-10n, 3n, 'floor')).toBe(-4n);\n        expect(div(10n, -3n, 'floor')).toBe(-4n);\n        expect(div(-10n, -3n, 'floor')).toBe(3n);\n    });\n\n    it('rounds toward positive infinity under ceil', () => {\n        expect(div(10n, 3n, 'ceil')).toBe(4n);\n        expect(div(-10n, 3n, 'ceil')).toBe(-3n);\n        expect(div(10n, -3n, 'ceil')).toBe(-3n);\n        expect(div(-10n, -3n, 'ceil')).toBe(4n);\n    });\n\n    it('rounds to nearest with ties away from zero under round', () => {\n        // Non-tie: closer to the upper integer.\n        expect(div(7n, 4n, 'round')).toBe(2n); // 1.75 -> 2\n        expect(div(-7n, 4n, 'round')).toBe(-2n); // -1.75 -> -2\n\n        // Non-tie: closer to the lower integer.\n        expect(div(5n, 4n, 'round')).toBe(1n); // 1.25 -> 1\n        expect(div(-5n, 4n, 'round')).toBe(-1n); // -1.25 -> -1\n\n        // Ties break away from zero.\n        expect(div(10n, 4n, 'round')).toBe(3n); // 2.5 -> 3\n        expect(div(-10n, 4n, 'round')).toBe(-3n); // -2.5 -> -3\n        expect(div(6n, 4n, 'round')).toBe(2n); // 1.5 -> 2\n        expect(div(-6n, 4n, 'round')).toBe(-2n); // -1.5 -> -2\n    });\n\n    it('handles very large values without losing precision', () => {\n        expect(div((1n << 200n) + 1n, 3n, 'floor')).toBe((1n << 200n) / 3n);\n    });\n\n    it('preserves the provided kind and operation in strict-mode errors', () => {\n        expect(() => roundDivision('binaryFixedPoint', 'divide', 1n, 3n, 'strict')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'binaryFixedPoint',\n                operation: 'divide',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/binary-arithmetics-typetest.ts",
    "content": "import {\n    absoluteBinaryFixedPoint,\n    addBinaryFixedPoint,\n    type BinaryFixedPoint,\n    divideBinaryFixedPoint,\n    multiplyBinaryFixedPoint,\n    negateBinaryFixedPoint,\n    subtractBinaryFixedPoint,\n} from '../binary';\n\n// [DESCRIBE] addBinaryFixedPoint.\n{\n    // It preserves the full shape of both operands.\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        const b = {} as BinaryFixedPoint<'signed', 16, 15>;\n        addBinaryFixedPoint(a, b) satisfies BinaryFixedPoint<'signed', 16, 15>;\n    }\n\n    // It rejects operands whose shapes differ at the type level.\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        const b = {} as BinaryFixedPoint<'signed', 16, 8>;\n        // @ts-expect-error Operands must share the same shape.\n        addBinaryFixedPoint(a, b);\n    }\n}\n\n// [DESCRIBE] subtractBinaryFixedPoint.\n{\n    // It preserves the full shape of both operands.\n    {\n        const a = {} as BinaryFixedPoint<'unsigned', 32, 16>;\n        const b = {} as BinaryFixedPoint<'unsigned', 32, 16>;\n        subtractBinaryFixedPoint(a, b) satisfies BinaryFixedPoint<'unsigned', 32, 16>;\n    }\n\n    // It rejects operands whose shapes differ at the type level.\n    {\n        const a = {} as BinaryFixedPoint<'unsigned', 32, 16>;\n        const b = {} as BinaryFixedPoint<'unsigned', 32, 8>;\n        // @ts-expect-error Operands must share the same shape.\n        subtractBinaryFixedPoint(a, b);\n    }\n}\n\n// [DESCRIBE] multiplyBinaryFixedPoint.\n{\n    // It returns the shape of the first operand, regardless of the second.\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        const sameShape = {} as BinaryFixedPoint<'signed', 16, 15>;\n        multiplyBinaryFixedPoint(a, sameShape) satisfies BinaryFixedPoint<'signed', 16, 15>;\n    }\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        const differentShape = {} as BinaryFixedPoint<'signed', 32, 8>;\n        multiplyBinaryFixedPoint(a, differentShape) satisfies BinaryFixedPoint<'signed', 16, 15>;\n    }\n\n    // It accepts a bigint as the second operand.\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        multiplyBinaryFixedPoint(a, 3n) satisfies BinaryFixedPoint<'signed', 16, 15>;\n    }\n\n    // It rejects a plain `number` as the second operand.\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        // @ts-expect-error Second operand must be a BinaryFixedPoint or bigint, not a number.\n        multiplyBinaryFixedPoint(a, 3);\n    }\n\n    // It rejects a second operand whose signedness differs.\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        const wrongSignedness = {} as BinaryFixedPoint<'unsigned', 16, 15>;\n        // @ts-expect-error Second operand must share the first operand's signedness.\n        multiplyBinaryFixedPoint(a, wrongSignedness);\n    }\n}\n\n// [DESCRIBE] divideBinaryFixedPoint.\n{\n    // It behaves like multiply for the return-type shape and second-operand rules.\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        const different = {} as BinaryFixedPoint<'signed', 32, 8>;\n        divideBinaryFixedPoint(a, different) satisfies BinaryFixedPoint<'signed', 16, 15>;\n        divideBinaryFixedPoint(a, 3n) satisfies BinaryFixedPoint<'signed', 16, 15>;\n    }\n}\n\n// [DESCRIBE] negateBinaryFixedPoint.\n{\n    // It accepts a signed operand.\n    {\n        const a = {} as BinaryFixedPoint<'signed', 16, 15>;\n        negateBinaryFixedPoint(a) satisfies BinaryFixedPoint<'signed', 16, 15>;\n    }\n\n    // It rejects an unsigned operand at the type level.\n    {\n        const a = {} as BinaryFixedPoint<'unsigned', 16, 15>;\n        // @ts-expect-error Only signed values can be negated.\n        negateBinaryFixedPoint(a);\n    }\n}\n\n// [DESCRIBE] absoluteBinaryFixedPoint.\n{\n    // It accepts both signednesses and preserves the shape.\n    {\n        const signed = {} as BinaryFixedPoint<'signed', 16, 15>;\n        absoluteBinaryFixedPoint(signed) satisfies BinaryFixedPoint<'signed', 16, 15>;\n        const unsigned = {} as BinaryFixedPoint<'unsigned', 16, 15>;\n        absoluteBinaryFixedPoint(unsigned) satisfies BinaryFixedPoint<'unsigned', 16, 15>;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/binary-codec-typetest.ts",
    "content": "import type { FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport {\n    type BinaryFixedPoint,\n    getBinaryFixedPointCodec,\n    getBinaryFixedPointDecoder,\n    getBinaryFixedPointEncoder,\n} from '../binary';\n\n// [DESCRIBE] getBinaryFixedPointEncoder.\n{\n    // It preserves the shape generics in the encoded payload type.\n    {\n        const encoder = getBinaryFixedPointEncoder('signed', 16, 15);\n        encoder satisfies FixedSizeEncoder<BinaryFixedPoint<'signed', 16, 15>, 2>;\n    }\n\n    // It preserves the byte-size literal for all supported byte-aligned widths.\n    {\n        getBinaryFixedPointEncoder('unsigned', 8, 0) satisfies FixedSizeEncoder<BinaryFixedPoint<'unsigned', 8, 0>, 1>;\n        getBinaryFixedPointEncoder('signed', 32, 16) satisfies FixedSizeEncoder<BinaryFixedPoint<'signed', 32, 16>, 4>;\n        getBinaryFixedPointEncoder('unsigned', 128, 64) satisfies FixedSizeEncoder<\n            BinaryFixedPoint<'unsigned', 128, 64>,\n            16\n        >;\n    }\n}\n\n// [DESCRIBE] getBinaryFixedPointDecoder.\n{\n    // It preserves the shape generics in the decoded payload type.\n    {\n        const decoder = getBinaryFixedPointDecoder('signed', 16, 15);\n        decoder satisfies FixedSizeDecoder<BinaryFixedPoint<'signed', 16, 15>, 2>;\n    }\n}\n\n// [DESCRIBE] getBinaryFixedPointCodec.\n{\n    // It preserves the shape generics in both the encoded and decoded payload types.\n    {\n        const codec = getBinaryFixedPointCodec('unsigned', 128, 64);\n        codec satisfies FixedSizeCodec<\n            BinaryFixedPoint<'unsigned', 128, 64>,\n            BinaryFixedPoint<'unsigned', 128, 64>,\n            16\n        >;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/binary-conversions-typetest.ts",
    "content": "import {\n    type BinaryFixedPoint,\n    rescaleBinaryFixedPoint,\n    toSignedBinaryFixedPoint,\n    toUnsignedBinaryFixedPoint,\n} from '../binary';\n\n// [DESCRIBE] toUnsignedBinaryFixedPoint.\n{\n    // It returns an unsigned value regardless of the input's signedness.\n    {\n        const fromSigned = {} as BinaryFixedPoint<'signed', 16, 15>;\n        toUnsignedBinaryFixedPoint(fromSigned) satisfies BinaryFixedPoint<'unsigned', 16, 15>;\n        const fromUnsigned = {} as BinaryFixedPoint<'unsigned', 16, 15>;\n        toUnsignedBinaryFixedPoint(fromUnsigned) satisfies BinaryFixedPoint<'unsigned', 16, 15>;\n    }\n\n    // It preserves totalBits and fractionalBits in the return type.\n    {\n        const value = {} as BinaryFixedPoint<'signed', 8, 4>;\n        toUnsignedBinaryFixedPoint(value) satisfies BinaryFixedPoint<'unsigned', 8, 4>;\n    }\n}\n\n// [DESCRIBE] toSignedBinaryFixedPoint.\n{\n    // It returns a signed value regardless of the input's signedness.\n    {\n        const fromSigned = {} as BinaryFixedPoint<'signed', 16, 15>;\n        toSignedBinaryFixedPoint(fromSigned) satisfies BinaryFixedPoint<'signed', 16, 15>;\n        const fromUnsigned = {} as BinaryFixedPoint<'unsigned', 16, 15>;\n        toSignedBinaryFixedPoint(fromUnsigned) satisfies BinaryFixedPoint<'signed', 16, 15>;\n    }\n\n    // It preserves totalBits and fractionalBits in the return type.\n    {\n        const value = {} as BinaryFixedPoint<'unsigned', 8, 4>;\n        toSignedBinaryFixedPoint(value) satisfies BinaryFixedPoint<'signed', 8, 4>;\n    }\n}\n\n// [DESCRIBE] rescaleBinaryFixedPoint.\n{\n    // It preserves the input signedness and picks up the new totalBits and fractionalBits.\n    {\n        const value = {} as BinaryFixedPoint<'signed', 128, 64>;\n        rescaleBinaryFixedPoint(value, 16, 8) satisfies BinaryFixedPoint<'signed', 16, 8>;\n    }\n    {\n        const value = {} as BinaryFixedPoint<'unsigned', 8, 4>;\n        rescaleBinaryFixedPoint(value, 32, 16) satisfies BinaryFixedPoint<'unsigned', 32, 16>;\n    }\n\n    // It accepts an optional RoundingMode as its fourth argument.\n    {\n        const value = {} as BinaryFixedPoint<'signed', 32, 16>;\n        rescaleBinaryFixedPoint(value, 16, 8, 'floor') satisfies BinaryFixedPoint<'signed', 16, 8>;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/binary-core-typetest.ts",
    "content": "import type { BinaryFixedPoint } from '../binary/core';\n\n// [DESCRIBE] BinaryFixedPoint.\n{\n    // It preserves the Signedness, TotalBits, and FractionalBits type parameters.\n    {\n        const value = {} as BinaryFixedPoint<'signed', 16, 15>;\n        value.signedness satisfies 'signed';\n        value.totalBits satisfies 16;\n        value.fractionalBits satisfies 15;\n        value.kind satisfies 'binaryFixedPoint';\n        value.raw satisfies bigint;\n    }\n\n    // A concretely-parameterised value satisfies a generically-parameterised type.\n    {\n        const value = {} as BinaryFixedPoint<'signed', 16, 15>;\n        value satisfies BinaryFixedPoint<'signed', number, number>;\n    }\n\n    // Fields are readonly.\n    {\n        const value = {} as BinaryFixedPoint<'signed', 16, 8>;\n        // @ts-expect-error fractionalBits is readonly.\n        value.fractionalBits = 16;\n        // @ts-expect-error kind is readonly.\n        value.kind = 'decimalFixedPoint';\n        // @ts-expect-error raw is readonly.\n        value.raw = 1n;\n        // @ts-expect-error signedness is readonly.\n        value.signedness = 'unsigned';\n        // @ts-expect-error totalBits is readonly.\n        value.totalBits = 32;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/binary-guards-typetest.ts",
    "content": "import type { BinaryFixedPoint } from '../binary/core';\nimport { assertIsBinaryFixedPoint, isBinaryFixedPoint } from '../binary/guards';\nimport type { Signedness } from '../signedness';\n\n// [DESCRIBE] isBinaryFixedPoint.\n{\n    // It narrows to a fully-generic BinaryFixedPoint when no shape is provided.\n    {\n        const value = {} as unknown;\n        if (isBinaryFixedPoint(value)) {\n            value satisfies BinaryFixedPoint<Signedness, number, number>;\n        }\n    }\n\n    // It narrows progressively as shape arguments are added.\n    {\n        const value = {} as unknown;\n        if (isBinaryFixedPoint(value, 'signed')) {\n            value satisfies BinaryFixedPoint<'signed', number, number>;\n        }\n    }\n    {\n        const value = {} as unknown;\n        if (isBinaryFixedPoint(value, 'signed', 16)) {\n            value satisfies BinaryFixedPoint<'signed', 16, number>;\n        }\n    }\n    {\n        const value = {} as unknown;\n        if (isBinaryFixedPoint(value, 'signed', 16, 15)) {\n            value satisfies BinaryFixedPoint<'signed', 16, 15>;\n        }\n    }\n\n    // It preserves the generic default at a position when `undefined` is passed.\n    {\n        const value = {} as unknown;\n        if (isBinaryFixedPoint(value, undefined, 16)) {\n            value satisfies BinaryFixedPoint<Signedness, 16, number>;\n        }\n    }\n    {\n        const value = {} as unknown;\n        if (isBinaryFixedPoint(value, undefined, undefined, 15)) {\n            value satisfies BinaryFixedPoint<Signedness, number, 15>;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsBinaryFixedPoint.\n{\n    // It narrows to a fully-generic BinaryFixedPoint when no shape is provided.\n    {\n        const value = {} as unknown;\n        assertIsBinaryFixedPoint(value);\n        value satisfies BinaryFixedPoint<Signedness, number, number>;\n    }\n\n    // It narrows progressively as shape arguments are added.\n    {\n        const value = {} as unknown;\n        assertIsBinaryFixedPoint(value, 'signed');\n        value satisfies BinaryFixedPoint<'signed', number, number>;\n    }\n    {\n        const value = {} as unknown;\n        assertIsBinaryFixedPoint(value, 'signed', 16);\n        value satisfies BinaryFixedPoint<'signed', 16, number>;\n    }\n    {\n        const value = {} as unknown;\n        assertIsBinaryFixedPoint(value, 'signed', 16, 15);\n        value satisfies BinaryFixedPoint<'signed', 16, 15>;\n    }\n\n    // It preserves the generic default at a position when `undefined` is passed.\n    {\n        const value = {} as unknown;\n        assertIsBinaryFixedPoint(value, undefined, 16);\n        value satisfies BinaryFixedPoint<Signedness, 16, number>;\n    }\n    {\n        const value = {} as unknown;\n        assertIsBinaryFixedPoint(value, undefined, undefined, 15);\n        value satisfies BinaryFixedPoint<Signedness, number, 15>;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/decimal-arithmetics-typetest.ts",
    "content": "import {\n    absoluteDecimalFixedPoint,\n    addDecimalFixedPoint,\n    type DecimalFixedPoint,\n    divideDecimalFixedPoint,\n    multiplyDecimalFixedPoint,\n    negateDecimalFixedPoint,\n    subtractDecimalFixedPoint,\n} from '../decimal';\n\n// [DESCRIBE] addDecimalFixedPoint.\n{\n    // It preserves the full shape of both operands.\n    {\n        const a = {} as DecimalFixedPoint<'unsigned', 64, 6>;\n        const b = {} as DecimalFixedPoint<'unsigned', 64, 6>;\n        addDecimalFixedPoint(a, b) satisfies DecimalFixedPoint<'unsigned', 64, 6>;\n    }\n\n    // It rejects operands whose shapes differ at the type level.\n    {\n        const a = {} as DecimalFixedPoint<'unsigned', 64, 6>;\n        const b = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        // @ts-expect-error Operands must share the same shape.\n        addDecimalFixedPoint(a, b);\n    }\n}\n\n// [DESCRIBE] subtractDecimalFixedPoint.\n{\n    // It preserves the full shape of both operands.\n    {\n        const a = {} as DecimalFixedPoint<'signed', 32, 4>;\n        const b = {} as DecimalFixedPoint<'signed', 32, 4>;\n        subtractDecimalFixedPoint(a, b) satisfies DecimalFixedPoint<'signed', 32, 4>;\n    }\n\n    // It rejects operands whose shapes differ at the type level.\n    {\n        const a = {} as DecimalFixedPoint<'signed', 32, 4>;\n        const b = {} as DecimalFixedPoint<'signed', 32, 2>;\n        // @ts-expect-error Operands must share the same shape.\n        subtractDecimalFixedPoint(a, b);\n    }\n}\n\n// [DESCRIBE] multiplyDecimalFixedPoint.\n{\n    // It returns the shape of the first operand, regardless of the second.\n    {\n        const a = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        const sameShape = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        multiplyDecimalFixedPoint(a, sameShape) satisfies DecimalFixedPoint<'unsigned', 64, 2>;\n    }\n    {\n        const a = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        const differentShape = {} as DecimalFixedPoint<'unsigned', 128, 4>;\n        multiplyDecimalFixedPoint(a, differentShape) satisfies DecimalFixedPoint<'unsigned', 64, 2>;\n    }\n\n    // It accepts a bigint as the second operand.\n    {\n        const a = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        multiplyDecimalFixedPoint(a, 3n) satisfies DecimalFixedPoint<'unsigned', 64, 2>;\n    }\n\n    // It rejects a plain `number` as the second operand.\n    {\n        const a = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        // @ts-expect-error Second operand must be a DecimalFixedPoint or bigint, not a number.\n        multiplyDecimalFixedPoint(a, 3);\n    }\n\n    // It rejects a second operand whose signedness differs.\n    {\n        const a = {} as DecimalFixedPoint<'signed', 64, 2>;\n        const wrongSignedness = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        // @ts-expect-error Second operand must share the first operand's signedness.\n        multiplyDecimalFixedPoint(a, wrongSignedness);\n    }\n}\n\n// [DESCRIBE] divideDecimalFixedPoint.\n{\n    // It behaves like multiply for the return-type shape and second-operand rules.\n    {\n        const a = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        const different = {} as DecimalFixedPoint<'unsigned', 128, 4>;\n        divideDecimalFixedPoint(a, different) satisfies DecimalFixedPoint<'unsigned', 64, 2>;\n        divideDecimalFixedPoint(a, 3n) satisfies DecimalFixedPoint<'unsigned', 64, 2>;\n    }\n}\n\n// [DESCRIBE] negateDecimalFixedPoint.\n{\n    // It accepts a signed operand.\n    {\n        const a = {} as DecimalFixedPoint<'signed', 32, 4>;\n        negateDecimalFixedPoint(a) satisfies DecimalFixedPoint<'signed', 32, 4>;\n    }\n\n    // It rejects an unsigned operand at the type level.\n    {\n        const a = {} as DecimalFixedPoint<'unsigned', 64, 6>;\n        // @ts-expect-error Only signed values can be negated.\n        negateDecimalFixedPoint(a);\n    }\n}\n\n// [DESCRIBE] absoluteDecimalFixedPoint.\n{\n    // It accepts both signednesses and preserves the shape.\n    {\n        const signed = {} as DecimalFixedPoint<'signed', 32, 4>;\n        absoluteDecimalFixedPoint(signed) satisfies DecimalFixedPoint<'signed', 32, 4>;\n        const unsigned = {} as DecimalFixedPoint<'unsigned', 64, 6>;\n        absoluteDecimalFixedPoint(unsigned) satisfies DecimalFixedPoint<'unsigned', 64, 6>;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/decimal-codec-typetest.ts",
    "content": "import type { FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\n\nimport {\n    type DecimalFixedPoint,\n    getDecimalFixedPointCodec,\n    getDecimalFixedPointDecoder,\n    getDecimalFixedPointEncoder,\n} from '../decimal';\n\n// [DESCRIBE] getDecimalFixedPointEncoder.\n{\n    // It preserves the shape generics in the encoded payload type.\n    {\n        const encoder = getDecimalFixedPointEncoder('unsigned', 64, 6);\n        encoder satisfies FixedSizeEncoder<DecimalFixedPoint<'unsigned', 64, 6>, 8>;\n    }\n\n    // It preserves the byte-size literal for all supported byte-aligned widths.\n    {\n        getDecimalFixedPointEncoder('unsigned', 8, 0) satisfies FixedSizeEncoder<\n            DecimalFixedPoint<'unsigned', 8, 0>,\n            1\n        >;\n        getDecimalFixedPointEncoder('signed', 32, 6) satisfies FixedSizeEncoder<DecimalFixedPoint<'signed', 32, 6>, 4>;\n        getDecimalFixedPointEncoder('unsigned', 128, 18) satisfies FixedSizeEncoder<\n            DecimalFixedPoint<'unsigned', 128, 18>,\n            16\n        >;\n    }\n}\n\n// [DESCRIBE] getDecimalFixedPointDecoder.\n{\n    // It preserves the shape generics in the decoded payload type.\n    {\n        const decoder = getDecimalFixedPointDecoder('unsigned', 64, 6);\n        decoder satisfies FixedSizeDecoder<DecimalFixedPoint<'unsigned', 64, 6>, 8>;\n    }\n}\n\n// [DESCRIBE] getDecimalFixedPointCodec.\n{\n    // It preserves the shape generics in both the encoded and decoded payload types.\n    {\n        const codec = getDecimalFixedPointCodec('unsigned', 128, 18);\n        codec satisfies FixedSizeCodec<\n            DecimalFixedPoint<'unsigned', 128, 18>,\n            DecimalFixedPoint<'unsigned', 128, 18>,\n            16\n        >;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/decimal-conversions-typetest.ts",
    "content": "import {\n    type DecimalFixedPoint,\n    rescaleDecimalFixedPoint,\n    toSignedDecimalFixedPoint,\n    toUnsignedDecimalFixedPoint,\n} from '../decimal';\n\n// [DESCRIBE] toUnsignedDecimalFixedPoint.\n{\n    // It returns an unsigned value regardless of the input's signedness.\n    {\n        const fromSigned = {} as DecimalFixedPoint<'signed', 64, 2>;\n        toUnsignedDecimalFixedPoint(fromSigned) satisfies DecimalFixedPoint<'unsigned', 64, 2>;\n        const fromUnsigned = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        toUnsignedDecimalFixedPoint(fromUnsigned) satisfies DecimalFixedPoint<'unsigned', 64, 2>;\n    }\n\n    // It preserves totalBits and decimals in the return type.\n    {\n        const value = {} as DecimalFixedPoint<'signed', 8, 2>;\n        toUnsignedDecimalFixedPoint(value) satisfies DecimalFixedPoint<'unsigned', 8, 2>;\n    }\n}\n\n// [DESCRIBE] toSignedDecimalFixedPoint.\n{\n    // It returns a signed value regardless of the input's signedness.\n    {\n        const fromSigned = {} as DecimalFixedPoint<'signed', 64, 2>;\n        toSignedDecimalFixedPoint(fromSigned) satisfies DecimalFixedPoint<'signed', 64, 2>;\n        const fromUnsigned = {} as DecimalFixedPoint<'unsigned', 64, 2>;\n        toSignedDecimalFixedPoint(fromUnsigned) satisfies DecimalFixedPoint<'signed', 64, 2>;\n    }\n\n    // It preserves totalBits and decimals in the return type.\n    {\n        const value = {} as DecimalFixedPoint<'unsigned', 8, 2>;\n        toSignedDecimalFixedPoint(value) satisfies DecimalFixedPoint<'signed', 8, 2>;\n    }\n}\n\n// [DESCRIBE] rescaleDecimalFixedPoint.\n{\n    // It preserves the input signedness and picks up the new totalBits and decimals.\n    {\n        const value = {} as DecimalFixedPoint<'unsigned', 128, 18>;\n        rescaleDecimalFixedPoint(value, 64, 6) satisfies DecimalFixedPoint<'unsigned', 64, 6>;\n    }\n    {\n        const value = {} as DecimalFixedPoint<'signed', 16, 2>;\n        rescaleDecimalFixedPoint(value, 64, 9) satisfies DecimalFixedPoint<'signed', 64, 9>;\n    }\n\n    // It accepts an optional RoundingMode as its fourth argument.\n    {\n        const value = {} as DecimalFixedPoint<'unsigned', 128, 18>;\n        rescaleDecimalFixedPoint(value, 64, 6, 'floor') satisfies DecimalFixedPoint<'unsigned', 64, 6>;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/decimal-core-typetest.ts",
    "content": "import type { DecimalFixedPoint } from '../decimal/core';\n\n// [DESCRIBE] DecimalFixedPoint.\n{\n    // It preserves the Signedness, TotalBits, and Decimals type parameters.\n    {\n        const value = {} as DecimalFixedPoint<'unsigned', 64, 6>;\n        value.signedness satisfies 'unsigned';\n        value.totalBits satisfies 64;\n        value.decimals satisfies 6;\n        value.kind satisfies 'decimalFixedPoint';\n        value.raw satisfies bigint;\n    }\n\n    // A concretely-parameterised value satisfies a generically-parameterised type.\n    {\n        const value = {} as DecimalFixedPoint<'unsigned', 64, 6>;\n        value satisfies DecimalFixedPoint<'unsigned', number, number>;\n    }\n\n    // Fields are readonly.\n    {\n        const value = {} as DecimalFixedPoint<'unsigned', 64, 6>;\n        // @ts-expect-error decimals is readonly.\n        value.decimals = 16;\n        // @ts-expect-error kind is readonly.\n        value.kind = 'binaryFixedPoint';\n        // @ts-expect-error raw is readonly.\n        value.raw = 1n;\n        // @ts-expect-error signedness is readonly.\n        value.signedness = 'signed';\n        // @ts-expect-error totalBits is readonly.\n        value.totalBits = 32;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/__typetests__/decimal-guards-typetest.ts",
    "content": "import type { DecimalFixedPoint } from '../decimal/core';\nimport { assertIsDecimalFixedPoint, isDecimalFixedPoint } from '../decimal/guards';\nimport type { Signedness } from '../signedness';\n\n// [DESCRIBE] isDecimalFixedPoint.\n{\n    // It narrows to a fully-generic DecimalFixedPoint when no shape is provided.\n    {\n        const value = {} as unknown;\n        if (isDecimalFixedPoint(value)) {\n            value satisfies DecimalFixedPoint<Signedness, number, number>;\n        }\n    }\n\n    // It narrows progressively as shape arguments are added.\n    {\n        const value = {} as unknown;\n        if (isDecimalFixedPoint(value, 'unsigned')) {\n            value satisfies DecimalFixedPoint<'unsigned', number, number>;\n        }\n    }\n    {\n        const value = {} as unknown;\n        if (isDecimalFixedPoint(value, 'unsigned', 64)) {\n            value satisfies DecimalFixedPoint<'unsigned', 64, number>;\n        }\n    }\n    {\n        const value = {} as unknown;\n        if (isDecimalFixedPoint(value, 'unsigned', 64, 6)) {\n            value satisfies DecimalFixedPoint<'unsigned', 64, 6>;\n        }\n    }\n\n    // It preserves the generic default at a position when `undefined` is passed.\n    {\n        const value = {} as unknown;\n        if (isDecimalFixedPoint(value, undefined, 64)) {\n            value satisfies DecimalFixedPoint<Signedness, 64, number>;\n        }\n    }\n    {\n        const value = {} as unknown;\n        if (isDecimalFixedPoint(value, undefined, undefined, 6)) {\n            value satisfies DecimalFixedPoint<Signedness, number, 6>;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsDecimalFixedPoint.\n{\n    // It narrows to a fully-generic DecimalFixedPoint when no shape is provided.\n    {\n        const value = {} as unknown;\n        assertIsDecimalFixedPoint(value);\n        value satisfies DecimalFixedPoint<Signedness, number, number>;\n    }\n\n    // It narrows progressively as shape arguments are added.\n    {\n        const value = {} as unknown;\n        assertIsDecimalFixedPoint(value, 'unsigned');\n        value satisfies DecimalFixedPoint<'unsigned', number, number>;\n    }\n    {\n        const value = {} as unknown;\n        assertIsDecimalFixedPoint(value, 'unsigned', 64);\n        value satisfies DecimalFixedPoint<'unsigned', 64, number>;\n    }\n    {\n        const value = {} as unknown;\n        assertIsDecimalFixedPoint(value, 'unsigned', 64, 6);\n        value satisfies DecimalFixedPoint<'unsigned', 64, 6>;\n    }\n\n    // It preserves the generic default at a position when `undefined` is passed.\n    {\n        const value = {} as unknown;\n        assertIsDecimalFixedPoint(value, undefined, 64);\n        value satisfies DecimalFixedPoint<Signedness, 64, number>;\n    }\n    {\n        const value = {} as unknown;\n        assertIsDecimalFixedPoint(value, undefined, undefined, 6);\n        value satisfies DecimalFixedPoint<Signedness, number, 6>;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/assertions.ts",
    "content": "import {\n    SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW,\n    SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO,\n    SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS,\n    SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE,\n    SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH,\n    SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport type { Signedness } from './signedness';\n\ntype FixedPointKind = 'binaryFixedPoint' | 'decimalFixedPoint';\n\n/**\n * Returns the inclusive raw bigint range for a fixed-point number with the\n * given signedness and total bits.\n *\n * Signed ranges use two's-complement semantics, so an 8-bit signed value\n * spans `[-128n, 127n]` and an 8-bit unsigned value spans `[0n, 255n]`.\n *\n * This helper trusts that `totalBits` has already been validated as a\n * positive integer by the caller.\n *\n * @internal\n */\nexport function getRawRange(signedness: Signedness, totalBits: number): { max: bigint; min: bigint } {\n    if (signedness === 'signed') {\n        const half = 1n << BigInt(totalBits - 1);\n        return { max: half - 1n, min: -half };\n    }\n    return { max: (1n << BigInt(totalBits)) - 1n, min: 0n };\n}\n\n/**\n * Asserts that `totalBits` is a positive integer. Throws\n * `SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS` otherwise.\n *\n * @internal\n */\nexport function assertValidTotalBits(kind: FixedPointKind, totalBits: unknown): asserts totalBits is number {\n    if (typeof totalBits !== 'number' || !Number.isInteger(totalBits) || totalBits <= 0) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_TOTAL_BITS, {\n            kind,\n            totalBits,\n        });\n    }\n}\n\n/**\n * Asserts that `fractionalBits` is a non-negative integer. Throws\n * `SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS` otherwise.\n *\n * @internal\n */\nexport function assertValidFractionalBits(fractionalBits: unknown): asserts fractionalBits is number {\n    if (typeof fractionalBits !== 'number' || !Number.isInteger(fractionalBits) || fractionalBits < 0) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_FRACTIONAL_BITS, {\n            fractionalBits,\n        });\n    }\n}\n\n/**\n * Asserts that `decimals` is a non-negative integer. Throws\n * `SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS` otherwise.\n *\n * @internal\n */\nexport function assertValidDecimals(decimals: unknown): asserts decimals is number {\n    if (typeof decimals !== 'number' || !Number.isInteger(decimals) || decimals < 0) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_DECIMALS, {\n            decimals,\n        });\n    }\n}\n\n/**\n * Asserts that `fractionalBits` does not exceed `totalBits` for a binary\n * fixed-point shape. Throws\n * `SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS` otherwise.\n *\n * @internal\n */\nexport function assertFractionalBitsFitInTotalBits(fractionalBits: number, totalBits: number): void {\n    if (fractionalBits > totalBits) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__FRACTIONAL_BITS_EXCEED_TOTAL_BITS, {\n            fractionalBits,\n            totalBits,\n        });\n    }\n}\n\n/**\n * Asserts that `totalBits` is a multiple of 8. Throws\n * `SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED` otherwise.\n *\n * This is a codec-only constraint: fixed-point values themselves accept\n * any positive `totalBits`, but the byte-oriented codec can only serialize\n * sizes that are exact multiples of 8 bits.\n *\n * @internal\n */\nexport function assertTotalBitsIsByteAligned(kind: FixedPointKind, totalBits: number): void {\n    if (totalBits % 8 !== 0) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED, {\n            kind,\n            totalBits,\n        });\n    }\n}\n\n/**\n * Asserts that a raw bigint fits the range claimed by the given signedness\n * and total bits. Throws `SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE`\n * otherwise.\n *\n * @internal\n */\nexport function assertRawFitsInRange(\n    kind: FixedPointKind,\n    signedness: Signedness,\n    totalBits: number,\n    raw: bigint,\n): void {\n    const { max, min } = getRawRange(signedness, totalBits);\n    if (raw < min || raw > max) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n            kind,\n            max,\n            min,\n            raw,\n            signedness,\n            totalBits,\n        });\n    }\n}\n\n/**\n * Describes the concrete shape of a fixed-point value for `SHAPE_MISMATCH`\n * error context. The `scale` is `fractionalBits` for binary values and\n * `decimals` for decimal values; `scaleLabel` is the matching\n * human-readable label.\n *\n * @internal\n */\nexport type FixedPointShape = {\n    kind: string;\n    scale: number;\n    scaleLabel: string;\n    signedness: string;\n    totalBits: number;\n};\n\n/**\n * Expected shape for {@link assertShapeMatches}. Each field except `kind`\n * and `scaleLabel` is optional: `undefined` means \"don't constrain this\n * field\". `kind` is always required because mismatched kinds are always\n * mismatches; `scaleLabel` is always required because it appears in the\n * expected side of the error message even when `scale` is not pinned.\n *\n * @internal\n */\nexport type ExpectedFixedPointShape = {\n    kind: string;\n    scale?: number;\n    scaleLabel: string;\n    signedness?: string;\n    totalBits?: number;\n};\n\n/**\n * Best-effort {@link FixedPointShape} description for an unknown value.\n * Used to populate the `actual*` half of `SHAPE_MISMATCH` contexts when\n * the input may not be a valid fixed-point value at all.\n *\n * @internal\n */\nexport function describeShape(value: unknown): FixedPointShape {\n    const record = value && typeof value === 'object' ? (value as Record<string, unknown>) : {};\n    const kind = typeof record.kind === 'string' ? record.kind : 'unknown';\n    const signedness = typeof record.signedness === 'string' ? record.signedness : 'unknown';\n    const totalBits = typeof record.totalBits === 'number' ? record.totalBits : 0;\n    let scale: number;\n    let scaleLabel: string;\n    if (kind === 'decimalFixedPoint') {\n        scale = typeof record.decimals === 'number' ? record.decimals : 0;\n        scaleLabel = 'decimals';\n    } else if (kind === 'binaryFixedPoint') {\n        scale = typeof record.fractionalBits === 'number' ? record.fractionalBits : 0;\n        scaleLabel = 'fractional bits';\n    } else {\n        scale = 0;\n        scaleLabel = 'unknown';\n    }\n    return { kind, scale, scaleLabel, signedness, totalBits };\n}\n\n/**\n * Asserts that `actual` matches the `expected` shape. Throws\n * `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` otherwise.\n *\n * Fields left `undefined` on `expected` are not constrained — the actual\n * value may carry any value for that field. This is how partial shape\n * checks (e.g. \"any signed value\" without pinning `totalBits`) are\n * expressed.\n *\n * @internal\n */\nexport function assertShapeMatches(\n    operation: string,\n    actual: FixedPointShape,\n    expected: ExpectedFixedPointShape,\n): void {\n    const actualIsStructurallyValid =\n        (actual.signedness === 'signed' || actual.signedness === 'unsigned') &&\n        Number.isInteger(actual.totalBits) &&\n        actual.totalBits > 0 &&\n        Number.isInteger(actual.scale) &&\n        actual.scale >= 0;\n    if (\n        !actualIsStructurallyValid ||\n        actual.kind !== expected.kind ||\n        (expected.signedness !== undefined && actual.signedness !== expected.signedness) ||\n        (expected.totalBits !== undefined && actual.totalBits !== expected.totalBits) ||\n        (expected.scale !== undefined && actual.scale !== expected.scale)\n    ) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH, {\n            actualKind: actual.kind,\n            actualScale: actual.scale,\n            actualScaleLabel: actual.scaleLabel,\n            actualSignedness: actual.signedness,\n            actualTotalBits: actual.totalBits,\n            expectedKind: expected.kind,\n            expectedScale: expected.scale ?? actual.scale,\n            expectedScaleLabel: expected.scaleLabel,\n            expectedSignedness: expected.signedness ?? actual.signedness,\n            expectedTotalBits: expected.totalBits ?? actual.totalBits,\n            operation,\n        });\n    }\n}\n\n/**\n * Asserts that `value.raw` is a bigint, so that downstream range checks\n * can compare it against the claimed signedness and total bits. Throws\n * `SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE` otherwise.\n *\n * @internal\n */\nexport function assertRawIsBigint(kind: FixedPointKind, value: unknown): asserts value is { raw: bigint } {\n    const raw = value && typeof value === 'object' ? (value as { raw?: unknown }).raw : undefined;\n    if (typeof raw !== 'bigint') {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__MALFORMED_RAW_VALUE, {\n            kind,\n            raw,\n        });\n    }\n}\n\n/**\n * Asserts that a bigint `result` produced by an arithmetic operation fits\n * the range claimed by the given signedness and total bits. Throws\n * `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW` otherwise, carrying\n * the operation name so the error message can identify which op overflowed.\n *\n * @internal\n */\nexport function assertNoArithmeticOverflow(\n    kind: FixedPointKind,\n    operation: string,\n    signedness: Signedness,\n    totalBits: number,\n    result: bigint,\n): void {\n    const { max, min } = getRawRange(signedness, totalBits);\n    if (result < min || result > max) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW, {\n            kind,\n            max,\n            min,\n            operation,\n            result,\n            signedness,\n            totalBits,\n        });\n    }\n}\n\n/**\n * Asserts that a divisor is non-zero. Throws\n * `SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO` otherwise.\n *\n * @internal\n */\nexport function assertNoDivisionByZero(\n    kind: FixedPointKind,\n    signedness: Signedness,\n    totalBits: number,\n    denominator: bigint,\n): void {\n    if (denominator === 0n) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO, {\n            kind,\n            signedness,\n            totalBits,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/binary/arithmetics.ts",
    "content": "import { assertNoArithmeticOverflow, assertNoDivisionByZero, assertShapeMatches, describeShape } from '../assertions';\nimport { roundDivision, type RoundingMode } from '../rounding';\nimport type { Signedness } from '../signedness';\nimport type { BinaryFixedPoint } from './core';\n\n/**\n * Adds two {@link BinaryFixedPoint} values of the same shape and returns\n * the result at the same shape.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` if the two operands\n * differ in signedness, total bits, or fractional bits, and\n * `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW` if the sum does not\n * fit the target shape.\n *\n * @example\n * ```ts\n * const usd = binaryFixedPoint('signed', 32, 16);\n * addBinaryFixedPoint(usd('1.5'), usd('2.25')); // represents 3.75\n * ```\n *\n * @see {@link subtractBinaryFixedPoint}\n */\nexport function addBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    a: BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>,\n    b: NoInfer<BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>>,\n): BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    assertShapeMatches('addBinaryFixedPoint', describeShape(b), {\n        kind: a.kind,\n        scale: a.fractionalBits,\n        scaleLabel: 'fractional bits',\n        signedness: a.signedness,\n        totalBits: a.totalBits,\n    });\n    const result = a.raw + b.raw;\n    assertNoArithmeticOverflow(a.kind, 'add', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Subtracts `b` from `a` where both are {@link BinaryFixedPoint} values of\n * the same shape, and returns the result at the same shape.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` if the two operands\n * differ in shape, and `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW`\n * if the difference does not fit the target shape.\n *\n * @see {@link addBinaryFixedPoint}\n */\nexport function subtractBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    a: BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>,\n    b: NoInfer<BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>>,\n): BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    assertShapeMatches('subtractBinaryFixedPoint', describeShape(b), {\n        kind: a.kind,\n        scale: a.fractionalBits,\n        scaleLabel: 'fractional bits',\n        signedness: a.signedness,\n        totalBits: a.totalBits,\n    });\n    const result = a.raw - b.raw;\n    assertNoArithmeticOverflow(a.kind, 'subtract', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Multiplies a {@link BinaryFixedPoint} by a scalar.\n *\n * The second operand may be another {@link BinaryFixedPoint} with the same\n * signedness (any total bits or fractional bits) or a bare `bigint`. The\n * result always has `a`'s shape.\n *\n * Multiplication by a same-kind fixed-point rescales the product back to\n * `a`'s scale. When that rescaling is not exact, the optional\n * {@link RoundingMode} is consulted; it defaults to `'strict'` and throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` in that case.\n *\n * @example\n * ```ts\n * const audioSample = binaryFixedPoint('signed', 16, 15);\n * multiplyBinaryFixedPoint(audioSample('0.6'), audioSample('0.8')); // represents 0.48\n * multiplyBinaryFixedPoint(audioSample('0.5'), 2n);                 // represents 1.0 (overflows Q1.15)\n * ```\n *\n * @see {@link divideBinaryFixedPoint}\n */\nexport function multiplyBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    a: BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>,\n    b: BinaryFixedPoint<NoInfer<TSignedness>, number, number> | bigint,\n    rounding: RoundingMode = 'strict',\n): BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    let result: bigint;\n    if (typeof b === 'bigint') {\n        result = a.raw * b;\n    } else {\n        assertShapeMatches('multiplyBinaryFixedPoint', describeShape(b), {\n            kind: a.kind,\n            scaleLabel: 'fractional bits',\n            signedness: a.signedness,\n        });\n        result = roundDivision(a.kind, 'multiply', a.raw * b.raw, 1n << BigInt(b.fractionalBits), rounding);\n    }\n    assertNoArithmeticOverflow(a.kind, 'multiply', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Divides a {@link BinaryFixedPoint} by a scalar.\n *\n * The second operand may be another {@link BinaryFixedPoint} with the same\n * signedness (any total bits or fractional bits) or a bare `bigint`. The\n * result always has `a`'s shape.\n *\n * The optional {@link RoundingMode} is consulted whenever the division is\n * inexact; it defaults to `'strict'` and throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` in that case.\n * A zero divisor always throws\n * `SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO`.\n *\n * @example\n * ```ts\n * const q1_15 = binaryFixedPoint('signed', 16, 15);\n * divideBinaryFixedPoint(q1_15('0.5'), q1_15('0.25')); // represents 2.0 (overflows)\n * divideBinaryFixedPoint(q1_15('0.5'), 2n);            // represents 0.25\n * ```\n *\n * @see {@link multiplyBinaryFixedPoint}\n */\nexport function divideBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    a: BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>,\n    b: BinaryFixedPoint<NoInfer<TSignedness>, number, number> | bigint,\n    rounding: RoundingMode = 'strict',\n): BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    let result: bigint;\n    if (typeof b === 'bigint') {\n        assertNoDivisionByZero(a.kind, a.signedness, a.totalBits, b);\n        result = roundDivision(a.kind, 'divide', a.raw, b, rounding);\n    } else {\n        assertShapeMatches('divideBinaryFixedPoint', describeShape(b), {\n            kind: a.kind,\n            scaleLabel: 'fractional bits',\n            signedness: a.signedness,\n        });\n        assertNoDivisionByZero(a.kind, a.signedness, a.totalBits, b.raw);\n        result = roundDivision(a.kind, 'divide', a.raw * (1n << BigInt(b.fractionalBits)), b.raw, rounding);\n    }\n    assertNoArithmeticOverflow(a.kind, 'divide', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Returns the additive inverse of a signed {@link BinaryFixedPoint}.\n *\n * Unsigned values are rejected at the type level; they are also rejected\n * at runtime with `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` in case the\n * type safety is bypassed. Negating the minimum representable value\n * overflows and throws `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW`.\n *\n * @see {@link absoluteBinaryFixedPoint}\n */\nexport function negateBinaryFixedPoint<TTotalBits extends number, TFractionalBits extends number>(\n    a: BinaryFixedPoint<'signed', TTotalBits, TFractionalBits>,\n): BinaryFixedPoint<'signed', TTotalBits, TFractionalBits> {\n    assertShapeMatches('negateBinaryFixedPoint', describeShape(a), {\n        kind: a.kind,\n        scaleLabel: 'fractional bits',\n        signedness: 'signed',\n    });\n    const result = -a.raw;\n    assertNoArithmeticOverflow(a.kind, 'negate', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Returns the absolute value of a {@link BinaryFixedPoint}. Unsigned\n * inputs are returned unchanged.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW` when taking the\n * absolute value of the minimum representable signed value, which has no\n * positive counterpart in two's-complement.\n *\n * @see {@link negateBinaryFixedPoint}\n */\nexport function absoluteBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    a: BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>,\n): BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    const result = a.raw < 0n ? -a.raw : a.raw;\n    assertNoArithmeticOverflow(a.kind, 'absolute', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n"
  },
  {
    "path": "packages/fixed-points/src/binary/codecs.ts",
    "content": "import {\n    assertByteArrayHasEnoughBytesForCodec,\n    assertByteArrayIsNotEmptyForCodec,\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    type FixedSizeCodec,\n    type FixedSizeDecoder,\n    type FixedSizeEncoder,\n} from '@solana/codecs-core';\n\nimport {\n    assertFractionalBitsFitInTotalBits,\n    assertShapeMatches,\n    assertTotalBitsIsByteAligned,\n    assertValidFractionalBits,\n    assertValidTotalBits,\n    describeShape,\n} from '../assertions';\nimport { type BytesForTotalBits, type FixedPointCodecConfig, readRawBigInt, writeRawBigInt } from '../codecs';\nimport type { Signedness } from '../signedness';\nimport type { BinaryFixedPoint } from './core';\n\n/**\n * Returns an encoder for {@link BinaryFixedPoint} values of a specific\n * shape. The encoder serializes `value.raw` as a fixed-size integer using\n * two's-complement for signed values and little-endian byte order by\n * default.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED` when\n * `totalBits` is not a multiple of 8. Encoding a value whose shape does\n * not match the codec's shape throws\n * `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH`.\n *\n * @example\n * ```ts\n * const encoder = getBinaryFixedPointEncoder('signed', 16, 15);\n * encoder.encode(binaryFixedPoint('signed', 16, 15)('0.5')); // 0x0040\n * ```\n *\n * @see {@link getBinaryFixedPointDecoder}\n * @see {@link getBinaryFixedPointCodec}\n */\nexport function getBinaryFixedPointEncoder<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    fractionalBits: TFractionalBits,\n    config: FixedPointCodecConfig = {},\n): FixedSizeEncoder<BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>, BytesForTotalBits<TTotalBits>> {\n    assertValidTotalBits('binaryFixedPoint', totalBits);\n    assertValidFractionalBits(fractionalBits);\n    assertFractionalBitsFitInTotalBits(fractionalBits, totalBits);\n    assertTotalBitsIsByteAligned('binaryFixedPoint', totalBits);\n    const byteSize = (totalBits / 8) as BytesForTotalBits<TTotalBits>;\n    const littleEndian = config.endian !== 'be';\n    return createEncoder({\n        fixedSize: byteSize,\n        write(value, bytes, offset) {\n            assertShapeMatches('getBinaryFixedPointEncoder', describeShape(value), {\n                kind: 'binaryFixedPoint',\n                scale: fractionalBits,\n                scaleLabel: 'fractional bits',\n                signedness,\n                totalBits,\n            });\n            writeRawBigInt(bytes, offset, value.raw, byteSize, signedness, littleEndian);\n            return offset + byteSize;\n        },\n    });\n}\n\n/**\n * Returns a decoder for {@link BinaryFixedPoint} values of a specific\n * shape. The decoder reads a fixed-size integer using two's-complement for\n * signed values and little-endian byte order by default, and reconstructs\n * a frozen {@link BinaryFixedPoint} from the bytes.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED` when\n * `totalBits` is not a multiple of 8.\n *\n * @example\n * ```ts\n * const decoder = getBinaryFixedPointDecoder('signed', 16, 15);\n * decoder.decode(new Uint8Array([0x00, 0x40])); // represents 0.5\n * ```\n *\n * @see {@link getBinaryFixedPointEncoder}\n * @see {@link getBinaryFixedPointCodec}\n */\nexport function getBinaryFixedPointDecoder<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    fractionalBits: TFractionalBits,\n    config: FixedPointCodecConfig = {},\n): FixedSizeDecoder<BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>, BytesForTotalBits<TTotalBits>> {\n    assertValidTotalBits('binaryFixedPoint', totalBits);\n    assertValidFractionalBits(fractionalBits);\n    assertFractionalBitsFitInTotalBits(fractionalBits, totalBits);\n    assertTotalBitsIsByteAligned('binaryFixedPoint', totalBits);\n    const byteSize = (totalBits / 8) as BytesForTotalBits<TTotalBits>;\n    const littleEndian = config.endian !== 'be';\n    const codecDescription = 'getBinaryFixedPointDecoder';\n    return createDecoder({\n        fixedSize: byteSize,\n        read(bytes, offset) {\n            assertByteArrayIsNotEmptyForCodec(codecDescription, bytes, offset);\n            assertByteArrayHasEnoughBytesForCodec(codecDescription, byteSize, bytes, offset);\n            const raw = readRawBigInt(bytes, offset, byteSize, signedness, littleEndian);\n            const value = Object.freeze({\n                fractionalBits,\n                kind: 'binaryFixedPoint',\n                raw,\n                signedness,\n                totalBits,\n            }) as BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>;\n            return [value, offset + byteSize];\n        },\n    });\n}\n\n/**\n * Returns a codec for {@link BinaryFixedPoint} values of a specific shape,\n * combining {@link getBinaryFixedPointEncoder} and\n * {@link getBinaryFixedPointDecoder}.\n *\n * @example\n * ```ts\n * const codec = getBinaryFixedPointCodec('signed', 16, 15);\n * const bytes = codec.encode(binaryFixedPoint('signed', 16, 15)('0.5'));\n * const value = codec.decode(bytes); // represents 0.5\n * ```\n *\n * @see {@link getBinaryFixedPointEncoder}\n * @see {@link getBinaryFixedPointDecoder}\n */\nexport function getBinaryFixedPointCodec<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    fractionalBits: TFractionalBits,\n    config: FixedPointCodecConfig = {},\n): FixedSizeCodec<\n    BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>,\n    BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits>,\n    BytesForTotalBits<TTotalBits>\n> {\n    return combineCodec(\n        getBinaryFixedPointEncoder(signedness, totalBits, fractionalBits, config),\n        getBinaryFixedPointDecoder(signedness, totalBits, fractionalBits, config),\n    );\n}\n"
  },
  {
    "path": "packages/fixed-points/src/binary/comparisons.ts",
    "content": "import { assertShapeMatches, describeShape } from '../assertions';\nimport type { Signedness } from '../signedness';\nimport type { BinaryFixedPoint } from './core';\n\n/**\n * Compares two {@link BinaryFixedPoint} values and returns `-1`, `0`, or\n * `1` depending on whether `a` is less than, equal to, or greater than `b`.\n *\n * Only the `kind` and `fractionalBits` of the two operands must match;\n * `signedness` and `totalBits` are allowed to differ because they are\n * storage concerns only and do not affect the mathematical value being\n * compared. Mismatches on the constrained dimensions throw\n * `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH`.\n *\n * @example\n * ```ts\n * const q1_15 = binaryFixedPoint('signed', 16, 15);\n * cmpBinaryFixedPoint(q1_15('0.25'), q1_15('0.5')); // -1\n * cmpBinaryFixedPoint(q1_15('0.5'), q1_15('0.5'));  // 0\n * cmpBinaryFixedPoint(q1_15('0.75'), q1_15('0.5')); // 1\n * ```\n *\n * @see {@link eqBinaryFixedPoint}\n * @see {@link ltBinaryFixedPoint}\n * @see {@link lteBinaryFixedPoint}\n * @see {@link gtBinaryFixedPoint}\n * @see {@link gteBinaryFixedPoint}\n */\nexport function cmpBinaryFixedPoint<TFractionalBits extends number>(\n    a: BinaryFixedPoint<Signedness, number, TFractionalBits>,\n    b: BinaryFixedPoint<Signedness, number, NoInfer<TFractionalBits>>,\n): -1 | 0 | 1 {\n    assertShapeMatches('cmpBinaryFixedPoint', describeShape(b), {\n        kind: a.kind,\n        scale: a.fractionalBits,\n        scaleLabel: 'fractional bits',\n    });\n    return a.raw < b.raw ? -1 : a.raw > b.raw ? 1 : 0;\n}\n\n/**\n * Returns `true` when `a` and `b` represent the same value.\n *\n * See {@link cmpBinaryFixedPoint} for shape-matching rules.\n */\nexport function eqBinaryFixedPoint<TFractionalBits extends number>(\n    a: BinaryFixedPoint<Signedness, number, TFractionalBits>,\n    b: BinaryFixedPoint<Signedness, number, NoInfer<TFractionalBits>>,\n): boolean {\n    return cmpBinaryFixedPoint(a, b) === 0;\n}\n\n/**\n * Returns `true` when `a` is strictly less than `b`.\n *\n * See {@link cmpBinaryFixedPoint} for shape-matching rules.\n */\nexport function ltBinaryFixedPoint<TFractionalBits extends number>(\n    a: BinaryFixedPoint<Signedness, number, TFractionalBits>,\n    b: BinaryFixedPoint<Signedness, number, NoInfer<TFractionalBits>>,\n): boolean {\n    return cmpBinaryFixedPoint(a, b) < 0;\n}\n\n/**\n * Returns `true` when `a` is less than or equal to `b`.\n *\n * See {@link cmpBinaryFixedPoint} for shape-matching rules.\n */\nexport function lteBinaryFixedPoint<TFractionalBits extends number>(\n    a: BinaryFixedPoint<Signedness, number, TFractionalBits>,\n    b: BinaryFixedPoint<Signedness, number, NoInfer<TFractionalBits>>,\n): boolean {\n    return cmpBinaryFixedPoint(a, b) <= 0;\n}\n\n/**\n * Returns `true` when `a` is strictly greater than `b`.\n *\n * See {@link cmpBinaryFixedPoint} for shape-matching rules.\n */\nexport function gtBinaryFixedPoint<TFractionalBits extends number>(\n    a: BinaryFixedPoint<Signedness, number, TFractionalBits>,\n    b: BinaryFixedPoint<Signedness, number, NoInfer<TFractionalBits>>,\n): boolean {\n    return cmpBinaryFixedPoint(a, b) > 0;\n}\n\n/**\n * Returns `true` when `a` is greater than or equal to `b`.\n *\n * See {@link cmpBinaryFixedPoint} for shape-matching rules.\n */\nexport function gteBinaryFixedPoint<TFractionalBits extends number>(\n    a: BinaryFixedPoint<Signedness, number, TFractionalBits>,\n    b: BinaryFixedPoint<Signedness, number, NoInfer<TFractionalBits>>,\n): boolean {\n    return cmpBinaryFixedPoint(a, b) >= 0;\n}\n"
  },
  {
    "path": "packages/fixed-points/src/binary/conversions.ts",
    "content": "import {\n    assertFractionalBitsFitInTotalBits,\n    assertNoArithmeticOverflow,\n    assertRawFitsInRange,\n    assertValidFractionalBits,\n    assertValidTotalBits,\n} from '../assertions';\nimport { roundDivision, type RoundingMode } from '../rounding';\nimport type { Signedness } from '../signedness';\nimport type { BinaryFixedPoint } from './core';\n\n/**\n * Converts a {@link BinaryFixedPoint} to its exact base-10 representation\n * as a `(raw, decimals)` pair such that the mathematical value equals\n * `raw / 10 ** decimals`.\n *\n * Because `1 / 2 ** F` has a finite decimal expansion of exactly `F`\n * digits, the conversion is always lossless:\n * `raw / 2 ** F === (raw * 5 ** F) / 10 ** F`. The transformed raw\n * therefore carries exactly `fractionalBits` decimal digits of\n * precision.\n *\n * Useful when you want to feed a binary fixed-point into a tool that\n * understands base-10 scaled integers (such as `Intl.NumberFormat`'s\n * string scientific notation).\n *\n * @example\n * ```ts\n * const q1_15 = binaryFixedPoint('signed', 16, 15);\n * binaryFixedPointToBase10(q1_15('0.5'));\n * // { raw: 500000000000000n, decimals: 15 }\n * ```\n *\n * @see {@link BinaryFixedPoint}\n */\nexport function binaryFixedPointToBase10(value: BinaryFixedPoint<Signedness, number, number>): {\n    decimals: number;\n    raw: bigint;\n} {\n    const decimals = value.fractionalBits;\n    const raw = decimals === 0 ? value.raw : value.raw * 5n ** BigInt(decimals);\n    return { decimals, raw };\n}\n\n/**\n * Converts a {@link BinaryFixedPoint} to its unsigned equivalent at the\n * same `totalBits` and `fractionalBits`.\n *\n * Unsigned inputs are returned by reference unchanged; signed inputs are\n * accepted as long as their raw value is non-negative.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE` when the input\n * represents a negative value that cannot be stored as unsigned.\n *\n * @example\n * ```ts\n * const signedUsd = binaryFixedPoint('signed', 16, 8);\n * toUnsignedBinaryFixedPoint(signedUsd('1.5')); // unsigned, raw unchanged\n * toUnsignedBinaryFixedPoint(signedUsd('-1'));  // throws\n * ```\n *\n * @see {@link toSignedBinaryFixedPoint}\n */\nexport function toUnsignedBinaryFixedPoint<TTotalBits extends number, TFractionalBits extends number>(\n    value: BinaryFixedPoint<Signedness, TTotalBits, TFractionalBits>,\n): BinaryFixedPoint<'unsigned', TTotalBits, TFractionalBits> {\n    if (value.signedness === 'unsigned') {\n        return value as BinaryFixedPoint<'unsigned', TTotalBits, TFractionalBits>;\n    }\n    assertRawFitsInRange('binaryFixedPoint', 'unsigned', value.totalBits, value.raw);\n    return Object.freeze({ ...value, signedness: 'unsigned' });\n}\n\n/**\n * Converts a {@link BinaryFixedPoint} to its signed equivalent at the same\n * `totalBits` and `fractionalBits`.\n *\n * Signed inputs are returned by reference unchanged; unsigned inputs are\n * accepted as long as their raw value fits the signed range, i.e.\n * `raw <= 2 ** (totalBits - 1) - 1`.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE` when the input's\n * raw value exceeds the maximum representable signed value at its\n * `totalBits`.\n *\n * @example\n * ```ts\n * const unsigned = rawBinaryFixedPoint('unsigned', 8, 0);\n * toSignedBinaryFixedPoint(unsigned(100n)); // signed, raw === 100n\n * toSignedBinaryFixedPoint(unsigned(200n)); // throws (200 > 127)\n * ```\n *\n * @see {@link toUnsignedBinaryFixedPoint}\n */\nexport function toSignedBinaryFixedPoint<TTotalBits extends number, TFractionalBits extends number>(\n    value: BinaryFixedPoint<Signedness, TTotalBits, TFractionalBits>,\n): BinaryFixedPoint<'signed', TTotalBits, TFractionalBits> {\n    if (value.signedness === 'signed') {\n        return value as BinaryFixedPoint<'signed', TTotalBits, TFractionalBits>;\n    }\n    assertRawFitsInRange('binaryFixedPoint', 'signed', value.totalBits, value.raw);\n    return Object.freeze({ ...value, signedness: 'signed' });\n}\n\n/**\n * Returns a {@link BinaryFixedPoint} with the same signedness as `value`\n * but a new `totalBits` and `fractionalBits`. If the requested shape\n * matches the input shape, the same reference is returned.\n *\n * Scale-up (higher `fractionalBits`) is always exact. Scale-down (lower\n * `fractionalBits`) is potentially lossy; the optional {@link RoundingMode}\n * is consulted on inexact results and defaults to `'strict'`, which throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS`.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW` when the\n * rescaled raw value does not fit the new `totalBits`.\n *\n * @example\n * ```ts\n * const q1_15 = binaryFixedPoint('signed', 16, 15);\n * rescaleBinaryFixedPoint(q1_15('0.5'), 32, 30);          // wider, higher precision\n * rescaleBinaryFixedPoint(q1_15('0.5'), 16, 8, 'floor');  // lower precision, explicit rounding\n * ```\n *\n * @see {@link toSignedBinaryFixedPoint}\n * @see {@link toUnsignedBinaryFixedPoint}\n */\nexport function rescaleBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TNewTotalBits extends number,\n    TNewFractionalBits extends number,\n>(\n    value: BinaryFixedPoint<TSignedness, number, number>,\n    newTotalBits: TNewTotalBits,\n    newFractionalBits: TNewFractionalBits,\n    rounding: RoundingMode = 'strict',\n): BinaryFixedPoint<TSignedness, TNewTotalBits, TNewFractionalBits> {\n    assertValidTotalBits('binaryFixedPoint', newTotalBits);\n    assertValidFractionalBits(newFractionalBits);\n    assertFractionalBitsFitInTotalBits(newFractionalBits, newTotalBits);\n    if (value.totalBits === newTotalBits && value.fractionalBits === newFractionalBits) {\n        return value as BinaryFixedPoint<TSignedness, TNewTotalBits, TNewFractionalBits>;\n    }\n    let result: bigint;\n    if (newFractionalBits === value.fractionalBits) {\n        result = value.raw;\n    } else if (newFractionalBits > value.fractionalBits) {\n        result = value.raw << BigInt(newFractionalBits - value.fractionalBits);\n    } else {\n        result = roundDivision(\n            'binaryFixedPoint',\n            'rescale',\n            value.raw,\n            1n << BigInt(value.fractionalBits - newFractionalBits),\n            rounding,\n        );\n    }\n    assertNoArithmeticOverflow('binaryFixedPoint', 'rescale', value.signedness, newTotalBits, result);\n    return Object.freeze({ ...value, fractionalBits: newFractionalBits, raw: result, totalBits: newTotalBits });\n}\n"
  },
  {
    "path": "packages/fixed-points/src/binary/core.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO, SolanaError } from '@solana/errors';\n\nimport {\n    assertFractionalBitsFitInTotalBits,\n    assertRawFitsInRange,\n    assertValidFractionalBits,\n    assertValidTotalBits,\n} from '../assertions';\nimport { parseDecimalString } from '../parsing';\nimport { roundDivision, type RoundingMode } from '../rounding';\nimport type { Signedness } from '../signedness';\n\n/**\n * A fixed-point number whose scale is a power of 2. The stored `raw` bigint\n * represents the mathematical value `raw / 2 ** fractionalBits`.\n *\n * Binary fixed-point is the fastest fractional representation to compute\n * with — rescaling is a bit shift — so it is the preferred choice for\n * audio samples, graphics, probabilities, and any other quantity where\n * performance matters and the scale does not need to align with decimal\n * digits.\n *\n * @typeParam TSignedness - Whether the value can be negative.\n * @typeParam TTotalBits - The total number of bits used to store the raw value.\n * @typeParam TFractionalBits - The number of bits to the right of the binary point.\n *\n * @example\n * A 16-bit signed Q1.15 audio sample:\n * ```ts\n * type AudioSample = BinaryFixedPoint<'signed', 16, 15>;\n * ```\n *\n * @see {@link DecimalFixedPoint}\n * @see {@link Signedness}\n */\nexport type BinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n> = {\n    readonly fractionalBits: TFractionalBits;\n    readonly kind: 'binaryFixedPoint';\n    readonly raw: bigint;\n    readonly signedness: TSignedness;\n    readonly totalBits: TTotalBits;\n};\n\nfunction createBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    fractionalBits: TFractionalBits,\n    raw: bigint,\n): BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    assertRawFitsInRange('binaryFixedPoint', signedness, totalBits, raw);\n    return Object.freeze({ fractionalBits, kind: 'binaryFixedPoint', raw, signedness, totalBits });\n}\n\n/**\n * Returns a factory that constructs {@link BinaryFixedPoint} values from\n * decimal strings.\n *\n * The outer call validates the shape parameters once and the returned\n * factory can be called many times to construct values of that shape.\n *\n * The input string is parsed as a decimal number and scaled by\n * `2 ** fractionalBits` to compute the raw bigint. Values that cannot be\n * represented exactly in binary (such as `\"0.1\"`) trigger the rounding\n * behaviour documented on {@link RoundingMode}, with `'strict'` throwing\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` by default.\n *\n * @example\n * ```ts\n * const audioSample = binaryFixedPoint('signed', 16, 15);\n * audioSample('0.5');          // raw === 16384n (exact)\n * audioSample('0.1');          // throws under the default 'strict' mode\n * audioSample('0.1', 'round'); // raw === 3277n\n * ```\n *\n * @see {@link BinaryFixedPoint}\n * @see {@link rawBinaryFixedPoint}\n * @see {@link ratioBinaryFixedPoint}\n */\nexport function binaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    fractionalBits: TFractionalBits,\n): (input: string, rounding?: RoundingMode) => BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    assertValidTotalBits('binaryFixedPoint', totalBits);\n    assertValidFractionalBits(fractionalBits);\n    assertFractionalBitsFitInTotalBits(fractionalBits, totalBits);\n    return (input, rounding = 'strict') => {\n        const parsed = parseDecimalString('binaryFixedPoint', input);\n        // The parsed value is `parsed.raw / 10^parsed.decimals`. We need\n        // `raw = value * 2^fractionalBits`, i.e.\n        // `raw = parsed.raw * 2^fractionalBits / 10^parsed.decimals`.\n        const scaledRaw = parsed.raw * (1n << BigInt(fractionalBits));\n        const raw =\n            parsed.decimals === 0\n                ? scaledRaw\n                : roundDivision('binaryFixedPoint', 'fromString', scaledRaw, 10n ** BigInt(parsed.decimals), rounding);\n        return createBinaryFixedPoint(signedness, totalBits, fractionalBits, raw);\n    };\n}\n\n/**\n * Returns a factory that constructs {@link BinaryFixedPoint} values from a\n * raw bigint in the smallest representable unit (i.e. already scaled by\n * `2 ** fractionalBits`).\n *\n * The outer call validates the shape parameters once and the returned\n * factory can be called many times to construct values of that shape.\n *\n * The raw value is range-checked against the claimed `totalBits` and\n * `signedness`; no rounding is ever required.\n *\n * @example\n * ```ts\n * const q1_15 = rawBinaryFixedPoint('signed', 16, 15);\n * q1_15(16384n); // Represents 0.5\n * ```\n *\n * @see {@link BinaryFixedPoint}\n * @see {@link binaryFixedPoint}\n * @see {@link ratioBinaryFixedPoint}\n */\nexport function rawBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    fractionalBits: TFractionalBits,\n): (raw: bigint) => BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    assertValidTotalBits('binaryFixedPoint', totalBits);\n    assertValidFractionalBits(fractionalBits);\n    assertFractionalBitsFitInTotalBits(fractionalBits, totalBits);\n    return raw => createBinaryFixedPoint(signedness, totalBits, fractionalBits, raw);\n}\n\n/**\n * Returns a factory that constructs {@link BinaryFixedPoint} values from a\n * rational `numerator / denominator`.\n *\n * The outer call validates the shape parameters once and the returned\n * factory can be called many times to construct values of that shape.\n *\n * If the ratio cannot be exactly represented at the target\n * `fractionalBits`, the returned factory throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` under the\n * default `'strict'` rounding mode. Pass a different {@link RoundingMode}\n * to allow a rounded result. Zero denominators always throw\n * `SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO`.\n *\n * @example\n * ```ts\n * const probability = ratioBinaryFixedPoint('signed', 16, 15);\n * probability(1n, 4n);           // raw === 8192n (0.25, exact)\n * probability(1n, 3n);           // throws under 'strict'\n * probability(1n, 3n, 'floor');  // raw === 10922n\n * ```\n *\n * @see {@link BinaryFixedPoint}\n * @see {@link binaryFixedPoint}\n * @see {@link rawBinaryFixedPoint}\n */\nexport function ratioBinaryFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TFractionalBits extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    fractionalBits: TFractionalBits,\n): (\n    numerator: bigint,\n    denominator: bigint,\n    rounding?: RoundingMode,\n) => BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    assertValidTotalBits('binaryFixedPoint', totalBits);\n    assertValidFractionalBits(fractionalBits);\n    assertFractionalBitsFitInTotalBits(fractionalBits, totalBits);\n    return (numerator, denominator, rounding = 'strict') => {\n        if (denominator === 0n) {\n            throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO, {\n                denominator,\n                kind: 'binaryFixedPoint',\n                numerator,\n            });\n        }\n        const raw = roundDivision(\n            'binaryFixedPoint',\n            'fromRatio',\n            numerator * (1n << BigInt(fractionalBits)),\n            denominator,\n            rounding,\n        );\n        return createBinaryFixedPoint(signedness, totalBits, fractionalBits, raw);\n    };\n}\n"
  },
  {
    "path": "packages/fixed-points/src/binary/formatting.ts",
    "content": "import { applyDecimalsOption, type FixedPointToStringOptions, formatScaledBigint } from '../formatting';\nimport type { Signedness } from '../signedness';\nimport { binaryFixedPointToBase10 } from './conversions';\nimport type { BinaryFixedPoint } from './core';\n\n/**\n * Returns the canonical decimal string representation of a\n * {@link BinaryFixedPoint}.\n *\n * Because `1 / 2 ** fractionalBits` has a finite decimal expansion, the\n * default output is always exact. This means that values with many\n * `fractionalBits` can produce long strings — pass `options.decimals` to\n * cap the output at a desired precision, optionally with a\n * {@link RoundingMode}. Use `options.padTrailingZeros` to emit exactly as\n * many fractional digits as requested; when `decimals` is omitted, this\n * pads to `value.fractionalBits` (the full exact expansion length).\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` when\n * `options.decimals` forces a lossy rescale under the default `'strict'`\n * rounding mode.\n *\n * @example\n * ```ts\n * const q1_15 = binaryFixedPoint('signed', 16, 15);\n * binaryFixedPointToString(q1_15('0.5'));                                 // \"0.5\"\n * binaryFixedPointToString(q1_15('0.5'), { padTrailingZeros: true });     // \"0.500000000000000\"\n * binaryFixedPointToString(ugly, { decimals: 2, rounding: 'round' });     // \"0.48\"\n * ```\n *\n * @see {@link binaryFixedPointToNumber}\n */\nexport function binaryFixedPointToString(\n    value: BinaryFixedPoint<Signedness, number, number>,\n    options?: FixedPointToStringOptions,\n): string {\n    const base10 = binaryFixedPointToBase10(value);\n    const { decimals, raw } = applyDecimalsOption('binaryFixedPoint', base10.raw, base10.decimals, options);\n    return formatScaledBigint(raw, decimals, options?.padTrailingZeros ?? false);\n}\n\n/**\n * Formats a {@link BinaryFixedPoint} using a user-supplied\n * `Intl.NumberFormat` instance, preserving full precision regardless of\n * the value's magnitude.\n *\n * Internally calls {@link binaryFixedPointToBase10} and forwards the\n * resulting integer to `formatter.format` using ES2023 string scientific\n * notation (`\"<raw>E-<decimals>\"`). This preserves precision in\n * fully-compliant runtimes and bypasses the JavaScript `number` mantissa\n * limit.\n *\n * Use this when you want locale-aware output, currency formatting,\n * grouping separators, or rounding modes from the rich\n * `Intl.NumberFormat` API. Prefer {@link binaryFixedPointToString} when\n * portability across older runtimes (older Hermes/React Native, etc.) is\n * a concern.\n *\n * @example\n * ```ts\n * const q1_15 = binaryFixedPoint('signed', 16, 15);\n * const formatter = new Intl.NumberFormat('fr-FR', {\n *     maximumFractionDigits: 4,\n * });\n * formatBinaryFixedPoint(formatter, q1_15('0.1')); // \"0,1\"\n * ```\n *\n * @see {@link binaryFixedPointToString}\n * @see {@link binaryFixedPointToBase10}\n */\nexport function formatBinaryFixedPoint(\n    formatter: Intl.NumberFormat,\n    value: BinaryFixedPoint<Signedness, number, number>,\n): string {\n    const { decimals, raw } = binaryFixedPointToBase10(value);\n    return (formatter.format as unknown as (input: string) => string)(`${raw}E-${decimals}`);\n}\n\n/**\n * Converts a {@link BinaryFixedPoint} to a JavaScript `number`.\n *\n * Precision loss occurs only when `|value.raw / 2 ** fractionalBits|`\n * exceeds `Number.MAX_SAFE_INTEGER`, since JavaScript numbers have only\n * ~53 bits of mantissa. For values whose magnitude fits that budget the\n * result is exact, regardless of the raw value's magnitude.\n *\n * For exact representations prefer {@link binaryFixedPointToString}.\n *\n * @example\n * ```ts\n * const q1_15 = binaryFixedPoint('signed', 16, 15);\n * binaryFixedPointToNumber(q1_15('0.5')); // 0.5\n * ```\n *\n * @see {@link binaryFixedPointToString}\n */\nexport function binaryFixedPointToNumber(value: BinaryFixedPoint<Signedness, number, number>): number {\n    const { fractionalBits, raw } = value;\n    if (fractionalBits === 0) {\n        return Number(raw);\n    }\n    // Split `raw` into an integer and a fractional residue before coercing to\n    // Number. This preserves exactness for values whose final magnitude fits\n    // ~53 bits of mantissa even when `|raw|` itself exceeds MAX_SAFE_INTEGER.\n    const scale = 1n << BigInt(fractionalBits);\n    const integerPart = raw / scale;\n    const fractionalPart = Number(raw - integerPart * scale) / 2 ** fractionalBits;\n    return Number(integerPart) + fractionalPart;\n}\n"
  },
  {
    "path": "packages/fixed-points/src/binary/guards.ts",
    "content": "import {\n    assertFractionalBitsFitInTotalBits,\n    assertRawFitsInRange,\n    assertRawIsBigint,\n    assertShapeMatches,\n    describeShape,\n} from '../assertions';\nimport type { Signedness } from '../signedness';\nimport type { BinaryFixedPoint } from './core';\n\n/**\n * Asserts that `value` is a {@link BinaryFixedPoint}.\n *\n * Every shape parameter is independently optional. Pass `undefined` (or\n * simply omit trailing arguments) to leave a given field unconstrained.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` if the value does\n * not match the expected shape, or\n * `SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE` if the `raw` bigint\n * does not fit the claimed signedness and total bits.\n *\n * @example\n * ```ts\n * assertIsBinaryFixedPoint(value);                   // any binary fixed-point\n * assertIsBinaryFixedPoint(value, 'signed');         // any signed binary\n * assertIsBinaryFixedPoint(value, 'signed', 16, 15); // fully pinned\n * assertIsBinaryFixedPoint(value, undefined, 16);    // any binary with totalBits=16\n * ```\n *\n * @see {@link isBinaryFixedPoint}\n * @see {@link BinaryFixedPoint}\n */\nexport function assertIsBinaryFixedPoint<\n    TSignedness extends Signedness = Signedness,\n    TTotalBits extends number = number,\n    TFractionalBits extends number = number,\n>(\n    value: unknown,\n    signedness?: TSignedness,\n    totalBits?: TTotalBits,\n    fractionalBits?: TFractionalBits,\n): asserts value is BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    const actual = describeShape(value);\n    const expected = {\n        kind: 'binaryFixedPoint',\n        scale: fractionalBits,\n        scaleLabel: 'fractional bits',\n        signedness,\n        totalBits,\n    };\n    assertShapeMatches('assertIsBinaryFixedPoint', actual, expected);\n    // Binary fixed-points carry an extra structural invariant beyond the\n    // generic shape check: `fractionalBits` (stored in `actual.scale`)\n    // must not exceed `totalBits`.\n    assertFractionalBitsFitInTotalBits(actual.scale, actual.totalBits);\n    assertRawIsBigint('binaryFixedPoint', value);\n    assertRawFitsInRange('binaryFixedPoint', actual.signedness as Signedness, actual.totalBits, value.raw);\n}\n\n/**\n * Type guard that refines an unknown value to a {@link BinaryFixedPoint}.\n *\n * Accepts the same partial-positional shape arguments as\n * {@link assertIsBinaryFixedPoint} and returns `true` if the assertion\n * would pass, `false` otherwise.\n *\n * @example\n * ```ts\n * if (isBinaryFixedPoint(value)) {\n *     value satisfies BinaryFixedPoint<Signedness, number, number>;\n * }\n * if (isBinaryFixedPoint(value, 'signed', 16, 15)) {\n *     value satisfies BinaryFixedPoint<'signed', 16, 15>;\n * }\n * ```\n *\n * @see {@link assertIsBinaryFixedPoint}\n * @see {@link BinaryFixedPoint}\n */\nexport function isBinaryFixedPoint<\n    TSignedness extends Signedness = Signedness,\n    TTotalBits extends number = number,\n    TFractionalBits extends number = number,\n>(\n    value: unknown,\n    signedness?: TSignedness,\n    totalBits?: TTotalBits,\n    fractionalBits?: TFractionalBits,\n): value is BinaryFixedPoint<TSignedness, TTotalBits, TFractionalBits> {\n    try {\n        assertIsBinaryFixedPoint(value, signedness, totalBits, fractionalBits);\n        return true;\n    } catch {\n        return false;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/binary/index.ts",
    "content": "export * from './arithmetics';\nexport * from './codecs';\nexport * from './comparisons';\nexport * from './conversions';\nexport * from './core';\nexport * from './formatting';\nexport * from './guards';\n"
  },
  {
    "path": "packages/fixed-points/src/codecs.ts",
    "content": "import { type ReadonlyUint8Array, toArrayBuffer } from '@solana/codecs-core';\n\nimport type { Signedness } from './signedness';\n\n/**\n * Configuration options for fixed-point codecs.\n */\nexport type FixedPointCodecConfig = {\n    /**\n     * Whether values are serialized in little- or big-endian byte order.\n     *\n     * @defaultValue `'le'`\n     */\n    endian?: 'be' | 'le';\n};\n\n/**\n * Maps a byte-aligned `totalBits` literal to its byte count. Falls back to\n * `number` when `totalBits` is not a known multiple of 8 between 8 and 256\n * inclusive — in which case the runtime still works, but the literal size\n * generic is erased.\n *\n * @internal\n */\n/* eslint-disable typescript-sort-keys/interface */\ntype TotalBitsToBytesTable = {\n    8: 1;\n    16: 2;\n    24: 3;\n    32: 4;\n    40: 5;\n    48: 6;\n    56: 7;\n    64: 8;\n    72: 9;\n    80: 10;\n    88: 11;\n    96: 12;\n    104: 13;\n    112: 14;\n    120: 15;\n    128: 16;\n    136: 17;\n    144: 18;\n    152: 19;\n    160: 20;\n    168: 21;\n    176: 22;\n    184: 23;\n    192: 24;\n    200: 25;\n    208: 26;\n    216: 27;\n    224: 28;\n    232: 29;\n    240: 30;\n    248: 31;\n    256: 32;\n};\n/* eslint-enable typescript-sort-keys/interface */\n\n/**\n * Byte count implied by a fixed-point codec's `totalBits`. Preserves the\n * byte-size literal in the codec type for common widths (multiples of 8\n * from 8 to 256); widens to `number` for other widths.\n *\n * @internal\n */\nexport type BytesForTotalBits<TTotalBits extends number> = TTotalBits extends keyof TotalBitsToBytesTable\n    ? TotalBitsToBytesTable[TTotalBits]\n    : number;\n\nconst MASK_64 = 0xffffffffffffffffn;\nconst MASK_32 = 0xffffffffn;\nconst MASK_16 = 0xffffn;\nconst MASK_8 = 0xffn;\n\n/**\n * Writes a raw bigint into `bytes` starting at `offset`, using `byteSize`\n * bytes with the given `signedness` and endianness.\n *\n * Signed negative values are serialized using two's-complement semantics:\n * `raw + 2 ** (byteSize * 8)` is written as if unsigned. The caller is\n * expected to have validated that `raw` fits the claimed range.\n *\n * The implementation processes 64-bit chunks via `DataView.setBigUint64`\n * and greedily consumes the remaining 0–7 bytes with at most one\n * `setUint32`, one `setUint16`, and one direct byte write. For common\n * widths this matches `@solana/codecs-numbers` performance exactly.\n *\n * @internal\n */\nexport function writeRawBigInt(\n    bytes: Uint8Array,\n    offset: number,\n    raw: bigint,\n    byteSize: number,\n    signedness: Signedness,\n    littleEndian: boolean,\n): void {\n    // Normalize to an unsigned bit pattern so downstream code can treat\n    // signed negatives as their two's-complement counterparts.\n    const unsigned = signedness === 'signed' && raw < 0n ? raw + (1n << BigInt(byteSize * 8)) : raw;\n\n    const fullChunks = byteSize >> 3;\n    const residual = byteSize & 7;\n    const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n\n    // Full 64-bit chunks. LE lays chunks low-to-high; BE lays higher-order\n    // chunks at lower memory addresses.\n    for (let c = 0; c < fullChunks; c++) {\n        const chunk = (unsigned >> BigInt(c * 64)) & MASK_64;\n        const position = littleEndian ? c * 8 : byteSize - (c + 1) * 8;\n        view.setBigUint64(offset + position, chunk, littleEndian);\n    }\n\n    if (residual > 0) {\n        const residualChunk = unsigned >> BigInt(fullChunks * 64);\n        // LE: residual bytes follow the chunks. BE: residual occupies the\n        // highest-order bytes, which sit at the start of the memory region.\n        const residualBase = littleEndian ? fullChunks * 8 : 0;\n        let consumed = 0;\n\n        if (residual - consumed >= 4) {\n            const chunk = Number((residualChunk >> BigInt(consumed * 8)) & MASK_32);\n            const position = littleEndian ? residualBase + consumed : residualBase + residual - consumed - 4;\n            view.setUint32(offset + position, chunk, littleEndian);\n            consumed += 4;\n        }\n        if (residual - consumed >= 2) {\n            const chunk = Number((residualChunk >> BigInt(consumed * 8)) & MASK_16);\n            const position = littleEndian ? residualBase + consumed : residualBase + residual - consumed - 2;\n            view.setUint16(offset + position, chunk, littleEndian);\n            consumed += 2;\n        }\n        if (residual - consumed >= 1) {\n            const chunk = Number((residualChunk >> BigInt(consumed * 8)) & MASK_8);\n            const position = littleEndian ? residualBase + consumed : residualBase + residual - consumed - 1;\n            bytes[offset + position] = chunk;\n        }\n    }\n}\n\n/**\n * Reads a raw bigint from `bytes` starting at `offset`, using `byteSize`\n * bytes with the given `signedness` and endianness.\n *\n * Signed values use two's-complement semantics: if the top bit of the\n * decoded unsigned value is set, `2 ** (byteSize * 8)` is subtracted to\n * produce the negative result.\n *\n * The implementation processes 64-bit chunks via `DataView.getBigUint64`\n * and greedily consumes the remaining 0–7 bytes with at most one\n * `getUint32`, one `getUint16`, and one direct byte read.\n *\n * @internal\n */\nexport function readRawBigInt(\n    bytes: ReadonlyUint8Array | Uint8Array,\n    offset: number,\n    byteSize: number,\n    signedness: Signedness,\n    littleEndian: boolean,\n): bigint {\n    const fullChunks = byteSize >> 3;\n    const residual = byteSize & 7;\n    // `toArrayBuffer` defensively copies when the backing is a\n    // SharedArrayBuffer and is safe to call where SharedArrayBuffer is\n    // undefined (React Native, non-isolated browser contexts).\n    const view = new DataView(toArrayBuffer(bytes, offset, byteSize));\n    let unsigned = 0n;\n\n    for (let c = 0; c < fullChunks; c++) {\n        const position = littleEndian ? c * 8 : byteSize - (c + 1) * 8;\n        const chunk = view.getBigUint64(position, littleEndian);\n        unsigned |= chunk << BigInt(c * 64);\n    }\n\n    if (residual > 0) {\n        const residualBase = littleEndian ? fullChunks * 8 : 0;\n        let residualChunk = 0n;\n        let consumed = 0;\n\n        if (residual - consumed >= 4) {\n            const position = littleEndian ? residualBase + consumed : residualBase + residual - consumed - 4;\n            residualChunk |= BigInt(view.getUint32(position, littleEndian)) << BigInt(consumed * 8);\n            consumed += 4;\n        }\n        if (residual - consumed >= 2) {\n            const position = littleEndian ? residualBase + consumed : residualBase + residual - consumed - 2;\n            residualChunk |= BigInt(view.getUint16(position, littleEndian)) << BigInt(consumed * 8);\n            consumed += 2;\n        }\n        if (residual - consumed >= 1) {\n            const position = littleEndian ? residualBase + consumed : residualBase + residual - consumed - 1;\n            residualChunk |= BigInt(bytes[offset + position]) << BigInt(consumed * 8);\n        }\n\n        unsigned |= residualChunk << BigInt(fullChunks * 64);\n    }\n\n    if (signedness === 'signed') {\n        const signBit = 1n << BigInt(byteSize * 8 - 1);\n        if ((unsigned & signBit) !== 0n) {\n            return unsigned - (1n << BigInt(byteSize * 8));\n        }\n    }\n    return unsigned;\n}\n"
  },
  {
    "path": "packages/fixed-points/src/decimal/arithmetics.ts",
    "content": "import { assertNoArithmeticOverflow, assertNoDivisionByZero, assertShapeMatches, describeShape } from '../assertions';\nimport { roundDivision, type RoundingMode } from '../rounding';\nimport type { Signedness } from '../signedness';\nimport type { DecimalFixedPoint } from './core';\n\n/**\n * Adds two {@link DecimalFixedPoint} values of the same shape and returns\n * the result at the same shape.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` if the two operands\n * differ in signedness, total bits, or decimals, and\n * `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW` if the sum does not\n * fit the target shape.\n *\n * @example\n * ```ts\n * const usd = decimalFixedPoint('unsigned', 64, 2);\n * addDecimalFixedPoint(usd('1.50'), usd('2.25')); // represents 3.75\n * ```\n *\n * @see {@link subtractDecimalFixedPoint}\n */\nexport function addDecimalFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    a: DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>,\n    b: NoInfer<DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>>,\n): DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    assertShapeMatches('addDecimalFixedPoint', describeShape(b), {\n        kind: a.kind,\n        scale: a.decimals,\n        scaleLabel: 'decimals',\n        signedness: a.signedness,\n        totalBits: a.totalBits,\n    });\n    const result = a.raw + b.raw;\n    assertNoArithmeticOverflow(a.kind, 'add', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Subtracts `b` from `a` where both are {@link DecimalFixedPoint} values\n * of the same shape, and returns the result at the same shape.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` if the two operands\n * differ in shape, and `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW`\n * if the difference does not fit the target shape.\n *\n * @see {@link addDecimalFixedPoint}\n */\nexport function subtractDecimalFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    a: DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>,\n    b: NoInfer<DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>>,\n): DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    assertShapeMatches('subtractDecimalFixedPoint', describeShape(b), {\n        kind: a.kind,\n        scale: a.decimals,\n        scaleLabel: 'decimals',\n        signedness: a.signedness,\n        totalBits: a.totalBits,\n    });\n    const result = a.raw - b.raw;\n    assertNoArithmeticOverflow(a.kind, 'subtract', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Multiplies a {@link DecimalFixedPoint} by a scalar.\n *\n * The second operand may be another {@link DecimalFixedPoint} with the\n * same signedness (any total bits or decimals) or a bare `bigint`. The\n * result always has `a`'s shape.\n *\n * Multiplication by a same-kind fixed-point rescales the product back to\n * `a`'s scale. When that rescaling is not exact, the optional\n * {@link RoundingMode} is consulted; it defaults to `'strict'` and throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` in that case.\n *\n * @example\n * ```ts\n * const usd = decimalFixedPoint('unsigned', 64, 2);\n * const rate = decimalFixedPoint('unsigned', 64, 4);\n * multiplyDecimalFixedPoint(usd('100'), rate('0.0025')); // represents 0.25\n * multiplyDecimalFixedPoint(usd('1.50'), 3n);             // represents 4.50\n * ```\n *\n * @see {@link divideDecimalFixedPoint}\n */\nexport function multiplyDecimalFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    a: DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>,\n    b: DecimalFixedPoint<NoInfer<TSignedness>, number, number> | bigint,\n    rounding: RoundingMode = 'strict',\n): DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    let result: bigint;\n    if (typeof b === 'bigint') {\n        result = a.raw * b;\n    } else {\n        assertShapeMatches('multiplyDecimalFixedPoint', describeShape(b), {\n            kind: a.kind,\n            scaleLabel: 'decimals',\n            signedness: a.signedness,\n        });\n        result = roundDivision(a.kind, 'multiply', a.raw * b.raw, 10n ** BigInt(b.decimals), rounding);\n    }\n    assertNoArithmeticOverflow(a.kind, 'multiply', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Divides a {@link DecimalFixedPoint} by a scalar.\n *\n * The second operand may be another {@link DecimalFixedPoint} with the\n * same signedness (any total bits or decimals) or a bare `bigint`. The\n * result always has `a`'s shape.\n *\n * The optional {@link RoundingMode} is consulted whenever the division is\n * inexact; it defaults to `'strict'` and throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` in that case.\n * A zero divisor always throws\n * `SOLANA_ERROR__FIXED_POINTS__DIVISION_BY_ZERO`.\n *\n * @example\n * ```ts\n * const usd = decimalFixedPoint('unsigned', 64, 2);\n * const rate = decimalFixedPoint('unsigned', 64, 4);\n * divideDecimalFixedPoint(usd('10'), rate('0.05'));   // represents 200.00\n * divideDecimalFixedPoint(usd('10.50'), 3n, 'round'); // represents 3.50\n * ```\n *\n * @see {@link multiplyDecimalFixedPoint}\n */\nexport function divideDecimalFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    a: DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>,\n    b: DecimalFixedPoint<NoInfer<TSignedness>, number, number> | bigint,\n    rounding: RoundingMode = 'strict',\n): DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    let result: bigint;\n    if (typeof b === 'bigint') {\n        assertNoDivisionByZero(a.kind, a.signedness, a.totalBits, b);\n        result = roundDivision(a.kind, 'divide', a.raw, b, rounding);\n    } else {\n        assertShapeMatches('divideDecimalFixedPoint', describeShape(b), {\n            kind: a.kind,\n            scaleLabel: 'decimals',\n            signedness: a.signedness,\n        });\n        assertNoDivisionByZero(a.kind, a.signedness, a.totalBits, b.raw);\n        result = roundDivision(a.kind, 'divide', a.raw * 10n ** BigInt(b.decimals), b.raw, rounding);\n    }\n    assertNoArithmeticOverflow(a.kind, 'divide', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Returns the additive inverse of a signed {@link DecimalFixedPoint}.\n *\n * Unsigned values are rejected at the type level; they are also rejected\n * at runtime with `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` in case the\n * type safety is bypassed. Negating the minimum representable value\n * overflows and throws `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW`.\n *\n * @see {@link absoluteDecimalFixedPoint}\n */\nexport function negateDecimalFixedPoint<TTotalBits extends number, TDecimals extends number>(\n    a: DecimalFixedPoint<'signed', TTotalBits, TDecimals>,\n): DecimalFixedPoint<'signed', TTotalBits, TDecimals> {\n    assertShapeMatches('negateDecimalFixedPoint', describeShape(a), {\n        kind: a.kind,\n        scaleLabel: 'decimals',\n        signedness: 'signed',\n    });\n    const result = -a.raw;\n    assertNoArithmeticOverflow(a.kind, 'negate', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n\n/**\n * Returns the absolute value of a {@link DecimalFixedPoint}. Unsigned\n * inputs are returned unchanged.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW` when taking the\n * absolute value of the minimum representable signed value, which has no\n * positive counterpart in two's-complement.\n *\n * @see {@link negateDecimalFixedPoint}\n */\nexport function absoluteDecimalFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(a: DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>): DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    const result = a.raw < 0n ? -a.raw : a.raw;\n    assertNoArithmeticOverflow(a.kind, 'absolute', a.signedness, a.totalBits, result);\n    return Object.freeze({ ...a, raw: result });\n}\n"
  },
  {
    "path": "packages/fixed-points/src/decimal/codecs.ts",
    "content": "import {\n    assertByteArrayHasEnoughBytesForCodec,\n    assertByteArrayIsNotEmptyForCodec,\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    type FixedSizeCodec,\n    type FixedSizeDecoder,\n    type FixedSizeEncoder,\n} from '@solana/codecs-core';\n\nimport {\n    assertShapeMatches,\n    assertTotalBitsIsByteAligned,\n    assertValidDecimals,\n    assertValidTotalBits,\n    describeShape,\n} from '../assertions';\nimport { type BytesForTotalBits, type FixedPointCodecConfig, readRawBigInt, writeRawBigInt } from '../codecs';\nimport type { Signedness } from '../signedness';\nimport type { DecimalFixedPoint } from './core';\n\n/**\n * Returns an encoder for {@link DecimalFixedPoint} values of a specific\n * shape. The encoder serializes `value.raw` as a fixed-size integer using\n * two's-complement for signed values and little-endian byte order by\n * default.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED` when\n * `totalBits` is not a multiple of 8. Encoding a value whose shape does\n * not match the codec's shape throws\n * `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH`.\n *\n * @example\n * ```ts\n * const encoder = getDecimalFixedPointEncoder('unsigned', 64, 6);\n * encoder.encode(decimalFixedPoint('unsigned', 64, 6)('42.5'));\n * ```\n *\n * @see {@link getDecimalFixedPointDecoder}\n * @see {@link getDecimalFixedPointCodec}\n */\nexport function getDecimalFixedPointEncoder<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    decimals: TDecimals,\n    config: FixedPointCodecConfig = {},\n): FixedSizeEncoder<DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>, BytesForTotalBits<TTotalBits>> {\n    assertValidTotalBits('decimalFixedPoint', totalBits);\n    assertValidDecimals(decimals);\n    assertTotalBitsIsByteAligned('decimalFixedPoint', totalBits);\n    const byteSize = (totalBits / 8) as BytesForTotalBits<TTotalBits>;\n    const littleEndian = config.endian !== 'be';\n    return createEncoder({\n        fixedSize: byteSize,\n        write(value, bytes, offset) {\n            assertShapeMatches('getDecimalFixedPointEncoder', describeShape(value), {\n                kind: 'decimalFixedPoint',\n                scale: decimals,\n                scaleLabel: 'decimals',\n                signedness,\n                totalBits,\n            });\n            writeRawBigInt(bytes, offset, value.raw, byteSize, signedness, littleEndian);\n            return offset + byteSize;\n        },\n    });\n}\n\n/**\n * Returns a decoder for {@link DecimalFixedPoint} values of a specific\n * shape. The decoder reads a fixed-size integer using two's-complement for\n * signed values and little-endian byte order by default, and reconstructs\n * a frozen {@link DecimalFixedPoint} from the bytes.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED` when\n * `totalBits` is not a multiple of 8.\n *\n * @example\n * ```ts\n * const decoder = getDecimalFixedPointDecoder('unsigned', 64, 6);\n * decoder.decode(bytes); // represents 42.5 for appropriately encoded bytes\n * ```\n *\n * @see {@link getDecimalFixedPointEncoder}\n * @see {@link getDecimalFixedPointCodec}\n */\nexport function getDecimalFixedPointDecoder<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    decimals: TDecimals,\n    config: FixedPointCodecConfig = {},\n): FixedSizeDecoder<DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>, BytesForTotalBits<TTotalBits>> {\n    assertValidTotalBits('decimalFixedPoint', totalBits);\n    assertValidDecimals(decimals);\n    assertTotalBitsIsByteAligned('decimalFixedPoint', totalBits);\n    const byteSize = (totalBits / 8) as BytesForTotalBits<TTotalBits>;\n    const littleEndian = config.endian !== 'be';\n    const codecDescription = 'getDecimalFixedPointDecoder';\n    return createDecoder({\n        fixedSize: byteSize,\n        read(bytes, offset) {\n            assertByteArrayIsNotEmptyForCodec(codecDescription, bytes, offset);\n            assertByteArrayHasEnoughBytesForCodec(codecDescription, byteSize, bytes, offset);\n            const raw = readRawBigInt(bytes, offset, byteSize, signedness, littleEndian);\n            const value = Object.freeze({\n                decimals,\n                kind: 'decimalFixedPoint',\n                raw,\n                signedness,\n                totalBits,\n            }) as DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>;\n            return [value, offset + byteSize];\n        },\n    });\n}\n\n/**\n * Returns a codec for {@link DecimalFixedPoint} values of a specific\n * shape, combining {@link getDecimalFixedPointEncoder} and\n * {@link getDecimalFixedPointDecoder}.\n *\n * @example\n * ```ts\n * const codec = getDecimalFixedPointCodec('unsigned', 64, 6);\n * const bytes = codec.encode(decimalFixedPoint('unsigned', 64, 6)('42.5'));\n * const value = codec.decode(bytes); // represents 42.5\n * ```\n *\n * @see {@link getDecimalFixedPointEncoder}\n * @see {@link getDecimalFixedPointDecoder}\n */\nexport function getDecimalFixedPointCodec<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    decimals: TDecimals,\n    config: FixedPointCodecConfig = {},\n): FixedSizeCodec<\n    DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>,\n    DecimalFixedPoint<TSignedness, TTotalBits, TDecimals>,\n    BytesForTotalBits<TTotalBits>\n> {\n    return combineCodec(\n        getDecimalFixedPointEncoder(signedness, totalBits, decimals, config),\n        getDecimalFixedPointDecoder(signedness, totalBits, decimals, config),\n    );\n}\n"
  },
  {
    "path": "packages/fixed-points/src/decimal/comparisons.ts",
    "content": "import { assertShapeMatches, describeShape } from '../assertions';\nimport type { Signedness } from '../signedness';\nimport type { DecimalFixedPoint } from './core';\n\n/**\n * Compares two {@link DecimalFixedPoint} values and returns `-1`, `0`, or\n * `1` depending on whether `a` is less than, equal to, or greater than `b`.\n *\n * Only the `kind` and `decimals` of the two operands must match;\n * `signedness` and `totalBits` are allowed to differ because they are\n * storage concerns only and do not affect the mathematical value being\n * compared. Mismatches on the constrained dimensions throw\n * `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH`.\n *\n * @example\n * ```ts\n * const usd = decimalFixedPoint('unsigned', 64, 2);\n * cmpDecimalFixedPoint(usd('1.25'), usd('2.50')); // -1\n * cmpDecimalFixedPoint(usd('2.50'), usd('2.50')); // 0\n * cmpDecimalFixedPoint(usd('3.75'), usd('2.50')); // 1\n * ```\n *\n * @see {@link eqDecimalFixedPoint}\n * @see {@link ltDecimalFixedPoint}\n * @see {@link lteDecimalFixedPoint}\n * @see {@link gtDecimalFixedPoint}\n * @see {@link gteDecimalFixedPoint}\n */\nexport function cmpDecimalFixedPoint<TDecimals extends number>(\n    a: DecimalFixedPoint<Signedness, number, TDecimals>,\n    b: DecimalFixedPoint<Signedness, number, NoInfer<TDecimals>>,\n): -1 | 0 | 1 {\n    assertShapeMatches('cmpDecimalFixedPoint', describeShape(b), {\n        kind: a.kind,\n        scale: a.decimals,\n        scaleLabel: 'decimals',\n    });\n    return a.raw < b.raw ? -1 : a.raw > b.raw ? 1 : 0;\n}\n\n/**\n * Returns `true` when `a` and `b` represent the same value.\n *\n * See {@link cmpDecimalFixedPoint} for shape-matching rules.\n */\nexport function eqDecimalFixedPoint<TDecimals extends number>(\n    a: DecimalFixedPoint<Signedness, number, TDecimals>,\n    b: DecimalFixedPoint<Signedness, number, NoInfer<TDecimals>>,\n): boolean {\n    return cmpDecimalFixedPoint(a, b) === 0;\n}\n\n/**\n * Returns `true` when `a` is strictly less than `b`.\n *\n * See {@link cmpDecimalFixedPoint} for shape-matching rules.\n */\nexport function ltDecimalFixedPoint<TDecimals extends number>(\n    a: DecimalFixedPoint<Signedness, number, TDecimals>,\n    b: DecimalFixedPoint<Signedness, number, NoInfer<TDecimals>>,\n): boolean {\n    return cmpDecimalFixedPoint(a, b) < 0;\n}\n\n/**\n * Returns `true` when `a` is less than or equal to `b`.\n *\n * See {@link cmpDecimalFixedPoint} for shape-matching rules.\n */\nexport function lteDecimalFixedPoint<TDecimals extends number>(\n    a: DecimalFixedPoint<Signedness, number, TDecimals>,\n    b: DecimalFixedPoint<Signedness, number, NoInfer<TDecimals>>,\n): boolean {\n    return cmpDecimalFixedPoint(a, b) <= 0;\n}\n\n/**\n * Returns `true` when `a` is strictly greater than `b`.\n *\n * See {@link cmpDecimalFixedPoint} for shape-matching rules.\n */\nexport function gtDecimalFixedPoint<TDecimals extends number>(\n    a: DecimalFixedPoint<Signedness, number, TDecimals>,\n    b: DecimalFixedPoint<Signedness, number, NoInfer<TDecimals>>,\n): boolean {\n    return cmpDecimalFixedPoint(a, b) > 0;\n}\n\n/**\n * Returns `true` when `a` is greater than or equal to `b`.\n *\n * See {@link cmpDecimalFixedPoint} for shape-matching rules.\n */\nexport function gteDecimalFixedPoint<TDecimals extends number>(\n    a: DecimalFixedPoint<Signedness, number, TDecimals>,\n    b: DecimalFixedPoint<Signedness, number, NoInfer<TDecimals>>,\n): boolean {\n    return cmpDecimalFixedPoint(a, b) >= 0;\n}\n"
  },
  {
    "path": "packages/fixed-points/src/decimal/conversions.ts",
    "content": "import {\n    assertNoArithmeticOverflow,\n    assertRawFitsInRange,\n    assertValidDecimals,\n    assertValidTotalBits,\n} from '../assertions';\nimport { roundDivision, type RoundingMode } from '../rounding';\nimport type { Signedness } from '../signedness';\nimport type { DecimalFixedPoint } from './core';\n\n/**\n * Converts a {@link DecimalFixedPoint} to its unsigned equivalent at the\n * same `totalBits` and `decimals`.\n *\n * Unsigned inputs are returned by reference unchanged; signed inputs are\n * accepted as long as their raw value is non-negative.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE` when the input\n * represents a negative value that cannot be stored as unsigned.\n *\n * @example\n * ```ts\n * const signedUsd = decimalFixedPoint('signed', 64, 2);\n * toUnsignedDecimalFixedPoint(signedUsd('1.50')); // unsigned, raw unchanged\n * toUnsignedDecimalFixedPoint(signedUsd('-1'));   // throws\n * ```\n *\n * @see {@link toSignedDecimalFixedPoint}\n */\nexport function toUnsignedDecimalFixedPoint<TTotalBits extends number, TDecimals extends number>(\n    value: DecimalFixedPoint<Signedness, TTotalBits, TDecimals>,\n): DecimalFixedPoint<'unsigned', TTotalBits, TDecimals> {\n    if (value.signedness === 'unsigned') {\n        return value as DecimalFixedPoint<'unsigned', TTotalBits, TDecimals>;\n    }\n    assertRawFitsInRange('decimalFixedPoint', 'unsigned', value.totalBits, value.raw);\n    return Object.freeze({ ...value, signedness: 'unsigned' });\n}\n\n/**\n * Converts a {@link DecimalFixedPoint} to its signed equivalent at the same\n * `totalBits` and `decimals`.\n *\n * Signed inputs are returned by reference unchanged; unsigned inputs are\n * accepted as long as their raw value fits the signed range, i.e.\n * `raw <= 2 ** (totalBits - 1) - 1`.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE` when the input's\n * raw value exceeds the maximum representable signed value at its\n * `totalBits`.\n *\n * @example\n * ```ts\n * const unsigned = rawDecimalFixedPoint('unsigned', 8, 0);\n * toSignedDecimalFixedPoint(unsigned(100n)); // signed, raw === 100n\n * toSignedDecimalFixedPoint(unsigned(200n)); // throws (200 > 127)\n * ```\n *\n * @see {@link toUnsignedDecimalFixedPoint}\n */\nexport function toSignedDecimalFixedPoint<TTotalBits extends number, TDecimals extends number>(\n    value: DecimalFixedPoint<Signedness, TTotalBits, TDecimals>,\n): DecimalFixedPoint<'signed', TTotalBits, TDecimals> {\n    if (value.signedness === 'signed') {\n        return value as DecimalFixedPoint<'signed', TTotalBits, TDecimals>;\n    }\n    assertRawFitsInRange('decimalFixedPoint', 'signed', value.totalBits, value.raw);\n    return Object.freeze({ ...value, signedness: 'signed' });\n}\n\n/**\n * Returns a {@link DecimalFixedPoint} with the same signedness as `value`\n * but a new `totalBits` and `decimals`. If the requested shape matches\n * the input shape, the same reference is returned.\n *\n * Scale-up (higher `decimals`) is always exact. Scale-down (lower\n * `decimals`) is potentially lossy; the optional {@link RoundingMode} is\n * consulted on inexact results and defaults to `'strict'`, which throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS`.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__ARITHMETIC_OVERFLOW` when the\n * rescaled raw value does not fit the new `totalBits`.\n *\n * @example\n * ```ts\n * // Bridge EVM USDC (u128 d18) down to SPL USDC (u64 d6).\n * const evmUsdc = decimalFixedPoint('unsigned', 128, 18);\n * rescaleDecimalFixedPoint(evmUsdc('100.123456789012345678'), 64, 6, 'floor');\n * // represents 100.123456\n * ```\n *\n * @see {@link toSignedDecimalFixedPoint}\n * @see {@link toUnsignedDecimalFixedPoint}\n */\nexport function rescaleDecimalFixedPoint<\n    TSignedness extends Signedness,\n    TNewTotalBits extends number,\n    TNewDecimals extends number,\n>(\n    value: DecimalFixedPoint<TSignedness, number, number>,\n    newTotalBits: TNewTotalBits,\n    newDecimals: TNewDecimals,\n    rounding: RoundingMode = 'strict',\n): DecimalFixedPoint<TSignedness, TNewTotalBits, TNewDecimals> {\n    assertValidTotalBits('decimalFixedPoint', newTotalBits);\n    assertValidDecimals(newDecimals);\n    if (value.totalBits === newTotalBits && value.decimals === newDecimals) {\n        return value as DecimalFixedPoint<TSignedness, TNewTotalBits, TNewDecimals>;\n    }\n    let result: bigint;\n    if (newDecimals === value.decimals) {\n        result = value.raw;\n    } else if (newDecimals > value.decimals) {\n        result = value.raw * 10n ** BigInt(newDecimals - value.decimals);\n    } else {\n        result = roundDivision(\n            'decimalFixedPoint',\n            'rescale',\n            value.raw,\n            10n ** BigInt(value.decimals - newDecimals),\n            rounding,\n        );\n    }\n    assertNoArithmeticOverflow('decimalFixedPoint', 'rescale', value.signedness, newTotalBits, result);\n    return Object.freeze({ ...value, decimals: newDecimals, raw: result, totalBits: newTotalBits });\n}\n"
  },
  {
    "path": "packages/fixed-points/src/decimal/core.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO, SolanaError } from '@solana/errors';\n\nimport { assertRawFitsInRange, assertValidDecimals, assertValidTotalBits } from '../assertions';\nimport { parseDecimalString } from '../parsing';\nimport { roundDivision, type RoundingMode } from '../rounding';\nimport type { Signedness } from '../signedness';\n\n/**\n * A fixed-point number whose scale is a power of 10. The stored `raw` bigint\n * represents the mathematical value `raw / 10 ** decimals`.\n *\n * Decimal fixed-point is the natural representation for quantities that\n * users reason about in base-10 terms, such as token amounts, currency, or\n * probabilities with decimal precision.\n *\n * @typeParam TSignedness - Whether the value can be negative.\n * @typeParam TTotalBits - The total number of bits used to store the raw value.\n * @typeParam TDecimals - The number of decimal digits to the right of the decimal point.\n *\n * @example\n * An unsigned 64-bit USDC amount with 6 decimals of precision:\n * ```ts\n * type Usdc = DecimalFixedPoint<'unsigned', 64, 6>;\n * ```\n *\n * @see {@link BinaryFixedPoint}\n * @see {@link Signedness}\n */\nexport type DecimalFixedPoint<TSignedness extends Signedness, TTotalBits extends number, TDecimals extends number> = {\n    readonly decimals: TDecimals;\n    readonly kind: 'decimalFixedPoint';\n    readonly raw: bigint;\n    readonly signedness: TSignedness;\n    readonly totalBits: TTotalBits;\n};\n\nfunction createDecimalFixedPoint<TSignedness extends Signedness, TTotalBits extends number, TDecimals extends number>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    decimals: TDecimals,\n    raw: bigint,\n): DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    assertRawFitsInRange('decimalFixedPoint', signedness, totalBits, raw);\n    return Object.freeze({ decimals, kind: 'decimalFixedPoint', raw, signedness, totalBits });\n}\n\n/**\n * Returns a factory that constructs {@link DecimalFixedPoint} values from\n * decimal strings.\n *\n * The outer call validates the shape parameters once and the returned\n * factory can be called many times to construct values of that shape.\n *\n * If the string carries more precision than the target `decimals` can\n * represent exactly, the returned factory throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` under the\n * default `'strict'` rounding mode. Pass a different {@link RoundingMode}\n * to allow a rounded result.\n *\n * @example\n * ```ts\n * const usdc = decimalFixedPoint('unsigned', 64, 6);\n * usdc('42.5');          // raw === 42500000n\n * usdc('0.0000001');     // throws under the default 'strict' mode\n * usdc('0.0000001', 'round'); // raw === 0n\n * ```\n *\n * @see {@link DecimalFixedPoint}\n * @see {@link rawDecimalFixedPoint}\n * @see {@link ratioDecimalFixedPoint}\n */\nexport function decimalFixedPoint<TSignedness extends Signedness, TTotalBits extends number, TDecimals extends number>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    decimals: TDecimals,\n): (input: string, rounding?: RoundingMode) => DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    assertValidTotalBits('decimalFixedPoint', totalBits);\n    assertValidDecimals(decimals);\n    return (input, rounding = 'strict') => {\n        const parsed = parseDecimalString('decimalFixedPoint', input);\n        const raw =\n            parsed.decimals <= decimals\n                ? parsed.raw * 10n ** BigInt(decimals - parsed.decimals)\n                : roundDivision(\n                      'decimalFixedPoint',\n                      'fromString',\n                      parsed.raw,\n                      10n ** BigInt(parsed.decimals - decimals),\n                      rounding,\n                  );\n        return createDecimalFixedPoint(signedness, totalBits, decimals, raw);\n    };\n}\n\n/**\n * Returns a factory that constructs {@link DecimalFixedPoint} values from a\n * raw bigint in the smallest representable unit (i.e. already scaled by\n * `10 ** decimals`).\n *\n * The outer call validates the shape parameters once and the returned\n * factory can be called many times to construct values of that shape.\n *\n * The raw value is range-checked against the claimed `totalBits` and\n * `signedness`; no rounding is ever required.\n *\n * @example\n * ```ts\n * const cents = rawDecimalFixedPoint('unsigned', 16, 2);\n * cents(425n); // Represents 4.25\n * ```\n *\n * @see {@link DecimalFixedPoint}\n * @see {@link decimalFixedPoint}\n * @see {@link ratioDecimalFixedPoint}\n */\nexport function rawDecimalFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    decimals: TDecimals,\n): (raw: bigint) => DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    assertValidTotalBits('decimalFixedPoint', totalBits);\n    assertValidDecimals(decimals);\n    return raw => createDecimalFixedPoint(signedness, totalBits, decimals, raw);\n}\n\n/**\n * Returns a factory that constructs {@link DecimalFixedPoint} values from\n * a rational `numerator / denominator`.\n *\n * The outer call validates the shape parameters once and the returned\n * factory can be called many times to construct values of that shape.\n *\n * If the ratio cannot be exactly represented at the target `decimals`,\n * the returned factory throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` under the\n * default `'strict'` rounding mode. Pass a different {@link RoundingMode}\n * to allow a rounded result. Zero denominators always throw\n * `SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO`.\n *\n * @example\n * ```ts\n * const probability = ratioDecimalFixedPoint('unsigned', 64, 4);\n * probability(1n, 4n);           // raw === 2500n (0.2500)\n * probability(1n, 3n);           // throws under 'strict'\n * probability(1n, 3n, 'floor');  // raw === 3333n\n * ```\n *\n * @see {@link DecimalFixedPoint}\n * @see {@link decimalFixedPoint}\n * @see {@link rawDecimalFixedPoint}\n */\nexport function ratioDecimalFixedPoint<\n    TSignedness extends Signedness,\n    TTotalBits extends number,\n    TDecimals extends number,\n>(\n    signedness: TSignedness,\n    totalBits: TTotalBits,\n    decimals: TDecimals,\n): (\n    numerator: bigint,\n    denominator: bigint,\n    rounding?: RoundingMode,\n) => DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    assertValidTotalBits('decimalFixedPoint', totalBits);\n    assertValidDecimals(decimals);\n    return (numerator, denominator, rounding = 'strict') => {\n        if (denominator === 0n) {\n            throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_ZERO_DENOMINATOR_RATIO, {\n                denominator,\n                kind: 'decimalFixedPoint',\n                numerator,\n            });\n        }\n        const raw = roundDivision(\n            'decimalFixedPoint',\n            'fromRatio',\n            numerator * 10n ** BigInt(decimals),\n            denominator,\n            rounding,\n        );\n        return createDecimalFixedPoint(signedness, totalBits, decimals, raw);\n    };\n}\n"
  },
  {
    "path": "packages/fixed-points/src/decimal/formatting.ts",
    "content": "import { applyDecimalsOption, type FixedPointToStringOptions, formatScaledBigint } from '../formatting';\nimport type { Signedness } from '../signedness';\nimport type { DecimalFixedPoint } from './core';\n\n/**\n * Returns the canonical decimal string representation of a\n * {@link DecimalFixedPoint}.\n *\n * By default, trailing zeros are trimmed and the decimal point is\n * dropped for whole numbers. Pass `options.decimals` to emit a different\n * number of fractional digits (with {@link RoundingMode} control when\n * scale-down is lossy), and `options.padTrailingZeros` to emit exactly\n * that many digits. When `padTrailingZeros` is set without `decimals`,\n * the output is padded to `value.decimals`.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` when\n * `options.decimals` forces a lossy rescale under the default `'strict'`\n * rounding mode.\n *\n * @example\n * ```ts\n * const usdc = decimalFixedPoint('unsigned', 64, 6);\n * decimalFixedPointToString(usdc('42.5'));                               // \"42.5\"\n * decimalFixedPointToString(usdc('42.5'), { padTrailingZeros: true });   // \"42.500000\"\n * decimalFixedPointToString(usdc('42.678'), { decimals: 2, rounding: 'floor' }); // \"42.67\"\n * ```\n *\n * @see {@link decimalFixedPointToNumber}\n */\nexport function decimalFixedPointToString(\n    value: DecimalFixedPoint<Signedness, number, number>,\n    options?: FixedPointToStringOptions,\n): string {\n    const { decimals, raw } = applyDecimalsOption('decimalFixedPoint', value.raw, value.decimals, options);\n    return formatScaledBigint(raw, decimals, options?.padTrailingZeros ?? false);\n}\n\n/**\n * Formats a {@link DecimalFixedPoint} using a user-supplied\n * `Intl.NumberFormat` instance, preserving full precision regardless of\n * the value's magnitude.\n *\n * Forwards `value.raw` to `formatter.format` using ES2023 string\n * scientific notation (`\"<raw>E-<decimals>\"`). This preserves precision\n * in fully-compliant runtimes and bypasses the JavaScript `number`\n * mantissa limit.\n *\n * Use this when you want locale-aware output, currency formatting,\n * grouping separators, or rounding modes from the rich\n * `Intl.NumberFormat` API. Prefer {@link decimalFixedPointToString} when\n * portability across older runtimes (older Hermes/React Native, etc.) is\n * a concern.\n *\n * @example\n * ```ts\n * const usdc = decimalFixedPoint('unsigned', 64, 6);\n * const formatter = new Intl.NumberFormat('en-US', {\n *     currency: 'USD',\n *     style: 'currency',\n * });\n * formatDecimalFixedPoint(formatter, usdc('1234.5')); // \"$1,234.50\"\n * ```\n *\n * @see {@link decimalFixedPointToString}\n */\nexport function formatDecimalFixedPoint(\n    formatter: Intl.NumberFormat,\n    value: DecimalFixedPoint<Signedness, number, number>,\n): string {\n    return (formatter.format as unknown as (input: string) => string)(`${value.raw}E-${value.decimals}`);\n}\n\n/**\n * Converts a {@link DecimalFixedPoint} to a JavaScript `number`.\n *\n * This conversion is inherently lossy: `1 / 10 ** decimals` is not\n * representable exactly in IEEE 754 for any positive `decimals`, and\n * additional precision is lost when `|value.raw|` exceeds\n * `Number.MAX_SAFE_INTEGER`, since JavaScript numbers have only ~53\n * bits of mantissa.\n *\n * For exact representations prefer {@link decimalFixedPointToString}.\n *\n * @example\n * ```ts\n * const usdc = decimalFixedPoint('unsigned', 64, 6);\n * decimalFixedPointToNumber(usdc('42.5')); // 42.5\n * ```\n *\n * @see {@link decimalFixedPointToString}\n */\nexport function decimalFixedPointToNumber(value: DecimalFixedPoint<Signedness, number, number>): number {\n    return Number(value.raw) / 10 ** value.decimals;\n}\n"
  },
  {
    "path": "packages/fixed-points/src/decimal/guards.ts",
    "content": "import { assertRawFitsInRange, assertRawIsBigint, assertShapeMatches, describeShape } from '../assertions';\nimport type { Signedness } from '../signedness';\nimport type { DecimalFixedPoint } from './core';\n\n/**\n * Asserts that `value` is a {@link DecimalFixedPoint}.\n *\n * Every shape parameter is independently optional. Pass `undefined` (or\n * simply omit trailing arguments) to leave a given field unconstrained.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__SHAPE_MISMATCH` if the value does\n * not match the expected shape, or\n * `SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE` if the `raw` bigint\n * does not fit the claimed signedness and total bits.\n *\n * @example\n * ```ts\n * assertIsDecimalFixedPoint(value);                   // any decimal fixed-point\n * assertIsDecimalFixedPoint(value, 'unsigned');        // any unsigned decimal\n * assertIsDecimalFixedPoint(value, 'unsigned', 64, 6); // fully pinned\n * assertIsDecimalFixedPoint(value, undefined, 64);     // any decimal with totalBits=64\n * ```\n *\n * @see {@link isDecimalFixedPoint}\n * @see {@link DecimalFixedPoint}\n */\nexport function assertIsDecimalFixedPoint<\n    TSignedness extends Signedness = Signedness,\n    TTotalBits extends number = number,\n    TDecimals extends number = number,\n>(\n    value: unknown,\n    signedness?: TSignedness,\n    totalBits?: TTotalBits,\n    decimals?: TDecimals,\n): asserts value is DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    const actual = describeShape(value);\n    const expected = {\n        kind: 'decimalFixedPoint',\n        scale: decimals,\n        scaleLabel: 'decimals',\n        signedness,\n        totalBits,\n    };\n    assertShapeMatches('assertIsDecimalFixedPoint', actual, expected);\n    assertRawIsBigint('decimalFixedPoint', value);\n    assertRawFitsInRange('decimalFixedPoint', actual.signedness as Signedness, actual.totalBits, value.raw);\n}\n\n/**\n * Type guard that refines an unknown value to a {@link DecimalFixedPoint}.\n *\n * Accepts the same partial-positional shape arguments as\n * {@link assertIsDecimalFixedPoint} and returns `true` if the assertion\n * would pass, `false` otherwise.\n *\n * @example\n * ```ts\n * if (isDecimalFixedPoint(value)) {\n *     value satisfies DecimalFixedPoint<Signedness, number, number>;\n * }\n * if (isDecimalFixedPoint(value, 'unsigned', 64, 6)) {\n *     value satisfies DecimalFixedPoint<'unsigned', 64, 6>;\n * }\n * ```\n *\n * @see {@link assertIsDecimalFixedPoint}\n * @see {@link DecimalFixedPoint}\n */\nexport function isDecimalFixedPoint<\n    TSignedness extends Signedness = Signedness,\n    TTotalBits extends number = number,\n    TDecimals extends number = number,\n>(\n    value: unknown,\n    signedness?: TSignedness,\n    totalBits?: TTotalBits,\n    decimals?: TDecimals,\n): value is DecimalFixedPoint<TSignedness, TTotalBits, TDecimals> {\n    try {\n        assertIsDecimalFixedPoint(value, signedness, totalBits, decimals);\n        return true;\n    } catch {\n        return false;\n    }\n}\n"
  },
  {
    "path": "packages/fixed-points/src/decimal/index.ts",
    "content": "export * from './arithmetics';\nexport * from './codecs';\nexport * from './comparisons';\nexport * from './conversions';\nexport * from './core';\nexport * from './formatting';\nexport * from './guards';\n"
  },
  {
    "path": "packages/fixed-points/src/formatting.ts",
    "content": "import { roundDivision, type RoundingMode } from './rounding';\n\n/**\n * Options accepted by `binaryFixedPointToString` and\n * `decimalFixedPointToString` to control the emitted representation.\n *\n * - `decimals`: caps the number of fractional digits in the output. When\n *   this is lower than the value's native precision the raw value is\n *   rescaled using `rounding` (defaults to `'strict'`, which throws\n *   `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` on inexact\n *   results). When higher, the extra precision is zero-padded only if\n *   `padTrailingZeros` is also set.\n * - `padTrailingZeros`: emits exactly as many fractional digits as\n *   requested by `decimals`. When `decimals` is omitted, pads to the\n *   value's native scale (`decimals` for decimal values,\n *   `fractionalBits` for binary values — the length of the exact\n *   base-10 expansion). Defaults to `false`, which trims trailing zeros\n *   (and drops the decimal point altogether for whole numbers).\n * - `rounding`: only consulted when `decimals` forces a scale-down.\n *   Defaults to `'strict'`.\n */\nexport type FixedPointToStringOptions = {\n    decimals?: number;\n    padTrailingZeros?: boolean;\n    rounding?: RoundingMode;\n};\n\n/**\n * Rescales `raw` from `currentDecimals` decimal digits to `options.decimals`\n * decimal digits (when set), respecting `options.rounding`. Returns the\n * raw value to format and the number of fractional digits implied by it.\n *\n * @internal\n */\nexport function applyDecimalsOption(\n    kind: 'binaryFixedPoint' | 'decimalFixedPoint',\n    raw: bigint,\n    currentDecimals: number,\n    options: FixedPointToStringOptions | undefined,\n): { decimals: number; raw: bigint } {\n    const targetDecimals = options?.decimals;\n    if (targetDecimals === undefined || targetDecimals === currentDecimals) {\n        return { decimals: currentDecimals, raw };\n    }\n    if (targetDecimals > currentDecimals) {\n        return {\n            decimals: targetDecimals,\n            raw: raw * 10n ** BigInt(targetDecimals - currentDecimals),\n        };\n    }\n    const divisor = 10n ** BigInt(currentDecimals - targetDecimals);\n    const rescaled = roundDivision(kind, 'toString', raw, divisor, options?.rounding ?? 'strict');\n    return { decimals: targetDecimals, raw: rescaled };\n}\n\n/**\n * Formats a scaled bigint `(raw, decimals)` as a canonical decimal\n * string. When `padTrailingZeros` is `true`, the output emits exactly\n * `decimals` fractional digits; otherwise trailing zeros are trimmed and\n * the decimal point is dropped if the fractional part becomes empty.\n *\n * @internal\n */\nexport function formatScaledBigint(raw: bigint, decimals: number, padTrailingZeros: boolean): string {\n    if (decimals === 0) {\n        return raw.toString();\n    }\n    const isNegative = raw < 0n;\n    const absDigits = (isNegative ? -raw : raw).toString();\n    const padded = absDigits.padStart(decimals + 1, '0');\n    const integerPart = padded.slice(0, -decimals);\n    let fractionalPart = padded.slice(-decimals);\n    if (!padTrailingZeros) {\n        fractionalPart = fractionalPart.replace(/0+$/, '');\n    }\n    const sign = isNegative ? '-' : '';\n    if (fractionalPart.length === 0) {\n        return `${sign}${integerPart}`;\n    }\n    return `${sign}${integerPart}.${fractionalPart}`;\n}\n"
  },
  {
    "path": "packages/fixed-points/src/index.ts",
    "content": "/**\n * This package provides fixed-point number types — both decimal (scale is a\n * power of 10) and binary (scale is a power of 2) — in signed and unsigned\n * flavors with arbitrary bit widths. It can be used standalone, but it is also\n * exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * This package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs)\n * which acts as an entry point for all codec packages as well as for their documentation.\n *\n * @packageDocumentation\n */\nexport * from './binary';\nexport type { FixedPointCodecConfig } from './codecs';\nexport * from './decimal';\nexport type { FixedPointToStringOptions } from './formatting';\nexport type { RoundingMode } from './rounding';\nexport * from './signedness';\n"
  },
  {
    "path": "packages/fixed-points/src/parsing.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__INVALID_STRING, SolanaError } from '@solana/errors';\n\n/**\n * Parses a human-readable decimal string into a decimal fixed-point\n * representation `{ raw, decimals }` such that the parsed value is exactly\n * `raw / 10 ** decimals`.\n *\n * Accepts strings of the form:\n * - `\"123\"`, `\"-123\"`\n * - `\"12.5\"`, `\"-0.25\"`\n * - `\".5\"`, `\"-.5\"`, `\"5.\"`\n *\n * Rejects scientific notation, leading `+`, whitespace, and any other\n * non-digit / non-sign / non-decimal-point characters.\n *\n * Throws `SOLANA_ERROR__FIXED_POINTS__INVALID_STRING` for malformed input.\n *\n * @internal\n */\nexport function parseDecimalString(\n    kind: 'binaryFixedPoint' | 'decimalFixedPoint',\n    input: string,\n): { decimals: number; raw: bigint } {\n    if (typeof input !== 'string' || !/^-?(?:\\d+\\.?\\d*|\\.\\d+)$/.test(input)) {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__INVALID_STRING, {\n            input: String(input),\n            kind,\n        });\n    }\n    const isNegative = input.startsWith('-');\n    const unsigned = isNegative ? input.slice(1) : input;\n    const dotIndex = unsigned.indexOf('.');\n    let integerPart: string;\n    let fractionalPart: string;\n    if (dotIndex === -1) {\n        integerPart = unsigned;\n        fractionalPart = '';\n    } else {\n        integerPart = unsigned.slice(0, dotIndex);\n        fractionalPart = unsigned.slice(dotIndex + 1);\n    }\n    const digits = (integerPart || '0') + fractionalPart;\n    const rawAbs = BigInt(digits);\n    const raw = isNegative ? -rawAbs : rawAbs;\n    return { decimals: fractionalPart.length, raw };\n}\n"
  },
  {
    "path": "packages/fixed-points/src/rounding.ts",
    "content": "import { SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, SolanaError } from '@solana/errors';\n\n/**\n * Rounding mode used by fixed-point operations that must coerce an exact\n * mathematical result into a value with fewer bits of precision. Applies to\n * factories that accept lossy inputs, as well as to downscaling rescales and\n * divisions.\n *\n * - `'floor'` rounds toward negative infinity.\n * - `'ceil'` rounds toward positive infinity.\n * - `'trunc'` rounds toward zero, discarding the fractional part.\n * - `'round'` rounds to the nearest representable value, with ties rounded\n *   away from zero. That is, `0.5` rounds to `1`, `-0.5` rounds to `-1`, and\n *   `-1.5` rounds to `-2`. This is symmetric around zero and differs from\n *   JavaScript's `Math.round`, which breaks ties toward positive infinity.\n * - `'strict'` rejects any input that would require rounding and throws\n *   `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` instead of\n *   coercing the result.\n */\nexport type RoundingMode = 'ceil' | 'floor' | 'round' | 'strict' | 'trunc';\n\n/**\n * Divides `numerator` by `denominator` and rounds the quotient according to\n * the given {@link RoundingMode}.\n *\n * If the division is exact, the quotient is returned unchanged regardless\n * of the rounding mode. Otherwise, `'strict'` throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` and the other\n * modes round as documented on {@link RoundingMode}.\n *\n * The helper handles negative numerators and denominators correctly and\n * assumes `denominator !== 0n` — callers must check for and report\n * division-by-zero before invoking this function.\n *\n * @internal\n */\nexport function roundDivision(\n    kind: 'binaryFixedPoint' | 'decimalFixedPoint',\n    operation: string,\n    numerator: bigint,\n    denominator: bigint,\n    mode: RoundingMode,\n): bigint {\n    const quotient = numerator / denominator;\n    const remainder = numerator - quotient * denominator;\n    if (remainder === 0n) {\n        return quotient;\n    }\n    if (mode === 'strict') {\n        throw new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n            kind,\n            operation,\n        });\n    }\n    const sameSign = numerator < 0n === denominator < 0n;\n    if (mode === 'trunc') {\n        return quotient;\n    }\n    if (mode === 'floor') {\n        return sameSign ? quotient : quotient - 1n;\n    }\n    if (mode === 'ceil') {\n        return sameSign ? quotient + 1n : quotient;\n    }\n    // 'round': ties away from zero.\n    const absRemainderDoubled = (remainder < 0n ? -remainder : remainder) * 2n;\n    const absDenominator = denominator < 0n ? -denominator : denominator;\n    if (absRemainderDoubled < absDenominator) {\n        return quotient;\n    }\n    return sameSign ? quotient + 1n : quotient - 1n;\n}\n"
  },
  {
    "path": "packages/fixed-points/src/signedness.ts",
    "content": "/**\n * Whether a fixed-point number can represent negative values.\n *\n * - `'signed'` fixed-point numbers use two's-complement semantics and can\n *   represent both negative and non-negative values.\n * - `'unsigned'` fixed-point numbers can only represent non-negative values\n *   but get one extra bit of positive range.\n *\n * @see {@link BinaryFixedPoint}\n * @see {@link DecimalFixedPoint}\n */\nexport type Signedness = 'signed' | 'unsigned';\n"
  },
  {
    "path": "packages/fixed-points/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/fixed-points/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2019\"]\n    },\n    \"display\": \"@solana/fixed-points\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/fixed-points/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/fs-impl/.gitignore",
    "content": "dist/\n"
  },
  {
    "path": "packages/fs-impl/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/fs-impl/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/fs-impl/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/fs-impl/package.json",
    "content": "{\n    \"name\": \"@solana/fs-impl\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"exports\": {\n        \"edge-light\": {\n            \"types\": \"./dist/types/index.node.d.ts\",\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"workerd\": {\n            \"types\": \"./dist/types/index.node.d.ts\",\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"browser\": {\n            \"types\": \"./dist/types/index.node.d.ts\",\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"types\": \"./dist/types/index.node.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        }\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"types\": \"./dist/types/index.node.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\"\n    ],\n    \"sideEffects\": false,\n    \"scripts\": {\n        \"compile:js\": \"tsup\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/fs-impl/src/index.browser.ts",
    "content": "import type * as fs from 'node:fs/promises';\nimport type * as path from 'node:path';\n\nimport { SOLANA_ERROR__FS__UNSUPPORTED_ENVIRONMENT, SolanaError } from '@solana/errors';\n\nfunction throwUnsupported(operation: string): never {\n    throw new SolanaError(SOLANA_ERROR__FS__UNSUPPORTED_ENVIRONMENT, { operation });\n}\n\nexport const mkdir = ((..._args: Parameters<typeof fs.mkdir>) => throwUnsupported('mkdir')) as typeof fs.mkdir;\nexport const writeFile = ((..._args: Parameters<typeof fs.writeFile>) =>\n    throwUnsupported('writeFile')) as typeof fs.writeFile;\nexport const dirname = ((..._args: Parameters<typeof path.dirname>) =>\n    throwUnsupported('dirname')) as typeof path.dirname;\n"
  },
  {
    "path": "packages/fs-impl/src/index.node.ts",
    "content": "export { mkdir, writeFile } from 'node:fs/promises';\nexport { dirname } from 'node:path';\n"
  },
  {
    "path": "packages/fs-impl/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"isolatedModules\": false,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.node.ts\"]\n}\n"
  },
  {
    "path": "packages/fs-impl/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"ES2022\"]\n    },\n    \"display\": \"Filesystem Implementation\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/fs-impl/tsup.config.ts",
    "content": "import { defineConfig } from 'tsup';\n\nexport default defineConfig(_options =>\n    (['browser', 'node'] as const).map(platform => ({\n        entry: [`./src/index.${platform}.ts`],\n        format: ['cjs', 'esm'],\n        minify: true,\n        name: platform,\n        outExtension({ format }) {\n            return { js: `.${format === 'cjs' ? 'cjs' : 'mjs'}` };\n        },\n        platform,\n        sourcemap: true,\n        treeshake: true,\n    })),\n);\n"
  },
  {
    "path": "packages/functional/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/functional/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/functional/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/functional/CHANGELOG.md",
    "content": "# @solana/functional\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n## 6.6.0\n\n## 6.5.0\n\n## 6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n## 6.1.0\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n## 5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n## 5.3.0\n\n## 5.2.0\n\n## 5.1.0\n\n## 5.0.0\n\n## 4.0.0\n\n## 3.0.0\n\n## 2.3.0\n\n## 2.2.1\n\n## 2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n## 2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n## 2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n"
  },
  {
    "path": "packages/functional/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/functional/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/functional?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/functional?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/functional\n\n# @solana/functional\n\nThis package contains generalized functional helpers and functional helpers specific to Solana application components. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Functions\n\n### `pipe()`\n\nA pipeline is a solution that allows you to perform successive transforms of a value using functions. This is useful when building up a transaction message.\n\nUntil the [pipeline operator](https://github.com/tc39/proposal-pipeline-operator) becomes part of JavaScript you can use this utility to create pipelines.\n\n```ts\nconst add = (a, b) => a + b;\nconst add10 = x => add(x, 10);\nconst add100 = x => add(x, 100);\nconst sum = pipe(1, add10, add100);\nsum === 111; // true\n```\n\n```ts\nconst transferTransactionMessage = pipe(\n    // The result of the first expression...\n    createTransactionMessage({ version: 0 }),\n    // ...gets passed as the sole argument to the next function in the pipeline.\n    tx => setTransactionMessageFeePayer(myAddress, tx),\n    // The return value of that function gets passed to the next...\n    tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n    // ...and so on.\n    tx => appendTransactionMessageInstruction(getTransferSolInstruction({ source, destination, amount }), tx),\n);\n```\n"
  },
  {
    "path": "packages/functional/package.json",
    "content": "{\n    \"name\": \"@solana/functional\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Functional JavaScript helpers\",\n    \"homepage\": \"https://www.solanakit.com/api#solanafunctional\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/functional/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/functional/src/__tests__/pipe-test.ts",
    "content": "import { pipe } from '../pipe';\n\ndescribe('pipe', () => {\n    it('can pipe a single value', () => {\n        expect(pipe(true)).toBe(true);\n        expect(pipe('test')).toBe('test');\n        expect(pipe(1)).toBe(1);\n        expect(pipe(3n)).toBe(3n);\n        expect(pipe(null)).toBeNull();\n        expect(pipe(undefined)).toBeUndefined();\n    });\n    it('can pipe a single function', () => {\n        expect(pipe('test', value => value.toUpperCase())).toBe('TEST');\n    });\n    it('can pipe multiple functions', () => {\n        expect(\n            pipe(\n                'test',\n                value => value.toUpperCase(),\n                value => value + '!',\n                value => value.repeat(3),\n            ),\n        ).toBe('TEST!TEST!TEST!');\n        expect(\n            pipe(\n                1,\n                value => value + 1,\n                value => value + 2,\n                value => value + 3,\n            ),\n        ).toBe(7);\n        expect(\n            pipe(\n                1,\n                value => value + 1,\n                value => value * 2,\n                value => value - 1,\n            ),\n        ).toBe(3);\n    });\n    it('can pipe multiple functions with different types', () => {\n        expect(\n            pipe(\n                1,\n                value => value + 1,\n                value => value.toString(),\n                value => value + '!',\n            ),\n        ).toBe('2!');\n        expect(\n            pipe(\n                'test',\n                value => value.toUpperCase(),\n                value => value.length,\n                value => value + 1,\n            ),\n        ).toBe(5);\n        expect(\n            pipe(\n                1,\n                value => value + 1,\n                value => value * 2,\n                value => value - 1,\n                value => value.toString(),\n                value => value + '!',\n            ),\n        ).toBe('3!');\n    });\n    describe('mutating objects', () => {\n        it('will not mutate an object directly', () => {\n            const startObj = {\n                hello: 'world',\n            };\n            const endObj = pipe(startObj, obj => {\n                obj.hello = 'there';\n                return obj;\n            });\n            expect(startObj).toBe(endObj);\n        });\n        it('will mutate a cloned object', () => {\n            const startObj = {\n                hello: 'world',\n            };\n            const endObj = pipe(startObj, obj => {\n                const newObj = { ...obj, hello: 'there' };\n                return newObj;\n            });\n            expect(endObj).toMatchObject({ hello: 'there' });\n        });\n    });\n    describe('combining objects', () => {\n        function combine<T extends object, U extends object>(a: T, b: U): T & U {\n            return { ...a, ...b };\n        }\n        it('can combine two objects', () => {\n            expect(pipe({ a: 1 }, value => combine(value, { b: 2 }))).toEqual({ a: 1, b: 2 });\n        });\n        it('can combine four objects', () => {\n            expect(\n                pipe(\n                    { a: 1 },\n                    value => combine(value, { b: 2 }),\n                    value => combine(value, { c: 3 }),\n                    value => combine(value, { d: 4 }),\n                ),\n            ).toEqual({ a: 1, b: 2, c: 3, d: 4 });\n        });\n    });\n    describe('combining arrays', () => {\n        function combine<T>(a: T[], b: T[]): T[] {\n            return [...a, ...b];\n        }\n        it('can combine two arrays', () => {\n            expect(pipe([1], value => combine(value, [2]))).toEqual([1, 2]);\n        });\n        it('can combine four arrays', () => {\n            expect(\n                pipe(\n                    [1],\n                    value => combine(value, [2]),\n                    value => combine(value, [3]),\n                    value => combine(value, [4]),\n                ),\n            ).toEqual([1, 2, 3, 4]);\n        });\n    });\n    describe('combining strings', () => {\n        function combine(a: string, b: string): string {\n            return a + b;\n        }\n        it('can combine two strings', () => {\n            expect(pipe('a', value => combine(value, 'b'))).toBe('ab');\n        });\n        it('can combine four strings', () => {\n            expect(\n                pipe(\n                    'a',\n                    value => combine(value, 'b'),\n                    value => combine(value, 'c'),\n                    value => combine(value, 'd'),\n                ),\n            ).toBe('abcd');\n        });\n    });\n    describe('appending or creating arrays on objects', () => {\n        function addOrAppend(obj: { a: number; b?: string; c?: boolean; d?: string[] }, value: string) {\n            if (obj.d) {\n                return { ...obj, d: [...obj.d, value] };\n            } else {\n                return { ...obj, d: [value] };\n            }\n        }\n        function dropArray(obj: { a: number; b?: string; c?: boolean; d?: string[] }) {\n            if (obj.d) {\n                // eslint-disable-next-line @typescript-eslint/no-unused-vars\n                const { d, ...rest } = obj;\n                return rest;\n            } else {\n                return obj;\n            }\n        }\n        it('can create the array', () => {\n            expect(pipe({ a: 1 }, value => addOrAppend(value, 'test'))).toEqual({ a: 1, d: ['test'] });\n        });\n        it('can append to the array', () => {\n            expect(pipe({ a: 1, d: ['test'] }, value => addOrAppend(value, 'test'))).toEqual({\n                a: 1,\n                d: ['test', 'test'],\n            });\n        });\n        it('can create and append to the array', () => {\n            expect(\n                pipe(\n                    { a: 1, b: 'test' },\n                    value => addOrAppend(value, 'test'),\n                    value => addOrAppend(value, 'test again'),\n                ),\n            ).toEqual({\n                a: 1,\n                b: 'test',\n                d: ['test', 'test again'],\n            });\n        });\n        it('can create and append to the array multiple times', () => {\n            expect(\n                pipe(\n                    { a: 1, b: 'test' },\n                    value => addOrAppend(value, 'test'),\n                    value => addOrAppend(value, 'test again'),\n                    value => addOrAppend(value, 'test again'),\n                    value => addOrAppend(value, 'test again'),\n                ),\n            ).toEqual({\n                a: 1,\n                b: 'test',\n                d: ['test', 'test again', 'test again', 'test again'],\n            });\n        });\n        it('can create the array, do some other operations, then append to the array', () => {\n            expect(\n                pipe(\n                    { a: 1, b: 'test' },\n                    value => addOrAppend(value, 'test'),\n                    value => addOrAppend(value, 'test again'),\n                    value => ({ ...value, b: value.b + '!' }),\n                    value => addOrAppend(value, 'test again'),\n                ),\n            ).toEqual({\n                a: 1,\n                b: 'test!',\n                d: ['test', 'test again', 'test again'],\n            });\n        });\n        it('can create the array, append to it, do some other operations, then drop it', () => {\n            expect(\n                pipe(\n                    { a: 1, b: 'test' },\n                    value => addOrAppend(value, 'test'),\n                    value => addOrAppend(value, 'test again'),\n                    value => ({ ...value, b: value.b + '!' }),\n                    value => dropArray(value),\n                ),\n            ).toEqual({\n                a: 1,\n                b: 'test!',\n            });\n        });\n        it('can create the array, append to it, do some other operations, then drop it, then create/append to it again', () => {\n            expect(\n                pipe(\n                    { a: 1, b: 'test' },\n                    value => addOrAppend(value, 'test'),\n                    value => addOrAppend(value, 'test again'),\n                    value => ({ ...value, b: value.b + '!' }),\n                    value => dropArray(value),\n                    value => addOrAppend(value, 'test again'),\n                ),\n            ).toEqual({\n                a: 1,\n                b: 'test!',\n                d: ['test again'],\n            });\n        });\n    });\n    describe('capturing errors', () => {\n        function throws(_a: string): string {\n            throw new Error('test error');\n        }\n        it('can capture errors', () => {\n            expect(() => pipe('init', throws)).toThrow('test error');\n        });\n        it('can capture errors with multiple throws', () => {\n            expect(() => pipe('init', throws, throws, throws)).toThrow('test error');\n        });\n        it('can capture errors when throw occurs early in pipe', () => {\n            expect(() =>\n                pipe(\n                    'init',\n                    throws,\n                    value => value.toUpperCase(),\n                    value => value + '!',\n                    value => value.repeat(3),\n                ),\n            ).toThrow('test error');\n        });\n    });\n    describe('nested pipes', () => {\n        it('can pipe a single value from a nested pipe of a single value', () => {\n            expect(pipe(pipe(pipe(1)))).toBe(1);\n        });\n        it('can pipe a single value from a nested pipe of multiple functions', () => {\n            expect(\n                pipe(\n                    pipe(\n                        pipe(\n                            1,\n                            value => value + 1,\n                            value => value * 2,\n                            value => value - 1,\n                        ),\n                    ),\n                ),\n            ).toBe(3);\n        });\n        it('can pipe multiple functions on a nested pipe of multiple functions', () => {\n            expect(\n                pipe(\n                    pipe(\n                        pipe(\n                            1,\n                            value => value + 1,\n                            value => value * 2,\n                            value => value - 1,\n                        ),\n                    ),\n                    value => value.toString(),\n                    value => value + '!',\n                ),\n            ).toBe('3!');\n        });\n        it('can pipe an initial value through multiple functions, apply a nested pipe of multiple functions, then apply more functions', () => {\n            expect(\n                pipe(\n                    1,\n                    value => value + 1,\n                    value => value * 2,\n                    value => value - 1,\n                    value =>\n                        pipe(\n                            value,\n                            value => value.toString(),\n                            value => value + '!',\n                        ),\n                    value => value + '##',\n                    value => value.repeat(2),\n                ),\n            ).toBe('3!##3!##');\n        });\n    });\n    it('can pipe an initial object through multiple functions, apply a nested pipe of multiple functions, then apply more functions', () => {\n        expect(\n            pipe(\n                { a: 1 },\n                value => ({ ...value, b: 2 }),\n                value => ({ ...value, c: 3 }),\n                value => ({ ...value, d: 4 }),\n                value =>\n                    pipe(\n                        value,\n                        value => ({ ...value, e: 5 }),\n                        value => ({ ...value, f: 6 }),\n                        value => ({ ...value, g: 7 }),\n                    ),\n                value => ({ ...value, h: 8 }),\n                value => ({ ...value, i: 9 }),\n                value => ({ ...value, j: 10 }),\n            ),\n        ).toEqual({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10 });\n    });\n    it('can pipe an initial object through multiple functions, apply a nested pipe of multiple functions to one field, then apply more functions', () => {\n        expect(\n            pipe(\n                { a: 1 },\n                value => ({ ...value, b: 2 }),\n                value => ({ ...value, c: 3 }),\n                value => ({\n                    ...value,\n                    d: pipe(\n                        [] as string[],\n                        d => {\n                            d.push('test');\n                            return d;\n                        },\n                        d => {\n                            d.push('test again');\n                            return d;\n                        },\n                        d => {\n                            d.push('test a third time');\n                            return d;\n                        },\n                    ),\n                }),\n                value => ({ ...value, e: 5 }),\n                value => ({ ...value, f: 6 }),\n                value => ({ ...value, g: 7 }),\n            ),\n        ).toEqual({\n            a: 1,\n            b: 2,\n            c: 3,\n            d: ['test', 'test again', 'test a third time'],\n            e: 5,\n            f: 6,\n            g: 7,\n        });\n    });\n});\n"
  },
  {
    "path": "packages/functional/src/__typetests__/pipe-typetest.ts",
    "content": "import { pipe } from '../pipe';\n\nfunction assertNotAProperty<T extends object, TPropName extends string>(\n    _: { [Prop in keyof T]: Prop extends TPropName ? never : T[Prop] },\n    _propName: TPropName,\n): void {}\n\n// Single-value primitives\n{\n    const value = pipe(true);\n    value satisfies boolean;\n}\n{\n    const value = pipe('test');\n    value satisfies string;\n}\n{\n    const value = pipe(1);\n    value satisfies number;\n}\n{\n    const value = pipe(3n);\n    value satisfies bigint;\n}\n{\n    const value = pipe(null);\n    value satisfies null;\n}\n{\n    const value = pipe(undefined);\n    value satisfies undefined;\n}\n\n// Single-value objects\n{\n    const value = pipe({});\n    value satisfies Record<never, never>;\n}\n{\n    const value = pipe({ a: 1 });\n    value satisfies { a: number };\n}\n{\n    const value = pipe({ a: 1, b: 'test' });\n    value satisfies { a: number; b: string };\n}\n{\n    const value = pipe({ a: 1, b: 'test', c: true });\n    value satisfies { a: number; b: string; c: boolean };\n}\n\n// Single-value arrays\n{\n    const value = pipe([]);\n    value satisfies never[];\n}\n{\n    // TypeScript will infer this as an array\n    const value = pipe([1]);\n    value satisfies number[];\n}\n{\n    // TypeScript will infer this as an array\n    const value = pipe([1, 'test']);\n    value satisfies (number | string)[];\n}\n{\n    // TypeScript will infer this as an array\n    const value = pipe([1, 'test', true]);\n    value satisfies (boolean | number | string)[];\n}\n\n// Single-value tuples\n{\n    const value = pipe([1] as [number]);\n    value satisfies [number];\n}\n{\n    const value = pipe([1, 'test'] as [number, string]);\n    value satisfies [number, string];\n}\n{\n    const value = pipe([1, 'test', true] as [number, string, boolean]);\n    value satisfies [number, string, boolean];\n}\n\n// Functions that operate on primitives\n{\n    const value = pipe(true, value => !value);\n    value satisfies boolean;\n}\n{\n    const value = pipe('test', value => value.toUpperCase());\n    value satisfies string;\n}\n{\n    const value = pipe(1, value => value + 1);\n    value satisfies number;\n}\n{\n    const value = pipe(3n, value => value + 1n);\n    value satisfies bigint;\n}\n{\n    const value = pipe(null, value => value);\n    value satisfies null;\n}\n{\n    const value = pipe(undefined, value => value);\n    value satisfies undefined;\n}\n\n// Functions that change primitives to new types\n{\n    const value = pipe(1, value => value.toString());\n    value satisfies string;\n}\n{\n    const value = pipe('test', value => value.length);\n    value satisfies number;\n}\n{\n    const value = pipe(\n        1,\n        value => value.toString(),\n        value => value + '!',\n    );\n    value satisfies string;\n}\n{\n    const value = pipe(\n        'test',\n        value => value.length,\n        value => value + 1,\n    );\n    value satisfies number;\n}\n\n// Functions that operate on objects\n{\n    const value = pipe({}, value => value);\n    value satisfies Record<never, never>;\n}\n{\n    const value = pipe({ a: 1 }, value => value);\n    value satisfies { a: number };\n}\n{\n    const value = pipe({ a: 1, b: 'test' }, value => value);\n    value satisfies { a: number; b: string };\n}\n{\n    const value = pipe({ a: 1, b: 'test', c: true }, value => value);\n    value satisfies { a: number; b: string; c: boolean };\n}\n\n// Functions that change objects to new types\n{\n    const value = pipe({ a: 1 }, value => value.a);\n    value satisfies number;\n}\n{\n    const value = pipe({ a: 1 }, value => value.a.toString());\n    value satisfies string;\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => value.a,\n        value => value + 1,\n    );\n    value satisfies number;\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => value.a.toString(),\n        value => value + '!',\n    );\n    value satisfies string;\n}\n\n// Functions that change objects to new objects\n{\n    const value = pipe({ a: 1 }, value => ({ b: value.a }));\n    value satisfies { b: number };\n}\n{\n    const value = pipe({ a: 1 }, value => ({ b: value.a.toString() }));\n    value satisfies { b: string };\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => ({ b: value.a }),\n        value => ({ c: value.b }),\n    );\n    value satisfies { c: number };\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => ({ b: value.a.toString() }),\n        value => ({ c: value.b }),\n    );\n    value satisfies { c: string };\n}\n\n// Functions that combine objects\n{\n    const value = pipe({ a: 1 }, value => ({ ...value, b: 2 }));\n    value satisfies { a: number; b: number };\n}\n{\n    const value = pipe({ a: 1 }, value => ({ ...value, b: 'test' }));\n    value satisfies { a: number; b: string };\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => ({ ...value, b: 2 }),\n        value => ({ ...value, c: true }),\n    );\n    value satisfies { a: number; b: number; c: boolean };\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => ({ ...value, b: 'test' }),\n        value => ({ ...value, c: true }),\n    );\n    value satisfies { a: number; b: string; c: boolean };\n}\n\n// Functions that append or create arrays on objects\nfunction addOrAppend(obj: { a: number; b?: string; c?: boolean; d?: string[] }, value: string) {\n    if (obj.d) {\n        return { ...obj, d: [...obj.d, value] };\n    } else {\n        return { ...obj, d: [value] };\n    }\n}\nfunction dropArray(obj: { a: number; b?: string; c?: boolean; d?: string[] }) {\n    if (obj.d) {\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        const { d, ...rest } = obj;\n        return rest;\n    } else {\n        return obj;\n    }\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => ({ ...value, b: 'test' }),\n        value => ({ ...value, c: true }),\n        value => addOrAppend(value, 'test'),\n    );\n    value satisfies { a: number; b?: string; c?: boolean; d: string[] };\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => ({ ...value, b: 'test' }),\n        value => ({ ...value, c: true }),\n        value => addOrAppend(value, 'test'),\n        value => addOrAppend(value, 'test again'),\n        value => addOrAppend(value, 'test a third time'),\n    );\n    value satisfies { a: number; b?: string; c?: boolean; d: string[] };\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => addOrAppend(value, 'test'),\n        value => ({ ...value, b: 'test' }),\n        value => ({ ...value, c: true }),\n    );\n    value satisfies { a: number; b?: string; c?: boolean; d: string[] };\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => addOrAppend(value, 'test'),\n        value => addOrAppend(value, 'test again'),\n        value => ({ ...value, b: 'test' }),\n        value => ({ ...value, c: true }),\n        value => dropArray(value),\n    );\n    value satisfies { a: number; b?: string; c?: boolean };\n    assertNotAProperty(value, 'd');\n}\n\n// Nested pipes\n{\n    const value = pipe(\n        { a: 1 },\n        value => ({ ...value, b: 'test' }),\n        value => ({ ...value, c: true }),\n        value => ({ ...value, d: pipe({}, value => ({ ...value, e: 1 })) }),\n    );\n    value satisfies { a: number; b?: string; c?: boolean; d: { e: number } };\n}\n{\n    const value = pipe(\n        { a: 1 },\n        value => ({ ...value, b: 'test' }),\n        value => ({ ...value, c: true }),\n        value => ({ ...value, d: pipe({}, value => ({ ...value, e: 1 })) }),\n        value => ({ ...value, d: pipe(value.d, value => ({ ...value, f: 'test' })) }),\n    );\n    value satisfies { a: number; b?: string; c?: boolean; d: { e: number; f: string } };\n}\n"
  },
  {
    "path": "packages/functional/src/index.ts",
    "content": "/**\n * This package contains generalized functional helpers and functional helpers specific to Solana application components. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n * @packageDocumentation\n */\nexport * from './pipe';\n"
  },
  {
    "path": "packages/functional/src/pipe.ts",
    "content": "/**\n * A pipeline is a solution that allows you to perform successive transforms of a value using functions. This is useful when building up a transaction message.\n *\n * Until the [pipeline operator](https://github.com/tc39/proposal-pipeline-operator) becomes part of JavaScript you can use this utility to create pipelines.\n *\n * Following common implementations of pipe functions that use TypeScript, this function supports a maximum arity of 10 for type safety.\n *\n * Note you can use nested pipes to extend this limitation, like so:\n * ```ts\n * const myValue = pipe(\n *      pipe(\n *          1,\n *          (x) => x + 1,\n *          (x) => x * 2,\n *          (x) => x - 1,\n *      ),\n *      (y) => y / 3,\n *      (y) => y + 1,\n * );\n * ```\n *\n * @see https://github.com/ramda/ramda/blob/master/source/pipe.js\n * @see https://github.com/darky/rocket-pipes/blob/master/index.ts\n *\n * @example Basic\n * ```ts\n * const add = (a, b) => a + b;\n * const add10 = x => add(x, 10);\n * const add100 = x => add(x, 100);\n * const sum = pipe(1, add10, add100);\n * sum === 111; // true\n * ```\n *\n * @example Building a Solana transaction message\n * ```ts\n * const transferTransactionMessage = pipe(\n *     // The result of the first expression...\n *     createTransactionMessage({ version: 0 }),\n *     // ...gets passed as the sole argument to the next function in the pipeline.\n *     tx => setTransactionMessageFeePayer(myAddress, tx),\n *     // The return value of that function gets passed to the next...\n *     tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),\n *     // ...and so on.\n *     tx => appendTransactionMessageInstruction(createTransferInstruction(myAddress, toAddress, amountInLamports), tx),\n * );\n * ```\n *\n * @returns The initial value\n */\nexport function pipe<TInitial>(\n    /** The initial value */\n    init: TInitial,\n): TInitial;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n): R1;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n): R2;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2, R3>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n    /** The function with which to transform the return value of the prior function */\n    r2_r3: (r2: R2) => R3,\n): R3;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2, R3, R4>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n    /** The function with which to transform the return value of the prior function */\n    r2_r3: (r2: R2) => R3,\n    /** The function with which to transform the return value of the prior function */\n    r3_r4: (r3: R3) => R4,\n): R4;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2, R3, R4, R5>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n    /** The function with which to transform the return value of the prior function */\n    r2_r3: (r2: R2) => R3,\n    /** The function with which to transform the return value of the prior function */\n    r3_r4: (r3: R3) => R4,\n    /** The function with which to transform the return value of the prior function */\n    r4_r5: (r4: R4) => R5,\n): R5;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2, R3, R4, R5, R6>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n    /** The function with which to transform the return value of the prior function */\n    r2_r3: (r2: R2) => R3,\n    /** The function with which to transform the return value of the prior function */\n    r3_r4: (r3: R3) => R4,\n    /** The function with which to transform the return value of the prior function */\n    r4_r5: (r4: R4) => R5,\n    /** The function with which to transform the return value of the prior function */\n    r5_r6: (r5: R5) => R6,\n): R6;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2, R3, R4, R5, R6, R7>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n    /** The function with which to transform the return value of the prior function */\n    r2_r3: (r2: R2) => R3,\n    /** The function with which to transform the return value of the prior function */\n    r3_r4: (r3: R3) => R4,\n    /** The function with which to transform the return value of the prior function */\n    r4_r5: (r4: R4) => R5,\n    /** The function with which to transform the return value of the prior function */\n    r5_r6: (r5: R5) => R6,\n    /** The function with which to transform the return value of the prior function */\n    r6_r7: (r6: R6) => R7,\n): R7;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2, R3, R4, R5, R6, R7, R8>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n    /** The function with which to transform the return value of the prior function */\n    r2_r3: (r2: R2) => R3,\n    /** The function with which to transform the return value of the prior function */\n    r3_r4: (r3: R3) => R4,\n    /** The function with which to transform the return value of the prior function */\n    r4_r5: (r4: R4) => R5,\n    /** The function with which to transform the return value of the prior function */\n    r5_r6: (r5: R5) => R6,\n    /** The function with which to transform the return value of the prior function */\n    r6_r7: (r6: R6) => R7,\n    /** The function with which to transform the return value of the prior function */\n    r7_r8: (r7: R7) => R8,\n): R8;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2, R3, R4, R5, R6, R7, R8, R9>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n    /** The function with which to transform the return value of the prior function */\n    r2_r3: (r2: R2) => R3,\n    /** The function with which to transform the return value of the prior function */\n    r3_r4: (r3: R3) => R4,\n    /** The function with which to transform the return value of the prior function */\n    r4_r5: (r4: R4) => R5,\n    /** The function with which to transform the return value of the prior function */\n    r5_r6: (r5: R5) => R6,\n    /** The function with which to transform the return value of the prior function */\n    r6_r7: (r6: R6) => R7,\n    /** The function with which to transform the return value of the prior function */\n    r7_r8: (r7: R7) => R8,\n    /** The function with which to transform the return value of the prior function */\n    r8_r9: (r8: R8) => R9,\n): R9;\n/**\n * @returns The return value of the final transform function\n */\nexport function pipe<TInitial, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10>(\n    /** The initial value */\n    init: TInitial,\n    /** The function with which to transform the initial value */\n    init_r1: (init: TInitial) => R1,\n    /** The function with which to transform the return value of the prior function */\n    r1_r2: (r1: R1) => R2,\n    /** The function with which to transform the return value of the prior function */\n    r2_r3: (r2: R2) => R3,\n    /** The function with which to transform the return value of the prior function */\n    r3_r4: (r3: R3) => R4,\n    /** The function with which to transform the return value of the prior function */\n    r4_r5: (r4: R4) => R5,\n    /** The function with which to transform the return value of the prior function */\n    r5_r6: (r5: R5) => R6,\n    /** The function with which to transform the return value of the prior function */\n    r6_r7: (r6: R6) => R7,\n    /** The function with which to transform the return value of the prior function */\n    r7_r8: (r7: R7) => R8,\n    /** The function with which to transform the return value of the prior function */\n    r8_r9: (r8: R8) => R9,\n    /** The function with which to transform the return value of the prior function */\n    r9_r10: (r9: R9) => R10,\n): R10;\nexport function pipe<TInitial>(init: TInitial, ...fns: CallableFunction[]) {\n    return fns.reduce((acc, fn) => fn(acc), init);\n}\n"
  },
  {
    "path": "packages/functional/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/functional/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/functional\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/functional/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/instruction-plans/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/instruction-plans/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/instruction-plans/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/instruction-plans/CHANGELOG.md",
    "content": "# @solana/instruction-plans\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`8d73de5`](https://github.com/anza-xyz/kit/commit/8d73de5241d709946431f2fdda74f2a0df5e9529), [`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/promises@6.9.0\n    - @solana/errors@6.9.0\n    - @solana/instructions@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/transaction-messages@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/keys@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/instructions@6.8.0\n    - @solana/promises@6.8.0\n    - @solana/transaction-messages@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n    - @solana/instructions@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/promises@6.7.0\n    - @solana/transaction-messages@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Minor Changes\n\n- [#1499](https://github.com/anza-xyz/kit/pull/1499) [`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add version-aware transaction size limits. Version 1 transactions now allow up to 4096 bytes, while legacy and v0 transactions continue to use the existing 1232-byte limit. Two new helper functions are exported from `@solana/transactions`: `getTransactionSizeLimit` for compiled `Transaction` objects, and `getTransactionMessageSizeLimit` for `TransactionMessage` objects.\n\n    The existing `TRANSACTION_SIZE_LIMIT`, `TRANSACTION_PACKET_SIZE`, and `TRANSACTION_PACKET_HEADER` constants are now deprecated in favour of `getTransactionSizeLimit` and will be removed in a future major version.\n\n### Patch Changes\n\n- [#1497](https://github.com/anza-xyz/kit/pull/1497) [`f055201`](https://github.com/anza-xyz/kit/commit/f055201c2dd3a4a69b9894d66b622ae81c13b8cd) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The transaction planner now handles the four new transaction compilation constraint errors (`TOO_MANY_ACCOUNT_ADDRESSES`, `TOO_MANY_SIGNER_ADDRESSES`, `TOO_MANY_INSTRUCTIONS`, `TOO_MANY_ACCOUNTS_IN_INSTRUCTION`) gracefully. When adding an instruction to an existing candidate transaction would violate a constraint, the planner splits it into a new transaction — the same behaviour it already had for transactions that exceed the byte size limit. If even a fresh transaction cannot accommodate the instruction, the constraint error propagates to the caller.\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/transactions@6.6.0\n    - @solana/errors@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/instructions@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/promises@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n    - @solana/instructions@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/promises@6.5.0\n    - @solana/transaction-messages@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- [#1470](https://github.com/anza-xyz/kit/pull/1470) [`896412d`](https://github.com/anza-xyz/kit/commit/896412da20ced2b81f9f529e9b5feef16b7e790f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add trailing newline to multi-line error messages so that chained error causes render on their own line.\n\n- Updated dependencies [[`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888)]:\n    - @solana/transaction-messages@6.4.0\n    - @solana/instructions@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/promises@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- [#1464](https://github.com/anza-xyz/kit/pull/1464) [`a557a62`](https://github.com/anza-xyz/kit/commit/a557a62e0f42d2d526f0b8fbdd0a9fcc08ac9ef7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add the last 8 transaction log lines to the error message of `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION` and `SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS` (when only one transaction failed).\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n    - @solana/instructions@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/promises@6.3.1\n    - @solana/transaction-messages@6.3.1\n    - @solana/transactions@6.3.1\n\n## 6.3.0\n\n### Minor Changes\n\n- [#1444](https://github.com/anza-xyz/kit/pull/1444) [`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Enrich the `SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT` error context with the full simulation result (`Omit<RpcSimulateTransactionResult, 'err'>`) and add it to `SolanaErrorCodeWithCause`, aligning it with the `SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE` error.\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/instructions@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/transaction-messages@6.3.0\n    - @solana/transactions@6.3.0\n    - @solana/promises@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- [#1435](https://github.com/anza-xyz/kit/pull/1435) [`98a8869`](https://github.com/anza-xyz/kit/commit/98a8869d5a728a65b7a525d87ed481616112503c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `createFailedToExecuteTransactionPlanError` factory helper for custom transaction plan executor authors and refactor the built-in executor to use it.\n\n- [#1434](https://github.com/anza-xyz/kit/pull/1434) [`79db829`](https://github.com/anza-xyz/kit/commit/79db8292b2064145f615576589d8ecbf32196dc1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `createFailedToSendTransactionError` and `createFailedToSendTransactionsError` factory helpers that create high-level `SolanaError` instances from failed or canceled transaction plan results, with unwrapped simulation errors, preflight data, and logs in the error context.\n\n- [#1433](https://github.com/anza-xyz/kit/pull/1433) [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `abortReason` to the `SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN` error context so consumers can access the abort reason when converting this error to higher-level error types.\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/instructions@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/transaction-messages@6.2.0\n    - @solana/transactions@6.2.0\n    - @solana/promises@6.2.0\n\n## 6.1.0\n\n### Minor Changes\n\n- [#1334](https://github.com/anza-xyz/kit/pull/1334) [`1f6cd4b`](https://github.com/anza-xyz/kit/commit/1f6cd4bc7f41e865ff81ecd819dd9f728c27af77) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `parseInstructionOrTransactionPlanInput` helper that converts flexible inputs (instruction plan input or transaction plan input) into an `InstructionPlan` or `TransactionPlan`\n\n- [#1332](https://github.com/anza-xyz/kit/pull/1332) [`50010b5`](https://github.com/anza-xyz/kit/commit/50010b5b791ff0e6d8636ded3af33158f2380e4e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `parseInstructionPlanInput` helper that converts flexible inputs (single instruction, instruction plan, or array) into an `InstructionPlan`\n\n- [#1333](https://github.com/anza-xyz/kit/pull/1333) [`33234f5`](https://github.com/anza-xyz/kit/commit/33234f50760e34a21072304e6aaf1a31b7a410f1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `parseTransactionPlanInput` helper that converts flexible inputs (single transaction message, transaction plan, or array) into an `TransactionPlan`\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/transaction-messages@6.1.0\n    - @solana/transactions@6.1.0\n    - @solana/instructions@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/promises@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies [[`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492), [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462)]:\n    - @solana/transaction-messages@6.0.1\n    - @solana/transactions@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/instructions@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/promises@6.0.1\n\n## 6.0.0\n\n### Major Changes\n\n- [#1302](https://github.com/anza-xyz/kit/pull/1302) [`5f12df2`](https://github.com/anza-xyz/kit/commit/5f12df20b6f4b4b3536cc76c69b90fb8dc22455d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - The `executeTransactionMessage` callback in `createTransactionPlanExecutor` now receives a mutable context object as its first argument. This context can be incrementally populated during execution (e.g. with the latest transaction message, the compiled transaction, or custom properties) and is preserved in the resulting `SingleTransactionPlanResult` regardless of the outcome. If an error is thrown at any point in the callback, any attributes already saved to the context will still be available in the `FailedSingleTransactionPlanResult`, which is useful for debugging failures or building recovery plans.\n\n    The callback must now return either a `Signature` or a full `Transaction` object directly, instead of wrapping the result in an object.\n\n    **BREAKING CHANGES**\n\n    **`executeTransactionMessage` callback signature changed.** The callback now receives `(context, message, config)` instead of `(message, config)` and returns `Signature | Transaction` instead of `{ transaction: Transaction } | { signature: Signature }`.\n\n    ```diff\n      const executor = createTransactionPlanExecutor({\n    -   executeTransactionMessage: async (message, { abortSignal }) => {\n    +   executeTransactionMessage: async (context, message, { abortSignal }) => {\n          const transaction = await signTransactionMessageWithSigners(message);\n    +     context.transaction = transaction;\n          await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n    -     return { transaction };\n    +     return transaction;\n        }\n      });\n    ```\n\n    **Custom context is now set via mutation instead of being returned.** Previously, custom context was returned as part of the result object. Now, it must be set directly on the mutable context argument.\n\n    ```diff\n      const executor = createTransactionPlanExecutor({\n    -   executeTransactionMessage: async (message) => {\n    -     const transaction = await signAndSend(message);\n    -     return { transaction, context: { custom: 'value' } };\n    +   executeTransactionMessage: async (context, message) => {\n    +     context.custom = 'value';\n    +     const transaction = await signAndSend(message);\n    +     return transaction;\n        }\n      });\n    ```\n\n- [#1293](https://github.com/anza-xyz/kit/pull/1293) [`5c810ac`](https://github.com/anza-xyz/kit/commit/5c810ac20414a893b94045f0e89f01a8ca79ba8a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Reshape the successful `SingleTransactionPlanResult` factory functions. The `successfulSingleTransactionPlanResult` helper now accepts a context object (which must include a `signature` property) instead of a separate `signature` argument. A new `successfulSingleTransactionPlanResultFromTransaction` helper is introduced for the common case of creating a successful result from a full `Transaction` object.\n\n    **BREAKING CHANGES**\n\n    **`successfulSingleTransactionPlanResult` renamed to `successfulSingleTransactionPlanResultFromTransaction`.** If you were creating a successful result from a `Transaction`, update the function name.\n\n    ```diff\n    - successfulSingleTransactionPlanResult(message, transaction)\n    + successfulSingleTransactionPlanResultFromTransaction(message, transaction)\n    ```\n\n    **`successfulSingleTransactionPlanResultFromSignature` renamed to `successfulSingleTransactionPlanResult` with a new signature.** The `signature` is no longer a separate argument — it must be included in the `context` object.\n\n    ```diff\n    - successfulSingleTransactionPlanResultFromSignature(message, signature)\n    + successfulSingleTransactionPlanResult(message, { signature })\n    ```\n\n    ```diff\n    - successfulSingleTransactionPlanResultFromSignature(message, signature, context)\n    + successfulSingleTransactionPlanResult(message, { ...context, signature })\n    ```\n\n- [#1309](https://github.com/anza-xyz/kit/pull/1309) [`bd3d5f1`](https://github.com/anza-xyz/kit/commit/bd3d5f11eac57d1930a747af9ae02cde07d13aa1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a new `planType` property to all `InstructionPlan`, `TransactionPlan`, and `TransactionPlanResult` types to distinguish them from each other at runtime. This property is a string literal with the value `'instructionPlan'`, `'transactionPlan'`, or `'transactionPlanResult'` respectively. It also adds new type guard functions that make use of that new property: `isInstructionPlan`, `isTransactionPlan`, and `isTransactionPlanResult`.\n\n    **BREAKING CHANGES**\n\n    **`InstructionPlan`, `TransactionPlan`, and `TransactionPlanResult` type guards updated.** All factories have been updated to add the new `planType` property but any custom instantiation of these types must be updated to include it as well.\n\n    ```diff\n      const myInstructionPlan: InstructionPlan = {\n        kind: 'parallel',\n        plans: [/* ... */],\n    +   planType: 'instructionPlan',\n      };\n\n      const myTransactionPlan: TransactionPlan = {\n        kind: 'parallel',\n        plans: [/* ... */],\n    +   planType: 'transactionPlan',\n      };\n\n      const myTransactionPlanResult: TransactionPlanResult = {\n        kind: 'parallel',\n        plans: [/* ... */],\n    +   planType: 'transactionPlanResult',\n      };\n    ```\n\n- [#1311](https://github.com/anza-xyz/kit/pull/1311) [`91cdb71`](https://github.com/anza-xyz/kit/commit/91cdb7129daaf0fa0a6d78d16a571e6f2a3feded) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove deprecated function `getAllSingleTransactionPlans`\n\n    **BREAKING CHANGES**\n\n    **`getAllSingleTransactionPlans` removed.** Use `flattenTransactionPlan` instead.\n\n    ```diff\n    - const singlePlans = getAllSingleTransactionPlans(transactionPlan);\n    + const singlePlans = flattenTransactionPlan(transactionPlan);\n    ```\n\n- [#1276](https://github.com/anza-xyz/kit/pull/1276) [`2fbad6a`](https://github.com/anza-xyz/kit/commit/2fbad6ab60789e4207f6c4c95c4c2ac514aafab5) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Reshape `SingleTransactionPlanResult` from a single object type with a `status` discriminated union into three distinct types: `SuccessfulSingleTransactionPlanResult`, `FailedSingleTransactionPlanResult`, and `CanceledSingleTransactionPlanResult`. This flattens the result structure so that `status` is now a string literal (`'successful'`, `'failed'`, or `'canceled'`) and properties like `context`, `error`, and `plannedMessage` live at the top level of each variant.\n\n    Other changes include:\n    - Rename the `message` property to `plannedMessage` on all single transaction plan result types. This makes it clearer that this original planned message from the `TransactionPlan`, not the final message that was sent to the network.\n    - Move the `context` object from inside the `status` field to the top level of each result variant. All variants now carry a `context` — not just successful ones.\n    - Expand `context` attribute to optionally include `message`, `signature`, and `transaction` properties. These properties are meant to hold the actual `TransactionMessage`, `Signature`, and `Transaction` used when the transaction was sent to the network — which may differ from the originally `plannedMessage`.\n    - Remove the now-unused `TransactionPlanResultStatus` type.\n    - `failedSingleTransactionPlanResult` and `canceledSingleTransactionPlanResult` now accept an optional `context` parameter too.\n\n    **BREAKING CHANGES**\n\n    **Accessing the status kind.** Replace `result.status.kind` with `result.status`.\n\n    ```diff\n    - if (result.status.kind === 'successful') { /* ... */ }\n    + if (result.status === 'successful') { /* ... */ }\n    ```\n\n    **Accessing the signature.** The signature has moved from `result.status.signature` to `result.context.signature`.\n\n    ```diff\n    - const sig = result.status.signature;\n    + const sig = result.context.signature;\n    ```\n\n    **Accessing the transaction.** The transaction has moved from `result.status.transaction` to `result.context.transaction`.\n\n    ```diff\n    - const tx = result.status.transaction;\n    + const tx = result.context.transaction;\n    ```\n\n    **Accessing the error.** The error has moved from `result.status.error` to `result.error`.\n\n    ```diff\n    - const err = result.status.error;\n    + const err = result.error;\n    ```\n\n    **Accessing the context.** The context has moved from `result.status.context` to `result.context`.\n\n    ```diff\n    - const ctx = result.status.context;\n    + const ctx = result.context;\n    ```\n\n    **Accessing the message.** The `message` property has been renamed to `plannedMessage`.\n\n    ```diff\n    - const msg = result.message;\n    + const msg = result.plannedMessage;\n    ```\n\n    **`TransactionPlanResultStatus` removed.** Code that references this type must be updated to use the individual result variant types (`SuccessfulSingleTransactionPlanResult`, `FailedSingleTransactionPlanResult`, `CanceledSingleTransactionPlanResult`) or the `SingleTransactionPlanResult` union directly.\n\n### Minor Changes\n\n- [#1275](https://github.com/anza-xyz/kit/pull/1275) [`f8ef83e`](https://github.com/anza-xyz/kit/commit/f8ef83ee7491db8aa7331a0628045ee9072196a4) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add missing `TContext`, `TTransactionMessage` and/or `TSingle` type parameters to `TransactionPlanResult` types and helper functions to better preserve type information through narrowing operations.\n\n### Patch Changes\n\n- Updated dependencies [[`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926), [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a), [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db)]:\n    - @solana/transaction-messages@6.0.0\n    - @solana/transactions@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/instructions@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/promises@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- [#1264](https://github.com/anza-xyz/kit/pull/1264) [`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Exports missing helpers in errors and instruction-plans\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/instructions@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/transaction-messages@5.5.1\n    - @solana/transactions@5.5.1\n    - @solana/promises@5.5.1\n\n## 5.5.0\n\n### Minor Changes\n\n- [#1245](https://github.com/anza-xyz/kit/pull/1245) [`f731129`](https://github.com/anza-xyz/kit/commit/f731129939bac8b2574ecbbcd6afe0a0a6b00e5f) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `flattenInstructionPlan` and `flattenTransactionPlan` functions, that can be used to remove the sequential/parallel structure from these plans. Deprecate `getAllSingleTransactionPlans` which is superseded by `flattenTransactionPlan`.\n\n- [#1233](https://github.com/anza-xyz/kit/pull/1233) [`b174ed5`](https://github.com/anza-xyz/kit/commit/b174ed531c15d34e354657d3945e4ea5b38932bc) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `everyInstructionPlan`, `everyTransactionPlan` and `everyTransactionPlanResult` functions that can be used to ensure a given predicate holds for all nodes inside their respective plan structures.\n\n- [#1247](https://github.com/anza-xyz/kit/pull/1247) [`ea97d43`](https://github.com/anza-xyz/kit/commit/ea97d43f588c6b5bf3d4bd96464f3c927967ae28) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a new function `appendTransactionMessageInstructionPlan` that can be used to add the instructions from an instruction plan to a transaction message\n\n- [#1253](https://github.com/anza-xyz/kit/pull/1253) [`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `isX` and `assertIsX` type guard helpers for instruction plans, transaction plans, and transaction plan results\n\n- [#1243](https://github.com/anza-xyz/kit/pull/1243) [`60e8c45`](https://github.com/anza-xyz/kit/commit/60e8c456356d52fb93637a6323cac9d9b2fc6816) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `transformInstructionPlan`, `transformTransactionPlan` and `transformTransactionPlanResult` helpers for bottom-up transformation of instruction plan trees.\n\n- [#1235](https://github.com/anza-xyz/kit/pull/1235) [`a47e441`](https://github.com/anza-xyz/kit/commit/a47e44109e90ddb03193d4e1e207f9e68118679d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `passthroughFailedTransactionPlanExecution` helper function that wraps a transaction plan execution promise to return a `TransactionPlanResult` even on execution failure. This allows handling execution results in a unified way without try/catch.\n\n- [#1254](https://github.com/anza-xyz/kit/pull/1254) [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `SuccessfulTransactionPlanResult` type with `isSuccessfulTransactionPlanResult` and `assertIsSuccessfulTransactionPlanResult` type guards\n\n- [#1236](https://github.com/anza-xyz/kit/pull/1236) [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `getFirstFailedSingleTransactionPlanResult`, which you can use to get the first failed transaction plan result from a transaction plan result, or throw if none failed\n\n- [#1232](https://github.com/anza-xyz/kit/pull/1232) [`589d761`](https://github.com/anza-xyz/kit/commit/589d761483a8feaf46b4cda7a97ec7abd5e7ab90) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `findInstructionPlan`, `findTransactionPlan` and `findTransactionPlanResult` functions that can be used to find the plan matching a given predicate\n\n### Patch Changes\n\n- [#1256](https://github.com/anza-xyz/kit/pull/1256) [`cccea6f`](https://github.com/anza-xyz/kit/commit/cccea6fc266e71bb2f1b4b843c3a815e3032f208) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix a bug where a message packer that requires multiple iterations is not correctly added when forced to fit in a single transaction, even if it can fit\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/instructions@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/transaction-messages@5.5.0\n    - @solana/transactions@5.5.0\n    - @solana/promises@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/transaction-messages@5.4.0\n    - @solana/instructions@5.4.0\n    - @solana/transactions@5.4.0\n    - @solana/promises@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n    - @solana/instructions@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/promises@5.3.0\n    - @solana/transaction-messages@5.3.0\n    - @solana/transactions@5.3.0\n\n## 5.2.0\n\n### Minor Changes\n\n- [#1139](https://github.com/anza-xyz/kit/pull/1139) [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Return more precise types from transaction message functions\n\n    Deprecate `BaseTransactionMessage` in favour of `TransactionMessage`\n\n### Patch Changes\n\n- [#1155](https://github.com/anza-xyz/kit/pull/1155) [`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Throw early when the default transaction plan executor encounters a non-divisible transaction plan.\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/errors@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/transaction-messages@5.2.0\n    - @solana/transactions@5.2.0\n    - @solana/instructions@5.2.0\n    - @solana/promises@5.2.0\n\n## 5.1.0\n\n### Minor Changes\n\n- [#1044](https://github.com/anza-xyz/kit/pull/1044) [`e64a9b2`](https://github.com/anza-xyz/kit/commit/e64a9b263f7752bd470144d19562eff8819bd799) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function to summarize a `TransactionPlanResult`\n\n- [#1035](https://github.com/anza-xyz/kit/pull/1035) [`2bd0bc2`](https://github.com/anza-xyz/kit/commit/2bd0bc2b8d45eedca661ddf056341deba159a6b1) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function to flatten a transaction plan result\n\n- [#1056](https://github.com/anza-xyz/kit/pull/1056) [`a0c394b`](https://github.com/anza-xyz/kit/commit/a0c394b2f5fcaf543382ca30f052830ca91759e3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Accept any `Error` object in failed `SingleTransactionPlanResult`\n\n- [#1043](https://github.com/anza-xyz/kit/pull/1043) [`5c1f9e5`](https://github.com/anza-xyz/kit/commit/5c1f9e5d61ae55851aaa44e7a5ab83ff09ffee28) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Transaction optional in successful transaction plan result + add signature\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951), [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd)]:\n    - @solana/errors@5.1.0\n    - @solana/transactions@5.1.0\n    - @solana/transaction-messages@5.1.0\n    - @solana/instructions@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/promises@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/transaction-messages@5.0.0\n    - @solana/transactions@5.0.0\n    - @solana/instructions@5.0.0\n    - @solana/promises@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df), [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013)]:\n    - @solana/transactions@4.0.0\n    - @solana/errors@4.0.0\n    - @solana/transaction-messages@4.0.0\n    - @solana/instructions@4.0.0\n    - @solana/promises@4.0.0\n\n## 3.0.0\n\n### Minor Changes\n\n- [#543](https://github.com/anza-xyz/kit/pull/543) [`358df82`](https://github.com/anza-xyz/kit/commit/358df829770c4164fde50e57be04fe0782ddd4b5) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `TransactionPlanResult` type with helpers. This type describes the execution results of transaction plans with the same structural hierarchy — capturing the execution status of each transaction message whether executed in parallel, sequentially, or as a single transaction.\n\n- [#546](https://github.com/anza-xyz/kit/pull/546) [`12d06d1`](https://github.com/anza-xyz/kit/commit/12d06d11d6a5fcf6ce06e9f9698175720666de39) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a `TransactionPlanner` function type that defines how `InstructionPlans` gets planned and turned into `TransactionPlans`.\n\n- [#664](https://github.com/anza-xyz/kit/pull/664) [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `createTransactionPlanExecutor` implementation for the `TransactionPlanExecutor` type.\n\n- [#648](https://github.com/anza-xyz/kit/pull/648) [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `createTransactionPlanner` implementation for the `TransactionPlanner` type.\n\n- [#547](https://github.com/anza-xyz/kit/pull/547) [`24967d1`](https://github.com/anza-xyz/kit/commit/24967d166e9a7035bab2cdababbaae4b46d0deaa) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a `TransactionPlanExecutor` function type that defines how `TransactionPlans` get executed and turned into `TransactionPlanResults`.\n\n- [#533](https://github.com/anza-xyz/kit/pull/533) [`7d48ccd`](https://github.com/anza-xyz/kit/commit/7d48ccd47f08de8d7e9105567d3766ee6ff1e64f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a new `@solana/instruction-plans` package offering a new `InstructionPlan` type that aims to describe a set of instructions with constraints on how they should be executed — e.g. sequentially, in parallel, divisible, etc.\n\n- [#542](https://github.com/anza-xyz/kit/pull/542) [`f79d05a`](https://github.com/anza-xyz/kit/commit/f79d05a92387522ef05816d1d20b75e050da42f3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `TransactionPlan` type with helpers. This type defines a set of transaction messages with constraints on how they should be executed — e.g. sequentially, in parallel, divisible, etc.\n\n### Patch Changes\n\n- [#727](https://github.com/anza-xyz/kit/pull/727) [`018479f`](https://github.com/anza-xyz/kit/commit/018479f56dc7f487b9a9ec444184cea7f13d9f3a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Export more types and functions from the `@solana/instruction-plans` package.\n\n- [#742](https://github.com/anza-xyz/kit/pull/742) [`c6e8568`](https://github.com/anza-xyz/kit/commit/c6e8568214c1647b42e259f464f7e5f220627525) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Fix the `onTransactionMessageUpdated` signature of the `createTransactionPlanner` helper by removing the unnecessary `TTransactionMessage` type parameter.\n\n- [#741](https://github.com/anza-xyz/kit/pull/741) [`a4310a5`](https://github.com/anza-xyz/kit/commit/a4310a571268c03e8d31b64ab450c922079de9c3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Fix the `executeTransactionMessage` signature of the `createTransactionPlanExecutor` helper by removing the unnecessary `TTransactionMessage` type parameter.\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6), [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845), [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf)]:\n    - @solana/transaction-messages@3.0.0\n    - @solana/instructions@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/transactions@3.0.0\n    - @solana/promises@3.0.0\n"
  },
  {
    "path": "packages/instruction-plans/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/instruction-plans/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/instruction-plans?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/instruction-plans?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/instruction-plans\n\n# @solana/instruction-plans\n\nThis package contains types and functions for planning transaction from multiple instructions. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nYou can read more about instruction plans in the [official Kit documentation](https://www.solanakit.com/docs/concepts/instruction-plans).\n"
  },
  {
    "path": "packages/instruction-plans/package.json",
    "content": "{\n    \"name\": \"@solana/instruction-plans\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Construct, plan and execute transactions from multiple instructions.\",\n    \"homepage\": \"https://www.solanakit.com/api#solanainstruction-plans\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/instructions\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/promises\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs\": \"workspace:*\",\n        \"@solana/functional\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/__setup__.ts",
    "content": "import { Address, getAddressDecoder } from '@solana/addresses';\nimport { fixEncoderSize, getBase58Encoder, getUtf8Encoder } from '@solana/codecs';\nimport { SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, SolanaError } from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport type { Instruction } from '@solana/instructions';\nimport { SignatureBytes } from '@solana/keys';\nimport {\n    appendTransactionMessageInstruction,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    type TransactionMessage,\n    type TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, SignaturesMap, Transaction, TRANSACTION_SIZE_LIMIT } from '@solana/transactions';\n\nimport { MessagePackerInstructionPlan } from '../index';\n\nconst MINIMUM_INSTRUCTION_SIZE = 35;\n\n/**\n * Creates a message packer that packs one instruction at a time,\n * even when there's space to pack more in a single iteration.\n * This is useful for testing that the message packer loop correctly accumulates\n * results across iterations.\n */\nexport function createSingleInstructionAtATimeMessagePackerInstructionPlan(\n    instructions: Instruction[],\n): MessagePackerInstructionPlan {\n    return Object.freeze({\n        getMessagePacker: () => {\n            let index = 0;\n            return {\n                done: () => index >= instructions.length,\n                packMessageToCapacity: message => {\n                    if (index >= instructions.length) {\n                        return message;\n                    }\n                    const instruction = instructions[index];\n                    index++;\n                    return appendTransactionMessageInstruction(instruction, message);\n                },\n            };\n        },\n        kind: 'messagePacker',\n        planType: 'instructionPlan',\n    });\n}\n\nexport const FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\nexport function createMessage<TId extends string>(\n    id: TId,\n): TransactionMessage & TransactionMessageWithFeePayer & { id: TId } {\n    return pipe(\n        createTransactionMessage({ version: 0 }),\n        m => setTransactionMessageFeePayer('E9Nykp3rSdza2moQutaJ3K3RSC8E5iFERX2SqLTsQfjJ' as Address, m),\n        m => Object.freeze({ ...m, id }),\n    );\n}\n\nexport function createTransaction<TId extends string>(id: TId): Transaction & { id: TId } {\n    // We set the id as the signature of the transaction, by setting its bytes in the signatures map\n    const signatures: SignaturesMap = { ['' as Address]: signatureEncoder.encode(id) as SignatureBytes };\n    return Object.freeze({ id, signatures }) as unknown as Transaction & { id: TId };\n}\n\nconst signatureEncoder = getBase58Encoder();\n\nexport function instructionFactory(baseSeed?: string) {\n    const seedPrefix = baseSeed ? `${baseSeed}-` : '';\n    const seedEncoder = fixEncoderSize(getUtf8Encoder(), 32);\n    const addressDecoder = getAddressDecoder();\n    const getProgramAddress = (seed: string): Address => addressDecoder.decode(seedEncoder.encode(seed));\n\n    return (seed: string, bytes: number): Instruction => {\n        if (bytes < MINIMUM_INSTRUCTION_SIZE) {\n            throw new Error(`Instruction size must be at least ${MINIMUM_INSTRUCTION_SIZE} bytes`);\n        }\n        return {\n            data: new Uint8Array(bytes - MINIMUM_INSTRUCTION_SIZE),\n            programAddress: getProgramAddress(`${seedPrefix}${seed}`),\n        };\n    };\n}\n\nexport function transactionPercentFactory(\n    createTransactionMessage: () => TransactionMessage & TransactionMessageWithFeePayer,\n) {\n    const minimumTransactionSize = getTransactionMessageSize(createTransactionMessage());\n    const remainingSize = TRANSACTION_SIZE_LIMIT - minimumTransactionSize - 1; /* For shortU16. */\n    return (percent: number) => Math.floor((remainingSize * percent) / 100);\n}\n\nexport function createMessagePackerInstructionPlan(\n    totalBytes: number,\n    baseSeed?: string,\n): MessagePackerInstructionPlan & Readonly<{ get: (offset: number, length: number) => Instruction }> {\n    const getInstruction = instructionFactory(baseSeed ? `message-packer-${baseSeed}` : 'message-packer');\n    const getInstructionFromOffsetAndLength = (offset: number, length: number): Instruction =>\n        getInstruction(`${offset}-${length}`, length);\n\n    // Note that we cannot use `getLinearMessagePackerInstructionPlan` here because\n    // we want the `MINIMUM_INSTRUCTION_SIZE` to be included in our calculations.\n    // For instance, if an instruction that takes 50% of the transaction size,\n    // This should include the base instruction size to simplify our expectations.\n    const baseInstruction = getInstructionFromOffsetAndLength(0, MINIMUM_INSTRUCTION_SIZE);\n    return Object.freeze({\n        get: getInstructionFromOffsetAndLength,\n        getMessagePacker: () => {\n            let offset = 0;\n            return {\n                done: () => offset >= totalBytes,\n                packMessageToCapacity: message => {\n                    const messageSizeWithBaseInstruction = getTransactionMessageSize(\n                        appendTransactionMessageInstruction(baseInstruction, message),\n                    );\n                    const freeSpace =\n                        TRANSACTION_SIZE_LIMIT -\n                        messageSizeWithBaseInstruction /* Includes the base instruction (length: 0). */ -\n                        1; /* Leeway for shortU16 numbers in transaction headers. */\n\n                    if (freeSpace <= 0) {\n                        const messageSize = getTransactionMessageSize(message);\n                        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n                            // (+1) We need to pack at least one byte of data otherwise\n                            // there is no point packing the base instruction alone.\n                            numBytesRequired: messageSizeWithBaseInstruction - messageSize + 1,\n                            // (-1) Leeway for shortU16 numbers in transaction headers.\n                            numFreeBytes: TRANSACTION_SIZE_LIMIT - messageSize - 1,\n                        });\n                    }\n\n                    const length = Math.min(totalBytes - offset, freeSpace + MINIMUM_INSTRUCTION_SIZE);\n                    const instruction = getInstructionFromOffsetAndLength(offset, length);\n                    offset += length;\n                    return appendTransactionMessageInstruction(instruction, message);\n                },\n            };\n        },\n        kind: 'messagePacker',\n        planType: 'instructionPlan',\n    });\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/append-instruction-plan-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { isSolanaError, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN } from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport { Instruction } from '@solana/instructions';\nimport {\n    appendTransactionMessageInstruction,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n} from '@solana/transaction-messages';\n\nimport {\n    appendTransactionMessageInstructionPlan,\n    getMessagePackerInstructionPlanFromInstructions,\n    parallelInstructionPlan,\n    sequentialInstructionPlan,\n    singleInstructionPlan,\n} from '../index';\n\nfunction createInstruction<TId extends string>(id: TId): Instruction & { id: TId } {\n    return { id, programAddress: '1'.repeat(32) as Address };\n}\n\nconst feePayer = '2'.repeat(44) as Address;\n\ndescribe('appendTransactionMessageInstructionPlan', () => {\n    it('appends a single instruction plan to a transaction message', () => {\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const instructionA = createInstruction('A');\n        const plan = singleInstructionPlan(instructionA);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([instructionA]);\n    });\n\n    it('appends instructions from a sequential instruction plan in order', () => {\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const instructionC = createInstruction('C');\n        const plan = sequentialInstructionPlan([instructionA, instructionB, instructionC]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([instructionA, instructionB, instructionC]);\n    });\n\n    it('appends instructions from a parallel instruction plan', () => {\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = parallelInstructionPlan([instructionA, instructionB]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([instructionA, instructionB]);\n    });\n\n    it('appends instructions from nested plans', () => {\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const instructionC = createInstruction('C');\n        const instructionD = createInstruction('D');\n        const plan = sequentialInstructionPlan([\n            parallelInstructionPlan([instructionA, instructionB]),\n            parallelInstructionPlan([instructionC, instructionD]),\n        ]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([instructionA, instructionB, instructionC, instructionD]);\n    });\n\n    it('returns the original message for an empty sequential plan', () => {\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const plan = sequentialInstructionPlan([]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([]);\n    });\n\n    it('returns the original message for an empty parallel plan', () => {\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const plan = parallelInstructionPlan([]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([]);\n    });\n\n    it('preserves existing instructions when appending', () => {\n        const existingInstruction = createInstruction('existing');\n        const message = pipe(\n            createTransactionMessage({ version: 0 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => appendTransactionMessageInstruction(existingInstruction, m),\n        );\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = sequentialInstructionPlan([instructionA, instructionB]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([existingInstruction, instructionA, instructionB]);\n    });\n\n    it('appends instructions from a message packer instruction plan', () => {\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = getMessagePackerInstructionPlanFromInstructions([instructionA, instructionB]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([instructionA, instructionB]);\n    });\n\n    it('appends instructions from a plan containing both single and message packer plans', () => {\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const instructionC = createInstruction('C');\n        const plan = sequentialInstructionPlan([\n            instructionA,\n            getMessagePackerInstructionPlanFromInstructions([instructionB, instructionC]),\n        ]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([instructionA, instructionB, instructionC]);\n    });\n\n    it('preserves existing instructions when appending a message packer plan', () => {\n        const existingInstruction = createInstruction('existing');\n        const message = pipe(\n            createTransactionMessage({ version: 0 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => appendTransactionMessageInstruction(existingInstruction, m),\n        );\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = getMessagePackerInstructionPlanFromInstructions([instructionA, instructionB]);\n\n        const result = appendTransactionMessageInstructionPlan(plan, message);\n\n        expect(result.instructions).toStrictEqual([existingInstruction, instructionA, instructionB]);\n    });\n\n    it('throws if the message packer plan cannot fit all instructions', () => {\n        expect.assertions(1);\n        const message = pipe(createTransactionMessage({ version: 0 }), m => setTransactionMessageFeePayer(feePayer, m));\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const largeInstruction = { ...createInstruction('C'), data: new Uint8Array(50_000) }; // Simulate a large instruction\n        const plan = getMessagePackerInstructionPlanFromInstructions([instructionA, instructionB, largeInstruction]);\n\n        try {\n            appendTransactionMessageInstructionPlan(plan, message);\n        } catch (error) {\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(isSolanaError(error, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN)).toBe(true);\n        }\n    });\n});\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/instruction-plan-input-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { Instruction } from '@solana/instructions';\n\nimport {\n    parallelInstructionPlan,\n    parallelTransactionPlan,\n    parseInstructionOrTransactionPlanInput,\n    parseInstructionPlanInput,\n    parseTransactionPlanInput,\n    sequentialInstructionPlan,\n    sequentialTransactionPlan,\n    singleInstructionPlan,\n    singleTransactionPlan,\n} from '../index';\nimport { createMessage } from './__setup__';\n\nfunction createInstruction<TId extends string>(id: TId): Instruction & { id: TId } {\n    return { id, programAddress: '11111111111111111111111111111111' as Address };\n}\n\ndescribe('parseInstructionPlanInput', () => {\n    it('returns an InstructionPlan from a single instruction', () => {\n        const plan = parseInstructionPlanInput(createInstruction('A'));\n        expect(plan).toStrictEqual(singleInstructionPlan(createInstruction('A')));\n    });\n    it('returns a provided InstructionPlan as-is', () => {\n        const input = sequentialInstructionPlan([\n            createInstruction('A'),\n            parallelInstructionPlan([createInstruction('B'), createInstruction('C')]),\n        ]);\n        const plan = parseInstructionPlanInput(input);\n        expect(plan).toBe(input);\n    });\n    it('returns an empty SequentialInstructionPlan from an empty array', () => {\n        const plan = parseInstructionPlanInput([]);\n        expect(plan).toStrictEqual(sequentialInstructionPlan([]));\n    });\n    it('returns a SingleInstructionPlan from an array of only one Instruction', () => {\n        const plan = parseInstructionPlanInput([createInstruction('A')]);\n        expect(plan).toStrictEqual(singleInstructionPlan(createInstruction('A')));\n    });\n    it('returns a provided InstructionPlan as-is when it is the only item in the provided array', () => {\n        const input = sequentialInstructionPlan([\n            createInstruction('A'),\n            parallelInstructionPlan([createInstruction('B'), createInstruction('C')]),\n        ]);\n        const plan = parseInstructionPlanInput([input]);\n        expect(plan).toBe(input);\n    });\n    it('returns a SequentialInstructionPlan from an array of instructions', () => {\n        const plan = parseInstructionPlanInput([createInstruction('A'), createInstruction('B')]);\n        expect(plan).toStrictEqual(sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]));\n    });\n    it('returns a SequentialInstructionPlan from an array of InstructionPlans', () => {\n        const plan = parseInstructionPlanInput([\n            sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]),\n            parallelInstructionPlan([createInstruction('C'), createInstruction('D')]),\n        ]);\n        expect(plan).toStrictEqual(\n            sequentialInstructionPlan([\n                sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]),\n                parallelInstructionPlan([createInstruction('C'), createInstruction('D')]),\n            ]),\n        );\n    });\n    it('returns a SequentialInstructionPlan from a mixed array of InstructionPlans and Instructions', () => {\n        const plan = parseInstructionPlanInput([\n            createInstruction('A'),\n            sequentialInstructionPlan([createInstruction('B'), createInstruction('C')]),\n            createInstruction('D'),\n            parallelInstructionPlan([createInstruction('E'), createInstruction('F')]),\n        ]);\n        expect(plan).toStrictEqual(\n            sequentialInstructionPlan([\n                createInstruction('A'),\n                sequentialInstructionPlan([createInstruction('B'), createInstruction('C')]),\n                createInstruction('D'),\n                parallelInstructionPlan([createInstruction('E'), createInstruction('F')]),\n            ]),\n        );\n    });\n    it('returns frozen objects', () => {\n        expect(parseInstructionPlanInput(createInstruction('A'))).toBeFrozenObject();\n        expect(parseInstructionPlanInput(sequentialInstructionPlan([createInstruction('A')]))).toBeFrozenObject();\n        expect(parseInstructionPlanInput([])).toBeFrozenObject();\n        expect(parseInstructionPlanInput([createInstruction('A')])).toBeFrozenObject();\n        expect(parseInstructionPlanInput([sequentialInstructionPlan([createInstruction('B')])])).toBeFrozenObject();\n        expect(\n            parseInstructionPlanInput([createInstruction('A'), sequentialInstructionPlan([createInstruction('B')])]),\n        ).toBeFrozenObject();\n    });\n});\n\ndescribe('parseTransactionPlanInput', () => {\n    it('returns an TransactionPlan from a single message', () => {\n        const plan = parseTransactionPlanInput(createMessage('A'));\n        expect(plan).toStrictEqual(singleTransactionPlan(createMessage('A')));\n    });\n    it('returns a provided TransactionPlan as-is', () => {\n        const input = sequentialTransactionPlan([\n            createMessage('A'),\n            parallelTransactionPlan([createMessage('B'), createMessage('C')]),\n        ]);\n        const plan = parseTransactionPlanInput(input);\n        expect(plan).toBe(input);\n    });\n    it('returns an empty SequentialTransactionPlan from an empty array', () => {\n        const plan = parseTransactionPlanInput([]);\n        expect(plan).toStrictEqual(sequentialTransactionPlan([]));\n    });\n    it('returns a SingleTransactionPlan from an array of only one TransactionMessage', () => {\n        const plan = parseTransactionPlanInput([createMessage('A')]);\n        expect(plan).toStrictEqual(singleTransactionPlan(createMessage('A')));\n    });\n    it('returns a provided TransactionPlan as-is when it is the only item in the provided array', () => {\n        const input = sequentialTransactionPlan([\n            createMessage('A'),\n            parallelTransactionPlan([createMessage('B'), createMessage('C')]),\n        ]);\n        const plan = parseTransactionPlanInput([input]);\n        expect(plan).toBe(input);\n    });\n    it('returns a SequentialTransactionPlan from an array of messages', () => {\n        const plan = parseTransactionPlanInput([createMessage('A'), createMessage('B')]);\n        expect(plan).toStrictEqual(sequentialTransactionPlan([createMessage('A'), createMessage('B')]));\n    });\n    it('returns a SequentialTransactionPlan from an array of TransactionPlans', () => {\n        const plan = parseTransactionPlanInput([\n            sequentialTransactionPlan([createMessage('A'), createMessage('B')]),\n            parallelTransactionPlan([createMessage('C'), createMessage('D')]),\n        ]);\n        expect(plan).toStrictEqual(\n            sequentialTransactionPlan([\n                sequentialTransactionPlan([createMessage('A'), createMessage('B')]),\n                parallelTransactionPlan([createMessage('C'), createMessage('D')]),\n            ]),\n        );\n    });\n    it('returns a SequentialTransactionPlan from a mixed array of TransactionPlans and TransactionMessages', () => {\n        const plan = parseTransactionPlanInput([\n            createMessage('A'),\n            sequentialTransactionPlan([createMessage('B'), createMessage('C')]),\n            createMessage('D'),\n            parallelTransactionPlan([createMessage('E'), createMessage('F')]),\n        ]);\n        expect(plan).toStrictEqual(\n            sequentialTransactionPlan([\n                createMessage('A'),\n                sequentialTransactionPlan([createMessage('B'), createMessage('C')]),\n                createMessage('D'),\n                parallelTransactionPlan([createMessage('E'), createMessage('F')]),\n            ]),\n        );\n    });\n    it('returns frozen objects', () => {\n        expect(parseTransactionPlanInput(createMessage('A'))).toBeFrozenObject();\n        expect(parseTransactionPlanInput(sequentialTransactionPlan([createMessage('A')]))).toBeFrozenObject();\n        expect(parseTransactionPlanInput([])).toBeFrozenObject();\n        expect(parseTransactionPlanInput([createMessage('A')])).toBeFrozenObject();\n        expect(parseTransactionPlanInput([sequentialTransactionPlan([createMessage('B')])])).toBeFrozenObject();\n        expect(\n            parseTransactionPlanInput([createMessage('A'), sequentialTransactionPlan([createMessage('B')])]),\n        ).toBeFrozenObject();\n    });\n});\n\ndescribe('parseInstructionOrTransactionPlanInput', () => {\n    it('returns an empty SequentialTransactionPlan from an empty array', () => {\n        // Because if we're trying to parse nothing, might as well avoid the planning phase.\n        const plan = parseInstructionOrTransactionPlanInput([]);\n        expect(plan).toStrictEqual(sequentialTransactionPlan([]));\n    });\n    it('returns an InstructionPlan from a single instruction', () => {\n        const plan = parseInstructionOrTransactionPlanInput(createInstruction('A'));\n        expect(plan).toStrictEqual(singleInstructionPlan(createInstruction('A')));\n    });\n    it('returns a provided InstructionPlan as-is', () => {\n        const input = sequentialInstructionPlan([\n            createInstruction('A'),\n            parallelInstructionPlan([createInstruction('B'), createInstruction('C')]),\n        ]);\n        const plan = parseInstructionOrTransactionPlanInput(input);\n        expect(plan).toBe(input);\n    });\n    it('returns a SingleInstructionPlan from an array of only one Instruction', () => {\n        const plan = parseInstructionOrTransactionPlanInput([createInstruction('A')]);\n        expect(plan).toStrictEqual(singleInstructionPlan(createInstruction('A')));\n    });\n    it('returns a provided InstructionPlan as-is when it is the only item in the provided array', () => {\n        const input = sequentialInstructionPlan([\n            createInstruction('A'),\n            parallelInstructionPlan([createInstruction('B'), createInstruction('C')]),\n        ]);\n        const plan = parseInstructionOrTransactionPlanInput([input]);\n        expect(plan).toBe(input);\n    });\n    it('returns a SequentialInstructionPlan from an array of instructions', () => {\n        const plan = parseInstructionOrTransactionPlanInput([createInstruction('A'), createInstruction('B')]);\n        expect(plan).toStrictEqual(sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]));\n    });\n    it('returns a SequentialInstructionPlan from an array of InstructionPlans', () => {\n        const plan = parseInstructionOrTransactionPlanInput([\n            sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]),\n            parallelInstructionPlan([createInstruction('C'), createInstruction('D')]),\n        ]);\n        expect(plan).toStrictEqual(\n            sequentialInstructionPlan([\n                sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]),\n                parallelInstructionPlan([createInstruction('C'), createInstruction('D')]),\n            ]),\n        );\n    });\n    it('returns a SequentialInstructionPlan from a mixed array of InstructionPlans and Instructions', () => {\n        const plan = parseInstructionOrTransactionPlanInput([\n            createInstruction('A'),\n            sequentialInstructionPlan([createInstruction('B'), createInstruction('C')]),\n            createInstruction('D'),\n            parallelInstructionPlan([createInstruction('E'), createInstruction('F')]),\n        ]);\n        expect(plan).toStrictEqual(\n            sequentialInstructionPlan([\n                createInstruction('A'),\n                sequentialInstructionPlan([createInstruction('B'), createInstruction('C')]),\n                createInstruction('D'),\n                parallelInstructionPlan([createInstruction('E'), createInstruction('F')]),\n            ]),\n        );\n    });\n    it('returns an TransactionPlan from a single message', () => {\n        const plan = parseInstructionOrTransactionPlanInput(createMessage('A'));\n        expect(plan).toStrictEqual(singleTransactionPlan(createMessage('A')));\n    });\n    it('returns a provided TransactionPlan as-is', () => {\n        const input = sequentialTransactionPlan([\n            createMessage('A'),\n            parallelTransactionPlan([createMessage('B'), createMessage('C')]),\n        ]);\n        const plan = parseInstructionOrTransactionPlanInput(input);\n        expect(plan).toBe(input);\n    });\n    it('returns a SingleTransactionPlan from an array of only one TransactionMessage', () => {\n        const plan = parseInstructionOrTransactionPlanInput([createMessage('A')]);\n        expect(plan).toStrictEqual(singleTransactionPlan(createMessage('A')));\n    });\n    it('returns a provided TransactionPlan as-is when it is the only item in the provided array', () => {\n        const input = sequentialTransactionPlan([\n            createMessage('A'),\n            parallelTransactionPlan([createMessage('B'), createMessage('C')]),\n        ]);\n        const plan = parseInstructionOrTransactionPlanInput([input]);\n        expect(plan).toBe(input);\n    });\n    it('returns a SequentialTransactionPlan from an array of messages', () => {\n        const plan = parseInstructionOrTransactionPlanInput([createMessage('A'), createMessage('B')]);\n        expect(plan).toStrictEqual(sequentialTransactionPlan([createMessage('A'), createMessage('B')]));\n    });\n    it('returns a SequentialTransactionPlan from an array of TransactionPlans', () => {\n        const plan = parseInstructionOrTransactionPlanInput([\n            sequentialTransactionPlan([createMessage('A'), createMessage('B')]),\n            parallelTransactionPlan([createMessage('C'), createMessage('D')]),\n        ]);\n        expect(plan).toStrictEqual(\n            sequentialTransactionPlan([\n                sequentialTransactionPlan([createMessage('A'), createMessage('B')]),\n                parallelTransactionPlan([createMessage('C'), createMessage('D')]),\n            ]),\n        );\n    });\n    it('returns a SequentialTransactionPlan from a mixed array of TransactionPlans and TransactionMessages', () => {\n        const plan = parseInstructionOrTransactionPlanInput([\n            createMessage('A'),\n            sequentialTransactionPlan([createMessage('B'), createMessage('C')]),\n            createMessage('D'),\n            parallelTransactionPlan([createMessage('E'), createMessage('F')]),\n        ]);\n        expect(plan).toStrictEqual(\n            sequentialTransactionPlan([\n                createMessage('A'),\n                sequentialTransactionPlan([createMessage('B'), createMessage('C')]),\n                createMessage('D'),\n                parallelTransactionPlan([createMessage('E'), createMessage('F')]),\n            ]),\n        );\n    });\n    it('returns frozen objects', () => {\n        expect(parseInstructionOrTransactionPlanInput([])).toBeFrozenObject();\n        expect(parseInstructionOrTransactionPlanInput(createInstruction('A'))).toBeFrozenObject();\n        expect(\n            parseInstructionOrTransactionPlanInput(sequentialInstructionPlan([createInstruction('A')])),\n        ).toBeFrozenObject();\n        expect(parseInstructionOrTransactionPlanInput(createMessage('A'))).toBeFrozenObject();\n        expect(\n            parseInstructionOrTransactionPlanInput(sequentialTransactionPlan([createMessage('A')])),\n        ).toBeFrozenObject();\n        expect(parseInstructionOrTransactionPlanInput([createInstruction('A')])).toBeFrozenObject();\n        expect(parseInstructionOrTransactionPlanInput([createMessage('A')])).toBeFrozenObject();\n        expect(\n            parseInstructionOrTransactionPlanInput([\n                createInstruction('A'),\n                sequentialInstructionPlan([createInstruction('B')]),\n            ]),\n        ).toBeFrozenObject();\n        expect(\n            parseInstructionOrTransactionPlanInput([\n                createMessage('A'),\n                sequentialTransactionPlan([createMessage('B')]),\n            ]),\n        ).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/instruction-plan-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE,\n    SolanaError,\n} from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport { Instruction } from '@solana/instructions';\nimport {\n    appendTransactionMessageInstruction,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, TRANSACTION_SIZE_LIMIT } from '@solana/transactions';\n\nimport {\n    assertIsMessagePackerInstructionPlan,\n    assertIsNonDivisibleSequentialInstructionPlan,\n    assertIsParallelInstructionPlan,\n    assertIsSequentialInstructionPlan,\n    assertIsSingleInstructionPlan,\n    everyInstructionPlan,\n    findInstructionPlan,\n    flattenInstructionPlan,\n    getLinearMessagePackerInstructionPlan,\n    getMessagePackerInstructionPlanFromInstructions,\n    getReallocMessagePackerInstructionPlan,\n    isInstructionPlan,\n    isMessagePackerInstructionPlan,\n    isNonDivisibleSequentialInstructionPlan,\n    isParallelInstructionPlan,\n    isSequentialInstructionPlan,\n    isSingleInstructionPlan,\n    MessagePackerInstructionPlan,\n    nonDivisibleSequentialInstructionPlan,\n    parallelInstructionPlan,\n    sequentialInstructionPlan,\n    singleInstructionPlan,\n    transformInstructionPlan,\n} from '../index';\n\njest.mock('@solana/transactions', () => ({\n    ...jest.requireActual('@solana/transactions'),\n    getTransactionMessageSize: jest.fn(),\n}));\n\nfunction createInstruction<TId extends string>(id: TId): Instruction & { id: TId } {\n    return { id, programAddress: '11111111111111111111111111111111' as Address };\n}\n\ndescribe('singleInstructionPlan', () => {\n    it('creates SingleInstructionPlan objects', () => {\n        const instruction = createInstruction('A');\n        const plan = singleInstructionPlan(instruction);\n        expect(plan).toStrictEqual({ instruction, kind: 'single', planType: 'instructionPlan' });\n    });\n    it('freezes created SingleInstructionPlan objects', () => {\n        const instruction = createInstruction('A');\n        const plan = singleInstructionPlan(instruction);\n        expect(plan).toBeFrozenObject();\n    });\n});\n\ndescribe('parallelInstructionPlan', () => {\n    it('creates ParallelInstructionPlan objects from other plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = parallelInstructionPlan([\n            singleInstructionPlan(instructionA),\n            singleInstructionPlan(instructionB),\n        ]);\n        expect(plan).toStrictEqual({\n            kind: 'parallel',\n            planType: 'instructionPlan',\n            plans: [singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)],\n        });\n    });\n    it('accepts instructions directly and wrap them in single plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = parallelInstructionPlan([instructionA, instructionB]);\n        expect(plan).toStrictEqual({\n            kind: 'parallel',\n            planType: 'instructionPlan',\n            plans: [singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)],\n        });\n    });\n    it('can nest other parallel plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const instructionC = createInstruction('C');\n        const plan = parallelInstructionPlan([instructionA, parallelInstructionPlan([instructionB, instructionC])]);\n        expect(plan).toStrictEqual({\n            kind: 'parallel',\n            planType: 'instructionPlan',\n            plans: [\n                singleInstructionPlan(instructionA),\n                {\n                    kind: 'parallel',\n                    planType: 'instructionPlan',\n                    plans: [singleInstructionPlan(instructionB), singleInstructionPlan(instructionC)],\n                },\n            ],\n        });\n    });\n    it('freezes created ParallelInstructionPlan objects', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = parallelInstructionPlan([instructionA, instructionB]);\n        expect(plan).toBeFrozenObject();\n    });\n});\n\ndescribe('sequentialInstructionPlan', () => {\n    it('creates divisible SequentialInstructionPlan objects from other plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = sequentialInstructionPlan([\n            singleInstructionPlan(instructionA),\n            singleInstructionPlan(instructionB),\n        ]);\n        expect(plan).toStrictEqual({\n            divisible: true,\n            kind: 'sequential',\n            planType: 'instructionPlan',\n            plans: [singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)],\n        });\n    });\n    it('accepts instructions directly and wrap them in single plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = sequentialInstructionPlan([instructionA, instructionB]);\n        expect(plan).toStrictEqual({\n            divisible: true,\n            kind: 'sequential',\n            planType: 'instructionPlan',\n            plans: [singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)],\n        });\n    });\n    it('can nest other sequential plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const instructionC = createInstruction('C');\n        const plan = sequentialInstructionPlan([instructionA, sequentialInstructionPlan([instructionB, instructionC])]);\n        expect(plan).toStrictEqual({\n            divisible: true,\n            kind: 'sequential',\n            planType: 'instructionPlan',\n            plans: [\n                singleInstructionPlan(instructionA),\n                {\n                    divisible: true,\n                    kind: 'sequential',\n                    planType: 'instructionPlan',\n                    plans: [singleInstructionPlan(instructionB), singleInstructionPlan(instructionC)],\n                },\n            ],\n        });\n    });\n    it('freezes created SequentialInstructionPlan objects', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = sequentialInstructionPlan([instructionA, instructionB]);\n        expect(plan).toBeFrozenObject();\n    });\n});\n\ndescribe('nonDivisibleSequentialInstructionPlan', () => {\n    it('creates non-divisible SequentialInstructionPlan objects from other plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = nonDivisibleSequentialInstructionPlan([\n            singleInstructionPlan(instructionA),\n            singleInstructionPlan(instructionB),\n        ]);\n        expect(plan).toStrictEqual({\n            divisible: false,\n            kind: 'sequential',\n            planType: 'instructionPlan',\n            plans: [singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)],\n        });\n    });\n    it('accepts instructions directly and wrap them in single plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n        expect(plan).toStrictEqual({\n            divisible: false,\n            kind: 'sequential',\n            planType: 'instructionPlan',\n            plans: [singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)],\n        });\n    });\n    it('can nest other non-divisible sequential plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const instructionC = createInstruction('C');\n        const plan = nonDivisibleSequentialInstructionPlan([\n            instructionA,\n            nonDivisibleSequentialInstructionPlan([instructionB, instructionC]),\n        ]);\n        expect(plan).toStrictEqual({\n            divisible: false,\n            kind: 'sequential',\n            planType: 'instructionPlan',\n            plans: [\n                singleInstructionPlan(instructionA),\n                {\n                    divisible: false,\n                    kind: 'sequential',\n                    planType: 'instructionPlan',\n                    plans: [singleInstructionPlan(instructionB), singleInstructionPlan(instructionC)],\n                },\n            ],\n        });\n    });\n    it('freezes created SequentialInstructionPlan objects', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n        expect(plan).toBeFrozenObject();\n    });\n});\n\ndescribe('getLinearMessagePackerInstructionPlan', () => {\n    let message: TransactionMessage & TransactionMessageWithFeePayer;\n    beforeEach(() => {\n        message = pipe(createTransactionMessage({ version: 0 }), m =>\n            setTransactionMessageFeePayer('E9Nykp3rSdza2moQutaJ3K3RSC8E5iFERX2SqLTsQfjJ' as Address, m),\n        );\n    });\n    it('creates MessagePackerInstructionPlan objects by splitting instructions until we reach the total bytes required', () => {\n        jest.mocked(getTransactionMessageSize).mockReturnValue(100);\n        const expectedLength = TRANSACTION_SIZE_LIMIT - 100 - 1;\n\n        const plan = getLinearMessagePackerInstructionPlan({\n            getInstruction: (offset: number, length: number) => createInstruction(`[${offset},${offset + length})`),\n            totalLength: 2000,\n        });\n\n        const messagePacker = plan.getMessagePacker();\n        expect(messagePacker.done()).toBe(false);\n        expect(messagePacker.packMessageToCapacity(message).instructions[0]).toStrictEqual(\n            createInstruction(`[0,${expectedLength})`),\n        );\n        expect(messagePacker.done()).toBe(false);\n        expect(messagePacker.packMessageToCapacity(message).instructions[0]).toStrictEqual(\n            createInstruction(`[${expectedLength},2000)`),\n        );\n        expect(messagePacker.done()).toBe(true);\n        expect(() => messagePacker.packMessageToCapacity(message)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE),\n        );\n    });\n    it('freezes created MessagePackerInstructionPlan objects', () => {\n        const plan = getLinearMessagePackerInstructionPlan({\n            getInstruction: (offset: number, length: number) => createInstruction(`[${offset},${offset + length})`),\n            totalLength: 2000,\n        });\n        expect(plan).toBeFrozenObject();\n    });\n    it(\"throws if there isn't enough space on the provided message\", () => {\n        jest.mocked(getTransactionMessageSize).mockReturnValueOnce(TRANSACTION_SIZE_LIMIT + 50);\n        jest.mocked(getTransactionMessageSize).mockReturnValueOnce(TRANSACTION_SIZE_LIMIT - 50);\n        const plan = getLinearMessagePackerInstructionPlan({\n            getInstruction: () => createInstruction('ignored'),\n            totalLength: 2000,\n        });\n\n        const messagePacker = plan.getMessagePacker();\n        expect(() => messagePacker.packMessageToCapacity(message)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n                numBytesRequired: 101,\n                numFreeBytes: 49,\n            }),\n        );\n    });\n    it('freezes the messagePacker returned by getMessagePacker', () => {\n        const plan = getLinearMessagePackerInstructionPlan({\n            getInstruction: (offset: number, length: number) => createInstruction(`[${offset},${offset + length})`),\n            totalLength: 2000,\n        });\n        expect(plan.getMessagePacker()).toBeFrozenObject();\n    });\n});\n\ndescribe('getMessagePackerInstructionPlanFromInstructions', () => {\n    let message: TransactionMessage & TransactionMessageWithFeePayer;\n    beforeEach(() => {\n        message = pipe(createTransactionMessage({ version: 0 }), m =>\n            setTransactionMessageFeePayer('E9Nykp3rSdza2moQutaJ3K3RSC8E5iFERX2SqLTsQfjJ' as Address, m),\n        );\n    });\n    it('creates MessagePackerInstructionPlan objects by providing the iterated instruction in advance', () => {\n        const plan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A'), createInstruction('B')]);\n\n        const messagePacker = plan.getMessagePacker();\n        expect(messagePacker.done()).toBe(false);\n        expect(messagePacker.packMessageToCapacity(message).instructions).toStrictEqual([\n            createInstruction('A'),\n            createInstruction('B'),\n        ]);\n        expect(messagePacker.done()).toBe(true);\n        expect(() => messagePacker.packMessageToCapacity(message)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE),\n        );\n    });\n    it(\"throws if there isn't enough space on the provided message\", () => {\n        jest.mocked(getTransactionMessageSize).mockReturnValueOnce(TRANSACTION_SIZE_LIMIT - 100);\n        jest.mocked(getTransactionMessageSize).mockReturnValueOnce(TRANSACTION_SIZE_LIMIT + 50);\n        const plan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A'), createInstruction('B')]);\n\n        const messagePacker = plan.getMessagePacker();\n        expect(() => messagePacker.packMessageToCapacity(message)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n                numBytesRequired: 150,\n                numFreeBytes: 100,\n            }),\n        );\n    });\n    it('freezes created MessagePackerInstructionPlan objects', () => {\n        const plan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A'), createInstruction('B')]);\n        expect(plan).toBeFrozenObject();\n    });\n    it('freezes the messagePacker returned by getMessagePacker', () => {\n        const plan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A'), createInstruction('B')]);\n        expect(plan.getMessagePacker()).toBeFrozenObject();\n    });\n});\n\ndescribe('getReallocMessagePackerInstructionPlan', () => {\n    let message: TransactionMessage & TransactionMessageWithFeePayer;\n    beforeEach(() => {\n        message = pipe(createTransactionMessage({ version: 0 }), m =>\n            setTransactionMessageFeePayer('E9Nykp3rSdza2moQutaJ3K3RSC8E5iFERX2SqLTsQfjJ' as Address, m),\n        );\n    });\n    it('creates MessagePackerInstructionPlan objects by chunking instruction using the `REALLOC_LIMIT`', () => {\n        const plan = getReallocMessagePackerInstructionPlan({\n            getInstruction: (size: number) => createInstruction(`Size: ${size}`),\n            totalSize: 15_000,\n        });\n\n        const messagePacker = plan.getMessagePacker();\n        expect(messagePacker.done()).toBe(false);\n        expect(messagePacker.packMessageToCapacity(message).instructions).toStrictEqual([\n            createInstruction('Size: 10240'), // REALLOC_LIMIT\n            createInstruction('Size: 4760'), // 15000 - REALLOC_LIMIT\n        ]);\n        expect(messagePacker.done()).toBe(true);\n        expect(() => messagePacker.packMessageToCapacity(message)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE),\n        );\n    });\n    it(\"throws if there isn't enough space on the provided message\", () => {\n        jest.mocked(getTransactionMessageSize).mockReturnValueOnce(TRANSACTION_SIZE_LIMIT - 100);\n        jest.mocked(getTransactionMessageSize).mockReturnValueOnce(TRANSACTION_SIZE_LIMIT + 50);\n        const plan = getReallocMessagePackerInstructionPlan({\n            getInstruction: () => createInstruction('ignored'),\n            totalSize: 15_000,\n        });\n\n        const messagePacker = plan.getMessagePacker();\n        expect(() => messagePacker.packMessageToCapacity(message)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n                numBytesRequired: 150,\n                numFreeBytes: 100,\n            }),\n        );\n    });\n    it('freezes created MessagePackerInstructionPlan objects', () => {\n        const plan = getReallocMessagePackerInstructionPlan({\n            getInstruction: (size: number) => createInstruction(`Size: ${size}`),\n            totalSize: 15_000,\n        });\n        expect(plan).toBeFrozenObject();\n    });\n    it('freezes the messagePacker returned by getMessagePacker', () => {\n        const plan = getReallocMessagePackerInstructionPlan({\n            getInstruction: (size: number) => createInstruction(`Size: ${size}`),\n            totalSize: 15_000,\n        });\n        expect(plan.getMessagePacker()).toBeFrozenObject();\n    });\n});\n\ndescribe('isSingleInstructionPlan', () => {\n    it('returns true for SingleInstructionPlan', () => {\n        expect(isSingleInstructionPlan(singleInstructionPlan(createInstruction('A')))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isSingleInstructionPlan(getMessagePackerInstructionPlanFromInstructions([]))).toBe(false);\n        expect(isSingleInstructionPlan(sequentialInstructionPlan([]))).toBe(false);\n        expect(isSingleInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toBe(false);\n        expect(isSingleInstructionPlan(parallelInstructionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsSingleInstructionPlan', () => {\n    it('does nothing for SingleInstructionPlan', () => {\n        expect(() => assertIsSingleInstructionPlan(singleInstructionPlan(createInstruction('A')))).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsSingleInstructionPlan(getMessagePackerInstructionPlanFromInstructions([]))).toThrow(\n            'Unexpected instruction plan. Expected single plan, got messagePacker plan.',\n        );\n        expect(() => assertIsSingleInstructionPlan(sequentialInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected single plan, got sequential plan.',\n        );\n        expect(() => assertIsSingleInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected single plan, got sequential plan.',\n        );\n        expect(() => assertIsSingleInstructionPlan(parallelInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected single plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isMessagePackerInstructionPlan', () => {\n    it('returns true for MessagePackerInstructionPlan', () => {\n        expect(\n            isMessagePackerInstructionPlan(getMessagePackerInstructionPlanFromInstructions([createInstruction('A')])),\n        ).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isMessagePackerInstructionPlan(singleInstructionPlan(createInstruction('A')))).toBe(false);\n        expect(isMessagePackerInstructionPlan(sequentialInstructionPlan([]))).toBe(false);\n        expect(isMessagePackerInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toBe(false);\n        expect(isMessagePackerInstructionPlan(parallelInstructionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsMessagePackerInstructionPlan', () => {\n    it('does nothing for MessagePackerInstructionPlan', () => {\n        expect(() =>\n            assertIsMessagePackerInstructionPlan(\n                getMessagePackerInstructionPlanFromInstructions([createInstruction('A')]),\n            ),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsMessagePackerInstructionPlan(singleInstructionPlan(createInstruction('A')))).toThrow(\n            'Unexpected instruction plan. Expected messagePacker plan, got single plan.',\n        );\n        expect(() => assertIsMessagePackerInstructionPlan(sequentialInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected messagePacker plan, got sequential plan.',\n        );\n        expect(() => assertIsMessagePackerInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected messagePacker plan, got sequential plan.',\n        );\n        expect(() => assertIsMessagePackerInstructionPlan(parallelInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected messagePacker plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isSequentialInstructionPlan', () => {\n    it('returns true for SequentialInstructionPlan (divisible or not)', () => {\n        expect(isSequentialInstructionPlan(sequentialInstructionPlan([]))).toBe(true);\n        expect(isSequentialInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isSequentialInstructionPlan(singleInstructionPlan(createInstruction('A')))).toBe(false);\n        expect(isSequentialInstructionPlan(getMessagePackerInstructionPlanFromInstructions([]))).toBe(false);\n        expect(isSequentialInstructionPlan(parallelInstructionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsSequentialInstructionPlan', () => {\n    it('does nothing for SequentialInstructionPlan', () => {\n        expect(() => assertIsSequentialInstructionPlan(sequentialInstructionPlan([]))).not.toThrow();\n        expect(() => assertIsSequentialInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsSequentialInstructionPlan(singleInstructionPlan(createInstruction('A')))).toThrow(\n            'Unexpected instruction plan. Expected sequential plan, got single plan.',\n        );\n        expect(() => assertIsSequentialInstructionPlan(getMessagePackerInstructionPlanFromInstructions([]))).toThrow(\n            'Unexpected instruction plan. Expected sequential plan, got messagePacker plan.',\n        );\n        expect(() => assertIsSequentialInstructionPlan(parallelInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected sequential plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isNonDivisibleSequentialInstructionPlan', () => {\n    it('returns true for non-divisible SequentialInstructionPlan', () => {\n        expect(isNonDivisibleSequentialInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isNonDivisibleSequentialInstructionPlan(singleInstructionPlan(createInstruction('A')))).toBe(false);\n        expect(isNonDivisibleSequentialInstructionPlan(getMessagePackerInstructionPlanFromInstructions([]))).toBe(\n            false,\n        );\n        expect(isNonDivisibleSequentialInstructionPlan(sequentialInstructionPlan([]))).toBe(false);\n        expect(isNonDivisibleSequentialInstructionPlan(parallelInstructionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsNonDivisibleSequentialInstructionPlan', () => {\n    it('does nothing for non-divisible SequentialInstructionPlan', () => {\n        expect(() =>\n            assertIsNonDivisibleSequentialInstructionPlan(nonDivisibleSequentialInstructionPlan([])),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() =>\n            assertIsNonDivisibleSequentialInstructionPlan(singleInstructionPlan(createInstruction('A'))),\n        ).toThrow('Unexpected instruction plan. Expected non-divisible sequential plan, got single plan.');\n        expect(() =>\n            assertIsNonDivisibleSequentialInstructionPlan(getMessagePackerInstructionPlanFromInstructions([])),\n        ).toThrow('Unexpected instruction plan. Expected non-divisible sequential plan, got messagePacker plan.');\n        expect(() => assertIsNonDivisibleSequentialInstructionPlan(sequentialInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected non-divisible sequential plan, got divisible sequential plan.',\n        );\n        expect(() => assertIsNonDivisibleSequentialInstructionPlan(parallelInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected non-divisible sequential plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isParallelInstructionPlan', () => {\n    it('returns true for ParallelInstructionPlan', () => {\n        expect(isParallelInstructionPlan(parallelInstructionPlan([]))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isParallelInstructionPlan(singleInstructionPlan(createInstruction('A')))).toBe(false);\n        expect(isParallelInstructionPlan(getMessagePackerInstructionPlanFromInstructions([]))).toBe(false);\n        expect(isParallelInstructionPlan(sequentialInstructionPlan([]))).toBe(false);\n        expect(isParallelInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsParallelInstructionPlan', () => {\n    it('does nothing for ParallelInstructionPlan', () => {\n        expect(() => assertIsParallelInstructionPlan(parallelInstructionPlan([]))).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsParallelInstructionPlan(singleInstructionPlan(createInstruction('A')))).toThrow(\n            'Unexpected instruction plan. Expected parallel plan, got single plan.',\n        );\n        expect(() => assertIsParallelInstructionPlan(getMessagePackerInstructionPlanFromInstructions([]))).toThrow(\n            'Unexpected instruction plan. Expected parallel plan, got messagePacker plan.',\n        );\n        expect(() => assertIsParallelInstructionPlan(sequentialInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected parallel plan, got sequential plan.',\n        );\n        expect(() => assertIsParallelInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toThrow(\n            'Unexpected instruction plan. Expected parallel plan, got sequential plan.',\n        );\n    });\n});\n\ndescribe('findInstructionPlan', () => {\n    it('returns the plan itself when it matches the predicate', () => {\n        const instructionA = createInstruction('A');\n        const plan = singleInstructionPlan(instructionA);\n        const result = findInstructionPlan(plan, p => p.kind === 'single');\n        expect(result).toBe(plan);\n    });\n    it('returns undefined when no plan matches the predicate', () => {\n        const instructionA = createInstruction('A');\n        const plan = singleInstructionPlan(instructionA);\n        const result = findInstructionPlan(plan, p => p.kind === 'parallel');\n        expect(result).toBeUndefined();\n    });\n    it('finds a nested plan in a parallel structure', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const nestedSequential = sequentialInstructionPlan([instructionA, instructionB]);\n        const plan = parallelInstructionPlan([nestedSequential]);\n        const result = findInstructionPlan(plan, p => p.kind === 'sequential');\n        expect(result).toBe(nestedSequential);\n    });\n    it('finds a nested plan in a sequential structure', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const nestedParallel = parallelInstructionPlan([instructionA, instructionB]);\n        const plan = sequentialInstructionPlan([nestedParallel]);\n        const result = findInstructionPlan(plan, p => p.kind === 'parallel');\n        expect(result).toBe(nestedParallel);\n    });\n    it('returns the first matching plan in top-down order', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const innerSequential = sequentialInstructionPlan([instructionA]);\n        const outerSequential = sequentialInstructionPlan([innerSequential, instructionB]);\n        const result = findInstructionPlan(outerSequential, p => p.kind === 'sequential');\n        expect(result).toBe(outerSequential);\n    });\n    it('finds a deeply nested plan', () => {\n        const instructionA = createInstruction('A');\n        const deepSingle = singleInstructionPlan(instructionA);\n        const plan = parallelInstructionPlan([sequentialInstructionPlan([parallelInstructionPlan([deepSingle])])]);\n        const result = findInstructionPlan(plan, p => p.kind === 'single');\n        expect(result).toBe(deepSingle);\n    });\n    it('supports complex predicates that inspect nested properties', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const instructionC = createInstruction('C');\n        const targetPlan = sequentialInstructionPlan([instructionA, instructionB]);\n        const plan = parallelInstructionPlan([singleInstructionPlan(instructionC), targetPlan]);\n        const result = findInstructionPlan(\n            plan,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p => p.kind === 'sequential' && p.plans.length === 2,\n        );\n        expect(result).toBe(targetPlan);\n    });\n    it('returns undefined when searching an empty parallel plan', () => {\n        const plan = parallelInstructionPlan([]);\n        const result = findInstructionPlan(plan, p => p.kind === 'single');\n        expect(result).toBeUndefined();\n    });\n    it('finds non-divisible sequential plans', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const nonDivisible = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n        const plan = parallelInstructionPlan([sequentialInstructionPlan([createInstruction('C')]), nonDivisible]);\n        const result = findInstructionPlan(\n            plan,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p => p.kind === 'sequential' && !p.divisible,\n        );\n        expect(result).toBe(nonDivisible);\n    });\n    it('returns undefined when searching a messagePacker plan that does not match', () => {\n        const messagePackerPlan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A')]);\n        const result = findInstructionPlan(messagePackerPlan, p => p.kind === 'single');\n        expect(result).toBeUndefined();\n    });\n    it('finds a messagePacker plan when it matches the predicate', () => {\n        const messagePackerPlan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A')]);\n        const plan = parallelInstructionPlan([singleInstructionPlan(createInstruction('B')), messagePackerPlan]);\n        const result = findInstructionPlan(plan, p => p.kind === 'messagePacker');\n        expect(result).toBe(messagePackerPlan);\n    });\n});\n\ndescribe('everyInstructionPlan', () => {\n    it('returns true when all plans match the predicate', () => {\n        const plan = sequentialInstructionPlan([sequentialInstructionPlan([]), sequentialInstructionPlan([])]);\n        const result = everyInstructionPlan(plan, p => p.kind === 'sequential');\n        expect(result).toBe(true);\n    });\n    it('returns false when at least one plan does not match the predicate', () => {\n        const plan = sequentialInstructionPlan([parallelInstructionPlan([]), sequentialInstructionPlan([])]);\n        const result = everyInstructionPlan(plan, p => p.kind === 'sequential');\n        expect(result).toBe(false);\n    });\n    it('matches single instruction plans', () => {\n        const plan = singleInstructionPlan(createInstruction('A'));\n        const result = everyInstructionPlan(plan, p => p.kind === 'single');\n        expect(result).toBe(true);\n    });\n    it('matches sequential instruction plans', () => {\n        const plan = sequentialInstructionPlan([]);\n        const result = everyInstructionPlan(plan, p => p.kind === 'sequential');\n        expect(result).toBe(true);\n    });\n    it('matches non-divisible sequential instruction plans', () => {\n        const plan = nonDivisibleSequentialInstructionPlan([]);\n        // eslint-disable-next-line jest/no-conditional-in-test\n        const result = everyInstructionPlan(plan, p => p.kind === 'sequential' && !p.divisible);\n        expect(result).toBe(true);\n    });\n    it('matches parallel instruction plans', () => {\n        const plan = parallelInstructionPlan([]);\n        const result = everyInstructionPlan(plan, p => p.kind === 'parallel');\n        expect(result).toBe(true);\n    });\n    it('matches message packer instruction plans', () => {\n        const plan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A')]);\n        const result = everyInstructionPlan(plan, p => p.kind === 'messagePacker');\n        expect(result).toBe(true);\n    });\n    it('matches complex instruction plans', () => {\n        const plan = sequentialInstructionPlan([\n            parallelInstructionPlan([createInstruction('A'), createInstruction('B')]),\n            nonDivisibleSequentialInstructionPlan([createInstruction('A'), createInstruction('C')]),\n        ]);\n        const result = everyInstructionPlan(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind !== 'single') return true;\n            const instruction = p.instruction as ReturnType<typeof createInstruction>;\n            return ['A', 'B', 'C'].includes(instruction.id);\n        });\n        expect(result).toBe(true);\n    });\n    it('returns false on complex instruction plans', () => {\n        const plan = sequentialInstructionPlan([\n            parallelInstructionPlan([createInstruction('A'), createInstruction('B')]),\n            nonDivisibleSequentialInstructionPlan([createInstruction('A'), createInstruction('C')]),\n        ]);\n        const result = everyInstructionPlan(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind !== 'single') return true;\n            const instruction = p.instruction as ReturnType<typeof createInstruction>;\n            return instruction.id === 'A';\n        });\n        expect(result).toBe(false);\n    });\n    it('fails fast before evaluating children', () => {\n        const predicate = jest.fn().mockReturnValueOnce(false);\n        const instructionA = singleInstructionPlan(createInstruction('A'));\n        const instructionB = singleInstructionPlan(createInstruction('B'));\n        const plan = sequentialInstructionPlan([instructionA, instructionB]);\n        const result = everyInstructionPlan(plan, predicate);\n        expect(result).toBe(false);\n        expect(predicate).toHaveBeenCalledTimes(1);\n        expect(predicate).toHaveBeenNthCalledWith(1, plan);\n        expect(predicate).not.toHaveBeenCalledWith(instructionA);\n        expect(predicate).not.toHaveBeenCalledWith(instructionB);\n    });\n    it('fails fast before evaluating siblings', () => {\n        const predicate = jest.fn().mockReturnValueOnce(true).mockReturnValueOnce(false);\n        const instructionA = singleInstructionPlan(createInstruction('A'));\n        const instructionB = singleInstructionPlan(createInstruction('B'));\n        const plan = sequentialInstructionPlan([instructionA, instructionB]);\n        const result = everyInstructionPlan(plan, predicate);\n        expect(result).toBe(false);\n        expect(predicate).toHaveBeenCalledTimes(2);\n        expect(predicate).toHaveBeenNthCalledWith(1, plan);\n        expect(predicate).toHaveBeenNthCalledWith(2, instructionA);\n        expect(predicate).not.toHaveBeenCalledWith(instructionB);\n    });\n});\n\ndescribe('transformInstructionPlan', () => {\n    it('transforms single instruction plans', () => {\n        const plan = singleInstructionPlan(createInstruction('A'));\n        const transformedPlan = transformInstructionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'single' ? { ...p, instruction: { ...p.instruction, id: 'New A' } } : p,\n        );\n        expect(transformedPlan).toStrictEqual(singleInstructionPlan(createInstruction('New A')));\n    });\n    it('transforms message packer instruction plans', () => {\n        const plan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A')]);\n        const transformedPlan = transformInstructionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'messagePacker'\n                ? getMessagePackerInstructionPlanFromInstructions([createInstruction('New A')])\n                : p,\n        );\n        const messagePacker = (transformedPlan as MessagePackerInstructionPlan).getMessagePacker();\n        const message = pipe(createTransactionMessage({ version: 0 }), m =>\n            setTransactionMessageFeePayer('4BpnH9U3n8S4miGz4HYT8LPHrQfa9m3zTDeMaka1g6as' as Address, m),\n        );\n        const packedMessage = messagePacker.packMessageToCapacity(message);\n        expect(messagePacker.done()).toBe(true);\n        expect(packedMessage).toStrictEqual(appendTransactionMessageInstruction(createInstruction('New A'), message));\n    });\n    it('transforms sequential instruction plans', () => {\n        const plan = sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]);\n        const transformedPlan = transformInstructionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'sequential' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            sequentialInstructionPlan([createInstruction('B'), createInstruction('A')]),\n        );\n    });\n    it('transforms non-divisible sequential instruction plans', () => {\n        const plan = nonDivisibleSequentialInstructionPlan([createInstruction('A'), createInstruction('B')]);\n        const transformedPlan = transformInstructionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'sequential' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            nonDivisibleSequentialInstructionPlan([createInstruction('B'), createInstruction('A')]),\n        );\n    });\n    it('transforms parallel instruction plans', () => {\n        const plan = parallelInstructionPlan([createInstruction('A'), createInstruction('B')]);\n        const transformedPlan = transformInstructionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'parallel' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            parallelInstructionPlan([createInstruction('B'), createInstruction('A')]),\n        );\n    });\n    it('transforms using a bottom-up approach', () => {\n        // Given the following nested plans.\n        const plan = sequentialInstructionPlan([\n            createInstruction('A'),\n            sequentialInstructionPlan([createInstruction('B'), createInstruction('C')]),\n        ]);\n\n        // And given an array of instruction IDs that were seen by sequential plans during transformation.\n        const seenInstructionIds: string[] = [];\n\n        // When transforming by prepending \"New \" to single instruction plan IDs\n        // And recording the seen instruction IDs in sequential plans.\n        transformInstructionPlan(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind === 'single') {\n                const instruction = p.instruction as ReturnType<typeof createInstruction>;\n                return { ...p, instruction: { ...instruction, id: `New ${instruction.id}` } };\n            }\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind === 'sequential') {\n                const seenInstructions = p.plans\n                    .filter(subPlan => subPlan.kind === 'single')\n                    .map(subPlan => subPlan.instruction as ReturnType<typeof createInstruction>);\n                seenInstructionIds.push(...seenInstructions.map(instruction => instruction.id));\n            }\n            return p;\n        });\n\n        // Then we expect the seen instruction IDs to have already been transformed\n        // using a bottom-up approach.\n        expect(seenInstructionIds).toStrictEqual(['New B', 'New C', 'New A']);\n    });\n    it('can be used to duplicate instructions', () => {\n        const plan = sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]);\n        const transformedPlan = transformInstructionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'single' ? sequentialInstructionPlan([p.instruction, p.instruction]) : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            sequentialInstructionPlan([\n                sequentialInstructionPlan([createInstruction('A'), createInstruction('A')]),\n                sequentialInstructionPlan([createInstruction('B'), createInstruction('B')]),\n            ]),\n        );\n    });\n    it('can be used to remove parallelism', () => {\n        const plan = parallelInstructionPlan([createInstruction('A'), createInstruction('B')]);\n        const transformedPlan = transformInstructionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'parallel' ? sequentialInstructionPlan(p.plans) : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]),\n        );\n    });\n    it('can be used to flatten nested instruction plans', () => {\n        const plan = sequentialInstructionPlan([\n            sequentialInstructionPlan([createInstruction('A'), createInstruction('B')]),\n            sequentialInstructionPlan([\n                createInstruction('C'),\n                sequentialInstructionPlan([createInstruction('D'), createInstruction('E')]),\n            ]),\n        ]);\n        const transformedPlan = transformInstructionPlan(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind !== 'sequential') return p;\n            const subPlans = p.plans.flatMap(subPlan =>\n                // eslint-disable-next-line jest/no-conditional-in-test\n                subPlan.kind === 'sequential' && p.divisible === subPlan.divisible ? subPlan.plans : [subPlan],\n            );\n            return { ...p, plans: subPlans };\n        });\n        expect(transformedPlan).toStrictEqual(\n            sequentialInstructionPlan([\n                createInstruction('A'),\n                createInstruction('B'),\n                createInstruction('C'),\n                createInstruction('D'),\n                createInstruction('E'),\n            ]),\n        );\n    });\n    it('keeps transformed single instruction plans frozen', () => {\n        const plan = singleInstructionPlan(createInstruction('A'));\n        const transformedPlan = transformInstructionPlan(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed message packer instruction plans frozen', () => {\n        const plan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A')]);\n        const transformedPlan = transformInstructionPlan(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed sequential instruction plans frozen', () => {\n        const plan = sequentialInstructionPlan([createInstruction('A')]);\n        const transformedPlan = transformInstructionPlan(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed parallel instruction plans frozen', () => {\n        const plan = parallelInstructionPlan([createInstruction('A')]);\n        const transformedPlan = transformInstructionPlan(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n});\n\ndescribe('flattenInstructionPlan', () => {\n    it('returns the single instruction plan when given a SingleInstructionPlan', () => {\n        const instructionA = createInstruction('A');\n        const plan = singleInstructionPlan(instructionA);\n        const result = flattenInstructionPlan(plan);\n        expect(result).toStrictEqual([plan]);\n    });\n    it('returns the message packer plan when given a MessagePackerInstructionPlan', () => {\n        const plan = getMessagePackerInstructionPlanFromInstructions([createInstruction('A')]);\n        const result = flattenInstructionPlan(plan);\n        expect(result).toStrictEqual([plan]);\n    });\n    it('returns all leaf plans from a ParallelInstructionPlan', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = parallelInstructionPlan([instructionA, instructionB]);\n        const result = flattenInstructionPlan(plan);\n        expect(result).toStrictEqual([singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)]);\n    });\n    it('returns all leaf plans from a SequentialInstructionPlan', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const plan = sequentialInstructionPlan([instructionA, instructionB]);\n        const result = flattenInstructionPlan(plan);\n        expect(result).toStrictEqual([singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)]);\n    });\n    it('returns all leaf plans from a complex nested structure', () => {\n        const instructionA = createInstruction('A');\n        const instructionB = createInstruction('B');\n        const instructionC = createInstruction('C');\n        const instructionD = createInstruction('D');\n        const instructionE = createInstruction('E');\n        const messagePackerPlan = getMessagePackerInstructionPlanFromInstructions([createInstruction('F')]);\n        const plan = parallelInstructionPlan([\n            sequentialInstructionPlan([instructionA, instructionB]),\n            nonDivisibleSequentialInstructionPlan([instructionC, instructionD]),\n            instructionE,\n            messagePackerPlan,\n        ]);\n        const result = flattenInstructionPlan(plan);\n        expect(result).toStrictEqual([\n            singleInstructionPlan(instructionA),\n            singleInstructionPlan(instructionB),\n            singleInstructionPlan(instructionC),\n            singleInstructionPlan(instructionD),\n            singleInstructionPlan(instructionE),\n            messagePackerPlan,\n        ]);\n    });\n});\n\ndescribe('isInstructionPlan', () => {\n    it('returns true for SingleInstructionPlan', () => {\n        expect(isInstructionPlan(singleInstructionPlan(createInstruction('A')))).toBe(true);\n    });\n    it('returns true for ParallelInstructionPlan', () => {\n        expect(isInstructionPlan(parallelInstructionPlan([]))).toBe(true);\n    });\n    it('returns true for SequentialInstructionPlan', () => {\n        expect(isInstructionPlan(sequentialInstructionPlan([]))).toBe(true);\n    });\n    it('returns true for non-divisible SequentialInstructionPlan', () => {\n        expect(isInstructionPlan(nonDivisibleSequentialInstructionPlan([]))).toBe(true);\n    });\n    it('returns true for MessagePackerInstructionPlan', () => {\n        expect(isInstructionPlan(getMessagePackerInstructionPlanFromInstructions([]))).toBe(true);\n    });\n    it('returns false for non-objects', () => {\n        expect(isInstructionPlan(null)).toBe(false);\n        expect(isInstructionPlan(undefined)).toBe(false);\n        expect(isInstructionPlan('string')).toBe(false);\n        expect(isInstructionPlan(123)).toBe(false);\n        expect(isInstructionPlan(true)).toBe(false);\n    });\n    it('returns false for objects without planType', () => {\n        expect(isInstructionPlan({ kind: 'single' })).toBe(false);\n    });\n    it('returns false for objects with wrong planType', () => {\n        expect(isInstructionPlan({ planType: 123 })).toBe(false);\n        expect(isInstructionPlan({ planType: null })).toBe(false);\n        expect(isInstructionPlan({ planType: 'transactionPlan' })).toBe(false);\n        expect(isInstructionPlan({ planType: 'transactionPlanResult' })).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/transaction-plan-errors-test.ts",
    "content": "import {\n    type RpcSimulateTransactionResult,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE,\n    SolanaError,\n} from '@solana/errors';\nimport { Signature } from '@solana/keys';\n\nimport {\n    canceledSingleTransactionPlanResult,\n    createFailedToExecuteTransactionPlanError,\n    createFailedToSendTransactionError,\n    createFailedToSendTransactionsError,\n    failedSingleTransactionPlanResult,\n    parallelTransactionPlanResult,\n    sequentialTransactionPlanResult,\n    successfulSingleTransactionPlanResult,\n} from '../index';\nimport { createMessage } from './__setup__';\n\nconst preflightContext: Omit<RpcSimulateTransactionResult, 'err'> = {\n    accounts: null,\n    fee: null,\n    loadedAccountsDataSize: null,\n    loadedAddresses: { readonly: [], writable: [] },\n    logs: ['Program log: Instruction: Transfer', 'Program failed: insufficient funds'],\n    postBalances: null,\n    postTokenBalances: null,\n    preBalances: null,\n    preTokenBalances: null,\n    replacementBlockhash: null,\n    returnData: null,\n    unitsConsumed: null,\n};\n\nconst preflightContextWithoutLogs: Omit<RpcSimulateTransactionResult, 'err'> = {\n    accounts: null,\n    fee: null,\n    loadedAccountsDataSize: null,\n    loadedAddresses: { readonly: [], writable: [] },\n    logs: null,\n    postBalances: null,\n    postTokenBalances: null,\n    preBalances: null,\n    preTokenBalances: null,\n    replacementBlockhash: null,\n    returnData: null,\n    unitsConsumed: null,\n};\n\nfunction createPreflightError(\n    causeError: Error,\n    context: Omit<RpcSimulateTransactionResult, 'err'>,\n): SolanaError<typeof SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE> {\n    return new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE, {\n        ...context,\n        cause: causeError,\n    });\n}\n\ndescribe('createFailedToSendTransactionError', () => {\n    describe('given a failed result with a preflight error', () => {\n        it('unwraps the preflight error and sets the cause to the inner error', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContext);\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.cause).toBe(innerError);\n        });\n\n        it('sets preflightData from the preflight error context', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContext);\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.context.preflightData).toEqual(preflightContext);\n        });\n\n        it('sets logs as a shortcut to preflightData.logs', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContext);\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.context.logs).toEqual(preflightContext.logs);\n            expect(error.context.logs).toEqual(error.context.preflightData?.logs);\n        });\n\n        it('sets logs to undefined when preflight logs are null', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContextWithoutLogs);\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.context.logs).toBeUndefined();\n        });\n\n        it('includes (preflight) in the causeMessage', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContext);\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.context.causeMessage).toContain('(preflight)');\n        });\n\n        it('produces the expected error message', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, { ...preflightContext, logs: [] });\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe(`Failed to send transaction (preflight): ${innerError.message}`);\n        });\n    });\n\n    describe('given a failed result without a preflight error', () => {\n        it('uses the error directly as the cause', () => {\n            const plainError = new Error('Connection refused');\n            const result = failedSingleTransactionPlanResult(createMessage('A'), plainError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.cause).toBe(plainError);\n        });\n\n        it('sets preflightData to undefined', () => {\n            const plainError = new Error('Connection refused');\n            const result = failedSingleTransactionPlanResult(createMessage('A'), plainError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.context.preflightData).toBeUndefined();\n        });\n\n        it('sets logs to undefined', () => {\n            const plainError = new Error('Connection refused');\n            const result = failedSingleTransactionPlanResult(createMessage('A'), plainError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.context.logs).toBeUndefined();\n        });\n\n        it('produces the expected error message without an indicator', () => {\n            const plainError = new Error('Connection refused');\n            const result = failedSingleTransactionPlanResult(createMessage('A'), plainError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe('Failed to send transaction: Connection refused');\n        });\n    });\n\n    describe('given a failed result with a signature in the context', () => {\n        it('includes the full signature in the causeMessage', () => {\n            const plainError = new Error('Transaction failed');\n            const signature =\n                '5wHu1qwD7q5ifaN5nwdcDQNbHUiCfnzJ6vaR98NLugS1CiVfCZLMGmmFaKCAVfPTFE5KPMhSaZaLo2v4xXSHVJk' as Signature;\n            const result = failedSingleTransactionPlanResult(createMessage('A'), plainError, { signature });\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe(`Failed to send transaction (${signature}): Transaction failed`);\n        });\n    });\n\n    describe('given a failed result with a compute-limit simulation error', () => {\n        it('unwraps the simulation error', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const simulationError = new SolanaError(\n                SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n                { ...preflightContext, cause: innerError },\n            );\n            const result = failedSingleTransactionPlanResult(createMessage('A'), simulationError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.cause).toBe(innerError);\n        });\n\n        it('sets preflightData from the simulation error context', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const simulationError = new SolanaError(\n                SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n                { ...preflightContext, cause: innerError },\n            );\n            const result = failedSingleTransactionPlanResult(createMessage('A'), simulationError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.context.preflightData).toEqual(preflightContext);\n        });\n\n        it('sets logs from the simulation error context', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const simulationError = new SolanaError(\n                SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n                { ...preflightContext, cause: innerError },\n            );\n            const result = failedSingleTransactionPlanResult(createMessage('A'), simulationError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.context.logs).toEqual(preflightContext.logs);\n        });\n    });\n\n    describe('log snippet in error message', () => {\n        it('appends the last 8 log lines when there are more than 8 logs', () => {\n            const logs = Array.from({ length: 12 }, (_, i) => `Log line ${i + 1}`);\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, { ...preflightContext, logs });\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe(\n                `Failed to send transaction (preflight): ${innerError.message}\\n\\n` +\n                    'Logs (last 8 of 12):\\n' +\n                    '  > Log line 5\\n' +\n                    '  > Log line 6\\n' +\n                    '  > Log line 7\\n' +\n                    '  > Log line 8\\n' +\n                    '  > Log line 9\\n' +\n                    '  > Log line 10\\n' +\n                    '  > Log line 11\\n' +\n                    '  > Log line 12\\n',\n            );\n        });\n\n        it('appends all log lines when there are 8 or fewer logs', () => {\n            const logs = ['Log A', 'Log B', 'Log C'];\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, { ...preflightContext, logs });\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe(\n                `Failed to send transaction (preflight): ${innerError.message}\\n\\n` +\n                    'Logs:\\n' +\n                    '  > Log A\\n' +\n                    '  > Log B\\n' +\n                    '  > Log C\\n',\n            );\n        });\n\n        it('does not append logs when logs are undefined', () => {\n            const plainError = new Error('Connection refused');\n            const result = failedSingleTransactionPlanResult(createMessage('A'), plainError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe('Failed to send transaction: Connection refused');\n        });\n\n        it('does not append logs when preflight logs are null', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContextWithoutLogs);\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe(`Failed to send transaction (preflight): ${innerError.message}`);\n        });\n\n        it('does not append logs when logs array is empty', () => {\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, { ...preflightContext, logs: [] });\n            const result = failedSingleTransactionPlanResult(createMessage('A'), preflightError);\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe(`Failed to send transaction (preflight): ${innerError.message}`);\n        });\n    });\n\n    describe('given a canceled result with an abort reason', () => {\n        it('sets the cause to the abort reason', () => {\n            const abortReason = new Error('User canceled');\n            const result = canceledSingleTransactionPlanResult(createMessage('A'));\n            const error = createFailedToSendTransactionError(result, abortReason);\n            expect(error.cause).toBe(abortReason);\n        });\n\n        it('includes the abort reason in the causeMessage', () => {\n            const abortReason = new Error('User canceled');\n            const result = canceledSingleTransactionPlanResult(createMessage('A'));\n            const error = createFailedToSendTransactionError(result, abortReason);\n            expect(error.message).toBe('Failed to send transaction. Canceled with abort reason: Error: User canceled');\n        });\n\n        it('does not set preflightData or logs', () => {\n            const result = canceledSingleTransactionPlanResult(createMessage('A'));\n            const error = createFailedToSendTransactionError(result, new Error('abort'));\n            expect(error.context.preflightData).toBeUndefined();\n            expect(error.context.logs).toBeUndefined();\n        });\n    });\n\n    describe('given a canceled result without an abort reason', () => {\n        it('produces the expected error message', () => {\n            const result = canceledSingleTransactionPlanResult(createMessage('A'));\n            const error = createFailedToSendTransactionError(result);\n            expect(error.message).toBe('Failed to send transaction: Canceled');\n        });\n\n        it('sets the cause to undefined', () => {\n            const result = canceledSingleTransactionPlanResult(createMessage('A'));\n            const error = createFailedToSendTransactionError(result);\n            expect(error.cause).toBeUndefined();\n        });\n    });\n\n    it('sets transactionPlanResult as a non-enumerable property', () => {\n        const plainError = new Error('fail');\n        const result = failedSingleTransactionPlanResult(createMessage('A'), plainError);\n        const error = createFailedToSendTransactionError(result);\n        expect(error.context.transactionPlanResult).toBe(result);\n        expect(Object.keys(error.context)).not.toContain('transactionPlanResult');\n    });\n\n    it('has the correct error code', () => {\n        const plainError = new Error('fail');\n        const result = failedSingleTransactionPlanResult(createMessage('A'), plainError);\n        const error = createFailedToSendTransactionError(result);\n        expect(error.context.__code).toBe(SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION);\n    });\n});\n\ndescribe('createFailedToSendTransactionsError', () => {\n    describe('given a result with mixed failed, canceled, and successful transactions', () => {\n        it('only includes failed transactions in failedTransactions', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const errorB = new Error('B failed');\n            const result = sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResult(messageA, {\n                    signature: '11111111111111111111111111111111111111111111' as Signature,\n                }),\n                failedSingleTransactionPlanResult(messageB, errorB),\n                canceledSingleTransactionPlanResult(messageC),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.context.failedTransactions).toHaveLength(1);\n        });\n\n        it('uses 0-based indices from the flattened result array', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const errorB = new Error('B failed');\n            const result = sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResult(messageA, {\n                    signature: '11111111111111111111111111111111111111111111' as Signature,\n                }),\n                failedSingleTransactionPlanResult(messageB, errorB),\n                canceledSingleTransactionPlanResult(messageC),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.context.failedTransactions[0].index).toBe(1);\n        });\n\n        it('produces the expected error message', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const errorA = new Error('A failed');\n            const errorB = new Error('B failed');\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, errorA),\n                failedSingleTransactionPlanResult(messageB, errorB),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.message).toBe('Failed to send transactions.\\n[Tx #1] A failed\\n[Tx #2] B failed\\n');\n        });\n\n        it('sets the cause to the error when there is exactly one failure', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const errorA = new Error('A failed');\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, errorA),\n                canceledSingleTransactionPlanResult(messageB),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.cause).toBe(errorA);\n        });\n\n        it('does not set the cause when there are multiple failures', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const errorA = new Error('A failed');\n            const errorB = new Error('B failed');\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, errorA),\n                failedSingleTransactionPlanResult(messageB, errorB),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.cause).toBeUndefined();\n        });\n    });\n\n    describe('given failures with preflight errors', () => {\n        it('includes (preflight) indicator in causeMessages', () => {\n            const messageA = createMessage('A');\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContext);\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, preflightError),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.context.causeMessages).toContain('(preflight)');\n        });\n\n        it('unwraps the preflight error in failedTransactions entries', () => {\n            const messageA = createMessage('A');\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContext);\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, preflightError),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.context.failedTransactions[0].error).toBe(innerError);\n            expect(error.context.failedTransactions[0].preflightData).toEqual(preflightContext);\n        });\n\n        it('sets logs on failedTransactions entries', () => {\n            const messageA = createMessage('A');\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContext);\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, preflightError),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.context.failedTransactions[0].logs).toEqual(preflightContext.logs);\n        });\n    });\n\n    describe('given failures with signatures in the context', () => {\n        it('includes the signature in causeMessages', () => {\n            const messageA = createMessage('A');\n            const signature =\n                '5wHu1qwD7q5ifaN5nwdcDQNbHUiCfnzJ6vaR98NLugS1CiVfCZLMGmmFaKCAVfPTFE5KPMhSaZaLo2v4xXSHVJk' as Signature;\n            const plainError = new Error('Transaction failed');\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, plainError, { signature }),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.message).toBe(`Failed to send transactions.\\n[Tx #1 (${signature})] Transaction failed\\n`);\n        });\n    });\n\n    describe('log snippet in error message', () => {\n        it('appends logs when there is exactly one failed transaction with logs', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, preflightContext);\n            const result = sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResult(messageA, {\n                    signature: '11111111111111111111111111111111111111111111' as Signature,\n                }),\n                failedSingleTransactionPlanResult(messageB, preflightError),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.message).toBe(\n                `Failed to send transactions.\\n[Tx #2 (preflight)] ${innerError.message}\\n\\n` +\n                    'Logs:\\n' +\n                    '  > Program log: Instruction: Transfer\\n' +\n                    '  > Program failed: insufficient funds\\n',\n            );\n        });\n\n        it('appends the last 8 log lines with truncation indicator when there are more than 8 logs', () => {\n            const logs = Array.from({ length: 10 }, (_, i) => `Log line ${i + 1}`);\n            const messageA = createMessage('A');\n            const innerError = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightError = createPreflightError(innerError, { ...preflightContext, logs });\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, preflightError),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.message).toBe(\n                `Failed to send transactions.\\n[Tx #1 (preflight)] ${innerError.message}\\n\\n` +\n                    'Logs (last 8 of 10):\\n' +\n                    '  > Log line 3\\n' +\n                    '  > Log line 4\\n' +\n                    '  > Log line 5\\n' +\n                    '  > Log line 6\\n' +\n                    '  > Log line 7\\n' +\n                    '  > Log line 8\\n' +\n                    '  > Log line 9\\n' +\n                    '  > Log line 10\\n',\n            );\n        });\n\n        it('does not append logs when there are multiple failed transactions', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const innerErrorA = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightErrorA = createPreflightError(innerErrorA, preflightContext);\n            const innerErrorB = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n            const preflightErrorB = createPreflightError(innerErrorB, preflightContext);\n            const result = sequentialTransactionPlanResult([\n                failedSingleTransactionPlanResult(messageA, preflightErrorA),\n                failedSingleTransactionPlanResult(messageB, preflightErrorB),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.message).toBe(\n                `Failed to send transactions.\\n[Tx #1 (preflight)] ${innerErrorA.message}\\n` +\n                    `[Tx #2 (preflight)] ${innerErrorB.message}\\n`,\n            );\n        });\n\n        it('does not append logs when the single failed transaction has no logs', () => {\n            const messageA = createMessage('A');\n            const plainError = new Error('Connection refused');\n            const result = sequentialTransactionPlanResult([failedSingleTransactionPlanResult(messageA, plainError)]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.message).toBe('Failed to send transactions.\\n[Tx #1] Connection refused\\n');\n        });\n    });\n\n    describe('given all canceled results with an abort reason', () => {\n        it('produces a single-line canceled message', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const abortReason = new Error('User aborted');\n            const result = sequentialTransactionPlanResult([\n                canceledSingleTransactionPlanResult(messageA),\n                canceledSingleTransactionPlanResult(messageB),\n            ]);\n            const error = createFailedToSendTransactionsError(result, abortReason);\n            expect(error.message).toBe(\n                `Failed to send transactions. Canceled with abort reason: ${String(abortReason)}`,\n            );\n        });\n\n        it('has an empty failedTransactions array', () => {\n            const messageA = createMessage('A');\n            const result = sequentialTransactionPlanResult([canceledSingleTransactionPlanResult(messageA)]);\n            const error = createFailedToSendTransactionsError(result, new Error('abort'));\n            expect(error.context.failedTransactions).toHaveLength(0);\n        });\n\n        it('sets the cause to the abort reason', () => {\n            const messageA = createMessage('A');\n            const abortReason = new Error('User aborted');\n            const result = sequentialTransactionPlanResult([canceledSingleTransactionPlanResult(messageA)]);\n            const error = createFailedToSendTransactionsError(result, abortReason);\n            expect(error.cause).toBe(abortReason);\n        });\n    });\n\n    describe('given all canceled results without an abort reason', () => {\n        it('produces a single-line canceled message', () => {\n            const messageA = createMessage('A');\n            const result = sequentialTransactionPlanResult([canceledSingleTransactionPlanResult(messageA)]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.message).toBe('Failed to send transactions: Canceled');\n        });\n    });\n\n    describe('given a complex nested result', () => {\n        it('flattens the result tree and uses correct indices', () => {\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const messageD = createMessage('D');\n            const errorB = new Error('B failed');\n            const errorD = new Error('D failed');\n            const result = sequentialTransactionPlanResult([\n                parallelTransactionPlanResult([\n                    successfulSingleTransactionPlanResult(messageA, {\n                        signature: '11111111111111111111111111111111111111111111' as Signature,\n                    }),\n                    failedSingleTransactionPlanResult(messageB, errorB),\n                ]),\n                sequentialTransactionPlanResult([\n                    canceledSingleTransactionPlanResult(messageC),\n                    failedSingleTransactionPlanResult(messageD, errorD),\n                ]),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.context.failedTransactions).toHaveLength(2);\n            // messageB is index 1 in the flattened [A, B, C, D] array\n            expect(error.context.failedTransactions[0].index).toBe(1);\n            // messageD is index 3 in the flattened [A, B, C, D] array\n            expect(error.context.failedTransactions[1].index).toBe(3);\n        });\n\n        it('produces the expected error message with varied failure indicators', () => {\n            const sigB =\n                '2RocoT4bGn3GDCCkwBmpipjYHP1RWdoSxVUvMBqRTMFCnmFi2VoSuQhRYoP69NDPH8FPr4a3gH6JkJBJGP2DX2i' as Signature;\n            const sigD =\n                '5wHu1qwD7q5ifaN5nwdcDQNbHUiCfnzJ6vaR98NLugS1CiVfCZLMGmmFaKCAVfPTFE5KPMhSaZaLo2v4xXSHVJk' as Signature;\n            // Flattened: [A(ok), B(preflight+sig), C(canceled), D(sig only), E(ok), F(preflight), G(plain), H(canceled)]\n            const result = sequentialTransactionPlanResult([\n                parallelTransactionPlanResult([\n                    successfulSingleTransactionPlanResult(createMessage('A'), {\n                        signature: '11111111111111111111111111111111111111111111' as Signature,\n                    }),\n                    // Tx #2: preflight error with signature — should show (preflight)\n                    failedSingleTransactionPlanResult(\n                        createMessage('B'),\n                        createPreflightError(new Error('B failed'), preflightContext),\n                        { signature: sigB },\n                    ),\n                ]),\n                canceledSingleTransactionPlanResult(createMessage('C')),\n                sequentialTransactionPlanResult([\n                    // Tx #4: plain error with signature — should show (signature)\n                    failedSingleTransactionPlanResult(createMessage('D'), new Error('D failed'), { signature: sigD }),\n                    successfulSingleTransactionPlanResult(createMessage('E'), {\n                        signature: '22222222222222222222222222222222222222222222' as Signature,\n                    }),\n                    // Tx #6: preflight error without signature — should show (preflight)\n                    failedSingleTransactionPlanResult(\n                        createMessage('F'),\n                        createPreflightError(new Error('F failed'), preflightContext),\n                    ),\n                    // Tx #7: plain error without signature — no indicator\n                    failedSingleTransactionPlanResult(createMessage('G'), new Error('G failed')),\n                ]),\n                canceledSingleTransactionPlanResult(createMessage('H')),\n            ]);\n            const error = createFailedToSendTransactionsError(result);\n            expect(error.message).toBe(\n                'Failed to send transactions.\\n' +\n                    '[Tx #2 (preflight)] B failed\\n' +\n                    `[Tx #4 (${sigD})] D failed\\n` +\n                    '[Tx #6 (preflight)] F failed\\n' +\n                    '[Tx #7] G failed\\n',\n            );\n        });\n    });\n\n    it('sets transactionPlanResult as a non-enumerable property', () => {\n        const messageA = createMessage('A');\n        const errorA = new Error('A failed');\n        const result = sequentialTransactionPlanResult([failedSingleTransactionPlanResult(messageA, errorA)]);\n        const error = createFailedToSendTransactionsError(result);\n        expect(error.context.transactionPlanResult).toBe(result);\n        expect(Object.keys(error.context)).not.toContain('transactionPlanResult');\n    });\n\n    it('has the correct error code', () => {\n        const messageA = createMessage('A');\n        const errorA = new Error('A failed');\n        const result = sequentialTransactionPlanResult([failedSingleTransactionPlanResult(messageA, errorA)]);\n        const error = createFailedToSendTransactionsError(result);\n        expect(error.context.__code).toBe(SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS);\n    });\n});\n\ndescribe('createFailedToExecuteTransactionPlanError', () => {\n    it('has the correct error code', () => {\n        const result = sequentialTransactionPlanResult([\n            failedSingleTransactionPlanResult(createMessage('A'), new Error('A failed')),\n        ]);\n        const error = createFailedToExecuteTransactionPlanError(result);\n        expect(error.context.__code).toBe(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN);\n    });\n\n    it('sets transactionPlanResult as a non-enumerable property', () => {\n        const result = sequentialTransactionPlanResult([\n            failedSingleTransactionPlanResult(createMessage('A'), new Error('A failed')),\n        ]);\n        const error = createFailedToExecuteTransactionPlanError(result);\n        expect(error.context.transactionPlanResult).toBe(result);\n        expect(Object.keys(error.context)).not.toContain('transactionPlanResult');\n    });\n\n    it('sets abortReason in the context when provided', () => {\n        const abortReason = new Error('User canceled');\n        const result = sequentialTransactionPlanResult([canceledSingleTransactionPlanResult(createMessage('A'))]);\n        const error = createFailedToExecuteTransactionPlanError(result, abortReason);\n        expect(error.context.abortReason).toBe(abortReason);\n    });\n\n    it('sets abortReason to undefined when not provided', () => {\n        const result = sequentialTransactionPlanResult([\n            failedSingleTransactionPlanResult(createMessage('A'), new Error('A failed')),\n        ]);\n        const error = createFailedToExecuteTransactionPlanError(result);\n        expect(error.context.abortReason).toBeUndefined();\n    });\n});\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/transaction-plan-executor-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE,\n    SolanaError,\n} from '@solana/errors';\nimport { Signature } from '@solana/keys';\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport {\n    canceledSingleTransactionPlanResult,\n    createTransactionPlanExecutor,\n    failedSingleTransactionPlanResult,\n    nonDivisibleSequentialTransactionPlan,\n    parallelTransactionPlan,\n    parallelTransactionPlanResult,\n    passthroughFailedTransactionPlanExecution,\n    sequentialTransactionPlan,\n    sequentialTransactionPlanResult,\n    singleTransactionPlan,\n    successfulSingleTransactionPlanResult,\n    successfulSingleTransactionPlanResultFromTransaction,\n    TransactionPlanResult,\n} from '../index';\nimport { createMessage, createTransaction, FOREVER_PROMISE } from './__setup__';\n\njest.useFakeTimers();\n\nasync function expectFailedToExecute(\n    promise: Promise<TransactionPlanResult>,\n    error: SolanaError<typeof SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN>,\n): Promise<void> {\n    const transactionPlanResult = error.context.transactionPlanResult;\n    // Check for the error code and message (but not the full context since transactionPlanResult is non-enumerable)\n    await expect(promise).rejects.toThrow(\n        expect.objectContaining({\n            context: expect.objectContaining({\n                __code: SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n            }),\n            name: 'SolanaError',\n        }),\n    );\n    // This second expectation checks for transactionPlanResult which is a non-enumerable property\n    await expect(promise).rejects.toThrow(\n        expect.objectContaining({ context: expect.objectContaining({ transactionPlanResult }) }),\n    );\n}\n\nfunction forwardId(_: unknown, message: TransactionMessage & TransactionMessageWithFeePayer) {\n    return Promise.resolve(\n        createTransaction((message as TransactionMessage & TransactionMessageWithFeePayer & { id: string }).id),\n    );\n}\n\ndescribe('createTransactionPlanExecutor', () => {\n    describe('single scenarios', () => {\n        it('successfully executes a single transaction message', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const transactionA = createTransaction('A');\n            const executeTransactionMessage = jest.fn().mockResolvedValue(transactionA);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expect(promise).resolves.toStrictEqual(\n                successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n            );\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(1, expect.any(Object), messageA, {\n                abortSignal: undefined,\n            });\n        });\n\n        it('passes the abort signal to the `executeTransactionMessage` function', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const executeTransactionMessage = jest.fn().mockResolvedValue(createTransaction('A'));\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            await executor(singleTransactionPlan(messageA), { abortSignal });\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(1, expect.any(Object), messageA, { abortSignal });\n        });\n\n        it('uses the returned signature for the successful context', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: () => Promise.resolve('A' as Signature),\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expect(promise).resolves.toStrictEqual(\n                successfulSingleTransactionPlanResult(messageA, { signature: 'A' as Signature }),\n            );\n        });\n\n        it('uses the signature from the returned transaction for the successful context', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const transactionA = createTransaction('A');\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: () => Promise.resolve(transactionA),\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expect(promise).resolves.toStrictEqual(\n                successfulSingleTransactionPlanResult(messageA, {\n                    signature: 'A' as Signature,\n                    transaction: transactionA,\n                }),\n            );\n        });\n\n        it('override any set signature with the returned signature', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: context => {\n                    context.signature = 'CONTEXT_SIGNATURE' as Signature;\n                    return Promise.resolve('RETURNED_SIGNATURE' as Signature);\n                },\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expect(promise).resolves.toStrictEqual(\n                successfulSingleTransactionPlanResult(messageA, { signature: 'RETURNED_SIGNATURE' as Signature }),\n            );\n        });\n\n        it('override any set signature with the signature of the returned transaction', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const transactionA = createTransaction('A');\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: context => {\n                    context.signature = 'CONTEXT_SIGNATURE' as Signature;\n                    return Promise.resolve(transactionA);\n                },\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expect(promise).resolves.toStrictEqual(\n                successfulSingleTransactionPlanResult(messageA, {\n                    signature: 'A' as Signature,\n                    transaction: transactionA,\n                }),\n            );\n        });\n\n        it('override any set transaction with the returned transaction', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const transactionA = createTransaction('A');\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: context => {\n                    context.transaction = createTransaction('B');\n                    return Promise.resolve(transactionA);\n                },\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expect(promise).resolves.toStrictEqual(\n                successfulSingleTransactionPlanResult(messageA, {\n                    signature: 'A' as Signature,\n                    transaction: transactionA,\n                }),\n            );\n        });\n\n        it('stores the base context', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const transactionA = createTransaction('A');\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: (context, _) => {\n                    context.message = createMessage('NEW A');\n                    context.transaction = transactionA;\n                    context.signature = 'A' as Signature;\n                    return Promise.resolve(transactionA);\n                },\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expect(promise).resolves.toStrictEqual(\n                successfulSingleTransactionPlanResult(messageA, {\n                    message: createMessage('NEW A'),\n                    signature: 'A' as Signature,\n                    transaction: transactionA,\n                }),\n            );\n        });\n\n        it('stores custom context properties', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const executor = createTransactionPlanExecutor<{ custom: string }>({\n                executeTransactionMessage: context => {\n                    context.custom = 'custom value';\n                    context.message = messageB;\n                    return Promise.resolve('A' as Signature);\n                },\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expect(promise).resolves.toStrictEqual(\n                successfulSingleTransactionPlanResult(messageA, {\n                    custom: 'custom value',\n                    message: messageB,\n                    signature: 'A' as Signature,\n                }),\n            );\n        });\n\n        it('fails to execute a single transaction message when the executor function rejects', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const cause = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT, { index: 0 });\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: () => Promise.reject(cause),\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: failedSingleTransactionPlanResult(messageA, cause),\n                }),\n            );\n        });\n\n        it('keeps all information provided to the context before failure', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const transactionA = createTransaction('A');\n            const cause = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT, { index: 0 });\n            const throwCause = (): void => {\n                throw cause;\n            };\n            const executor = createTransactionPlanExecutor<{ afterFailure: string; beforeFailure: string }>({\n                executeTransactionMessage: async context => {\n                    context.beforeFailure = 'before failure';\n                    context.message = messageB;\n                    context.transaction = transactionA;\n                    context.signature = 'B' as Signature;\n                    throwCause();\n                    context.afterFailure = 'after failure';\n                    return await Promise.resolve('C' as Signature);\n                },\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: failedSingleTransactionPlanResult(messageA, cause, {\n                        beforeFailure: 'before failure',\n                        message: messageB,\n                        signature: 'B' as Signature,\n                        transaction: transactionA,\n                    }),\n                }),\n            );\n        });\n\n        it('adds the signature to a failed context if a transaction is present', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const transactionA = createTransaction('A');\n            const cause = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT, { index: 0 });\n            const throwCause = (): void => {\n                throw cause;\n            };\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: async context => {\n                    context.transaction = transactionA;\n                    throwCause();\n                    return await Promise.resolve(transactionA);\n                },\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: failedSingleTransactionPlanResult(messageA, cause, {\n                        signature: 'A' as Signature,\n                        transaction: transactionA,\n                    }),\n                }),\n            );\n        });\n\n        it('can use any error object as a failure cause', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const cause = new Error('Custom error message');\n            const executor = createTransactionPlanExecutor({\n                executeTransactionMessage: () => Promise.reject(cause),\n            });\n\n            const promise = executor(singleTransactionPlan(messageA));\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: failedSingleTransactionPlanResult(messageA, cause),\n                }),\n            );\n        });\n\n        it('can abort single transaction plans', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const cause = new Error('Aborted during execution');\n            const executeTransactionMessage = jest.fn().mockReturnValueOnce(FOREVER_PROMISE);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(singleTransactionPlan(messageA), { abortSignal });\n            await jest.runAllTimersAsync();\n            abortController.abort(cause);\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: failedSingleTransactionPlanResult(messageA, cause),\n                }),\n            );\n        });\n\n        it('can abort single transaction plans before execution', async () => {\n            expect.assertions(3);\n            const messageA = createMessage('A');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const cause = new Error('Aborted before execution');\n            const executeTransactionMessage = jest.fn().mockReturnValueOnce(FOREVER_PROMISE);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            abortController.abort(cause);\n            const promise = executor(singleTransactionPlan(messageA), { abortSignal });\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: canceledSingleTransactionPlanResult(messageA),\n                }),\n            );\n\n            expect(executeTransactionMessage).not.toHaveBeenCalled();\n        });\n\n        it('includes the abort reason in the error context', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const abortReason = new Error('User canceled');\n            const executeTransactionMessage = jest.fn().mockReturnValueOnce(FOREVER_PROMISE);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(singleTransactionPlan(messageA), { abortSignal });\n            await jest.runAllTimersAsync();\n            abortController.abort(abortReason);\n\n            await expect(promise).rejects.toThrow(\n                expect.objectContaining({\n                    context: expect.objectContaining({\n                        abortReason,\n                    }),\n                }),\n            );\n        });\n\n        it('freezes the returned single transaction plan result', async () => {\n            expect.assertions(1);\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const result = await executor(singleTransactionPlan(createMessage('A')));\n            expect(result).toBeFrozenObject();\n        });\n    });\n\n    describe('sequential scenarios', () => {\n        it('successfully executes a sequential transaction plan', async () => {\n            expect.assertions(4);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(sequentialTransactionPlan([messageA, messageB]));\n            await expect(promise).resolves.toStrictEqual(\n                sequentialTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                    successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B')),\n                ]),\n            );\n\n            expect(executeTransactionMessage).toHaveBeenCalledTimes(2);\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(1, expect.any(Object), messageA, {\n                abortSignal: undefined,\n            });\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(2, expect.any(Object), messageB, {\n                abortSignal: undefined,\n            });\n        });\n\n        it('throws when encountering a non-divisible sequential transaction plan', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(nonDivisibleSequentialTransactionPlan([messageA, messageB]));\n            await expect(promise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED),\n            );\n        });\n\n        it('does no execute transactions before checking for non-divisible plans', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            await executor(\n                sequentialTransactionPlan([messageA, nonDivisibleSequentialTransactionPlan([messageB, messageC])]),\n            ).catch(() => {});\n            expect(executeTransactionMessage).not.toHaveBeenCalled();\n        });\n\n        it('passes the abort signal to the `executeTransactionMessage` function', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            await executor(sequentialTransactionPlan([messageA, messageB]), { abortSignal });\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(1, expect.any(Object), messageA, { abortSignal });\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(2, expect.any(Object), messageB, { abortSignal });\n        });\n\n        it('executes a sequential transaction plan with custom context', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const executor = createTransactionPlanExecutor<{ custom: string }>({\n                executeTransactionMessage: (context, message) => {\n                    const id = (message as TransactionMessage & TransactionMessageWithFeePayer & { id: string }).id;\n                    context.custom = 'Message ' + id;\n                    return forwardId(context, message);\n                },\n            });\n\n            const promise = executor(sequentialTransactionPlan([messageA, messageB]));\n            await expect(promise).resolves.toStrictEqual(\n                sequentialTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A'), {\n                        custom: 'Message A',\n                    }),\n                    successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B'), {\n                        custom: 'Message B',\n                    }),\n                ]),\n            );\n        });\n\n        it('fails to execute a sequential transaction plan when the executor function rejects', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const cause = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT, { index: 0 });\n            const executeTransactionMessage = jest.fn().mockImplementationOnce(forwardId).mockRejectedValueOnce(cause);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(sequentialTransactionPlan([messageA, messageB]));\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: sequentialTransactionPlanResult([\n                        successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                        failedSingleTransactionPlanResult(messageB, cause),\n                    ]),\n                }),\n            );\n        });\n\n        it('cancels subsequent plans after one fails', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const cause = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT, { index: 0 });\n            const executeTransactionMessage = jest.fn().mockRejectedValueOnce(cause).mockImplementationOnce(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(sequentialTransactionPlan([messageA, messageB]));\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: sequentialTransactionPlanResult([\n                        failedSingleTransactionPlanResult(messageA, cause),\n                        canceledSingleTransactionPlanResult(messageB),\n                    ]),\n                }),\n            );\n        });\n\n        it('does not call `executeTransactionMessage` on subsequently canceled plans', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const cause = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT, { index: 0 });\n            const executeTransactionMessage = jest.fn().mockRejectedValueOnce(cause).mockImplementationOnce(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            await executor(sequentialTransactionPlan([messageA, messageB])).catch(() => {});\n            expect(executeTransactionMessage).toHaveBeenCalledTimes(1);\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(1, expect.any(Object), messageA, {\n                abortSignal: undefined,\n            });\n        });\n\n        it('can abort sequential transaction plans', async () => {\n            expect.assertions(6);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const cause = new Error('Aborted during execution');\n            const executeTransactionMessage = jest\n                .fn()\n                .mockImplementationOnce(forwardId)\n                .mockResolvedValueOnce(FOREVER_PROMISE)\n                .mockImplementationOnce(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(sequentialTransactionPlan([messageA, messageB, messageC]), { abortSignal });\n            await jest.runAllTimersAsync();\n            abortController.abort(cause);\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: sequentialTransactionPlanResult([\n                        successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                        failedSingleTransactionPlanResult(messageB, cause),\n                        canceledSingleTransactionPlanResult(messageC),\n                    ]),\n                }),\n            );\n\n            expect(executeTransactionMessage).toHaveBeenCalledTimes(2);\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(1, expect.any(Object), messageA, { abortSignal });\n            expect(executeTransactionMessage).toHaveBeenNthCalledWith(2, expect.any(Object), messageB, { abortSignal });\n            expect(executeTransactionMessage).not.toHaveBeenCalledWith(expect.any(Object), messageC, { abortSignal });\n        });\n\n        it('can abort sequential transaction plans before execution', async () => {\n            expect.assertions(3);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const cause = new Error('Aborted before execution');\n            const executeTransactionMessage = jest.fn();\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            abortController.abort(cause);\n            const promise = executor(sequentialTransactionPlan([messageA, messageB]), { abortSignal });\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: sequentialTransactionPlanResult([\n                        canceledSingleTransactionPlanResult(messageA),\n                        canceledSingleTransactionPlanResult(messageB),\n                    ]),\n                }),\n            );\n\n            expect(executeTransactionMessage).not.toHaveBeenCalled();\n        });\n\n        it('freezes the returned sequential transaction plan result', async () => {\n            expect.assertions(1);\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const result = await executor(sequentialTransactionPlan([createMessage('A'), createMessage('B')]));\n            expect(result).toBeFrozenObject();\n        });\n    });\n\n    describe('parallel scenarios', () => {\n        it('successfully executes a parallel transaction plan', async () => {\n            expect.assertions(4);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(parallelTransactionPlan([messageA, messageB]));\n            await expect(promise).resolves.toStrictEqual(\n                parallelTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                    successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B')),\n                ]),\n            );\n\n            expect(executeTransactionMessage).toHaveBeenCalledTimes(2);\n            expect(executeTransactionMessage).toHaveBeenCalledWith(expect.any(Object), messageA, {\n                abortSignal: undefined,\n            });\n            expect(executeTransactionMessage).toHaveBeenCalledWith(expect.any(Object), messageB, {\n                abortSignal: undefined,\n            });\n        });\n\n        it('passes the abort signal to the `executeTransactionMessage` function', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            await executor(parallelTransactionPlan([messageA, messageB]), { abortSignal });\n            expect(executeTransactionMessage).toHaveBeenCalledWith(expect.any(Object), messageA, { abortSignal });\n            expect(executeTransactionMessage).toHaveBeenCalledWith(expect.any(Object), messageB, { abortSignal });\n        });\n\n        it('executes a parallel transaction plan with custom context', async () => {\n            expect.assertions(1);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const executor = createTransactionPlanExecutor<{ custom: string }>({\n                executeTransactionMessage: (context, message) => {\n                    const id = (message as TransactionMessage & TransactionMessageWithFeePayer & { id: string }).id;\n                    context.custom = 'Message ' + id;\n                    return forwardId(context, message);\n                },\n            });\n\n            const promise = executor(parallelTransactionPlan([messageA, messageB]));\n            await expect(promise).resolves.toStrictEqual(\n                parallelTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A'), {\n                        custom: 'Message A',\n                    }),\n                    successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B'), {\n                        custom: 'Message B',\n                    }),\n                ]),\n            );\n        });\n\n        it('partially fails to execute a parallel transaction plan when the executor function rejects', async () => {\n            expect.assertions(3);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const cause = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT, { index: 0 });\n            const executeTransactionMessage = jest\n                .fn()\n                .mockImplementation(\n                    (context, message: TransactionMessage & TransactionMessageWithFeePayer & { id: string }) => {\n                        // eslint-disable-next-line jest/no-conditional-in-test\n                        return message.id === 'B' ? Promise.reject(cause) : forwardId(context, message);\n                    },\n                );\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(parallelTransactionPlan([messageA, messageB, messageC]));\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: parallelTransactionPlanResult([\n                        successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                        failedSingleTransactionPlanResult(messageB, cause),\n                        successfulSingleTransactionPlanResultFromTransaction(messageC, createTransaction('C')),\n                    ]),\n                }),\n            );\n\n            expect(executeTransactionMessage).toHaveBeenCalledTimes(3);\n        });\n\n        it('can abort parallel transaction plans', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const cause = new Error('Aborted during execution');\n            const executeTransactionMessage = jest\n                .fn()\n                .mockImplementation(\n                    (context, message: TransactionMessage & TransactionMessageWithFeePayer & { id: string }) => {\n                        // eslint-disable-next-line jest/no-conditional-in-test\n                        return message.id === 'B' ? FOREVER_PROMISE : forwardId(context, message);\n                    },\n                );\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(parallelTransactionPlan([messageA, messageB, messageC]), { abortSignal });\n            await jest.runAllTimersAsync();\n            abortController.abort(cause);\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: parallelTransactionPlanResult([\n                        successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                        failedSingleTransactionPlanResult(messageB, cause),\n                        successfulSingleTransactionPlanResultFromTransaction(messageC, createTransaction('C')),\n                    ]),\n                }),\n            );\n        });\n\n        it('can abort parallel transaction plans before execution', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const cause = new Error('Aborted before execution');\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            abortController.abort(cause);\n            const promise = executor(parallelTransactionPlan([messageA, messageB, messageC]), { abortSignal });\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: parallelTransactionPlanResult([\n                        canceledSingleTransactionPlanResult(messageA),\n                        canceledSingleTransactionPlanResult(messageB),\n                        canceledSingleTransactionPlanResult(messageC),\n                    ]),\n                }),\n            );\n        });\n\n        it('freezes the returned transaction plan result', async () => {\n            expect.assertions(1);\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const result = await executor(parallelTransactionPlan([createMessage('A'), createMessage('B')]));\n            expect(result).toBeFrozenObject();\n        });\n    });\n\n    describe('complex scenarios', () => {\n        it('successfully executes a complex transaction plan', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const messageD = createMessage('D');\n            const messageE = createMessage('E');\n            const messageF = createMessage('F');\n            const messageG = createMessage('G');\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(\n                parallelTransactionPlan([\n                    sequentialTransactionPlan([messageA, parallelTransactionPlan([messageB, messageC]), messageD]),\n                    messageE,\n                    sequentialTransactionPlan([messageF, messageG]),\n                ]),\n            );\n\n            await expect(promise).resolves.toStrictEqual(\n                parallelTransactionPlanResult([\n                    sequentialTransactionPlanResult([\n                        successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                        parallelTransactionPlanResult([\n                            successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B')),\n                            successfulSingleTransactionPlanResultFromTransaction(messageC, createTransaction('C')),\n                        ]),\n                        successfulSingleTransactionPlanResultFromTransaction(messageD, createTransaction('D')),\n                    ]),\n                    successfulSingleTransactionPlanResultFromTransaction(messageE, createTransaction('E')),\n                    sequentialTransactionPlanResult([\n                        successfulSingleTransactionPlanResultFromTransaction(messageF, createTransaction('F')),\n                        successfulSingleTransactionPlanResultFromTransaction(messageG, createTransaction('G')),\n                    ]),\n                ]),\n            );\n\n            expect(executeTransactionMessage).toHaveBeenCalledTimes(7);\n        });\n\n        it('fails to executes a complex transaction plan when the executor function rejects', async () => {\n            expect.assertions(3);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const messageD = createMessage('D');\n            const messageE = createMessage('E');\n            const messageF = createMessage('F');\n            const messageG = createMessage('G');\n            const cause = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__INVALID_ARGUMENT, { index: 0 });\n            const executeTransactionMessage = jest\n                .fn()\n                .mockImplementation(\n                    (context, message: TransactionMessage & TransactionMessageWithFeePayer & { id: string }) => {\n                        // eslint-disable-next-line jest/no-conditional-in-test\n                        return message.id === 'C' ? Promise.reject(cause) : forwardId(context, message);\n                    },\n                );\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(\n                parallelTransactionPlan([\n                    sequentialTransactionPlan([messageA, parallelTransactionPlan([messageB, messageC]), messageD]),\n                    messageE,\n                    sequentialTransactionPlan([messageF, messageG]),\n                ]),\n            );\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: parallelTransactionPlanResult([\n                        sequentialTransactionPlanResult([\n                            successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                            parallelTransactionPlanResult([\n                                successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B')),\n                                failedSingleTransactionPlanResult(messageC, cause),\n                            ]),\n                            canceledSingleTransactionPlanResult(messageD),\n                        ]),\n                        successfulSingleTransactionPlanResultFromTransaction(messageE, createTransaction('E')),\n                        sequentialTransactionPlanResult([\n                            successfulSingleTransactionPlanResultFromTransaction(messageF, createTransaction('F')),\n                            successfulSingleTransactionPlanResultFromTransaction(messageG, createTransaction('G')),\n                        ]),\n                    ]),\n                }),\n            );\n\n            expect(executeTransactionMessage).toHaveBeenCalledTimes(6);\n        });\n\n        it('can abort a complex transaction plan', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const messageD = createMessage('D');\n            const messageE = createMessage('E');\n            const messageF = createMessage('F');\n            const messageG = createMessage('G');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const cause = new Error('Aborted during execution');\n            const executeTransactionMessage = jest\n                .fn()\n                .mockImplementation(\n                    (context, message: TransactionMessage & TransactionMessageWithFeePayer & { id: string }) => {\n                        // eslint-disable-next-line jest/no-conditional-in-test\n                        return message.id === 'C' ? FOREVER_PROMISE : forwardId(context, message);\n                    },\n                );\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            const promise = executor(\n                parallelTransactionPlan([\n                    sequentialTransactionPlan([messageA, parallelTransactionPlan([messageB, messageC]), messageD]),\n                    messageE,\n                    sequentialTransactionPlan([messageF, messageG]),\n                ]),\n                { abortSignal },\n            );\n\n            await jest.runAllTimersAsync();\n            abortController.abort(cause);\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: parallelTransactionPlanResult([\n                        sequentialTransactionPlanResult([\n                            successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                            parallelTransactionPlanResult([\n                                successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B')),\n                                failedSingleTransactionPlanResult(messageC, cause),\n                            ]),\n                            canceledSingleTransactionPlanResult(messageD),\n                        ]),\n                        successfulSingleTransactionPlanResultFromTransaction(messageE, createTransaction('E')),\n                        sequentialTransactionPlanResult([\n                            successfulSingleTransactionPlanResultFromTransaction(messageF, createTransaction('F')),\n                            successfulSingleTransactionPlanResultFromTransaction(messageG, createTransaction('G')),\n                        ]),\n                    ]),\n                }),\n            );\n        });\n\n        it('can abort a complex transaction plan before execution', async () => {\n            expect.assertions(2);\n            const messageA = createMessage('A');\n            const messageB = createMessage('B');\n            const messageC = createMessage('C');\n            const messageD = createMessage('D');\n            const messageE = createMessage('E');\n            const messageF = createMessage('F');\n            const messageG = createMessage('G');\n            const abortController = new AbortController();\n            const abortSignal = abortController.signal;\n            const cause = new Error('Aborted during execution');\n            const executeTransactionMessage = jest.fn().mockImplementation(forwardId);\n            const executor = createTransactionPlanExecutor({ executeTransactionMessage });\n\n            abortController.abort(cause);\n            const promise = executor(\n                parallelTransactionPlan([\n                    sequentialTransactionPlan([messageA, parallelTransactionPlan([messageB, messageC]), messageD]),\n                    messageE,\n                    sequentialTransactionPlan([messageF, messageG]),\n                ]),\n                { abortSignal },\n            );\n\n            await expectFailedToExecute(\n                promise,\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                    cause,\n                    transactionPlanResult: parallelTransactionPlanResult([\n                        sequentialTransactionPlanResult([\n                            canceledSingleTransactionPlanResult(messageA),\n                            parallelTransactionPlanResult([\n                                canceledSingleTransactionPlanResult(messageB),\n                                canceledSingleTransactionPlanResult(messageC),\n                            ]),\n                            canceledSingleTransactionPlanResult(messageD),\n                        ]),\n                        canceledSingleTransactionPlanResult(messageE),\n                        sequentialTransactionPlanResult([\n                            canceledSingleTransactionPlanResult(messageF),\n                            canceledSingleTransactionPlanResult(messageG),\n                        ]),\n                    ]),\n                }),\n            );\n        });\n    });\n});\n\ndescribe('passthroughFailedTransactionPlanExecution', () => {\n    it('returns the resolved result as-is', async () => {\n        expect.assertions(1);\n        const result = successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A'));\n        const promise = Promise.resolve(result);\n        await expect(passthroughFailedTransactionPlanExecution(promise)).resolves.toBe(result);\n    });\n    it('returns the result inside the rejected execution error', async () => {\n        expect.assertions(1);\n        const result = failedSingleTransactionPlanResult(\n            createMessage('A'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        const promise = Promise.reject(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, {\n                transactionPlanResult: result,\n            }),\n        );\n        await expect(passthroughFailedTransactionPlanExecution(promise)).resolves.toBe(result);\n    });\n    it('does not catch errors other than failed execution errors', async () => {\n        expect.assertions(1);\n        const promise = Promise.reject(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED),\n        );\n        await expect(passthroughFailedTransactionPlanExecution(promise)).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/transaction-plan-result-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE,\n    SolanaError,\n} from '@solana/errors';\nimport { Signature } from '@solana/keys';\n\nimport {\n    assertIsCanceledSingleTransactionPlanResult,\n    assertIsFailedSingleTransactionPlanResult,\n    assertIsNonDivisibleSequentialTransactionPlanResult,\n    assertIsParallelTransactionPlanResult,\n    assertIsSequentialTransactionPlanResult,\n    assertIsSingleTransactionPlanResult,\n    assertIsSuccessfulSingleTransactionPlanResult,\n    assertIsSuccessfulTransactionPlanResult,\n    canceledSingleTransactionPlanResult,\n    everyTransactionPlanResult,\n    failedSingleTransactionPlanResult,\n    findTransactionPlanResult,\n    flattenTransactionPlanResult,\n    getFirstFailedSingleTransactionPlanResult,\n    isCanceledSingleTransactionPlanResult,\n    isFailedSingleTransactionPlanResult,\n    isNonDivisibleSequentialTransactionPlanResult,\n    isParallelTransactionPlanResult,\n    isSequentialTransactionPlanResult,\n    isSingleTransactionPlanResult,\n    isSuccessfulSingleTransactionPlanResult,\n    isSuccessfulTransactionPlanResult,\n    isTransactionPlanResult,\n    nonDivisibleSequentialTransactionPlanResult,\n    parallelTransactionPlanResult,\n    sequentialTransactionPlanResult,\n    successfulSingleTransactionPlanResult,\n    successfulSingleTransactionPlanResultFromTransaction,\n    summarizeTransactionPlanResult,\n    transformTransactionPlanResult,\n} from '../index';\nimport { createMessage, createTransaction } from './__setup__';\n\ndescribe('successfulSingleTransactionPlanResultFromTransaction', () => {\n    it('creates SingleTransactionPlanResult objects with successful status', () => {\n        const messageA = createMessage('A');\n        const transactionA = createTransaction('A');\n        const result = successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA);\n        expect(result).toEqual({\n            context: { signature: 'A', transaction: transactionA },\n            kind: 'single',\n            planType: 'transactionPlanResult',\n            plannedMessage: messageA,\n            status: 'successful',\n        });\n    });\n    it('accepts an optional context object', () => {\n        const messageA = createMessage('A');\n        const transactionA = createTransaction('A');\n        const context = { foo: 'bar' };\n        const result = successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA, context);\n        expect(result).toEqual({\n            context: { ...context, signature: 'A', transaction: transactionA },\n            kind: 'single',\n            planType: 'transactionPlanResult',\n            plannedMessage: messageA,\n            status: 'successful',\n        });\n    });\n    it('freezes created SingleTransactionPlanResult objects', () => {\n        const messageA = createMessage('A');\n        const transactionA = createTransaction('A');\n        const result = successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA);\n        expect(result).toBeFrozenObject();\n    });\n    it('freezes the status object of created SingleTransactionPlanResult objects', () => {\n        const messageA = createMessage('A');\n        const transactionA = createTransaction('A');\n        const result = successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA);\n        expect(result.status).toBeFrozenObject();\n    });\n});\n\ndescribe('successfulSingleTransactionPlanResult', () => {\n    it('creates SingleTransactionPlanResult objects with successful status', () => {\n        const messageA = createMessage('A');\n        const signature = 'A' as Signature;\n        const result = successfulSingleTransactionPlanResult(messageA, { signature });\n        expect(result).toEqual({\n            context: { signature: 'A' },\n            kind: 'single',\n            planType: 'transactionPlanResult',\n            plannedMessage: messageA,\n            status: 'successful',\n        });\n    });\n    it('accepts an optional context object', () => {\n        const messageA = createMessage('A');\n        const signature = 'A' as Signature;\n        const context = { foo: 'bar' };\n        const result = successfulSingleTransactionPlanResult(messageA, { ...context, signature });\n        expect(result).toEqual({\n            context: { ...context, signature: 'A' },\n            kind: 'single',\n            planType: 'transactionPlanResult',\n            plannedMessage: messageA,\n            status: 'successful',\n        });\n    });\n    it('freezes created SingleTransactionPlanResult objects', () => {\n        const messageA = createMessage('A');\n        const signature = 'A' as Signature;\n        const result = successfulSingleTransactionPlanResult(messageA, { signature });\n        expect(result).toBeFrozenObject();\n    });\n    it('freezes the status object of created SingleTransactionPlanResult objects', () => {\n        const messageA = createMessage('A');\n        const signature = 'A' as Signature;\n        const result = successfulSingleTransactionPlanResult(messageA, { signature });\n        expect(result.status).toBeFrozenObject();\n    });\n});\n\ndescribe('failedSingleTransactionPlanResult', () => {\n    it('creates SingleTransactionPlanResult objects with failed status', () => {\n        const messageA = createMessage('A');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const result = failedSingleTransactionPlanResult(messageA, error);\n        expect(result).toEqual({\n            context: {},\n            error,\n            kind: 'single',\n            planType: 'transactionPlanResult',\n            plannedMessage: messageA,\n            status: 'failed',\n        });\n    });\n    it('freezes created SingleTransactionPlanResult objects', () => {\n        const messageA = createMessage('A');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const result = failedSingleTransactionPlanResult(messageA, error);\n        expect(result).toBeFrozenObject();\n    });\n    it('freezes the status object of created SingleTransactionPlanResult objects', () => {\n        const messageA = createMessage('A');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const result = failedSingleTransactionPlanResult(messageA, error);\n        expect(result.status).toBeFrozenObject();\n    });\n});\n\ndescribe('canceledSingleTransactionPlanResult', () => {\n    it('creates SingleTransactionPlanResult objects with canceled status', () => {\n        const messageA = createMessage('A');\n        const result = canceledSingleTransactionPlanResult(messageA);\n        expect(result).toEqual({\n            context: {},\n            kind: 'single',\n            planType: 'transactionPlanResult',\n            plannedMessage: messageA,\n            status: 'canceled',\n        });\n    });\n    it('freezes created SingleTransactionPlanResult objects', () => {\n        const messageA = createMessage('A');\n        const result = canceledSingleTransactionPlanResult(messageA);\n        expect(result).toBeFrozenObject();\n    });\n    it('freezes the status object of created SingleTransactionPlanResult objects', () => {\n        const messageA = createMessage('A');\n        const result = canceledSingleTransactionPlanResult(messageA);\n        expect(result.status).toBeFrozenObject();\n    });\n});\n\ndescribe('parallelTransactionPlanResult', () => {\n    it('creates ParallelTransactionPlanResult objects from other results', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const result = parallelTransactionPlanResult([planA, planB]);\n        expect(result).toEqual({\n            kind: 'parallel',\n            planType: 'transactionPlanResult',\n            plans: [planA, planB],\n        });\n    });\n    it('can nest other result types', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const planC = canceledSingleTransactionPlanResult(createMessage('C'));\n        const result = parallelTransactionPlanResult([planA, parallelTransactionPlanResult([planB, planC])]);\n        expect(result).toEqual({\n            kind: 'parallel',\n            planType: 'transactionPlanResult',\n            plans: [planA, { kind: 'parallel', planType: 'transactionPlanResult', plans: [planB, planC] }],\n        });\n    });\n    it('freezes created ParallelTransactionPlanResult objects', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const result = parallelTransactionPlanResult([planA, planB]);\n        expect(result).toBeFrozenObject();\n    });\n});\n\ndescribe('sequentialTransactionPlanResult', () => {\n    it('creates divisible SequentialTransactionPlanResult objects from other results', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const result = sequentialTransactionPlanResult([planA, planB]);\n        expect(result).toEqual({\n            divisible: true,\n            kind: 'sequential',\n            planType: 'transactionPlanResult',\n            plans: [planA, planB],\n        });\n    });\n    it('can nest other result types', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const planC = canceledSingleTransactionPlanResult(createMessage('C'));\n        const result = sequentialTransactionPlanResult([planA, sequentialTransactionPlanResult([planB, planC])]);\n        expect(result).toEqual({\n            divisible: true,\n            kind: 'sequential',\n            planType: 'transactionPlanResult',\n            plans: [\n                planA,\n                { divisible: true, kind: 'sequential', planType: 'transactionPlanResult', plans: [planB, planC] },\n            ],\n        });\n    });\n    it('freezes created SequentialTransactionPlanResult objects', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const result = sequentialTransactionPlanResult([planA, planB]);\n        expect(result).toBeFrozenObject();\n    });\n});\n\ndescribe('nonDivisibleSequentialTransactionPlanResult', () => {\n    it('creates non-divisible SequentialTransactionPlanResult objects from other results', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const result = nonDivisibleSequentialTransactionPlanResult([planA, planB]);\n        expect(result).toEqual({\n            divisible: false,\n            kind: 'sequential',\n            planType: 'transactionPlanResult',\n            plans: [planA, planB],\n        });\n    });\n    it('can nest other result types', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const planC = canceledSingleTransactionPlanResult(createMessage('C'));\n        const result = nonDivisibleSequentialTransactionPlanResult([\n            planA,\n            nonDivisibleSequentialTransactionPlanResult([planB, planC]),\n        ]);\n        expect(result).toEqual({\n            divisible: false,\n            kind: 'sequential',\n            planType: 'transactionPlanResult',\n            plans: [\n                planA,\n                { divisible: false, kind: 'sequential', planType: 'transactionPlanResult', plans: [planB, planC] },\n            ],\n        });\n    });\n    it('freezes created SequentialTransactionPlanResult objects', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const result = nonDivisibleSequentialTransactionPlanResult([planA, planB]);\n        expect(result).toBeFrozenObject();\n    });\n});\n\ndescribe('isSingleTransactionPlanResult', () => {\n    it('returns true for any SingleTransactionPlanResult', () => {\n        expect(\n            isSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toBe(true);\n        expect(\n            isSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResult(createMessage('A'), { signature: 'A' as Signature }),\n            ),\n        ).toBe(true);\n        expect(\n            isSingleTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toBe(true);\n        expect(isSingleTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A')))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isSingleTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(false);\n        expect(isSingleTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toBe(false);\n        expect(isSingleTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsSingleTransactionPlanResult', () => {\n    it('does nothing for any SingleTransactionPlanResult', () => {\n        expect(() =>\n            assertIsSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).not.toThrow();\n        expect(() =>\n            assertIsSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResult(createMessage('A'), { signature: 'A' as Signature }),\n            ),\n        ).not.toThrow();\n        expect(() =>\n            assertIsSingleTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).not.toThrow();\n        expect(() =>\n            assertIsSingleTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A'))),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsSingleTransactionPlanResult(sequentialTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected single plan, got sequential plan.',\n        );\n        expect(() => assertIsSingleTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected single plan, got sequential plan.',\n        );\n        expect(() => assertIsSingleTransactionPlanResult(parallelTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected single plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isSuccessfulSingleTransactionPlanResult', () => {\n    it('returns true for successful SingleTransactionPlanResult', () => {\n        expect(\n            isSuccessfulSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toBe(true);\n        expect(\n            isSuccessfulSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResult(createMessage('A'), { signature: 'A' as Signature }),\n            ),\n        ).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(\n            isSuccessfulSingleTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toBe(false);\n        expect(isSuccessfulSingleTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A')))).toBe(\n            false,\n        );\n        expect(isSuccessfulSingleTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(false);\n        expect(isSuccessfulSingleTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toBe(false);\n        expect(isSuccessfulSingleTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsSuccessfulSingleTransactionPlanResult', () => {\n    it('does nothing for successful SingleTransactionPlanResult', () => {\n        expect(() =>\n            assertIsSuccessfulSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).not.toThrow();\n        expect(() =>\n            assertIsSuccessfulSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResult(createMessage('A'), { signature: 'A' as Signature }),\n            ),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() =>\n            assertIsSuccessfulSingleTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected successful single plan, got failed single plan.');\n        expect(() =>\n            assertIsSuccessfulSingleTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A'))),\n        ).toThrow('Unexpected transaction plan result. Expected successful single plan, got canceled single plan.');\n        expect(() => assertIsSuccessfulSingleTransactionPlanResult(sequentialTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected successful single plan, got sequential plan.',\n        );\n        expect(() =>\n            assertIsSuccessfulSingleTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([])),\n        ).toThrow('Unexpected transaction plan result. Expected successful single plan, got sequential plan.');\n        expect(() => assertIsSuccessfulSingleTransactionPlanResult(parallelTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected successful single plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isFailedSingleTransactionPlanResult', () => {\n    it('returns true for failed SingleTransactionPlanResult', () => {\n        expect(\n            isFailedSingleTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(\n            isFailedSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toBe(false);\n        expect(isFailedSingleTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A')))).toBe(\n            false,\n        );\n        expect(isFailedSingleTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(false);\n        expect(isFailedSingleTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toBe(false);\n        expect(isFailedSingleTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsFailedSingleTransactionPlanResult', () => {\n    it('does nothing for failed SingleTransactionPlanResult', () => {\n        expect(() =>\n            assertIsFailedSingleTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() =>\n            assertIsFailedSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected failed single plan, got successful single plan.');\n        expect(() =>\n            assertIsFailedSingleTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A'))),\n        ).toThrow('Unexpected transaction plan result. Expected failed single plan, got canceled single plan.');\n        expect(() => assertIsFailedSingleTransactionPlanResult(sequentialTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected failed single plan, got sequential plan.',\n        );\n        expect(() =>\n            assertIsFailedSingleTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([])),\n        ).toThrow('Unexpected transaction plan result. Expected failed single plan, got sequential plan.');\n        expect(() => assertIsFailedSingleTransactionPlanResult(parallelTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected failed single plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isCanceledSingleTransactionPlanResult', () => {\n    it('returns true for canceled SingleTransactionPlanResult', () => {\n        expect(isCanceledSingleTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A')))).toBe(\n            true,\n        );\n    });\n    it('returns false for other plans', () => {\n        expect(\n            isCanceledSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toBe(false);\n        expect(\n            isCanceledSingleTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toBe(false);\n        expect(isCanceledSingleTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(false);\n        expect(isCanceledSingleTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toBe(false);\n        expect(isCanceledSingleTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsCanceledSingleTransactionPlanResult', () => {\n    it('does nothing for canceled SingleTransactionPlanResult', () => {\n        expect(() =>\n            assertIsCanceledSingleTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A'))),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() =>\n            assertIsCanceledSingleTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected canceled single plan, got successful single plan.');\n        expect(() =>\n            assertIsCanceledSingleTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected canceled single plan, got failed single plan.');\n        expect(() => assertIsCanceledSingleTransactionPlanResult(sequentialTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected canceled single plan, got sequential plan.',\n        );\n        expect(() =>\n            assertIsCanceledSingleTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([])),\n        ).toThrow('Unexpected transaction plan result. Expected canceled single plan, got sequential plan.');\n        expect(() => assertIsCanceledSingleTransactionPlanResult(parallelTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected canceled single plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isSequentialTransactionPlanResult', () => {\n    it('returns true for SequentialTransactionPlanResult (divisible or not)', () => {\n        expect(isSequentialTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(true);\n        expect(isSequentialTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(\n            isSequentialTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toBe(false);\n        expect(\n            isSequentialTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toBe(false);\n        expect(isSequentialTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A')))).toBe(false);\n        expect(isSequentialTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsSequentialTransactionPlanResult', () => {\n    it('does nothing for SequentialTransactionPlanResult', () => {\n        expect(() => assertIsSequentialTransactionPlanResult(sequentialTransactionPlanResult([]))).not.toThrow();\n        expect(() =>\n            assertIsSequentialTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([])),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() =>\n            assertIsSequentialTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected sequential plan, got single plan.');\n        expect(() =>\n            assertIsSequentialTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected sequential plan, got single plan.');\n        expect(() =>\n            assertIsSequentialTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A'))),\n        ).toThrow('Unexpected transaction plan result. Expected sequential plan, got single plan.');\n        expect(() => assertIsSequentialTransactionPlanResult(parallelTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected sequential plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isNonDivisibleSequentialTransactionPlanResult', () => {\n    it('returns true for non-divisible SequentialTransactionPlanResult', () => {\n        expect(isNonDivisibleSequentialTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toBe(\n            true,\n        );\n    });\n    it('returns false for other plans', () => {\n        expect(\n            isNonDivisibleSequentialTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toBe(false);\n        expect(\n            isNonDivisibleSequentialTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toBe(false);\n        expect(\n            isNonDivisibleSequentialTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A'))),\n        ).toBe(false);\n        expect(isNonDivisibleSequentialTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(false);\n        expect(isNonDivisibleSequentialTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsNonDivisibleSequentialTransactionPlanResult', () => {\n    it('does nothing for non-divisible SequentialTransactionPlanResult', () => {\n        expect(() =>\n            assertIsNonDivisibleSequentialTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([])),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() =>\n            assertIsNonDivisibleSequentialTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected non-divisible sequential plan, got single plan.');\n        expect(() =>\n            assertIsNonDivisibleSequentialTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected non-divisible sequential plan, got single plan.');\n        expect(() =>\n            assertIsNonDivisibleSequentialTransactionPlanResult(\n                canceledSingleTransactionPlanResult(createMessage('A')),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected non-divisible sequential plan, got single plan.');\n        expect(() => assertIsNonDivisibleSequentialTransactionPlanResult(sequentialTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected non-divisible sequential plan, got divisible sequential plan.',\n        );\n        expect(() => assertIsNonDivisibleSequentialTransactionPlanResult(parallelTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected non-divisible sequential plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isParallelTransactionPlanResult', () => {\n    it('returns true for ParallelTransactionPlanResult', () => {\n        expect(isParallelTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(\n            isParallelTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toBe(false);\n        expect(\n            isParallelTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toBe(false);\n        expect(isParallelTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A')))).toBe(false);\n        expect(isParallelTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(false);\n        expect(isParallelTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsParallelTransactionPlanResult', () => {\n    it('does nothing for ParallelTransactionPlanResult', () => {\n        expect(() => assertIsParallelTransactionPlanResult(parallelTransactionPlanResult([]))).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() =>\n            assertIsParallelTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected parallel plan, got single plan.');\n        expect(() =>\n            assertIsParallelTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toThrow('Unexpected transaction plan result. Expected parallel plan, got single plan.');\n        expect(() =>\n            assertIsParallelTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A'))),\n        ).toThrow('Unexpected transaction plan result. Expected parallel plan, got single plan.');\n        expect(() => assertIsParallelTransactionPlanResult(sequentialTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected parallel plan, got sequential plan.',\n        );\n        expect(() => assertIsParallelTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toThrow(\n            'Unexpected transaction plan result. Expected parallel plan, got sequential plan.',\n        );\n    });\n});\n\ndescribe('isSuccessfulTransactionPlanResult', () => {\n    it('returns true for a single successful result', () => {\n        expect(\n            isSuccessfulTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).toBe(true);\n    });\n    it('returns true for nested results that are all successful', () => {\n        const result = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('C'), createTransaction('C')),\n            ]),\n        ]);\n        expect(isSuccessfulTransactionPlanResult(result)).toBe(true);\n    });\n    it('returns true for empty parallel result', () => {\n        expect(isSuccessfulTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(true);\n    });\n    it('returns true for empty sequential result', () => {\n        expect(isSuccessfulTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(true);\n    });\n    it('returns false when any single result is failed', () => {\n        const result = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            failedSingleTransactionPlanResult(\n                createMessage('B'),\n                new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n            ),\n        ]);\n        expect(isSuccessfulTransactionPlanResult(result)).toBe(false);\n    });\n    it('returns false when any single result is canceled', () => {\n        const result = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            canceledSingleTransactionPlanResult(createMessage('B')),\n        ]);\n        expect(isSuccessfulTransactionPlanResult(result)).toBe(false);\n    });\n    it('returns false for a single failed result', () => {\n        expect(\n            isSuccessfulTransactionPlanResult(\n                failedSingleTransactionPlanResult(\n                    createMessage('A'),\n                    new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                ),\n            ),\n        ).toBe(false);\n    });\n    it('returns false for a single canceled result', () => {\n        expect(isSuccessfulTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A')))).toBe(false);\n    });\n    it('returns false when a deeply nested result is not successful', () => {\n        const result = parallelTransactionPlanResult([\n            sequentialTransactionPlanResult([\n                parallelTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n                    failedSingleTransactionPlanResult(\n                        createMessage('B'),\n                        new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                    ),\n                ]),\n            ]),\n        ]);\n        expect(isSuccessfulTransactionPlanResult(result)).toBe(false);\n    });\n});\n\ndescribe('assertIsSuccessfulTransactionPlanResult', () => {\n    it('does nothing for a single successful result', () => {\n        expect(() =>\n            assertIsSuccessfulTransactionPlanResult(\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ),\n        ).not.toThrow();\n    });\n    it('does nothing for nested results that are all successful', () => {\n        const result = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('C'), createTransaction('C')),\n            ]),\n        ]);\n        expect(() => assertIsSuccessfulTransactionPlanResult(result)).not.toThrow();\n    });\n    it('does nothing for empty parallel result', () => {\n        expect(() => assertIsSuccessfulTransactionPlanResult(parallelTransactionPlanResult([]))).not.toThrow();\n    });\n    it('does nothing for empty sequential result', () => {\n        expect(() => assertIsSuccessfulTransactionPlanResult(sequentialTransactionPlanResult([]))).not.toThrow();\n    });\n    it('throws when any single result is failed', () => {\n        const result = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            failedSingleTransactionPlanResult(\n                createMessage('B'),\n                new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n            ),\n        ]);\n        expect(() => assertIsSuccessfulTransactionPlanResult(result)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT, {\n                transactionPlanResult: result,\n            }),\n        );\n    });\n    it('throws when any single result is canceled', () => {\n        const result = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            canceledSingleTransactionPlanResult(createMessage('B')),\n        ]);\n        expect(() => assertIsSuccessfulTransactionPlanResult(result)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT, {\n                transactionPlanResult: result,\n            }),\n        );\n    });\n    it('throws for a single failed result', () => {\n        const result = failedSingleTransactionPlanResult(\n            createMessage('A'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        expect(() => assertIsSuccessfulTransactionPlanResult(result)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT, {\n                transactionPlanResult: result,\n            }),\n        );\n    });\n    it('throws for a single canceled result', () => {\n        const result = canceledSingleTransactionPlanResult(createMessage('A'));\n        expect(() => assertIsSuccessfulTransactionPlanResult(result)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT, {\n                transactionPlanResult: result,\n            }),\n        );\n    });\n});\n\ndescribe('findTransactionPlanResult', () => {\n    it('returns the result itself when it matches the predicate', () => {\n        const messageA = createMessage('A');\n        const result = canceledSingleTransactionPlanResult(messageA);\n        const found = findTransactionPlanResult(result, r => r.kind === 'single');\n        expect(found).toBe(result);\n    });\n    it('returns undefined when no result matches the predicate', () => {\n        const messageA = createMessage('A');\n        const result = canceledSingleTransactionPlanResult(messageA);\n        const found = findTransactionPlanResult(result, r => r.kind === 'parallel');\n        expect(found).toBeUndefined();\n    });\n    it('finds a nested result in a parallel structure', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const nestedSequential = sequentialTransactionPlanResult([\n            canceledSingleTransactionPlanResult(messageA),\n            canceledSingleTransactionPlanResult(messageB),\n        ]);\n        const result = parallelTransactionPlanResult([nestedSequential]);\n        const found = findTransactionPlanResult(result, r => r.kind === 'sequential');\n        expect(found).toBe(nestedSequential);\n    });\n    it('finds a nested result in a sequential structure', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const nestedParallel = parallelTransactionPlanResult([\n            canceledSingleTransactionPlanResult(messageA),\n            canceledSingleTransactionPlanResult(messageB),\n        ]);\n        const result = sequentialTransactionPlanResult([nestedParallel]);\n        const found = findTransactionPlanResult(result, r => r.kind === 'parallel');\n        expect(found).toBe(nestedParallel);\n    });\n    it('returns the first matching result in top-down order', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const innerSequential = sequentialTransactionPlanResult([canceledSingleTransactionPlanResult(messageA)]);\n        const outerSequential = sequentialTransactionPlanResult([\n            innerSequential,\n            canceledSingleTransactionPlanResult(messageB),\n        ]);\n        const found = findTransactionPlanResult(outerSequential, r => r.kind === 'sequential');\n        expect(found).toBe(outerSequential);\n    });\n    it('finds a deeply nested result', () => {\n        const messageA = createMessage('A');\n        const deepSingle = canceledSingleTransactionPlanResult(messageA);\n        const result = parallelTransactionPlanResult([\n            sequentialTransactionPlanResult([parallelTransactionPlanResult([deepSingle])]),\n        ]);\n        const found = findTransactionPlanResult(result, r => r.kind === 'single');\n        expect(found).toBe(deepSingle);\n    });\n    it('supports complex predicates that inspect nested properties', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const messageC = createMessage('C');\n        const targetResult = sequentialTransactionPlanResult([\n            canceledSingleTransactionPlanResult(messageA),\n            canceledSingleTransactionPlanResult(messageB),\n        ]);\n        const result = parallelTransactionPlanResult([canceledSingleTransactionPlanResult(messageC), targetResult]);\n        const found = findTransactionPlanResult(\n            result,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            r => r.kind === 'sequential' && r.plans.length === 2,\n        );\n        expect(found).toBe(targetResult);\n    });\n    it('returns undefined when searching an empty parallel result', () => {\n        const result = parallelTransactionPlanResult([]);\n        const found = findTransactionPlanResult(result, r => r.kind === 'single');\n        expect(found).toBeUndefined();\n    });\n    it('finds non-divisible sequential results', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const nonDivisible = nonDivisibleSequentialTransactionPlanResult([\n            canceledSingleTransactionPlanResult(messageA),\n            canceledSingleTransactionPlanResult(messageB),\n        ]);\n        const result = parallelTransactionPlanResult([\n            sequentialTransactionPlanResult([canceledSingleTransactionPlanResult(createMessage('C'))]),\n            nonDivisible,\n        ]);\n        const found = findTransactionPlanResult(\n            result,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            r => r.kind === 'sequential' && !r.divisible,\n        );\n        expect(found).toBe(nonDivisible);\n    });\n    it('finds a failed single transaction result', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const failedResult = failedSingleTransactionPlanResult(messageB, error);\n        const result = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n            failedResult,\n        ]);\n        const found = findTransactionPlanResult(\n            result,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            r => r.kind === 'single' && r.status === 'failed',\n        );\n        expect(found).toBe(failedResult);\n    });\n    it('finds a successful single transaction result', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const successfulResult = successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A'));\n        const result = sequentialTransactionPlanResult([\n            successfulResult,\n            canceledSingleTransactionPlanResult(messageB),\n        ]);\n        const found = findTransactionPlanResult(\n            result,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            r => r.kind === 'single' && r.status === 'successful',\n        );\n        expect(found).toBe(successfulResult);\n    });\n});\n\ndescribe('everyTransactionPlanResult', () => {\n    it('returns true when all plans match the predicate', () => {\n        const plan = sequentialTransactionPlanResult([\n            sequentialTransactionPlanResult([]),\n            sequentialTransactionPlanResult([]),\n        ]);\n        const result = everyTransactionPlanResult(plan, p => p.kind === 'sequential');\n        expect(result).toBe(true);\n    });\n    it('returns false when at least one plan does not match the predicate', () => {\n        const plan = sequentialTransactionPlanResult([\n            parallelTransactionPlanResult([]),\n            sequentialTransactionPlanResult([]),\n        ]);\n        const result = everyTransactionPlanResult(plan, p => p.kind === 'sequential');\n        expect(result).toBe(false);\n    });\n    it('matches successful single transaction plans', () => {\n        const plan = successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        const result = everyTransactionPlanResult(plan, p => p.kind === 'single' && p.status === 'successful');\n        expect(result).toBe(true);\n    });\n    it('matches failed single transaction plans', () => {\n        const plan = failedSingleTransactionPlanResult(\n            createMessage('A'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        // eslint-disable-next-line jest/no-conditional-in-test\n        const result = everyTransactionPlanResult(plan, p => p.kind === 'single' && p.status === 'failed');\n        expect(result).toBe(true);\n    });\n    it('matches canceled single transaction plans', () => {\n        const plan = canceledSingleTransactionPlanResult(createMessage('A'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        const result = everyTransactionPlanResult(plan, p => p.kind === 'single' && p.status === 'canceled');\n        expect(result).toBe(true);\n    });\n    it('matches sequential transaction plans', () => {\n        const plan = sequentialTransactionPlanResult([]);\n        const result = everyTransactionPlanResult(plan, p => p.kind === 'sequential');\n        expect(result).toBe(true);\n    });\n    it('matches non-divisible sequential transaction plans', () => {\n        const plan = nonDivisibleSequentialTransactionPlanResult([]);\n        // eslint-disable-next-line jest/no-conditional-in-test\n        const result = everyTransactionPlanResult(plan, p => p.kind === 'sequential' && !p.divisible);\n        expect(result).toBe(true);\n    });\n    it('matches parallel transaction plans', () => {\n        const plan = parallelTransactionPlanResult([]);\n        const result = everyTransactionPlanResult(plan, p => p.kind === 'parallel');\n        expect(result).toBe(true);\n    });\n    it('matches complex transaction plans', () => {\n        const resultA = successfulSingleTransactionPlanResultFromTransaction(\n            createMessage('A'),\n            createTransaction('A'),\n        );\n        const resultB = failedSingleTransactionPlanResult(\n            createMessage('B'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        const resultC = canceledSingleTransactionPlanResult(createMessage('C'));\n        const plan = sequentialTransactionPlanResult([\n            parallelTransactionPlanResult([resultA, resultB]),\n            nonDivisibleSequentialTransactionPlanResult([resultA, resultC]),\n        ]);\n        const result = everyTransactionPlanResult(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind !== 'single') return true;\n            const message = p.plannedMessage as ReturnType<typeof createMessage>;\n            return ['A', 'B', 'C'].includes(message.id);\n        });\n        expect(result).toBe(true);\n    });\n    it('returns false on complex transaction plans', () => {\n        const resultA = successfulSingleTransactionPlanResultFromTransaction(\n            createMessage('A'),\n            createTransaction('A'),\n        );\n        const resultB = failedSingleTransactionPlanResult(\n            createMessage('B'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        const resultC = canceledSingleTransactionPlanResult(createMessage('C'));\n        const plan = sequentialTransactionPlanResult([\n            parallelTransactionPlanResult([resultA, resultB]),\n            nonDivisibleSequentialTransactionPlanResult([resultA, resultC]),\n        ]);\n        // eslint-disable-next-line jest/no-conditional-in-test\n        const result = everyTransactionPlanResult(plan, p => p.kind !== 'single' || p.status === 'successful');\n        expect(result).toBe(false);\n    });\n    it('fails fast before evaluating children', () => {\n        const predicate = jest.fn().mockReturnValueOnce(false);\n        const messageA = successfulSingleTransactionPlanResultFromTransaction(\n            createMessage('A'),\n            createTransaction('A'),\n        );\n        const messageB = successfulSingleTransactionPlanResultFromTransaction(\n            createMessage('B'),\n            createTransaction('B'),\n        );\n        const plan = sequentialTransactionPlanResult([messageA, messageB]);\n        const result = everyTransactionPlanResult(plan, predicate);\n        expect(result).toBe(false);\n        expect(predicate).toHaveBeenCalledTimes(1);\n        expect(predicate).toHaveBeenNthCalledWith(1, plan);\n        expect(predicate).not.toHaveBeenCalledWith(messageA);\n        expect(predicate).not.toHaveBeenCalledWith(messageB);\n    });\n    it('fails fast before evaluating siblings', () => {\n        const predicate = jest.fn().mockReturnValueOnce(true).mockReturnValueOnce(false);\n        const messageA = successfulSingleTransactionPlanResultFromTransaction(\n            createMessage('A'),\n            createTransaction('A'),\n        );\n        const messageB = successfulSingleTransactionPlanResultFromTransaction(\n            createMessage('B'),\n            createTransaction('B'),\n        );\n        const plan = sequentialTransactionPlanResult([messageA, messageB]);\n        const result = everyTransactionPlanResult(plan, predicate);\n        expect(result).toBe(false);\n        expect(predicate).toHaveBeenCalledTimes(2);\n        expect(predicate).toHaveBeenNthCalledWith(1, plan);\n        expect(predicate).toHaveBeenNthCalledWith(2, messageA);\n        expect(predicate).not.toHaveBeenCalledWith(messageB);\n    });\n});\n\ndescribe('transformTransactionPlanResult', () => {\n    it('transforms successful single transaction plan results', () => {\n        const plan = successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A'));\n        const transformedPlan = transformTransactionPlanResult(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'single' ? { ...p, plannedMessage: { ...p.plannedMessage, id: 'New A' } } : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('New A'), createTransaction('A')),\n        );\n    });\n    it('transforms failed single transaction plan results', () => {\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const plan = failedSingleTransactionPlanResult(createMessage('A'), error);\n        const transformedPlan = transformTransactionPlanResult(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'single' ? { ...p, plannedMessage: { ...p.plannedMessage, id: 'New A' } } : p,\n        );\n        expect(transformedPlan).toStrictEqual(failedSingleTransactionPlanResult(createMessage('New A'), error));\n    });\n    it('transforms canceled single transaction plan results', () => {\n        const plan = canceledSingleTransactionPlanResult(createMessage('A'));\n        const transformedPlan = transformTransactionPlanResult(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'single' ? { ...p, plannedMessage: { ...p.plannedMessage, id: 'New A' } } : p,\n        );\n        expect(transformedPlan).toStrictEqual(canceledSingleTransactionPlanResult(createMessage('New A')));\n    });\n    it('transforms sequential transaction plan results', () => {\n        const plan = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n        ]);\n        const transformedPlan = transformTransactionPlanResult(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'sequential' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ]),\n        );\n    });\n    it('transforms non-divisible sequential transaction plan results', () => {\n        const plan = nonDivisibleSequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n        ]);\n        const transformedPlan = transformTransactionPlanResult(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'sequential' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            nonDivisibleSequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ]),\n        );\n    });\n    it('transforms parallel transaction plan results', () => {\n        const plan = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n        ]);\n        const transformedPlan = transformTransactionPlanResult(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'parallel' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            parallelTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            ]),\n        );\n    });\n    it('transforms using a bottom-up approach', () => {\n        // Given the following nested plans.\n        const plan = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('C'), createTransaction('C')),\n            ]),\n        ]);\n\n        // And given an array of message IDs that were seen by sequential plans during transformation.\n        const seenTransactionMessageIds: string[] = [];\n\n        // When transforming by prepending \"New \" to single transaction plan result IDs\n        // And recording the seen transaction message IDs in sequential plans.\n        transformTransactionPlanResult(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind === 'single') {\n                const plannedMessage = p.plannedMessage as ReturnType<typeof createMessage>;\n                return { ...p, plannedMessage: { ...plannedMessage, id: `New ${plannedMessage.id}` } };\n            }\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind === 'sequential') {\n                const seenPlannedMessages = p.plans\n                    .filter(subPlan => subPlan.kind === 'single')\n                    .map(subPlan => subPlan.plannedMessage as ReturnType<typeof createMessage>);\n                seenTransactionMessageIds.push(...seenPlannedMessages.map(m => m.id));\n            }\n            return p;\n        });\n\n        // Then we expect the seen message IDs to have already been transformed\n        // using a bottom-up approach.\n        expect(seenTransactionMessageIds).toStrictEqual(['New B', 'New C', 'New A']);\n    });\n    it('can be used to duplicate transaction results', () => {\n        const plan = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n        ]);\n        const transformedPlan = transformTransactionPlanResult(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'single' ? sequentialTransactionPlanResult([p, p]) : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            sequentialTransactionPlanResult([\n                sequentialTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n                    successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n                ]),\n                sequentialTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                    successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                ]),\n            ]),\n        );\n    });\n    it('can be used to remove parallelism', () => {\n        const plan = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n        ]);\n        const transformedPlan = transformTransactionPlanResult(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'parallel' ? sequentialTransactionPlanResult(p.plans) : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n            ]),\n        );\n    });\n    it('can be used to flatten nested transaction plan results', () => {\n        const plan = sequentialTransactionPlanResult([\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n            ]),\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('C'), createTransaction('C')),\n                sequentialTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(createMessage('D'), createTransaction('D')),\n                    successfulSingleTransactionPlanResultFromTransaction(createMessage('E'), createTransaction('E')),\n                ]),\n            ]),\n        ]);\n        const transformedPlan = transformTransactionPlanResult(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind !== 'sequential') return p;\n            const subPlans = p.plans.flatMap(subPlan =>\n                // eslint-disable-next-line jest/no-conditional-in-test\n                subPlan.kind === 'sequential' && p.divisible === subPlan.divisible ? subPlan.plans : [subPlan],\n            );\n            return { ...p, plans: subPlans };\n        });\n        expect(transformedPlan).toStrictEqual(\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('C'), createTransaction('C')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('D'), createTransaction('D')),\n                successfulSingleTransactionPlanResultFromTransaction(createMessage('E'), createTransaction('E')),\n            ]),\n        );\n    });\n    it('keeps transformed successful single transaction plan results frozen', () => {\n        const plan = successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A'));\n        const transformedPlan = transformTransactionPlanResult(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed failed single transaction plan results frozen', () => {\n        const plan = failedSingleTransactionPlanResult(\n            createMessage('A'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        const transformedPlan = transformTransactionPlanResult(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed canceled single transaction plan results frozen', () => {\n        const plan = canceledSingleTransactionPlanResult(createMessage('A'));\n        const transformedPlan = transformTransactionPlanResult(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed sequential transaction plan results frozen', () => {\n        const plan = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n        ]);\n        const transformedPlan = transformTransactionPlanResult(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed parallel transaction plan results frozen', () => {\n        const plan = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A')),\n        ]);\n        const transformedPlan = transformTransactionPlanResult(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n});\n\ndescribe('flattenTransactionPlanResult', () => {\n    const plan1 = successfulSingleTransactionPlanResultFromTransaction(createMessage('A'), createTransaction('A'));\n    const plan2 = successfulSingleTransactionPlanResultFromTransaction(createMessage('B'), createTransaction('B'));\n    const plan3 = successfulSingleTransactionPlanResultFromTransaction(createMessage('C'), createTransaction('C'));\n\n    it('flattens a parallel transaction plan result', () => {\n        const result = parallelTransactionPlanResult([plan1, plan2, plan3]);\n\n        const flattened = flattenTransactionPlanResult(result);\n        expect(flattened).toEqual([plan1, plan2, plan3]);\n    });\n\n    it('flattens a sequential transaction plan result', () => {\n        const result = sequentialTransactionPlanResult([plan1, plan2, plan3]);\n\n        const flattened = flattenTransactionPlanResult(result);\n        expect(flattened).toEqual([plan1, plan2, plan3]);\n    });\n\n    it('flattens a nested transaction plan result', () => {\n        const nestedResult = sequentialTransactionPlanResult([parallelTransactionPlanResult([plan1, plan2]), plan3]);\n\n        const flattened = flattenTransactionPlanResult(nestedResult);\n        expect(flattened).toEqual([plan1, plan2, plan3]);\n    });\n\n    it('returns a single plan as-is', () => {\n        const result = plan1;\n        const flattened = flattenTransactionPlanResult(result);\n        expect(flattened).toEqual([result]);\n    });\n});\n\ndescribe('summarizeTransactionPlanResult', () => {\n    it('summarizes a single successful transaction', () => {\n        const result = successfulSingleTransactionPlanResult(createMessage('A'), {\n            signature: 'A' as Signature,\n        });\n        const summary = summarizeTransactionPlanResult(result);\n        expect(summary).toEqual({\n            canceledTransactions: [],\n            failedTransactions: [],\n            successful: true,\n            successfulTransactions: [result],\n        });\n    });\n\n    it('summarizes a single failed transaction', () => {\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const result = failedSingleTransactionPlanResult(createMessage('A'), error);\n        const summary = summarizeTransactionPlanResult(result);\n        expect(summary).toEqual({\n            canceledTransactions: [],\n            failedTransactions: [result],\n            successful: false,\n            successfulTransactions: [],\n        });\n    });\n\n    it('summarizes a single canceled transaction', () => {\n        const result = canceledSingleTransactionPlanResult(createMessage('A'));\n        const summary = summarizeTransactionPlanResult(result);\n        expect(summary).toEqual({\n            canceledTransactions: [result],\n            failedTransactions: [],\n            successful: false,\n            successfulTransactions: [],\n        });\n    });\n\n    it('summarizes nested successful transactions', () => {\n        const planA = successfulSingleTransactionPlanResult(createMessage('A'), {\n            signature: 'A' as Signature,\n        });\n        const planB = successfulSingleTransactionPlanResult(createMessage('B'), {\n            signature: 'B' as Signature,\n        });\n        const planC = successfulSingleTransactionPlanResult(createMessage('C'), {\n            signature: 'C' as Signature,\n        });\n        const nestedResult = sequentialTransactionPlanResult([parallelTransactionPlanResult([planA, planB]), planC]);\n\n        const summary = summarizeTransactionPlanResult(nestedResult);\n        expect(summary).toEqual({\n            canceledTransactions: [],\n            failedTransactions: [],\n            successful: true,\n            successfulTransactions: [planA, planB, planC],\n        });\n    });\n\n    it('summarizes nested failed transactions', () => {\n        const planA = failedSingleTransactionPlanResult(\n            createMessage('A'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        const planB = failedSingleTransactionPlanResult(\n            createMessage('B'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        const planC = failedSingleTransactionPlanResult(\n            createMessage('C'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        const nestedResult = sequentialTransactionPlanResult([parallelTransactionPlanResult([planA, planB]), planC]);\n\n        const summary = summarizeTransactionPlanResult(nestedResult);\n        expect(summary).toEqual({\n            canceledTransactions: [],\n            failedTransactions: [planA, planB, planC],\n            successful: false,\n            successfulTransactions: [],\n        });\n    });\n\n    it('summarizes nested canceled transactions', () => {\n        const planA = canceledSingleTransactionPlanResult(createMessage('A'));\n        const planB = canceledSingleTransactionPlanResult(createMessage('B'));\n        const planC = canceledSingleTransactionPlanResult(createMessage('C'));\n        const nestedResult = sequentialTransactionPlanResult([parallelTransactionPlanResult([planA, planB]), planC]);\n\n        const summary = summarizeTransactionPlanResult(nestedResult);\n        expect(summary).toEqual({\n            canceledTransactions: [planA, planB, planC],\n            failedTransactions: [],\n            successful: false,\n            successfulTransactions: [],\n        });\n    });\n\n    it('summarizes a mix of successful, failed, and canceled transactions', () => {\n        const planA = successfulSingleTransactionPlanResult(createMessage('A'), {\n            signature: 'A' as Signature,\n        });\n        const planB = failedSingleTransactionPlanResult(\n            createMessage('B'),\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n        );\n        const planC = canceledSingleTransactionPlanResult(createMessage('C'));\n        const mixedResult = sequentialTransactionPlanResult([planA, planB, planC]);\n\n        const summary = summarizeTransactionPlanResult(mixedResult);\n        expect(summary).toEqual({\n            canceledTransactions: [planC],\n            failedTransactions: [planB],\n            successful: false,\n            successfulTransactions: [planA],\n        });\n    });\n});\n\ndescribe('getFirstFailedSingleTransactionPlanResult', () => {\n    it('returns the failed result from a single failed transaction', () => {\n        const messageA = createMessage('A');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const failedResult = failedSingleTransactionPlanResult(messageA, error);\n\n        const result = getFirstFailedSingleTransactionPlanResult(failedResult);\n        expect(result).toBe(failedResult);\n    });\n\n    it('returns the first failed result from a parallel structure', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const failedResult = failedSingleTransactionPlanResult(messageB, error);\n        const parallelResult = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n            failedResult,\n        ]);\n\n        const result = getFirstFailedSingleTransactionPlanResult(parallelResult);\n        expect(result).toBe(failedResult);\n    });\n\n    it('returns the first failed result from a sequential structure', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const failedResult = failedSingleTransactionPlanResult(messageB, error);\n        const sequentialResult = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n            failedResult,\n        ]);\n\n        const result = getFirstFailedSingleTransactionPlanResult(sequentialResult);\n        expect(result).toBe(failedResult);\n    });\n\n    it('returns the first failed result from a deeply nested structure', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const messageC = createMessage('C');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const failedResult = failedSingleTransactionPlanResult(messageC, error);\n        const nestedResult = parallelTransactionPlanResult([\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n                parallelTransactionPlanResult([\n                    successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B')),\n                    failedResult,\n                ]),\n            ]),\n        ]);\n\n        const result = getFirstFailedSingleTransactionPlanResult(nestedResult);\n        expect(result).toBe(failedResult);\n    });\n\n    it('returns the first failed result when multiple failures exist', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const error = new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE);\n        const firstFailedResult = failedSingleTransactionPlanResult(messageA, error);\n        const secondFailedResult = failedSingleTransactionPlanResult(messageB, error);\n        const parallelResult = parallelTransactionPlanResult([firstFailedResult, secondFailedResult]);\n\n        const result = getFirstFailedSingleTransactionPlanResult(parallelResult);\n        expect(result).toBe(firstFailedResult);\n    });\n\n    it('throws SolanaError when no failed result exists (all successful)', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const successfulResult = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n            successfulSingleTransactionPlanResultFromTransaction(messageB, createTransaction('B')),\n        ]);\n\n        expect(() => getFirstFailedSingleTransactionPlanResult(successfulResult)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND, {\n                context: expect.any(Object),\n            }),\n        );\n    });\n\n    it('throws SolanaError when no failed result exists (all canceled)', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const canceledResult = parallelTransactionPlanResult([\n            canceledSingleTransactionPlanResult(messageA),\n            canceledSingleTransactionPlanResult(messageB),\n        ]);\n\n        expect(() => getFirstFailedSingleTransactionPlanResult(canceledResult)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND, {\n                context: {\n                    transactionPlanResult: canceledResult,\n                },\n            }),\n        );\n    });\n\n    it('throws SolanaError when no failed result exists (mixed successful/canceled)', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const mixedResult = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A')),\n            canceledSingleTransactionPlanResult(messageB),\n        ]);\n\n        expect(() => getFirstFailedSingleTransactionPlanResult(mixedResult)).toThrow(\n            new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND, {\n                context: {\n                    transactionPlanResult: mixedResult,\n                },\n            }),\n        );\n    });\n\n    it('throws an error where context contains transactionPlanResult as non-enumerable', () => {\n        const messageA = createMessage('A');\n        const successfulResult = successfulSingleTransactionPlanResultFromTransaction(messageA, createTransaction('A'));\n\n        let caughtError:\n            | SolanaError<typeof SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND>\n            | undefined;\n        try {\n            getFirstFailedSingleTransactionPlanResult(successfulResult);\n        } catch (error) {\n            caughtError = error as SolanaError<\n                typeof SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND\n            >;\n        }\n\n        expect(caughtError).toBeInstanceOf(SolanaError);\n\n        // The transactionPlanResult should be accessible directly on the context\n        expect(caughtError!.context.transactionPlanResult).toBe(successfulResult);\n\n        // But it should not be enumerable (won't appear in Object.keys or JSON.stringify)\n        expect(Object.keys(caughtError!.context)).not.toContain('transactionPlanResult');\n        expect(Object.prototype.propertyIsEnumerable.call(caughtError!.context, 'transactionPlanResult')).toBe(false);\n    });\n});\n\ndescribe('isTransactionPlanResult', () => {\n    it('returns true for SuccessfulSingleTransactionPlanResult', () => {\n        const signature = 'A' as Signature;\n        expect(isTransactionPlanResult(successfulSingleTransactionPlanResult(createMessage('A'), { signature }))).toBe(\n            true,\n        );\n    });\n    it('returns true for FailedSingleTransactionPlanResult', () => {\n        expect(isTransactionPlanResult(failedSingleTransactionPlanResult(createMessage('A'), new Error()))).toBe(true);\n    });\n    it('returns true for CanceledSingleTransactionPlanResult', () => {\n        expect(isTransactionPlanResult(canceledSingleTransactionPlanResult(createMessage('A')))).toBe(true);\n    });\n    it('returns true for ParallelTransactionPlanResult', () => {\n        expect(isTransactionPlanResult(parallelTransactionPlanResult([]))).toBe(true);\n    });\n    it('returns true for SequentialTransactionPlanResult', () => {\n        expect(isTransactionPlanResult(sequentialTransactionPlanResult([]))).toBe(true);\n    });\n    it('returns true for non-divisible SequentialTransactionPlanResult', () => {\n        expect(isTransactionPlanResult(nonDivisibleSequentialTransactionPlanResult([]))).toBe(true);\n    });\n    it('returns false for non-objects', () => {\n        expect(isTransactionPlanResult(null)).toBe(false);\n        expect(isTransactionPlanResult(undefined)).toBe(false);\n        expect(isTransactionPlanResult('string')).toBe(false);\n        expect(isTransactionPlanResult(123)).toBe(false);\n        expect(isTransactionPlanResult(true)).toBe(false);\n    });\n    it('returns false for objects without planType', () => {\n        expect(isTransactionPlanResult({ kind: 'single', status: 'successful' })).toBe(false);\n    });\n    it('returns false for objects with wrong planType', () => {\n        expect(isTransactionPlanResult({ planType: 123 })).toBe(false);\n        expect(isTransactionPlanResult({ planType: null })).toBe(false);\n        expect(isTransactionPlanResult({ planType: 'instructionPlan' })).toBe(false);\n        expect(isTransactionPlanResult({ planType: 'transactionPlan' })).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/transaction-plan-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    assertIsNonDivisibleSequentialTransactionPlan,\n    assertIsParallelTransactionPlan,\n    assertIsSequentialTransactionPlan,\n    assertIsSingleTransactionPlan,\n    everyTransactionPlan,\n    findTransactionPlan,\n    flattenTransactionPlan,\n    isNonDivisibleSequentialTransactionPlan,\n    isParallelTransactionPlan,\n    isSequentialTransactionPlan,\n    isSingleTransactionPlan,\n    isTransactionPlan,\n    nonDivisibleSequentialTransactionPlan,\n    parallelTransactionPlan,\n    sequentialTransactionPlan,\n    singleTransactionPlan,\n    transformTransactionPlan,\n} from '../index';\nimport { createMessage } from './__setup__';\n\ndescribe('singleTransactionPlan', () => {\n    it('creates SingleTransactionPlan objects', () => {\n        const messageA = createMessage('A');\n        const plan = singleTransactionPlan(messageA);\n        expect(plan).toEqual({ kind: 'single', message: messageA, planType: 'transactionPlan' });\n    });\n    it('freezes created SingleTransactionPlan objects', () => {\n        const messageA = createMessage('A');\n        const plan = singleTransactionPlan(messageA);\n        expect(plan).toBeFrozenObject();\n    });\n});\n\ndescribe('parallelTransactionPlan', () => {\n    it('creates ParallelTransactionPlan objects from other plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = parallelTransactionPlan([singleTransactionPlan(messageA), singleTransactionPlan(messageB)]);\n        expect(plan).toEqual({\n            kind: 'parallel',\n            planType: 'transactionPlan',\n            plans: [singleTransactionPlan(messageA), singleTransactionPlan(messageB)],\n        });\n    });\n    it('accepts transaction messages directly and wrap them in single plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = parallelTransactionPlan([messageA, messageB]);\n        expect(plan).toEqual({\n            kind: 'parallel',\n            planType: 'transactionPlan',\n            plans: [singleTransactionPlan(messageA), singleTransactionPlan(messageB)],\n        });\n    });\n    it('can nest other parallel plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const messageC = createMessage('C');\n        const plan = parallelTransactionPlan([messageA, parallelTransactionPlan([messageB, messageC])]);\n        expect(plan).toEqual({\n            kind: 'parallel',\n            planType: 'transactionPlan',\n            plans: [\n                singleTransactionPlan(messageA),\n                {\n                    kind: 'parallel',\n                    planType: 'transactionPlan',\n                    plans: [singleTransactionPlan(messageB), singleTransactionPlan(messageC)],\n                },\n            ],\n        });\n    });\n    it('freezes created ParallelTransactionPlan objects', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = parallelTransactionPlan([messageA, messageB]);\n        expect(plan).toBeFrozenObject();\n    });\n});\n\ndescribe('sequentialTransactionPlan', () => {\n    it('creates divisible SequentialTransactionPlan objects from other plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = sequentialTransactionPlan([singleTransactionPlan(messageA), singleTransactionPlan(messageB)]);\n        expect(plan).toEqual({\n            divisible: true,\n            kind: 'sequential',\n            planType: 'transactionPlan',\n            plans: [singleTransactionPlan(messageA), singleTransactionPlan(messageB)],\n        });\n    });\n    it('accepts transaction messages directly and wrap them in single plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = sequentialTransactionPlan([messageA, messageB]);\n        expect(plan).toEqual({\n            divisible: true,\n            kind: 'sequential',\n            planType: 'transactionPlan',\n            plans: [singleTransactionPlan(messageA), singleTransactionPlan(messageB)],\n        });\n    });\n    it('can nest other sequential plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const messageC = createMessage('C');\n        const plan = sequentialTransactionPlan([messageA, sequentialTransactionPlan([messageB, messageC])]);\n        expect(plan).toEqual({\n            divisible: true,\n            kind: 'sequential',\n            planType: 'transactionPlan',\n            plans: [\n                singleTransactionPlan(messageA),\n                {\n                    divisible: true,\n                    kind: 'sequential',\n                    planType: 'transactionPlan',\n                    plans: [singleTransactionPlan(messageB), singleTransactionPlan(messageC)],\n                },\n            ],\n        });\n    });\n    it('freezes created SequentialTransactionPlan objects', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = sequentialTransactionPlan([messageA, messageB]);\n        expect(plan).toBeFrozenObject();\n    });\n});\n\ndescribe('nonDivisibleSequentialTransactionPlan', () => {\n    it('creates non-divisible SequentialTransactionPlan objects from other plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = nonDivisibleSequentialTransactionPlan([\n            singleTransactionPlan(messageA),\n            singleTransactionPlan(messageB),\n        ]);\n        expect(plan).toEqual({\n            divisible: false,\n            kind: 'sequential',\n            planType: 'transactionPlan',\n            plans: [singleTransactionPlan(messageA), singleTransactionPlan(messageB)],\n        });\n    });\n    it('accepts transaction messages directly and wrap them in single plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n        expect(plan).toEqual({\n            divisible: false,\n            kind: 'sequential',\n            planType: 'transactionPlan',\n            plans: [singleTransactionPlan(messageA), singleTransactionPlan(messageB)],\n        });\n    });\n    it('can nest other non-divisible sequential plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const messageC = createMessage('C');\n        const plan = nonDivisibleSequentialTransactionPlan([\n            messageA,\n            nonDivisibleSequentialTransactionPlan([messageB, messageC]),\n        ]);\n        expect(plan).toEqual({\n            divisible: false,\n            kind: 'sequential',\n            planType: 'transactionPlan',\n            plans: [\n                singleTransactionPlan(messageA),\n                {\n                    divisible: false,\n                    kind: 'sequential',\n                    planType: 'transactionPlan',\n                    plans: [singleTransactionPlan(messageB), singleTransactionPlan(messageC)],\n                },\n            ],\n        });\n    });\n    it('freezes created SequentialTransactionPlan objects', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n        expect(plan).toBeFrozenObject();\n    });\n});\n\ndescribe('isSingleTransactionPlan', () => {\n    it('returns true for SingleTransactionPlan', () => {\n        expect(isSingleTransactionPlan(singleTransactionPlan(createMessage('A')))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isSingleTransactionPlan(sequentialTransactionPlan([]))).toBe(false);\n        expect(isSingleTransactionPlan(nonDivisibleSequentialTransactionPlan([]))).toBe(false);\n        expect(isSingleTransactionPlan(parallelTransactionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsSingleTransactionPlan', () => {\n    it('does nothing for SingleTransactionPlan', () => {\n        expect(() => assertIsSingleTransactionPlan(singleTransactionPlan(createMessage('A')))).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsSingleTransactionPlan(sequentialTransactionPlan([]))).toThrow(\n            'Unexpected transaction plan. Expected single plan, got sequential plan.',\n        );\n        expect(() => assertIsSingleTransactionPlan(nonDivisibleSequentialTransactionPlan([]))).toThrow(\n            'Unexpected transaction plan. Expected single plan, got sequential plan.',\n        );\n        expect(() => assertIsSingleTransactionPlan(parallelTransactionPlan([]))).toThrow(\n            'Unexpected transaction plan. Expected single plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isSequentialTransactionPlan', () => {\n    it('returns true for SequentialTransactionPlan (divisible or not)', () => {\n        expect(isSequentialTransactionPlan(sequentialTransactionPlan([]))).toBe(true);\n        expect(isSequentialTransactionPlan(nonDivisibleSequentialTransactionPlan([]))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isSequentialTransactionPlan(singleTransactionPlan(createMessage('A')))).toBe(false);\n        expect(isSequentialTransactionPlan(parallelTransactionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsSequentialTransactionPlan', () => {\n    it('does nothing for SequentialTransactionPlan', () => {\n        expect(() => assertIsSequentialTransactionPlan(sequentialTransactionPlan([]))).not.toThrow();\n        expect(() => assertIsSequentialTransactionPlan(nonDivisibleSequentialTransactionPlan([]))).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsSequentialTransactionPlan(singleTransactionPlan(createMessage('A')))).toThrow(\n            'Unexpected transaction plan. Expected sequential plan, got single plan.',\n        );\n        expect(() => assertIsSequentialTransactionPlan(parallelTransactionPlan([]))).toThrow(\n            'Unexpected transaction plan. Expected sequential plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isNonDivisibleSequentialTransactionPlan', () => {\n    it('returns true for non-divisible SequentialTransactionPlan', () => {\n        expect(isNonDivisibleSequentialTransactionPlan(nonDivisibleSequentialTransactionPlan([]))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isNonDivisibleSequentialTransactionPlan(singleTransactionPlan(createMessage('A')))).toBe(false);\n        expect(isNonDivisibleSequentialTransactionPlan(sequentialTransactionPlan([]))).toBe(false);\n        expect(isNonDivisibleSequentialTransactionPlan(parallelTransactionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsNonDivisibleSequentialTransactionPlan', () => {\n    it('does nothing for non-divisible SequentialTransactionPlan', () => {\n        expect(() =>\n            assertIsNonDivisibleSequentialTransactionPlan(nonDivisibleSequentialTransactionPlan([])),\n        ).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsNonDivisibleSequentialTransactionPlan(singleTransactionPlan(createMessage('A')))).toThrow(\n            'Unexpected transaction plan. Expected non-divisible sequential plan, got single plan.',\n        );\n        expect(() => assertIsNonDivisibleSequentialTransactionPlan(sequentialTransactionPlan([]))).toThrow(\n            'Unexpected transaction plan. Expected non-divisible sequential plan, got divisible sequential plan.',\n        );\n        expect(() => assertIsNonDivisibleSequentialTransactionPlan(parallelTransactionPlan([]))).toThrow(\n            'Unexpected transaction plan. Expected non-divisible sequential plan, got parallel plan.',\n        );\n    });\n});\n\ndescribe('isParallelTransactionPlan', () => {\n    it('returns true for ParallelTransactionPlan', () => {\n        expect(isParallelTransactionPlan(parallelTransactionPlan([]))).toBe(true);\n    });\n    it('returns false for other plans', () => {\n        expect(isParallelTransactionPlan(singleTransactionPlan(createMessage('A')))).toBe(false);\n        expect(isParallelTransactionPlan(sequentialTransactionPlan([]))).toBe(false);\n        expect(isParallelTransactionPlan(nonDivisibleSequentialTransactionPlan([]))).toBe(false);\n    });\n});\n\ndescribe('assertIsParallelTransactionPlan', () => {\n    it('does nothing for ParallelTransactionPlan', () => {\n        expect(() => assertIsParallelTransactionPlan(parallelTransactionPlan([]))).not.toThrow();\n    });\n    it('throws for other plans', () => {\n        expect(() => assertIsParallelTransactionPlan(singleTransactionPlan(createMessage('A')))).toThrow(\n            'Unexpected transaction plan. Expected parallel plan, got single plan.',\n        );\n        expect(() => assertIsParallelTransactionPlan(sequentialTransactionPlan([]))).toThrow(\n            'Unexpected transaction plan. Expected parallel plan, got sequential plan.',\n        );\n        expect(() => assertIsParallelTransactionPlan(nonDivisibleSequentialTransactionPlan([]))).toThrow(\n            'Unexpected transaction plan. Expected parallel plan, got sequential plan.',\n        );\n    });\n});\n\ndescribe('flattenTransactionPlan', () => {\n    it('returns the single transaction plan when given a SingleTransactionPlan', () => {\n        const messageA = createMessage('A');\n        const plan = singleTransactionPlan(messageA);\n        const result = flattenTransactionPlan(plan);\n        expect(result).toEqual([plan]);\n    });\n    it('returns all single transaction plans from a ParallelTransactionPlan', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = parallelTransactionPlan([messageA, messageB]);\n        const result = flattenTransactionPlan(plan);\n        expect(result).toEqual([singleTransactionPlan(messageA), singleTransactionPlan(messageB)]);\n    });\n    it('returns all single transaction plans from a SequentialTransactionPlan', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const plan = sequentialTransactionPlan([messageA, messageB]);\n        const result = flattenTransactionPlan(plan);\n        expect(result).toEqual([singleTransactionPlan(messageA), singleTransactionPlan(messageB)]);\n    });\n    it('returns all single transaction plans from a complex nested structure', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const messageC = createMessage('C');\n        const messageD = createMessage('D');\n        const messageE = createMessage('E');\n        const plan = parallelTransactionPlan([\n            sequentialTransactionPlan([messageA, messageB]),\n            nonDivisibleSequentialTransactionPlan([messageC, messageD]),\n            messageE,\n        ]);\n        const result = flattenTransactionPlan(plan);\n        expect(result).toEqual([\n            singleTransactionPlan(messageA),\n            singleTransactionPlan(messageB),\n            singleTransactionPlan(messageC),\n            singleTransactionPlan(messageD),\n            singleTransactionPlan(messageE),\n        ]);\n    });\n});\n\ndescribe('findTransactionPlan', () => {\n    it('returns the plan itself when it matches the predicate', () => {\n        const messageA = createMessage('A');\n        const plan = singleTransactionPlan(messageA);\n        const result = findTransactionPlan(plan, p => p.kind === 'single');\n        expect(result).toBe(plan);\n    });\n    it('returns undefined when no plan matches the predicate', () => {\n        const messageA = createMessage('A');\n        const plan = singleTransactionPlan(messageA);\n        const result = findTransactionPlan(plan, p => p.kind === 'parallel');\n        expect(result).toBeUndefined();\n    });\n    it('finds a nested plan in a parallel structure', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const nestedSequential = sequentialTransactionPlan([messageA, messageB]);\n        const plan = parallelTransactionPlan([nestedSequential]);\n        const result = findTransactionPlan(plan, p => p.kind === 'sequential');\n        expect(result).toBe(nestedSequential);\n    });\n    it('finds a nested plan in a sequential structure', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const nestedParallel = parallelTransactionPlan([messageA, messageB]);\n        const plan = sequentialTransactionPlan([nestedParallel]);\n        const result = findTransactionPlan(plan, p => p.kind === 'parallel');\n        expect(result).toBe(nestedParallel);\n    });\n    it('returns the first matching plan in top-down order', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const innerSequential = sequentialTransactionPlan([messageA]);\n        const outerSequential = sequentialTransactionPlan([innerSequential, messageB]);\n        const result = findTransactionPlan(outerSequential, p => p.kind === 'sequential');\n        expect(result).toBe(outerSequential);\n    });\n    it('finds a deeply nested plan', () => {\n        const messageA = createMessage('A');\n        const deepSingle = singleTransactionPlan(messageA);\n        const plan = parallelTransactionPlan([sequentialTransactionPlan([parallelTransactionPlan([deepSingle])])]);\n        const result = findTransactionPlan(plan, p => p.kind === 'single');\n        expect(result).toBe(deepSingle);\n    });\n    it('supports complex predicates that inspect nested properties', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const messageC = createMessage('C');\n        const targetPlan = sequentialTransactionPlan([messageA, messageB]);\n        const plan = parallelTransactionPlan([singleTransactionPlan(messageC), targetPlan]);\n        const result = findTransactionPlan(\n            plan,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p => p.kind === 'sequential' && p.plans.length === 2,\n        );\n        expect(result).toBe(targetPlan);\n    });\n    it('returns undefined when searching an empty parallel plan', () => {\n        const plan = parallelTransactionPlan([]);\n        const result = findTransactionPlan(plan, p => p.kind === 'single');\n        expect(result).toBeUndefined();\n    });\n    it('finds non-divisible sequential plans', () => {\n        const messageA = createMessage('A');\n        const messageB = createMessage('B');\n        const nonDivisible = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n        const plan = parallelTransactionPlan([sequentialTransactionPlan([createMessage('C')]), nonDivisible]);\n        const result = findTransactionPlan(\n            plan,\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p => p.kind === 'sequential' && !p.divisible,\n        );\n        expect(result).toBe(nonDivisible);\n    });\n});\n\ndescribe('everyTransactionPlan', () => {\n    it('returns true when all plans match the predicate', () => {\n        const plan = sequentialTransactionPlan([sequentialTransactionPlan([]), sequentialTransactionPlan([])]);\n        const result = everyTransactionPlan(plan, p => p.kind === 'sequential');\n        expect(result).toBe(true);\n    });\n    it('returns false when at least one plan does not match the predicate', () => {\n        const plan = sequentialTransactionPlan([parallelTransactionPlan([]), sequentialTransactionPlan([])]);\n        const result = everyTransactionPlan(plan, p => p.kind === 'sequential');\n        expect(result).toBe(false);\n    });\n    it('matches single transaction plans', () => {\n        const plan = singleTransactionPlan(createMessage('A'));\n        const result = everyTransactionPlan(plan, p => p.kind === 'single');\n        expect(result).toBe(true);\n    });\n    it('matches sequential transaction plans', () => {\n        const plan = sequentialTransactionPlan([]);\n        const result = everyTransactionPlan(plan, p => p.kind === 'sequential');\n        expect(result).toBe(true);\n    });\n    it('matches non-divisible sequential transaction plans', () => {\n        const plan = nonDivisibleSequentialTransactionPlan([]);\n        // eslint-disable-next-line jest/no-conditional-in-test\n        const result = everyTransactionPlan(plan, p => p.kind === 'sequential' && !p.divisible);\n        expect(result).toBe(true);\n    });\n    it('matches parallel transaction plans', () => {\n        const plan = parallelTransactionPlan([]);\n        const result = everyTransactionPlan(plan, p => p.kind === 'parallel');\n        expect(result).toBe(true);\n    });\n    it('matches complex transaction plans', () => {\n        const plan = sequentialTransactionPlan([\n            parallelTransactionPlan([createMessage('A'), createMessage('B')]),\n            nonDivisibleSequentialTransactionPlan([createMessage('A'), createMessage('C')]),\n        ]);\n        const result = everyTransactionPlan(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind !== 'single') return true;\n            const message = p.message as ReturnType<typeof createMessage>;\n            return ['A', 'B', 'C'].includes(message.id);\n        });\n        expect(result).toBe(true);\n    });\n    it('returns false on complex transaction plans', () => {\n        const plan = sequentialTransactionPlan([\n            parallelTransactionPlan([createMessage('A'), createMessage('B')]),\n            nonDivisibleSequentialTransactionPlan([createMessage('A'), createMessage('C')]),\n        ]);\n        const result = everyTransactionPlan(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind !== 'single') return true;\n            const message = p.message as ReturnType<typeof createMessage>;\n            return message.id === 'A';\n        });\n        expect(result).toBe(false);\n    });\n    it('fails fast before evaluating children', () => {\n        const predicate = jest.fn().mockReturnValueOnce(false);\n        const messageA = singleTransactionPlan(createMessage('A'));\n        const messageB = singleTransactionPlan(createMessage('B'));\n        const plan = sequentialTransactionPlan([messageA, messageB]);\n        const result = everyTransactionPlan(plan, predicate);\n        expect(result).toBe(false);\n        expect(predicate).toHaveBeenCalledTimes(1);\n        expect(predicate).toHaveBeenNthCalledWith(1, plan);\n        expect(predicate).not.toHaveBeenCalledWith(messageA);\n        expect(predicate).not.toHaveBeenCalledWith(messageB);\n    });\n    it('fails fast before evaluating siblings', () => {\n        const predicate = jest.fn().mockReturnValueOnce(true).mockReturnValueOnce(false);\n        const messageA = singleTransactionPlan(createMessage('A'));\n        const messageB = singleTransactionPlan(createMessage('B'));\n        const plan = sequentialTransactionPlan([messageA, messageB]);\n        const result = everyTransactionPlan(plan, predicate);\n        expect(result).toBe(false);\n        expect(predicate).toHaveBeenCalledTimes(2);\n        expect(predicate).toHaveBeenNthCalledWith(1, plan);\n        expect(predicate).toHaveBeenNthCalledWith(2, messageA);\n        expect(predicate).not.toHaveBeenCalledWith(messageB);\n    });\n});\n\ndescribe('transformTransactionPlan', () => {\n    it('transforms single transaction plans', () => {\n        const plan = singleTransactionPlan(createMessage('A'));\n        const transformedPlan = transformTransactionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'single' ? { ...p, message: { ...p.message, id: 'New A' } } : p,\n        );\n        expect(transformedPlan).toStrictEqual(singleTransactionPlan(createMessage('New A')));\n    });\n    it('transforms sequential transaction plans', () => {\n        const plan = sequentialTransactionPlan([createMessage('A'), createMessage('B')]);\n        const transformedPlan = transformTransactionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'sequential' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(sequentialTransactionPlan([createMessage('B'), createMessage('A')]));\n    });\n    it('transforms non-divisible sequential transaction plans', () => {\n        const plan = nonDivisibleSequentialTransactionPlan([createMessage('A'), createMessage('B')]);\n        const transformedPlan = transformTransactionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'sequential' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            nonDivisibleSequentialTransactionPlan([createMessage('B'), createMessage('A')]),\n        );\n    });\n    it('transforms parallel transaction plans', () => {\n        const plan = parallelTransactionPlan([createMessage('A'), createMessage('B')]);\n        const transformedPlan = transformTransactionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'parallel' ? { ...p, plans: p.plans.reverse() } : p,\n        );\n        expect(transformedPlan).toStrictEqual(parallelTransactionPlan([createMessage('B'), createMessage('A')]));\n    });\n    it('transforms using a bottom-up approach', () => {\n        // Given the following nested plans.\n        const plan = sequentialTransactionPlan([\n            createMessage('A'),\n            sequentialTransactionPlan([createMessage('B'), createMessage('C')]),\n        ]);\n\n        // And given an array of message IDs that were seen by sequential plans during transformation.\n        const seenTransactionMessageIds: string[] = [];\n\n        // When transforming by prepending \"New \" to single transaction plan IDs\n        // And recording the seen transaction message IDs in sequential plans.\n        transformTransactionPlan(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind === 'single') {\n                const message = p.message as ReturnType<typeof createMessage>;\n                return { ...p, message: { ...message, id: `New ${message.id}` } };\n            }\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind === 'sequential') {\n                const seenMessages = p.plans\n                    .filter(subPlan => subPlan.kind === 'single')\n                    .map(subPlan => subPlan.message as ReturnType<typeof createMessage>);\n                seenTransactionMessageIds.push(...seenMessages.map(message => message.id));\n            }\n            return p;\n        });\n\n        // Then we expect the seen message IDs to have already been transformed\n        // using a bottom-up approach.\n        expect(seenTransactionMessageIds).toStrictEqual(['New B', 'New C', 'New A']);\n    });\n    it('can be used to duplicate transactions', () => {\n        const plan = sequentialTransactionPlan([createMessage('A'), createMessage('B')]);\n        const transformedPlan = transformTransactionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'single' ? sequentialTransactionPlan([p.message, p.message]) : p,\n        );\n        expect(transformedPlan).toStrictEqual(\n            sequentialTransactionPlan([\n                sequentialTransactionPlan([createMessage('A'), createMessage('A')]),\n                sequentialTransactionPlan([createMessage('B'), createMessage('B')]),\n            ]),\n        );\n    });\n    it('can be used to remove parallelism', () => {\n        const plan = parallelTransactionPlan([createMessage('A'), createMessage('B')]);\n        const transformedPlan = transformTransactionPlan(plan, p =>\n            // eslint-disable-next-line jest/no-conditional-in-test\n            p.kind === 'parallel' ? sequentialTransactionPlan(p.plans) : p,\n        );\n        expect(transformedPlan).toStrictEqual(sequentialTransactionPlan([createMessage('A'), createMessage('B')]));\n    });\n    it('can be used to flatten nested transaction plans', () => {\n        const plan = sequentialTransactionPlan([\n            sequentialTransactionPlan([createMessage('A'), createMessage('B')]),\n            sequentialTransactionPlan([\n                createMessage('C'),\n                sequentialTransactionPlan([createMessage('D'), createMessage('E')]),\n            ]),\n        ]);\n        const transformedPlan = transformTransactionPlan(plan, p => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (p.kind !== 'sequential') return p;\n            const subPlans = p.plans.flatMap(subPlan =>\n                // eslint-disable-next-line jest/no-conditional-in-test\n                subPlan.kind === 'sequential' && p.divisible === subPlan.divisible ? subPlan.plans : [subPlan],\n            );\n            return { ...p, plans: subPlans };\n        });\n        expect(transformedPlan).toStrictEqual(\n            sequentialTransactionPlan([\n                createMessage('A'),\n                createMessage('B'),\n                createMessage('C'),\n                createMessage('D'),\n                createMessage('E'),\n            ]),\n        );\n    });\n    it('keeps transformed single transaction plans frozen', () => {\n        const plan = singleTransactionPlan(createMessage('A'));\n        const transformedPlan = transformTransactionPlan(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed sequential transaction plans frozen', () => {\n        const plan = sequentialTransactionPlan([createMessage('A')]);\n        const transformedPlan = transformTransactionPlan(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n    it('keeps transformed parallel transaction plans frozen', () => {\n        const plan = parallelTransactionPlan([createMessage('A')]);\n        const transformedPlan = transformTransactionPlan(plan, p => ({ ...p }));\n        expect(transformedPlan).toBeFrozenObject();\n    });\n});\n\ndescribe('isTransactionPlan', () => {\n    it('returns true for SingleTransactionPlan', () => {\n        expect(isTransactionPlan(singleTransactionPlan(createMessage('A')))).toBe(true);\n    });\n    it('returns true for ParallelTransactionPlan', () => {\n        expect(isTransactionPlan(parallelTransactionPlan([]))).toBe(true);\n    });\n    it('returns true for SequentialTransactionPlan', () => {\n        expect(isTransactionPlan(sequentialTransactionPlan([]))).toBe(true);\n    });\n    it('returns true for non-divisible SequentialTransactionPlan', () => {\n        expect(isTransactionPlan(nonDivisibleSequentialTransactionPlan([]))).toBe(true);\n    });\n    it('returns false for non-objects', () => {\n        expect(isTransactionPlan(null)).toBe(false);\n        expect(isTransactionPlan(undefined)).toBe(false);\n        expect(isTransactionPlan('string')).toBe(false);\n        expect(isTransactionPlan(123)).toBe(false);\n        expect(isTransactionPlan(true)).toBe(false);\n    });\n    it('returns false for objects without planType', () => {\n        expect(isTransactionPlan({ kind: 'single' })).toBe(false);\n    });\n    it('returns false for objects with wrong planType', () => {\n        expect(isTransactionPlan({ planType: 123 })).toBe(false);\n        expect(isTransactionPlan({ planType: null })).toBe(false);\n        expect(isTransactionPlan({ planType: 'instructionPlan' })).toBe(false);\n        expect(isTransactionPlan({ planType: 'transactionPlanResult' })).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/instruction-plans/src/__tests__/transaction-planner-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address, getAddressDecoder } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole, Instruction } from '@solana/instructions';\nimport {\n    appendTransactionMessageInstructions,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, TRANSACTION_SIZE_LIMIT } from '@solana/transactions';\n\nimport {\n    createTransactionPlanner,\n    InstructionPlan,\n    nonDivisibleSequentialInstructionPlan,\n    nonDivisibleSequentialTransactionPlan,\n    parallelInstructionPlan,\n    ParallelTransactionPlan,\n    parallelTransactionPlan,\n    sequentialInstructionPlan,\n    SequentialTransactionPlan,\n    sequentialTransactionPlan,\n    singleInstructionPlan,\n    SingleTransactionPlan,\n    singleTransactionPlan,\n    TransactionPlan,\n    TransactionPlanner,\n} from '../index';\nimport {\n    createMessage,\n    createMessagePackerInstructionPlan,\n    createSingleInstructionAtATimeMessagePackerInstructionPlan,\n    FOREVER_PROMISE,\n    instructionFactory,\n    transactionPercentFactory,\n} from './__setup__';\n\nfunction createMockTransactionMessage(): TransactionMessage & TransactionMessageWithFeePayer {\n    return createMessage('mock-message');\n}\n\nfunction getHelpers(createTransactionMessage: () => TransactionMessage & TransactionMessageWithFeePayer) {\n    return {\n        instruction: instructionFactory(),\n        singleTransactionPlan: (instructions: Instruction[]) =>\n            singleTransactionPlan(appendTransactionMessageInstructions(instructions, createTransactionMessage())),\n        txPercent: transactionPercentFactory(createTransactionMessage),\n    };\n}\n\ndescribe('createTransactionPlanner', () => {\n    describe('single scenarios', () => {\n        /**\n         *  [A: 42] ───────────────────▶ [Tx: A]\n         */\n        it('plans a single instruction', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', 42);\n\n            await expect(planner(singleInstructionPlan(instructionA))).resolves.toEqual(\n                singleTransactionPlan([instructionA]),\n            );\n        });\n\n        /**\n         *  [A: 200%] ───────────────────▶ Error\n         */\n        it('fail if a single instruction is too large', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(200));\n            const instructionPlan = singleInstructionPlan(instructionA);\n\n            const newMessage = createTransactionMessage();\n            const newMessageSize = getTransactionMessageSize(newMessage);\n            const impossibleMessageSize = getTransactionMessageSize(\n                appendTransactionMessageInstructions([instructionA], newMessage),\n            );\n\n            await expect(planner(instructionPlan)).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n                    numBytesRequired: impossibleMessageSize - newMessageSize,\n                    numFreeBytes: TRANSACTION_SIZE_LIMIT - newMessageSize,\n                }),\n            );\n        });\n    });\n\n    describe('transaction constraint scenarios', () => {\n        const addressDecoder = getAddressDecoder();\n        function makeAddress(i: number): Address {\n            return addressDecoder.decode(new Uint8Array(32).fill(i));\n        }\n        function makeAddresses(n: number, offset = 0): Address[] {\n            return Array.from({ length: n }, (_, i) => makeAddress(offset + i));\n        }\n\n        /**\n         *  [Seq]           ──────────────────────────────────────▶   [Seq]\n         *   │  (65 instructions, same program address)                  │\n         *   ├── [I0]                                                    ├── [Tx: I0…I63]\n         *   ├── …                                                       └── [Tx: I64]\n         *   └── [I64]\n         */\n        it('splits into a new transaction when there are too many instructions', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { singleTransactionPlan } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            // All 65 instructions share the same program address so they don't add\n            // to the unique-account count. The 65th triggers TOO_MANY_INSTRUCTIONS.\n            const instruction: Instruction = { programAddress: makeAddress(1) };\n            const instructions = Array.from({ length: 65 }, () => instruction);\n\n            await expect(\n                planner(sequentialInstructionPlan(instructions.map(i => singleInstructionPlan(i)))),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan(instructions.slice(0, 64)),\n                    singleTransactionPlan([instruction]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq]    ──────────────────────────────────────────────────▶   [Seq]\n         *   │  (A fills to 33 unique accounts; B adds 33 more               │\n         *   │   pushing the combined total to 66 > 64)                      ├── [Tx: A]\n         *   ├── [A]                                                         └── [Tx: B]\n         *   └── [B]\n         */\n        it('splits into a new transaction when there are too many account addresses', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { singleTransactionPlan } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            // Base message: feePayer (1)\n            // A: A's program (1) + 31 READONLY accounts = 32 new unique accounts.\n            // B: B's program (1) + 32 new READONLY accounts = 33 new unique accounts.\n            // Combined: 66 unique accounts → TOO_MANY_ACCOUNT_ADDRESSES.\n            // A alone: fee payer (1) + A's program (1) + 31 accounts = 33 unique accounts (within limit).\n            // B alone: fee payer (1) + B's program (1) + 32 accounts = 34 accounts (within limit).\n            const instructionA: Instruction = {\n                accounts: makeAddresses(31).map(address => ({ address, role: AccountRole.READONLY })),\n                programAddress: makeAddress(32),\n            };\n            const instructionB: Instruction = {\n                accounts: makeAddresses(32, 32).map(address => ({ address, role: AccountRole.READONLY })),\n                programAddress: makeAddress(100),\n            };\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq]    ──────────────────────────────────────────────────▶   [Seq]\n         *   │  (A fills to 11 signers; B adds 2 more                        │\n         *   │   pushing the combined total to 13 > 12)                      ├── [Tx: A]\n         *   ├── [A]                                                         └── [Tx: B]\n         *   └── [B]\n         */\n        it('splits into a new transaction when there are too many signer addresses', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { singleTransactionPlan } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            // Base message: feePayer (1 signer)\n            // A: 10 new READONLY_SIGNER\n            // B: 2 new READONLY_SIGNER\n            // Combined: 13 signers → TOO_MANY_SIGNER_ADDRESSES.\n            // A alone: fee payer (1) + A's 10 signers = 11 signers (within limit).\n            // B alone: fee payer (1) + B's 2 signers = 3 signers (within limit).\n            const instructionA: Instruction = {\n                accounts: makeAddresses(10).map(address => ({ address, role: AccountRole.READONLY_SIGNER })),\n                programAddress: makeAddress(20),\n            };\n            const instructionB: Instruction = {\n                accounts: makeAddresses(2, 10).map(address => ({ address, role: AccountRole.READONLY_SIGNER })),\n                programAddress: makeAddress(30),\n            };\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB]),\n                ]),\n            );\n        });\n\n        const CONSTRAINT_ERRORS: [string, SolanaError][] = [\n            [\n                'TOO_MANY_ACCOUNT_ADDRESSES',\n                new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES, {\n                    actualCount: 65,\n                    maxAllowed: 64,\n                }),\n            ],\n            [\n                'TOO_MANY_SIGNER_ADDRESSES',\n                new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES, {\n                    actualCount: 13,\n                    maxAllowed: 12,\n                }),\n            ],\n            [\n                'TOO_MANY_INSTRUCTIONS',\n                new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS, {\n                    actualCount: 65,\n                    maxAllowed: 64,\n                }),\n            ],\n            [\n                'TOO_MANY_ACCOUNTS_IN_INSTRUCTION',\n                new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                    actualCount: 256,\n                    instructionIndex: 0,\n                    maxAllowed: 255,\n                }),\n            ],\n        ];\n\n        /**\n         *  [A] ──────────▶  Error\n         *  (createTransactionMessage always throws the constraint error)\n         */\n        it.each(CONSTRAINT_ERRORS)(\n            'propagates %s when createTransactionMessage cannot create a fresh message',\n            async (_name, constraintError) => {\n                expect.assertions(1);\n                const instruction: Instruction = { programAddress: makeAddress(1) };\n                const planner = createTransactionPlanner({\n                    createTransactionMessage: () => {\n                        throw constraintError;\n                    },\n                });\n                await expect(planner(singleInstructionPlan(instruction))).rejects.toThrow(constraintError);\n            },\n        );\n    });\n\n    describe('sequential scenarios', () => {\n        /**\n         *  [Seq] ───────────────────▶ [Tx: A + B]\n         *   │\n         *   ├── [A: 50%]\n         *   └── [B: 50%]\n         */\n        it('plans a sequential plan with instructions that all fit in a single transaction', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB]));\n        });\n\n        /**\n         *  [Seq] ───────────────────▶ [Seq]\n         *   │                          │\n         *   ├── [A: 50%]               ├── [Tx: A + B]\n         *   ├── [B: 50%]               └── [Tx: C]\n         *   └── [C: 50%]\n         */\n        it('plans a sequential plan with instructions that must be split accross multiple transactions (v1)', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ───────────────────▶ [Seq]\n         *   │                          │\n         *   ├── [A: 60%]               ├── [Tx: A]\n         *   ├── [B: 50%]               └── [Tx: B + C]\n         *   └── [C: 50%]\n         */\n        it('plans a sequential plan with instructions that must be split accross multiple transactions (v2)', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(60)); // Tx A cannot have Ix B.\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB, instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ───────────────────▶ [Tx: A + B]\n         *   │\n         *   ├── [A: 50%]\n         *   ├── [Seq]\n         *   └── [Seq]\n         *        └── [B: 50%]\n         */\n        it('simplifies sequential plans with one child or less', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        sequentialInstructionPlan([]),\n                        sequentialInstructionPlan([singleInstructionPlan(instructionB)]),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB]));\n        });\n\n        /**\n         *  [Seq] ──────────────────────▶ [Seq]\n         *   │                             │\n         *   ├── [A: 100%]                 ├── [Tx: A]\n         *   └── [Seq]                     ├── [Tx: B]\n         *        ├── [B: 100%]            └── [Tx: C]\n         *        └── [C: 100%]\n         */\n        it('simplifies nested sequential plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(100));\n            const instructionB = instruction('B', txPercent(100));\n            const instructionC = instruction('C', txPercent(100));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionB),\n                            singleInstructionPlan(instructionC),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB]),\n                    singleTransactionPlan([instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ──────────────────────▶ [Seq]\n         *   │                             │\n         *   ├── [A: 50%]                  ├── [Tx: A + B]\n         *   ├── [Seq]                     └── [Tx: C + D]\n         *   │    ├── [B: 50%]\n         *   │    └── [C: 50%]\n         *   └── [D: 50%]\n         */\n        it('simplifies sequential plans nested in the middle', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(50));\n            const instructionD = instruction('D', txPercent(50));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionB),\n                            singleInstructionPlan(instructionC),\n                        ]),\n                        singleInstructionPlan(instructionD),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC, instructionD]),\n                ]),\n            );\n        });\n    });\n\n    describe('parallel scenarios', () => {\n        /**\n         *  [Par] ───────────────────▶ [Tx: A + B]\n         *   │\n         *   ├── [A: 50%]\n         *   └── [B: 50%]\n         */\n        it('plans a parallel plan with instructions that all fit in a single transaction', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([singleInstructionPlan(instructionA), singleInstructionPlan(instructionB)]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB]));\n        });\n\n        /**\n         *  [Par] ───────────────────▶ [Par]\n         *   │                          │\n         *   ├── [A: 50%]               ├── [Tx: A + B]\n         *   ├── [B: 50%]               └── [Tx: C]\n         *   └── [C: 50%]\n         */\n        it('plans a parallel plan with instructions that must be split accross multiple transactions (v1)', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Par] ───────────────────▶ [Par]\n         *   │                          │\n         *   ├── [A: 60%]               ├── [Tx: A]\n         *   ├── [B: 50%]               └── [Tx: B + C]\n         *   └── [C: 50%]\n         */\n        it('plans a parallel plan with instructions that must be split accross multiple transactions (v2)', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(60)); // Tx A cannot have Ix B.\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB, instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Par] ───────────────────▶ [Tx: A + B]\n         *   │\n         *   ├── [A: 50%]\n         *   ├── [Par]\n         *   └── [Par]\n         *        └── [B: 50%]\n         */\n        it('simplifies parallel plans with one child or less', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        parallelInstructionPlan([]),\n                        parallelInstructionPlan([singleInstructionPlan(instructionB)]),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB]));\n        });\n\n        /**\n         *  [Par] ──────────────────────▶ [Par]\n         *   │                             │\n         *   ├── [A: 100%]                 ├── [Tx: A]\n         *   └── [Par]                     ├── [Tx: B]\n         *        ├── [B: 100%]            └── [Tx: C]\n         *        └── [C: 100%]\n         */\n        it('simplifies nested parallel plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(100));\n            const instructionB = instruction('B', txPercent(100));\n            const instructionC = instruction('C', txPercent(100));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        parallelInstructionPlan([\n                            singleInstructionPlan(instructionB),\n                            singleInstructionPlan(instructionC),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB]),\n                    singleTransactionPlan([instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Par] ───────────────────▶ [Par]\n         *   │                          │\n         *   ├── [Seq]                  ├── [Tx: A + B + D]\n         *   │    ├── [A: 50%]          └── [Tx: C]\n         *   │    └── [B: 25%]\n         *   ├── [C: 90%]\n         *   └── [D: 25%]\n         */\n        it('re-uses previous parallel transactions if there is space', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(25));\n            const instructionC = instruction('C', txPercent(90));\n            const instructionD = instruction('D', txPercent(25));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        singleInstructionPlan(instructionC),\n                        singleInstructionPlan(instructionD),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB, instructionD]),\n                    singleTransactionPlan([instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Par] ───────────────────▶ [Tx: A + B + C + D]\n         *   │\n         *   ├── [Seq]\n         *   │    ├── [A: 25%]\n         *   │    └── [B: 25%]\n         *   └── [Seq]\n         *        ├── [C: 25%]\n         *        └── [D: 25%]\n         */\n        it('can merge sequential plans in a parallel plan if the whole sequential plan fits', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(25));\n            const instructionB = instruction('B', txPercent(25));\n            const instructionC = instruction('C', txPercent(25));\n            const instructionD = instruction('D', txPercent(25));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB, instructionC, instructionD]));\n        });\n\n        /**\n         *  [Par] ───────────────────▶ [Par]\n         *   │                          │\n         *   ├── [Seq]                  ├── [Tx: A + B]\n         *   │    ├── [A: 33%]          └── [Tx: C + D]\n         *   │    └── [B: 33%]\n         *   └── [Seq]\n         *        ├── [C: 33%]\n         *        └── [D: 33%]\n         */\n        it('does not split a sequential plan on a parallel parent', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(33));\n            const instructionB = instruction('B', txPercent(33));\n            const instructionC = instruction('C', txPercent(33));\n            const instructionD = instruction('D', txPercent(33));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC, instructionD]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ───────────────────▶ [Seq]\n         *   │                          │\n         *   ├── [Par]                  ├── [Tx: A + B + C]\n         *   │    ├── [A: 33%]          └── [Tx: D]\n         *   │    └── [B: 33%]\n         *   └── [Par]\n         *        ├── [C: 33%]\n         *        └── [D: 33%]\n         */\n        it('can split parallel plans inside sequential plans as long as they follow the sequence', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(33));\n            const instructionB = instruction('B', txPercent(33));\n            const instructionC = instruction('C', txPercent(33));\n            const instructionD = instruction('D', txPercent(33));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        parallelInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        parallelInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB, instructionC]),\n                    singleTransactionPlan([instructionD]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ───────────────────▶ [Seq]\n         *   │                          │\n         *   ├── [Par]                  ├── [Tx: A + B]\n         *   │    ├── [A: 33%]          ├── [Tx: C + D]\n         *   │    └── [B: 33%]          └── [Tx: E + F]\n         *   ├── [Par]\n         *   │    ├── [C: 50%]\n         *   │    └── [D: 50%]\n         *   └── [Par]\n         *         ├── [E: 33%]\n         *         └── [F: 33%]\n         */\n        it('cannnot split a parallel plan in a sequential plan if that would break the sequence', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(33));\n            const instructionB = instruction('B', txPercent(33));\n            const instructionC = instruction('C', txPercent(50));\n            const instructionD = instruction('D', txPercent(50));\n            const instructionE = instruction('E', txPercent(33));\n            const instructionF = instruction('F', txPercent(33));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        parallelInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        parallelInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                        parallelInstructionPlan([\n                            singleInstructionPlan(instructionE),\n                            singleInstructionPlan(instructionF),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC, instructionD]),\n                    singleTransactionPlan([instructionE, instructionF]),\n                ]),\n            );\n        });\n    });\n\n    describe('non-divisible sequential scenarios', () => {\n        /**\n         *  [NonDivSeq] ───────────────────▶ [Tx: A + B]\n         *   │\n         *   ├── [A: 50%]\n         *   └── [B: 50%]\n         */\n        it('plans an non-divisible sequential plan with instructions that all fit in a single transaction', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB]));\n        });\n\n        /**\n         *  [NonDivSeq] ─────────────▶ [NonDivSeq]\n         *   │                          │\n         *   ├── [A: 50%]               ├── [Tx: A + B]\n         *   ├── [B: 50%]               └── [Tx: C]\n         *   └── [C: 50%]\n         */\n        it('plans a non-divisible sequential plan with instructions that must be split accross multiple transactions (v1)', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                nonDivisibleSequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [NonDivSeq] ─────────────▶ [NonDivSeq]\n         *   │                          │\n         *   ├── [A: 60%]               ├── [Tx: A]\n         *   ├── [B: 50%]               └── [Tx: B + C]\n         *   └── [C: 50%]\n         */\n        it('plans a non-divisible sequential plan with instructions that must be split accross multiple transactions (v2)', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(60)); // Tx A cannot have Ix B.\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                nonDivisibleSequentialTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB, instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [NonDivSeq] ─────────────▶ [Tx: A + B]\n         *   │\n         *   ├── [A: 50%]\n         *   ├── [NonDivSeq]\n         *   └── [NonDivSeq]\n         *        └── [B: 50%]\n         */\n        it('simplifies non-divisible sequential plans with one child or less', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        nonDivisibleSequentialInstructionPlan([]),\n                        nonDivisibleSequentialInstructionPlan([singleInstructionPlan(instructionB)]),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB]));\n        });\n\n        /**\n         *  [NonDivSeq] ────────────────▶ [NonDivSeq]\n         *   │                             │\n         *   ├── [A: 100%]                 ├── [Tx: A]\n         *   └── [NonDivSeq]               ├── [Tx: B]\n         *        ├── [B: 100%]            └── [Tx: C]\n         *        └── [C: 100%]\n         */\n        it('simplifies nested non-divisible sequential plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(100));\n            const instructionB = instruction('B', txPercent(100));\n            const instructionC = instruction('C', txPercent(100));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionB),\n                            singleInstructionPlan(instructionC),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                nonDivisibleSequentialTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB]),\n                    singleTransactionPlan([instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [NonDivSeq] ────────────────▶ [NonDivSeq]\n         *   │                             │\n         *   ├── [A: 100%]                 ├── [Tx: A]\n         *   └── [Seq]                     ├── [Tx: B]\n         *        ├── [B: 100%]            └── [Tx: C]\n         *        └── [C: 100%]\n         */\n        it('simplifies divisible sequential plans inside non-divisible sequential plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(100));\n            const instructionB = instruction('B', txPercent(100));\n            const instructionC = instruction('C', txPercent(100));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionB),\n                            singleInstructionPlan(instructionC),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                nonDivisibleSequentialTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    singleTransactionPlan([instructionB]),\n                    singleTransactionPlan([instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ──────────────────────▶ [Seq]\n         *   │                             │\n         *   ├── [A: 100%]                 ├── [Tx: A]\n         *   └── [NonDivSeq]               └── [NonDivSeq]\n         *        ├── [B: 100%]                 ├── [Tx: B]\n         *        └── [C: 100%]                 └── [Tx: C]\n         */\n        it('does not simplify non-divisible sequential plans inside divisible sequential plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(100));\n            const instructionB = instruction('B', txPercent(100));\n            const instructionC = instruction('C', txPercent(100));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionB),\n                            singleInstructionPlan(instructionC),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA]),\n                    nonDivisibleSequentialTransactionPlan([\n                        singleTransactionPlan([instructionB]),\n                        singleTransactionPlan([instructionC]),\n                    ]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Par] ───────────────────▶ [Tx: A + B + C + D]\n         *   │\n         *   ├── [NonDivSeq]\n         *   │    ├── [A: 25%]\n         *   │    └── [B: 25%]\n         *   └── [NonDivSeq]\n         *        ├── [C: 25%]\n         *        └── [D: 25%]\n         */\n        it('can merge non-divisible sequential plans in a parallel plan if the whole sequential plan fits', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(25));\n            const instructionB = instruction('B', txPercent(25));\n            const instructionC = instruction('C', txPercent(25));\n            const instructionD = instruction('D', txPercent(25));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB, instructionC, instructionD]));\n        });\n\n        /**\n         *  [Par] ───────────────────▶ [Par]\n         *   │                          │\n         *   ├── [NonDivSeq]            ├── [Tx: A + B]\n         *   │    ├── [A: 33%]          └── [Tx: C + D]\n         *   │    └── [B: 33%]\n         *   └── [NonDivSeq]\n         *        ├── [C: 33%]\n         *        └── [D: 33%]\n         */\n        it('does not split a non-divisible sequential plan on a parallel parent', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(33));\n            const instructionB = instruction('B', txPercent(33));\n            const instructionC = instruction('C', txPercent(33));\n            const instructionD = instruction('D', txPercent(33));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC, instructionD]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ───────────────────▶ [Tx: A + B + C + D]\n         *   │\n         *   ├── [NonDivSeq]\n         *   │    ├── [A: 25%]\n         *   │    └── [B: 25%]\n         *   └── [NonDivSeq]\n         *        ├── [C: 25%]\n         *        └── [D: 25%]\n         */\n        it('can merge non-divisible sequential plans in a sequential plan if the whole plan fits', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(25));\n            const instructionB = instruction('B', txPercent(25));\n            const instructionC = instruction('C', txPercent(25));\n            const instructionD = instruction('D', txPercent(25));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB, instructionC, instructionD]));\n        });\n\n        /**\n         *  [Seq] ───────────────────▶ [Seq]\n         *   │                          │\n         *   ├── [NonDivSeq]            ├── [Tx: A + B]\n         *   │    ├── [A: 33%]          └── [Tx: C + D]\n         *   │    └── [B: 33%]\n         *   └── [NonDivSeq]\n         *        ├── [C: 33%]\n         *        └── [D: 33%]\n         */\n        it('does not split a non-divisible sequential plan on a sequential parent', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(33));\n            const instructionB = instruction('B', txPercent(33));\n            const instructionC = instruction('C', txPercent(33));\n            const instructionD = instruction('D', txPercent(33));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC, instructionD]),\n                ]),\n            );\n        });\n\n        /**\n         *  [NonDivSeq] ─────────────▶ [NonDivSeq]\n         *   │                          │\n         *   ├── [Par]                  ├── [Tx: A + B]\n         *   │    ├── [A: 50%]          └── [Par]\n         *   │    └── [B: 50%]               ├── [Tx: C]\n         *   └── [Par]                       └── [Tx: D]\n         *        ├── [C: 100%]\n         *        └── [D: 100%]\n         */\n        it('plans non-divisible sequentials plans with parallel children', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(100));\n            const instructionD = instruction('D', txPercent(100));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        parallelInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        parallelInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                nonDivisibleSequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    parallelTransactionPlan([\n                        singleTransactionPlan([instructionC]),\n                        singleTransactionPlan([instructionD]),\n                    ]),\n                ]),\n            );\n        });\n\n        /**\n         *  [NonDivSeq] ─────────────▶ [NonDivSeq]\n         *   │                          │\n         *   ├── [Seq]                  ├── [Tx: A + B]\n         *   │    ├── [A: 50%]          ├── [Tx: C]\n         *   │    └── [B: 50%]          └── [Tx: D]\n         *   └── [Seq]\n         *        ├── [C: 100%]\n         *        └── [D: 100%]\n         */\n        it('plans non-divisible sequentials plans with divisible sequential children', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(50));\n            const instructionB = instruction('B', txPercent(50));\n            const instructionC = instruction('C', txPercent(100));\n            const instructionD = instruction('D', txPercent(100));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionC),\n                            singleInstructionPlan(instructionD),\n                        ]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                nonDivisibleSequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    singleTransactionPlan([instructionC]),\n                    singleTransactionPlan([instructionD]),\n                ]),\n            );\n        });\n    });\n\n    describe('message packer scenarios', () => {\n        /**\n         *  [A(x, 250%)] ─────────────▶ [Seq]\n         *                               │\n         *                               ├── [Tx: A(1, 100%)]\n         *                               ├── [Tx: A(2, 100%)]\n         *                               └── [Tx: A(3, 50%)]\n         */\n        it('iterate over message packer instruction plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const messagePackerIx = createMessagePackerInstructionPlan(txPercent(250));\n\n            await expect(planner(messagePackerIx)).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([messagePackerIx.get(0, txPercent(100))]),\n                    singleTransactionPlan([messagePackerIx.get(txPercent(100), txPercent(100))]),\n                    singleTransactionPlan([messagePackerIx.get(txPercent(200), txPercent(50))]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ───────────────────▶ [Tx: A + B(1, 50%)]\n         *   │\n         *   ├── [A: 50%]\n         *   └── [B(x, 50%)]\n         */\n        it('combines single instruction plans with message packer instruction plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(50));\n            const messagePackerB = createMessagePackerInstructionPlan(txPercent(50));\n\n            await expect(\n                planner(sequentialInstructionPlan([singleInstructionPlan(instructionA), messagePackerB])),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, messagePackerB.get(0, txPercent(50))]));\n        });\n\n        /**\n         *  [Par] ────────────────────▶ [Par]\n         *   │                           │\n         *   └── [A(x, 250%)]            ├── [Tx: A(1, 100%)]\n         *                               ├── [Tx: A(2, 100%)]\n         *                               └── [Tx: A(3, 50%)]\n         */\n        it('can handle parallel message packer instruction plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const messagePackerA = createMessagePackerInstructionPlan(txPercent(250));\n\n            await expect(planner(parallelInstructionPlan([messagePackerA]))).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([messagePackerA.get(0, txPercent(100))]),\n                    singleTransactionPlan([messagePackerA.get(txPercent(100), txPercent(100))]),\n                    singleTransactionPlan([messagePackerA.get(txPercent(200), txPercent(50))]),\n                ]),\n            );\n        });\n\n        /**\n         *  [NonDivSeq] ──────────────▶ [NonDivSeq]\n         *   │                           │\n         *   └── [A(x, 250%)]            ├── [Tx: A(1, 100%)]\n         *                               ├── [Tx: A(2, 100%)]\n         *                               └── [Tx: A(3, 50%)]\n         */\n        it('can handle non-divisible sequential message packer instruction plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const messagePackerA = createMessagePackerInstructionPlan(txPercent(250));\n\n            await expect(planner(nonDivisibleSequentialInstructionPlan([messagePackerA]))).resolves.toEqual(\n                nonDivisibleSequentialTransactionPlan([\n                    singleTransactionPlan([messagePackerA.get(0, txPercent(100))]),\n                    singleTransactionPlan([messagePackerA.get(txPercent(100), txPercent(100))]),\n                    singleTransactionPlan([messagePackerA.get(txPercent(200), txPercent(50))]),\n                ]),\n            );\n        });\n\n        /**\n         *  [A(x, 100%)] ─────────────▶ [Tx: A(1, 100%)]\n         */\n        it('simplifies message packer instruction plans that fit in a single transaction', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const messagePackerA = createMessagePackerInstructionPlan(txPercent(100));\n\n            await expect(planner(messagePackerA)).resolves.toEqual(\n                singleTransactionPlan([messagePackerA.get(0, txPercent(100))]),\n            );\n        });\n\n        /**\n         *  [Par] ─────────────────────▶ [Par]\n         *   │                            │\n         *   ├── [A: 75%]                 ├── [Tx: A + C(1, 25%)]\n         *   ├── [B: 50%]                 ├── [Tx: B + C(2, 50%)]\n         *   └── [C(x, 125%)]             └── [Tx: C(3, 50%)]\n         */\n        it('uses message packer instruction plans to fill gaps in parallel candidates', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(75));\n            const instructionB = instruction('B', txPercent(50));\n            const messagePackerC = createMessagePackerInstructionPlan(txPercent(25) + txPercent(50) + txPercent(50)); // 125%\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        singleInstructionPlan(instructionB),\n                        messagePackerC,\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionA, messagePackerC.get(0, txPercent(25))]),\n                    singleTransactionPlan([instructionB, messagePackerC.get(txPercent(25), txPercent(50))]),\n                    singleTransactionPlan([messagePackerC.get(txPercent(25) + txPercent(50), txPercent(50))]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Par] ─────────────────────▶ [Par]\n         *   │                            │\n         *   ├── [A(x, 125%)]             ├── [Tx: B + A(1, 25%)]\n         *   ├── [C: 50%]                 ├── [Tx: C + A(2, 50%)]\n         *   └── [B: 75%]                 └── [Tx: A(3, 50%)]\n         */\n        it('handles parallel message packer instruction plans last to fill gaps in previous parallel candidates', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const messagePackerA = createMessagePackerInstructionPlan(txPercent(25) + txPercent(50) + txPercent(50)); // 125%\n            const instructionB = instruction('B', txPercent(75));\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        messagePackerA,\n                        singleInstructionPlan(instructionB),\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionB, messagePackerA.get(0, txPercent(25))]),\n                    singleTransactionPlan([instructionC, messagePackerA.get(txPercent(25), txPercent(50))]),\n                    singleTransactionPlan([messagePackerA.get(txPercent(25) + txPercent(50), txPercent(50))]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ─────────────────────▶ [Seq]\n         *   │                            │\n         *   ├── [A: 75%]                 ├── [Tx: A + B(1, 25%)]\n         *   ├── [B(x, 75%)]              └── [Tx: B(2, 50%) + C]\n         *   └── [C: 50%]\n         */\n        it('uses message packer instruction plans to fill gaps in sequential candidates', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(75));\n            const messagePackerB = createMessagePackerInstructionPlan(txPercent(25) + txPercent(50)); // 75%\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        messagePackerB,\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, messagePackerB.get(0, txPercent(25))]),\n                    singleTransactionPlan([messagePackerB.get(txPercent(25), txPercent(50)), instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [NonDivSeq] ───────────────▶ [NonDivSeq]\n         *   │                            │\n         *   ├── [A: 75%]                 ├── [Tx: A + B(1, 25%)]\n         *   ├── [B(x, 75%)]              └── [Tx: B(2, 50%) + C]\n         *   └── [C: 50%]\n         */\n        it('uses message packer instruction plans to fill gaps in non-divisible sequential candidates', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(75));\n            const messagePackerB = createMessagePackerInstructionPlan(txPercent(25) + txPercent(50)); // 75%\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    nonDivisibleSequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        messagePackerB,\n                        singleInstructionPlan(instructionC),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                nonDivisibleSequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, messagePackerB.get(0, txPercent(25))]),\n                    singleTransactionPlan([messagePackerB.get(txPercent(25), txPercent(50)), instructionC]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ───────────────────────▶ [Seq]\n         *   │                              │\n         *   ├── [A: 75%]                   ├── [Tx: A + B(1, 25%)]\n         *   └── [Par]                      └── [Tx: C + B(2, 50%)]\n         *        ├── [B(x, 75%)]\n         *        └── [C: 50%]\n         */\n        it('uses parallel message packer instruction plans to fill gaps in sequential candidates', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(75));\n            const messagePackerB = createMessagePackerInstructionPlan(txPercent(25) + txPercent(50)); // 75%\n            const instructionC = instruction('C', txPercent(50));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        parallelInstructionPlan([messagePackerB, singleInstructionPlan(instructionC)]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([instructionA, messagePackerB.get(0, txPercent(25))]),\n                    singleTransactionPlan([instructionC, messagePackerB.get(txPercent(25), txPercent(50))]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Par] ─────────────────────────▶ [Tx: A + B(1, 50%) + C]\n         *   │\n         *   ├── [A: 25%]\n         *   └── [Seq]\n         *        ├── [B(x, 50%)]\n         *        └── [C: 25%]\n         */\n        it('uses the whole sequential message packer instruction plan when it fits in the parent parallel candidate', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(25));\n            const messagePackerB = createMessagePackerInstructionPlan(txPercent(50));\n            const instructionC = instruction('C', txPercent(25));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        sequentialInstructionPlan([messagePackerB, singleInstructionPlan(instructionC)]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                singleTransactionPlan([instructionA, messagePackerB.get(0, txPercent(50)), instructionC]),\n            );\n        });\n\n        /**\n         *  [Seq] ─────────────────────────▶ [Tx: A + B(1, 50%) + C]\n         *   │\n         *   ├── [A: 25%]\n         *   └── [NonDivSeq]\n         *        ├── [B(x, 50%)]\n         *        └── [C: 25%]\n         */\n        it('uses the whole non-divisible sequential message packer instruction plan when it fits in the parent sequential candidate', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(25));\n            const messagePackerB = createMessagePackerInstructionPlan(txPercent(50));\n            const instructionC = instruction('C', txPercent(25));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        nonDivisibleSequentialInstructionPlan([messagePackerB, singleInstructionPlan(instructionC)]),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                singleTransactionPlan([instructionA, messagePackerB.get(0, txPercent(50)), instructionC]),\n            );\n        });\n\n        /**\n         *  [Par] ─────────────────────────▶ [Tx: A + B + C]\n         *   │\n         *   ├── [A: 25%]\n         *   └── [NonDivSeq]\n         *        └── [MessagePackerWithMultipleIterations(B: 25%, C: 25%)]\n         *\n         * This tests a case where the entire message packer must be packed into a single transaction.\n         * It uses a message packer that has instructions that can fit, but require multiple iterations\n         * to be fully added.\n         */\n        it('accumulates all instructions when a message packer requires multiple iterations in fitEntirePlanInsideMessage', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(25));\n            const instructionB = instruction('B', txPercent(25));\n            const instructionC = instruction('C', txPercent(25));\n\n            const multiIterPacker = createSingleInstructionAtATimeMessagePackerInstructionPlan([\n                instructionB,\n                instructionC,\n            ]);\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        nonDivisibleSequentialInstructionPlan([multiIterPacker]),\n                    ]),\n                ),\n            ).resolves.toEqual(singleTransactionPlan([instructionA, instructionB, instructionC]));\n        });\n    });\n\n    describe('complex scenarios', () => {\n        /**\n         *  [Par] ───────────────────────────▶ [Par]\n         *   │                                 │\n         *   ├── [Seq]                         ├── [Tx: A + B]\n         *   │    ├── [A: 40%]                 └── [NonDivSeq]\n         *   │    └── [B: 40%]                      ├── [Tx: C + D + E + G]\n         *   ├── [NonDivSeq]                        └── [Tx: F]\n         *   │    ├── [Par]\n         *   │    │    ├── [C: 25%]\n         *   │    │    └── [D: 25%]\n         *   │    └── [Par]\n         *   │         ├── [E: 25%]\n         *   │         └── [F: 50%]\n         *   └── [G: 25%]\n         */\n        it('can plan complex scenarios (1)', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const instructionA = instruction('A', txPercent(40));\n            const instructionB = instruction('B', txPercent(40));\n            const instructionC = instruction('C', txPercent(25));\n            const instructionD = instruction('D', txPercent(25));\n            const instructionE = instruction('E', txPercent(25));\n            const instructionF = instruction('F', txPercent(50));\n            const instructionG = instruction('G', txPercent(25));\n\n            await expect(\n                planner(\n                    parallelInstructionPlan([\n                        sequentialInstructionPlan([\n                            singleInstructionPlan(instructionA),\n                            singleInstructionPlan(instructionB),\n                        ]),\n                        nonDivisibleSequentialInstructionPlan([\n                            parallelInstructionPlan([\n                                singleInstructionPlan(instructionC),\n                                singleInstructionPlan(instructionD),\n                            ]),\n                            parallelInstructionPlan([\n                                singleInstructionPlan(instructionE),\n                                singleInstructionPlan(instructionF),\n                            ]),\n                        ]),\n                        singleInstructionPlan(instructionG),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                parallelTransactionPlan([\n                    singleTransactionPlan([instructionA, instructionB]),\n                    nonDivisibleSequentialTransactionPlan([\n                        singleTransactionPlan([instructionC, instructionD, instructionE, instructionG]),\n                        singleTransactionPlan([instructionF]),\n                    ]),\n                ]),\n            );\n        });\n\n        /**\n         *  [Seq] ─────────────────────────────────▶ [Seq]\n         *   │                                        │\n         *   ├── [A: 20%]                             ├── [Tx: A + B + C + E(1, 40%)]\n         *   ├── [NonDivSeq]                          ├── [Par]\n         *   │    ├── [B: 20%]                        │    ├── [Tx: D + E(2, 50%)]\n         *   │    └── [C: 20%]                        │    ├── [Tx: E(3, 100%)]\n         *   ├── [Par]                                │    └── [Tx: E(4, 60%)]\n         *   │    ├── [D: 50%]                        └── [Tx: F + G]\n         *   │    └── [E(x, 250%)]\n         *   ├── [F: 50%]\n         *   └── [G: 50%]\n         */\n        it('can plan complex scenarios (2)', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, singleTransactionPlan, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n\n            const instructionA = instruction('A', txPercent(20));\n            const instructionB = instruction('B', txPercent(20));\n            const instructionC = instruction('C', txPercent(20));\n            const instructionD = instruction('D', txPercent(50));\n            const messagePackerE = createMessagePackerInstructionPlan(txPercent(250));\n            const instructionF = instruction('F', txPercent(50));\n            const instructionG = instruction('G', txPercent(50));\n\n            await expect(\n                planner(\n                    sequentialInstructionPlan([\n                        singleInstructionPlan(instructionA),\n                        nonDivisibleSequentialInstructionPlan([\n                            singleInstructionPlan(instructionB),\n                            singleInstructionPlan(instructionC),\n                        ]),\n                        parallelInstructionPlan([singleInstructionPlan(instructionD), messagePackerE]),\n                        singleInstructionPlan(instructionF),\n                        singleInstructionPlan(instructionG),\n                    ]),\n                ),\n            ).resolves.toEqual(\n                sequentialTransactionPlan([\n                    singleTransactionPlan([\n                        instructionA,\n                        instructionB,\n                        instructionC,\n                        messagePackerE.get(0, txPercent(40) - 3),\n                    ]),\n                    parallelTransactionPlan([\n                        singleTransactionPlan([instructionD, messagePackerE.get(txPercent(40) - 3, txPercent(50))]),\n                        singleTransactionPlan([messagePackerE.get(txPercent(40) - 3 + txPercent(50), txPercent(100))]),\n                        singleTransactionPlan([\n                            messagePackerE.get(txPercent(40) - 3 + txPercent(50) + txPercent(100), txPercent(60) + 3),\n                        ]),\n                    ]),\n                    singleTransactionPlan([instructionF, instructionG]),\n                ]),\n            );\n        });\n    });\n\n    describe('freezability', () => {\n        it('freezes single transaction plans', async () => {\n            expect.assertions(1);\n            const instruction = instructionFactory();\n            const planner = createTransactionPlanner({ createTransactionMessage: createMockTransactionMessage });\n            const plan = (await planner(singleInstructionPlan(instruction('A', 42)))) as SingleTransactionPlan;\n            expect(plan).toBeFrozenObject();\n        });\n\n        it('freezes messages inside single transaction plans', async () => {\n            expect.assertions(1);\n            const instruction = instructionFactory();\n            const planner = createTransactionPlanner({ createTransactionMessage: createMockTransactionMessage });\n            const plan = (await planner(singleInstructionPlan(instruction('A', 42)))) as SingleTransactionPlan;\n            expect(plan.message).toBeFrozenObject();\n        });\n\n        it('freezes sequential transaction plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const plan = (await planner(\n                sequentialInstructionPlan([instruction('A', txPercent(100)), instruction('B', txPercent(100))]),\n            )) as SequentialTransactionPlan;\n            expect(plan).toBeFrozenObject();\n        });\n\n        it('freezes the children of sequential transaction plans', async () => {\n            expect.assertions(2);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const plan = (await planner(\n                sequentialInstructionPlan([instruction('A', txPercent(100)), instruction('B', txPercent(100))]),\n            )) as SequentialTransactionPlan;\n            expect(plan.plans[0]).toBeFrozenObject();\n            expect(plan.plans[1]).toBeFrozenObject();\n        });\n\n        it('freezes non-divisible sequential transaction plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const plan = (await planner(\n                nonDivisibleSequentialInstructionPlan([\n                    instruction('A', txPercent(100)),\n                    instruction('B', txPercent(100)),\n                ]),\n            )) as SequentialTransactionPlan & { divisible: false };\n            expect(plan).toBeFrozenObject();\n        });\n\n        it('freezes the children of non-divisible sequential transaction plans', async () => {\n            expect.assertions(2);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const plan = (await planner(\n                nonDivisibleSequentialInstructionPlan([\n                    instruction('A', txPercent(100)),\n                    instruction('B', txPercent(100)),\n                ]),\n            )) as SequentialTransactionPlan & { divisible: false };\n            expect(plan.plans[0]).toBeFrozenObject();\n            expect(plan.plans[1]).toBeFrozenObject();\n        });\n\n        it('freezes parallel transaction plans', async () => {\n            expect.assertions(1);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const plan = (await planner(\n                parallelInstructionPlan([instruction('A', txPercent(100)), instruction('B', txPercent(100))]),\n            )) as ParallelTransactionPlan;\n            expect(plan).toBeFrozenObject();\n        });\n\n        it('freezes the children of parallel transaction plans', async () => {\n            expect.assertions(2);\n            const createTransactionMessage = createMockTransactionMessage;\n            const { instruction, txPercent } = getHelpers(createTransactionMessage);\n            const planner = createTransactionPlanner({ createTransactionMessage });\n            const plan = (await planner(\n                parallelInstructionPlan([instruction('A', txPercent(100)), instruction('B', txPercent(100))]),\n            )) as ParallelTransactionPlan;\n            expect(plan.plans[0]).toBeFrozenObject();\n            expect(plan.plans[1]).toBeFrozenObject();\n        });\n    });\n\n    describe('abort signals', () => {\n        function runAndAbortPlanner(planner: TransactionPlanner, plan?: InstructionPlan): Promise<TransactionPlan> {\n            const abortController = new AbortController();\n            const promise = planner(plan ?? singleInstructionPlan(instructionFactory()('A', 42)), {\n                abortSignal: abortController.signal,\n            });\n            abortController.abort();\n            return promise;\n        }\n\n        it('can abort the planner should `createTransactionMessage` never resolve', async () => {\n            expect.assertions(1);\n            const foreverCreateMessage = jest.fn().mockReturnValue(FOREVER_PROMISE);\n            const planner = createTransactionPlanner({ createTransactionMessage: foreverCreateMessage });\n\n            const promise = runAndAbortPlanner(planner);\n            await expect(promise).rejects.toThrow('aborted');\n        });\n\n        it('can abort the planner should `onTransactionMessageUpdated` never resolve', async () => {\n            expect.assertions(1);\n            const foreverOnMessageUpdated = jest.fn().mockReturnValue(FOREVER_PROMISE);\n            const planner = createTransactionPlanner({\n                createTransactionMessage: createMockTransactionMessage,\n                onTransactionMessageUpdated: foreverOnMessageUpdated,\n            });\n\n            const promise = runAndAbortPlanner(planner);\n            await expect(promise).rejects.toThrow('aborted');\n        });\n\n        it('does not continue execution after being aborted in `createTransactionMessage` function', async () => {\n            expect.assertions(1);\n            const foreverCreateMessage = jest.fn().mockReturnValue(FOREVER_PROMISE);\n            const onMessageUpdated = jest.fn();\n            const planner = createTransactionPlanner({\n                createTransactionMessage: foreverCreateMessage,\n                onTransactionMessageUpdated: onMessageUpdated,\n            });\n\n            await runAndAbortPlanner(planner).catch(() => {});\n            expect(onMessageUpdated).not.toHaveBeenCalled();\n        });\n\n        it('does not continue execution after being aborted in `onTransactionMessageUpdated` function', async () => {\n            expect.assertions(1);\n            const createMessage = jest.fn();\n            const foreverOnMessageUpdated = jest.fn().mockReturnValue(FOREVER_PROMISE);\n            const planner = createTransactionPlanner({\n                createTransactionMessage: createMessage,\n                onTransactionMessageUpdated: foreverOnMessageUpdated,\n            });\n\n            await runAndAbortPlanner(planner).catch(() => {});\n            expect(createMessage).toHaveBeenCalledTimes(1);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/instruction-plans/src/__typetests__/append-instruction-plan-typetest.ts",
    "content": "import { Instruction } from '@solana/instructions';\nimport {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithinSizeLimit,\n} from '@solana/transaction-messages';\n\nimport { appendTransactionMessageInstructionPlan, InstructionPlan } from '../index';\n\n// [DESCRIBE] appendTransactionMessageInstructionPlan\n{\n    // It returns the same TransactionMessage type\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { some: 1 };\n        const newMessage = appendTransactionMessageInstructionPlan(null as unknown as InstructionPlan, message);\n        newMessage satisfies TransactionMessage & TransactionMessageWithFeePayer & { some: 1 };\n    }\n\n    // It maintains the existing instruction types\n    {\n        type InstructionA = Instruction & { identifier: 'A' };\n\n        const message = null as unknown as {\n            feePayer: TransactionMessageWithFeePayer['feePayer'];\n            instructions: [InstructionA];\n            version: 0;\n        };\n        const newMessage = appendTransactionMessageInstructionPlan(null as unknown as InstructionPlan, message);\n        newMessage.instructions[0] satisfies InstructionA;\n    }\n\n    // It removes the size limit type safety.\n    {\n        const message = null as unknown as TransactionMessage &\n            TransactionMessageWithFeePayer &\n            TransactionMessageWithinSizeLimit;\n        const newMessage = appendTransactionMessageInstructionPlan(null as unknown as InstructionPlan, message);\n        // @ts-expect-error Potentially no longer within size limit.\n        newMessage satisfies TransactionMessageWithinSizeLimit;\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/__typetests__/instruction-plan-input-typetest.ts",
    "content": "import type { Instruction } from '@solana/instructions';\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport {\n    InstructionPlan,\n    parseInstructionOrTransactionPlanInput,\n    parseInstructionPlanInput,\n    parseTransactionPlanInput,\n    TransactionPlan,\n} from '../index';\n\nconst instructionPlanA = null as unknown as InstructionPlan & { id: 'A' };\nconst instructionPlanB = null as unknown as InstructionPlan & { id: 'B' };\nconst instructionA = null as unknown as Instruction & { id: 'A' };\nconst instructionB = null as unknown as Instruction & { id: 'B' };\n\nconst transactionPlanA = null as unknown as TransactionPlan & { id: 'A' };\nconst transactionPlanB = null as unknown as TransactionPlan & { id: 'B' };\nconst messageA = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { id: 'A' };\nconst messageB = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { id: 'B' };\n\n// [DESCRIBE] parseInstructionPlanInput\n{\n    // It parses a single Instruction.\n    {\n        const plan = parseInstructionPlanInput(instructionA);\n        plan satisfies InstructionPlan;\n    }\n\n    // It parses an InstructionPlan.\n    {\n        const plan = parseInstructionPlanInput(instructionPlanA);\n        plan satisfies InstructionPlan;\n    }\n\n    // It parses an array of Instructions.\n    {\n        const plan = parseInstructionPlanInput([instructionA, instructionB]);\n        plan satisfies InstructionPlan;\n    }\n\n    // It parses an array of InstructionPlans.\n    {\n        const plan = parseInstructionPlanInput([instructionPlanA, instructionPlanB]);\n        plan satisfies InstructionPlan;\n    }\n\n    // It parses an array of mixed Instructions and InstructionPlans.\n    {\n        const plan = parseInstructionPlanInput([instructionA, instructionPlanA, instructionB, instructionPlanB]);\n        plan satisfies InstructionPlan;\n    }\n\n    // It parses an empty array.\n    {\n        const plan = parseInstructionPlanInput([]);\n        plan satisfies InstructionPlan;\n    }\n}\n\n// [DESCRIBE] parseTransactionPlanInput\n{\n    // It parses a single TransactionMessage & TransactionMessageWithFeePayer.\n    {\n        const plan = parseTransactionPlanInput(messageA);\n        plan satisfies TransactionPlan;\n    }\n\n    // It requires a fee payer.\n    {\n        const messageWithoutFeePayer = null as unknown as TransactionMessage;\n        // @ts-expect-error Missing fee payer.\n        parseTransactionPlanInput(messageWithoutFeePayer);\n    }\n\n    // It parses an InstructionPlan.\n    {\n        const plan = parseTransactionPlanInput(transactionPlanA);\n        plan satisfies TransactionPlan;\n    }\n\n    // It parses an array of Instructions.\n    {\n        const plan = parseTransactionPlanInput([messageA, messageB]);\n        plan satisfies TransactionPlan;\n    }\n\n    // It parses an array of InstructionPlans.\n    {\n        const plan = parseTransactionPlanInput([transactionPlanA, transactionPlanB]);\n        plan satisfies TransactionPlan;\n    }\n\n    // It parses an array of mixed Instructions and InstructionPlans.\n    {\n        const plan = parseTransactionPlanInput([messageA, transactionPlanA, messageB, transactionPlanB]);\n        plan satisfies TransactionPlan;\n    }\n\n    // It parses an empty array.\n    {\n        const plan = parseTransactionPlanInput([]);\n        plan satisfies TransactionPlan;\n    }\n}\n\n// [DESCRIBE] parseInstructionOrTransactionPlanInput\n{\n    // It parses a single Instruction.\n    {\n        const plan = parseInstructionOrTransactionPlanInput(instructionA);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses a single TransactionMessage & TransactionMessageWithFeePayer.\n    {\n        const plan = parseInstructionOrTransactionPlanInput(messageA);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It requires a fee payer for transaction messages.\n    {\n        const messageWithoutFeePayer = null as unknown as TransactionMessage;\n        // @ts-expect-error Missing fee payer.\n        parseInstructionOrTransactionPlanInput(messageWithoutFeePayer);\n    }\n\n    // It parses an InstructionPlan.\n    {\n        const plan = parseInstructionOrTransactionPlanInput(instructionPlanA);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses a TransactionPlan.\n    {\n        const plan = parseInstructionOrTransactionPlanInput(transactionPlanA);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses an array of Instructions.\n    {\n        const plan = parseInstructionOrTransactionPlanInput([instructionA, instructionB]);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses an array of TransactionMessages.\n    {\n        const plan = parseInstructionOrTransactionPlanInput([messageA, messageB]);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses an array of InstructionPlans.\n    {\n        const plan = parseInstructionOrTransactionPlanInput([instructionPlanA, instructionPlanB]);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses an array of mixed Instructions and InstructionPlans.\n    {\n        const plan = parseInstructionOrTransactionPlanInput([\n            instructionA,\n            instructionPlanA,\n            instructionB,\n            instructionPlanB,\n        ]);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses an array of TransactionPlans.\n    {\n        const plan = parseInstructionOrTransactionPlanInput([transactionPlanA, transactionPlanB]);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses an array of mixed TransactionMessages and TransactionPlans.\n    {\n        const plan = parseInstructionOrTransactionPlanInput([messageA, transactionPlanA, messageB, transactionPlanB]);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It parses an empty array.\n    {\n        const plan = parseInstructionOrTransactionPlanInput([]);\n        plan satisfies InstructionPlan | TransactionPlan;\n    }\n\n    // It does not parse arrays mixing Instruction and TransactionMessage inputs.\n    {\n        // @ts-expect-error Mixed instruction and transaction inputs are not supported.\n        parseInstructionOrTransactionPlanInput([instructionA, messageA]);\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/__typetests__/instruction-plan-typetest.ts",
    "content": "import type { Instruction } from '@solana/instructions';\n\nimport {\n    assertIsMessagePackerInstructionPlan,\n    assertIsNonDivisibleSequentialInstructionPlan,\n    assertIsParallelInstructionPlan,\n    assertIsSequentialInstructionPlan,\n    assertIsSingleInstructionPlan,\n    flattenInstructionPlan,\n    getLinearMessagePackerInstructionPlan,\n    getMessagePackerInstructionPlanFromInstructions,\n    getReallocMessagePackerInstructionPlan,\n    InstructionPlan,\n    isInstructionPlan,\n    isMessagePackerInstructionPlan,\n    isNonDivisibleSequentialInstructionPlan,\n    isParallelInstructionPlan,\n    isSequentialInstructionPlan,\n    isSingleInstructionPlan,\n    MessagePackerInstructionPlan,\n    nonDivisibleSequentialInstructionPlan,\n    ParallelInstructionPlan,\n    parallelInstructionPlan,\n    SequentialInstructionPlan,\n    sequentialInstructionPlan,\n    SingleInstructionPlan,\n    singleInstructionPlan,\n} from '../index';\n\nconst instructionA = null as unknown as Instruction & { id: 'A' };\nconst instructionB = null as unknown as Instruction & { id: 'B' };\nconst instructionC = null as unknown as Instruction & { id: 'C' };\n\n// [DESCRIBE] parallelInstructionPlan\n{\n    // It satisfies ParallelInstructionPlan.\n    {\n        const plan = parallelInstructionPlan([instructionA, instructionB]);\n        plan satisfies ParallelInstructionPlan;\n    }\n\n    // It can nest other plans.\n    {\n        const plan = parallelInstructionPlan([instructionA, parallelInstructionPlan([instructionB, instructionC])]);\n        plan satisfies ParallelInstructionPlan;\n    }\n}\n\n// [DESCRIBE] sequentialInstructionPlan\n{\n    // It satisfies a divisible SequentialInstructionPlan.\n    {\n        const plan = sequentialInstructionPlan([instructionA, instructionB]);\n        plan satisfies SequentialInstructionPlan & { divisible: true };\n    }\n\n    // It can nest other plans.\n    {\n        const plan = sequentialInstructionPlan([instructionA, sequentialInstructionPlan([instructionB, instructionC])]);\n        plan satisfies SequentialInstructionPlan & { divisible: true };\n    }\n}\n\n// [DESCRIBE] nonDivisibleSequentialInstructionPlan\n{\n    // It satisfies a non-divisible SequentialInstructionPlan.\n    {\n        const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n        plan satisfies SequentialInstructionPlan & { divisible: false };\n    }\n\n    // It can nest other plans.\n    {\n        const plan = nonDivisibleSequentialInstructionPlan([\n            instructionA,\n            nonDivisibleSequentialInstructionPlan([instructionB, instructionC]),\n        ]);\n        plan satisfies SequentialInstructionPlan & { divisible: false };\n    }\n}\n\n// [DESCRIBE] singleInstructionPlan\n{\n    // It satisfies SequentialInstructionPlan.\n    {\n        const plan = singleInstructionPlan(instructionA);\n        plan satisfies SingleInstructionPlan;\n    }\n}\n\n// [DESCRIBE] getLinearMessagePackerInstructionPlan\n{\n    // It satisfies MessagePackerInstructionPlan.\n    {\n        const plan = getLinearMessagePackerInstructionPlan({\n            getInstruction: () => instructionA,\n            totalLength: 42,\n        });\n        plan satisfies MessagePackerInstructionPlan;\n    }\n}\n\n// [DESCRIBE] getMessagePackerInstructionPlanFromInstructions\n{\n    // It satisfies MessagePackerInstructionPlan.\n    {\n        const plan = getMessagePackerInstructionPlanFromInstructions([instructionA, instructionB, instructionC]);\n        plan satisfies MessagePackerInstructionPlan;\n    }\n}\n\n// [DESCRIBE] getReallocMessagePackerInstructionPlan\n{\n    // It satisfies MessagePackerInstructionPlan.\n    {\n        const plan = getReallocMessagePackerInstructionPlan({\n            getInstruction: () => instructionA,\n            totalSize: 42,\n        });\n        plan satisfies MessagePackerInstructionPlan;\n    }\n}\n\n// [DESCRIBE] flattenInstructionPlan\n{\n    // It extracts leaf plans from a simple plan.\n    {\n        const plan = singleInstructionPlan(instructionA);\n        const leafPlans = flattenInstructionPlan(plan);\n        leafPlans satisfies (MessagePackerInstructionPlan | SingleInstructionPlan)[];\n    }\n\n    // It extracts leaf plans from a nested plan.\n    {\n        const messagePackerPlan = getMessagePackerInstructionPlanFromInstructions([instructionA]);\n        const plan = parallelInstructionPlan([\n            sequentialInstructionPlan([instructionA, instructionB]),\n            nonDivisibleSequentialInstructionPlan([instructionC]),\n            messagePackerPlan,\n        ]);\n        const leafPlans = flattenInstructionPlan(plan);\n        leafPlans satisfies (MessagePackerInstructionPlan | SingleInstructionPlan)[];\n    }\n}\n\n// [DESCRIBE] isSingleInstructionPlan\n{\n    // It narrows SingleInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        if (isSingleInstructionPlan(plan)) {\n            plan satisfies SingleInstructionPlan;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSingleInstructionPlan\n{\n    // It narrows SingleInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        assertIsSingleInstructionPlan(plan);\n        plan satisfies SingleInstructionPlan;\n    }\n}\n\n// [DESCRIBE] isMessagePackerInstructionPlan\n{\n    // It narrows MessagePackerInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        if (isMessagePackerInstructionPlan(plan)) {\n            plan satisfies MessagePackerInstructionPlan;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsMessagePackerInstructionPlan\n{\n    // It narrows MessagePackerInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        assertIsMessagePackerInstructionPlan(plan);\n        plan satisfies MessagePackerInstructionPlan;\n    }\n}\n\n// [DESCRIBE] isSequentialInstructionPlan\n{\n    // It narrows SequentialInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        if (isSequentialInstructionPlan(plan)) {\n            plan satisfies SequentialInstructionPlan;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSequentialInstructionPlan\n{\n    // It narrows SequentialInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        assertIsSequentialInstructionPlan(plan);\n        plan satisfies SequentialInstructionPlan;\n    }\n}\n\n// [DESCRIBE] isNonDivisibleInstructionPlan\n{\n    // It narrows non-divisible SequentialInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        if (isNonDivisibleSequentialInstructionPlan(plan)) {\n            plan satisfies SequentialInstructionPlan & { divisible: false };\n        }\n    }\n}\n\n// [DESCRIBE] assertIsNonDivisibleSequentialInstructionPlan\n{\n    // It narrows non-divisible SequentialInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        assertIsNonDivisibleSequentialInstructionPlan(plan);\n        plan satisfies SequentialInstructionPlan & { divisible: false };\n    }\n}\n\n// [DESCRIBE] isParallelInstructionPlan\n{\n    // It narrows ParallelInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        if (isParallelInstructionPlan(plan)) {\n            plan satisfies ParallelInstructionPlan;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsParallelInstructionPlan\n{\n    // It narrows ParallelInstructionPlan.\n    {\n        const plan = null as unknown as InstructionPlan;\n        assertIsParallelInstructionPlan(plan);\n        plan satisfies ParallelInstructionPlan;\n    }\n}\n\n// [DESCRIBE] isInstructionPlan\n{\n    // It narrows to any InstructionPlan.\n    {\n        const plan = null as unknown;\n        if (isInstructionPlan(plan)) {\n            plan satisfies InstructionPlan;\n        }\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/__typetests__/transaction-plan-executor-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\n\nimport { Signature } from '@solana/keys';\nimport {\n    setTransactionMessageLifetimeUsingBlockhash,\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { compileTransaction, Transaction, TransactionWithBlockhashLifetime } from '@solana/transactions';\n\nimport {\n    CanceledSingleTransactionPlanResult,\n    createTransactionPlanExecutor,\n    FailedSingleTransactionPlanResult,\n    passthroughFailedTransactionPlanExecution,\n    SingleTransactionPlanResult,\n    SuccessfulSingleTransactionPlanResult,\n    type TransactionPlan,\n    type TransactionPlanExecutor,\n    type TransactionPlanResult,\n} from '../index';\n\n// [DESCRIBE] TransactionPlanExecutor\n{\n    // Its return type satisfies TransactionPlanResult.\n    {\n        const transactionPlan = null as unknown as TransactionPlan;\n        const executor = null as unknown as TransactionPlanExecutor;\n        const result = executor(transactionPlan);\n        result satisfies Promise<TransactionPlanResult>;\n    }\n\n    // Its return type keeps track of the executor context.\n    {\n        type CustomContext = { customData: string };\n        const transactionPlan = null as unknown as TransactionPlan;\n        const executor = null as unknown as TransactionPlanExecutor<CustomContext>;\n        const result = executor(transactionPlan);\n        result satisfies Promise<TransactionPlanResult<CustomContext>>;\n    }\n}\n\n// [DESCRIBE] createTransactionPlanExecutor\n{\n    // It can return a signature or a full transaction.\n    {\n        createTransactionPlanExecutor({\n            executeTransactionMessage: () => Promise.resolve({} as Signature),\n        });\n        createTransactionPlanExecutor({\n            executeTransactionMessage: () => Promise.resolve({} as Transaction),\n        });\n    }\n\n    // It always receives a transaction message with fee payer.\n    {\n        createTransactionPlanExecutor({\n            executeTransactionMessage: (_, message) => {\n                message satisfies TransactionMessage & TransactionMessageWithFeePayer;\n                return Promise.resolve({} as Transaction);\n            },\n        });\n    }\n\n    // It receives a base context by default.\n    {\n        createTransactionPlanExecutor({\n            executeTransactionMessage: context => {\n                context.message satisfies (TransactionMessage & TransactionMessageWithFeePayer) | undefined;\n                context.transaction satisfies Transaction | undefined;\n                context.signature satisfies Signature | undefined;\n                return Promise.resolve({} as Signature);\n            },\n        });\n    }\n\n    // It removes undefined after assignment in the context.\n    {\n        createTransactionPlanExecutor({\n            executeTransactionMessage: context => {\n                // @ts-expect-error Initially, the context transaction may be undefined.\n                context.transaction satisfies Transaction;\n                context.transaction satisfies Transaction | undefined;\n                const mySignedTransaction = {} as unknown as Transaction;\n                context.transaction = mySignedTransaction;\n                context.transaction satisfies Transaction;\n                return Promise.resolve(context.transaction);\n            },\n        });\n    }\n\n    // It can use a custom context which is then assigned to the created TransactionPlanExecutor.\n    {\n        const executor = createTransactionPlanExecutor({\n            executeTransactionMessage: (_: { custom: string }) => {\n                return Promise.resolve({} as Signature);\n            },\n        });\n        executor satisfies TransactionPlanExecutor<{ custom: string }>;\n    }\n\n    // It can use a custom context with the base context.\n    {\n        const executor = createTransactionPlanExecutor<{ custom: string }>({\n            executeTransactionMessage: context => {\n                context.custom satisfies string;\n                context.message satisfies (TransactionMessage & TransactionMessageWithFeePayer) | undefined;\n                context.transaction satisfies Transaction | undefined;\n                context.signature satisfies Signature | undefined;\n                return Promise.resolve({} as Signature);\n            },\n        });\n        executor satisfies TransactionPlanExecutor<{ custom: string }>;\n    }\n\n    // It transfers the lifetime to the compiled transaction.\n    {\n        createTransactionPlanExecutor({\n            executeTransactionMessage: (_, message) => {\n                const latestBlockhash = {} as unknown as Parameters<\n                    typeof setTransactionMessageLifetimeUsingBlockhash\n                >[0];\n                const messageWithBlockhash = setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, message);\n                messageWithBlockhash satisfies TransactionMessageWithBlockhashLifetime;\n                const transaction = compileTransaction(messageWithBlockhash);\n                transaction satisfies TransactionWithBlockhashLifetime;\n                return Promise.resolve(transaction);\n            },\n        });\n    }\n}\n\n// [DESCRIBE] passthroughFailedTransactionPlanExecution\n{\n    // It returns a single result when the provided promise expects a single result.\n    {\n        const promise = null as unknown as Promise<SingleTransactionPlanResult>;\n        const result = passthroughFailedTransactionPlanExecution(promise);\n        void (result satisfies Promise<SingleTransactionPlanResult>);\n    }\n\n    // It widens the result of successful single results to include all possible single results.\n    {\n        const promise = null as unknown as Promise<SuccessfulSingleTransactionPlanResult>;\n        const result = passthroughFailedTransactionPlanExecution(promise);\n        void (result satisfies Promise<SingleTransactionPlanResult>);\n        // @ts-expect-error Can no longer expect successful result only.\n        void (result satisfies Promise<SuccessfulSingleTransactionPlanResult>);\n    }\n\n    // It widens the result of canceled single results to include all possible single results.\n    {\n        const promise = null as unknown as Promise<CanceledSingleTransactionPlanResult>;\n        const result = passthroughFailedTransactionPlanExecution(promise);\n        void (result satisfies Promise<SingleTransactionPlanResult>);\n        // @ts-expect-error Can no longer expect canceled result only.\n        void (result satisfies Promise<CanceledSingleTransactionPlanResult>);\n    }\n\n    // It widens the result of failed single results to include all possible single results.\n    {\n        const promise = null as unknown as Promise<FailedSingleTransactionPlanResult>;\n        const result = passthroughFailedTransactionPlanExecution(promise);\n        void (result satisfies Promise<SingleTransactionPlanResult>);\n        // @ts-expect-error Can no longer expect failed result only. It could be canceled too.\n        void (result satisfies Promise<FailedSingleTransactionPlanResult>);\n    }\n\n    // It returns any TransactionPlanResult otherwise.\n    {\n        const promise = null as unknown as Promise<TransactionPlanResult>;\n        const result = passthroughFailedTransactionPlanExecution(promise);\n        void (result satisfies Promise<TransactionPlanResult>);\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/__typetests__/transaction-plan-result-typetest.ts",
    "content": "import { Signature } from '@solana/keys';\nimport type { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\nimport type { Transaction } from '@solana/transactions';\n\nimport {\n    assertIsCanceledSingleTransactionPlanResult,\n    assertIsFailedSingleTransactionPlanResult,\n    assertIsNonDivisibleSequentialTransactionPlanResult,\n    assertIsParallelTransactionPlanResult,\n    assertIsSequentialTransactionPlanResult,\n    assertIsSingleTransactionPlanResult,\n    assertIsSuccessfulSingleTransactionPlanResult,\n    assertIsSuccessfulTransactionPlanResult,\n    CanceledSingleTransactionPlanResult,\n    canceledSingleTransactionPlanResult,\n    FailedSingleTransactionPlanResult,\n    failedSingleTransactionPlanResult,\n    flattenTransactionPlanResult,\n    isCanceledSingleTransactionPlanResult,\n    isFailedSingleTransactionPlanResult,\n    isNonDivisibleSequentialTransactionPlanResult,\n    isParallelTransactionPlanResult,\n    isSequentialTransactionPlanResult,\n    isSingleTransactionPlanResult,\n    isSuccessfulSingleTransactionPlanResult,\n    isSuccessfulTransactionPlanResult,\n    isTransactionPlanResult,\n    nonDivisibleSequentialTransactionPlanResult,\n    ParallelTransactionPlanResult,\n    parallelTransactionPlanResult,\n    SequentialTransactionPlanResult,\n    sequentialTransactionPlanResult,\n    SingleTransactionPlanResult,\n    SuccessfulSingleTransactionPlanResult,\n    successfulSingleTransactionPlanResult,\n    successfulSingleTransactionPlanResultFromTransaction,\n    SuccessfulTransactionPlanResult,\n    TransactionPlanResult,\n    TransactionPlanResultContext,\n} from '../index';\n\nconst messageA = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { id: 'A' };\nconst messageB = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { id: 'B' };\nconst messageC = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { id: 'C' };\nconst transactionA = null as unknown as Transaction & { id: 'A' };\nconst transactionB = null as unknown as Transaction & { id: 'B' };\nconst error = null as unknown as Error;\n\ntype CustomContext = { customData: string };\n\n// [DESCRIBE] parallelTransactionPlanResult\n{\n    // It satisfies ParallelTransactionPlanResult.\n    {\n        const result = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n            successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n        ]);\n        result satisfies ParallelTransactionPlanResult;\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can work with custom context.\n    {\n        const result = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA, { customData: 'A' }),\n            successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB, { customData: 'B' }),\n        ]);\n        result satisfies ParallelTransactionPlanResult<CustomContext>;\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can nest other result plans.\n    {\n        const result = parallelTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n            parallelTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n                canceledSingleTransactionPlanResult(messageC),\n            ]),\n        ]);\n        result satisfies ParallelTransactionPlanResult;\n        result satisfies TransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] sequentialTransactionPlanResult\n{\n    // It satisfies a divisible SequentialTransactionPlanResult.\n    {\n        const result = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n            successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n        ]);\n        result satisfies SequentialTransactionPlanResult & { divisible: true };\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can work with custom context.\n    {\n        const result = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA, { customData: 'A' }),\n            successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB, { customData: 'B' }),\n        ]);\n        result satisfies SequentialTransactionPlanResult<CustomContext> & { divisible: true };\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can nest other result plans.\n    {\n        const result = sequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n                canceledSingleTransactionPlanResult(messageC),\n            ]),\n        ]);\n        result satisfies SequentialTransactionPlanResult & { divisible: true };\n        result satisfies TransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] nonDivisibleSequentialTransactionPlanResult\n{\n    // It satisfies a non-divisible SequentialTransactionPlanResult.\n    {\n        const result = nonDivisibleSequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n            successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n        ]);\n        result satisfies SequentialTransactionPlanResult & { divisible: false };\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can work with custom context.\n    {\n        const result = nonDivisibleSequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA, { customData: 'A' }),\n            successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB, { customData: 'B' }),\n        ]);\n        result satisfies SequentialTransactionPlanResult<CustomContext> & { divisible: false };\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can nest other result plans.\n    {\n        const result = nonDivisibleSequentialTransactionPlanResult([\n            successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n            nonDivisibleSequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n                canceledSingleTransactionPlanResult(messageC),\n            ]),\n        ]);\n        result satisfies SequentialTransactionPlanResult & { divisible: false };\n        result satisfies TransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] successfulSingleTransactionPlanResultFromTransaction\n{\n    // It satisfies SingleTransactionPlanResult with a successful status.\n    {\n        const result = successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA);\n        result satisfies SuccessfulSingleTransactionPlanResult<TransactionPlanResultContext, typeof messageA>;\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can include a custom context.\n    {\n        const result = successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA, {\n            customData: 'test',\n        });\n        result satisfies SuccessfulSingleTransactionPlanResult<CustomContext, typeof messageA>;\n        result satisfies TransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] successfulSingleTransactionPlanResult\n{\n    // It satisfies SingleTransactionPlanResult with a successful status.\n    {\n        const result = successfulSingleTransactionPlanResult(messageA, { signature: 'A' as Signature });\n        result satisfies SuccessfulSingleTransactionPlanResult<TransactionPlanResultContext, typeof messageA>;\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can include a custom context.\n    {\n        const result = successfulSingleTransactionPlanResult(messageA, {\n            customData: 'test',\n            signature: 'A' as Signature,\n        });\n        result satisfies SuccessfulSingleTransactionPlanResult<CustomContext, typeof messageA>;\n        result satisfies TransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] failedSingleTransactionPlanResult\n{\n    // It satisfies SingleTransactionPlanResult with a failed status.\n    {\n        const result = failedSingleTransactionPlanResult(messageA, error);\n        result satisfies FailedSingleTransactionPlanResult<TransactionPlanResultContext, typeof messageA>;\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can include a custom context.\n    {\n        const result = failedSingleTransactionPlanResult(messageA, error, { customData: 'test' });\n        result satisfies FailedSingleTransactionPlanResult<CustomContext, typeof messageA>;\n        result satisfies TransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] canceledSingleTransactionPlanResult\n{\n    // It satisfies SingleTransactionPlanResult with a canceled status.\n    {\n        const result = canceledSingleTransactionPlanResult(messageA);\n        result satisfies CanceledSingleTransactionPlanResult<TransactionPlanResultContext, typeof messageA>;\n        result satisfies TransactionPlanResult;\n    }\n\n    // It can include a custom context.\n    {\n        const result = canceledSingleTransactionPlanResult(messageA, { customData: 'test' });\n        result satisfies CanceledSingleTransactionPlanResult<CustomContext, typeof messageA>;\n        result satisfies TransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] flattenTransactionPlanResult\n{\n    // It extracts single plan results from a simple plan result.\n    {\n        const result = successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA);\n        const results = flattenTransactionPlanResult(result);\n        results satisfies SingleTransactionPlanResult[];\n    }\n\n    // It extracts single plan results from a nested plan result.\n    {\n        const result = parallelTransactionPlanResult([\n            sequentialTransactionPlanResult([\n                successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n                successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n            ]),\n        ]);\n        const results = flattenTransactionPlanResult(result);\n        results satisfies SingleTransactionPlanResult[];\n    }\n}\n\n// [DESCRIBE] isSingleTransactionPlanResult\n{\n    // It narrows SingleTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        if (isSingleTransactionPlanResult(plan)) {\n            plan satisfies SingleTransactionPlanResult;\n        }\n    }\n\n    // It keeps TSingle information.\n    {\n        const plan = null as unknown as SuccessfulTransactionPlanResult;\n        if (isSingleTransactionPlanResult(plan)) {\n            plan satisfies SingleTransactionPlanResult;\n            plan satisfies SuccessfulSingleTransactionPlanResult;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSingleTransactionPlanResult\n{\n    // It narrows SingleTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        assertIsSingleTransactionPlanResult(plan);\n        plan satisfies SingleTransactionPlanResult;\n    }\n\n    // It keeps TSingle information.\n    {\n        const plan = null as unknown as SuccessfulTransactionPlanResult;\n        assertIsSingleTransactionPlanResult(plan);\n        plan satisfies SingleTransactionPlanResult;\n        plan satisfies SuccessfulSingleTransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] isSuccessfulSingleTransactionPlanResult\n{\n    // It narrows SuccessfulSingleTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        if (isSuccessfulSingleTransactionPlanResult(plan)) {\n            plan satisfies SuccessfulSingleTransactionPlanResult;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSuccessfulSingleTransactionPlanResult\n{\n    // It narrows SuccessfulSingleTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        assertIsSuccessfulSingleTransactionPlanResult(plan);\n        plan satisfies SuccessfulSingleTransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] isFailedSingleTransactionPlanResult\n{\n    // It narrows FailedSingleTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        if (isFailedSingleTransactionPlanResult(plan)) {\n            plan satisfies FailedSingleTransactionPlanResult;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsFailedSingleTransactionPlanResult\n{\n    // It narrows FailedSingleTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        assertIsFailedSingleTransactionPlanResult(plan);\n        plan satisfies FailedSingleTransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] isCanceledSingleTransactionPlanResult\n{\n    // It narrows CanceledSingleTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        if (isCanceledSingleTransactionPlanResult(plan)) {\n            plan satisfies CanceledSingleTransactionPlanResult;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsCanceledSingleTransactionPlanResult\n{\n    // It narrows CanceledSingleTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        assertIsCanceledSingleTransactionPlanResult(plan);\n        plan satisfies CanceledSingleTransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] isSequentialTransactionPlanResult\n{\n    // It narrows SequentialTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        if (isSequentialTransactionPlanResult(plan)) {\n            plan satisfies SequentialTransactionPlanResult;\n        }\n    }\n\n    // It keeps TSingle information.\n    {\n        const plan = null as unknown as SuccessfulTransactionPlanResult;\n        if (isSequentialTransactionPlanResult(plan)) {\n            plan satisfies SequentialTransactionPlanResult;\n            plan satisfies SequentialTransactionPlanResult<\n                TransactionPlanResultContext,\n                TransactionMessage & TransactionMessageWithFeePayer,\n                SuccessfulSingleTransactionPlanResult\n            >;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSequentialTransactionPlanResult\n{\n    // It narrows SequentialTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        assertIsSequentialTransactionPlanResult(plan);\n        plan satisfies SequentialTransactionPlanResult;\n    }\n\n    // It keeps TSingle information.\n    {\n        const plan = null as unknown as SuccessfulTransactionPlanResult;\n        assertIsSequentialTransactionPlanResult(plan);\n        plan satisfies SequentialTransactionPlanResult;\n        plan satisfies SequentialTransactionPlanResult<\n            TransactionPlanResultContext,\n            TransactionMessage & TransactionMessageWithFeePayer,\n            SuccessfulSingleTransactionPlanResult\n        >;\n    }\n}\n\n// [DESCRIBE] isNonDivisibleTransactionPlanResult\n{\n    // It narrows non-divisible SequentialTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        if (isNonDivisibleSequentialTransactionPlanResult(plan)) {\n            plan satisfies SequentialTransactionPlanResult & { divisible: false };\n        }\n    }\n\n    // It keeps TSingle information.\n    {\n        const plan = null as unknown as SuccessfulTransactionPlanResult;\n        if (isNonDivisibleSequentialTransactionPlanResult(plan)) {\n            plan satisfies SequentialTransactionPlanResult & { divisible: false };\n            plan satisfies SequentialTransactionPlanResult<\n                TransactionPlanResultContext,\n                TransactionMessage & TransactionMessageWithFeePayer,\n                SuccessfulSingleTransactionPlanResult\n            > & { divisible: false };\n        }\n    }\n}\n\n// [DESCRIBE] assertIsNonDivisibleSequentialTransactionPlanResult\n{\n    // It narrows non-divisible SequentialTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        assertIsNonDivisibleSequentialTransactionPlanResult(plan);\n        plan satisfies SequentialTransactionPlanResult & { divisible: false };\n    }\n\n    // It keeps TSingle information.\n    {\n        const plan = null as unknown as SuccessfulTransactionPlanResult;\n        assertIsNonDivisibleSequentialTransactionPlanResult(plan);\n        plan satisfies SequentialTransactionPlanResult & { divisible: false };\n        plan satisfies SequentialTransactionPlanResult<\n            TransactionPlanResultContext,\n            TransactionMessage & TransactionMessageWithFeePayer,\n            SuccessfulSingleTransactionPlanResult\n        > & { divisible: false };\n    }\n}\n\n// [DESCRIBE] isParallelTransactionPlanResult\n{\n    // It narrows ParallelTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        if (isParallelTransactionPlanResult(plan)) {\n            plan satisfies ParallelTransactionPlanResult;\n        }\n    }\n\n    // It keeps TSingle information.\n    {\n        const plan = null as unknown as SuccessfulTransactionPlanResult;\n        if (isParallelTransactionPlanResult(plan)) {\n            plan satisfies ParallelTransactionPlanResult;\n            plan satisfies ParallelTransactionPlanResult<\n                TransactionPlanResultContext,\n                TransactionMessage & TransactionMessageWithFeePayer,\n                SuccessfulSingleTransactionPlanResult\n            >;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsParallelTransactionPlanResult\n{\n    // It narrows ParallelTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        assertIsParallelTransactionPlanResult(plan);\n        plan satisfies ParallelTransactionPlanResult;\n    }\n\n    // It keeps TSingle information.\n    {\n        const plan = null as unknown as SuccessfulTransactionPlanResult;\n        assertIsParallelTransactionPlanResult(plan);\n        plan satisfies ParallelTransactionPlanResult;\n        plan satisfies ParallelTransactionPlanResult<\n            TransactionPlanResultContext,\n            TransactionMessage & TransactionMessageWithFeePayer,\n            SuccessfulSingleTransactionPlanResult\n        >;\n    }\n}\n\n// [DESCRIBE] isSuccessfulTransactionPlanResult\n{\n    // It narrows SuccessfulTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        if (isSuccessfulTransactionPlanResult(plan)) {\n            plan satisfies SuccessfulTransactionPlanResult;\n        }\n    }\n    // It narrows a single plan to SuccessfulSingleTransactionPlanResult.\n    {\n        const plan = null as unknown as SingleTransactionPlanResult;\n        if (isSuccessfulTransactionPlanResult(plan)) {\n            plan satisfies SuccessfulSingleTransactionPlanResult;\n            plan satisfies SuccessfulTransactionPlanResult;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSuccessfulTransactionPlanResult\n{\n    // It narrows SuccessfulTransactionPlanResult.\n    {\n        const plan = null as unknown as TransactionPlanResult;\n        assertIsSuccessfulTransactionPlanResult(plan);\n        plan satisfies SuccessfulTransactionPlanResult;\n    }\n    // It narrows a single plan to SuccessfulSingleTransactionPlanResult.\n    {\n        const plan = null as unknown as SingleTransactionPlanResult;\n        assertIsSuccessfulTransactionPlanResult(plan);\n        plan satisfies SuccessfulSingleTransactionPlanResult;\n        plan satisfies SuccessfulTransactionPlanResult;\n    }\n}\n\n// [DESCRIBE] isTransactionPlanResult\n{\n    // It narrows to any TransactionPlanResult.\n    {\n        const plan = null as unknown;\n        if (isTransactionPlanResult(plan)) {\n            plan satisfies TransactionPlanResult;\n        }\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/__typetests__/transaction-plan-typetest.ts",
    "content": "import type { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport {\n    assertIsNonDivisibleSequentialTransactionPlan,\n    assertIsParallelTransactionPlan,\n    assertIsSequentialTransactionPlan,\n    assertIsSingleTransactionPlan,\n    flattenTransactionPlan,\n    isNonDivisibleSequentialTransactionPlan,\n    isParallelTransactionPlan,\n    isSequentialTransactionPlan,\n    isSingleTransactionPlan,\n    isTransactionPlan,\n    nonDivisibleSequentialTransactionPlan,\n    ParallelTransactionPlan,\n    parallelTransactionPlan,\n    SequentialTransactionPlan,\n    sequentialTransactionPlan,\n    SingleTransactionPlan,\n    singleTransactionPlan,\n    TransactionPlan,\n} from '../index';\n\nconst messageA = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { id: 'A' };\nconst messageB = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { id: 'B' };\nconst messageC = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { id: 'C' };\n\n// [DESCRIBE] parallelTransactionPlan\n{\n    // It satisfies ParallelTransactionPlan.\n    {\n        const plan = parallelTransactionPlan([messageA, messageB]);\n        plan satisfies ParallelTransactionPlan;\n    }\n\n    // It can nest other plans.\n    {\n        const plan = parallelTransactionPlan([messageA, parallelTransactionPlan([messageB, messageC])]);\n        plan satisfies ParallelTransactionPlan;\n    }\n}\n\n// [DESCRIBE] sequentialTransactionPlan\n{\n    // It satisfies a divisible SequentialTransactionPlan.\n    {\n        const plan = sequentialTransactionPlan([messageA, messageB]);\n        plan satisfies SequentialTransactionPlan & { divisible: true };\n    }\n\n    // It can nest other plans.\n    {\n        const plan = sequentialTransactionPlan([messageA, sequentialTransactionPlan([messageB, messageC])]);\n        plan satisfies SequentialTransactionPlan & { divisible: true };\n    }\n}\n\n// [DESCRIBE] nonDivisibleSequentialTransactionPlan\n{\n    // It satisfies a non-divisible SequentialTransactionPlan.\n    {\n        const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n        plan satisfies SequentialTransactionPlan & { divisible: false };\n    }\n\n    // It can nest other plans.\n    {\n        const plan = nonDivisibleSequentialTransactionPlan([\n            messageA,\n            nonDivisibleSequentialTransactionPlan([messageB, messageC]),\n        ]);\n        plan satisfies SequentialTransactionPlan & { divisible: false };\n    }\n}\n\n// [DESCRIBE] singleTransactionPlan\n{\n    // It satisfies SingleTransactionPlan.\n    {\n        const plan = singleTransactionPlan(messageA);\n        plan satisfies SingleTransactionPlan;\n    }\n}\n\n// [DESCRIBE] flattenTransactionPlan\n{\n    // It extracts single transaction plans from a simple plan.\n    {\n        const plan = singleTransactionPlan(messageA);\n        const singlePlans = flattenTransactionPlan(plan);\n        singlePlans satisfies SingleTransactionPlan[];\n    }\n\n    // It extracts single transaction plans from a nested plan.\n    {\n        const plan = parallelTransactionPlan([\n            sequentialTransactionPlan([messageA, messageB]),\n            nonDivisibleSequentialTransactionPlan([messageC]),\n        ]);\n        const singlePlans = flattenTransactionPlan(plan);\n        singlePlans satisfies SingleTransactionPlan[];\n    }\n}\n\n// [DESCRIBE] isSingleTransactionPlan\n{\n    // It narrows SingleTransactionPlan.\n    {\n        const plan = null as unknown as TransactionPlan;\n        if (isSingleTransactionPlan(plan)) {\n            plan satisfies SingleTransactionPlan;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSingleTransactionPlan\n{\n    // It narrows SingleTransactionPlan.\n    {\n        const plan = null as unknown as TransactionPlan;\n        assertIsSingleTransactionPlan(plan);\n        plan satisfies SingleTransactionPlan;\n    }\n}\n\n// [DESCRIBE] isSequentialTransactionPlan\n{\n    // It narrows SequentialTransactionPlan.\n    {\n        const plan = null as unknown as TransactionPlan;\n        if (isSequentialTransactionPlan(plan)) {\n            plan satisfies SequentialTransactionPlan;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSequentialTransactionPlan\n{\n    // It narrows SequentialTransactionPlan.\n    {\n        const plan = null as unknown as TransactionPlan;\n        assertIsSequentialTransactionPlan(plan);\n        plan satisfies SequentialTransactionPlan;\n    }\n}\n\n// [DESCRIBE] isNonDivisibleTransactionPlan\n{\n    // It narrows non-divisible SequentialTransactionPlan.\n    {\n        const plan = null as unknown as TransactionPlan;\n        if (isNonDivisibleSequentialTransactionPlan(plan)) {\n            plan satisfies SequentialTransactionPlan & { divisible: false };\n        }\n    }\n}\n\n// [DESCRIBE] assertIsNonDivisibleSequentialTransactionPlan\n{\n    // It narrows non-divisible SequentialTransactionPlan.\n    {\n        const plan = null as unknown as TransactionPlan;\n        assertIsNonDivisibleSequentialTransactionPlan(plan);\n        plan satisfies SequentialTransactionPlan & { divisible: false };\n    }\n}\n\n// [DESCRIBE] isParallelTransactionPlan\n{\n    // It narrows ParallelTransactionPlan.\n    {\n        const plan = null as unknown as TransactionPlan;\n        if (isParallelTransactionPlan(plan)) {\n            plan satisfies ParallelTransactionPlan;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsParallelTransactionPlan\n{\n    // It narrows ParallelTransactionPlan.\n    {\n        const plan = null as unknown as TransactionPlan;\n        assertIsParallelTransactionPlan(plan);\n        plan satisfies ParallelTransactionPlan;\n    }\n}\n\n// [DESCRIBE] isTransactionPlan\n{\n    // It narrows to any TransactionPlan.\n    {\n        const plan = null as unknown;\n        if (isTransactionPlan(plan)) {\n            plan satisfies TransactionPlan;\n        }\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/__typetests__/transaction-planner-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\n\nimport { Instruction } from '@solana/instructions';\nimport {\n    appendTransactionMessageInstruction,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\n\nimport {\n    createTransactionPlanner,\n    type InstructionPlan,\n    type TransactionPlan,\n    type TransactionPlanner,\n} from '../index';\n\n// [DESCRIBE] TransactionPlanner\n{\n    // Its return type satisfies TransactionPlan.\n    {\n        const instructionPlan = null as unknown as InstructionPlan;\n        const planner = null as unknown as TransactionPlanner;\n        const transactionPlan = planner(instructionPlan);\n        transactionPlan satisfies Promise<TransactionPlan>;\n    }\n}\n\n// [DESCRIBE] createTransactionPlanner\n{\n    // `onTransactionMessageUpdated` always receives a transaction message with fee payer.\n    {\n        createTransactionPlanner({\n            createTransactionMessage: {} as unknown as Parameters<\n                typeof createTransactionPlanner\n            >[0]['createTransactionMessage'],\n            onTransactionMessageUpdated: message => {\n                message satisfies TransactionMessage & TransactionMessageWithFeePayer;\n                return message;\n            },\n        });\n    }\n\n    // `onTransactionMessageUpdated` may return a different transaction message then the one received.\n    {\n        createTransactionPlanner({\n            createTransactionMessage: {} as unknown as Parameters<\n                typeof createTransactionPlanner\n            >[0]['createTransactionMessage'],\n            onTransactionMessageUpdated: message => {\n                return appendTransactionMessageInstruction({} as unknown as Instruction, message);\n            },\n        });\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/append-instruction-plan.ts",
    "content": "import { SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, SolanaError } from '@solana/errors';\nimport { type Instruction } from '@solana/instructions';\nimport {\n    appendTransactionMessageInstruction,\n    appendTransactionMessageInstructions,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\n\nimport { flattenInstructionPlan, InstructionPlan } from './instruction-plan';\n\n/**\n * A helper type to append instructions to a transaction message\n * without losing type information about the current instructions.\n */\n\ntype AppendTransactionMessageInstructions<TTransactionMessage extends TransactionMessage> = ReturnType<\n    typeof appendTransactionMessageInstructions<TTransactionMessage, Instruction[]>\n>;\n\n/**\n * Appends all instructions from an instruction plan to a transaction message.\n *\n * This function flattens the instruction plan into its leaf plans and sequentially\n * appends each instruction to the provided transaction message. It handles both\n * single instructions and message packer plans.\n *\n * Note that any {@link MessagePackerInstructionPlan} is assumed to only append\n * instructions. If it modifies other properties of the transaction message, the\n * type of the returned transaction message may not accurately reflect those changes.\n *\n * @typeParam TTransactionMessage - The type of transaction message being modified.\n *\n * @param transactionMessage - The transaction message to append instructions to.\n * @param instructionPlan - The instruction plan containing the instructions to append.\n * @returns The transaction message with all instructions from the plan appended.\n *\n * @example\n * Appending a simple instruction plan to a transaction message.\n * ```ts\n * import { appendTransactionMessageInstructionPlan } from '@solana/instruction-plans';\n * import { createTransactionMessage, setTransactionMessageFeePayer } from '@solana/transaction-messages';\n *\n * const message = setTransactionMessageFeePayer(feePayer, createTransactionMessage({ version: 0 }));\n * const plan = singleInstructionPlan(myInstruction);\n *\n * const messageWithInstructions = appendTransactionMessageInstructionPlan(message, plan);\n * ```\n *\n * @example\n * Appending a sequential instruction plan.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB, instructionC]);\n * const messageWithInstructions = appendTransactionMessageInstructionPlan(message, plan);\n * ```\n *\n * @see {@link InstructionPlan}\n * @see {@link flattenInstructionPlan}\n */\nexport function appendTransactionMessageInstructionPlan<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer,\n>(\n    instructionPlan: InstructionPlan,\n    transactionMessage: TTransactionMessage,\n): AppendTransactionMessageInstructions<TTransactionMessage> {\n    type Out = AppendTransactionMessageInstructions<TTransactionMessage>;\n\n    const leafInstructionPlans = flattenInstructionPlan(instructionPlan);\n\n    return leafInstructionPlans.reduce(\n        (messageSoFar, plan) => {\n            const kind = plan.kind;\n            if (kind === 'single') {\n                return appendTransactionMessageInstruction(plan.instruction, messageSoFar) as unknown as Out;\n            }\n            if (kind === 'messagePacker') {\n                const messagerPacker = plan.getMessagePacker();\n                let nextMessage: Out = messageSoFar;\n                while (!messagerPacker.done()) {\n                    nextMessage = messagerPacker.packMessageToCapacity(nextMessage) as Out;\n                }\n                return nextMessage;\n            }\n            throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, {\n                kind,\n            });\n        },\n        transactionMessage as unknown as Out,\n    );\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/index.ts",
    "content": "/**\n * Instruction plans describe operations that go beyond a\n * single instruction and may even span multiple transactions.\n *\n * They define a set of instructions that must be executed following a specific order.\n * For instance, imagine we wanted to create an instruction plan for a simple escrow\n * transfer between Alice and Bob. First, both would need to deposit their assets\n * into a vault. This could happen in any order. Then and only then, the vault can be\n * activated to switch the assets. Alice and Bob can now both withdraw each other’s assets\n * (again, in any order). Here’s how we could describe an instruction plan for such an operation.\n *\n * ```typescript\n * const instructionPlan = sequentialInstructionPlan([\n *     parallelInstructionPlan([\n *         depositFromAlice,\n *         depositFromBob,\n *     ]),\n *     activateVault,\n *     parallelInstructionPlan([\n *         withdrawToAlice,\n *         withdrawToBob,\n *     ]),\n * ]);\n * ```\n *\n * As you can see, instruction plans don’t concern themselves with:\n * - Adding structural instructions — e.g. compute budget limits and prices.\n * - Building transaction messages from these instructions.\n *   That is planning how many can fit into a single instruction, adding a fee payer, a lifetime, etc.\n * - Compiling, signing and sending transactions to the network.\n *\n * Instead, they solely focus on describing operations and delegate\n * all that to two components introduced in this package:\n * - **Transaction planner**: builds transaction messages from an\n *   instruction plan and returns an appropriate transaction plan.\n * - **Transaction plan executor**: compiles, signs and sends\n *   transaction plans and returns a detailed result of this operation.\n *\n * ```typescript\n * // Plan instructions into transactions.\n * const transactionPlan = await transactionPlanner(instructionPlan);\n *\n * // Execute transactions.\n * const transactionPlanResult = await transactionPlanExecutor(transactionPlan);\n * ```\n *\n * This separation of concerns not only improves the developer experience but also\n * allows program maintainers to offer helper functions that go beyond a single instruction,\n * while leaving their consumers to decide how they want these operations to materialise.\n *\n * @packageDocumentation\n */\nexport * from './append-instruction-plan';\nexport * from './instruction-plan';\nexport * from './instruction-plan-input';\nexport * from './transaction-plan';\nexport * from './transaction-plan-errors';\nexport * from './transaction-plan-executor';\nexport * from './transaction-plan-result';\nexport * from './transaction-planner';\n"
  },
  {
    "path": "packages/instruction-plans/src/instruction-plan-input.ts",
    "content": "import type { Instruction } from '@solana/instructions';\n\nimport {\n    type InstructionPlan,\n    isInstructionPlan,\n    sequentialInstructionPlan,\n    singleInstructionPlan,\n} from './instruction-plan';\nimport {\n    isTransactionPlan,\n    sequentialTransactionPlan,\n    SingleTransactionPlan,\n    singleTransactionPlan,\n    TransactionPlan,\n} from './transaction-plan';\n\n/**\n * A flexible input type that can be used to create an {@link InstructionPlan}.\n *\n * This type accepts:\n * - A single {@link Instruction}.\n * - An existing {@link InstructionPlan}.\n * - An array of instructions and/or instruction plans.\n *\n * Use the {@link parseInstructionPlanInput} function to convert this input\n * into a proper {@link InstructionPlan}.\n *\n * @example\n * Using a single instruction.\n * ```ts\n * const input: InstructionPlanInput = myInstruction;\n * ```\n *\n * @example\n * Use as argument type in a function that will parse it into an InstructionPlan.\n * ```ts\n * function myFunction(input: InstructionPlanInput) {\n *   const plan = parseInstructionPlanInput(input);\n *   // Use the plan...\n * }\n * ```\n *\n * @see {@link parseInstructionPlanInput}\n * @see {@link InstructionPlan}\n */\nexport type InstructionPlanInput = Instruction | InstructionPlan | readonly (Instruction | InstructionPlan)[];\n\n/**\n * Parses an {@link InstructionPlanInput} and returns an {@link InstructionPlan}.\n *\n * This function handles the following input types:\n * - A single {@link Instruction} is wrapped in a {@link SingleInstructionPlan}.\n * - An existing {@link InstructionPlan} is returned as-is.\n * - An array with a single element is unwrapped and parsed recursively.\n * - An array with multiple elements is wrapped in a divisible {@link SequentialInstructionPlan}.\n *\n * @param input - The input to parse into an instruction plan.\n * @return The parsed instruction plan.\n *\n * @example\n * Parsing a single instruction.\n * ```ts\n * const plan = parseInstructionPlanInput(myInstruction);\n * // Equivalent to: singleInstructionPlan(myInstruction)\n * ```\n *\n * @example\n * Parsing an array of instructions.\n * ```ts\n * const plan = parseInstructionPlanInput([instructionA, instructionB]);\n * // Equivalent to: sequentialInstructionPlan([instructionA, instructionB])\n * ```\n *\n * @example\n * Parsing a mixed array with nested plans.\n * ```ts\n * const plan = parseInstructionPlanInput([\n *   instructionA,\n *   parallelInstructionPlan([instructionB, instructionC]),\n * ]);\n * // Returns a sequential plan containing:\n * // - A single instruction plan for instructionA.\n * // - The parallel plan for instructionB and instructionC.\n * ```\n *\n * @example\n * Single-element arrays are unwrapped.\n * ```ts\n * const plan = parseInstructionPlanInput([myInstruction]);\n * // Equivalent to: singleInstructionPlan(myInstruction)\n * ```\n *\n * @see {@link InstructionPlanInput}\n * @see {@link InstructionPlan}\n */\nexport function parseInstructionPlanInput(input: InstructionPlanInput): InstructionPlan {\n    if (Array.isArray(input) && input.length === 1) {\n        return parseInstructionPlanInput(input[0]);\n    }\n    if (Array.isArray(input)) {\n        return sequentialInstructionPlan(input.map(parseInstructionPlanInput));\n    }\n    return isInstructionPlan(input) ? input : singleInstructionPlan(input as Instruction);\n}\n\n/**\n * A flexible input type that can be used to create a {@link TransactionPlan}.\n *\n * This type accepts:\n * - A single {@link TransactionMessage} with a fee payer.\n * - An existing {@link TransactionPlan}.\n * - An array of transaction messages and/or transaction plans.\n *\n * Use the {@link parseTransactionPlanInput} function to convert this input\n * into a proper {@link TransactionPlan}.\n *\n * @example\n * Using a single transaction message.\n * ```ts\n * const input: TransactionPlanInput = myTransactionMessage;\n * ```\n *\n * @example\n * Use as argument type in a function that will parse it into a TransactionPlan.\n * ```ts\n * function myFunction(input: TransactionPlanInput) {\n *   const plan = parseTransactionPlanInput(input);\n *   // Use the plan...\n * }\n * ```\n *\n * @see {@link parseTransactionPlanInput}\n * @see {@link TransactionPlan}\n */\nexport type TransactionPlanInput =\n    | SingleTransactionPlan['message']\n    | TransactionPlan\n    | readonly (SingleTransactionPlan['message'] | TransactionPlan)[];\n\n/**\n * Parses a {@link TransactionPlanInput} and returns a {@link TransactionPlan}.\n *\n * This function handles the following input types:\n * - A single {@link TransactionMessage} is wrapped in a {@link SingleTransactionPlan}.\n * - An existing {@link TransactionPlan} is returned as-is.\n * - An array with a single element is unwrapped and parsed recursively.\n * - An array with multiple elements is wrapped in a divisible {@link SequentialTransactionPlan}.\n *\n * @param input - The input to parse into a transaction plan.\n * @return The parsed transaction plan.\n *\n * @example\n * Parsing a single transaction message.\n * ```ts\n * const plan = parseTransactionPlanInput(myTransactionMessage);\n * // Equivalent to: singleTransactionPlan(myTransactionMessage)\n * ```\n *\n * @example\n * Parsing an array of transaction messages.\n * ```ts\n * const plan = parseTransactionPlanInput([messageA, messageB]);\n * // Equivalent to: sequentialTransactionPlan([messageA, messageB])\n * ```\n *\n * @example\n * Parsing a mixed array with nested plans.\n * ```ts\n * const plan = parseTransactionPlanInput([\n *   messageA,\n *   parallelTransactionPlan([messageB, messageC]),\n * ]);\n * // Returns a sequential plan containing:\n * // - A single transaction plan for messageA.\n * // - The parallel plan for messageB and messageC.\n * ```\n *\n * @example\n * Single-element arrays are unwrapped.\n * ```ts\n * const plan = parseTransactionPlanInput([myTransactionMessage]);\n * // Equivalent to: singleTransactionPlan(myTransactionMessage)\n * ```\n *\n * @see {@link TransactionPlanInput}\n * @see {@link TransactionPlan}\n */\nexport function parseTransactionPlanInput(input: TransactionPlanInput): TransactionPlan {\n    if (Array.isArray(input) && input.length === 1) {\n        return parseTransactionPlanInput(input[0]);\n    }\n    if (Array.isArray(input)) {\n        return sequentialTransactionPlan(input.map(item => parseTransactionPlanInput(item)));\n    }\n    return isTransactionPlan(input) ? input : singleTransactionPlan(input as SingleTransactionPlan['message']);\n}\n\n/**\n * Parses an {@link InstructionPlanInput} or {@link TransactionPlanInput} and\n * returns the appropriate plan type.\n *\n * This function automatically detects whether the input represents instructions\n * or transactions and delegates to the appropriate parser:\n * - If the input is a transaction message or transaction plan, it delegates\n *   to {@link parseTransactionPlanInput}.\n * - Otherwise, it delegates to {@link parseInstructionPlanInput}.\n *\n * @param input - The input to parse, which can be either an instruction-based\n *   or transaction-based input.\n * @returns The parsed plan, either an {@link InstructionPlan} or a {@link TransactionPlan}.\n *\n * @example\n * Parsing an instruction input.\n * ```ts\n * const plan = parseInstructionOrTransactionPlanInput(myInstruction);\n * // Returns an InstructionPlan\n * ```\n *\n * @example\n * Parsing a transaction message input.\n * ```ts\n * const plan = parseInstructionOrTransactionPlanInput(myTransactionMessage);\n * // Returns a TransactionPlan\n * ```\n *\n * @see {@link parseInstructionPlanInput}\n * @see {@link parseTransactionPlanInput}\n * @see {@link InstructionPlanInput}\n * @see {@link TransactionPlanInput}\n */\nexport function parseInstructionOrTransactionPlanInput(\n    input: InstructionPlanInput | TransactionPlanInput,\n): InstructionPlan | TransactionPlan {\n    if (Array.isArray(input) && input.length === 0) {\n        return parseTransactionPlanInput(input);\n    }\n    if (Array.isArray(input) && isTransactionPlanInput(input[0])) {\n        return parseTransactionPlanInput(input as TransactionPlanInput);\n    }\n    if (isTransactionPlanInput(input)) {\n        return parseTransactionPlanInput(input as TransactionPlanInput);\n    }\n    return parseInstructionPlanInput(input as InstructionPlanInput);\n}\n\nfunction isTransactionPlanInput(value: unknown): value is SingleTransactionPlan['message'] | TransactionPlan {\n    return isTransactionPlan(value) || isTransactionMessage(value);\n}\n\nfunction isTransactionMessage(value: unknown): value is SingleTransactionPlan['message'] {\n    return (\n        typeof value === 'object' &&\n        value !== null &&\n        'instructions' in value &&\n        Array.isArray(value.instructions) &&\n        'version' in value\n    );\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/instruction-plan.ts",
    "content": "import {\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE,\n    SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN,\n    SolanaError,\n} from '@solana/errors';\nimport { Instruction } from '@solana/instructions';\nimport {\n    appendTransactionMessageInstruction,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, getTransactionMessageSizeLimit } from '@solana/transactions';\n\n/**\n * A set of instructions with constraints on how they can be executed.\n *\n * This is structured as a recursive tree of plans in order to allow for\n * parallel execution, sequential execution and combinations of both.\n *\n * Namely the following plans are supported:\n * - {@link SingleInstructionPlan} - A plan that contains a single instruction.\n *   This is a simple instruction wrapper and the simplest leaf in this tree.\n * - {@link ParallelInstructionPlan} - A plan that contains other plans that\n *   can be executed in parallel.\n * - {@link SequentialInstructionPlan} - A plan that contains other plans that\n *   must be executed sequentially. It also defines whether the plan is divisible\n *   meaning that instructions inside it can be split into separate transactions.\n * - {@link MessagePackerInstructionPlan} - A plan that can dynamically pack\n *  instructions into transaction messages.\n *\n * Helpers are provided for each of these plans to make it easier to create them.\n *\n * @example\n * ```ts\n * const myInstructionPlan: InstructionPlan = parallelInstructionPlan([\n *    sequentialInstructionPlan([instructionA, instructionB]),\n *    instructionC,\n *    instructionD,\n * ]);\n * ```\n *\n * @see {@link SingleInstructionPlan}\n * @see {@link ParallelInstructionPlan}\n * @see {@link SequentialInstructionPlan}\n * @see {@link MessagePackerInstructionPlan}\n */\nexport type InstructionPlan =\n    | MessagePackerInstructionPlan\n    | ParallelInstructionPlan\n    | SequentialInstructionPlan\n    | SingleInstructionPlan;\n\n/**\n * A plan wrapping other plans that must be executed sequentially.\n *\n * It also defines whether nested plans are divisible — meaning that\n * the instructions inside them can be split into separate transactions.\n * When `divisible` is `false`, the instructions inside the plan should\n * all be executed atomically — either in a single transaction or in a\n * transaction bundle.\n *\n * You may use the {@link sequentialInstructionPlan} and {@link nonDivisibleSequentialInstructionPlan}\n * helpers to create objects of this type.\n *\n * @example Simple sequential plan with two instructions.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB]);\n * plan satisfies SequentialInstructionPlan;\n * ```\n *\n * @example Non-divisible sequential plan with two instructions.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n * plan satisfies SequentialInstructionPlan & { divisible: false };\n * ```\n *\n * @example Sequential plan with nested parallel plans.\n * Here, instructions A and B can be executed in parallel, but they must both be finalized\n * before instructions C and D can be sent — which can also be executed in parallel.\n * ```ts\n * const plan = sequentialInstructionPlan([\n *   parallelInstructionPlan([instructionA, instructionB]),\n *   parallelInstructionPlan([instructionC, instructionD]),\n * ]);\n * plan satisfies SequentialInstructionPlan & { divisible: false };\n * ```\n *\n * @see {@link sequentialInstructionPlan}\n * @see {@link nonDivisibleSequentialInstructionPlan}\n */\nexport type SequentialInstructionPlan = Readonly<{\n    divisible: boolean;\n    kind: 'sequential';\n    planType: 'instructionPlan';\n    plans: InstructionPlan[];\n}>;\n\n/**\n * A plan wrapping other plans that can be executed in parallel.\n *\n * This means direct children of this plan can be executed in separate\n * parallel transactions without consequence.\n * However, the children themselves can define additional constraints\n * for that specific branch of the tree — such as the {@link SequentialInstructionPlan}.\n *\n * You may use the {@link parallelInstructionPlan} helper to create objects of this type.\n *\n * @example Simple parallel plan with two instructions.\n * ```ts\n * const plan = parallelInstructionPlan([instructionA, instructionB]);\n * plan satisfies ParallelInstructionPlan;\n * ```\n *\n * @example Parallel plan with nested sequential plans.\n * Here, instructions A and B must be executed sequentially and so must instructions C and D,\n * but both pairs can be executed in parallel.\n * ```ts\n * const plan = parallelInstructionPlan([\n *   sequentialInstructionPlan([instructionA, instructionB]),\n *   sequentialInstructionPlan([instructionC, instructionD]),\n * ]);\n * plan satisfies ParallelInstructionPlan;\n * ```\n *\n * @see {@link parallelInstructionPlan}\n */\nexport type ParallelInstructionPlan = Readonly<{\n    kind: 'parallel';\n    planType: 'instructionPlan';\n    plans: InstructionPlan[];\n}>;\n\n/**\n * A plan that contains a single instruction.\n *\n * This is a simple instruction wrapper that transforms an instruction into a plan.\n *\n * You may use the {@link singleInstructionPlan} helper to create objects of this type.\n *\n * @example\n * ```ts\n * const plan = singleInstructionPlan(instructionA);\n * plan satisfies SingleInstructionPlan;\n * ```\n *\n * @see {@link singleInstructionPlan}\n */\nexport type SingleInstructionPlan<TInstruction extends Instruction = Instruction> = Readonly<{\n    instruction: TInstruction;\n    kind: 'single';\n    planType: 'instructionPlan';\n}>;\n\n/**\n * A plan that can dynamically pack instructions into transaction messages.\n *\n * This plan provides a {@link MessagePacker} via the `getMessagePacker`\n * method, which enables instructions to be dynamically packed into the\n * provided transaction message until there are no more instructions to pack.\n * The returned {@link MessagePacker} offers a `packMessageToCapacity(message)`\n * method that packs the provided message — when possible — and a `done()` method\n * that checks whether there are more instructions to pack.\n *\n * Several helper functions are provided to create objects of this type such as\n * {@link getLinearMessagePackerInstructionPlan} or {@link getMessagePackerInstructionPlanFromInstructions}.\n *\n * @example An message packer plan for a write instruction that uses as many bytes as possible.\n * ```ts\n * const plan = getLinearMessagePackerInstructionPlan({\n *   totalLength: dataToWrite.length,\n *   getInstruction: (offset, length) =>\n *     getWriteInstruction({\n *       offset,\n *       data: dataToWrite.slice(offset, offset + length),\n *     }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @example A message packer plan for multiple realloc instructions.\n * ```ts\n * const plan = getReallocMessagePackerInstructionPlan({\n *   totalSize: additionalDataSize,\n *   getInstruction: (size) => getExtendInstruction({ length: size }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @example Using a message packer plan.\n * ```ts\n * let plan: MessagePackerInstructionPlan;\n * const messagePacker = plan.getMessagePacker();\n *\n * while (!messagePacker.done()) {\n *   try {\n *     transactionMessage = messagePacker.packMessageToCapacity(transactionMessage);\n *   } catch (error) {\n *     // The current transaction message cannot be used to pack this plan.\n *     // We should create a new one and try again.\n *   }\n * }\n * ```\n *\n * @see {@link getLinearMessagePackerInstructionPlan}\n * @see {@link getMessagePackerInstructionPlanFromInstructions}\n * @see {@link getReallocMessagePackerInstructionPlan}\n */\nexport type MessagePackerInstructionPlan = Readonly<{\n    getMessagePacker: () => MessagePacker;\n    kind: 'messagePacker';\n    planType: 'instructionPlan';\n}>;\n\n/**\n * The message packer returned by the {@link MessagePackerInstructionPlan}.\n *\n * It offers a `packMessageToCapacity(transactionMessage)` method that packs as many instructions\n * as possible into the provided transaction message, while still being able to fit into the\n * transaction size limit. It returns the updated transaction message with the packed instructions\n * or throws an error if the current transaction message cannot accommodate this plan.\n *\n * The `done()` method checks whether there are more instructions to pack into\n * transaction messages.\n *\n * @example\n * ```ts\n * let plan: MessagePackerInstructionPlan;\n * const messagePacker = plan.getMessagePacker();\n *\n * while (!messagePacker.done()) {\n *   try {\n *     transactionMessage = messagePacker.packMessageToCapacity(transactionMessage);\n *   } catch (error) {\n *     // The current transaction message cannot be used to pack this plan.\n *     // We should create a new one and try again.\n *   }\n * }\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport type MessagePacker = Readonly<{\n    /** Checks whether the message packer has more instructions to pack into transaction messages. */\n    done: () => boolean;\n    /**\n     * Packs the provided transaction message with instructions or throws if not possible.\n     *\n     * @throws {@link SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN}\n     *   if the provided transaction message cannot be used to fill the next instructions.\n     * @throws {@link SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE}\n     *   if the message packer is already done and no more instructions can be packed.\n     */\n    packMessageToCapacity: (\n        transactionMessage: TransactionMessage & TransactionMessageWithFeePayer,\n    ) => TransactionMessage & TransactionMessageWithFeePayer;\n}>;\n\n/**\n * Creates a {@link ParallelInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = parallelInstructionPlan([\n *   singleInstructionPlan(instructionA),\n *   singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = parallelInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link ParallelInstructionPlan}\n */\nexport function parallelInstructionPlan(plans: (Instruction | InstructionPlan)[]): ParallelInstructionPlan {\n    return Object.freeze({\n        kind: 'parallel',\n        planType: 'instructionPlan',\n        plans: parseSingleInstructionPlans(plans),\n    });\n}\n\n/**\n * Creates a divisible {@link SequentialInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = sequentialInstructionPlan([\n *   singleInstructionPlan(instructionA),\n *   singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n */\nexport function sequentialInstructionPlan(\n    plans: (Instruction | InstructionPlan)[],\n): SequentialInstructionPlan & { divisible: true } {\n    return Object.freeze({\n        divisible: true,\n        kind: 'sequential',\n        planType: 'instructionPlan',\n        plans: parseSingleInstructionPlans(plans),\n    });\n}\n\n/**\n * Creates a non-divisible {@link SequentialInstructionPlan} from an array of nested plans.\n *\n * It can accept {@link Instruction} objects directly, which will be wrapped\n * in {@link SingleInstructionPlan | SingleInstructionPlans} automatically.\n *\n * @example Using explicit {@link SingleInstructionPlan | SingleInstructionPlans}.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([\n *   singleInstructionPlan(instructionA),\n *   singleInstructionPlan(instructionB),\n * ]);\n * ```\n *\n * @example Using {@link Instruction | Instructions} directly.\n * ```ts\n * const plan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n */\nexport function nonDivisibleSequentialInstructionPlan(\n    plans: (Instruction | InstructionPlan)[],\n): SequentialInstructionPlan & { divisible: false } {\n    return Object.freeze({\n        divisible: false,\n        kind: 'sequential',\n        planType: 'instructionPlan',\n        plans: parseSingleInstructionPlans(plans),\n    });\n}\n\n/**\n * Creates a {@link SingleInstructionPlan} from an {@link Instruction} object.\n *\n * @example\n * ```ts\n * const plan = singleInstructionPlan(instructionA);\n * ```\n *\n * @see {@link SingleInstructionPlan}\n */\nexport function singleInstructionPlan(instruction: Instruction): SingleInstructionPlan {\n    return Object.freeze({ instruction, kind: 'single', planType: 'instructionPlan' });\n}\n\nfunction parseSingleInstructionPlans(plans: (Instruction | InstructionPlan)[]): InstructionPlan[] {\n    return plans.map(plan => ('kind' in plan ? plan : singleInstructionPlan(plan)));\n}\n\n/**\n * Checks if the given value is an {@link InstructionPlan}.\n *\n * This type guard checks the `planType` property to determine if the value\n * is an instruction plan. This is useful when you have a value that could be\n * an {@link InstructionPlan}, {@link TransactionPlan}, or {@link TransactionPlanResult}\n * and need to narrow the type.\n *\n * @param value - The value to check.\n * @return `true` if the value is an instruction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * function processItem(item: InstructionPlan | TransactionPlan | TransactionPlanResult) {\n *   if (isInstructionPlan(item)) {\n *     // item is narrowed to InstructionPlan\n *     console.log(item.kind);\n *   }\n * }\n * ```\n *\n * @see {@link InstructionPlan}\n * @see {@link isTransactionPlan}\n * @see {@link isTransactionPlanResult}\n */\nexport function isInstructionPlan(value: unknown): value is InstructionPlan {\n    return (\n        typeof value === 'object' &&\n        value !== null &&\n        'planType' in value &&\n        typeof value.planType === 'string' &&\n        value.planType === 'instructionPlan'\n    );\n}\n\n/**\n * Checks if the given instruction plan is a {@link SingleInstructionPlan}.\n *\n * @param plan - The instruction plan to check.\n * @return `true` if the plan is a single instruction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = singleInstructionPlan(myInstruction);\n *\n * if (isSingleInstructionPlan(plan)) {\n *   console.log(plan.instruction); // TypeScript knows this is a SingleInstructionPlan.\n * }\n * ```\n *\n * @see {@link SingleInstructionPlan}\n * @see {@link assertIsSingleInstructionPlan}\n */\nexport function isSingleInstructionPlan(plan: InstructionPlan): plan is SingleInstructionPlan {\n    return plan.kind === 'single';\n}\n\n/**\n * Asserts that the given instruction plan is a {@link SingleInstructionPlan}.\n *\n * @param plan - The instruction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN` if the plan is not a single instruction plan.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = singleInstructionPlan(myInstruction);\n *\n * assertIsSingleInstructionPlan(plan);\n * console.log(plan.instruction); // TypeScript knows this is a SingleInstructionPlan.\n * ```\n *\n * @see {@link SingleInstructionPlan}\n * @see {@link isSingleInstructionPlan}\n */\nexport function assertIsSingleInstructionPlan(plan: InstructionPlan): asserts plan is SingleInstructionPlan {\n    if (!isSingleInstructionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN, {\n            actualKind: plan.kind,\n            expectedKind: 'single',\n            instructionPlan: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given instruction plan is a {@link MessagePackerInstructionPlan}.\n *\n * @param plan - The instruction plan to check.\n * @return `true` if the plan is a message packer instruction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = getLinearMessagePackerInstructionPlan({ /* ... *\\/ });\n *\n * if (isMessagePackerInstructionPlan(plan)) {\n *   const packer = plan.getMessagePacker(); // TypeScript knows this is a MessagePackerInstructionPlan.\n * }\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n * @see {@link assertIsMessagePackerInstructionPlan}\n */\nexport function isMessagePackerInstructionPlan(plan: InstructionPlan): plan is MessagePackerInstructionPlan {\n    return plan.kind === 'messagePacker';\n}\n\n/**\n * Asserts that the given instruction plan is a {@link MessagePackerInstructionPlan}.\n *\n * @param plan - The instruction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN` if the plan is not a message packer instruction plan.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = getLinearMessagePackerInstructionPlan({ /* ... *\\/ });\n *\n * assertIsMessagePackerInstructionPlan(plan);\n * const packer = plan.getMessagePacker(); // TypeScript knows this is a MessagePackerInstructionPlan.\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n * @see {@link isMessagePackerInstructionPlan}\n */\nexport function assertIsMessagePackerInstructionPlan(\n    plan: InstructionPlan,\n): asserts plan is MessagePackerInstructionPlan {\n    if (!isMessagePackerInstructionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN, {\n            actualKind: plan.kind,\n            expectedKind: 'messagePacker',\n            instructionPlan: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given instruction plan is a {@link SequentialInstructionPlan}.\n *\n * @param plan - The instruction plan to check.\n * @return `true` if the plan is a sequential instruction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = sequentialInstructionPlan([instructionA, instructionB]);\n *\n * if (isSequentialInstructionPlan(plan)) {\n *   console.log(plan.divisible); // TypeScript knows this is a SequentialInstructionPlan.\n * }\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n * @see {@link assertIsSequentialInstructionPlan}\n */\nexport function isSequentialInstructionPlan(plan: InstructionPlan): plan is SequentialInstructionPlan {\n    return plan.kind === 'sequential';\n}\n\n/**\n * Asserts that the given instruction plan is a {@link SequentialInstructionPlan}.\n *\n * @param plan - The instruction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN` if the plan is not a sequential instruction plan.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = sequentialInstructionPlan([instructionA, instructionB]);\n *\n * assertIsSequentialInstructionPlan(plan);\n * console.log(plan.divisible); // TypeScript knows this is a SequentialInstructionPlan.\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n * @see {@link isSequentialInstructionPlan}\n */\nexport function assertIsSequentialInstructionPlan(plan: InstructionPlan): asserts plan is SequentialInstructionPlan {\n    if (!isSequentialInstructionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN, {\n            actualKind: plan.kind,\n            expectedKind: 'sequential',\n            instructionPlan: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given instruction plan is a non-divisible {@link SequentialInstructionPlan}.\n *\n * A non-divisible sequential plan requires all its instructions to be executed\n * atomically — either in a single transaction or in a transaction bundle.\n *\n * @param plan - The instruction plan to check.\n * @return `true` if the plan is a non-divisible sequential instruction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n *\n * if (isNonDivisibleSequentialInstructionPlan(plan)) {\n *   // All instructions must be executed atomically.\n * }\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n * @see {@link assertIsNonDivisibleSequentialInstructionPlan}\n */\nexport function isNonDivisibleSequentialInstructionPlan(\n    plan: InstructionPlan,\n): plan is SequentialInstructionPlan & { divisible: false } {\n    return plan.kind === 'sequential' && plan.divisible === false;\n}\n\n/**\n * Asserts that the given instruction plan is a non-divisible {@link SequentialInstructionPlan}.\n *\n * A non-divisible sequential plan requires all its instructions to be executed\n * atomically — either in a single transaction or in a transaction bundle.\n *\n * @param plan - The instruction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN` if the plan is not a non-divisible sequential instruction plan.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = nonDivisibleSequentialInstructionPlan([instructionA, instructionB]);\n *\n * assertIsNonDivisibleSequentialInstructionPlan(plan);\n * // All instructions must be executed atomically.\n * ```\n *\n * @see {@link SequentialInstructionPlan}\n * @see {@link isNonDivisibleSequentialInstructionPlan}\n */\nexport function assertIsNonDivisibleSequentialInstructionPlan(\n    plan: InstructionPlan,\n): asserts plan is SequentialInstructionPlan & { divisible: false } {\n    if (!isNonDivisibleSequentialInstructionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN, {\n            actualKind: plan.kind === 'sequential' ? 'divisible sequential' : plan.kind,\n            expectedKind: 'non-divisible sequential',\n            instructionPlan: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given instruction plan is a {@link ParallelInstructionPlan}.\n *\n * @param plan - The instruction plan to check.\n * @return `true` if the plan is a parallel instruction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = parallelInstructionPlan([instructionA, instructionB]);\n *\n * if (isParallelInstructionPlan(plan)) {\n *   console.log(plan.plans.length); // TypeScript knows this is a ParallelInstructionPlan.\n * }\n * ```\n *\n * @see {@link ParallelInstructionPlan}\n * @see {@link assertIsParallelInstructionPlan}\n */\nexport function isParallelInstructionPlan(plan: InstructionPlan): plan is ParallelInstructionPlan {\n    return plan.kind === 'parallel';\n}\n\n/**\n * Asserts that the given instruction plan is a {@link ParallelInstructionPlan}.\n *\n * @param plan - The instruction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN` if the plan is not a parallel instruction plan.\n *\n * @example\n * ```ts\n * const plan: InstructionPlan = parallelInstructionPlan([instructionA, instructionB]);\n *\n * assertIsParallelInstructionPlan(plan);\n * console.log(plan.plans.length); // TypeScript knows this is a ParallelInstructionPlan.\n * ```\n *\n * @see {@link ParallelInstructionPlan}\n * @see {@link isParallelInstructionPlan}\n */\nexport function assertIsParallelInstructionPlan(plan: InstructionPlan): asserts plan is ParallelInstructionPlan {\n    if (!isParallelInstructionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_INSTRUCTION_PLAN, {\n            actualKind: plan.kind,\n            expectedKind: 'parallel',\n            instructionPlan: plan,\n        });\n    }\n}\n\n/**\n * Finds the first instruction plan in the tree that matches the given predicate.\n *\n * This function performs a depth-first search through the instruction plan tree,\n * returning the first plan that satisfies the predicate. It checks the root plan\n * first, then recursively searches through nested plans.\n *\n * @param instructionPlan - The instruction plan tree to search.\n * @param predicate - A function that returns `true` for the plan to find.\n * @returns The first matching instruction plan, or `undefined` if no match is found.\n *\n * @example\n * Finding a non-divisible sequential plan.\n * ```ts\n * const plan = parallelInstructionPlan([\n *   sequentialInstructionPlan([instructionA, instructionB]),\n *   nonDivisibleSequentialInstructionPlan([instructionC, instructionD]),\n * ]);\n *\n * const nonDivisible = findInstructionPlan(\n *   plan,\n *   (p) => p.kind === 'sequential' && !p.divisible,\n * );\n * // Returns the non-divisible sequential plan containing instructionC and instructionD.\n * ```\n *\n * @example\n * Finding a specific single instruction plan.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB, instructionC]);\n *\n * const found = findInstructionPlan(\n *   plan,\n *   (p) => p.kind === 'single' && p.instruction === instructionB,\n * );\n * // Returns the SingleInstructionPlan wrapping instructionB.\n * ```\n *\n * @see {@link InstructionPlan}\n * @see {@link everyInstructionPlan}\n * @see {@link transformInstructionPlan}\n * @see {@link flattenInstructionPlan}\n */\nexport function findInstructionPlan(\n    instructionPlan: InstructionPlan,\n    predicate: (plan: InstructionPlan) => boolean,\n): InstructionPlan | undefined {\n    if (predicate(instructionPlan)) {\n        return instructionPlan;\n    }\n    if (instructionPlan.kind === 'single' || instructionPlan.kind === 'messagePacker') {\n        return undefined;\n    }\n    for (const subPlan of instructionPlan.plans) {\n        const foundPlan = findInstructionPlan(subPlan, predicate);\n        if (foundPlan) {\n            return foundPlan;\n        }\n    }\n    return undefined;\n}\n\n/**\n * Checks if every instruction plan in the tree satisfies the given predicate.\n *\n * This function performs a depth-first traversal through the instruction plan tree,\n * returning `true` only if the predicate returns `true` for every plan in the tree\n * (including the root plan and all nested plans).\n *\n * @param instructionPlan - The instruction plan tree to check.\n * @param predicate - A function that returns `true` if the plan satisfies the condition.\n * @return `true` if every plan in the tree satisfies the predicate, `false` otherwise.\n *\n * @example\n * Checking if all plans are divisible.\n * ```ts\n * const plan = sequentialInstructionPlan([\n *   parallelInstructionPlan([instructionA, instructionB]),\n *   sequentialInstructionPlan([instructionC, instructionD]),\n * ]);\n *\n * const allDivisible = everyInstructionPlan(\n *   plan,\n *   (p) => p.kind !== 'sequential' || p.divisible,\n * );\n * // Returns true because all sequential plans are divisible.\n * ```\n *\n * @example\n * Checking if all single instructions use a specific program.\n * ```ts\n * const plan = parallelInstructionPlan([instructionA, instructionB, instructionC]);\n *\n * const allUseSameProgram = everyInstructionPlan(\n *   plan,\n *   (p) => p.kind !== 'single' || p.instruction.programAddress === myProgramAddress,\n * );\n * ```\n *\n * @see {@link InstructionPlan}\n * @see {@link findInstructionPlan}\n * @see {@link transformInstructionPlan}\n * @see {@link flattenInstructionPlan}\n */\nexport function everyInstructionPlan(\n    instructionPlan: InstructionPlan,\n    predicate: (plan: InstructionPlan) => boolean,\n): boolean {\n    if (!predicate(instructionPlan)) {\n        return false;\n    }\n    if (instructionPlan.kind === 'single' || instructionPlan.kind === 'messagePacker') {\n        return true;\n    }\n    return instructionPlan.plans.every(p => everyInstructionPlan(p, predicate));\n}\n\n/**\n * Transforms an instruction plan tree using a bottom-up approach.\n *\n * This function recursively traverses the instruction plan tree, applying the\n * transformation function to each plan. The transformation is applied bottom-up,\n * meaning nested plans are transformed first, then the parent plans receive\n * the already-transformed children before being transformed themselves.\n *\n * All transformed plans are frozen using `Object.freeze` to ensure immutability.\n *\n * @param instructionPlan - The instruction plan tree to transform.\n * @param fn - A function that transforms each plan and returns a new plan.\n * @return A new transformed instruction plan tree.\n *\n * @example\n * Making all sequential plans non-divisible to ensure atomicity.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, instructionB]);\n *\n * const transformed = transformInstructionPlan(plan, (p) => {\n *   if (p.kind === 'sequential' && p.divisible) {\n *     return nonDivisibleSequentialInstructionPlan(p.plans);\n *   }\n *   return p;\n * });\n * ```\n *\n * @example\n * Filtering out debug instructions before production execution.\n * ```ts\n * const plan = sequentialInstructionPlan([instructionA, debugInstruction, instructionB]);\n *\n * const transformed = transformInstructionPlan(plan, (p) => {\n *   if (p.kind === 'sequential' || p.kind === 'parallel') {\n *     return { ...p, plans: p.plans.filter((p) => !isDebugInstruction(p)) };\n *   }\n *   return p;\n * });\n * ```\n *\n * @see {@link InstructionPlan}\n * @see {@link findInstructionPlan}\n * @see {@link everyInstructionPlan}\n * @see {@link flattenInstructionPlan}\n */\nexport function transformInstructionPlan(\n    instructionPlan: InstructionPlan,\n    fn: (plan: InstructionPlan) => InstructionPlan,\n): InstructionPlan {\n    if (instructionPlan.kind === 'single' || instructionPlan.kind === 'messagePacker') {\n        return Object.freeze(fn(instructionPlan));\n    }\n    return Object.freeze(\n        fn(\n            Object.freeze({\n                ...instructionPlan,\n                plans: instructionPlan.plans.map(p => transformInstructionPlan(p, fn)),\n            }),\n        ),\n    );\n}\n\n/**\n * Retrieves all individual {@link SingleInstructionPlan} and {@link MessagePackerInstructionPlan}\n * instances from an instruction plan tree.\n *\n * This function recursively traverses any nested structure of instruction plans and extracts\n * all the leaf plans they contain. It's useful when you need to access all the individual\n * instructions or message packers that will be executed, regardless of their organization\n * in the plan tree (parallel or sequential).\n *\n * @param instructionPlan - The instruction plan to extract leaf plans from\n * @returns An array of all single and message packer instruction plans contained in the tree\n *\n * @example\n * ```ts\n * const plan = parallelInstructionPlan([\n *   sequentialInstructionPlan([instructionA, instructionB]),\n *   nonDivisibleSequentialInstructionPlan([instructionC, instructionD]),\n *   instructionE,\n * ]);\n *\n * const leafPlans = flattenInstructionPlan(plan);\n * // Array of `SingleInstructionPlan` containing:\n * // instructionA, instructionB, instructionC, instructionD and instructionE.\n * ```\n *\n * @see {@link InstructionPlan}\n * @see {@link findInstructionPlan}\n * @see {@link everyInstructionPlan}\n * @see {@link transformInstructionPlan}\n */\nexport function flattenInstructionPlan(\n    instructionPlan: InstructionPlan,\n): (MessagePackerInstructionPlan | SingleInstructionPlan)[] {\n    if (instructionPlan.kind === 'single' || instructionPlan.kind === 'messagePacker') {\n        return [instructionPlan];\n    }\n    return instructionPlan.plans.flatMap(flattenInstructionPlan);\n}\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} that packs instructions\n * such that each instruction consumes as many bytes as possible from the given\n * `totalLength` while still being able to fit into the given transaction messages.\n *\n * This is particularly useful for instructions that write data to accounts and must\n * span multiple transactions due to their size limit.\n *\n * This message packer will first call `getInstruction` with a length of zero to\n * determine the base size of the instruction before figuring out how many\n * additional bytes can be packed into the transaction message. That remaining space\n * will then be used to call `getInstruction` again with the appropriate length.\n *\n * @param getInstruction - A function that returns an instruction for a given offset and length.\n * @param totalLength - The total length of the data to write, in bytes.\n *\n * @example\n * ```ts\n * const plan = getLinearMessagePackerInstructionPlan({\n *   totalLength: dataToWrite.length,\n *   getInstruction: (offset, length) =>\n *     getWriteInstruction({\n *       offset,\n *       data: dataToWrite.slice(offset, offset + length),\n *     }),\n * });\n * plan satisfies MessagePackerInstructionPlan;\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport function getLinearMessagePackerInstructionPlan({\n    getInstruction,\n    totalLength: totalBytes,\n}: {\n    getInstruction: (offset: number, length: number) => Instruction;\n    totalLength: number;\n}): MessagePackerInstructionPlan {\n    return Object.freeze({\n        getMessagePacker: () => {\n            let offset = 0;\n            return Object.freeze({\n                done: () => offset >= totalBytes,\n                packMessageToCapacity: (message: TransactionMessage & TransactionMessageWithFeePayer) => {\n                    if (offset >= totalBytes) {\n                        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE);\n                    }\n\n                    const messageSizeWithBaseInstruction = getTransactionMessageSize(\n                        appendTransactionMessageInstruction(getInstruction(offset, 0), message),\n                    );\n                    const freeSpace =\n                        getTransactionMessageSizeLimit(message) -\n                        messageSizeWithBaseInstruction /* Includes the base instruction (length: 0). */ -\n                        1; /* Leeway for shortU16 numbers in transaction headers. */\n\n                    if (freeSpace <= 0) {\n                        const messageSize = getTransactionMessageSize(message);\n                        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n                            // (+1) We need to pack at least one byte of data otherwise\n                            // there is no point packing the base instruction alone.\n                            numBytesRequired: messageSizeWithBaseInstruction - messageSize + 1,\n                            // (-1) Leeway for shortU16 numbers in transaction headers.\n                            numFreeBytes: getTransactionMessageSizeLimit(message) - messageSize - 1,\n                        });\n                    }\n\n                    const length = Math.min(totalBytes - offset, freeSpace);\n                    const instruction = getInstruction(offset, length);\n                    offset += length;\n                    return appendTransactionMessageInstruction(instruction, message);\n                },\n            });\n        },\n        kind: 'messagePacker',\n        planType: 'instructionPlan',\n    });\n}\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} from a list of instructions.\n *\n * This can be useful to prepare a set of instructions that can be iterated over\n * — e.g. to pack a list of instructions that gradually reallocate the size of an account\n * one `REALLOC_LIMIT` (10'240 bytes) at a time.\n *\n * @example\n * ```ts\n * const plan = getMessagePackerInstructionPlanFromInstructions([\n *   instructionA,\n *   instructionB,\n *   instructionC,\n * ]);\n *\n * const messagePacker = plan.getMessagePacker();\n * firstTransactionMessage = messagePacker.packMessageToCapacity(firstTransactionMessage);\n * // Contains instruction A and instruction B.\n * secondTransactionMessage = messagePacker.packMessageToCapacity(secondTransactionMessage);\n * // Contains instruction C.\n * messagePacker.done(); // true\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n * @see {@link getReallocMessagePackerInstructionPlan}\n */\nexport function getMessagePackerInstructionPlanFromInstructions<TInstruction extends Instruction = Instruction>(\n    instructions: TInstruction[],\n): MessagePackerInstructionPlan {\n    return Object.freeze({\n        getMessagePacker: () => {\n            let instructionIndex = 0;\n            return Object.freeze({\n                done: () => instructionIndex >= instructions.length,\n                packMessageToCapacity: (message: TransactionMessage & TransactionMessageWithFeePayer) => {\n                    if (instructionIndex >= instructions.length) {\n                        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_PACKER_ALREADY_COMPLETE);\n                    }\n\n                    const originalMessageSize = getTransactionMessageSize(message);\n\n                    for (let index = instructionIndex; index < instructions.length; index++) {\n                        message = appendTransactionMessageInstruction(instructions[index], message);\n                        const messageSize = getTransactionMessageSize(message);\n\n                        if (messageSize > getTransactionMessageSizeLimit(message)) {\n                            if (index === instructionIndex) {\n                                throw new SolanaError(\n                                    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n                                    {\n                                        numBytesRequired: messageSize - originalMessageSize,\n                                        numFreeBytes: getTransactionMessageSizeLimit(message) - originalMessageSize,\n                                    },\n                                );\n                            }\n                            instructionIndex = index;\n                            return message;\n                        }\n                    }\n\n                    instructionIndex = instructions.length;\n                    return message;\n                },\n            });\n        },\n        kind: 'messagePacker',\n        planType: 'instructionPlan',\n    });\n}\n\nconst REALLOC_LIMIT = 10_240;\n\n/**\n * Creates a {@link MessagePackerInstructionPlan} that packs a list of realloc instructions.\n *\n * That is, it splits instruction by chunks of `REALLOC_LIMIT` (10'240) bytes until\n * the given total size is reached.\n *\n * @example\n * ```ts\n * const plan = getReallocMessagePackerInstructionPlan({\n *   totalSize: additionalDataSize,\n *   getInstruction: (size) => getExtendInstruction({ length: size }),\n * });\n * ```\n *\n * @see {@link MessagePackerInstructionPlan}\n */\nexport function getReallocMessagePackerInstructionPlan({\n    getInstruction,\n    totalSize,\n}: {\n    getInstruction: (size: number) => Instruction;\n    totalSize: number;\n}): MessagePackerInstructionPlan {\n    const numberOfInstructions = Math.ceil(totalSize / REALLOC_LIMIT);\n    const lastInstructionSize = totalSize % REALLOC_LIMIT;\n    const instructions = new Array(numberOfInstructions)\n        .fill(0)\n        .map((_, i) => getInstruction(i === numberOfInstructions - 1 ? lastInstructionSize : REALLOC_LIMIT));\n\n    return getMessagePackerInstructionPlanFromInstructions(instructions);\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/transaction-plan-errors.ts",
    "content": "import {\n    isSolanaError,\n    type RpcSimulateTransactionResult,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION,\n    SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n    SolanaError,\n    type SolanaErrorCode,\n} from '@solana/errors';\n\nimport {\n    type CanceledSingleTransactionPlanResult,\n    type FailedSingleTransactionPlanResult,\n    flattenTransactionPlanResult,\n    type TransactionPlanResult,\n} from './transaction-plan-result';\n\ntype PreflightData = Omit<RpcSimulateTransactionResult, 'err'>;\n\n/**\n * Creates a {@link SolanaError} with the {@link SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION}\n * error code from a failed or canceled {@link SingleTransactionPlanResult}.\n *\n * This is a high-level error designed for user-facing transaction send failures.\n * It unwraps simulation errors (such as preflight failures) to expose the\n * underlying transaction error as the `cause`, and extracts preflight data\n * and logs into the error context for easy access.\n *\n * The error message includes an indicator showing whether the failure was a\n * preflight error or includes the on-chain transaction signature for easy\n * copy-pasting into block explorers.\n *\n * @param result - A failed or canceled single transaction plan result.\n * @param abortReason - An optional abort reason if the transaction was canceled.\n * @return A {@link SolanaError} with the appropriate error code, context, and cause.\n *\n * @example\n * Creating an error from a failed transaction plan result.\n * ```ts\n * import { createFailedToSendTransactionError } from '@solana/instruction-plans';\n *\n * const error = createFailedToSendTransactionError(failedResult);\n * console.log(error.message);\n * // \"Failed to send transaction (preflight): Insufficient funds for fee\"\n * console.log(error.cause);\n * // The unwrapped transaction error\n * console.log(error.context.logs);\n * // Transaction logs from the preflight simulation\n * ```\n *\n * @see {@link createFailedToSendTransactionsError}\n */\nexport function createFailedToSendTransactionError(\n    result: CanceledSingleTransactionPlanResult | FailedSingleTransactionPlanResult,\n    abortReason?: unknown,\n): SolanaError<typeof SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION> {\n    let causeMessage: string;\n    let cause: unknown;\n    let logs: readonly string[] | undefined;\n    let preflightData: PreflightData | undefined;\n\n    if (result.status === 'failed') {\n        const unwrapped = unwrapErrorWithPreflightData(result.error);\n        logs = unwrapped.logs;\n        preflightData = unwrapped.preflightData;\n        cause = unwrapped.unwrappedError;\n        const indicator = getFailedIndicator(!!preflightData, result.context.signature);\n        causeMessage = `${indicator}: ${(cause as Error).message}${formatLogSnippet(logs)}`;\n    } else {\n        cause = abortReason;\n        causeMessage = abortReason != null ? `. Canceled with abort reason: ${String(abortReason)}` : ': Canceled';\n    }\n\n    const context: Record<string, unknown> = {\n        cause,\n        causeMessage,\n        logs,\n        preflightData,\n    };\n    Object.defineProperty(context, 'transactionPlanResult', {\n        configurable: false,\n        enumerable: false,\n        value: result,\n        writable: false,\n    });\n    return new SolanaError(SOLANA_ERROR__FAILED_TO_SEND_TRANSACTION, context);\n}\n\n/**\n * Creates a {@link SolanaError} with the {@link SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS}\n * error code from a {@link TransactionPlanResult}.\n *\n * This is a high-level error designed for user-facing transaction send failures\n * involving multiple transactions. It walks the result tree, unwraps simulation\n * errors from each failure, and builds a `failedTransactions` array pairing each\n * failure with its unwrapped error, logs, and preflight data.\n *\n * The error message lists each failure with its position in the plan and an\n * indicator showing whether it was a preflight error or includes the transaction\n * signature. When all transactions were canceled, the message is a single line.\n *\n * @param result - The full transaction plan result tree.\n * @param abortReason - An optional abort reason if the plan was aborted.\n * @return A {@link SolanaError} with the appropriate error code, context, and cause.\n *\n * @example\n * Creating an error from a failed transaction plan result.\n * ```ts\n * import { createFailedToSendTransactionsError } from '@solana/instruction-plans';\n *\n * const error = createFailedToSendTransactionsError(planResult);\n * console.log(error.message);\n * // \"Failed to send transactions.\n * // [Tx #1 (preflight)] Insufficient funds for fee\n * // [Tx #3 (5abc...)] Custom program error: 0x1\"\n * console.log(error.context.failedTransactions);\n * // [{ index: 0, error: ..., logs: [...], preflightData: {...} }, ...]\n * ```\n *\n * @see {@link createFailedToSendTransactionError}\n */\nexport function createFailedToSendTransactionsError(\n    result: TransactionPlanResult,\n    abortReason?: unknown,\n): SolanaError<typeof SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS> {\n    const flattenedResults = flattenTransactionPlanResult(result);\n\n    const failedTransactions = flattenedResults.flatMap((singleResult, index) => {\n        if (singleResult.status !== 'failed') return [];\n        const unwrapped = unwrapErrorWithPreflightData(singleResult.error);\n        return [\n            {\n                error: unwrapped.unwrappedError as Error,\n                index,\n                logs: unwrapped.logs,\n                preflightData: unwrapped.preflightData,\n            },\n        ];\n    });\n\n    let causeMessages: string;\n    let cause: unknown;\n\n    if (failedTransactions.length > 0) {\n        cause = failedTransactions.length === 1 ? failedTransactions[0].error : undefined;\n        const failureLines = failedTransactions.map(({ error, index, preflightData }) => {\n            const indicator = getFailedIndicator(!!preflightData, flattenedResults[index].context.signature);\n            return `\\n[Tx #${index + 1}${indicator}] ${error.message}`;\n        });\n        const logSnippet = failedTransactions.length === 1 ? formatLogSnippet(failedTransactions[0].logs) : '';\n        causeMessages = `.${failureLines.join('')}${logSnippet}${logSnippet ? '' : '\\n'}`;\n    } else {\n        cause = abortReason;\n        causeMessages = abortReason != null ? `. Canceled with abort reason: ${String(abortReason)}` : ': Canceled';\n    }\n\n    const context: Record<string, unknown> = {\n        cause,\n        causeMessages,\n        failedTransactions,\n    };\n    Object.defineProperty(context, 'transactionPlanResult', {\n        configurable: false,\n        enumerable: false,\n        value: result,\n        writable: false,\n    });\n    return new SolanaError(SOLANA_ERROR__FAILED_TO_SEND_TRANSACTIONS, context);\n}\n\n/**\n * Creates a {@link SolanaError} with the\n * {@link SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN}\n * error code from a {@link TransactionPlanResult}.\n *\n * This is a low-level error intended for custom transaction plan executor\n * authors. It attaches the full `transactionPlanResult` as a non-enumerable\n * property so that callers can inspect execution details without the result\n * being serialized with the error.\n *\n * @param result - The full transaction plan result tree.\n * @param abortReason - An optional abort reason if the plan was aborted.\n * @return A {@link SolanaError} with the appropriate error code and context.\n *\n * @example\n * Throwing a failed-to-execute error from a custom executor.\n * ```ts\n * import { createFailedToExecuteTransactionPlanError } from '@solana/instruction-plans';\n *\n * throw createFailedToExecuteTransactionPlanError(transactionPlanResult, abortSignal?.reason);\n * ```\n *\n * @see {@link createFailedToSendTransactionError}\n * @see {@link createFailedToSendTransactionsError}\n */\nexport function createFailedToExecuteTransactionPlanError(\n    result: TransactionPlanResult,\n    abortReason?: unknown,\n): SolanaError<typeof SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN> {\n    const context: Record<string, unknown> = {\n        abortReason,\n        // Deprecated: will be removed in a future version.\n        cause: findErrorFromTransactionPlanResult(result) ?? abortReason,\n    };\n    Object.defineProperty(context, 'transactionPlanResult', {\n        configurable: false,\n        enumerable: false,\n        value: result,\n        writable: false,\n    });\n    return new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN, context);\n}\n\nfunction unwrapErrorWithPreflightData(error: Error): {\n    logs: readonly string[] | undefined;\n    preflightData: PreflightData | undefined;\n    unwrappedError: unknown;\n} {\n    const simulationCodes: SolanaErrorCode[] = [\n        SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n        SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n    ];\n    if (isSolanaError(error) && simulationCodes.includes(error.context.__code)) {\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        const { __code, ...preflightData } = error.context;\n        return {\n            logs: (preflightData as PreflightData).logs ?? undefined,\n            preflightData: preflightData as PreflightData,\n            unwrappedError: error.cause ?? error,\n        };\n    }\n    return { logs: undefined, preflightData: undefined, unwrappedError: error };\n}\n\nfunction findErrorFromTransactionPlanResult(result: TransactionPlanResult): Error | undefined {\n    if (result.kind === 'single') {\n        return result.status === 'failed' ? result.error : undefined;\n    }\n    for (const plan of result.plans) {\n        const error = findErrorFromTransactionPlanResult(plan);\n        if (error) {\n            return error;\n        }\n    }\n}\n\nfunction formatLogSnippet(logs: readonly string[] | undefined): string {\n    if (!logs || logs.length === 0) return '';\n    const maxLines = 8;\n    const lastLines = logs.slice(-maxLines);\n    const header = logs.length > maxLines ? `\\n\\nLogs (last ${maxLines} of ${logs.length}):` : '\\n\\nLogs:';\n    return `${header}\\n${lastLines.map(line => `  > ${line}\\n`).join('')}`;\n}\n\nfunction getFailedIndicator(isPreflight: boolean, signature: string | undefined): string {\n    if (isPreflight) return ' (preflight)';\n    if (signature) return ` (${signature})`;\n    return '';\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/transaction-plan-executor.ts",
    "content": "import {\n    isSolanaError,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED,\n    SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND,\n    SolanaError,\n} from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport { getAbortablePromise } from '@solana/promises';\nimport type { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\nimport { getSignatureFromTransaction, type Transaction } from '@solana/transactions';\n\nimport type {\n    ParallelTransactionPlan,\n    SequentialTransactionPlan,\n    SingleTransactionPlan,\n    TransactionPlan,\n} from './transaction-plan';\nimport { createFailedToExecuteTransactionPlanError } from './transaction-plan-errors';\nimport {\n    BaseTransactionPlanResultContext,\n    canceledSingleTransactionPlanResult,\n    failedSingleTransactionPlanResult,\n    parallelTransactionPlanResult,\n    sequentialTransactionPlanResult,\n    SingleTransactionPlanResult,\n    successfulSingleTransactionPlanResult,\n    successfulSingleTransactionPlanResultFromTransaction,\n    type TransactionPlanResult,\n    type TransactionPlanResultContext,\n} from './transaction-plan-result';\n\n/**\n * Executes a transaction plan and returns the execution results.\n *\n * This function traverses the transaction plan tree, executing each transaction\n * message and collecting results that mirror the structure of the original plan.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results.\n * @param transactionPlan - The transaction plan to execute.\n * @param config - Optional configuration object that can include an `AbortSignal` to cancel execution.\n * @return A promise that resolves to the execution results.\n *\n * @see {@link TransactionPlan}\n * @see {@link TransactionPlanResult}\n * @see {@link createTransactionPlanExecutor}\n */\nexport type TransactionPlanExecutor<TContext extends TransactionPlanResultContext = TransactionPlanResultContext> = (\n    transactionPlan: TransactionPlan,\n    config?: { abortSignal?: AbortSignal },\n) => Promise<TransactionPlanResult<TContext>>;\n\ntype ExecuteTransactionMessage<TContext extends TransactionPlanResultContext> = (\n    context: BaseTransactionPlanResultContext & TContext,\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer,\n    config?: { abortSignal?: AbortSignal },\n) => Promise<Signature | Transaction>;\n\n/**\n * Configuration object for creating a new transaction plan executor.\n *\n * @see {@link createTransactionPlanExecutor}\n */\nexport type TransactionPlanExecutorConfig<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n> = {\n    /** Called whenever a transaction message must be sent to the blockchain. */\n    executeTransactionMessage: ExecuteTransactionMessage<TContext>;\n};\n\n/**\n * Creates a new transaction plan executor based on the provided configuration.\n *\n * The executor will traverse the provided `TransactionPlan` sequentially or in parallel,\n * executing each transaction message using the `executeTransactionMessage` function.\n *\n * The `executeTransactionMessage` callback receives a mutable context object as its first\n * argument, which can be used to incrementally store useful data as execution progresses\n * (e.g. the latest version of the transaction message after setting its lifetime, the\n * compiled and signed transaction, or any custom properties). This context is included\n * in the resulting {@link SingleTransactionPlanResult} regardless of the outcome. This\n * means that if an error is thrown at any point in the callback, any attributes already\n * saved to the context will still be available in the plan result, which can be useful\n * for debugging failures or building recovery plans. The callback must return either a\n * {@link Signature} or a full {@link Transaction} object.\n *\n * - If that function is successful, the executor will return a successful `TransactionPlanResult`\n * for that message. The returned signature or transaction is stored in the context automatically.\n * - If that function throws an error, the executor will stop processing and cancel all\n * remaining transaction messages in the plan. The context accumulated up to the point of\n * failure is preserved in the resulting {@link FailedSingleTransactionPlanResult}.\n * - If the `abortSignal` is triggered, the executor will immediately stop processing the plan and\n * return a `TransactionPlanResult` with the status set to `canceled`.\n *\n * @param config - Configuration object containing the transaction message executor function.\n * @return A {@link TransactionPlanExecutor} function that can execute transaction plans.\n *\n * @throws {@link SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN}\n *   if any transaction in the plan fails to execute. The error context contains a\n *   `transactionPlanResult` property with the partial results up to the point of failure.\n * @throws {@link SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED}\n *   if the transaction plan contains non-divisible sequential plans, which are not\n *   supported by this executor.\n *\n * @example\n * ```ts\n * const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n *\n * const transactionPlanExecutor = createTransactionPlanExecutor({\n *   executeTransactionMessage: async (context, message) => {\n *     const transaction = await signTransactionMessageWithSigners(message);\n *     context.transaction = transaction;\n *     await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n *     return transaction;\n *   }\n * });\n * ```\n *\n * @see {@link TransactionPlanExecutorConfig}\n */\nexport function createTransactionPlanExecutor<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(config: TransactionPlanExecutorConfig<TContext>): TransactionPlanExecutor<TContext> {\n    return async (plan, { abortSignal } = {}): Promise<TransactionPlanResult<TContext>> => {\n        const traverseConfig: TraverseConfig<TContext> = {\n            ...config,\n            abortSignal: abortSignal,\n            canceled: abortSignal?.aborted ?? false,\n        };\n\n        // Fail early if there are non-divisible sequential plans in the\n        // transaction plan as they are not supported by this executor.\n        assertDivisibleSequentialPlansOnly(plan);\n\n        const cancelHandler = () => {\n            traverseConfig.canceled = true;\n        };\n        abortSignal?.addEventListener('abort', cancelHandler);\n        const transactionPlanResult = await traverse(plan, traverseConfig);\n        abortSignal?.removeEventListener('abort', cancelHandler);\n\n        if (traverseConfig.canceled) {\n            const abortReason = abortSignal?.aborted ? abortSignal.reason : undefined;\n            throw createFailedToExecuteTransactionPlanError(transactionPlanResult, abortReason);\n        }\n\n        return transactionPlanResult;\n    };\n}\n\ntype TraverseConfig<TContext extends TransactionPlanResultContext> = TransactionPlanExecutorConfig<TContext> & {\n    abortSignal?: AbortSignal;\n    canceled: boolean;\n};\n\nasync function traverse<TContext extends TransactionPlanResultContext>(\n    transactionPlan: TransactionPlan,\n    traverseConfig: TraverseConfig<TContext>,\n): Promise<TransactionPlanResult<TContext>> {\n    const kind = transactionPlan.kind;\n    switch (kind) {\n        case 'sequential':\n            return await traverseSequential(transactionPlan, traverseConfig);\n        case 'parallel':\n            return await traverseParallel(transactionPlan, traverseConfig);\n        case 'single':\n            return await traverseSingle(transactionPlan, traverseConfig);\n        default:\n            transactionPlan satisfies never;\n            throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND, { kind });\n    }\n}\n\nasync function traverseSequential<TContext extends TransactionPlanResultContext>(\n    transactionPlan: SequentialTransactionPlan,\n    traverseConfig: TraverseConfig<TContext>,\n): Promise<TransactionPlanResult<TContext>> {\n    if (!transactionPlan.divisible) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED);\n    }\n\n    const results: TransactionPlanResult<TContext>[] = [];\n\n    for (const subPlan of transactionPlan.plans) {\n        const result = await traverse(subPlan, traverseConfig);\n        results.push(result);\n    }\n\n    return sequentialTransactionPlanResult(results);\n}\n\nasync function traverseParallel<TContext extends TransactionPlanResultContext>(\n    transactionPlan: ParallelTransactionPlan,\n    traverseConfig: TraverseConfig<TContext>,\n): Promise<TransactionPlanResult<TContext>> {\n    const results = await Promise.all(transactionPlan.plans.map(plan => traverse(plan, traverseConfig)));\n    return parallelTransactionPlanResult(results);\n}\n\nasync function traverseSingle<TContext extends TransactionPlanResultContext>(\n    transactionPlan: SingleTransactionPlan,\n    traverseConfig: TraverseConfig<TContext>,\n): Promise<TransactionPlanResult<TContext>> {\n    const context = {} as BaseTransactionPlanResultContext & TContext;\n    if (traverseConfig.canceled) {\n        return canceledSingleTransactionPlanResult(transactionPlan.message, context);\n    }\n\n    try {\n        const result = await getAbortablePromise(\n            traverseConfig.executeTransactionMessage(context, transactionPlan.message, {\n                abortSignal: traverseConfig.abortSignal,\n            }),\n            traverseConfig.abortSignal,\n        );\n        return typeof result === 'string'\n            ? successfulSingleTransactionPlanResult(transactionPlan.message, { ...context, signature: result })\n            : successfulSingleTransactionPlanResultFromTransaction(transactionPlan.message, result, context);\n    } catch (error) {\n        traverseConfig.canceled = true;\n        const contextWithSignature =\n            'transaction' in context && typeof context.transaction === 'object' && context.signature == null\n                ? { ...context, signature: getSignatureFromTransaction(context.transaction) }\n                : context;\n        return failedSingleTransactionPlanResult(transactionPlan.message, error as Error, contextWithSignature);\n    }\n}\n\nfunction assertDivisibleSequentialPlansOnly(transactionPlan: TransactionPlan): void {\n    const kind = transactionPlan.kind;\n    switch (kind) {\n        case 'sequential':\n            if (!transactionPlan.divisible) {\n                throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__NON_DIVISIBLE_TRANSACTION_PLANS_NOT_SUPPORTED);\n            }\n            for (const subPlan of transactionPlan.plans) {\n                assertDivisibleSequentialPlansOnly(subPlan);\n            }\n            return;\n        case 'parallel':\n            for (const subPlan of transactionPlan.plans) {\n                assertDivisibleSequentialPlansOnly(subPlan);\n            }\n            return;\n        case 'single':\n        default:\n            return;\n    }\n}\n\n/**\n * Wraps a transaction plan execution promise to return a\n * {@link TransactionPlanResult} even on execution failure.\n *\n * When a transaction plan executor throws a\n * {@link SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN}\n * error, this helper catches it and returns the `TransactionPlanResult`\n * from the error context instead of throwing.\n *\n * This allows us to handle the result of an execution in a single unified way\n * instead of using try/catch and examine the `TransactionPlanResult` in both\n * success and failure cases.\n *\n * Any other errors are re-thrown as normal.\n *\n * @param promise - A promise returned by a transaction plan executor.\n * @return A promise that resolves to the transaction plan result, even if some transactions failed.\n *\n * @example\n * Handling failures using a single result object:\n * ```ts\n * const result = await passthroughFailedTransactionPlanExecution(\n *   transactionPlanExecutor(transactionPlan)\n * );\n *\n * const summary = summarizeTransactionPlanResult(result);\n * if (summary.successful) {\n *   console.log('All transactions executed successfully');\n * } else {\n *   console.log(`${summary.successfulTransactions.length} succeeded`);\n *   console.log(`${summary.failedTransactions.length} failed`);\n *   console.log(`${summary.canceledTransactions.length} canceled`);\n * }\n * ```\n *\n * @see {@link TransactionPlanResult}\n * @see {@link createTransactionPlanExecutor}\n * @see {@link summarizeTransactionPlanResult}\n */\nexport async function passthroughFailedTransactionPlanExecution(\n    promise: Promise<SingleTransactionPlanResult>,\n): Promise<SingleTransactionPlanResult>;\nexport async function passthroughFailedTransactionPlanExecution(\n    promise: Promise<TransactionPlanResult>,\n): Promise<TransactionPlanResult>;\nexport async function passthroughFailedTransactionPlanExecution(\n    promise: Promise<TransactionPlanResult>,\n): Promise<TransactionPlanResult> {\n    try {\n        return await promise;\n    } catch (error) {\n        if (isSolanaError(error, SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_TO_EXECUTE_TRANSACTION_PLAN)) {\n            return error.context.transactionPlanResult as TransactionPlanResult;\n        }\n        throw error;\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/transaction-plan-result.ts",
    "content": "import {\n    SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT,\n    SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND,\n    SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT,\n    SolanaError,\n} from '@solana/errors';\nimport { Signature } from '@solana/keys';\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\nimport { getSignatureFromTransaction, Transaction } from '@solana/transactions';\n\n/**\n * The result of executing a transaction plan.\n *\n * This is structured as a recursive tree of results that mirrors the structure\n * of the original transaction plan, capturing the execution status at each level.\n *\n * Namely, the following result types are supported:\n * - {@link SingleTransactionPlanResult} - A result for a single transaction message\n *   containing its execution status.\n * - {@link ParallelTransactionPlanResult} - A result containing other results that\n *   were executed in parallel.\n * - {@link SequentialTransactionPlanResult} - A result containing other results that\n *   were executed sequentially. It also retains the divisibility property from the\n *   original plan.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n * @typeParam TSingle - The type of single transaction plan results in this tree\n *\n * @see {@link SingleTransactionPlanResult}\n * @see {@link ParallelTransactionPlanResult}\n * @see {@link SequentialTransactionPlanResult}\n */\nexport type TransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n> =\n    | ParallelTransactionPlanResult<TContext, TTransactionMessage, TSingle>\n    | SequentialTransactionPlanResult<TContext, TTransactionMessage, TSingle>\n    | TSingle;\n\n/**\n * A {@link TransactionPlanResult} where all single transaction results are successful.\n *\n * This type represents a transaction plan result tree where every\n * {@link SingleTransactionPlanResult} has a 'successful' status. It can be used\n * to ensure that an entire execution completed without any failures or cancellations.\n *\n * Note: This is different from {@link SuccessfulSingleTransactionPlanResult} which\n * represents a single successful transaction, whereas this type represents an entire\n * plan result tree (which may contain parallel/sequential structures) where all\n * leaf nodes are successful.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n *\n * @see {@link isSuccessfulTransactionPlanResult}\n * @see {@link assertIsSuccessfulTransactionPlanResult}\n * @see {@link SuccessfulSingleTransactionPlanResult}\n */\nexport type SuccessfulTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n> = TransactionPlanResult<\n    TContext,\n    TTransactionMessage,\n    SuccessfulSingleTransactionPlanResult<TContext, TTransactionMessage>\n>;\n\n/**\n * The context object associated with a {@link SingleTransactionPlanResult}.\n *\n * This type defines the shape of custom context that can be attached to\n * transaction plan results. It allows arbitrary additional properties that\n * consumers can use to pass along extra data with their results.\n *\n * Note that base context fields such as `message`, `signature`, and\n * `transaction` are provided separately by {@link BaseTransactionPlanResultContext}\n * and {@link SuccessfulBaseTransactionPlanResultContext}, which are intersected\n * with this type in each {@link SingleTransactionPlanResult} variant.\n *\n * @see {@link SingleTransactionPlanResult}\n * @see {@link SuccessfulSingleTransactionPlanResult}\n * @see {@link FailedSingleTransactionPlanResult}\n * @see {@link CanceledSingleTransactionPlanResult}\n */\nexport type TransactionPlanResultContext = { [key: number | string | symbol]: unknown };\n\n/**\n * The base context fields that are common to all {@link SingleTransactionPlanResult} variants.\n *\n * This type provides optional fields for the transaction message, signature, and\n * full transaction object. These fields may or may not be populated depending on\n * how far execution progressed before the result was produced.\n *\n * @see {@link FailedSingleTransactionPlanResult}\n * @see {@link CanceledSingleTransactionPlanResult}\n * @see {@link SuccessfulBaseTransactionPlanResultContext}\n */\nexport interface BaseTransactionPlanResultContext {\n    message?: TransactionMessage & TransactionMessageWithFeePayer;\n    signature?: Signature;\n    transaction?: Transaction;\n}\n\n/**\n * The base context fields for a {@link SuccessfulSingleTransactionPlanResult}.\n *\n * This extends the base context by requiring a {@link Signature}, since a\n * successful transaction always produces one. The transaction message and full\n * transaction object remain optional.\n *\n * @see {@link SuccessfulSingleTransactionPlanResult}\n * @see {@link BaseTransactionPlanResultContext}\n */\nexport interface SuccessfulBaseTransactionPlanResultContext extends BaseTransactionPlanResultContext {\n    signature: Signature;\n}\n\n/**\n * A result for a sequential transaction plan.\n *\n * This represents the execution result of a {@link SequentialTransactionPlan} and\n * contains child results that were executed sequentially. It also retains the\n * divisibility property from the original plan.\n *\n * You may use the {@link sequentialTransactionPlanResult} and\n * {@link nonDivisibleSequentialTransactionPlanResult} helpers to create objects of this type.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n * @typeParam TSingle - The type of single transaction plan results in this tree\n *\n * @example\n * ```ts\n * const result = sequentialTransactionPlanResult([\n *   singleResultA,\n *   singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult;\n * ```\n *\n * @example\n * Non-divisible sequential result.\n * ```ts\n * const result = nonDivisibleSequentialTransactionPlanResult([\n *   singleResultA,\n *   singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: false };\n * ```\n *\n * @see {@link sequentialTransactionPlanResult}\n * @see {@link nonDivisibleSequentialTransactionPlanResult}\n */\nexport type SequentialTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n> = Readonly<{\n    divisible: boolean;\n    kind: 'sequential';\n    planType: 'transactionPlanResult';\n    plans: TransactionPlanResult<TContext, TTransactionMessage, TSingle>[];\n}>;\n\n/**\n * A result for a parallel transaction plan.\n *\n * This represents the execution result of a {@link ParallelTransactionPlan} and\n * contains child results that were executed in parallel.\n *\n * You may use the {@link parallelTransactionPlanResult} helper to create objects of this type.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n * @typeParam TSingle - The type of single transaction plan results in this tree\n *\n * @example\n * ```ts\n * const result = parallelTransactionPlanResult([\n *   singleResultA,\n *   singleResultB,\n * ]);\n * result satisfies ParallelTransactionPlanResult;\n * ```\n *\n * @see {@link parallelTransactionPlanResult}\n */\nexport type ParallelTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n> = Readonly<{\n    kind: 'parallel';\n    planType: 'transactionPlanResult';\n    plans: TransactionPlanResult<TContext, TTransactionMessage, TSingle>[];\n}>;\n\n/**\n * A result for a single transaction plan.\n *\n * This represents the execution result of a {@link SingleTransactionPlan} and\n * contains the original transaction message along with its execution status.\n *\n * You may use the {@link successfulSingleTransactionPlanResultFromTransaction},\n * {@link failedSingleTransactionPlanResult}, or {@link canceledSingleTransactionPlanResult}\n * helpers to create objects of this type.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n *\n * @example\n * Successful result with a transaction and context.\n * ```ts\n * const result = successfulSingleTransactionPlanResultFromTransaction(\n *   transactionMessage,\n *   transaction\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @example\n * Failed result with an error.\n * ```ts\n * const result = failedSingleTransactionPlanResult(\n *   transactionMessage,\n *   new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @example\n * Canceled result.\n * ```ts\n * const result = canceledSingleTransactionPlanResult(transactionMessage);\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link successfulSingleTransactionPlanResultFromTransaction}\n * @see {@link failedSingleTransactionPlanResult}\n * @see {@link canceledSingleTransactionPlanResult}\n */\nexport type SingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n> =\n    | CanceledSingleTransactionPlanResult<TContext, TTransactionMessage>\n    | FailedSingleTransactionPlanResult<TContext, TTransactionMessage>\n    | SuccessfulSingleTransactionPlanResult<TContext, TTransactionMessage>;\n\n/**\n * A {@link SingleTransactionPlanResult} with a 'successful' status.\n *\n * This type represents a single transaction that was successfully executed.\n * It includes the original planned message and a context object containing\n * the fields from {@link SuccessfulBaseTransactionPlanResultContext} — namely\n * a required transaction {@link Signature}, and optionally the\n * {@link TransactionMessage} and the full {@link Transaction} object.\n *\n * You may use the {@link successfulSingleTransactionPlanResultFromTransaction} or\n * {@link successfulSingleTransactionPlanResult} helpers to\n * create objects of this type.\n *\n * @typeParam TContext - The type of the context object that may be passed along with the result.\n * @typeParam TTransactionMessage - The type of the transaction message.\n *\n * @example\n * Creating a successful result from a transaction.\n * ```ts\n * const result = successfulSingleTransactionPlanResultFromTransaction(\n *   transactionMessage,\n *   transaction,\n * );\n * result satisfies SuccessfulSingleTransactionPlanResult;\n * result.context.signature; // The transaction signature.\n * ```\n *\n * @see {@link successfulSingleTransactionPlanResultFromTransaction}\n * @see {@link successfulSingleTransactionPlanResult}\n * @see {@link isSuccessfulSingleTransactionPlanResult}\n * @see {@link assertIsSuccessfulSingleTransactionPlanResult}\n */\nexport type SuccessfulSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n> = {\n    context: Readonly<SuccessfulBaseTransactionPlanResultContext & TContext>;\n    kind: 'single';\n    planType: 'transactionPlanResult';\n    plannedMessage: TTransactionMessage;\n    status: 'successful';\n};\n\n/**\n * A {@link SingleTransactionPlanResult} with a 'failed' status.\n *\n * This type represents a single transaction that failed during execution.\n * It includes the original planned message, the {@link Error} that caused\n * the failure, and a context object containing the fields from\n * {@link BaseTransactionPlanResultContext} — namely optional\n * {@link TransactionMessage}, {@link Signature}, and {@link Transaction}\n * fields that may or may not be populated depending on how far execution\n * progressed before the failure.\n *\n * You may use the {@link failedSingleTransactionPlanResult} helper to\n * create objects of this type.\n *\n * @typeParam TContext - The type of the context object that may be passed along with the result.\n * @typeParam TTransactionMessage - The type of the transaction message.\n *\n * @example\n * Creating a failed result from a transaction message and error.\n * ```ts\n * const result = failedSingleTransactionPlanResult(\n *   transactionMessage,\n *   new Error('Transaction simulation failed'),\n * );\n * result satisfies FailedSingleTransactionPlanResult;\n * result.error; // The error that caused the failure.\n * ```\n *\n * @see {@link failedSingleTransactionPlanResult}\n * @see {@link isFailedSingleTransactionPlanResult}\n * @see {@link assertIsFailedSingleTransactionPlanResult}\n */\nexport type FailedSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n> = {\n    context: Readonly<BaseTransactionPlanResultContext & TContext>;\n    error: Error;\n    kind: 'single';\n    planType: 'transactionPlanResult';\n    plannedMessage: TTransactionMessage;\n    status: 'failed';\n};\n\n/**\n * A {@link SingleTransactionPlanResult} with a 'canceled' status.\n *\n * This type represents a single transaction whose execution was canceled\n * before it could complete. It includes the original planned message and\n * a context object containing the fields from\n * {@link BaseTransactionPlanResultContext} — namely optional\n * {@link TransactionMessage}, {@link Signature}, and {@link Transaction}\n * fields that may or may not be populated depending on how far execution\n * progressed before cancellation.\n *\n * You may use the {@link canceledSingleTransactionPlanResult} helper to\n * create objects of this type.\n *\n * @typeParam TContext - The type of the context object that may be passed along with the result.\n * @typeParam TTransactionMessage - The type of the transaction message.\n *\n * @example\n * Creating a canceled result from a transaction message.\n * ```ts\n * const result = canceledSingleTransactionPlanResult(transactionMessage);\n * result satisfies CanceledSingleTransactionPlanResult;\n * ```\n *\n * @see {@link canceledSingleTransactionPlanResult}\n * @see {@link isCanceledSingleTransactionPlanResult}\n * @see {@link assertIsCanceledSingleTransactionPlanResult}\n */\nexport type CanceledSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n> = {\n    context: Readonly<BaseTransactionPlanResultContext & TContext>;\n    kind: 'single';\n    planType: 'transactionPlanResult';\n    plannedMessage: TTransactionMessage;\n    status: 'canceled';\n};\n\n/**\n * Creates a divisible {@link SequentialTransactionPlanResult} from an array of nested results.\n *\n * This function creates a sequential result with the `divisible` property set to `true`,\n * indicating that the nested plans were executed sequentially but could have been\n * split into separate transactions or batches.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @param plans - The child results that were executed sequentially\n *\n * @example\n * ```ts\n * const result = sequentialTransactionPlanResult([\n *   singleResultA,\n *   singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: true };\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n */\nexport function sequentialTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): SequentialTransactionPlanResult<TContext> & { divisible: true } {\n    return Object.freeze({ divisible: true, kind: 'sequential', planType: 'transactionPlanResult', plans });\n}\n\n/**\n * Creates a non-divisible {@link SequentialTransactionPlanResult} from an array of nested results.\n *\n * This function creates a sequential result with the `divisible` property set to `false`,\n * indicating that the nested plans were executed sequentially and could not have been\n * split into separate transactions or batches (e.g., they were executed as a transaction bundle).\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @param plans - The child results that were executed sequentially\n *\n * @example\n * ```ts\n * const result = nonDivisibleSequentialTransactionPlanResult([\n *   singleResultA,\n *   singleResultB,\n * ]);\n * result satisfies SequentialTransactionPlanResult & { divisible: false };\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n */\nexport function nonDivisibleSequentialTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): SequentialTransactionPlanResult<TContext> & { divisible: false } {\n    return Object.freeze({ divisible: false, kind: 'sequential', planType: 'transactionPlanResult', plans });\n}\n\n/**\n * Creates a {@link ParallelTransactionPlanResult} from an array of nested results.\n *\n * This function creates a parallel result indicating that the nested plans\n * were executed in parallel.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @param plans - The child results that were executed in parallel\n *\n * @example\n * ```ts\n * const result = parallelTransactionPlanResult([\n *   singleResultA,\n *   singleResultB,\n * ]);\n * result satisfies ParallelTransactionPlanResult;\n * ```\n *\n * @see {@link ParallelTransactionPlanResult}\n */\nexport function parallelTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n>(plans: TransactionPlanResult<TContext>[]): ParallelTransactionPlanResult<TContext> {\n    return Object.freeze({ kind: 'parallel', planType: 'transactionPlanResult', plans });\n}\n\n/**\n * Creates a successful {@link SingleTransactionPlanResult} from a transaction message and transaction.\n *\n * This function creates a single result with a 'successful' status, indicating that\n * the transaction was successfully executed. It also includes the original transaction\n * message, the executed transaction, and an optional context object.\n *\n * @typeParam TContext - The type of the context object\n * @typeParam TTransactionMessage - The type of the transaction message\n * @param plannedMessage - The original transaction message\n * @param transaction - The successfully executed transaction\n * @param context - Optional context object to be included with the result\n *\n * @example\n * ```ts\n * const result = successfulSingleTransactionPlanResultFromTransaction(\n *   transactionMessage,\n *   transaction\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function successfulSingleTransactionPlanResultFromTransaction<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plannedMessage: TTransactionMessage,\n    transaction: Transaction,\n    context?: Omit<BaseTransactionPlanResultContext, 'signature' | 'transaction'> & TContext,\n): SuccessfulSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    const signature = getSignatureFromTransaction(transaction);\n    return Object.freeze({\n        context: Object.freeze({ ...((context ?? {}) as TContext), signature, transaction }),\n        kind: 'single',\n        planType: 'transactionPlanResult',\n        plannedMessage,\n        status: 'successful',\n    });\n}\n\n/**\n * Creates a successful {@link SingleTransactionPlanResult} from a transaction message and context.\n *\n * This function creates a single result with a 'successful' status, indicating that\n * the transaction was successfully executed. It also includes the original transaction\n * message and a context object that must contain at least a {@link Signature}.\n *\n * @typeParam TContext - The type of the context object\n * @typeParam TTransactionMessage - The type of the transaction message\n * @param plannedMessage - The original transaction message\n * @param context - Context object to be included with the result, must include a `signature` property\n *\n * @example\n * ```ts\n * const result = successfulSingleTransactionPlanResult(\n *   transactionMessage,\n *   { signature },\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function successfulSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plannedMessage: TTransactionMessage,\n    context: SuccessfulBaseTransactionPlanResultContext & TContext,\n): SuccessfulSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    return Object.freeze({\n        context: Object.freeze({ ...context }),\n        kind: 'single',\n        planType: 'transactionPlanResult',\n        plannedMessage,\n        status: 'successful',\n    });\n}\n\n/**\n * Creates a failed {@link SingleTransactionPlanResult} from a transaction message and error.\n *\n * This function creates a single result with a 'failed' status, indicating that\n * the transaction execution failed. It includes the original transaction message\n * and the error that caused the failure.\n *\n * @typeParam TContext - The type of the context object\n * @typeParam TTransactionMessage - The type of the transaction message\n * @param plannedMessage - The original transaction message\n * @param error - The error that caused the transaction to fail\n *\n * @example\n * ```ts\n * const result = failedSingleTransactionPlanResult(\n *   transactionMessage,\n *   new SolanaError({\n *     code: 123,\n *     message: 'Transaction simulation failed',\n *   }),\n * );\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function failedSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plannedMessage: TTransactionMessage,\n    error: Error,\n    context?: TContext,\n): FailedSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    return Object.freeze({\n        context: Object.freeze({ ...((context ?? {}) as TContext) }),\n        error,\n        kind: 'single',\n        planType: 'transactionPlanResult',\n        plannedMessage,\n        status: 'failed',\n    });\n}\n\n/**\n * Creates a canceled {@link SingleTransactionPlanResult} from a transaction message.\n *\n * This function creates a single result with a 'canceled' status, indicating that\n * the transaction execution was canceled. It includes the original transaction message.\n *\n * @typeParam TContext - The type of the context object\n * @typeParam TTransactionMessage - The type of the transaction message\n * @param plannedMessage - The original transaction message\n *\n * @example\n * ```ts\n * const result = canceledSingleTransactionPlanResult(transactionMessage);\n * result satisfies SingleTransactionPlanResult;\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n */\nexport function canceledSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plannedMessage: TTransactionMessage,\n    context?: TContext,\n): CanceledSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    return Object.freeze({\n        context: Object.freeze({ ...((context ?? {}) as TContext) }),\n        kind: 'single',\n        planType: 'transactionPlanResult',\n        plannedMessage,\n        status: 'canceled',\n    });\n}\n\n/**\n * Checks if the given value is a {@link TransactionPlanResult}.\n *\n * This type guard checks the `planType` property to determine if the value\n * is a transaction plan result. This is useful when you have a value that could be\n * an {@link InstructionPlan}, {@link TransactionPlan}, or {@link TransactionPlanResult}\n * and need to narrow the type.\n *\n * @param value - The value to check.\n * @return `true` if the value is a transaction plan result, `false` otherwise.\n *\n * @example\n * ```ts\n * function processItem(item: InstructionPlan | TransactionPlan | TransactionPlanResult) {\n *   if (isTransactionPlanResult(item)) {\n *     // item is narrowed to TransactionPlanResult\n *     console.log(item.kind);\n *   }\n * }\n * ```\n *\n * @see {@link TransactionPlanResult}\n * @see {@link isInstructionPlan}\n * @see {@link isTransactionPlan}\n */\nexport function isTransactionPlanResult(value: unknown): value is TransactionPlanResult {\n    return (\n        typeof value === 'object' &&\n        value !== null &&\n        'planType' in value &&\n        typeof value.planType === 'string' &&\n        value.planType === 'transactionPlanResult'\n    );\n}\n\n/**\n * Checks if the given transaction plan result is a {@link SingleTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to check.\n * @return `true` if the result is a single transaction plan result, `false` otherwise.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = successfulSingleTransactionPlanResultFromTransaction(message, transaction);\n *\n * if (isSingleTransactionPlanResult(result)) {\n *   console.log(result.status); // TypeScript knows this is a SingleTransactionPlanResult.\n * }\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n * @see {@link assertIsSingleTransactionPlanResult}\n */\nexport function isSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>): plan is TSingle {\n    return plan.kind === 'single';\n}\n\n/**\n * Asserts that the given transaction plan result is a {@link SingleTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT` if the result is not a single transaction plan result.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = successfulSingleTransactionPlanResultFromTransaction(message, transaction);\n *\n * assertIsSingleTransactionPlanResult(result);\n * console.log(result.status); // TypeScript knows this is a SingleTransactionPlanResult.\n * ```\n *\n * @see {@link SingleTransactionPlanResult}\n * @see {@link isSingleTransactionPlanResult}\n */\nexport function assertIsSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>): asserts plan is TSingle {\n    if (!isSingleTransactionPlanResult(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT, {\n            actualKind: plan.kind,\n            expectedKind: 'single',\n            transactionPlanResult: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan result is a successful {@link SingleTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to check.\n * @return `true` if the result is a successful single transaction plan result, `false` otherwise.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = successfulSingleTransactionPlanResultFromTransaction(message, transaction);\n *\n * if (isSuccessfulSingleTransactionPlanResult(result)) {\n *   console.log(result.context.signature); // TypeScript knows this is a successful result.\n * }\n * ```\n *\n * @see {@link SuccessfulSingleTransactionPlanResult}\n * @see {@link assertIsSuccessfulSingleTransactionPlanResult}\n */\nexport function isSuccessfulSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage>,\n): plan is SuccessfulSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    return plan.kind === 'single' && plan.status === 'successful';\n}\n\n/**\n * Asserts that the given transaction plan result is a successful {@link SingleTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT` if the result is not a successful single transaction plan result.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = successfulSingleTransactionPlanResultFromTransaction(message, transaction);\n *\n * assertIsSuccessfulSingleTransactionPlanResult(result);\n * console.log(result.context.signature); // TypeScript knows this is a successful result.\n * ```\n *\n * @see {@link SuccessfulSingleTransactionPlanResult}\n * @see {@link isSuccessfulSingleTransactionPlanResult}\n */\nexport function assertIsSuccessfulSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage>,\n): asserts plan is SuccessfulSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    if (!isSuccessfulSingleTransactionPlanResult(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT, {\n            actualKind: plan.kind === 'single' ? `${plan.status} single` : plan.kind,\n            expectedKind: 'successful single',\n            transactionPlanResult: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan result is a failed {@link SingleTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to check.\n * @return `true` if the result is a failed single transaction plan result, `false` otherwise.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = failedSingleTransactionPlanResult(message, error);\n *\n * if (isFailedSingleTransactionPlanResult(result)) {\n *   console.log(result.error); // TypeScript knows this is a failed result.\n * }\n * ```\n *\n * @see {@link FailedSingleTransactionPlanResult}\n * @see {@link assertIsFailedSingleTransactionPlanResult}\n */\nexport function isFailedSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage>,\n): plan is FailedSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    return plan.kind === 'single' && plan.status === 'failed';\n}\n\n/**\n * Asserts that the given transaction plan result is a failed {@link SingleTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT` if the result is not a failed single transaction plan result.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = failedSingleTransactionPlanResult(message, error);\n *\n * assertIsFailedSingleTransactionPlanResult(result);\n * console.log(result.error); // TypeScript knows this is a failed result.\n * ```\n *\n * @see {@link FailedSingleTransactionPlanResult}\n * @see {@link isFailedSingleTransactionPlanResult}\n */\nexport function assertIsFailedSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage>,\n): asserts plan is FailedSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    if (!isFailedSingleTransactionPlanResult(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT, {\n            actualKind: plan.kind === 'single' ? `${plan.status} single` : plan.kind,\n            expectedKind: 'failed single',\n            transactionPlanResult: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan result is a canceled {@link SingleTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to check.\n * @return `true` if the result is a canceled single transaction plan result, `false` otherwise.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = canceledSingleTransactionPlanResult(message);\n *\n * if (isCanceledSingleTransactionPlanResult(result)) {\n *   console.log('Transaction was canceled'); // TypeScript knows this is a canceled result.\n * }\n * ```\n *\n * @see {@link CanceledSingleTransactionPlanResult}\n * @see {@link assertIsCanceledSingleTransactionPlanResult}\n */\nexport function isCanceledSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage>,\n): plan is CanceledSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    return plan.kind === 'single' && plan.status === 'canceled';\n}\n\n/**\n * Asserts that the given transaction plan result is a canceled {@link SingleTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT` if the result is not a canceled single transaction plan result.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = canceledSingleTransactionPlanResult(message);\n *\n * assertIsCanceledSingleTransactionPlanResult(result);\n * console.log('Transaction was canceled'); // TypeScript knows this is a canceled result.\n * ```\n *\n * @see {@link CanceledSingleTransactionPlanResult}\n * @see {@link isCanceledSingleTransactionPlanResult}\n */\nexport function assertIsCanceledSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage>,\n): asserts plan is CanceledSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    if (!isCanceledSingleTransactionPlanResult(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT, {\n            actualKind: plan.kind === 'single' ? `${plan.status} single` : plan.kind,\n            expectedKind: 'canceled single',\n            transactionPlanResult: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan result is a {@link SequentialTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to check.\n * @return `true` if the result is a sequential transaction plan result, `false` otherwise.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = sequentialTransactionPlanResult([resultA, resultB]);\n *\n * if (isSequentialTransactionPlanResult(result)) {\n *   console.log(result.divisible); // TypeScript knows this is a SequentialTransactionPlanResult.\n * }\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n * @see {@link assertIsSequentialTransactionPlanResult}\n */\nexport function isSequentialTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>,\n): plan is SequentialTransactionPlanResult<TContext, TTransactionMessage, TSingle> {\n    return plan.kind === 'sequential';\n}\n\n/**\n * Asserts that the given transaction plan result is a {@link SequentialTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT` if the result is not a sequential transaction plan result.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = sequentialTransactionPlanResult([resultA, resultB]);\n *\n * assertIsSequentialTransactionPlanResult(result);\n * console.log(result.divisible); // TypeScript knows this is a SequentialTransactionPlanResult.\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n * @see {@link isSequentialTransactionPlanResult}\n */\nexport function assertIsSequentialTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>,\n): asserts plan is SequentialTransactionPlanResult<TContext, TTransactionMessage, TSingle> {\n    if (!isSequentialTransactionPlanResult(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT, {\n            actualKind: plan.kind,\n            expectedKind: 'sequential',\n            transactionPlanResult: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan result is a non-divisible {@link SequentialTransactionPlanResult}.\n *\n * A non-divisible sequential result indicates that the transactions were executed\n * atomically — usually in a transaction bundle.\n *\n * @param plan - The transaction plan result to check.\n * @return `true` if the result is a non-divisible sequential transaction plan result, `false` otherwise.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = nonDivisibleSequentialTransactionPlanResult([resultA, resultB]);\n *\n * if (isNonDivisibleSequentialTransactionPlanResult(result)) {\n *   // Transactions were executed atomically.\n * }\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n * @see {@link assertIsNonDivisibleSequentialTransactionPlanResult}\n */\nexport function isNonDivisibleSequentialTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>,\n): plan is SequentialTransactionPlanResult<TContext, TTransactionMessage, TSingle> & { divisible: false } {\n    return plan.kind === 'sequential' && plan.divisible === false;\n}\n\n/**\n * Asserts that the given transaction plan result is a non-divisible {@link SequentialTransactionPlanResult}.\n *\n * A non-divisible sequential result indicates that the transactions were executed\n * atomically — usually in a transaction bundle.\n *\n * @param plan - The transaction plan result to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT` if the result is not a non-divisible sequential transaction plan result.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = nonDivisibleSequentialTransactionPlanResult([resultA, resultB]);\n *\n * assertIsNonDivisibleSequentialTransactionPlanResult(result);\n * // Transactions were executed atomically.\n * ```\n *\n * @see {@link SequentialTransactionPlanResult}\n * @see {@link isNonDivisibleSequentialTransactionPlanResult}\n */\nexport function assertIsNonDivisibleSequentialTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>,\n): asserts plan is SequentialTransactionPlanResult<TContext, TTransactionMessage, TSingle> & { divisible: false } {\n    if (!isNonDivisibleSequentialTransactionPlanResult(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT, {\n            actualKind: plan.kind === 'sequential' ? 'divisible sequential' : plan.kind,\n            expectedKind: 'non-divisible sequential',\n            transactionPlanResult: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan result is a {@link ParallelTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to check.\n * @return `true` if the result is a parallel transaction plan result, `false` otherwise.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = parallelTransactionPlanResult([resultA, resultB]);\n *\n * if (isParallelTransactionPlanResult(result)) {\n *   console.log(result.plans.length); // TypeScript knows this is a ParallelTransactionPlanResult.\n * }\n * ```\n *\n * @see {@link ParallelTransactionPlanResult}\n * @see {@link assertIsParallelTransactionPlanResult}\n */\nexport function isParallelTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>,\n): plan is ParallelTransactionPlanResult<TContext, TTransactionMessage, TSingle> {\n    return plan.kind === 'parallel';\n}\n\n/**\n * Asserts that the given transaction plan result is a {@link ParallelTransactionPlanResult}.\n *\n * @param plan - The transaction plan result to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT` if the result is not a parallel transaction plan result.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = parallelTransactionPlanResult([resultA, resultB]);\n *\n * assertIsParallelTransactionPlanResult(result);\n * console.log(result.plans.length); // TypeScript knows this is a ParallelTransactionPlanResult.\n * ```\n *\n * @see {@link ParallelTransactionPlanResult}\n * @see {@link isParallelTransactionPlanResult}\n */\nexport function assertIsParallelTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>,\n): asserts plan is ParallelTransactionPlanResult<TContext, TTransactionMessage, TSingle> {\n    if (!isParallelTransactionPlanResult(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN_RESULT, {\n            actualKind: plan.kind,\n            expectedKind: 'parallel',\n            transactionPlanResult: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan result is a {@link SuccessfulTransactionPlanResult}.\n *\n * This function verifies that the entire transaction plan result tree contains only\n * successful single transaction results. It recursively checks all nested results\n * to ensure every {@link SingleTransactionPlanResult} has a 'successful' status.\n *\n * Note: This is different from {@link isSuccessfulSingleTransactionPlanResult} which\n * checks if a single result is successful. This function checks that the entire\n * plan result tree (including all nested parallel/sequential structures) contains\n * only successful transactions.\n *\n * @param plan - The transaction plan result to check.\n * @return `true` if all single transaction results in the tree are successful, `false` otherwise.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = parallelTransactionPlanResult([\n *   successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n *   successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n * ]);\n *\n * if (isSuccessfulTransactionPlanResult(result)) {\n *   // All transactions were successful.\n *   result satisfies SuccessfulTransactionPlanResult;\n * }\n * ```\n *\n * @see {@link SuccessfulTransactionPlanResult}\n * @see {@link assertIsSuccessfulTransactionPlanResult}\n * @see {@link isSuccessfulSingleTransactionPlanResult}\n */\nexport function isSuccessfulTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage>,\n): plan is SuccessfulTransactionPlanResult<TContext, TTransactionMessage> {\n    return everyTransactionPlanResult(\n        plan,\n        r => !isSingleTransactionPlanResult(r) || isSuccessfulSingleTransactionPlanResult(r),\n    );\n}\n\n/**\n * Asserts that the given transaction plan result is a {@link SuccessfulTransactionPlanResult}.\n *\n * This function verifies that the entire transaction plan result tree contains only\n * successful single transaction results. It throws if any {@link SingleTransactionPlanResult}\n * in the tree has a 'failed' or 'canceled' status.\n *\n * Note: This is different from {@link assertIsSuccessfulSingleTransactionPlanResult} which\n * asserts that a single result is successful. This function asserts that the entire\n * plan result tree (including all nested parallel/sequential structures) contains\n * only successful transactions.\n *\n * @param plan - The transaction plan result to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT` if\n * any single transaction result in the tree is not successful.\n *\n * @example\n * ```ts\n * const result: TransactionPlanResult = parallelTransactionPlanResult([\n *   successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n *   successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n * ]);\n *\n * assertIsSuccessfulTransactionPlanResult(result);\n * // All transactions were successful.\n * result satisfies SuccessfulTransactionPlanResult;\n * ```\n *\n * @see {@link SuccessfulTransactionPlanResult}\n * @see {@link isSuccessfulTransactionPlanResult}\n * @see {@link assertIsSuccessfulSingleTransactionPlanResult}\n */\nexport function assertIsSuccessfulTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    plan: TransactionPlanResult<TContext, TTransactionMessage>,\n): asserts plan is SuccessfulTransactionPlanResult<TContext, TTransactionMessage> {\n    if (!isSuccessfulTransactionPlanResult(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__EXPECTED_SUCCESSFUL_TRANSACTION_PLAN_RESULT, {\n            transactionPlanResult: plan,\n        });\n    }\n}\n\n/**\n * Finds the first transaction plan result in the tree that matches the given predicate.\n *\n * This function performs a depth-first search through the transaction plan result tree,\n * returning the first result that satisfies the predicate. It checks the root result\n * first, then recursively searches through nested results.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n * @typeParam TSingle - The type of single transaction plan results in this tree\n * @param transactionPlanResult - The transaction plan result tree to search.\n * @param predicate - A function that returns `true` for the result to find.\n * @returns The first matching transaction plan result, or `undefined` if no match is found.\n *\n * @example\n * Finding a failed transaction result.\n * ```ts\n * const result = parallelTransactionPlanResult([\n *   successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n *   failedSingleTransactionPlanResult(messageB, error),\n * ]);\n *\n * const failed = findTransactionPlanResult(\n *   result,\n *   (r) => r.kind === 'single' && r.status === 'failed',\n * );\n * // Returns the failed single transaction plan result for messageB.\n * ```\n *\n * @see {@link TransactionPlanResult}\n * @see {@link everyTransactionPlanResult}\n * @see {@link transformTransactionPlanResult}\n * @see {@link flattenTransactionPlanResult}\n */\nexport function findTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(\n    transactionPlanResult: TransactionPlanResult<TContext, TTransactionMessage, TSingle>,\n    predicate: (result: TransactionPlanResult<TContext, TTransactionMessage, TSingle>) => boolean,\n): TransactionPlanResult<TContext, TTransactionMessage, TSingle> | undefined {\n    if (predicate(transactionPlanResult)) {\n        return transactionPlanResult;\n    }\n    if (transactionPlanResult.kind === 'single') {\n        return undefined;\n    }\n    for (const subResult of transactionPlanResult.plans) {\n        const foundResult = findTransactionPlanResult(subResult, predicate);\n        if (foundResult) {\n            return foundResult;\n        }\n    }\n    return undefined;\n}\n\n/**\n * Retrieves the first failed transaction plan result from a transaction plan result tree.\n *\n * This function searches the transaction plan result tree using a depth-first traversal\n * and returns the first single transaction result with a 'failed' status. If no failed\n * result is found, it throws a {@link SolanaError}.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n * @param transactionPlanResult - The transaction plan result tree to search.\n * @return The first failed single transaction plan result.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND` if no\n * failed transaction plan result is found. The error context contains a non-enumerable\n * `transactionPlanResult` property for recovery purposes.\n *\n * @example\n * Retrieving the first failed result from a parallel execution.\n * ```ts\n * const result = parallelTransactionPlanResult([\n *   successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n *   failedSingleTransactionPlanResult(messageB, error),\n *   failedSingleTransactionPlanResult(messageC, anotherError),\n * ]);\n *\n * const firstFailed = getFirstFailedSingleTransactionPlanResult(result);\n * // Returns the failed result for messageB.\n * ```\n *\n * @see {@link FailedSingleTransactionPlanResult}\n * @see {@link findTransactionPlanResult}\n */\nexport function getFirstFailedSingleTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    transactionPlanResult: TransactionPlanResult<TContext, TTransactionMessage>,\n): FailedSingleTransactionPlanResult<TContext, TTransactionMessage> {\n    const result = findTransactionPlanResult(transactionPlanResult, r => r.kind === 'single' && r.status === 'failed');\n\n    if (!result) {\n        // Here we want the `transactionPlanResult` to be available in the error context\n        // so applications can recover but we don't want this object to be\n        // serialized with the error. This is why we set it as a non-enumerable property.\n        const context = {};\n        Object.defineProperty(context, 'transactionPlanResult', {\n            configurable: false,\n            enumerable: false,\n            value: transactionPlanResult,\n            writable: false,\n        });\n        throw new SolanaError(\n            SOLANA_ERROR__INSTRUCTION_PLANS__FAILED_SINGLE_TRANSACTION_PLAN_RESULT_NOT_FOUND,\n            context,\n        );\n    }\n\n    return result as FailedSingleTransactionPlanResult<TContext, TTransactionMessage>;\n}\n\n/**\n * Checks if every transaction plan result in the tree satisfies the given predicate.\n *\n * This function performs a depth-first traversal through the transaction plan result tree,\n * returning `true` only if the predicate returns `true` for every result in the tree\n * (including the root result and all nested results).\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n * @typeParam TSingle - The type of single transaction plan results in this tree\n * @param transactionPlanResult - The transaction plan result tree to check.\n * @param predicate - A function that returns `true` if the result satisfies the condition.\n * @return `true` if every result in the tree satisfies the predicate, `false` otherwise.\n *\n * @example\n * Checking if all transactions were successful.\n * ```ts\n * const result = parallelTransactionPlanResult([\n *   successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n *   successfulSingleTransactionPlanResultFromTransaction(messageB, transactionB),\n * ]);\n *\n * const allSuccessful = everyTransactionPlanResult(\n *   result,\n *   (r) => r.kind !== 'single' || r.status === 'successful',\n * );\n * // Returns true because all single results are successful.\n * ```\n *\n * @example\n * Checking if no transactions were canceled.\n * ```ts\n * const result = sequentialTransactionPlanResult([resultA, resultB, resultC]);\n *\n * const noCanceled = everyTransactionPlanResult(\n *   result,\n *   (r) => r.kind !== 'single' || r.status !== 'canceled',\n * );\n * ```\n *\n * @see {@link TransactionPlanResult}\n * @see {@link findTransactionPlanResult}\n * @see {@link transformTransactionPlanResult}\n * @see {@link flattenTransactionPlanResult}\n */\nexport function everyTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(\n    transactionPlanResult: TransactionPlanResult<TContext, TTransactionMessage, TSingle>,\n    predicate: (plan: TransactionPlanResult<TContext, TTransactionMessage, TSingle>) => boolean,\n): boolean {\n    if (!predicate(transactionPlanResult)) {\n        return false;\n    }\n    if (transactionPlanResult.kind === 'single') {\n        return true;\n    }\n    return transactionPlanResult.plans.every(p => everyTransactionPlanResult(p, predicate));\n}\n\n/**\n * Transforms a transaction plan result tree using a bottom-up approach.\n *\n * This function recursively traverses the transaction plan result tree, applying the\n * transformation function to each result. The transformation is applied bottom-up,\n * meaning nested results are transformed first, then the parent results receive\n * the already-transformed children before being transformed themselves.\n *\n * All transformed results are frozen using `Object.freeze` to ensure immutability.\n *\n * @param transactionPlanResult - The transaction plan result tree to transform.\n * @param fn - A function that transforms each result and returns a new result.\n * @return A new transformed transaction plan result tree.\n *\n * @example\n * Converting all canceled results to failed results.\n * ```ts\n * const result = parallelTransactionPlanResult([\n *   successfulSingleTransactionPlanResultFromTransaction(messageA, transactionA),\n *   canceledSingleTransactionPlanResult(messageB),\n * ]);\n *\n * const transformed = transformTransactionPlanResult(result, (r) => {\n *   if (r.kind === 'single' && r.status === 'canceled') {\n *     return failedSingleTransactionPlanResult(r.plannedMessage, new Error('Execution canceled'));\n *   }\n *   return r;\n * });\n * ```\n *\n * @see {@link TransactionPlanResult}\n * @see {@link findTransactionPlanResult}\n * @see {@link everyTransactionPlanResult}\n * @see {@link flattenTransactionPlanResult}\n */\nexport function transformTransactionPlanResult(\n    transactionPlanResult: TransactionPlanResult,\n    fn: (plan: TransactionPlanResult) => TransactionPlanResult,\n): TransactionPlanResult {\n    if (transactionPlanResult.kind === 'single') {\n        return Object.freeze(fn(transactionPlanResult));\n    }\n    return Object.freeze(\n        fn(\n            Object.freeze({\n                ...transactionPlanResult,\n                plans: transactionPlanResult.plans.map(p => transformTransactionPlanResult(p, fn)),\n            }),\n        ),\n    );\n}\n\n/**\n * Retrieves all individual {@link SingleTransactionPlanResult} instances from a transaction plan result tree.\n *\n * This function recursively traverses any nested structure of transaction plan results and extracts\n * all the single results they contain. It's useful when you need to access all the individual\n * transaction results, regardless of their organization in the result tree (parallel or sequential).\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n * @typeParam TSingle - The type of single transaction plan results in this tree\n * @param result - The transaction plan result to extract single results from\n * @returns An array of all single transaction plan results contained in the tree\n *\n * @example\n * ```ts\n * const result = parallelTransactionPlanResult([\n *   sequentialTransactionPlanResult([resultA, resultB]),\n *   nonDivisibleSequentialTransactionPlanResult([resultC, resultD]),\n *   resultE,\n * ]);\n *\n * const singleResults = flattenTransactionPlanResult(result);\n * // Array of `SingleTransactionPlanResult` containing:\n * // resultA, resultB, resultC, resultD and resultE.\n * ```\n *\n * @see {@link TransactionPlanResult}\n * @see {@link findTransactionPlanResult}\n * @see {@link everyTransactionPlanResult}\n * @see {@link transformTransactionPlanResult}\n */\nexport function flattenTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n    TSingle extends SingleTransactionPlanResult<TContext, TTransactionMessage> = SingleTransactionPlanResult<\n        TContext,\n        TTransactionMessage\n    >,\n>(result: TransactionPlanResult<TContext, TTransactionMessage, TSingle>): TSingle[] {\n    if (result.kind === 'single') {\n        return [result];\n    }\n    return result.plans.flatMap(flattenTransactionPlanResult);\n}\n\n/**\n * A summary of a {@link TransactionPlanResult}, categorizing transactions by their execution status.\n * - `successful`: Indicates whether all transactions were successful (i.e., no failed or canceled transactions).\n * - `successfulTransactions`: An array of successful transactions, each including its signature.\n * - `failedTransactions`: An array of failed transactions, each including the error that caused the failure.\n * - `canceledTransactions`: An array of canceled transactions.\n */\nexport type TransactionPlanResultSummary<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n> = Readonly<{\n    canceledTransactions: CanceledSingleTransactionPlanResult<TContext, TTransactionMessage>[];\n    failedTransactions: FailedSingleTransactionPlanResult<TContext, TTransactionMessage>[];\n    successful: boolean;\n    successfulTransactions: SuccessfulSingleTransactionPlanResult<TContext, TTransactionMessage>[];\n}>;\n\n/**\n * Summarize a {@link TransactionPlanResult} into a {@link TransactionPlanResultSummary}.\n *\n * @typeParam TContext - The type of the context object that may be passed along with results\n * @typeParam TTransactionMessage - The type of the transaction message\n * @param result The transaction plan result to summarize\n * @returns A summary of the transaction plan result\n */\nexport function summarizeTransactionPlanResult<\n    TContext extends TransactionPlanResultContext = TransactionPlanResultContext,\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(\n    result: TransactionPlanResult<TContext, TTransactionMessage>,\n): TransactionPlanResultSummary<TContext, TTransactionMessage> {\n    type Out = TransactionPlanResultSummary<TContext, TTransactionMessage>;\n    const successfulTransactions: Out['successfulTransactions'] = [];\n    const failedTransactions: Out['failedTransactions'] = [];\n    const canceledTransactions: Out['canceledTransactions'] = [];\n\n    const flattenedResults = flattenTransactionPlanResult(result);\n\n    for (const singleResult of flattenedResults) {\n        switch (singleResult.status) {\n            case 'successful': {\n                successfulTransactions.push(singleResult);\n                break;\n            }\n            case 'failed': {\n                failedTransactions.push(singleResult);\n                break;\n            }\n            case 'canceled': {\n                canceledTransactions.push(singleResult);\n                break;\n            }\n        }\n    }\n\n    return Object.freeze({\n        canceledTransactions,\n        failedTransactions,\n        successful: failedTransactions.length === 0 && canceledTransactions.length === 0,\n        successfulTransactions,\n    });\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/transaction-plan.ts",
    "content": "import { SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN, SolanaError } from '@solana/errors';\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\n/**\n * A set of transaction messages with constraints on how they can be executed.\n *\n * This is structured as a recursive tree of plans to allow for\n * parallel execution, sequential execution and combinations of both.\n *\n * Namely, the following plans are supported:\n * - {@link SingleTransactionPlan} - A plan that contains a single transaction message.\n *   This is the simplest leaf in this tree.\n * - {@link ParallelTransactionPlan} - A plan that contains other plans that\n *   can be executed in parallel.\n * - {@link SequentialTransactionPlan} - A plan that contains other plans that\n *   must be executed sequentially. It also defines whether the plan is divisible\n *   meaning that transaction messages inside it can be split into separate batches.\n *\n * Helpers are provided for each of these plans to make it easier to create them.\n *\n * @example\n * ```ts\n * const myTransactionPlan: TransactionPlan = parallelTransactionPlan([\n *   sequentialTransactionPlan([messageA, messageB]),\n *   messageC,\n * ]);\n * ```\n *\n * @see {@link SingleTransactionPlan}\n * @see {@link ParallelTransactionPlan}\n * @see {@link SequentialTransactionPlan}\n */\nexport type TransactionPlan = ParallelTransactionPlan | SequentialTransactionPlan | SingleTransactionPlan;\n\n/**\n * A plan wrapping other plans that must be executed sequentially.\n *\n * It also defines whether nested plans are divisible — meaning that\n * the transaction messages inside them can be split into separate batches.\n * When `divisible` is `false`, the transaction messages inside the plan should\n * all be executed atomically — usually in a transaction bundle.\n *\n * You may use the {@link sequentialTransactionPlan} and {@link nonDivisibleSequentialTransactionPlan}\n * helpers to create objects of this type.\n *\n * @example\n * Simple sequential plan with two transaction messages.\n * ```ts\n * const plan = sequentialTransactionPlan([messageA, messageB]);\n * plan satisfies SequentialTransactionPlan;\n * ```\n *\n * @example\n * Non-divisible sequential plan with two transaction messages.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n * plan satisfies SequentialTransactionPlan & { divisible: false };\n * ```\n *\n * @example\n * Sequential plan with nested parallel plans.\n * Here, messages A and B can be executed in parallel, but they must both be finalized\n * before messages C and D can be sent — which can also be executed in parallel.\n * ```ts\n * const plan = sequentialTransactionPlan([\n *   parallelTransactionPlan([messageA, messageB]),\n *   parallelTransactionPlan([messageC, messageD]),\n * ]);\n * ```\n *\n * @see {@link sequentialTransactionPlan}\n * @see {@link nonDivisibleSequentialTransactionPlan}\n */\nexport type SequentialTransactionPlan = Readonly<{\n    divisible: boolean;\n    kind: 'sequential';\n    planType: 'transactionPlan';\n    plans: TransactionPlan[];\n}>;\n\n/**\n * A plan wrapping other plans that can be executed in parallel.\n *\n * This means direct children of this plan can be executed in separate\n * parallel transactions without causing any side effects.\n * However, the children themselves can define additional constraints\n * for that specific branch of the tree — such as the {@link SequentialTransactionPlan}.\n *\n * You may use the {@link parallelTransactionPlan} helper to create objects of this type.\n *\n * @example\n * Simple parallel plan with two transaction messages.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB]);\n * plan satisfies ParallelTransactionPlan;\n * ```\n *\n * @example\n * Parallel plan with nested sequential plans.\n * Here, messages A and B must be executed sequentially and so must messages C and D,\n * but both pairs can be executed in parallel.\n * ```ts\n * const plan = parallelTransactionPlan([\n *   sequentialTransactionPlan([messageA, messageB]),\n *   sequentialTransactionPlan([messageC, messageD]),\n * ]);\n * plan satisfies ParallelTransactionPlan;\n * ```\n *\n * @see {@link parallelTransactionPlan}\n */\nexport type ParallelTransactionPlan = Readonly<{\n    kind: 'parallel';\n    planType: 'transactionPlan';\n    plans: TransactionPlan[];\n}>;\n\n/**\n * A plan that contains a single transaction message.\n *\n * This is a simple transaction message wrapper that transforms a message into a plan.\n *\n * You may use the {@link singleTransactionPlan} helper to create objects of this type.\n *\n * @example\n * ```ts\n * const plan = singleTransactionPlan(transactionMessage);\n * plan satisfies SingleTransactionPlan;\n * ```\n *\n * @see {@link singleTransactionPlan}\n */\nexport type SingleTransactionPlan<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n> = Readonly<{\n    kind: 'single';\n    message: TTransactionMessage;\n    planType: 'transactionPlan';\n}>;\n\n/**\n * Creates a {@link ParallelTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = parallelTransactionPlan([\n *   singleTransactionPlan(messageA),\n *   singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link ParallelTransactionPlan}\n */\nexport function parallelTransactionPlan(\n    plans: (TransactionPlan | (TransactionMessage & TransactionMessageWithFeePayer))[],\n): ParallelTransactionPlan {\n    return Object.freeze({ kind: 'parallel', planType: 'transactionPlan', plans: parseSingleTransactionPlans(plans) });\n}\n\n/**\n * Creates a divisible {@link SequentialTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = sequentialTransactionPlan([\n *   singleTransactionPlan(messageA),\n *   singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = sequentialTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n */\nexport function sequentialTransactionPlan(\n    plans: (TransactionPlan | (TransactionMessage & TransactionMessageWithFeePayer))[],\n): SequentialTransactionPlan & { divisible: true } {\n    return Object.freeze({\n        divisible: true,\n        kind: 'sequential',\n        planType: 'transactionPlan',\n        plans: parseSingleTransactionPlans(plans),\n    });\n}\n\n/**\n * Creates a non-divisible {@link SequentialTransactionPlan} from an array of nested plans.\n *\n * It can accept {@link TransactionMessage} objects directly, which will be wrapped\n * in {@link SingleTransactionPlan | SingleTransactionPlans} automatically.\n *\n * @example\n * Using explicit {@link SingleTransactionPlan | SingleTransactionPlans}.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([\n *   singleTransactionPlan(messageA),\n *   singleTransactionPlan(messageB),\n * ]);\n * ```\n *\n * @example\n * Using {@link TransactionMessage | TransactionMessages} directly.\n * ```ts\n * const plan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n */\nexport function nonDivisibleSequentialTransactionPlan(\n    plans: (TransactionPlan | (TransactionMessage & TransactionMessageWithFeePayer))[],\n): SequentialTransactionPlan & { divisible: false } {\n    return Object.freeze({\n        divisible: false,\n        kind: 'sequential',\n        planType: 'transactionPlan',\n        plans: parseSingleTransactionPlans(plans),\n    });\n}\n\n/**\n * Creates a {@link SingleTransactionPlan} from a {@link TransactionMessage} object.\n *\n * @example\n * ```ts\n * const plan = singleTransactionPlan(transactionMessage);\n * plan satisfies SingleTransactionPlan;\n * ```\n *\n * @see {@link SingleTransactionPlan}\n */\nexport function singleTransactionPlan<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer = TransactionMessage &\n        TransactionMessageWithFeePayer,\n>(transactionMessage: TTransactionMessage): SingleTransactionPlan<TTransactionMessage> {\n    return Object.freeze({ kind: 'single', message: transactionMessage, planType: 'transactionPlan' });\n}\n\nfunction parseSingleTransactionPlans(\n    plans: (TransactionPlan | (TransactionMessage & TransactionMessageWithFeePayer))[],\n): TransactionPlan[] {\n    return plans.map(plan => ('kind' in plan ? plan : singleTransactionPlan(plan)));\n}\n\n/**\n * Checks if the given value is a {@link TransactionPlan}.\n *\n * This type guard checks the `planType` property to determine if the value\n * is a transaction plan. This is useful when you have a value that could be\n * an {@link InstructionPlan}, {@link TransactionPlan}, or {@link TransactionPlanResult}\n * and need to narrow the type.\n *\n * @param value - The value to check.\n * @return `true` if the value is a transaction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * function processItem(item: InstructionPlan | TransactionPlan | TransactionPlanResult) {\n *   if (isTransactionPlan(item)) {\n *     // item is narrowed to TransactionPlan\n *     console.log(item.kind);\n *   }\n * }\n * ```\n *\n * @see {@link TransactionPlan}\n * @see {@link isInstructionPlan}\n * @see {@link isTransactionPlanResult}\n */\nexport function isTransactionPlan(value: unknown): value is TransactionPlan {\n    return (\n        typeof value === 'object' &&\n        value !== null &&\n        'planType' in value &&\n        typeof value.planType === 'string' &&\n        value.planType === 'transactionPlan'\n    );\n}\n\n/**\n * Checks if the given transaction plan is a {@link SingleTransactionPlan}.\n *\n * @param plan - The transaction plan to check.\n * @return `true` if the plan is a single transaction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: TransactionPlan = singleTransactionPlan(transactionMessage);\n *\n * if (isSingleTransactionPlan(plan)) {\n *   console.log(plan.message); // TypeScript knows this is a SingleTransactionPlan.\n * }\n * ```\n *\n * @see {@link SingleTransactionPlan}\n * @see {@link assertIsSingleTransactionPlan}\n */\nexport function isSingleTransactionPlan(plan: TransactionPlan): plan is SingleTransactionPlan {\n    return plan.kind === 'single';\n}\n\n/**\n * Asserts that the given transaction plan is a {@link SingleTransactionPlan}.\n *\n * @param plan - The transaction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN` if the plan is not a single transaction plan.\n *\n * @example\n * ```ts\n * const plan: TransactionPlan = singleTransactionPlan(transactionMessage);\n *\n * assertIsSingleTransactionPlan(plan);\n * console.log(plan.message); // TypeScript knows this is a SingleTransactionPlan.\n * ```\n *\n * @see {@link SingleTransactionPlan}\n * @see {@link isSingleTransactionPlan}\n */\nexport function assertIsSingleTransactionPlan(plan: TransactionPlan): asserts plan is SingleTransactionPlan {\n    if (!isSingleTransactionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN, {\n            actualKind: plan.kind,\n            expectedKind: 'single',\n            transactionPlan: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan is a {@link SequentialTransactionPlan}.\n *\n * @param plan - The transaction plan to check.\n * @return `true` if the plan is a sequential transaction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: TransactionPlan = sequentialTransactionPlan([messageA, messageB]);\n *\n * if (isSequentialTransactionPlan(plan)) {\n *   console.log(plan.divisible); // TypeScript knows this is a SequentialTransactionPlan.\n * }\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n * @see {@link assertIsSequentialTransactionPlan}\n */\nexport function isSequentialTransactionPlan(plan: TransactionPlan): plan is SequentialTransactionPlan {\n    return plan.kind === 'sequential';\n}\n\n/**\n * Asserts that the given transaction plan is a {@link SequentialTransactionPlan}.\n *\n * @param plan - The transaction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN` if the plan is not a sequential transaction plan.\n *\n * @example\n * ```ts\n * const plan: TransactionPlan = sequentialTransactionPlan([messageA, messageB]);\n *\n * assertIsSequentialTransactionPlan(plan);\n * console.log(plan.divisible); // TypeScript knows this is a SequentialTransactionPlan.\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n * @see {@link isSequentialTransactionPlan}\n */\nexport function assertIsSequentialTransactionPlan(plan: TransactionPlan): asserts plan is SequentialTransactionPlan {\n    if (!isSequentialTransactionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN, {\n            actualKind: plan.kind,\n            expectedKind: 'sequential',\n            transactionPlan: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan is a non-divisible {@link SequentialTransactionPlan}.\n *\n * A non-divisible sequential plan requires all its transaction messages to be executed\n * atomically — usually in a transaction bundle.\n *\n * @param plan - The transaction plan to check.\n * @return `true` if the plan is a non-divisible sequential transaction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: TransactionPlan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n *\n * if (isNonDivisibleSequentialTransactionPlan(plan)) {\n *   // All transaction messages must be executed atomically.\n * }\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n * @see {@link assertIsNonDivisibleSequentialTransactionPlan}\n */\nexport function isNonDivisibleSequentialTransactionPlan(\n    plan: TransactionPlan,\n): plan is SequentialTransactionPlan & { divisible: false } {\n    return plan.kind === 'sequential' && plan.divisible === false;\n}\n\n/**\n * Asserts that the given transaction plan is a non-divisible {@link SequentialTransactionPlan}.\n *\n * A non-divisible sequential plan requires all its transaction messages to be executed\n * atomically — usually in a transaction bundle.\n *\n * @param plan - The transaction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN` if the plan is not a non-divisible sequential transaction plan.\n *\n * @example\n * ```ts\n * const plan: TransactionPlan = nonDivisibleSequentialTransactionPlan([messageA, messageB]);\n *\n * assertIsNonDivisibleSequentialTransactionPlan(plan);\n * // All transaction messages must be executed atomically.\n * ```\n *\n * @see {@link SequentialTransactionPlan}\n * @see {@link isNonDivisibleSequentialTransactionPlan}\n */\nexport function assertIsNonDivisibleSequentialTransactionPlan(\n    plan: TransactionPlan,\n): asserts plan is SequentialTransactionPlan & { divisible: false } {\n    if (!isNonDivisibleSequentialTransactionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN, {\n            actualKind: plan.kind === 'sequential' ? 'divisible sequential' : plan.kind,\n            expectedKind: 'non-divisible sequential',\n            transactionPlan: plan,\n        });\n    }\n}\n\n/**\n * Checks if the given transaction plan is a {@link ParallelTransactionPlan}.\n *\n * @param plan - The transaction plan to check.\n * @return `true` if the plan is a parallel transaction plan, `false` otherwise.\n *\n * @example\n * ```ts\n * const plan: TransactionPlan = parallelTransactionPlan([messageA, messageB]);\n *\n * if (isParallelTransactionPlan(plan)) {\n *   console.log(plan.plans.length); // TypeScript knows this is a ParallelTransactionPlan.\n * }\n * ```\n *\n * @see {@link ParallelTransactionPlan}\n * @see {@link assertIsParallelTransactionPlan}\n */\nexport function isParallelTransactionPlan(plan: TransactionPlan): plan is ParallelTransactionPlan {\n    return plan.kind === 'parallel';\n}\n\n/**\n * Asserts that the given transaction plan is a {@link ParallelTransactionPlan}.\n *\n * @param plan - The transaction plan to assert.\n * @throws Throws a {@link SolanaError} with code\n * `SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN` if the plan is not a parallel transaction plan.\n *\n * @example\n * ```ts\n * const plan: TransactionPlan = parallelTransactionPlan([messageA, messageB]);\n *\n * assertIsParallelTransactionPlan(plan);\n * console.log(plan.plans.length); // TypeScript knows this is a ParallelTransactionPlan.\n * ```\n *\n * @see {@link ParallelTransactionPlan}\n * @see {@link isParallelTransactionPlan}\n */\nexport function assertIsParallelTransactionPlan(plan: TransactionPlan): asserts plan is ParallelTransactionPlan {\n    if (!isParallelTransactionPlan(plan)) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__UNEXPECTED_TRANSACTION_PLAN, {\n            actualKind: plan.kind,\n            expectedKind: 'parallel',\n            transactionPlan: plan,\n        });\n    }\n}\n\n/**\n * Retrieves all individual {@link SingleTransactionPlan} instances from a transaction plan tree.\n *\n * This function recursively traverses any nested structure of transaction plans and extracts\n * all the single transaction plans they contain. It's useful when you need to access all\n * the actual transaction messages that will be executed, regardless of their organization\n * in the plan tree (parallel or sequential).\n *\n * @param transactionPlan - The transaction plan to extract single plans from\n * @returns An array of all single transaction plans contained in the tree\n *\n * @example\n * ```ts\n * const plan = parallelTransactionPlan([\n *   sequentialTransactionPlan([messageA, messageB]),\n *   nonDivisibleSequentialTransactionPlan([messageC, messageD]),\n *   messageE,\n * ]);\n *\n * const singlePlans = flattenTransactionPlan(plan);\n * // Array of `SingleTransactionPlan` containing:\n * // messageA, messageB, messageC and messageD.\n *\n * @see {@link TransactionPlan}\n * @see {@link findTransactionPlan}\n * @see {@link everyTransactionPlan}\n * @see {@link transformTransactionPlan}\n * ```\n */\nexport function flattenTransactionPlan(transactionPlan: TransactionPlan): SingleTransactionPlan[] {\n    if (transactionPlan.kind === 'single') {\n        return [transactionPlan];\n    }\n    return transactionPlan.plans.flatMap(flattenTransactionPlan);\n}\n\n/**\n * Finds the first transaction plan in the tree that matches the given predicate.\n *\n * This function performs a depth-first search through the transaction plan tree,\n * returning the first plan that satisfies the predicate. It checks the root plan\n * first, then recursively searches through nested plans.\n *\n * @param transactionPlan - The transaction plan tree to search.\n * @param predicate - A function that returns `true` for the plan to find.\n * @return The first matching transaction plan, or `undefined` if no match is found.\n *\n * @example\n * Finding a non-divisible sequential plan.\n * ```ts\n * const plan = parallelTransactionPlan([\n *   sequentialTransactionPlan([messageA, messageB]),\n *   nonDivisibleSequentialTransactionPlan([messageC, messageD]),\n * ]);\n *\n * const nonDivisible = findTransactionPlan(\n *   plan,\n *   (p) => p.kind === 'sequential' && !p.divisible,\n * );\n * // Returns the non-divisible sequential plan containing messageC and messageD.\n * ```\n *\n * @example\n * Finding a specific single transaction plan.\n * ```ts\n * const plan = sequentialTransactionPlan([messageA, messageB, messageC]);\n *\n * const found = findTransactionPlan(\n *   plan,\n *   (p) => p.kind === 'single' && p.message === messageB,\n * );\n * // Returns the SingleTransactionPlan wrapping messageB.\n * ```\n *\n * @see {@link TransactionPlan}\n * @see {@link everyTransactionPlan}\n * @see {@link transformTransactionPlan}\n * @see {@link flattenTransactionPlan}\n */\nexport function findTransactionPlan(\n    transactionPlan: TransactionPlan,\n    predicate: (plan: TransactionPlan) => boolean,\n): TransactionPlan | undefined {\n    if (predicate(transactionPlan)) {\n        return transactionPlan;\n    }\n    if (transactionPlan.kind === 'single') {\n        return undefined;\n    }\n    for (const subPlan of transactionPlan.plans) {\n        const foundPlan = findTransactionPlan(subPlan, predicate);\n        if (foundPlan) {\n            return foundPlan;\n        }\n    }\n    return undefined;\n}\n\n/**\n * Checks if every transaction plan in the tree satisfies the given predicate.\n *\n * This function performs a depth-first traversal through the transaction plan tree,\n * returning `true` only if the predicate returns `true` for every plan in the tree\n * (including the root plan and all nested plans).\n *\n * @param transactionPlan - The transaction plan tree to check.\n * @param predicate - A function that returns `true` if the plan satisfies the condition.\n * @return `true` if every plan in the tree satisfies the predicate, `false` otherwise.\n *\n * @example\n * Checking if all plans are divisible.\n * ```ts\n * const plan = sequentialTransactionPlan([\n *   parallelTransactionPlan([messageA, messageB]),\n *   sequentialTransactionPlan([messageC, messageD]),\n * ]);\n *\n * const allDivisible = everyTransactionPlan(\n *   plan,\n *   (p) => p.kind !== 'sequential' || p.divisible,\n * );\n * // Returns true because all sequential plans are divisible.\n * ```\n *\n * @example\n * Checking if all single plans have a specific fee payer.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB, messageC]);\n *\n * const allUseSameFeePayer = everyTransactionPlan(\n *   plan,\n *   (p) => p.kind !== 'single' || p.message.feePayer.address === myFeePayer,\n * );\n * ```\n *\n * @see {@link TransactionPlan}\n * @see {@link findTransactionPlan}\n * @see {@link transformTransactionPlan}\n * @see {@link flattenTransactionPlan}\n */\nexport function everyTransactionPlan(\n    transactionPlan: TransactionPlan,\n    predicate: (plan: TransactionPlan) => boolean,\n): boolean {\n    if (!predicate(transactionPlan)) {\n        return false;\n    }\n    if (transactionPlan.kind === 'single') {\n        return true;\n    }\n    return transactionPlan.plans.every(p => everyTransactionPlan(p, predicate));\n}\n\n/**\n * Transforms a transaction plan tree using a bottom-up approach.\n *\n * This function recursively traverses the transaction plan tree, applying the\n * transformation function to each plan. The transformation is applied bottom-up,\n * meaning nested plans are transformed first, then the parent plans receive\n * the already-transformed children before being transformed themselves.\n *\n * All transformed plans are frozen using `Object.freeze` to ensure immutability.\n *\n * @param transactionPlan - The transaction plan tree to transform.\n * @param fn - A function that transforms each plan and returns a new plan.\n * @return A new transformed transaction plan tree.\n *\n * @example\n * Removing parallelism by converting parallel plans to sequential.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB, messageC]);\n *\n * const transformed = transformTransactionPlan(plan, (p) => {\n *   if (p.kind === 'parallel') {\n *     return sequentialTransactionPlan(p.plans);\n *   }\n *   return p;\n * });\n * ```\n *\n * @example\n * Updating the fee payer on all transaction messages.\n * ```ts\n * const plan = parallelTransactionPlan([messageA, messageB]);\n *\n * const transformed = transformTransactionPlan(plan, (p) => {\n *   if (p.kind === 'single') {\n *     return singleTransactionPlan({ ...p.message, feePayer: newFeePayer });\n *   }\n *   return p;\n * });\n * ```\n *\n * @see {@link TransactionPlan}\n * @see {@link findTransactionPlan}\n * @see {@link everyTransactionPlan}\n * @see {@link flattenTransactionPlan}\n */\nexport function transformTransactionPlan(\n    transactionPlan: TransactionPlan,\n    fn: (plan: TransactionPlan) => TransactionPlan,\n): TransactionPlan {\n    if (transactionPlan.kind === 'single') {\n        return Object.freeze(fn(transactionPlan));\n    }\n    return Object.freeze(\n        fn(\n            Object.freeze({\n                ...transactionPlan,\n                plans: transactionPlan.plans.map(p => transformTransactionPlan(p, fn)),\n            }),\n        ),\n    );\n}\n"
  },
  {
    "path": "packages/instruction-plans/src/transaction-planner.ts",
    "content": "import {\n    isSolanaError,\n    SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN,\n    SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN,\n    SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND,\n    SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SolanaError,\n} from '@solana/errors';\nimport { getAbortablePromise } from '@solana/promises';\nimport {\n    appendTransactionMessageInstructions,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { getTransactionMessageSize, getTransactionMessageSizeLimit } from '@solana/transactions';\n\nimport {\n    InstructionPlan,\n    MessagePackerInstructionPlan,\n    ParallelInstructionPlan,\n    SequentialInstructionPlan,\n    SingleInstructionPlan,\n} from './instruction-plan';\nimport {\n    flattenTransactionPlan,\n    nonDivisibleSequentialTransactionPlan,\n    parallelTransactionPlan,\n    sequentialTransactionPlan,\n    SingleTransactionPlan,\n    singleTransactionPlan,\n    TransactionPlan,\n} from './transaction-plan';\n\n/**\n * Plans one or more transactions according to the provided instruction plan.\n *\n * @param instructionPlan - The instruction plan to be planned and executed.\n * @param config - Optional configuration object that can include an `AbortSignal` to cancel the planning process.\n *\n * @see {@link InstructionPlan}\n * @see {@link TransactionPlan}\n */\nexport type TransactionPlanner = (\n    instructionPlan: InstructionPlan,\n    config?: { abortSignal?: AbortSignal },\n) => Promise<TransactionPlan>;\n\ntype Mutable<T> = { -readonly [P in keyof T]: T[P] };\n\ntype CreateTransactionMessage = (config?: {\n    abortSignal?: AbortSignal;\n}) =>\n    | Promise<TransactionMessage & TransactionMessageWithFeePayer>\n    | (TransactionMessage & TransactionMessageWithFeePayer);\n\ntype OnTransactionMessageUpdated = (\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer,\n    config?: { abortSignal?: AbortSignal },\n) =>\n    | Promise<TransactionMessage & TransactionMessageWithFeePayer>\n    | (TransactionMessage & TransactionMessageWithFeePayer);\n\n/**\n * Configuration object for creating a new transaction planner.\n *\n * @see {@link createTransactionPlanner}\n */\nexport type TransactionPlannerConfig = {\n    /** Called whenever a new transaction message is needed. */\n    createTransactionMessage: CreateTransactionMessage;\n    /**\n     * Called whenever a transaction message is updated — e.g. new instructions were added.\n     * This function must return the updated transaction message back — even if no changes were made.\n     */\n    onTransactionMessageUpdated?: OnTransactionMessageUpdated;\n};\n\n/**\n * Creates a new transaction planner based on the provided configuration.\n *\n * At the very least, the `createTransactionMessage` function must be provided.\n * This function is used to create new transaction messages whenever needed.\n *\n * Additionally, the `onTransactionMessageUpdated` function can be provided\n * to update transaction messages during the planning process. This function will\n * be called whenever a transaction message is updated, e.g. when new instructions\n * are added to a transaction message. It accepts the updated transaction message\n * and must return a transaction message back, even if no changes were made.\n *\n * @example\n * ```ts\n * const transactionPlanner = createTransactionPlanner({\n *   createTransactionMessage: () => pipe(\n *     createTransactionMessage({ version: 0 }),\n *     message => setTransactionMessageFeePayerSigner(mySigner, message),\n *   )\n * });\n * ```\n *\n * @see {@link TransactionPlannerConfig}\n */\nexport function createTransactionPlanner(config: TransactionPlannerConfig): TransactionPlanner {\n    return async (instructionPlan, { abortSignal } = {}): Promise<TransactionPlan> => {\n        const plan = await traverse(instructionPlan, {\n            abortSignal,\n            createTransactionMessage: config.createTransactionMessage,\n            onTransactionMessageUpdated: config.onTransactionMessageUpdated ?? (msg => msg),\n            parent: null,\n            parentCandidates: [],\n        });\n\n        if (!plan) {\n            throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__EMPTY_INSTRUCTION_PLAN);\n        }\n\n        return freezeTransactionPlan(plan);\n    };\n}\n\ntype MutableTransactionPlan = Mutable<TransactionPlan>;\ntype MutableSingleTransactionPlan = Mutable<SingleTransactionPlan>;\n\ntype TraverseContext = {\n    abortSignal?: AbortSignal;\n    createTransactionMessage: CreateTransactionMessage;\n    onTransactionMessageUpdated: OnTransactionMessageUpdated;\n    parent: InstructionPlan | null;\n    parentCandidates: MutableSingleTransactionPlan[];\n};\n\nasync function traverse(\n    instructionPlan: InstructionPlan,\n    context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n    context.abortSignal?.throwIfAborted();\n    const kind = instructionPlan.kind;\n    switch (kind) {\n        case 'sequential':\n            return await traverseSequential(instructionPlan, context);\n        case 'parallel':\n            return await traverseParallel(instructionPlan, context);\n        case 'single':\n            return await traverseSingle(instructionPlan, context);\n        case 'messagePacker':\n            return await traverseMessagePacker(instructionPlan, context);\n        default:\n            instructionPlan satisfies never;\n            throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, { kind });\n    }\n}\n\nasync function traverseSequential(\n    instructionPlan: SequentialInstructionPlan,\n    context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n    let candidate: MutableSingleTransactionPlan | null = null;\n\n    // Check if the sequential plan must fit entirely in its parent candidates\n    // due to constraints like being inside a parallel plan or not being divisible.\n    const mustEntirelyFitInParentCandidate =\n        context.parent && (context.parent.kind === 'parallel' || !instructionPlan.divisible);\n\n    // If so, try to fit the entire plan inside one of the parent candidates.\n    if (mustEntirelyFitInParentCandidate) {\n        const candidate = await selectAndMutateCandidate(context, context.parentCandidates, message =>\n            fitEntirePlanInsideMessage(instructionPlan, message),\n        );\n        // If that's possible, we the candidate is mutated and we can return null.\n        // Otherwise, we proceed with the normal traversal and no parent candidate.\n        if (candidate) {\n            return null;\n        }\n    } else {\n        // Otherwise, we can use the first parent candidate, if any,\n        // since we know it must be a divisible sequential plan.\n        candidate = context.parentCandidates.length > 0 ? context.parentCandidates[0] : null;\n    }\n\n    const transactionPlans: TransactionPlan[] = [];\n    for (const plan of instructionPlan.plans) {\n        const transactionPlan = await traverse(plan, {\n            ...context,\n            parent: instructionPlan,\n            parentCandidates: candidate ? [candidate] : [],\n        });\n        if (transactionPlan) {\n            candidate = getSequentialCandidate(transactionPlan);\n            const newPlans =\n                transactionPlan.kind === 'sequential' && (transactionPlan.divisible || !instructionPlan.divisible)\n                    ? transactionPlan.plans\n                    : [transactionPlan];\n            transactionPlans.push(...newPlans);\n        }\n    }\n\n    // Wrap in a sequential plan or simplify.\n    if (transactionPlans.length === 1) {\n        return transactionPlans[0];\n    }\n    if (transactionPlans.length === 0) {\n        return null;\n    }\n    return {\n        divisible: instructionPlan.divisible,\n        kind: 'sequential',\n        planType: 'transactionPlan',\n        plans: transactionPlans,\n    };\n}\n\nasync function traverseParallel(\n    instructionPlan: ParallelInstructionPlan,\n    context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n    const candidates: MutableSingleTransactionPlan[] = [...context.parentCandidates];\n    const transactionPlans: TransactionPlan[] = [];\n\n    // Reorder children so message packer plans are last.\n    const sortedChildren = Array.from(instructionPlan.plans).sort(\n        (a, b) => Number(a.kind === 'messagePacker') - Number(b.kind === 'messagePacker'),\n    );\n\n    for (const plan of sortedChildren) {\n        const transactionPlan = await traverse(plan, {\n            ...context,\n            parent: instructionPlan,\n            parentCandidates: candidates,\n        });\n        if (transactionPlan) {\n            candidates.push(...getParallelCandidates(transactionPlan));\n            const newPlans = transactionPlan.kind === 'parallel' ? transactionPlan.plans : [transactionPlan];\n            transactionPlans.push(...newPlans);\n        }\n    }\n\n    // Wrap in a parallel plan or simplify.\n    if (transactionPlans.length === 1) {\n        return transactionPlans[0];\n    }\n    if (transactionPlans.length === 0) {\n        return null;\n    }\n    return { kind: 'parallel', planType: 'transactionPlan', plans: transactionPlans };\n}\n\nasync function traverseSingle(\n    instructionPlan: SingleInstructionPlan,\n    context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n    const predicate = (message: TransactionMessage & TransactionMessageWithFeePayer) =>\n        appendTransactionMessageInstructions([instructionPlan.instruction], message);\n    const candidate = await selectAndMutateCandidate(context, context.parentCandidates, predicate);\n    if (candidate) {\n        return null;\n    }\n    const message = await createNewMessage(context, predicate);\n    return { kind: 'single', message, planType: 'transactionPlan' };\n}\n\nasync function traverseMessagePacker(\n    instructionPlan: MessagePackerInstructionPlan,\n    context: TraverseContext,\n): Promise<MutableTransactionPlan | null> {\n    const messagePacker = instructionPlan.getMessagePacker();\n    const transactionPlans: SingleTransactionPlan[] = [];\n    const candidates = [...context.parentCandidates];\n\n    while (!messagePacker.done()) {\n        const candidate = await selectAndMutateCandidate(context, candidates, messagePacker.packMessageToCapacity);\n        if (!candidate) {\n            const message = await createNewMessage(context, messagePacker.packMessageToCapacity);\n            const newPlan: MutableSingleTransactionPlan = { kind: 'single', message, planType: 'transactionPlan' };\n            transactionPlans.push(newPlan);\n        }\n    }\n\n    if (transactionPlans.length === 1) {\n        return transactionPlans[0];\n    }\n    if (transactionPlans.length === 0) {\n        return null;\n    }\n    if (context.parent?.kind === 'parallel') {\n        return { kind: 'parallel', planType: 'transactionPlan', plans: transactionPlans };\n    }\n    return {\n        divisible: context.parent?.kind === 'sequential' ? context.parent.divisible : true,\n        kind: 'sequential',\n        planType: 'transactionPlan',\n        plans: transactionPlans,\n    };\n}\n\nfunction getSequentialCandidate(latestPlan: MutableTransactionPlan): MutableSingleTransactionPlan | null {\n    if (latestPlan.kind === 'single') {\n        return latestPlan;\n    }\n    if (latestPlan.kind === 'sequential' && latestPlan.plans.length > 0) {\n        return getSequentialCandidate(latestPlan.plans[latestPlan.plans.length - 1]);\n    }\n    return null;\n}\n\nfunction getParallelCandidates(latestPlan: TransactionPlan): MutableSingleTransactionPlan[] {\n    return flattenTransactionPlan(latestPlan);\n}\n\nasync function selectAndMutateCandidate(\n    context: Pick<TraverseContext, 'abortSignal' | 'onTransactionMessageUpdated'>,\n    candidates: MutableSingleTransactionPlan[],\n    predicate: (\n        message: TransactionMessage & TransactionMessageWithFeePayer,\n    ) => TransactionMessage & TransactionMessageWithFeePayer,\n): Promise<MutableSingleTransactionPlan | null> {\n    for (const candidate of candidates) {\n        try {\n            const message = await getAbortablePromise(\n                Promise.resolve(\n                    context.onTransactionMessageUpdated(predicate(candidate.message), {\n                        abortSignal: context.abortSignal,\n                    }),\n                ),\n                context.abortSignal,\n            );\n            if (getTransactionMessageSize(message) <= getTransactionMessageSizeLimit(message)) {\n                candidate.message = message;\n                return candidate;\n            }\n        } catch (error) {\n            if (\n                isSolanaError(error, SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN) ||\n                isSolanaError(error, SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES) ||\n                isSolanaError(error, SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION) ||\n                isSolanaError(error, SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS) ||\n                isSolanaError(error, SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES)\n            ) {\n                // Try the next candidate.\n            } else {\n                throw error;\n            }\n        }\n    }\n    return null;\n}\n\nasync function createNewMessage(\n    context: Pick<TraverseContext, 'abortSignal' | 'createTransactionMessage' | 'onTransactionMessageUpdated'>,\n    predicate: (\n        message: TransactionMessage & TransactionMessageWithFeePayer,\n    ) => TransactionMessage & TransactionMessageWithFeePayer,\n): Promise<TransactionMessage & TransactionMessageWithFeePayer> {\n    const newMessage = await getAbortablePromise(\n        Promise.resolve(context.createTransactionMessage({ abortSignal: context.abortSignal })),\n        context.abortSignal,\n    );\n    const updatedMessage = await getAbortablePromise(\n        Promise.resolve(\n            context.onTransactionMessageUpdated(predicate(newMessage), { abortSignal: context.abortSignal }),\n        ),\n        context.abortSignal,\n    );\n    const updatedMessageSize = getTransactionMessageSize(updatedMessage);\n    if (updatedMessageSize > getTransactionMessageSizeLimit(updatedMessage)) {\n        const newMessageSize = getTransactionMessageSize(newMessage);\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n            numBytesRequired: updatedMessageSize - newMessageSize,\n            numFreeBytes: getTransactionMessageSizeLimit(newMessage) - newMessageSize,\n        });\n    }\n    return updatedMessage;\n}\n\nfunction freezeTransactionPlan(plan: MutableTransactionPlan): TransactionPlan {\n    const kind = plan.kind;\n    switch (kind) {\n        case 'single':\n            return singleTransactionPlan(plan.message);\n        case 'sequential':\n            return plan.divisible\n                ? sequentialTransactionPlan(plan.plans.map(freezeTransactionPlan))\n                : nonDivisibleSequentialTransactionPlan(plan.plans.map(freezeTransactionPlan));\n        case 'parallel':\n            return parallelTransactionPlan(plan.plans.map(freezeTransactionPlan));\n        default:\n            plan satisfies never;\n            throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_TRANSACTION_PLAN_KIND, { kind });\n    }\n}\n\nfunction fitEntirePlanInsideMessage(\n    instructionPlan: InstructionPlan,\n    message: TransactionMessage & TransactionMessageWithFeePayer,\n): TransactionMessage & TransactionMessageWithFeePayer {\n    let newMessage: TransactionMessage & TransactionMessageWithFeePayer = message;\n\n    const kind = instructionPlan.kind;\n    switch (kind) {\n        case 'sequential':\n        case 'parallel':\n            for (const plan of instructionPlan.plans) {\n                newMessage = fitEntirePlanInsideMessage(plan, newMessage);\n            }\n            return newMessage;\n        case 'single':\n            newMessage = appendTransactionMessageInstructions([instructionPlan.instruction], message);\n            // eslint-disable-next-line no-case-declarations\n            const newMessageSize = getTransactionMessageSize(newMessage);\n            if (newMessageSize > getTransactionMessageSizeLimit(newMessage)) {\n                const baseMessageSize = getTransactionMessageSize(message);\n                throw new SolanaError(SOLANA_ERROR__INSTRUCTION_PLANS__MESSAGE_CANNOT_ACCOMMODATE_PLAN, {\n                    numBytesRequired: newMessageSize - baseMessageSize,\n                    numFreeBytes: getTransactionMessageSizeLimit(message) - baseMessageSize,\n                });\n            }\n            return newMessage;\n        case 'messagePacker':\n            // eslint-disable-next-line no-case-declarations\n            const messagePacker = instructionPlan.getMessagePacker();\n            while (!messagePacker.done()) {\n                newMessage = messagePacker.packMessageToCapacity(newMessage);\n            }\n            return newMessage;\n        default:\n            instructionPlan satisfies never;\n            throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__INVALID_INSTRUCTION_PLAN_KIND, { kind });\n    }\n}\n"
  },
  {
    "path": "packages/instruction-plans/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/instruction-plans/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": []\n    },\n    \"display\": \"@solana/instruction-plans\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/instruction-plans/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/instructions/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/instructions/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/instructions/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/instructions/CHANGELOG.md",
    "content": "# @solana/instructions\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/codecs-core@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/codecs-core@6.8.0\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.7.0\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/codecs-core@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.5.0\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.3.1\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/codecs-core@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-core@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/codecs-core@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.1\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.0\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/codecs-core@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/codecs-core@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-core@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.3.0\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-core@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/codecs-core@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/codecs-core@4.0.0\n\n## 3.0.0\n\n### Major Changes\n\n- [#691](https://github.com/anza-xyz/kit/pull/691) [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: Removes the following deprecated types: `IAccountMeta`, `IAccountLookupMeta`, `IInstruction`, `IInstructionWithAccounts` and `IInstructionWithData`.\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-core@3.0.0\n\n## 2.3.0\n\n### Minor Changes\n\n- [#488](https://github.com/anza-xyz/kit/pull/488) [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove the `I` prefix on the following types: `IInstruction`, `IInstructionWithAccounts`, `IInstructionWithData`, `IInstructionWithSigners`, `IAccountMeta`, `IAccountLookupMeta` and `IAccountSignerMeta`. The old names are kept as aliases but marked as deprecated.\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/codecs-core@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.1\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-core@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Change `data` field of transaction message instructions to use `ReadonlyUint8Array`\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/codecs-core@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/instructions/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/instructions/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/instructions?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/instructions?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/instructions\n\n# @solana/instructions\n\nThis package contains types for creating transaction instructions. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Types\n\n### `AccountRole`\n\nThe purpose for which an account participates in a transaction is described by the `AccountRole` type. Every account that participates in a transaction can be read from, but only ones that you mark as writable may be written to, and only ones that you indicate must sign the transaction will gain the privileges associated with signers at runtime.\n\n|                               | `isSigner` | `isWritable` |\n| ----------------------------- | ---------- | ------------ |\n| `AccountRole.READONLY`        | &#x274c;   | &#x274c;     |\n| `AccountRole.WRITABLE`        | &#x274c;   | &#x2705;     |\n| `AccountRole.READONLY_SIGNER` | &#x2705;   | &#x274c;     |\n| `AccountRole.WRITABLE_SIGNER` | &#x2705;   | &#x2705;     |\n\n### `AccountMeta<TAddress>`\n\nThis type represents an account's address and metadata about its mutability and whether it must be a signer of the transaction.\n\nTypically, you will use one of its subtypes.\n\n|                                   | `role`                        | `isSigner` | `isWritable` |\n| --------------------------------- | ----------------------------- | ---------- | ------------ |\n| `ReadonlyAccount<TAddress>`       | `AccountRole.READONLY`        | &#x274c;   | &#x274c;     |\n| `WritableAccount<TAddress>`       | `AccountRole.WRITABLE`        | &#x274c;   | &#x2705;     |\n| `ReadonlySignerAccount<TAddress>` | `AccountRole.READONLY_SIGNER` | &#x2705;   | &#x274c;     |\n| `WritableSignerAccount<TAddress>` | `AccountRole.WRITABLE_SIGNER` | &#x2705;   | &#x2705;     |\n\nFor example, you could type the rent sysvar account like this:\n\n```ts\ntype RentSysvar = ReadonlyAccount<'SysvarRent111111111111111111111111111111111'>;\n```\n\n### `AccountLookupMeta<TAddress, TLookupTableAddress>`\n\nThis type represents a lookup of the account's address in an address lookup table. It specifies which lookup table account in which to perform the lookup, the index of the desired account address in that table, and metadata about its mutability. Notably, account addresses obtained via lookups may not act as signers.\n\nTypically, you will use one of its subtypes.\n\n|                                                        | `role`                 | `isSigner` | `isWritable` |\n| ------------------------------------------------------ | ---------------------- | ---------- | ------------ |\n| `ReadonlyLookupAccount<TAddress, TLookupTableAddress>` | `AccountRole.READONLY` | &#x274c;   | &#x274c;     |\n| `WritableLookupAccount<TAddress, TLookupTableAddress>` | `AccountRole.WRITABLE` | &#x274c;   | &#x2705;     |\n\nFor example, you could type the rent sysvar account that you looked up in a lookup table like this:\n\n```ts\ntype RentSysvar = ReadonlyLookupAccount<\n    'SysvarRent111111111111111111111111111111111',\n    'MyLookupTable111111111111111111111111111111'\n>;\n```\n\n### `Instruction<TProgramAddress>`\n\nUse this to specify an instruction destined for a given program.\n\n```ts\ntype StakeProgramInstruction = Instruction<'StakeConfig11111111111111111111111111111111'>;\n```\n\n### `InstructionWithAccounts<TAccounts>`\n\nUse this type to specify an instruction that loads certain accounts.\n\n```ts\ntype InstructionWithTwoAccounts = InstructionWithAccounts<\n    [\n        WritableAccount, // First account\n        RentSysvar, // Second account\n    ]\n>;\n```\n\n### `InstructionWithData<TData>`\n\nUse this type to specify an instruction whose data conforms to a certain type. This is most useful when you have a branded `Uint8Array` that represents a particular instruction's data.\n\nFor example, here is how the `AdvanceNonce` instruction is typed.\n\n```ts\ntype AdvanceNonceAccountInstruction<\n    TNonceAccountAddress extends string = string,\n    TNonceAuthorityAddress extends string = string,\n> = Instruction<'11111111111111111111111111111111'> &\n    InstructionWithAccounts<\n        [\n            WritableAccount<TNonceAccountAddress>,\n            ReadonlyAccount<'SysvarRecentB1ockHashes11111111111111111111'>,\n            ReadonlySignerAccount<TNonceAuthorityAddress>,\n        ]\n    > &\n    InstructionWithData<AdvanceNonceAccountInstructionData>;\n```\n\n## Functions\n\n### `isSignerRole(role: AccountRole)`\n\nReturns `true` if the `AccountRole` given represents that of a signer. Also refines the TypeScript type of the supplied role.\n\n### `isWritable(role: AccountRole)`\n\nReturns `true` if the `AccountRole` given represents that of a writable account. Also refines the TypeScript type of the supplied role.\n\n### `mergeRoles(roleA: AccountRole, roleB: AccountRole)`\n\nGiven two `AccountRoles`, will return the `AccountRole` that grants the highest privileges of both.\n\nExample:\n\n```ts\n// Returns `AccountRole.WRITABLE_SIGNER`\nmergeRoles(AccountRole.READONLY_SIGNER, AccountRole.WRITABLE);\n```\n\n### `downgradeRoleToNonSigner(role: AccountRole)`\n\nReturns an `AccountRole` representing the non-signer variant of the supplied role.\n\n### `downgradeRoleToReadonly(role: AccountRole)`\n\nReturns an `AccountRole` representing the read-only variant of the supplied role.\n\n### `upgradeRoleToSigner(role: AccountRole)`\n\nReturns an `AccountRole` representing the signer variant of the supplied role.\n\n### `upgradeRoleToWritable(role: AccountRole)`\n\nReturns an `AccountRole` representing the writable variant of the supplied role.\n"
  },
  {
    "path": "packages/instructions/package.json",
    "content": "{\n    \"name\": \"@solana/instructions\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for creating transaction instructions\",\n    \"homepage\": \"https://www.solanakit.com/api#solanainstructions\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/addresses\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/instructions/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/instructions/src/__tests__/instruction-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SolanaError } from '@solana/errors';\n\nimport {\n    assertIsInstructionForProgram,\n    assertIsInstructionWithAccounts,\n    assertIsInstructionWithData,\n    Instruction,\n    isInstructionForProgram,\n    isInstructionWithAccounts,\n    isInstructionWithData,\n} from '../instruction';\nimport { AccountRole } from '../roles';\n\nconst programAddress = 'address' as Address;\n\ndescribe('isInstructionForProgram', () => {\n    it('returns true when the instruction has the given program address', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        expect(isInstructionForProgram(instruction, programAddress)).toBe(true);\n    });\n\n    it('returns false when the instruction does not have the given program address', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        const address = 'abc' as Address;\n        expect(isInstructionForProgram(instruction, address)).toBe(false);\n    });\n});\n\ndescribe('assertIsInstructionForProgram', () => {\n    it('does not throw when the instruction has the given program address', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        const assert = () => assertIsInstructionForProgram(instruction, programAddress);\n        expect(assert).not.toThrow();\n    });\n\n    it('throws when the instruction does not have the given program address', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        const address = 'abc' as Address;\n        const assert = () => assertIsInstructionForProgram(instruction, address);\n        expect(assert).toThrow(SolanaError);\n    });\n});\n\ndescribe('isInstructionWithAccounts', () => {\n    it('returns true when the instruction has an array of accounts', () => {\n        const instruction: Instruction = {\n            accounts: [\n                {\n                    address: 'abc' as Address,\n                    role: AccountRole.READONLY,\n                },\n            ],\n            programAddress,\n        };\n        expect(isInstructionWithAccounts(instruction)).toBe(true);\n    });\n\n    it('returns true when the instruction has an empty array of accounts', () => {\n        const instruction: Instruction = {\n            accounts: [],\n            programAddress,\n        };\n        expect(isInstructionWithAccounts(instruction)).toBe(true);\n    });\n\n    it('returns false when the instruction does not have accounts defined', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        expect(isInstructionWithAccounts(instruction)).toBe(false);\n    });\n});\n\ndescribe('assertIsInstructionWithAccounts', () => {\n    it('does not throw when the instruction has an array of accounts', () => {\n        const instruction: Instruction = {\n            accounts: [\n                {\n                    address: 'abc' as Address,\n                    role: AccountRole.READONLY,\n                },\n            ],\n            programAddress,\n        };\n        const assert = () => assertIsInstructionWithAccounts(instruction);\n        expect(assert).not.toThrow();\n    });\n\n    it('does not throw when the instruction has an empty array of accounts', () => {\n        const instruction: Instruction = {\n            accounts: [],\n            programAddress,\n        };\n        const assert = () => assertIsInstructionWithAccounts(instruction);\n        expect(assert).not.toThrow();\n    });\n\n    it('throws when the instruction does not have accounts defined', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        const assert = () => assertIsInstructionWithAccounts(instruction);\n        expect(assert).toThrow(SolanaError);\n    });\n});\n\ndescribe('isInstructionWithData', () => {\n    it('returns true when the instruction has a non-empty data', () => {\n        const instruction: Instruction = {\n            data: new Uint8Array([1, 2, 3, 4]),\n            programAddress,\n        };\n        expect(isInstructionWithData(instruction)).toBe(true);\n    });\n\n    it('returns true when the instruction has an empty data', () => {\n        const instruction: Instruction = {\n            data: new Uint8Array([]),\n            programAddress,\n        };\n        expect(isInstructionWithData(instruction)).toBe(true);\n    });\n\n    it('returns false when the instruction does not have data defined', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        expect(isInstructionWithData(instruction)).toBe(false);\n    });\n});\n\ndescribe('assertIsInstructionWithData', () => {\n    it('does not throw when the instruction has a non-empty data', () => {\n        const instruction: Instruction = {\n            data: new Uint8Array([1, 2, 3, 4]),\n            programAddress,\n        };\n        const assert = () => assertIsInstructionWithData(instruction);\n        expect(assert).not.toThrow();\n    });\n\n    it('does not throw when the instruction has an empty data', () => {\n        const instruction: Instruction = {\n            data: new Uint8Array([]),\n            programAddress,\n        };\n        const assert = () => assertIsInstructionWithData(instruction);\n        expect(assert).not.toThrow();\n    });\n\n    it('throws when the instruction does not have data defined', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        const assert = () => assertIsInstructionWithData(instruction);\n        expect(assert).toThrow(SolanaError);\n    });\n});\n"
  },
  {
    "path": "packages/instructions/src/__tests__/roles-test.ts",
    "content": "import {\n    AccountRole,\n    downgradeRoleToNonSigner,\n    downgradeRoleToReadonly,\n    isSignerRole,\n    isWritableRole,\n    mergeRoles,\n    upgradeRoleToSigner,\n    upgradeRoleToWritable,\n} from '../roles';\n\ndescribe('downgradeRoleToNonSigner', () => {\n    it.each`\n        role                 | expected\n        ${'READONLY'}        | ${'READONLY'}\n        ${'WRITABLE'}        | ${'WRITABLE'}\n        ${'READONLY_SIGNER'} | ${'READONLY'}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE'}\n    `(\n        'downgrades $role to $expected',\n        ({ role, expected }: { expected: keyof typeof AccountRole; role: keyof typeof AccountRole }) => {\n            expect(downgradeRoleToNonSigner(AccountRole[role])).toBe(AccountRole[expected]);\n        },\n    );\n});\n\ndescribe('downgradeRoleToReadonly', () => {\n    it.each`\n        role                 | expected\n        ${'READONLY'}        | ${'READONLY'}\n        ${'WRITABLE'}        | ${'READONLY'}\n        ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'}\n        ${'WRITABLE_SIGNER'} | ${'READONLY_SIGNER'}\n    `(\n        'downgrades $role to $expected',\n        ({ role, expected }: { expected: keyof typeof AccountRole; role: keyof typeof AccountRole }) => {\n            expect(downgradeRoleToReadonly(AccountRole[role])).toBe(AccountRole[expected]);\n        },\n    );\n});\n\ndescribe('isSignerRole', () => {\n    it.each([AccountRole.READONLY, AccountRole.WRITABLE])('returns `false` for AccountRole.$role', role => {\n        expect(isSignerRole(role)).toBe(false);\n    });\n    it.each([AccountRole.READONLY_SIGNER, AccountRole.WRITABLE_SIGNER])(\n        'returns `true` for AccountRole.$role',\n        role => {\n            expect(isSignerRole(role)).toBe(true);\n        },\n    );\n});\n\ndescribe('isWritableRole', () => {\n    it.each([AccountRole.READONLY, AccountRole.READONLY_SIGNER])('returns `false` for AccountRole.$role', role => {\n        expect(isWritableRole(role)).toBe(false);\n    });\n    it.each([AccountRole.WRITABLE, AccountRole.WRITABLE_SIGNER])('returns `true` for AccountRole.$role', role => {\n        expect(isWritableRole(role)).toBe(true);\n    });\n});\n\ndescribe('mergeRoles', () => {\n    it.each`\n        aRole                | bRole                | expected\n        ${'READONLY'}        | ${'READONLY'}        | ${'READONLY'}\n        ${'READONLY'}        | ${'WRITABLE'}        | ${'WRITABLE'}\n        ${'READONLY'}        | ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'}\n        ${'READONLY'}        | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'}\n        ${'WRITABLE'}        | ${'READONLY'}        | ${'WRITABLE'}\n        ${'WRITABLE'}        | ${'WRITABLE'}        | ${'WRITABLE'}\n        ${'WRITABLE'}        | ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'}\n        ${'WRITABLE'}        | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'}\n        ${'READONLY_SIGNER'} | ${'READONLY'}        | ${'READONLY_SIGNER'}\n        ${'READONLY_SIGNER'} | ${'WRITABLE'}        | ${'WRITABLE_SIGNER'}\n        ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'}\n        ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'}\n        ${'WRITABLE_SIGNER'} | ${'READONLY'}        | ${'WRITABLE_SIGNER'}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE'}        | ${'WRITABLE_SIGNER'}\n        ${'WRITABLE_SIGNER'} | ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'}\n    `(\n        'returns $expected when given $aRole and $bRole',\n        ({\n            aRole,\n            bRole,\n            expected,\n        }: {\n            aRole: keyof typeof AccountRole;\n            bRole: keyof typeof AccountRole;\n            expected: keyof typeof AccountRole;\n        }) => {\n            expect(mergeRoles(AccountRole[aRole], AccountRole[bRole])).toBe(AccountRole[expected]);\n        },\n    );\n});\n\ndescribe('upgradeRoleToSigner', () => {\n    it.each`\n        role                 | expected\n        ${'READONLY'}        | ${'READONLY_SIGNER'}\n        ${'WRITABLE'}        | ${'WRITABLE_SIGNER'}\n        ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'}\n    `(\n        'upgrades $role to $expected',\n        ({ role, expected }: { expected: keyof typeof AccountRole; role: keyof typeof AccountRole }) => {\n            expect(upgradeRoleToSigner(AccountRole[role])).toBe(AccountRole[expected]);\n        },\n    );\n});\n\ndescribe('upgradeRoleToWritable', () => {\n    it.each`\n        role                 | expected\n        ${'READONLY'}        | ${'WRITABLE'}\n        ${'WRITABLE'}        | ${'WRITABLE'}\n        ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'}\n    `(\n        'upgrades $role to $expected',\n        ({ role, expected }: { expected: keyof typeof AccountRole; role: keyof typeof AccountRole }) => {\n            expect(upgradeRoleToWritable(AccountRole[role])).toBe(AccountRole[expected]);\n        },\n    );\n});\n"
  },
  {
    "path": "packages/instructions/src/__typetests__/instruction-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { AccountLookupMeta, AccountMeta } from '../accounts';\nimport {\n    assertIsInstructionForProgram,\n    assertIsInstructionWithAccounts,\n    assertIsInstructionWithData,\n    Instruction,\n    InstructionWithAccounts,\n    InstructionWithData,\n    isInstructionForProgram,\n    isInstructionWithAccounts,\n    isInstructionWithData,\n} from '../instruction';\n\n// narrowing using if checks\n{\n    const instruction = {} as unknown as Instruction;\n\n    // @ts-expect-error instruction might not have accounts\n    instruction satisfies InstructionWithAccounts<readonly (AccountLookupMeta | AccountMeta)[]>;\n\n    // @ts-expect-error instruction might not have data\n    instruction satisfies InstructionWithData<ReadonlyUint8Array>;\n\n    if (isInstructionWithAccounts(instruction) && isInstructionWithData(instruction)) {\n        instruction satisfies Instruction &\n            InstructionWithAccounts<readonly (AccountLookupMeta | AccountMeta)[]> &\n            InstructionWithData<ReadonlyUint8Array>;\n    }\n}\n\n// narrowing using assertions\n{\n    const instruction = {} as unknown as Instruction;\n\n    // @ts-expect-error instruction might not have accounts\n    instruction satisfies InstructionWithAccounts<readonly (AccountLookupMeta | AccountMeta)[]>;\n\n    // @ts-expect-error instruction might not have data\n    instruction satisfies InstructionWithData<ReadonlyUint8Array>;\n\n    assertIsInstructionWithAccounts(instruction);\n    instruction satisfies Instruction & InstructionWithAccounts<readonly (AccountLookupMeta | AccountMeta)[]>;\n\n    assertIsInstructionWithData(instruction);\n    instruction satisfies Instruction &\n        InstructionWithAccounts<readonly (AccountLookupMeta | AccountMeta)[]> &\n        InstructionWithData<ReadonlyUint8Array>;\n}\n\n// narrowing by program address\n{\n    const instruction = {} as unknown as Instruction;\n    const myAddress = '1111' as Address<'1111'>;\n    type MyAddress = typeof myAddress;\n\n    // @ts-expect-error instruction might not have the right address\n    instruction satisfies Instruction<MyAddress>;\n\n    if (isInstructionForProgram(instruction, myAddress)) {\n        instruction satisfies Instruction<MyAddress>;\n        instruction satisfies Instruction<'1111'>;\n    }\n\n    assertIsInstructionForProgram(instruction, myAddress);\n    instruction satisfies Instruction<MyAddress>;\n    instruction satisfies Instruction<'1111'>;\n}\n"
  },
  {
    "path": "packages/instructions/src/accounts.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { AccountRole } from './roles';\n\n/**\n * Represents an account's address and metadata about its mutability and whether it must be a signer\n * of the transaction.\n *\n * Typically, you will use one of its subtypes.\n *\n * |                                   | `role`                        | `isSigner` | `isWritable` |\n * | --------------------------------- | ----------------------------- | ---------- | ------------ |\n * | `ReadonlyAccount<TAddress>`       | `AccountRole.READONLY`        |  No        |  No          |\n * | `WritableAccount<TAddress>`       | `AccountRole.WRITABLE`        |  No        |  Yes         |\n * | `ReadonlySignerAccount<TAddress>` | `AccountRole.READONLY_SIGNER` |  Yes       |  No          |\n * | `WritableSignerAccount<TAddress>` | `AccountRole.WRITABLE_SIGNER` |  Yes       |  Yes         |\n *\n * @example A type for the Rent sysvar account\n * ```ts\n * type RentSysvar = ReadonlyAccount<'SysvarRent111111111111111111111111111111111'>;\n * ```\n */\nexport interface AccountMeta<TAddress extends string = string> {\n    readonly address: Address<TAddress>;\n    readonly role: AccountRole;\n}\n\n/**\n * @see {@link AccountMeta}\n */\nexport type ReadonlyAccount<TAddress extends string = string> = AccountMeta<TAddress> & {\n    readonly role: AccountRole.READONLY;\n};\n/**\n * @see {@link AccountMeta}\n */\nexport type WritableAccount<TAddress extends string = string> = AccountMeta<TAddress> & { role: AccountRole.WRITABLE };\n/**\n * @see {@link AccountMeta}\n */\nexport type ReadonlySignerAccount<TAddress extends string = string> = AccountMeta<TAddress> & {\n    role: AccountRole.READONLY_SIGNER;\n};\n/**\n * @see {@link AccountMeta}\n */\nexport type WritableSignerAccount<TAddress extends string = string> = AccountMeta<TAddress> & {\n    role: AccountRole.WRITABLE_SIGNER;\n};\n\n/**\n * Represents a lookup of the account's address in an address lookup table. It specifies which\n * lookup table account in which to perform the lookup, the index of the desired account address in\n * that table, and metadata about its mutability. Notably, account addresses obtained via lookups\n * may not act as signers.\n *\n * Typically, you will use one of its subtypes.\n *\n * |                                                        | `role`                 | `isSigner` | `isWritable` |\n * | ------------------------------------------------------ | ---------------------- | ---------- | ------------ |\n * | `ReadonlyLookupAccount<TAddress, TLookupTableAddress>` | `AccountRole.READONLY` |  No        |  No          |\n * | `WritableLookupAccount<TAddress, TLookupTableAddress>` | `AccountRole.WRITABLE` |  No        |  Yes         |\n *\n * @example A type for the Rent sysvar account that you looked up in a lookup table\n * ```ts\n * type RentSysvar = ReadonlyLookupAccount<\n *     'SysvarRent111111111111111111111111111111111',\n *     'MyLookupTable111111111111111111111111111111'\n * >;\n * ```\n */\nexport interface AccountLookupMeta<TAddress extends string = string, TLookupTableAddress extends string = string> {\n    readonly address: Address<TAddress>;\n    readonly addressIndex: number;\n    readonly lookupTableAddress: Address<TLookupTableAddress>;\n    readonly role: AccountRole.READONLY | AccountRole.WRITABLE;\n}\n\n/**\n * @see {@link AccountLookupMeta}\n */\nexport type ReadonlyAccountLookup<\n    TAddress extends string = string,\n    TLookupTableAddress extends string = string,\n> = AccountLookupMeta<TAddress, TLookupTableAddress> & { readonly role: AccountRole.READONLY };\n/**\n * @see {@link AccountLookupMeta}\n */\nexport type WritableAccountLookup<\n    TAddress extends string = string,\n    TLookupTableAddress extends string = string,\n> = AccountLookupMeta<TAddress, TLookupTableAddress> & { readonly role: AccountRole.WRITABLE };\n"
  },
  {
    "path": "packages/instructions/src/index.ts",
    "content": "/**\n * This package contains types for creating transaction instructions. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n * @packageDocumentation\n */\nexport * from './accounts';\nexport * from './instruction';\nexport * from './roles';\n"
  },
  {
    "path": "packages/instructions/src/instruction.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_ACCOUNTS,\n    SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_DATA,\n    SOLANA_ERROR__INSTRUCTION__PROGRAM_ID_MISMATCH,\n    SolanaError,\n} from '@solana/errors';\n\nimport { AccountLookupMeta, AccountMeta } from './accounts';\n\n/**\n * An instruction destined for a given program.\n *\n * @example\n * ```ts\n * type StakeProgramInstruction = Instruction<'StakeConfig11111111111111111111111111111111'>;\n * ```\n */\nexport interface Instruction<\n    TProgramAddress extends string = string,\n    TAccounts extends readonly (AccountLookupMeta | AccountMeta)[] = readonly (AccountLookupMeta | AccountMeta)[],\n> {\n    readonly accounts?: TAccounts;\n    readonly data?: ReadonlyUint8Array;\n    readonly programAddress: Address<TProgramAddress>;\n}\n\n/**\n * An instruction that loads certain accounts.\n *\n * @example\n * ```ts\n * type InstructionWithTwoAccounts = InstructionWithAccounts<\n *     [\n *         WritableAccount, // First account\n *         RentSysvar, // Second account\n *     ]\n * >;\n * ```\n */\nexport interface InstructionWithAccounts<\n    TAccounts extends readonly (AccountLookupMeta | AccountMeta)[],\n> extends Instruction {\n    readonly accounts: TAccounts;\n}\n\nexport function isInstructionForProgram<TProgramAddress extends string, TInstruction extends Instruction>(\n    instruction: TInstruction,\n    programAddress: Address<TProgramAddress>,\n): instruction is TInstruction & { programAddress: Address<TProgramAddress> } {\n    return instruction.programAddress === programAddress;\n}\n\nexport function assertIsInstructionForProgram<TProgramAddress extends string, TInstruction extends Instruction>(\n    instruction: TInstruction,\n    programAddress: Address<TProgramAddress>,\n): asserts instruction is TInstruction & { programAddress: Address<TProgramAddress> } {\n    if (instruction.programAddress !== programAddress) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION__PROGRAM_ID_MISMATCH, {\n            actualProgramAddress: instruction.programAddress,\n            expectedProgramAddress: programAddress,\n        });\n    }\n}\n\nexport function isInstructionWithAccounts<\n    TAccounts extends readonly (AccountLookupMeta | AccountMeta)[] = readonly (AccountLookupMeta | AccountMeta)[],\n    TInstruction extends Instruction = Instruction,\n>(instruction: TInstruction): instruction is InstructionWithAccounts<TAccounts> & TInstruction {\n    return instruction.accounts !== undefined;\n}\n\nexport function assertIsInstructionWithAccounts<\n    TAccounts extends readonly (AccountLookupMeta | AccountMeta)[] = readonly (AccountLookupMeta | AccountMeta)[],\n    TInstruction extends Instruction = Instruction,\n>(instruction: TInstruction): asserts instruction is InstructionWithAccounts<TAccounts> & TInstruction {\n    if (instruction.accounts === undefined) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_ACCOUNTS, {\n            data: instruction.data,\n            programAddress: instruction.programAddress,\n        });\n    }\n}\n\n/**\n * An instruction whose data conforms to a certain type.\n *\n * This is most useful when you have a branded `Uint8Array` that represents a particular\n * instruction's data.\n *\n * @example A type for the \\`AdvanceNonce\\` instruction of the System program\n * ```ts\n * type AdvanceNonceAccountInstruction<\n *     TNonceAccountAddress extends string = string,\n *     TNonceAuthorityAddress extends string = string,\n * > = Instruction<'11111111111111111111111111111111'> &\n *     InstructionWithAccounts<\n *         [\n *             WritableAccount<TNonceAccountAddress>,\n *             ReadonlyAccount<'SysvarRecentB1ockHashes11111111111111111111'>,\n *             ReadonlySignerAccount<TNonceAuthorityAddress>,\n *         ]\n *     > &\n *     InstructionWithData<AdvanceNonceAccountInstructionData>;\n * ```\n */\nexport interface InstructionWithData<TData extends ReadonlyUint8Array> extends Instruction {\n    readonly data: TData;\n}\n\nexport function isInstructionWithData<\n    TData extends ReadonlyUint8Array = ReadonlyUint8Array,\n    TInstruction extends Instruction = Instruction,\n>(instruction: TInstruction): instruction is InstructionWithData<TData> & TInstruction {\n    return instruction.data !== undefined;\n}\n\nexport function assertIsInstructionWithData<\n    TData extends ReadonlyUint8Array = ReadonlyUint8Array,\n    TInstruction extends Instruction = Instruction,\n>(instruction: TInstruction): asserts instruction is InstructionWithData<TData> & TInstruction {\n    if (instruction.data === undefined) {\n        throw new SolanaError(SOLANA_ERROR__INSTRUCTION__EXPECTED_TO_HAVE_DATA, {\n            accountAddresses: instruction.accounts?.map(a => a.address),\n            programAddress: instruction.programAddress,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/instructions/src/roles.ts",
    "content": "/**\n * Describes the purpose for which an account participates in a transaction.\n *\n * Every account that participates in a transaction can be read from, but only ones that you mark as\n * writable may be written to, and only ones that you indicate must sign the transaction will gain\n * the privileges associated with signers at runtime.\n *\n * |                               | `isSigner` | `isWritable` |\n * | ----------------------------- | ---------- | ------------ |\n * | `AccountRole.READONLY`        | &#x274c;   | &#x274c;     |\n * | `AccountRole.WRITABLE`        | &#x274c;   | &#x2705;     |\n * | `AccountRole.READONLY_SIGNER` | &#x2705;   | &#x274c;     |\n * | `AccountRole.WRITABLE_SIGNER` | &#x2705;   | &#x2705;     |\n */\nexport enum AccountRole {\n    // Bitflag guide: is signer ⌄⌄ is writable\n    WRITABLE_SIGNER = /* 3 */ 0b11, // prettier-ignore\n    READONLY_SIGNER = /* 2 */ 0b10, // prettier-ignore\n    WRITABLE =        /* 1 */ 0b01, // prettier-ignore\n    READONLY =        /* 0 */ 0b00, // prettier-ignore\n}\n\n// Quick primer on bitwise operations: https://stackoverflow.com/a/1436448/802047\nconst IS_SIGNER_BITMASK = 0b10;\nconst IS_WRITABLE_BITMASK = 0b01;\n\n/**\n * @returns An {@link AccountRole} representing the non-signer variant of the supplied role.\n */\nexport function downgradeRoleToNonSigner(role: AccountRole.READONLY_SIGNER): AccountRole.READONLY;\nexport function downgradeRoleToNonSigner(role: AccountRole.WRITABLE_SIGNER): AccountRole.WRITABLE;\nexport function downgradeRoleToNonSigner(role: AccountRole): AccountRole;\nexport function downgradeRoleToNonSigner(role: AccountRole): AccountRole {\n    return role & ~IS_SIGNER_BITMASK;\n}\n\n/**\n * @returns An {@link AccountRole} representing the read-only variant of the supplied role.\n */\nexport function downgradeRoleToReadonly(role: AccountRole.WRITABLE): AccountRole.READONLY;\nexport function downgradeRoleToReadonly(role: AccountRole.WRITABLE_SIGNER): AccountRole.READONLY_SIGNER;\nexport function downgradeRoleToReadonly(role: AccountRole): AccountRole;\nexport function downgradeRoleToReadonly(role: AccountRole): AccountRole {\n    return role & ~IS_WRITABLE_BITMASK;\n}\n\n/**\n * Returns `true` if the {@link AccountRole} given represents that of a signer. Also refines the\n * TypeScript type of the supplied role.\n */\nexport function isSignerRole(role: AccountRole): role is AccountRole.READONLY_SIGNER | AccountRole.WRITABLE_SIGNER {\n    return role >= AccountRole.READONLY_SIGNER;\n}\n\n/**\n * Returns `true` if the {@link AccountRole} given represents that of a writable account. Also\n * refines the TypeScript type of the supplied role.\n */\nexport function isWritableRole(role: AccountRole): role is AccountRole.WRITABLE | AccountRole.WRITABLE_SIGNER {\n    return (role & IS_WRITABLE_BITMASK) !== 0;\n}\n\n/**\n * Given two {@link AccountRole | AccountRoles}, will return the {@link AccountRole} that grants the\n * highest privileges of both.\n *\n * @example\n * ```ts\n * // Returns `AccountRole.WRITABLE_SIGNER`\n * mergeRoles(AccountRole.READONLY_SIGNER, AccountRole.WRITABLE);\n * ```\n */\nexport function mergeRoles(roleA: AccountRole.WRITABLE, roleB: AccountRole.READONLY_SIGNER): AccountRole.WRITABLE_SIGNER; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole.READONLY_SIGNER, roleB: AccountRole.WRITABLE): AccountRole.WRITABLE_SIGNER; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole, roleB: AccountRole.WRITABLE_SIGNER): AccountRole.WRITABLE_SIGNER; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole.WRITABLE_SIGNER, roleB: AccountRole): AccountRole.WRITABLE_SIGNER; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole, roleB: AccountRole.READONLY_SIGNER): AccountRole.READONLY_SIGNER; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole.READONLY_SIGNER, roleB: AccountRole): AccountRole.READONLY_SIGNER; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole, roleB: AccountRole.WRITABLE): AccountRole.WRITABLE; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole.WRITABLE, roleB: AccountRole): AccountRole.WRITABLE; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole.READONLY, roleB: AccountRole.READONLY): AccountRole.READONLY; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole, roleB: AccountRole): AccountRole; // prettier-ignore\nexport function mergeRoles(roleA: AccountRole, roleB: AccountRole): AccountRole {\n    return roleA | roleB;\n}\n\n/**\n * @returns An {@link AccountRole} representing the signer variant of the supplied role.\n */\nexport function upgradeRoleToSigner(role: AccountRole.READONLY): AccountRole.READONLY_SIGNER;\nexport function upgradeRoleToSigner(role: AccountRole.WRITABLE): AccountRole.WRITABLE_SIGNER;\nexport function upgradeRoleToSigner(role: AccountRole): AccountRole;\nexport function upgradeRoleToSigner(role: AccountRole): AccountRole {\n    return role | IS_SIGNER_BITMASK;\n}\n\n/**\n * @returns An {@link AccountRole} representing the writable variant of the supplied role.\n */\nexport function upgradeRoleToWritable(role: AccountRole.READONLY): AccountRole.WRITABLE;\nexport function upgradeRoleToWritable(role: AccountRole.READONLY_SIGNER): AccountRole.WRITABLE_SIGNER;\nexport function upgradeRoleToWritable(role: AccountRole): AccountRole;\nexport function upgradeRoleToWritable(role: AccountRole): AccountRole {\n    return role | IS_WRITABLE_BITMASK;\n}\n"
  },
  {
    "path": "packages/instructions/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/instructions/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/instructions\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/instructions/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/keys/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/keys/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/keys/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/keys/CHANGELOG.md",
    "content": "# @solana/keys\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`8d73de5`](https://github.com/anza-xyz/kit/commit/8d73de5241d709946431f2fdda74f2a0df5e9529), [`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/promises@6.9.0\n    - @solana/errors@6.9.0\n    - @solana/assertions@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/nominal-types@6.9.0\n\n## 6.8.0\n\n### Minor Changes\n\n- [#1531](https://github.com/anza-xyz/kit/pull/1531) [`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add an optional `extractable` argument to `generateKeyPair` and `generateKeyPairSigner`. It defaults to `false`, preserving the existing secure-by-default behavior, but can be set to `true` when you need to export the generated private key bytes via `crypto.subtle.exportKey()`.\n\n- [#1537](https://github.com/anza-xyz/kit/pull/1537) [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `writeKeyPair` and `writeKeyPairSigner` helpers for persisting an extractable key pair to disk as a JSON byte array, matching the format produced by `solana-keygen`. Missing parent directories are created automatically, and written files use mode `0600`. These helpers are Node-only and refuse to overwrite an existing file unless the caller sets `unsafelyOverwriteExistingKeyPair: true`.\n\n- [#1534](https://github.com/anza-xyz/kit/pull/1534) [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `grindKeyPair`, `grindKeyPairs`, `grindKeyPairSigner`, and `grindKeyPairSigners` for mining vanity key pairs whose base58-encoded public key matches a `RegExp` or a custom predicate. Supports `amount` for mining multiple key pairs, `extractable` for forwarding to the underlying `generateKeyPair` call, `concurrency` (defaulting to `32`) for batched parallel key generation, and `abortSignal` for cancellation. Regex matchers are statically checked for base58-alphabet violations at runtime (after stripping escapes, character classes, quantifiers, and groups) to catch common typos like `/^sol0/`.\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/assertions@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/nominal-types@6.8.0\n    - @solana/promises@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/nominal-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/assertions@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/nominal-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/nominal-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/assertions@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/nominal-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/nominal-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/assertions@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/nominal-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/assertions@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/nominal-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/assertions@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-strings@6.1.0\n    - @solana/nominal-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/nominal-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/nominal-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/assertions@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/nominal-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/assertions@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/nominal-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-strings@5.4.0\n    - @solana/nominal-types@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/assertions@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/nominal-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- [#1116](https://github.com/anza-xyz/kit/pull/1116) [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549) Thanks [@steveluscher](https://github.com/steveluscher)! - Any `SharedArrayBuffer` that gets passed to a crypto operation like `signBytes` or `verifySignature` will now be copied as non-shared. Crypto operations like `sign` and `verify` reject `SharedArrayBuffers` otherwise\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/assertions@5.2.0\n    - @solana/nominal-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/assertions@5.1.0\n    - @solana/nominal-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/assertions@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-strings@5.0.0\n    - @solana/nominal-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#901](https://github.com/anza-xyz/kit/pull/901) [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e) Thanks [@guibescos](https://github.com/guibescos)! - Added assertion (`assertIsSignatureBytes`), guard (`isSignatureBytes`), and coercion (`signatureBytes`) methods to make it easier to work with callsites that demand a `SignatureBytes` type\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/assertions@4.0.0\n    - @solana/codecs-strings@4.0.0\n    - @solana/nominal-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/assertions@3.0.0\n    - @solana/codecs-strings@3.0.0\n    - @solana/nominal-types@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/assertions@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-strings@2.3.0\n    - @solana/nominal-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/nominal-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/nominal-types@2.2.0\n    - @solana/assertions@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-strings@2.1.1\n    - @solana/nominal-types@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/assertions@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- [#60](https://github.com/anza-xyz/kit/pull/60) [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a) Thanks [@steveluscher](https://github.com/steveluscher)! - Key operations now work in versions of Firefox that support `Ed25519` natively\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/assertions@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3050](https://github.com/solana-labs/solana-web3.js/pull/3050) [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a `createKeyPairFromPrivateKeyBytes` helper that creates a keypair from the 32-byte private key bytes.\n\n    ```ts\n    import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n\n    const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n    ```\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2707](https://github.com/solana-labs/solana-web3.js/pull/2707) [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow creating keypairs and keys from ReadonlyUint8Array\n\n- [#2329](https://github.com/solana-labs/solana-web3.js/pull/2329) [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8) Thanks [@luu-alex](https://github.com/luu-alex)! - `createKeyPairFromBytes()` now validates that the public key imported is the one that would be derived from the private key imported\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3128](https://github.com/solana-labs/solana-web3.js/pull/3128) [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Fix missing export in `@solana/keys` package. This means, the `getPublicKeyFromPrivateKey` function is now properly exported.\n\n- [#3049](https://github.com/solana-labs/solana-web3.js/pull/3049) [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a `getPublicKeyFromPrivateKey` helper that, given an extractable `CryptoKey` private key, gets the corresponding public key as a `CryptoKey`.\n\n    ```ts\n    import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n\n    const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n\n    const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n    const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n    ```\n\n- [#2352](https://github.com/solana-labs/solana-web3.js/pull/2352) [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1) Thanks [@steveluscher](https://github.com/steveluscher)! - `SubtleCrypto` assertion methods that can make their assertions synchronously are now synchronous, for performance.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`441fa3a`](https://github.com/solana-labs/solana-web3.js/commit/441fa3a6c7c104961f935e65e259f40c10e82f8a), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/assertions@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/assertions@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/assertions@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3128](https://github.com/solana-labs/solana-web3.js/pull/3128) [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Fix missing export in `@solana/keys` package. This means, the `getPublicKeyFromPrivateKey` function is now properly exported.\n\n- Updated dependencies [[`441fa3a`](https://github.com/solana-labs/solana-web3.js/commit/441fa3a6c7c104961f935e65e259f40c10e82f8a), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/assertions@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- [#3050](https://github.com/solana-labs/solana-web3.js/pull/3050) [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a `createKeyPairFromPrivateKeyBytes` helper that creates a keypair from the 32-byte private key bytes.\n\n    ```ts\n    import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n\n    const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n    ```\n\n- [#3049](https://github.com/solana-labs/solana-web3.js/pull/3049) [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a `getPublicKeyFromPrivateKey` helper that, given an extractable `CryptoKey` private key, gets the corresponding public key as a `CryptoKey`.\n\n    ```ts\n    import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n\n    const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n\n    const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n    const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n    ```\n\n- Updated dependencies []:\n    - @solana/assertions@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/assertions@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2707](https://github.com/solana-labs/solana-web3.js/pull/2707) [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow creating keypairs and keys from ReadonlyUint8Array\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/assertions@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2329](https://github.com/solana-labs/solana-web3.js/pull/2329) [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8) Thanks [@luu-alex](https://github.com/luu-alex)! - `createKeyPairFromBytes()` now validates that the public key imported is the one that would be derived from the private key imported\n\n- [#2352](https://github.com/solana-labs/solana-web3.js/pull/2352) [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1) Thanks [@steveluscher](https://github.com/steveluscher)! - `SubtleCrypto` assertion methods that can make their assertions synchronously are now synchronous, for performance.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/assertions@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/assertions@2.0.0-preview.2\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-strings@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/keys/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/keys/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/keys?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/keys?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/keys\n\n# @solana/keys\n\nThis package contains utilities for validating, generating, and manipulating addresses and key material. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Types\n\n### `Signature`\n\nThis type represents a 64-byte Ed25519 signature as a base58-encoded string.\n\n### `SignatureBytes`\n\nThis type represents a 64-byte Ed25519 signature.\n\nWhenever you need to verify that a particular signature is, in fact, the one that would have been produced by signing some known bytes using the private key associated with some known public key, use the `verifySignature()` function in this package.\n\n## Functions\n\n### `assertIsSignature()`\n\nFrom time to time you might acquire a string that you expect to be a base58-encoded signature (eg. of a transaction) from an untrusted network API or user input. To assert that such an arbitrary string is in fact an Ed25519 signature, use the `assertIsSignature` function.\n\n```ts\nimport { assertIsSignature } from '@solana/keys';\n\n// Imagine a function that asserts whether a user-supplied signature is valid or not.\nfunction handleSubmit() {\n    // We know only that what the user typed conforms to the `string` type.\n    const signature: string = signatureInput.value;\n    try {\n        // If this type assertion function doesn't throw, then\n        // Typescript will upcast `signature` to `Signature`.\n        assertIsSignature(signature);\n        // At this point, `signature` is a `Signature` that can be used with the RPC.\n        const {\n            value: [status],\n        } = await rpc.getSignatureStatuses([signature]).send();\n    } catch (e) {\n        // `signature` turned out not to be a base58-encoded signature\n    }\n}\n```\n\n### `generateKeyPair()`\n\nGenerates an Ed25519 public/private key pair for use with other methods in this package that accept `CryptoKey` objects.\n\n```ts\nimport { generateKeyPair } from '@solana/keys';\n\nconst { privateKey, publicKey } = await generateKeyPair();\n```\n\n### `grindKeyPair()`\n\nMines a vanity Ed25519 key pair whose base58-encoded public key satisfies the provided `matches` criterion. The matcher may be a `RegExp` or a predicate function that receives the candidate address as a string. Key pairs are generated in parallel batches until one matches, so the expected time to find a match grows exponentially with the length of the desired prefix.\n\n```ts\nimport { grindKeyPair } from '@solana/keys';\n\nconst keyPair = await grindKeyPair({ matches: /^anza/ });\n```\n\nWhen `matches` is a `RegExp`, its literal characters are validated against the base58 alphabet up front to catch common typos (e.g. `/^sol0/`) before any key is generated. The config also accepts an `extractable` flag (forwarded to `generateKeyPair`), a `concurrency` setting for the batch size (defaulting to `32`), and an `abortSignal` to cancel long-running grinds.\n\n### `grindKeyPairs()`\n\nMines multiple vanity Ed25519 key pairs whose base58-encoded public keys all satisfy the provided `matches` criterion. This is the batch variant of `grindKeyPair()` and accepts the same configuration plus an `amount` field.\n\n```ts\nimport { grindKeyPairs } from '@solana/keys';\n\nconst keyPairs = await grindKeyPairs({ matches: /^anza/, amount: 4 });\n```\n\n### `createKeyPairFromBytes()`\n\nGiven a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with other methods in this package that accept `CryptoKey` objects.\n\n```ts\nimport fs from 'fs';\nimport { createKeyPairFromBytes } from '@solana/keys';\n\n// Get bytes from local keypair file.\nconst keypairFile = fs.readFileSync('~/.config/solana/id.json');\nconst keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n\n// Create a CryptoKeyPair from the bytes.\nconst { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n```\n\n### `writeKeyPair()`\n\nWrites an extractable `CryptoKeyPair` to disk as a JSON array of 64 bytes, matching the format produced by `solana-keygen`. The first 32 bytes are the raw Ed25519 seed (private key) and the last 32 bytes are the raw public key. Missing parent directories are created automatically and the file is written with mode `0600` (owner read/write only). This helper requires a writable filesystem and will throw in environments that don't provide one (such as browsers or React Native).\n\n```ts\nimport { generateKeyPair, writeKeyPair } from '@solana/keys';\n\n// Generate an extractable key pair so its bytes can be persisted.\nconst keyPair = await generateKeyPair(true);\nawait writeKeyPair(keyPair, './my-keypair.json');\n```\n\nBy default, `writeKeyPair()` refuses to overwrite an existing file and throws `EEXIST`. Callers can opt in by passing `{ unsafelyOverwriteExistingKeyPair: true }`, but doing so permanently destroys the previous key and, with it, access to any funds or onchain state controlled by that address.\n\n### `createKeyPairFromPrivateKeyBytes()`\n\nGiven a private key represented as a 32-bytes `Uint8Array`, creates an Ed25519 public/private key pair for use with other methods in this package that accept `CryptoKey` objects.\n\n```ts\nimport { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n\nconst { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n```\n\nThis can be useful when you have a private key but not the corresponding public key or when you need to derive key pairs from seeds. For instance, the following code snippet derives a key pair from the hash of a message.\n\n```ts\nimport { getUtf8Encoder } from '@solana/codecs-strings';\nimport { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n\nconst message = getUtf8Encoder().encode('Hello, World!');\nconst seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n\nconst derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n```\n\n### `createPrivateKeyFromBytes()`\n\nGiven a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use with other methods in this package that accept `CryptoKey` objects.\n\n```ts\nimport { createPrivateKeyFromBytes } from '@solana/keys';\n\nconst privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\nconst extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n```\n\n### `getPublicKeyFromPrivateKey()`\n\nGiven an extractable `CryptoKey` private key, gets the corresponding public key as a `CryptoKey`.\n\n```ts\nimport { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n\nconst privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n\nconst publicKey = await getPublicKeyFromPrivateKey(privateKey);\nconst extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n```\n\n### `isSignature()`\n\nThis is a type guard that accepts a string as input. It will both return `true` if the string conforms to the `Signature` type and will refine the type for use in your program.\n\n```ts\nimport { isSignature } from '@solana/keys';\n\nif (isSignature(signature)) {\n    // At this point, `signature` has been refined to a\n    // `Signature` that can be used with the RPC.\n    const {\n        value: [status],\n    } = await rpc.getSignatureStatuses([signature]).send();\n    setSignatureStatus(status);\n} else {\n    setError(`${signature} is not a transaction signature`);\n}\n```\n\n### `signBytes()`\n\nGiven a private `CryptoKey` and a `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a `Uint8Array`.\n\n```ts\nimport { signBytes } from '@solana/keys';\n\nconst data = new Uint8Array([1, 2, 3]);\nconst signature = await signBytes(privateKey, data);\n```\n\n### `signature()`\n\nThis helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the `Signature` type. It's best used with untrusted input.\n\n```ts\nimport { signature } from '@solana/keys';\n\nconst signature = signature(userSuppliedSignature);\nconst {\n    value: [status],\n} = await rpc.getSignatureStatuses([signature]).send();\n```\n\n### `verifySignature()`\n\nGiven a public `CryptoKey`, some `SignatureBytes`, and a `Uint8Array` of data, this method will return `true` if the signature was produced by signing the data using the private key associated with the public key, and `false` otherwise.\n\n```ts\nimport { verifySignature } from '@solana/keys';\n\nconst data = new Uint8Array([1, 2, 3]);\nif (!(await verifySignature(publicKey, signature, data))) {\n    throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n}\n```\n"
  },
  {
    "path": "packages/keys/package.json",
    "content": "{\n    \"name\": \"@solana/keys\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for generating and transforming key material\",\n    \"homepage\": \"https://www.solanakit.com/api#solanakeys\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"benchmark\": \"./src/__benchmarks__/run.ts\",\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/assertions\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/nominal-types\": \"workspace:*\",\n        \"@solana/promises\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"devDependencies\": {\n        \"@solana/fs-impl\": \"workspace:*\",\n        \"tinybench\": \"^6.0.0\"\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/keys/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/keys/src/__benchmarks__/run.ts",
    "content": "#!/usr/bin/env -S pnpm dlx tsx -r ../build-scripts/register-node-globals.cjs\n\nimport { Bench } from 'tinybench';\n\nimport { generateKeyPair, SignatureBytes, signBytes, verifySignature } from '../index';\n\nconst bench = new Bench({\n    throws: true,\n});\n\nlet keyPair: CryptoKeyPair;\nasync function generateKeyPairForTest() {\n    keyPair = await generateKeyPair();\n}\n\nlet randomBytes: Uint8Array;\nfunction generateRandomBytesForTest() {\n    randomBytes ||= new Uint8Array(32);\n    crypto.getRandomValues(randomBytes);\n}\n\nlet signature: SignatureBytes;\nasync function generateSignatureForBytes() {\n    signature = await signBytes(keyPair.privateKey, randomBytes);\n}\n\nbench\n    .add('generateKeyPair', generateKeyPair)\n    .add('signBytes', async () => await signBytes(keyPair.privateKey, randomBytes), {\n        async beforeEach() {\n            generateRandomBytesForTest();\n            await generateKeyPairForTest();\n        },\n    })\n    .add('verifySignature', async () => await verifySignature(keyPair.publicKey, signature, randomBytes), {\n        async beforeEach() {\n            generateRandomBytesForTest();\n            await generateKeyPairForTest();\n            await generateSignatureForBytes();\n        },\n    });\n\nvoid (async () => {\n    await bench.run();\n    console.table(bench.table());\n})();\n"
  },
  {
    "path": "packages/keys/src/__tests__/coercions-test.ts",
    "content": "import {\n    SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { Signature, signature, signatureBytes } from '../signatures';\n\ndescribe('signature', () => {\n    it('can coerce to `Signature`', () => {\n        // Randomly generated\n        const raw =\n            '3bwsNoq6EP89sShUAKBeB26aCC3KLGNajRm5wqwr6zRPP3gErZH7erSg3332SVY7Ru6cME43qT35Z7JKpZqCoPaL' as Signature;\n        const coerced = signature(\n            '3bwsNoq6EP89sShUAKBeB26aCC3KLGNajRm5wqwr6zRPP3gErZH7erSg3332SVY7Ru6cME43qT35Z7JKpZqCoPaL',\n        );\n        expect(coerced).toBe(raw);\n    });\n    it.each([63, 89])('throws on a `Signature` whose string length is %s', actualLength => {\n        const thisThrows = () => signature('t'.repeat(actualLength));\n        expect(thisThrows).toThrow(\n            new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n                actualLength,\n            }),\n        );\n    });\n    it.each([\n        [63, '3bwsNoq6EP89sShUAKBeB26aCC3KLGNajRm5wqwr6zRPP3gErZH7erSg3332SVY7Ru6cME43qT35Z7JKpZqCoP'],\n        [65, 'ZbwsNoq6EP89sShUAKBeB26aCC3KLGNajRm5wqwr6zRPP3gErZH7erSg3332SVY7Ru6cME43qT35Z7JKPZqCoPZZ'],\n    ])('throws on a `Signature` whose decoded byte length is %s', (actualLength, encodedSignature) => {\n        const thisThrows = () => signature(encodedSignature);\n        expect(thisThrows).toThrow(\n            new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n                actualLength,\n            }),\n        );\n    });\n});\n\ndescribe('signatureBytes', () => {\n    it('can coerce to `SignatureBytes`', () => {\n        const raw = new Uint8Array(64);\n        const coerced = signatureBytes(raw);\n        expect(coerced).toBe(raw);\n    });\n    it.each([63, 65])('throws on a `SignatureBytes` whose byte length is %s', actualLength => {\n        const thisThrows = () => signatureBytes(new Uint8Array(actualLength));\n        expect(thisThrows).toThrow(\n            new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n                actualLength,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/keys/src/__tests__/grind-keypair-test.ts",
    "content": "import { getBase58Decoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX, SolanaError } from '@solana/errors';\n\nimport { grindKeyPair, grindKeyPairs } from '../grind-keypair';\nimport { generateKeyPair } from '../key-pair';\n\n// Partial mock of the key-pair module so we can spy on `generateKeyPair` in\n// forwarding tests. By default, the real implementation is used.\njest.mock('../key-pair', () => ({\n    ...jest.requireActual('../key-pair'),\n    generateKeyPair: jest.fn(),\n}));\n\nconst actualGenerateKeyPair = jest.requireActual<typeof import('../key-pair')>('../key-pair').generateKeyPair;\n\nasync function getAddressFromKeyPair(keyPair: CryptoKeyPair): Promise<string> {\n    const bytes = new Uint8Array(await crypto.subtle.exportKey('raw', keyPair.publicKey));\n    return getBase58Decoder().decode(bytes);\n}\n\n// Some tests in this file exercise the real `generateKeyPair` implementation,\n// which uses WebCrypto under the hood and cannot be seeded. As a result, the\n// addresses produced are genuinely random. To keep these tests fast and\n// deterministic (i.e. non-flaky), any test that does NOT mock\n// `generateKeyPair` must use an extremely permissive matcher — typically a\n// single-character regex prefix like `/^1/` or a trivial `() => true`\n// predicate — so that the grind loop converges within one batch. Do not\n// tighten these matchers: if you need to assert more specific behaviour,\n// mock `generateKeyPair` the same way the forwarding tests below do.\ndescribe('grind-keypair', () => {\n    beforeEach(() => {\n        // Reset to the real implementation between tests; individual tests can\n        // override with a custom implementation when needed.\n        jest.mocked(generateKeyPair).mockImplementation(actualGenerateKeyPair);\n    });\n\n    describe('grindKeyPair', () => {\n        it('returns a key pair whose address matches the provided regex', async () => {\n            expect.assertions(1);\n            const keyPair = await grindKeyPair({ matches: /^1/ });\n            const address = await getAddressFromKeyPair(keyPair);\n            expect(address).toMatch(/^1/);\n        });\n\n        it('returns a key pair whose address satisfies the provided predicate', async () => {\n            expect.assertions(1);\n            const keyPair = await grindKeyPair({ matches: address => address.startsWith('1') });\n            const address = await getAddressFromKeyPair(keyPair);\n            expect(address).toMatch(/^1/);\n        });\n\n        it('forwards `extractable: true` to `generateKeyPair`', async () => {\n            expect.assertions(1);\n            await grindKeyPair({ extractable: true, matches: () => true });\n            expect(jest.mocked(generateKeyPair)).toHaveBeenCalledWith(true);\n        });\n\n        it('forwards `extractable: false` to `generateKeyPair` by default', async () => {\n            expect.assertions(1);\n            await grindKeyPair({ matches: () => true });\n            expect(jest.mocked(generateKeyPair)).toHaveBeenCalledWith(false);\n        });\n\n        it('throws when the regex contains a non-base58 character', async () => {\n            expect.assertions(1);\n            await expect(grindKeyPair({ matches: /^foo0/ })).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX, {\n                    character: '0',\n                    source: '^foo0',\n                }),\n            );\n        });\n\n        it('throws immediately when the `AbortSignal` is already aborted', async () => {\n            expect.assertions(2);\n            const abortController = new AbortController();\n            abortController.abort(new Error('Already aborted'));\n            await expect(grindKeyPair({ abortSignal: abortController.signal, matches: () => true })).rejects.toThrow(\n                'Already aborted',\n            );\n            expect(jest.mocked(generateKeyPair)).not.toHaveBeenCalled();\n        });\n    });\n\n    describe('grindKeyPairs', () => {\n        it('returns the requested number of key pairs whose addresses all match', async () => {\n            expect.assertions(2);\n            const keyPairs = await grindKeyPairs({ amount: 3, matches: /^1/ });\n            expect(keyPairs).toHaveLength(3);\n            const addresses = await Promise.all(keyPairs.map(getAddressFromKeyPair));\n            expect(addresses.every(address => /^1/.test(address))).toBe(true);\n        });\n\n        it('returns an empty array when `amount` is `0`', async () => {\n            expect.assertions(2);\n            const keyPairs = await grindKeyPairs({ amount: 0, matches: () => true });\n            expect(keyPairs).toEqual([]);\n            expect(jest.mocked(generateKeyPair)).not.toHaveBeenCalled();\n        });\n\n        it('returns an empty array when `amount` is negative', async () => {\n            expect.assertions(2);\n            const keyPairs = await grindKeyPairs({ amount: -5, matches: () => true });\n            expect(keyPairs).toEqual([]);\n            expect(jest.mocked(generateKeyPair)).not.toHaveBeenCalled();\n        });\n\n        it('generates key pairs in batches of `concurrency`', async () => {\n            expect.assertions(1);\n            // With a permissive matcher and `amount: 1`, exactly one full\n            // batch of `concurrency` key pairs is generated before the loop\n            // exits.\n            await grindKeyPairs({ amount: 1, concurrency: 8, matches: () => true });\n            expect(jest.mocked(generateKeyPair)).toHaveBeenCalledTimes(8);\n        });\n\n        it('defaults to a concurrency of 32', async () => {\n            expect.assertions(1);\n            await grindKeyPairs({ amount: 1, matches: () => true });\n            expect(jest.mocked(generateKeyPair)).toHaveBeenCalledTimes(32);\n        });\n\n        it('throws when the regex contains a non-base58 character', async () => {\n            expect.assertions(1);\n            await expect(grindKeyPairs({ amount: 3, matches: /^foo0/ })).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX, {\n                    character: '0',\n                    source: '^foo0',\n                }),\n            );\n        });\n\n        it('still validates the regex when `amount` is `0`', async () => {\n            expect.assertions(1);\n            await expect(grindKeyPairs({ amount: 0, matches: /^foo0/ })).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX, {\n                    character: '0',\n                    source: '^foo0',\n                }),\n            );\n        });\n\n        it('rejects immediately when the `AbortSignal` fires during a batch', async () => {\n            expect.assertions(1);\n            const abortController = new AbortController();\n            // Mock `generateKeyPair` so the first call aborts the controller\n            // and returns a never-resolving promise, and all subsequent\n            // calls also hang. This simulates a batch that is cancelled\n            // while its key generations are still in flight. The returned\n            // promise from `grindKeyPairs` must reject immediately without\n            // waiting for those in-flight generations to settle.\n            jest.mocked(generateKeyPair)\n                .mockImplementationOnce(() => {\n                    abortController.abort(new Error('Mid-batch'));\n                    return new Promise<never>(() => {});\n                })\n                .mockImplementation(() => new Promise<never>(() => {}));\n\n            await expect(\n                grindKeyPairs({\n                    abortSignal: abortController.signal,\n                    amount: 1,\n                    matches: () => true,\n                }),\n            ).rejects.toThrow('Mid-batch');\n        });\n    });\n\n    describe('grindKeyPairs regex validation', () => {\n        // These tests exercise the static regex validation logic. They use\n        // `amount: 0` so that no key pairs are actually generated after a\n        // successful validation — the goal is to check that validation passes\n        // or throws as expected.\n        //\n        // The base58 alphabet excludes `0`, `O`, `I`, and lowercase `l`, so\n        // any prefix or suffix containing those characters should be rejected\n        // unless the `i` flag or a character class context allows it.\n\n        it.each([\n            { regex: /^foo/ },\n            { regex: /bar$/ },\n            { regex: /^foo.*bar$/ },\n            { regex: /^foo/i },\n            { regex: /[0-9]/ }, // char class is stripped\n            { regex: /(?:foo0)/ }, // group is stripped\n            { regex: /foo{10}/ }, // quantifier is stripped\n            { regex: /\\0/ }, // escape is stripped\n            { regex: /^[abc0]foo/ }, // class is stripped, foo is base58\n            { regex: /^(?:foo0|bar0)/ }, // group is stripped\n            { regex: /^FOO/i }, // upper/lower smartness: `O`'s lowercase `o` is base58\n        ])('accepts the regex $regex', async ({ regex }) => {\n            expect.assertions(1);\n            await expect(grindKeyPairs({ amount: 0, matches: regex })).resolves.toEqual([]);\n        });\n\n        it.each([\n            { character: '0', regex: /^foo0/ },\n            { character: 'O', regex: /^fooO/ },\n            { character: 'I', regex: /^fooI/ },\n            { character: 'l', regex: /^fool/ },\n            { character: '0', regex: /0bar$/ },\n            { character: 'O', regex: /^FOO/ },\n        ])('rejects the regex $regex', async ({ character, regex }) => {\n            expect.assertions(1);\n            await expect(grindKeyPairs({ amount: 0, matches: regex })).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX, {\n                    character,\n                    source: regex.source,\n                }),\n            );\n        });\n\n        it('does not validate function matchers', async () => {\n            expect.assertions(1);\n            // A function matcher that would be rejected if it were a regex.\n            const matches = (address: string) => address.includes('0');\n            // amount: 0 short-circuits, so the matcher is never called.\n            await expect(grindKeyPairs({ amount: 0, matches })).resolves.toEqual([]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/keys/src/__tests__/key-pair-test.ts",
    "content": "import {\n    SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n    SolanaError,\n} from '@solana/errors';\n\nimport { createKeyPairFromBytes, createKeyPairFromPrivateKeyBytes, generateKeyPair } from '../key-pair';\n\nconst MOCK_KEY_BYTES = new Uint8Array([\n    0xeb, 0xfa, 0x65, 0xeb, 0x93, 0xdc, 0x79, 0x15, 0x7a, 0xba, 0xde, 0xa2, 0xf7, 0x94, 0x37, 0x9d, 0xfc, 0x07, 0x1d,\n    0x68, 0x86, 0x87, 0x37, 0x6d, 0xc5, 0xd5, 0xa0, 0x54, 0x12, 0x1d, 0x34, 0x4a, 0x1d, 0x0e, 0x93, 0x86, 0x4d, 0xcc,\n    0x81, 0x5f, 0xc3, 0xf2, 0x86, 0x18, 0x09, 0x11, 0xd0, 0x0a, 0x3f, 0xd2, 0x06, 0xde, 0x31, 0xa1, 0xc9, 0x42, 0x87,\n    0xcb, 0x43, 0xf0, 0x5f, 0xc9, 0xf2, 0xb5,\n]);\n\nconst MOCK_INVALID_KEY_BYTES = new Uint8Array([\n    0xeb, 0xfa, 0x65, 0xeb, 0x93, 0xdc, 0x79, 0x15, 0x7a, 0xba, 0xde, 0xa2, 0xf7, 0x94, 0x37, 0x9d, 0xfc, 0x07, 0x1d,\n    0x68, 0x86, 0x87, 0x37, 0x6d, 0xc5, 0xd5, 0xa0, 0x54, 0x12, 0x1d, 0x34, 0x4a, 0x1d, 0x0e, 0x93, 0x86, 0x4d, 0xcc,\n    0x81, 0x5f, 0xc3, 0xf2, 0x86, 0x18, 0x09, 0x11, 0xd0, 0x0a, 0x3f, 0xd2, 0x06, 0xde, 0x31, 0xa1, 0xc9, 0x42, 0x87,\n    0xcb, 0x43, 0xf0, 0x5f, 0xc9, 0xf2, 0xb1,\n]);\n\ndescribe('key-pair', () => {\n    describe('generateKeyPair', () => {\n        it.each(['private', 'public'])('generates an ed25519 %s `CryptoKey`', async type => {\n            expect.assertions(1);\n            const keyPair = await generateKeyPair();\n            expect(keyPair).toMatchObject({\n                [`${type}Key`]: expect.objectContaining({\n                    [Symbol.toStringTag]: 'CryptoKey',\n                    algorithm: { name: 'Ed25519' },\n                    type,\n                }),\n            });\n        });\n        it('generates a non-extractable private key', async () => {\n            expect.assertions(1);\n            const { privateKey } = await generateKeyPair();\n            expect(privateKey).toHaveProperty('extractable', false);\n        });\n        it('generates a non-extractable private key when `extractable` is explicitly `false`', async () => {\n            expect.assertions(1);\n            const { privateKey } = await generateKeyPair(false);\n            expect(privateKey).toHaveProperty('extractable', false);\n        });\n        it('generates an extractable private key when `extractable` is `true`', async () => {\n            expect.assertions(1);\n            const { privateKey } = await generateKeyPair(true);\n            expect(privateKey).toHaveProperty('extractable', true);\n        });\n        it('generates a private key usable for signing operations', async () => {\n            expect.assertions(1);\n            const { privateKey } = await generateKeyPair();\n            expect(privateKey).toHaveProperty('usages', ['sign']);\n        });\n        it('generates an extractable public key', async () => {\n            expect.assertions(1);\n            const { publicKey } = await generateKeyPair();\n            expect(publicKey).toHaveProperty('extractable', true);\n        });\n        it('generates a public key usable for verifying signatures', async () => {\n            expect.assertions(1);\n            const { publicKey } = await generateKeyPair();\n            expect(publicKey).toHaveProperty('usages', ['verify']);\n        });\n    });\n\n    describe('createKeyPairFromBytes', () => {\n        it('creates a key pair from a 64-byte array', async () => {\n            expect.assertions(1);\n            const keyPair = await createKeyPairFromBytes(MOCK_KEY_BYTES);\n            expect(keyPair).toMatchObject({\n                privateKey: expect.objectContaining({\n                    [Symbol.toStringTag]: 'CryptoKey',\n                    algorithm: { name: 'Ed25519' },\n                    type: 'private',\n                }),\n                publicKey: expect.objectContaining({\n                    [Symbol.toStringTag]: 'CryptoKey',\n                    algorithm: { name: 'Ed25519' },\n                    type: 'public',\n                }),\n            });\n        });\n        it('errors when the byte array is not 64 bytes', async () => {\n            expect.assertions(1);\n            await expect(createKeyPairFromBytes(MOCK_KEY_BYTES.slice(0, 31))).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: 31 }),\n            );\n        });\n        it('errors when public key fails signature verification', async () => {\n            expect.assertions(1);\n            await expect(createKeyPairFromBytes(MOCK_INVALID_KEY_BYTES)).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY),\n            );\n        });\n    });\n\n    describe('createKeyPairFromPrivateKeyBytes', () => {\n        it('creates a key pair from a 32-bytes private key', async () => {\n            expect.assertions(1);\n            const keyPair = await createKeyPairFromPrivateKeyBytes(MOCK_KEY_BYTES.slice(0, 32));\n            expect(keyPair).toMatchObject({\n                privateKey: expect.objectContaining({\n                    [Symbol.toStringTag]: 'CryptoKey',\n                    algorithm: { name: 'Ed25519' },\n                    type: 'private',\n                }),\n                publicKey: expect.objectContaining({\n                    [Symbol.toStringTag]: 'CryptoKey',\n                    algorithm: { name: 'Ed25519' },\n                    type: 'public',\n                }),\n            });\n        });\n        it('uses the public key associated with the provided private key bytes', async () => {\n            expect.assertions(1);\n            const keyPair = await createKeyPairFromPrivateKeyBytes(MOCK_KEY_BYTES.slice(0, 32));\n            const publicKeyBytes = new Uint8Array(await crypto.subtle.exportKey('raw', keyPair.publicKey));\n            const expectedPublicKeyBytes = MOCK_KEY_BYTES.slice(32);\n            expect(publicKeyBytes).toEqual(expectedPublicKeyBytes);\n        });\n        it('errors when the byte array is not 32 bytes', async () => {\n            expect.assertions(1);\n            await expect(createKeyPairFromPrivateKeyBytes(MOCK_KEY_BYTES.slice(0, 31))).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, { actualLength: 31 }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/keys/src/__tests__/private-key-test.ts",
    "content": "import { createPrivateKeyFromBytes } from '../private-key';\n\nconst MOCK_DATA = new Uint8Array([1, 2, 3]);\nconst MOCK_DATA_SIGNATURE = new Uint8Array([\n    66, 111, 184, 228, 239, 189, 127, 46, 23, 168, 117, 69, 58, 143, 132, 164, 112, 189, 203, 228, 183, 151, 0, 23, 179,\n    181, 52, 75, 112, 225, 150, 128, 184, 164, 36, 21, 101, 205, 115, 28, 127, 221, 24, 135, 229, 8, 69, 232, 16, 225,\n    44, 229, 17, 236, 206, 174, 102, 207, 79, 253, 96, 7, 174, 10,\n]);\nconst MOCK_PRIVATE_KEY_BYTES = new Uint8Array([\n    0xeb, 0xfa, 0x65, 0xeb, 0x93, 0xdc, 0x79, 0x15, 0x7a, 0xba, 0xde, 0xa2, 0xf7, 0x94, 0x37, 0x9d, 0xfc, 0x07, 0x1d,\n    0x68, 0x86, 0x87, 0x37, 0x6d, 0xc5, 0xd5, 0xa0, 0x54, 0x12, 0x1d, 0x34, 0x4a,\n]);\n\ndescribe('createPrivateKeyFromBytes', () => {\n    it.each([0, 16, 31, 33])('throws when the bytes are of length %s', async length => {\n        expect.assertions(1);\n        await expect(createPrivateKeyFromBytes(new Uint8Array(length))).rejects.toThrow();\n    });\n    describe('given a key created from valid private key bytes', () => {\n        let privateKey: CryptoKey;\n        beforeEach(async () => {\n            privateKey = await createPrivateKeyFromBytes(MOCK_PRIVATE_KEY_BYTES);\n        });\n        it('is non-extractable', () => {\n            expect(privateKey).toHaveProperty('extractable', false);\n        });\n        it('has the expected metadata', () => {\n            expect(privateKey).toMatchObject({\n                [Symbol.toStringTag]: 'CryptoKey',\n                algorithm: { name: 'Ed25519' },\n                type: 'private',\n                usages: ['sign'],\n            });\n        });\n        it('can be used to produce the expected signature', async () => {\n            expect.assertions(1);\n            const signature = await crypto.subtle.sign('Ed25519', privateKey, MOCK_DATA);\n            expect(new Uint8Array(signature)).toEqual(MOCK_DATA_SIGNATURE);\n        });\n    });\n    describe.each([true, false])(\n        'given a key created with the `extractable` option set to `%s`',\n        expectedExtractability => {\n            let privateKey: CryptoKey;\n            beforeEach(async () => {\n                privateKey = await createPrivateKeyFromBytes(\n                    MOCK_PRIVATE_KEY_BYTES,\n                    /* extractable */ expectedExtractability,\n                );\n            });\n            it('has the expected extractability', () => {\n                expect(privateKey).toHaveProperty('extractable', expectedExtractability);\n            });\n            if (expectedExtractability) {\n                it('can be exported', async () => {\n                    expect.assertions(1);\n                    expect(new Uint8Array(await crypto.subtle.exportKey('pkcs8', privateKey))).toEqual(\n                        // prettier-ignore\n                        new Uint8Array([\n                            /**\n                             * PKCS#8 header\n                             */\n                            0x30, // ASN.1 sequence tag\n                            0x2e, // Length of sequence (46 more bytes)\n\n                                0x02, // ASN.1 integer tag\n                                0x01, // Length of integer\n                                    0x00, // Version number\n\n                                0x30, // ASN.1 sequence tag\n                                0x05, // Length of sequence\n                                    0x06, // ASN.1 object identifier tag\n                                    0x03, // Length of object identifier\n                                        // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n                                            0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n                                            0x65, // thawte(101)\n                                        // Ed25519 identifier\n                                            0x70, // id-Ed25519(112)\n\n                            /**\n                             * Private key payload\n                             */\n                            0x04, // ASN.1 octet string tag\n                            0x22, // String length (34 more bytes)\n\n                                // Private key bytes as octet string\n                                0x04, // ASN.1 octet string tag\n                                0x20, // String length (32 bytes)\n                                ...MOCK_PRIVATE_KEY_BYTES,\n                        ]),\n                    );\n                });\n            } else {\n                it('throws if you try to export it', async () => {\n                    expect.assertions(1);\n                    await expect(crypto.subtle.exportKey('pkcs8', privateKey)).rejects.toThrow(\n                        'key is not extractable',\n                    );\n                });\n            }\n        },\n    );\n});\n"
  },
  {
    "path": "packages/keys/src/__tests__/public-key-test.ts",
    "content": "import { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\nimport { createPrivateKeyFromBytes } from '../private-key';\nimport { getPublicKeyFromPrivateKey } from '../public-key';\n\nconst MOCK_PRIVATE_KEY_BYTES = new Uint8Array([\n    0xeb, 0xfa, 0x65, 0xeb, 0x93, 0xdc, 0x79, 0x15, 0x7a, 0xba, 0xde, 0xa2, 0xf7, 0x94, 0x37, 0x9d, 0xfc, 0x07, 0x1d,\n    0x68, 0x86, 0x87, 0x37, 0x6d, 0xc5, 0xd5, 0xa0, 0x54, 0x12, 0x1d, 0x34, 0x4a,\n]);\n\nconst EXPECTED_MOCK_PUBLIC_KEY_BYTES = new Uint8Array([\n    0x1d, 0x0e, 0x93, 0x86, 0x4d, 0xcc, 0x81, 0x5f, 0xc3, 0xf2, 0x86, 0x18, 0x09, 0x11, 0xd0, 0x0a, 0x3f, 0xd2, 0x06,\n    0xde, 0x31, 0xa1, 0xc9, 0x42, 0x87, 0xcb, 0x43, 0xf0, 0x5f, 0xc9, 0xf2, 0xb5,\n]);\n\ndescribe('getPublicKeyFromPrivateKey', () => {\n    describe('given an extractable private key', () => {\n        let privateKey: CryptoKey;\n        beforeEach(async () => {\n            privateKey = await createPrivateKeyFromBytes(MOCK_PRIVATE_KEY_BYTES, true);\n        });\n        it('gets the associated public key', async () => {\n            expect.assertions(1);\n            const publicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n            const publicKeyBytes = new Uint8Array(await crypto.subtle.exportKey('raw', publicKey));\n            expect(publicKeyBytes).toEqual(EXPECTED_MOCK_PUBLIC_KEY_BYTES);\n        });\n        it('can get an extractable public key', async () => {\n            expect.assertions(1);\n            const publicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n            expect(publicKey.extractable).toBe(true);\n        });\n        it('can get a non-extractable public key', async () => {\n            expect.assertions(1);\n            const publicKey = await getPublicKeyFromPrivateKey(privateKey, false);\n            expect(publicKey.extractable).toBe(false);\n        });\n        it('returns a non-extractable public key by default', async () => {\n            expect.assertions(1);\n            const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n            expect(publicKey.extractable).toBe(false);\n        });\n    });\n    describe('given a non-extractable private key', () => {\n        let privateKey: CryptoKey;\n        beforeEach(async () => {\n            privateKey = await createPrivateKeyFromBytes(MOCK_PRIVATE_KEY_BYTES, false);\n        });\n        it('cannot get the associated public key', async () => {\n            expect.assertions(1);\n            await expect(() => getPublicKeyFromPrivateKey(privateKey, true)).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/keys/src/__tests__/signatures-test.ts",
    "content": "import { createEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\n\nimport { createPrivateKeyFromBytes } from '../private-key';\nimport { assertIsSignatureBytes, SignatureBytes, signBytes, verifySignature } from '../signatures';\n\njest.mock('@solana/codecs-strings', () => ({\n    ...jest.requireActual('@solana/codecs-strings'),\n    getBase58Encoder: jest.fn(),\n}));\n\nconst MOCK_DATA = new Uint8Array([1, 2, 3]);\nconst MOCK_DATA_SIGNATURE = new Uint8Array([\n    66, 111, 184, 228, 239, 189, 127, 46, 23, 168, 117, 69, 58, 143, 132, 164, 112, 189, 203, 228, 183, 151, 0, 23, 179,\n    181, 52, 75, 112, 225, 150, 128, 184, 164, 36, 21, 101, 205, 115, 28, 127, 221, 24, 135, 229, 8, 69, 232, 16, 225,\n    44, 229, 17, 236, 206, 174, 102, 207, 79, 253, 96, 7, 174, 10,\n]);\nconst MOCK_PRIVATE_KEY_BYTES = new Uint8Array([\n    0xeb, 0xfa, 0x65, 0xeb, 0x93, 0xdc, 0x79, 0x15, 0x7a, 0xba, 0xde, 0xa2, 0xf7, 0x94, 0x37, 0x9d, 0xfc, 0x07, 0x1d,\n    0x68, 0x86, 0x87, 0x37, 0x6d, 0xc5, 0xd5, 0xa0, 0x54, 0x12, 0x1d, 0x34, 0x4a,\n]);\nconst MOCK_PUBLIC_KEY_BYTES = new Uint8Array([\n    0x1d, 0x0e, 0x93, 0x86, 0x4d, 0xcc, 0x81, 0x5f, 0xc3, 0xf2, 0x86, 0x18, 0x09, 0x11, 0xd0, 0x0a, 0x3f, 0xd2, 0x06,\n    0xde, 0x31, 0xa1, 0xc9, 0x42, 0x87, 0xcb, 0x43, 0xf0, 0x5f, 0xc9, 0xf2, 0xb5,\n]);\n\n// real implementations\nconst originalBase58Module = jest.requireActual('@solana/codecs-strings');\nconst originalGetBase58Encoder = originalBase58Module.getBase58Encoder();\n\ndescribe('assertIsSignature()', () => {\n    let assertIsSignature: typeof import('../signatures').assertIsSignature;\n    // Reload `assertIsSignature` before each test to reset memoized state\n    beforeEach(async () => {\n        await jest.isolateModulesAsync(async () => {\n            const base58ModulePromise =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                import('../signatures');\n            assertIsSignature = (await base58ModulePromise).assertIsSignature;\n        });\n    });\n\n    describe('using the real base58 implementation', () => {\n        beforeEach(() => {\n            // use real implementation\n            jest.mocked(getBase58Encoder).mockReturnValue(originalGetBase58Encoder);\n        });\n\n        it('throws when supplied a non-base58 string', () => {\n            expect(() => {\n                assertIsSignature('not-a-base-58-encoded-string');\n            }).toThrow();\n        });\n        it('throws when the decoded byte array has a length other than 32 bytes', () => {\n            expect(() => {\n                assertIsSignature(\n                    // 63 bytes [128, ..., 128]\n                    '1'.repeat(63),\n                );\n            }).toThrow();\n        });\n        it('does not throw when supplied a base-58 encoded signature', () => {\n            expect(() => {\n                // 64 bytes [0, ..., 0]\n                assertIsSignature('1'.repeat(64));\n\n                // example signatures\n                assertIsSignature(\n                    '5HkW5GttYoahVHaujuxEyfyq7RwvoKpc94ko5Fq9GuYdyhejg9cHcqm1MjEvHsjaADRe6hVBqB2E4RQgGgxeA2su',\n                );\n                assertIsSignature(\n                    '2VZm7DkqSKaHxsGiAuVuSkvEbGWf7JrfRdPTw42WKuJC8qw7yQbGL5AE7UxHH3tprgmT9EVbambnK9h3PLpvMvES',\n                );\n                assertIsSignature(\n                    '5sXRtm61WrRGRTjJ6f2anKUWt86Y4V9gWU4WUpue4T4Zh6zuvFoSyaX5LkEtChfqVC8oHdqLo2eUXbhVduThBdfG',\n                );\n                assertIsSignature(\n                    '2Dy6Qai5JyChoP4BKoh9KAYhpD96CUhmEce1GJ8HpV5h8Q4CgUt8KZQzhVNDEQYcjARxYyBNhNjhKUGC2XLZtCCm',\n                );\n            }).not.toThrow();\n        });\n        it('returns undefined when supplied a base-58 encoded signature', () => {\n            // 64 bytes [0, ..., 0]\n            expect(assertIsSignature('1'.repeat(64))).toBeUndefined();\n        });\n    });\n\n    describe('using a mock base58 implementation', () => {\n        const mockWrite = jest.fn();\n        beforeEach(() => {\n            // use mock implementation\n            mockWrite.mockClear();\n            jest.mocked(getBase58Encoder).mockReturnValue(\n                createEncoder({\n                    fixedSize: 64,\n                    write: mockWrite,\n                }) as unknown as VariableSizeEncoder<string>,\n            );\n        });\n        [64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88].forEach(\n            len => {\n                it(`attempts to decode input strings of exactly ${len} characters`, () => {\n                    try {\n                        assertIsSignature('1'.repeat(len));\n                        // eslint-disable-next-line no-empty\n                    } catch {}\n                    expect(mockWrite).toHaveBeenCalledTimes(1);\n                });\n            },\n        );\n        it('does not attempt to decode too-short input strings', () => {\n            try {\n                assertIsSignature(\n                    // 63 bytes [0, ..., 0]\n                    '1'.repeat(63),\n                );\n                // eslint-disable-next-line no-empty\n            } catch {}\n            expect(mockWrite).not.toHaveBeenCalled();\n        });\n        it('does not attempt to decode too-long input strings', () => {\n            try {\n                assertIsSignature(\n                    // 65 bytes [0, 255, ..., 255]\n                    '167rpwLCuS5DGA8KGZXKsVQ7dnPb9goRLoKfgGbLfQg9WoLUgNY77E2jT11fem3coV9nAkguBACzrU1iyZM4B8roQ',\n                );\n                // eslint-disable-next-line no-empty\n            } catch {}\n            expect(mockWrite).not.toHaveBeenCalled();\n        });\n        it('memoizes getBase58Encoder when called multiple times', () => {\n            try {\n                assertIsSignature('1'.repeat(64));\n                // eslint-disable-next-line no-empty\n            } catch {}\n            try {\n                assertIsSignature('1'.repeat(64));\n                // eslint-disable-next-line no-empty\n            } catch {}\n            expect(jest.mocked(getBase58Encoder)).toHaveBeenCalledTimes(1);\n        });\n    });\n});\n\ndescribe('assertIsSignatureBytes()', () => {\n    it('throws when supplied an empty byte array', () => {\n        expect(() => {\n            assertIsSignatureBytes(new Uint8Array(0));\n        }).toThrow();\n    });\n    it.each([63, 65])('throws when the byte array has a length of %s', length => {\n        expect(() => {\n            assertIsSignatureBytes(new Uint8Array(length));\n        }).toThrow();\n    });\n    it('does not throw when supplied a zeroed 64-byte bytearray', () => {\n        expect(() => {\n            assertIsSignatureBytes(new Uint8Array(64));\n        }).not.toThrow();\n    });\n    it('does not throw when supplied a 64-byte signature as a bytearray', () => {\n        expect(() => {\n            assertIsSignatureBytes(MOCK_DATA_SIGNATURE);\n        }).not.toThrow();\n    });\n    it('returns undefined when supplied a 64-byte byte array', () => {\n        // 64 bytes [0, ..., 0]\n        expect(assertIsSignatureBytes(new Uint8Array(64))).toBeUndefined();\n    });\n});\n\ndescribe('sign', () => {\n    it('produces the expected signature given a private key', async () => {\n        expect.assertions(1);\n        const privateKey = await createPrivateKeyFromBytes(MOCK_PRIVATE_KEY_BYTES, /* extractable */ false);\n        const signature = await signBytes(privateKey, MOCK_DATA);\n        expect(signature).toEqual(MOCK_DATA_SIGNATURE);\n    });\n    it('produces signatures 64 bytes in length', async () => {\n        expect.assertions(1);\n        const { privateKey } = await crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign']);\n        const signature = await signBytes(privateKey, MOCK_DATA);\n        expect(signature).toHaveLength(64);\n    });\n});\n\ndescribe('verify', () => {\n    let mockPublicKey: CryptoKey;\n    beforeEach(async () => {\n        mockPublicKey = await crypto.subtle.importKey(\n            'raw',\n            MOCK_PUBLIC_KEY_BYTES,\n            'Ed25519',\n            /* extractable */ false,\n            ['verify'],\n        );\n    });\n    it('returns `true` when the correct signature is supplied for a given payload', async () => {\n        expect.assertions(1);\n        const result = await verifySignature(mockPublicKey, MOCK_DATA_SIGNATURE as SignatureBytes, MOCK_DATA);\n        expect(result).toBe(true);\n    });\n    it('returns `false` when a bad signature is supplied for a given payload', async () => {\n        expect.assertions(1);\n        const badSignature = new Uint8Array(Array(64).fill(1)) as SignatureBytes;\n        const result = await verifySignature(mockPublicKey, badSignature, MOCK_DATA);\n        expect(result).toBe(false);\n    });\n    it('returns `false` when the signature 65 bytes long', async () => {\n        expect.assertions(1);\n        const badSignature = new Uint8Array([...MOCK_DATA_SIGNATURE, 1]) as SignatureBytes;\n        const result = await verifySignature(mockPublicKey, badSignature, MOCK_DATA);\n        expect(result).toBe(false);\n    });\n    it('returns `false` when the signature 63 bytes long', async () => {\n        expect.assertions(1);\n        const badSignature = MOCK_DATA_SIGNATURE.slice(0, 63) as SignatureBytes;\n        const result = await verifySignature(mockPublicKey, badSignature, MOCK_DATA);\n        expect(result).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/keys/src/__tests__/write-keypair-test.browser.ts",
    "content": "import { SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT, SolanaError } from '@solana/errors';\n\nimport { generateKeyPair } from '../key-pair';\nimport { writeKeyPair } from '../write-keypair';\n\ndescribe('writeKeyPair', () => {\n    it('throws with `SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT` when called outside Node', async () => {\n        expect.assertions(1);\n        const keyPair = await generateKeyPair(/* extractable */ true);\n        await expect(writeKeyPair(keyPair, '/fake/path/keypair.json')).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/keys/src/__tests__/write-keypair-test.node.ts",
    "content": "import { mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\n\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\nimport { createKeyPairFromBytes, generateKeyPair } from '../key-pair';\nimport { createPrivateKeyFromBytes } from '../private-key';\nimport { getPublicKeyFromPrivateKey } from '../public-key';\nimport { writeKeyPair } from '../write-keypair';\n\nconst MOCK_PRIVATE_KEY_BYTES = new Uint8Array([\n    0xeb, 0xfa, 0x65, 0xeb, 0x93, 0xdc, 0x79, 0x15, 0x7a, 0xba, 0xde, 0xa2, 0xf7, 0x94, 0x37, 0x9d, 0xfc, 0x07, 0x1d,\n    0x68, 0x86, 0x87, 0x37, 0x6d, 0xc5, 0xd5, 0xa0, 0x54, 0x12, 0x1d, 0x34, 0x4a,\n]);\n\ndescribe('writeKeyPair', () => {\n    let tmpDir: string;\n    let mockKeyPair: CryptoKeyPair;\n    let mockPublicKeyBytes: Uint8Array;\n    beforeEach(async () => {\n        tmpDir = await mkdtemp(join(tmpdir(), 'kit-write-keypair-'));\n        // Build an extractable key pair from the known private key bytes so we can assert exact file contents.\n        const privateKey = await createPrivateKeyFromBytes(MOCK_PRIVATE_KEY_BYTES, /* extractable */ true);\n        const publicKey = await getPublicKeyFromPrivateKey(privateKey, /* extractable */ true);\n        mockKeyPair = { privateKey, publicKey };\n        mockPublicKeyBytes = new Uint8Array(await crypto.subtle.exportKey('raw', publicKey));\n    });\n    afterEach(async () => {\n        await rm(tmpDir, { force: true, recursive: true });\n    });\n    it('writes the key pair to disk as a JSON array of 64 bytes', async () => {\n        expect.assertions(1);\n        const path = join(tmpDir, 'keypair.json');\n        await writeKeyPair(mockKeyPair, path);\n        const contents = await readFile(path, 'utf8');\n        expect(JSON.parse(contents)).toEqual([...MOCK_PRIVATE_KEY_BYTES, ...mockPublicKeyBytes]);\n    });\n    it('writes bytes that can be round-tripped back through `createKeyPairFromBytes`', async () => {\n        expect.assertions(1);\n        const path = join(tmpDir, 'keypair.json');\n        await writeKeyPair(mockKeyPair, path);\n        const contents = await readFile(path, 'utf8');\n        const recreatedKeyPair = await createKeyPairFromBytes(new Uint8Array(JSON.parse(contents)));\n        const recreatedPublicKeyBytes = new Uint8Array(\n            await crypto.subtle.exportKey('raw', recreatedKeyPair.publicKey),\n        );\n        expect(recreatedPublicKeyBytes).toEqual(mockPublicKeyBytes);\n    });\n    it('writes the file with owner-readable and owner-writable mode', async () => {\n        expect.assertions(1);\n        const path = join(tmpDir, 'keypair.json');\n        await writeKeyPair(mockKeyPair, path);\n        const stats = await stat(path);\n        const mode = stats.mode & 0o777;\n        // Windows does not honor POSIX mode bits: the `mode` option passed to\n        // `fs.writeFile` is effectively ignored, and Node synthesizes the reported\n        // `stats.mode` bits from the file's DOS attributes. On Windows we can only\n        // verify that the file is readable and writable by its owner; on POSIX we\n        // assert the exact `0o600` mode.\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (process.platform === 'win32') {\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mode & 0o600).toBe(0o600);\n        } else {\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mode).toBe(0o600);\n        }\n    });\n    it('creates missing parent directories recursively', async () => {\n        expect.assertions(1);\n        const path = join(tmpDir, 'nested', 'deeply', 'keypair.json');\n        await writeKeyPair(mockKeyPair, path);\n        const contents = await readFile(path, 'utf8');\n        expect(JSON.parse(contents)).toEqual([...MOCK_PRIVATE_KEY_BYTES, ...mockPublicKeyBytes]);\n    });\n    it('throws when the private key is not extractable', async () => {\n        expect.assertions(1);\n        const nonExtractableKeyPair = await generateKeyPair(/* extractable */ false);\n        await expect(writeKeyPair(nonExtractableKeyPair, join(tmpDir, 'keypair.json'))).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, {\n                key: nonExtractableKeyPair.privateKey,\n            }),\n        );\n    });\n    it('throws when the public key is not extractable', async () => {\n        expect.assertions(1);\n        const privateKey = await createPrivateKeyFromBytes(MOCK_PRIVATE_KEY_BYTES, /* extractable */ true);\n        const publicKey = await getPublicKeyFromPrivateKey(privateKey, /* extractable */ false);\n        const keyPair: CryptoKeyPair = { privateKey, publicKey };\n        await expect(writeKeyPair(keyPair, join(tmpDir, 'keypair.json'))).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, {\n                key: publicKey,\n            }),\n        );\n    });\n    it('refuses to overwrite an existing file by default', async () => {\n        expect.assertions(2);\n        const path = join(tmpDir, 'keypair.json');\n        await writeFile(path, 'pre-existing contents');\n        await expect(writeKeyPair(mockKeyPair, path)).rejects.toThrow(expect.objectContaining({ code: 'EEXIST' }));\n        // Verify the original file was not modified.\n        await expect(readFile(path, 'utf8')).resolves.toBe('pre-existing contents');\n    });\n    it('overwrites an existing file when `unsafelyOverwriteExistingKeyPair` is set', async () => {\n        expect.assertions(1);\n        const path = join(tmpDir, 'keypair.json');\n        await writeFile(path, 'pre-existing contents');\n        await writeKeyPair(mockKeyPair, path, { unsafelyOverwriteExistingKeyPair: true });\n        const contents = await readFile(path, 'utf8');\n        expect(JSON.parse(contents)).toEqual([...MOCK_PRIVATE_KEY_BYTES, ...mockPublicKeyBytes]);\n    });\n});\n"
  },
  {
    "path": "packages/keys/src/__typetests__/key-pair-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { createKeyPairFromBytes, createKeyPairFromPrivateKeyBytes } from '../key-pair';\n\ncreateKeyPairFromBytes(new Uint8Array()) satisfies Promise<CryptoKeyPair>;\ncreateKeyPairFromBytes(new Uint8Array() as ReadonlyUint8Array) satisfies Promise<CryptoKeyPair>;\ncreateKeyPairFromBytes(new Uint8Array(), true) satisfies Promise<CryptoKeyPair>;\n\ncreateKeyPairFromPrivateKeyBytes(new Uint8Array()) satisfies Promise<CryptoKeyPair>;\ncreateKeyPairFromPrivateKeyBytes(new Uint8Array() as ReadonlyUint8Array) satisfies Promise<CryptoKeyPair>;\ncreateKeyPairFromPrivateKeyBytes(new Uint8Array(), true) satisfies Promise<CryptoKeyPair>;\n"
  },
  {
    "path": "packages/keys/src/__typetests__/private-key-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { createPrivateKeyFromBytes } from '../private-key';\n\ncreatePrivateKeyFromBytes(new Uint8Array()) satisfies Promise<CryptoKey>;\ncreatePrivateKeyFromBytes(new Uint8Array() as ReadonlyUint8Array) satisfies Promise<CryptoKey>;\n"
  },
  {
    "path": "packages/keys/src/__typetests__/public-key-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { getPublicKeyFromPrivateKey } from '../public-key';\n\ngetPublicKeyFromPrivateKey(new CryptoKey()) satisfies Promise<CryptoKey>;\ngetPublicKeyFromPrivateKey(new CryptoKey(), true) satisfies Promise<CryptoKey>;\ngetPublicKeyFromPrivateKey(new CryptoKey(), false) satisfies Promise<CryptoKey>;\n"
  },
  {
    "path": "packages/keys/src/__typetests__/signatures-typetest.ts",
    "content": "import { EncodedString } from '@solana/nominal-types';\n\nimport { Signature, signature, SignatureBytes, signatureBytes } from '../signatures';\n\n// [DESCRIBE] signature()\n{\n    // It returns a `Signature`\n    {\n        signature('x') satisfies Signature;\n    }\n}\n\n// [DESCRIBE] Signature\n{\n    // It satisfies the base58 encoded string brand\n    {\n        const signature = null as unknown as Signature;\n        signature satisfies EncodedString<string, 'base58'>;\n    }\n}\n\n// [DESCRIBE] signatureBytes()\n{\n    // It returns a `SignatureBytes`\n    {\n        signatureBytes(new Uint8Array(0)) satisfies SignatureBytes;\n    }\n}\n\n// [DESCRIBE] SignatureBytes\n{\n    // It satisfies the `Uint8Array` type\n    {\n        const signatureBytes = null as unknown as SignatureBytes;\n        signatureBytes satisfies Uint8Array;\n    }\n}\n"
  },
  {
    "path": "packages/keys/src/__typetests__/write-keypair-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { writeKeyPair } from '../write-keypair';\n\n// [DESCRIBE] writeKeyPair\n{\n    const keyPair = null as unknown as CryptoKeyPair;\n\n    // It accepts a key pair and a path\n    {\n        writeKeyPair(keyPair, './keypair.json') satisfies Promise<void>;\n    }\n\n    // It accepts an optional config argument\n    {\n        writeKeyPair(keyPair, './keypair.json', {}) satisfies Promise<void>;\n        writeKeyPair(keyPair, './keypair.json', { unsafelyOverwriteExistingKeyPair: true }) satisfies Promise<void>;\n        writeKeyPair(keyPair, './keypair.json', { unsafelyOverwriteExistingKeyPair: false }) satisfies Promise<void>;\n    }\n}\n"
  },
  {
    "path": "packages/keys/src/algorithm.ts",
    "content": "export const ED25519_ALGORITHM_IDENTIFIER =\n    // Resist the temptation to convert this to a simple string; As of version 133.0.3, Firefox\n    // requires the object form of `AlgorithmIdentifier` and will throw a `DOMException` otherwise.\n    Object.freeze({ name: 'Ed25519' });\n"
  },
  {
    "path": "packages/keys/src/grind-keypair.ts",
    "content": "import { getBase58Decoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX, SolanaError } from '@solana/errors';\nimport { getAbortablePromise } from '@solana/promises';\n\nimport { generateKeyPair } from './key-pair';\n\n/**\n * A function or {@link RegExp} used to test whether a candidate base58-encoded\n * address produced from a generated key pair satisfies the grind criteria.\n *\n * - When a `RegExp` is provided, its literal characters (outside of escape\n *   sequences, character classes, quantifiers, and groups) are validated up\n *   front to ensure they are all in the base58 alphabet. This catches common\n *   typos like `/^ab0/` before any key generation takes place.\n * - When a function is provided, it is used as-is with no validation. Use this\n *   form when you need arbitrary matching logic that falls outside what a\n *   simple regex can express.\n *\n * @see {@link grindKeyPair}\n * @see {@link grindKeyPairs}\n */\nexport type GrindKeyPairMatches = RegExp | ((address: string) => boolean);\n\n/**\n * Configuration object accepted by {@link grindKeyPairs}.\n *\n * @see {@link grindKeyPairs}\n * @see {@link GrindKeyPairMatches}\n */\nexport type GrindKeyPairsConfig = Readonly<{\n    /**\n     * An optional {@link AbortSignal} used to cancel the grind loop. When the\n     * signal fires, the returned promise rejects immediately with the signal's\n     * reason, even if a batch of key pair generations is still in flight (the\n     * in-flight generations are abandoned in the background).\n     */\n    abortSignal?: AbortSignal;\n    /**\n     * The number of matching key pairs to return. Defaults to `1`. Values less\n     * than or equal to `0` cause the function to return an empty array without\n     * generating any key pairs (after validating the `matches` regex, if any).\n     */\n    amount?: number;\n    /**\n     * The number of key pairs to generate in parallel per batch. Defaults to\n     * `32`. Higher values increase throughput at the cost of more memory\n     * pressure per batch.\n     */\n    concurrency?: number;\n    /**\n     * Setting this to `true` makes it possible to extract the bytes of the\n     * generated private keys using\n     * [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey).\n     * This value is forwarded to the inner {@link generateKeyPair} call and\n     * defaults to `false`, which prevents the bytes of the private key from\n     * being visible to JS.\n     */\n    extractable?: boolean;\n    /**\n     * Either a {@link RegExp} or a predicate function that tests candidate\n     * base58-encoded addresses. See {@link GrindKeyPairMatches} for details.\n     */\n    matches: GrindKeyPairMatches;\n}>;\n\n// Matches regex parts that should be skipped during base58 validation:\n//   - `\\<any>` escape sequences\n//   - `[...]` character classes\n//   - `{...}` quantifiers\n//   - `(...)` groups\nconst STRIP_UNVALIDATED_REGEX_PARTS = /\\\\.|\\[[^\\]]*\\]|\\{[^}]*\\}|\\([^)]*\\)/g;\n\n// Matches regex metacharacters and stray grouping delimiters that may remain\n// after stripping the unvalidated parts above.\nconst STRIP_GRIND_METACHARACTERS = /[$()*+./?[\\]^{|}]/g;\n\n// Matches a string containing only characters from the base58 alphabet.\nconst BASE58_ALPHABET_REGEX = /^[1-9A-HJ-NP-Za-km-z]*$/;\n\n/**\n * Validates that every top-level literal character in the provided regex is\n * part of the base58 alphabet used by Solana addresses. Characters inside\n * escape sequences, character classes, quantifiers, and groups are skipped\n * because they cannot be analyzed reliably without a full regex parser.\n *\n * When the regex has the `i` flag, a literal character is considered valid if\n * either its upper-case or lower-case form is in the base58 alphabet.\n *\n * Throws {@link SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX} on the first\n * invalid character encountered.\n */\nfunction assertGrindRegexIsValid(regex: RegExp): void {\n    const stripped = regex.source.replace(STRIP_UNVALIDATED_REGEX_PARTS, '').replace(STRIP_GRIND_METACHARACTERS, '');\n\n    const isBase58Character = (character: string): boolean => {\n        if (regex.ignoreCase) {\n            return (\n                BASE58_ALPHABET_REGEX.test(character.toLowerCase()) ||\n                BASE58_ALPHABET_REGEX.test(character.toUpperCase())\n            );\n        }\n        return BASE58_ALPHABET_REGEX.test(character);\n    };\n\n    for (const character of stripped) {\n        if (!isBase58Character(character)) {\n            throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX, {\n                character,\n                source: regex.source,\n            });\n        }\n    }\n}\n\n/**\n * Generates multiple Ed25519 key pairs whose base58-encoded public key\n * satisfies the provided `matches` criterion.\n *\n * Key pairs are generated in batches of `concurrency` in parallel and tested\n * against the matcher. The loop continues until `amount` matching key pairs\n * have been found or the provided `abortSignal` is aborted.\n *\n * When `matches` is a {@link RegExp}, its literal characters are validated\n * against the base58 alphabet up front to prevent infinite loops caused by\n * typos (e.g. `/^anza0/`). When `matches` is a function, it is used as-is\n * with no validation.\n *\n * @param config - See {@link GrindKeyPairsConfig}.\n * @returns A promise that resolves to an array of exactly `amount`\n * {@link CryptoKeyPair} instances, each of which satisfies the matcher. When\n * `amount <= 0`, the promise resolves to an empty array.\n *\n * @example\n * Find four key pairs whose address starts with `anza`:\n * ```ts\n * import { grindKeyPairs } from '@solana/keys';\n *\n * const keyPairs = await grindKeyPairs({ matches: /^anza/, amount: 4 });\n * ```\n *\n * @example\n * Use a predicate function for arbitrary matching logic:\n * ```ts\n * import { grindKeyPairs } from '@solana/keys';\n *\n * const keyPairs = await grindKeyPairs({\n *     matches: address => address.startsWith('anza') && address.endsWith('end'),\n *     amount: 2,\n * });\n * ```\n *\n * @example\n * Cancel a long-running grind using an {@link AbortSignal}:\n * ```ts\n * import { grindKeyPairs } from '@solana/keys';\n *\n * const keyPairs = await grindKeyPairs({\n *     matches: /^anza/,\n *     amount: 10,\n *     abortSignal: AbortSignal.timeout(60_000),\n * });\n * ```\n *\n * @see {@link grindKeyPair}\n */\nexport async function grindKeyPairs(config: GrindKeyPairsConfig): Promise<CryptoKeyPair[]> {\n    const { abortSignal, amount = 1, concurrency = 32, extractable = false, matches } = config;\n\n    let matcher: (address: string) => boolean;\n    if (typeof matches === 'function') {\n        matcher = matches;\n    } else {\n        assertGrindRegexIsValid(matches);\n        matcher = address => matches.test(address);\n    }\n\n    if (amount <= 0) {\n        return [];\n    }\n\n    const base58Decoder = getBase58Decoder();\n    const found: CryptoKeyPair[] = [];\n\n    while (found.length < amount) {\n        abortSignal?.throwIfAborted();\n\n        // Generate one batch of `concurrency` key pairs in parallel. The\n        // batch is wrapped in `getAbortablePromise` so that cancellation\n        // takes effect as soon as the signal fires, rather than waiting for\n        // the in-flight key generations to settle.\n        const batch = await getAbortablePromise(\n            Promise.all(\n                Array.from({ length: concurrency }, async () => {\n                    const keyPair = await generateKeyPair(extractable);\n                    const publicKeyBytes = new Uint8Array(await crypto.subtle.exportKey('raw', keyPair.publicKey));\n                    const address = base58Decoder.decode(publicKeyBytes);\n                    return { address, keyPair };\n                }),\n            ),\n            abortSignal,\n        );\n\n        for (const { address, keyPair } of batch) {\n            if (found.length >= amount) break;\n            if (matcher(address)) {\n                found.push(keyPair);\n            }\n        }\n    }\n\n    return found;\n}\n\n/**\n * Generates a single Ed25519 key pair whose base58-encoded public key\n * satisfies the provided `matches` criterion. This is the main entry point\n * for mining vanity Solana addresses: the function keeps generating fresh\n * key pairs in parallel batches until one of them matches.\n *\n * When `matches` is a {@link RegExp}, its literal characters (outside of\n * escape sequences, character classes, quantifiers, and groups) are\n * validated against the base58 alphabet up front. This catches common typos\n * such as `/^ab0/` (`0` is not in the base58 alphabet) before any key is\n * generated, preventing a guaranteed infinite loop.\n *\n * When `matches` is a function, it is used as-is with no validation — use\n * this form when you need arbitrary matching logic that cannot be expressed\n * as a regex. Be mindful that if the function can never return `true`, the\n * grind loop will never terminate unless you supply an {@link AbortSignal}.\n *\n * @param config - See {@link GrindKeyPairsConfig}. The `amount` field is\n * omitted because this function always returns a single key pair.\n *\n * @returns A promise that resolves to a {@link CryptoKeyPair} whose\n * base58-encoded public key satisfies the matcher.\n *\n * @throws {@link SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX} when the\n * provided regex contains a literal character that is not in the base58\n * alphabet.\n *\n * @throws The `AbortSignal`'s reason when the supplied `abortSignal` is\n * fired (either before the function is called or during the grind loop).\n *\n * @example\n * Mine a vanity address that starts with `anza`:\n * ```ts\n * import { grindKeyPair } from '@solana/keys';\n *\n * const keyPair = await grindKeyPair({ matches: /^anza/ });\n * ```\n *\n * @example\n * Use the `i` flag for case-insensitive matching:\n * ```ts\n * import { grindKeyPair } from '@solana/keys';\n *\n * const keyPair = await grindKeyPair({ matches: /^anza/i });\n * ```\n *\n * @example\n * Use a predicate function for arbitrary matching logic:\n * ```ts\n * import { grindKeyPair } from '@solana/keys';\n *\n * const keyPair = await grindKeyPair({\n *     matches: address => address.startsWith('anza') && address.length === 44,\n * });\n * ```\n *\n * @example\n * Cap the grind at 60 seconds using\n * [`AbortSignal.timeout()`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static):\n * ```ts\n * import { grindKeyPair } from '@solana/keys';\n *\n * const keyPair = await grindKeyPair({\n *     matches: /^anza/,\n *     abortSignal: AbortSignal.timeout(60_000),\n * });\n * ```\n *\n * @example\n * Generate an extractable key pair so you can persist its private key bytes:\n * ```ts\n * import { grindKeyPair } from '@solana/keys';\n *\n * const keyPair = await grindKeyPair({ matches: /^anza/, extractable: true });\n * const privateKeyBytes = new Uint8Array(\n *     await crypto.subtle.exportKey('pkcs8', keyPair.privateKey),\n * );\n * ```\n *\n * @see {@link grindKeyPairs}\n * @see {@link GrindKeyPairsConfig}\n * @see {@link GrindKeyPairMatches}\n * @see {@link generateKeyPair}\n */\nexport async function grindKeyPair(config: Omit<GrindKeyPairsConfig, 'amount'>): Promise<CryptoKeyPair> {\n    const [keyPair] = await grindKeyPairs({ ...config, amount: 1 });\n    return keyPair;\n}\n"
  },
  {
    "path": "packages/keys/src/index.ts",
    "content": "/**\n * This package contains utilities for validating, generating, and manipulating addresses and key\n * material. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n * @packageDocumentation\n */\nexport * from './grind-keypair';\nexport * from './key-pair';\nexport * from './private-key';\nexport * from './public-key';\nexport * from './signatures';\nexport * from './write-keypair';\n"
  },
  {
    "path": "packages/keys/src/key-pair.ts",
    "content": "import { assertKeyGenerationIsAvailable, assertPRNGIsAvailable } from '@solana/assertions';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY,\n    SolanaError,\n} from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\nimport { createPrivateKeyFromBytes } from './private-key';\nimport { getPublicKeyFromPrivateKey } from './public-key';\nimport { signBytes, verifySignature } from './signatures';\n\n/**\n * Generates an Ed25519 public/private key pair for use with other methods in this package that\n * accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`, which prevents the bytes of the private key from being visible to JS.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await generateKeyPair();\n * ```\n */\nexport async function generateKeyPair(extractable: boolean = false): Promise<CryptoKeyPair> {\n    await assertKeyGenerationIsAvailable();\n    const keyPair = await crypto.subtle.generateKey(\n        /* algorithm */ ED25519_ALGORITHM_IDENTIFIER, // Native implementation status: https://github.com/WICG/webcrypto-secure-curves/issues/20\n        extractable,\n        /* allowed uses */ ['sign', 'verify'],\n    );\n    return keyPair;\n}\n\n/**\n * Given a 64-byte `Uint8Array` secret key, creates an Ed25519 public/private key pair for use with\n * other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 64 bytes, the first 32 of which represent the private key and the last 32 of which\n * represent its associated public key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairFromBytes } from '@solana/keys';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a CryptoKeyPair from the bytes.\n * const { privateKey, publicKey } = await createKeyPairFromBytes(keypairBytes);\n * ```\n *\n * @see {@link writeKeyPair} — the inverse helper that persists a key pair to disk in the\n * same format.\n */\nexport async function createKeyPairFromBytes(\n    bytes: ReadonlyUint8Array,\n    extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n    assertPRNGIsAvailable();\n\n    if (bytes.byteLength !== 64) {\n        throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_KEY_PAIR_BYTE_LENGTH, { byteLength: bytes.byteLength });\n    }\n    const [publicKey, privateKey] = await Promise.all([\n        crypto.subtle.importKey('raw', bytes.slice(32), ED25519_ALGORITHM_IDENTIFIER, /* extractable */ true, [\n            'verify',\n        ]),\n        createPrivateKeyFromBytes(bytes.slice(0, 32), extractable),\n    ]);\n\n    // Verify the key pair\n    const randomBytes = new Uint8Array(32);\n    crypto.getRandomValues(randomBytes);\n    const signedData = await signBytes(privateKey, randomBytes);\n    const isValid = await verifySignature(publicKey, signedData, randomBytes);\n    if (!isValid) {\n        throw new SolanaError(SOLANA_ERROR__KEYS__PUBLIC_KEY_MUST_MATCH_PRIVATE_KEY);\n    }\n\n    return { privateKey, publicKey } as CryptoKeyPair;\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 public/private key\n * pair for use with other methods in this package that accept [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const { privateKey, publicKey } = await createKeyPairFromPrivateKeyBytes(new Uint8Array([...]));\n * ```\n *\n * This can be useful when you have a private key but not the corresponding public key or when you\n * need to derive key pairs from seeds. For instance, the following code snippet derives a key pair\n * from the hash of a message.\n *\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairFromPrivateKeyBytes } from '@solana/keys';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedKeypair = await createKeyPairFromPrivateKeyBytes(seed);\n * ```\n */\nexport async function createKeyPairFromPrivateKeyBytes(\n    bytes: ReadonlyUint8Array,\n    extractable: boolean = false,\n): Promise<CryptoKeyPair> {\n    const privateKeyPromise = createPrivateKeyFromBytes(bytes, extractable);\n\n    // Here we need the private key to be extractable in order to export\n    // it as a public key. Therefore, if the `extractable` parameter\n    // is `false`, we need to create two private keys such that:\n    //   - The extractable one is used to create the public key and\n    //   - The non-extractable one is the one we will return.\n    const [publicKey, privateKey] = await Promise.all([\n        // This nested promise makes things efficient by\n        // creating the public key in parallel with the\n        // second private key creation, if it is needed.\n        (extractable ? privateKeyPromise : createPrivateKeyFromBytes(bytes, true /* extractable */)).then(\n            async privateKey => await getPublicKeyFromPrivateKey(privateKey, true /* extractable */),\n        ),\n        privateKeyPromise,\n    ]);\n\n    return { privateKey, publicKey };\n}\n"
  },
  {
    "path": "packages/keys/src/private-key.ts",
    "content": "import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, SolanaError } from '@solana/errors';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\nfunction addPkcs8Header(bytes: ReadonlyUint8Array): ReadonlyUint8Array<ArrayBuffer> {\n    // prettier-ignore\n    return new Uint8Array([\n        /**\n         * PKCS#8 header\n         */\n        0x30, // ASN.1 sequence tag\n        0x2e, // Length of sequence (46 more bytes)\n\n            0x02, // ASN.1 integer tag\n            0x01, // Length of integer\n                0x00, // Version number\n\n            0x30, // ASN.1 sequence tag\n            0x05, // Length of sequence\n                0x06, // ASN.1 object identifier tag\n                0x03, // Length of object identifier\n                    // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n                        0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n                        0x65, // thawte(101)\n                    // Ed25519 identifier\n                        0x70, // id-Ed25519(112)\n\n        /**\n         * Private key payload\n         */\n        0x04, // ASN.1 octet string tag\n        0x22, // String length (34 more bytes)\n\n            // Private key bytes as octet string\n            0x04, // ASN.1 octet string tag\n            0x20, // String length (32 bytes)\n\n        ...bytes\n    ]);\n}\n\n/**\n * Given a private key represented as a 32-byte `Uint8Array`, creates an Ed25519 private key for use\n * with other methods in this package that accept\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) objects.\n *\n * @param bytes 32 bytes that represent the private key\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]));\n * const extractablePrivateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n * ```\n */\nexport async function createPrivateKeyFromBytes(\n    bytes: ReadonlyUint8Array,\n    extractable: boolean = false,\n): Promise<CryptoKey> {\n    const actualLength = bytes.byteLength;\n    if (actualLength !== 32) {\n        throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n            actualLength,\n        });\n    }\n    const privateKeyBytesPkcs8 = addPkcs8Header(bytes);\n    return await crypto.subtle.importKey('pkcs8', privateKeyBytesPkcs8, ED25519_ALGORITHM_IDENTIFIER, extractable, [\n        'sign',\n    ]);\n}\n"
  },
  {
    "path": "packages/keys/src/public-key.ts",
    "content": "import { assertKeyExporterIsAvailable } from '@solana/assertions';\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\n\n/**\n * Given an extractable [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey)\n * private key, gets the corresponding public key as a\n * [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey).\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the public\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`.\n *\n * @example\n * ```ts\n * import { createPrivateKeyFromBytes, getPublicKeyFromPrivateKey } from '@solana/keys';\n *\n * const privateKey = await createPrivateKeyFromBytes(new Uint8Array([...]), true);\n *\n * const publicKey = await getPublicKeyFromPrivateKey(privateKey);\n * const extractablePublicKey = await getPublicKeyFromPrivateKey(privateKey, true);\n * ```\n */\nexport async function getPublicKeyFromPrivateKey(\n    privateKey: CryptoKey,\n    extractable: boolean = false,\n): Promise<CryptoKey> {\n    assertKeyExporterIsAvailable();\n\n    if (privateKey.extractable === false) {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, { key: privateKey });\n    }\n\n    // Export private key.\n    const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n\n    // Import public key.\n    return await crypto.subtle.importKey(\n        'jwk',\n        {\n            crv /* curve */: 'Ed25519',\n            ext /* extractable */: extractable,\n            key_ops /* key operations */: ['verify'],\n            kty /* key type */: 'OKP' /* octet key pair */,\n            x /* public key x-coordinate */: jwk.x,\n        },\n        'Ed25519',\n        extractable,\n        ['verify'],\n    );\n}\n"
  },
  {
    "path": "packages/keys/src/signatures.ts",
    "content": "import { assertSigningCapabilityIsAvailable, assertVerificationCapabilityIsAvailable } from '@solana/assertions';\nimport { Encoder, ReadonlyUint8Array, toArrayBuffer } from '@solana/codecs-core';\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { ED25519_ALGORITHM_IDENTIFIER } from './algorithm';\n\n/**\n * A 64-byte Ed25519 signature as a base58-encoded string.\n */\nexport type Signature = Brand<EncodedString<string, 'base58'>, 'Signature'>;\n/**\n * A 64-byte Ed25519 signature.\n *\n * Whenever you need to verify that a particular signature is, in fact, the one that would have been\n * produced by signing some known bytes using the private key associated with some known public key,\n * use the {@link verifySignature} function in this package.\n */\nexport type SignatureBytes = Brand<Uint8Array, 'SignatureBytes'>;\n\nlet base58Encoder: Encoder<string> | undefined;\n\n/**\n * Asserts that an arbitrary string is a base58-encoded Ed25519 signature.\n *\n * Useful when you receive a string from user input or an untrusted network API that you expect to\n * represent an Ed25519 signature (eg. of a transaction).\n *\n * @example\n * ```ts\n * import { assertIsSignature } from '@solana/keys';\n *\n * // Imagine a function that asserts whether a user-supplied signature is valid or not.\n * function handleSubmit() {\n *     // We know only that what the user typed conforms to the `string` type.\n *     const signature: string = signatureInput.value;\n *     try {\n *         // If this type assertion function doesn't throw, then\n *         // Typescript will upcast `signature` to `Signature`.\n *         assertIsSignature(signature);\n *         // At this point, `signature` is a `Signature` that can be used with the RPC.\n *         const {\n *             value: [status],\n *         } = await rpc.getSignatureStatuses([signature]).send();\n *     } catch (e) {\n *         // `signature` turned out not to be a base58-encoded signature\n *     }\n * }\n * ```\n */\nexport function assertIsSignature(putativeSignature: string): asserts putativeSignature is Signature {\n    if (!base58Encoder) base58Encoder = getBase58Encoder();\n    // Fast-path; see if the input string is of an acceptable length.\n    if (\n        // Lowest value (64 bytes of zeroes)\n        putativeSignature.length < 64 ||\n        // Highest value (64 bytes of 255)\n        putativeSignature.length > 88\n    ) {\n        throw new SolanaError(SOLANA_ERROR__KEYS__SIGNATURE_STRING_LENGTH_OUT_OF_RANGE, {\n            actualLength: putativeSignature.length,\n        });\n    }\n    // Slow-path; actually attempt to decode the input string.\n    const bytes = base58Encoder.encode(putativeSignature);\n    assertIsSignatureBytes(bytes);\n}\n\n/**\n * Asserts that an arbitrary `ReadonlyUint8Array` is an Ed25519 signature.\n *\n * Useful when you receive a `ReadonlyUint8Array` from an external interface (like the browser wallets' `signMessage` API) that you expect to\n * represent an Ed25519 signature.\n *\n * @example\n * ```ts\n * import { assertIsSignatureBytes } from '@solana/keys';\n *\n * // Imagine a function that verifies a signature.\n * function verifySignature() {\n *     // We know only that the input conforms to the `ReadonlyUint8Array` type.\n *     const signatureBytes: ReadonlyUint8Array = signatureBytesInput;\n *     try {\n *         // If this type assertion function doesn't throw, then\n *         // Typescript will upcast `signatureBytes` to `SignatureBytes`.\n *         assertIsSignatureBytes(signatureBytes);\n *         // At this point, `signatureBytes` is a `SignatureBytes` that can be used with `verifySignature`.\n *         if (!(await verifySignature(publicKey, signatureBytes, data))) {\n *             throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n *         }\n *     } catch (e) {\n *         // `signatureBytes` turned out not to be a 64-byte Ed25519 signature\n *     }\n * }\n * ```\n */\nexport function assertIsSignatureBytes(\n    putativeSignatureBytes: ReadonlyUint8Array,\n): asserts putativeSignatureBytes is SignatureBytes {\n    const numBytes = putativeSignatureBytes.byteLength;\n    if (numBytes !== 64) {\n        throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_SIGNATURE_BYTE_LENGTH, {\n            actualLength: numBytes,\n        });\n    }\n}\n\n/**\n * A type guard that accepts a string as input. It will both return `true` if the string conforms to\n * the {@link Signature} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignature } from '@solana/keys';\n *\n * if (isSignature(signature)) {\n *     // At this point, `signature` has been refined to a\n *     // `Signature` that can be used with the RPC.\n *     const {\n *         value: [status],\n *     } = await rpc.getSignatureStatuses([signature]).send();\n *     setSignatureStatus(status);\n * } else {\n *     setError(`${signature} is not a transaction signature`);\n * }\n * ```\n */\nexport function isSignature(putativeSignature: string): putativeSignature is Signature {\n    if (!base58Encoder) base58Encoder = getBase58Encoder();\n\n    // Fast-path; see if the input string is of an acceptable length.\n    if (\n        // Lowest value (64 bytes of zeroes)\n        putativeSignature.length < 64 ||\n        // Highest value (64 bytes of 255)\n        putativeSignature.length > 88\n    ) {\n        return false;\n    }\n    // Slow-path; actually attempt to decode the input string.\n    const bytes = base58Encoder.encode(putativeSignature);\n    return isSignatureBytes(bytes);\n}\n\n/**\n * A type guard that accepts a `ReadonlyUint8Array` as input. It will both return `true` if the `ReadonlyUint8Array` conforms to\n * the {@link SignatureBytes} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isSignatureBytes } from '@solana/keys';\n *\n * if (isSignatureBytes(signatureBytes)) {\n *     // At this point, `signatureBytes` has been refined to a\n *     // `SignatureBytes` that can be used with `verifySignature`.\n *     if (!(await verifySignature(publicKey, signatureBytes, data))) {\n *         throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n *     }\n * } else {\n *     setError(`${signatureBytes} is not a 64-byte Ed25519 signature`);\n * }\n * ```\n */\nexport function isSignatureBytes(putativeSignatureBytes: ReadonlyUint8Array): putativeSignatureBytes is SignatureBytes {\n    return putativeSignatureBytes.byteLength === 64;\n}\n\n/**\n * Given a private [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) and a\n * `Uint8Array` of bytes, this method will return the 64-byte Ed25519 signature of that data as a\n * `Uint8Array`.\n *\n * @example\n * ```ts\n * import { signBytes } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await signBytes(privateKey, data);\n * ```\n */\nexport async function signBytes(key: CryptoKey, data: ReadonlyUint8Array): Promise<SignatureBytes> {\n    assertSigningCapabilityIsAvailable();\n    const signedData = await crypto.subtle.sign(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(data));\n    return new Uint8Array(signedData) as SignatureBytes;\n}\n\n/**\n * This helper combines _asserting_ that a string is an Ed25519 signature with _coercing_ it to the\n * {@link Signature} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signature } from '@solana/keys';\n *\n * const signature = signature(userSuppliedSignature);\n * const {\n *     value: [status],\n * } = await rpc.getSignatureStatuses([signature]).send();\n * ```\n */\nexport function signature(putativeSignature: string): Signature {\n    assertIsSignature(putativeSignature);\n    return putativeSignature;\n}\n\n/**\n * This helper combines _asserting_ that a `ReadonlyUint8Array` is an Ed25519 signature with _coercing_ it to the\n * {@link SignatureBytes} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { signatureBytes } from '@solana/keys';\n *\n * const signature = signatureBytes(userSuppliedSignatureBytes);\n * if (!(await verifySignature(publicKey, signature, data))) {\n *     throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport function signatureBytes(putativeSignatureBytes: ReadonlyUint8Array): SignatureBytes {\n    assertIsSignatureBytes(putativeSignatureBytes);\n    return putativeSignatureBytes;\n}\n\n/**\n * Given a public [`CryptoKey`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey), some\n * {@link SignatureBytes}, and a `Uint8Array` of data, this method will return `true` if the\n * signature was produced by signing the data using the private key associated with the public key,\n * and `false` otherwise.\n *\n * @example\n * ```ts\n * import { verifySignature } from '@solana/keys';\n *\n * const data = new Uint8Array([1, 2, 3]);\n * if (!(await verifySignature(publicKey, signature, data))) {\n *     throw new Error('The data were *not* signed by the private key associated with `publicKey`');\n * }\n * ```\n */\nexport async function verifySignature(\n    key: CryptoKey,\n    signature: SignatureBytes,\n    data: ReadonlyUint8Array,\n): Promise<boolean> {\n    assertVerificationCapabilityIsAvailable();\n    return await crypto.subtle.verify(ED25519_ALGORITHM_IDENTIFIER, key, toArrayBuffer(signature), toArrayBuffer(data));\n}\n"
  },
  {
    "path": "packages/keys/src/write-keypair.ts",
    "content": "import {\n    SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH,\n    SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT,\n    SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY,\n    SolanaError,\n} from '@solana/errors';\nimport { dirname, mkdir, writeFile } from '@solana/fs-impl';\n\n/**\n * Configuration options for {@link writeKeyPair} and {@link writeKeyPairSigner}.\n */\nexport type WriteKeyPairConfig = Readonly<{\n    /**\n     * When `true`, allows the write to overwrite an existing file at the destination path.\n     * Defaults to `false`, in which case attempting to write to a path that already exists\n     * will throw an `EEXIST` error.\n     *\n     * **DANGER:** Overwriting an existing key pair file with a different key pair\n     * permanently destroys the previous key and, with it, access to any funds or\n     * onchain state controlled by that address. This action is irreversible.\n     * Only enable this option if you are certain the existing file is disposable.\n     */\n    unsafelyOverwriteExistingKeyPair?: boolean;\n}>;\n\n/**\n * Writes an extractable {@link CryptoKeyPair} to disk as a JSON array of 64 bytes, matching\n * the format produced by `solana-keygen`. The first 32 bytes are the raw Ed25519 seed\n * (private key) and the last 32 bytes are the raw public key.\n *\n * Any missing parent directories are created automatically. The written file uses mode\n * `0600` (owner read/write only) to match `solana-keygen`.\n *\n * This helper requires a writable filesystem and will throw in environments that don't\n * provide one (such as browsers or React Native).\n *\n * @param keyPair - An extractable {@link CryptoKeyPair}. Both the private and public keys\n * must have been created with `extractable: true`.\n * @param path - The destination path on disk.\n * @param config - See {@link WriteKeyPairConfig}.\n *\n * @throws A {@link SolanaError} of code\n * {@link SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT | `SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT`}\n * when called in an environment without a writable filesystem.\n * @throws A {@link SolanaError} of code\n * {@link SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY | `SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY`}\n * when either the private or public key is not extractable.\n *\n * @example\n * ```ts\n * import { generateKeyPair, writeKeyPair } from '@solana/keys';\n *\n * // Generate an extractable key pair so its bytes can be persisted.\n * const keyPair = await generateKeyPair(true);\n * await writeKeyPair(keyPair, './my-keypair.json');\n * ```\n *\n * @example\n * Overwriting an existing file requires an explicit opt-in, because doing so permanently\n * destroys the previous key and any funds controlled by it:\n * ```ts\n * import { writeKeyPair } from '@solana/keys';\n *\n * await writeKeyPair(keyPair, './my-keypair.json', {\n *     unsafelyOverwriteExistingKeyPair: true,\n * });\n * ```\n *\n * @see {@link createKeyPairFromBytes} — the inverse helper that loads a key pair from a\n * 64-byte buffer.\n * @see {@link writeKeyPairSigner} — the signer-flavored variant from `@solana/signers`.\n */\nexport async function writeKeyPair(\n    keyPair: CryptoKeyPair,\n    path: string,\n    config: WriteKeyPairConfig = {},\n): Promise<void> {\n    if (!__NODEJS__) {\n        throw new SolanaError(SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT);\n    }\n\n    if (!keyPair.privateKey.extractable) {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, {\n            key: keyPair.privateKey,\n        });\n    }\n    if (!keyPair.publicKey.extractable) {\n        throw new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, {\n            key: keyPair.publicKey,\n        });\n    }\n\n    const [privateKeyPkcs8, publicKeyRaw] = await Promise.all([\n        crypto.subtle.exportKey('pkcs8', keyPair.privateKey),\n        crypto.subtle.exportKey('raw', keyPair.publicKey),\n    ]);\n    // The PKCS#8 header added by `createPrivateKeyFromBytes` (see `./private-key.ts`) is\n    // a fixed 16-byte prefix for Ed25519 keys, so slicing it off yields the raw 32-byte\n    // seed that `solana-keygen` writes as the first half of its output. The length\n    // check below is a forward-compatibility guard in case WebCrypto ever emits a\n    // different envelope shape for this curve.\n    const privateKeyBytes = new Uint8Array(privateKeyPkcs8).slice(16);\n    if (privateKeyBytes.byteLength !== 32) {\n        throw new SolanaError(SOLANA_ERROR__KEYS__INVALID_PRIVATE_KEY_BYTE_LENGTH, {\n            actualLength: privateKeyBytes.byteLength,\n        });\n    }\n    const publicKeyBytes = new Uint8Array(publicKeyRaw);\n\n    const bytes = new Uint8Array(64);\n    bytes.set(privateKeyBytes, 0);\n    bytes.set(publicKeyBytes, 32);\n\n    await mkdir(dirname(path), { recursive: true });\n    await writeFile(path, JSON.stringify(Array.from(bytes)), {\n        flag: config.unsafelyOverwriteExistingKeyPair ? 'w' : 'wx',\n        mode: 0o600,\n    });\n}\n"
  },
  {
    "path": "packages/keys/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/keys/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/keys\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"],\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2022.Error\"]\n    }\n}\n"
  },
  {
    "path": "packages/keys/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/kit/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/kit/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/kit/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/kit/CHANGELOG.md",
    "content": "# @solana/kit\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1544](https://github.com/anza-xyz/kit/pull/1544) [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update RPC types for Agave v3.x validator compatibility.\n\n    **`@solana/rpc-parsed-types`**: `JsonParsedVoteAccount` now includes `blockRevenueCollector`, `blockRevenueCommissionBps`, `blsPubkeyCompressed`, `inflationRewardsCollector`, `inflationRewardsCommissionBps`, `pendingDelegatorRewards`, and a `latency` field on each vote entry.\n\n    **`@solana/rpc-api`**: `SimulateTransactionApiResponseBase` now includes `fee`, `loadedAddresses`, `preBalances`, `postBalances`, `preTokenBalances`, and `postTokenBalances`.\n\n    **`@solana/errors`**: `RpcSimulateTransactionResult` updated with the same new fields.\n\n    **Note on `replacementBlockhash`**: Agave v3.x validators now always return `replacementBlockhash` in `simulateTransaction` responses (as `null` when `replaceRecentBlockhash` is not set). Kit's types still model this field as conditionally present based on config. A future breaking change will move it to the base response type as `TransactionBlockhashLifetime | null` to match v3.x behavior. Consumers using v3.x validators may see this field at runtime even when Kit's types don't surface it.\n\n    **Note on Agave v3.x validator behavior**: Validators running Agave v3.x no longer return a dedicated `TRANSACTION_SIGNATURE_VERIFICATION_FAILURE` RPC error for invalid signatures in `simulateTransaction` or `sendTransaction`. Instead, `simulateTransaction` returns a result with `err: \"SignatureFailure\"`, and `sendTransaction` returns a preflight failure with the signature error as the cause. This is a validator-level change and does not affect Kit's API surface.\n\n- [#1551](https://github.com/anza-xyz/kit/pull/1551) [`d24f908`](https://github.com/anza-xyz/kit/commit/d24f908a4fbbddddd9e8bacc57485de6d8e022b4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `ClientWithSubscribeToPayer` and `ClientWithSubscribeToIdentity` interfaces. These are a framework-agnostic convention for plugins that mutate `client.payer` / `client.identity` reactively — they install a sibling `subscribeToPayer` / `subscribeToIdentity` function so consumers can observe changes without naming the specific plugin that provides them.\n\n- [#1570](https://github.com/anza-xyz/kit/pull/1570) [`c5e0e14`](https://github.com/anza-xyz/kit/commit/c5e0e1444ae420390047d5e37a13650edf042954) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a new `@solana/fixed-points` package providing precise fixed-point number types for Solana, both decimal (power-of-10 scale) and binary (power-of-2 scale), in signed and unsigned flavors with arbitrary bit widths. The package includes factories, guards, arithmetic, comparisons, signedness conversions, rescaling, string/number formatting, and byte-level codecs. Also re-exported from `@solana/codecs` and `@solana/kit`.\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n- [#1578](https://github.com/anza-xyz/kit/pull/1578) [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `Sol`, `sol()`, `solToLamports`, and `lamportsToSol` helpers for converting between SOL amounts expressed as `@solana/fixed-points` values and `Lamports` branded bigints. Also add `getSolEncoder`, `getSolDecoder`, and `getSolCodec` for serializing SOL amounts to bytes (the encoder accepts both `Sol` and `Lamports` inputs; the decoder always returns `Sol`). Finally, update `getLamportsEncoder`/`getDefaultLamportsEncoder` and their codec counterparts to also accept `Sol` as input.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`b1ae82b`](https://github.com/anza-xyz/kit/commit/b1ae82bbb2159f17a3e0f337c5f8677613b5b32d), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`d24f908`](https://github.com/anza-xyz/kit/commit/d24f908a4fbbddddd9e8bacc57485de6d8e022b4), [`c5e0e14`](https://github.com/anza-xyz/kit/commit/c5e0e1444ae420390047d5e37a13650edf042954), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/errors@6.9.0\n    - @solana/plugin-core@6.9.0\n    - @solana/rpc-api@6.9.0\n    - @solana/rpc-parsed-types@6.9.0\n    - @solana/plugin-interfaces@6.9.0\n    - @solana/codecs@6.9.0\n    - @solana/accounts@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/functional@6.9.0\n    - @solana/instruction-plans@6.9.0\n    - @solana/instructions@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/offchain-messages@6.9.0\n    - @solana/program-client-core@6.9.0\n    - @solana/programs@6.9.0\n    - @solana/rpc-spec-types@6.9.0\n    - @solana/rpc-subscriptions@6.9.0\n    - @solana/rpc-types@6.9.0\n    - @solana/rpc@6.9.0\n    - @solana/signers@6.9.0\n    - @solana/subscribable@6.9.0\n    - @solana/sysvars@6.9.0\n    - @solana/transaction-confirmation@6.9.0\n    - @solana/transaction-messages@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Minor Changes\n\n- [#1528](https://github.com/anza-xyz/kit/pull/1528) [`09a7509`](https://github.com/anza-xyz/kit/commit/09a75092c48f4b827d7d2ac6db0b1bd34c4a41dd) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `createReactiveStoreWithInitialValueAndSlotTracking()`, a helper that combines an initial RPC fetch with an ongoing subscription into a single `ReactiveStore`. Uses slot-based comparison to ensure only the most recent value is kept, regardless of arrival order. The store state is a `SolanaRpcResponse<TItem>`. Compatible with `useSyncExternalStore`, Svelte stores, and other reactive primitives.\n\n- [#1536](https://github.com/anza-xyz/kit/pull/1536) [`cec688e`](https://github.com/anza-xyz/kit/commit/cec688e59a34f092d89f9a3f2253edb571c37899) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `createAsyncGeneratorWithInitialValueAndSlotTracking`, an async generator alternative to `createReactiveStoreWithInitialValueAndSlotTracking` that yields values from both an RPC fetch and an ongoing subscription, silently dropping any value at a slot older than the last seen.\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`f53ce07`](https://github.com/anza-xyz/kit/commit/f53ce0796c782e79490e1cf11a55e28fb62b8c8f), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc), [`f8d6131`](https://github.com/anza-xyz/kit/commit/f8d61310a0ca7dfeb86f7e7d3f5975b8a140370a)]:\n    - @solana/signers@6.8.0\n    - @solana/keys@6.8.0\n    - @solana/accounts@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/functional@6.8.0\n    - @solana/instruction-plans@6.8.0\n    - @solana/instructions@6.8.0\n    - @solana/offchain-messages@6.8.0\n    - @solana/plugin-core@6.8.0\n    - @solana/plugin-interfaces@6.8.0\n    - @solana/program-client-core@6.8.0\n    - @solana/programs@6.8.0\n    - @solana/rpc@6.8.0\n    - @solana/rpc-api@6.8.0\n    - @solana/rpc-parsed-types@6.8.0\n    - @solana/rpc-spec-types@6.8.0\n    - @solana/rpc-subscriptions@6.8.0\n    - @solana/rpc-types@6.8.0\n    - @solana/subscribable@6.8.0\n    - @solana/sysvars@6.8.0\n    - @solana/transaction-confirmation@6.8.0\n    - @solana/transaction-messages@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies [[`2763d0c`](https://github.com/anza-xyz/kit/commit/2763d0c92b60089f4b20f6241cb5f91232cc2e75)]:\n    - @solana/plugin-core@6.7.0\n    - @solana/accounts@6.7.0\n    - @solana/addresses@6.7.0\n    - @solana/codecs@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/functional@6.7.0\n    - @solana/instruction-plans@6.7.0\n    - @solana/instructions@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/offchain-messages@6.7.0\n    - @solana/plugin-interfaces@6.7.0\n    - @solana/program-client-core@6.7.0\n    - @solana/programs@6.7.0\n    - @solana/rpc@6.7.0\n    - @solana/rpc-api@6.7.0\n    - @solana/rpc-parsed-types@6.7.0\n    - @solana/rpc-spec-types@6.7.0\n    - @solana/rpc-subscriptions@6.7.0\n    - @solana/rpc-types@6.7.0\n    - @solana/signers@6.7.0\n    - @solana/sysvars@6.7.0\n    - @solana/transaction-confirmation@6.7.0\n    - @solana/transaction-messages@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad), [`9c4fd6e`](https://github.com/anza-xyz/kit/commit/9c4fd6e67a6f70b1386f0745cf5afe0f93c75e36), [`0fa54a4`](https://github.com/anza-xyz/kit/commit/0fa54a469937db3989f42afc4248882736f719f5), [`f055201`](https://github.com/anza-xyz/kit/commit/f055201c2dd3a4a69b9894d66b622ae81c13b8cd)]:\n    - @solana/instruction-plans@6.6.0\n    - @solana/transactions@6.6.0\n    - @solana/errors@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/plugin-core@6.6.0\n    - @solana/signers@6.6.0\n    - @solana/plugin-interfaces@6.6.0\n    - @solana/program-client-core@6.6.0\n    - @solana/rpc-api@6.6.0\n    - @solana/transaction-confirmation@6.6.0\n    - @solana/accounts@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/instructions@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/offchain-messages@6.6.0\n    - @solana/programs@6.6.0\n    - @solana/rpc@6.6.0\n    - @solana/rpc-subscriptions@6.6.0\n    - @solana/rpc-types@6.6.0\n    - @solana/sysvars@6.6.0\n    - @solana/rpc-parsed-types@6.6.0\n    - @solana/codecs@6.6.0\n    - @solana/functional@6.6.0\n    - @solana/rpc-spec-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- [#1485](https://github.com/anza-xyz/kit/pull/1485) [`4a4c217`](https://github.com/anza-xyz/kit/commit/4a4c21741e4982dd52e6d08a0e46ee626c73717c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecated `getMinimumBalanceForRentExemption`. The minimum balance for an account is being actively reduced (see [SIMD-0437](https://github.com/solana-foundation/solana-improvement-documents/pull/437)) and is expected to become dynamic in future Solana upgrades (see [SIMD-0194](https://github.com/solana-foundation/solana-improvement-documents/pull/194) and [SIMD-0389](https://github.com/solana-foundation/solana-improvement-documents/pull/389)). Use the `getMinimumBalanceForRentExemption` RPC method or a `ClientWithGetMinimumBalance` plugin instead. This function will be removed in v7.\n\n- Updated dependencies [[`10cb920`](https://github.com/anza-xyz/kit/commit/10cb92045bba4710a6c6157a3963d9e3a61f755e), [`9e05736`](https://github.com/anza-xyz/kit/commit/9e057365a1a4e350f8a0ccc233b262e09b0134fa)]:\n    - @solana/plugin-interfaces@6.5.0\n    - @solana/signers@6.5.0\n    - @solana/program-client-core@6.5.0\n    - @solana/accounts@6.5.0\n    - @solana/addresses@6.5.0\n    - @solana/codecs@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/functional@6.5.0\n    - @solana/instruction-plans@6.5.0\n    - @solana/instructions@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/offchain-messages@6.5.0\n    - @solana/plugin-core@6.5.0\n    - @solana/programs@6.5.0\n    - @solana/rpc@6.5.0\n    - @solana/rpc-api@6.5.0\n    - @solana/rpc-parsed-types@6.5.0\n    - @solana/rpc-spec-types@6.5.0\n    - @solana/rpc-subscriptions@6.5.0\n    - @solana/rpc-types@6.5.0\n    - @solana/sysvars@6.5.0\n    - @solana/transaction-confirmation@6.5.0\n    - @solana/transaction-messages@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Minor Changes\n\n- [#1476](https://github.com/anza-xyz/kit/pull/1476) [`3e9e0a2`](https://github.com/anza-xyz/kit/commit/3e9e0a207155b56e96b5ee556728b5afdb23d4fe) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add compute unit limit estimation utilities: `estimateComputeUnitLimitFactory`, `estimateAndSetComputeUnitLimitFactory`, and `fillTransactionMessageProvisoryComputeUnitLimit`. These replace the external `@solana-program/compute-budget` estimation functions with Kit-native equivalents that work across all transaction versions.\n\n### Patch Changes\n\n- [#1468](https://github.com/anza-xyz/kit/pull/1468) [`304436f`](https://github.com/anza-xyz/kit/commit/304436ffaad6812ee0cc2f67b5a881f7f918b3ae) Thanks [@amilz](https://github.com/amilz)! - Include source files in published packages so IDE \"Go to Definition\" navigates to TypeScript source instead of .d.ts type declarations\n\n- Updated dependencies [[`896412d`](https://github.com/anza-xyz/kit/commit/896412da20ced2b81f9f529e9b5feef16b7e790f), [`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888), [`abeca1b`](https://github.com/anza-xyz/kit/commit/abeca1b28725f675128f68e4e73d2f655e500eaa)]:\n    - @solana/instruction-plans@6.4.0\n    - @solana/transaction-messages@6.4.0\n    - @solana/plugin-core@6.4.0\n    - @solana/accounts@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/codecs@6.4.0\n    - @solana/instructions@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/offchain-messages@6.4.0\n    - @solana/program-client-core@6.4.0\n    - @solana/rpc-api@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/signers@6.4.0\n    - @solana/sysvars@6.4.0\n    - @solana/transaction-confirmation@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/plugin-interfaces@6.4.0\n    - @solana/programs@6.4.0\n    - @solana/rpc-parsed-types@6.4.0\n    - @solana/rpc-subscriptions@6.4.0\n    - @solana/rpc@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/functional@6.4.0\n    - @solana/rpc-spec-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies [[`a557a62`](https://github.com/anza-xyz/kit/commit/a557a62e0f42d2d526f0b8fbdd0a9fcc08ac9ef7)]:\n    - @solana/instruction-plans@6.3.1\n    - @solana/plugin-interfaces@6.3.1\n    - @solana/program-client-core@6.3.1\n    - @solana/accounts@6.3.1\n    - @solana/addresses@6.3.1\n    - @solana/codecs@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/functional@6.3.1\n    - @solana/instructions@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/offchain-messages@6.3.1\n    - @solana/plugin-core@6.3.1\n    - @solana/programs@6.3.1\n    - @solana/rpc@6.3.1\n    - @solana/rpc-api@6.3.1\n    - @solana/rpc-parsed-types@6.3.1\n    - @solana/rpc-spec-types@6.3.1\n    - @solana/rpc-subscriptions@6.3.1\n    - @solana/rpc-types@6.3.1\n    - @solana/signers@6.3.1\n    - @solana/sysvars@6.3.1\n    - @solana/transaction-confirmation@6.3.1\n    - @solana/transaction-messages@6.3.1\n    - @solana/transactions@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/instruction-plans@6.3.0\n    - @solana/accounts@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/instructions@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/offchain-messages@6.3.0\n    - @solana/program-client-core@6.3.0\n    - @solana/programs@6.3.0\n    - @solana/rpc@6.3.0\n    - @solana/rpc-api@6.3.0\n    - @solana/rpc-subscriptions@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/signers@6.3.0\n    - @solana/sysvars@6.3.0\n    - @solana/transaction-confirmation@6.3.0\n    - @solana/transaction-messages@6.3.0\n    - @solana/transactions@6.3.0\n    - @solana/plugin-interfaces@6.3.0\n    - @solana/rpc-parsed-types@6.3.0\n    - @solana/codecs@6.3.0\n    - @solana/functional@6.3.0\n    - @solana/plugin-core@6.3.0\n    - @solana/rpc-spec-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b28b843`](https://github.com/anza-xyz/kit/commit/b28b8439b1f62aefd9c35c4bea733816975033e5), [`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`98a8869`](https://github.com/anza-xyz/kit/commit/98a8869d5a728a65b7a525d87ed481616112503c), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`79db829`](https://github.com/anza-xyz/kit/commit/79db8292b2064145f615576589d8ecbf32196dc1), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/sysvars@6.2.0\n    - @solana/errors@6.2.0\n    - @solana/instruction-plans@6.2.0\n    - @solana/accounts@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/instructions@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/offchain-messages@6.2.0\n    - @solana/program-client-core@6.2.0\n    - @solana/programs@6.2.0\n    - @solana/rpc@6.2.0\n    - @solana/rpc-api@6.2.0\n    - @solana/rpc-subscriptions@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/signers@6.2.0\n    - @solana/transaction-confirmation@6.2.0\n    - @solana/transaction-messages@6.2.0\n    - @solana/transactions@6.2.0\n    - @solana/plugin-interfaces@6.2.0\n    - @solana/codecs@6.2.0\n    - @solana/rpc-parsed-types@6.2.0\n    - @solana/functional@6.2.0\n    - @solana/plugin-core@6.2.0\n    - @solana/rpc-spec-types@6.2.0\n\n## 6.1.0\n\n### Minor Changes\n\n- [#1356](https://github.com/anza-xyz/kit/pull/1356) [`da61429`](https://github.com/anza-xyz/kit/commit/da614294bb8af73302cdd0ff565e48b8a05ab478) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `@solana/kit/program-client-core` as a subpath export for `@solana/program-client-core` without changing root `@solana/kit` exports.\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`1f6cd4b`](https://github.com/anza-xyz/kit/commit/1f6cd4bc7f41e865ff81ecd819dd9f728c27af77), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75), [`ee558a1`](https://github.com/anza-xyz/kit/commit/ee558a1ea8a95295db0e7b0751b32ac9d6342911), [`50010b5`](https://github.com/anza-xyz/kit/commit/50010b5b791ff0e6d8636ded3af33158f2380e4e), [`d3314a6`](https://github.com/anza-xyz/kit/commit/d3314a6e22d32219a11953e4a7ef8274b82f4b37), [`33234f5`](https://github.com/anza-xyz/kit/commit/33234f50760e34a21072304e6aaf1a31b7a410f1)]:\n    - @solana/errors@6.1.0\n    - @solana/instruction-plans@6.1.0\n    - @solana/plugin-interfaces@6.1.0\n    - @solana/program-client-core@6.1.0\n    - @solana/codecs@6.1.0\n    - @solana/offchain-messages@6.1.0\n    - @solana/transaction-messages@6.1.0\n    - @solana/transactions@6.1.0\n    - @solana/accounts@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/instructions@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/programs@6.1.0\n    - @solana/rpc@6.1.0\n    - @solana/rpc-api@6.1.0\n    - @solana/rpc-subscriptions@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/signers@6.1.0\n    - @solana/sysvars@6.1.0\n    - @solana/transaction-confirmation@6.1.0\n    - @solana/rpc-parsed-types@6.1.0\n    - @solana/functional@6.1.0\n    - @solana/plugin-core@6.1.0\n    - @solana/rpc-spec-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- [#1321](https://github.com/anza-xyz/kit/pull/1321) [`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix a bug in the type of `TransactionMessageWithSigners`\n\n- Updated dependencies [[`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492), [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462)]:\n    - @solana/transaction-messages@6.0.1\n    - @solana/signers@6.0.1\n    - @solana/instruction-plans@6.0.1\n    - @solana/programs@6.0.1\n    - @solana/rpc-api@6.0.1\n    - @solana/transaction-confirmation@6.0.1\n    - @solana/transactions@6.0.1\n    - @solana/rpc@6.0.1\n    - @solana/sysvars@6.0.1\n    - @solana/rpc-subscriptions@6.0.1\n    - @solana/accounts@6.0.1\n    - @solana/addresses@6.0.1\n    - @solana/codecs@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/functional@6.0.1\n    - @solana/instructions@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/offchain-messages@6.0.1\n    - @solana/plugin-core@6.0.1\n    - @solana/rpc-parsed-types@6.0.1\n    - @solana/rpc-spec-types@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926), [`5f12df2`](https://github.com/anza-xyz/kit/commit/5f12df20b6f4b4b3536cc76c69b90fb8dc22455d), [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a), [`5c810ac`](https://github.com/anza-xyz/kit/commit/5c810ac20414a893b94045f0e89f01a8ca79ba8a), [`bd3d5f1`](https://github.com/anza-xyz/kit/commit/bd3d5f11eac57d1930a747af9ae02cde07d13aa1), [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db), [`f8ef83e`](https://github.com/anza-xyz/kit/commit/f8ef83ee7491db8aa7331a0628045ee9072196a4), [`91cdb71`](https://github.com/anza-xyz/kit/commit/91cdb7129daaf0fa0a6d78d16a571e6f2a3feded), [`2fbad6a`](https://github.com/anza-xyz/kit/commit/2fbad6ab60789e4207f6c4c95c4c2ac514aafab5)]:\n    - @solana/transaction-messages@6.0.0\n    - @solana/instruction-plans@6.0.0\n    - @solana/programs@6.0.0\n    - @solana/rpc-api@6.0.0\n    - @solana/signers@6.0.0\n    - @solana/transaction-confirmation@6.0.0\n    - @solana/transactions@6.0.0\n    - @solana/rpc@6.0.0\n    - @solana/sysvars@6.0.0\n    - @solana/rpc-subscriptions@6.0.0\n    - @solana/accounts@6.0.0\n    - @solana/addresses@6.0.0\n    - @solana/codecs@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/functional@6.0.0\n    - @solana/instructions@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/offchain-messages@6.0.0\n    - @solana/plugin-core@6.0.0\n    - @solana/rpc-parsed-types@6.0.0\n    - @solana/rpc-spec-types@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/instruction-plans@5.5.1\n    - @solana/errors@5.5.1\n    - @solana/accounts@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/instructions@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/offchain-messages@5.5.1\n    - @solana/programs@5.5.1\n    - @solana/rpc@5.5.1\n    - @solana/rpc-api@5.5.1\n    - @solana/rpc-subscriptions@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/signers@5.5.1\n    - @solana/sysvars@5.5.1\n    - @solana/transaction-confirmation@5.5.1\n    - @solana/transaction-messages@5.5.1\n    - @solana/transactions@5.5.1\n    - @solana/rpc-parsed-types@5.5.1\n    - @solana/codecs@5.5.1\n    - @solana/functional@5.5.1\n    - @solana/plugin-core@5.5.1\n    - @solana/rpc-spec-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- [#1234](https://github.com/anza-xyz/kit/pull/1234) [`7e0377b`](https://github.com/anza-xyz/kit/commit/7e0377b41caed78f81b3fe8272efbc9d4af0464a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix a race condition in `sendAndConfirmDurableNonceTransactionFactory`\n\n- Updated dependencies [[`f731129`](https://github.com/anza-xyz/kit/commit/f731129939bac8b2574ecbbcd6afe0a0a6b00e5f), [`b174ed5`](https://github.com/anza-xyz/kit/commit/b174ed531c15d34e354657d3945e4ea5b38932bc), [`ea97d43`](https://github.com/anza-xyz/kit/commit/ea97d43f588c6b5bf3d4bd96464f3c927967ae28), [`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`60e8c45`](https://github.com/anza-xyz/kit/commit/60e8c456356d52fb93637a6323cac9d9b2fc6816), [`cccea6f`](https://github.com/anza-xyz/kit/commit/cccea6fc266e71bb2f1b4b843c3a815e3032f208), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`a47e441`](https://github.com/anza-xyz/kit/commit/a47e44109e90ddb03193d4e1e207f9e68118679d), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`589d761`](https://github.com/anza-xyz/kit/commit/589d761483a8feaf46b4cda7a97ec7abd5e7ab90), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/instruction-plans@5.5.0\n    - @solana/errors@5.5.0\n    - @solana/accounts@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/instructions@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/offchain-messages@5.5.0\n    - @solana/programs@5.5.0\n    - @solana/rpc@5.5.0\n    - @solana/rpc-api@5.5.0\n    - @solana/rpc-subscriptions@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/signers@5.5.0\n    - @solana/sysvars@5.5.0\n    - @solana/transaction-confirmation@5.5.0\n    - @solana/transaction-messages@5.5.0\n    - @solana/transactions@5.5.0\n    - @solana/rpc-parsed-types@5.5.0\n    - @solana/codecs@5.5.0\n    - @solana/functional@5.5.0\n    - @solana/plugin-core@5.5.0\n    - @solana/rpc-spec-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`fb1c576`](https://github.com/anza-xyz/kit/commit/fb1c5761122bebc9955179a911a79a33a391e032), [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/accounts@5.4.0\n    - @solana/transaction-confirmation@5.4.0\n    - @solana/transaction-messages@5.4.0\n    - @solana/instruction-plans@5.4.0\n    - @solana/offchain-messages@5.4.0\n    - @solana/rpc-subscriptions@5.4.0\n    - @solana/rpc-parsed-types@5.4.0\n    - @solana/rpc-spec-types@5.4.0\n    - @solana/instructions@5.4.0\n    - @solana/transactions@5.4.0\n    - @solana/plugin-core@5.4.0\n    - @solana/functional@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/programs@5.4.0\n    - @solana/rpc-api@5.4.0\n    - @solana/signers@5.4.0\n    - @solana/sysvars@5.4.0\n    - @solana/codecs@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n    - @solana/rpc@5.4.0\n\n## 5.3.0\n\n### Minor Changes\n\n- [#1065](https://github.com/anza-xyz/kit/pull/1065) [`fafa52f`](https://github.com/anza-xyz/kit/commit/fafa52f6d058a12c7f0f7125f61906160aad2a37) Thanks [@rajgoesout](https://github.com/rajgoesout)! - Add local rent exemption calculator\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@5.3.0\n    - @solana/addresses@5.3.0\n    - @solana/codecs@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/functional@5.3.0\n    - @solana/instruction-plans@5.3.0\n    - @solana/instructions@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/offchain-messages@5.3.0\n    - @solana/plugin-core@5.3.0\n    - @solana/programs@5.3.0\n    - @solana/rpc@5.3.0\n    - @solana/rpc-api@5.3.0\n    - @solana/rpc-parsed-types@5.3.0\n    - @solana/rpc-spec-types@5.3.0\n    - @solana/rpc-subscriptions@5.3.0\n    - @solana/rpc-types@5.3.0\n    - @solana/signers@5.3.0\n    - @solana/sysvars@5.3.0\n    - @solana/transaction-confirmation@5.3.0\n    - @solana/transaction-messages@5.3.0\n    - @solana/transactions@5.3.0\n\n## 5.2.0\n\n### Minor Changes\n\n- [#1113](https://github.com/anza-xyz/kit/pull/1113) [`b1937c7`](https://github.com/anza-xyz/kit/commit/b1937c7385050b911f50ac36913a6cfe4575036d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `@solana/plugin-core` package enabling us to create modular Kit clients that can be extended with plugins.\n\n- [#1139](https://github.com/anza-xyz/kit/pull/1139) [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Return more precise types from transaction message functions\n\n    Deprecate `BaseTransactionMessage` in favour of `TransactionMessage`\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`b1937c7`](https://github.com/anza-xyz/kit/commit/b1937c7385050b911f50ac36913a6cfe4575036d), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/instruction-plans@5.2.0\n    - @solana/errors@5.2.0\n    - @solana/plugin-core@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/transaction-messages@5.2.0\n    - @solana/transactions@5.2.0\n    - @solana/signers@5.2.0\n    - @solana/accounts@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/instructions@5.2.0\n    - @solana/offchain-messages@5.2.0\n    - @solana/programs@5.2.0\n    - @solana/rpc@5.2.0\n    - @solana/rpc-api@5.2.0\n    - @solana/rpc-subscriptions@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/sysvars@5.2.0\n    - @solana/transaction-confirmation@5.2.0\n    - @solana/codecs@5.2.0\n    - @solana/rpc-parsed-types@5.2.0\n    - @solana/functional@5.2.0\n    - @solana/rpc-spec-types@5.2.0\n\n## 5.1.0\n\n### Minor Changes\n\n- [#880](https://github.com/anza-xyz/kit/pull/880) [`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Added codecs for encoding and decoding Solana Offchain Messages (see https://github.com/solana-foundation/SRFCs/discussions/3)\n\n- [#984](https://github.com/anza-xyz/kit/pull/984) [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df) Thanks [@steveluscher](https://github.com/steveluscher)! - Added the capability to sign Solana Offchain Messages using a `CryptoKey`\n\n### Patch Changes\n\n- [#999](https://github.com/anza-xyz/kit/pull/999) [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97) Thanks [@tmm](https://github.com/tmm)! - Some npm packages are needed for specific runtimes only (eg. React Native, Node). To prevent package managers from unconditionally installing these packages when they have `auto-install-peers` enabled, we are marking them as optional in `peerDependenciesMeta`. When running in React Native, be sure to explicitly install `fastestsmallesttextencoderdecoder`. When running in Node, be sure to explicitly install `ws`. When using `@solana/react`, we will presume that you have already installed `react`.\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`18e7e2c`](https://github.com/anza-xyz/kit/commit/18e7e2c9d9013be6223932398f40cbc276c4a0e9), [`e64a9b2`](https://github.com/anza-xyz/kit/commit/e64a9b263f7752bd470144d19562eff8819bd799), [`2bd0bc2`](https://github.com/anza-xyz/kit/commit/2bd0bc2b8d45eedca661ddf056341deba159a6b1), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`a0c394b`](https://github.com/anza-xyz/kit/commit/a0c394b2f5fcaf543382ca30f052830ca91759e3), [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951), [`eb49ed7`](https://github.com/anza-xyz/kit/commit/eb49ed7dd45f2a5a0098b3de5ef482a813f8ad47), [`5c1f9e5`](https://github.com/anza-xyz/kit/commit/5c1f9e5d61ae55851aaa44e7a5ab83ff09ffee28), [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd)]:\n    - @solana/offchain-messages@5.1.0\n    - @solana/errors@5.1.0\n    - @solana/transaction-confirmation@5.1.0\n    - @solana/instruction-plans@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/transactions@5.1.0\n    - @solana/rpc@5.1.0\n    - @solana/transaction-messages@5.1.0\n    - @solana/signers@5.1.0\n    - @solana/accounts@5.1.0\n    - @solana/instructions@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/programs@5.1.0\n    - @solana/rpc-subscriptions@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/sysvars@5.1.0\n    - @solana/codecs@5.1.0\n    - @solana/rpc-parsed-types@5.1.0\n    - @solana/functional@5.1.0\n    - @solana/rpc-spec-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/accounts@5.0.0\n    - @solana/rpc@5.0.0\n    - @solana/rpc-parsed-types@5.0.0\n    - @solana/rpc-subscriptions@5.0.0\n    - @solana/signers@5.0.0\n    - @solana/sysvars@5.0.0\n    - @solana/transaction-confirmation@5.0.0\n    - @solana/transaction-messages@5.0.0\n    - @solana/transactions@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/instruction-plans@5.0.0\n    - @solana/instructions@5.0.0\n    - @solana/keys@5.0.0\n    - @solana/programs@5.0.0\n    - @solana/codecs@5.0.0\n    - @solana/functional@5.0.0\n    - @solana/rpc-spec-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#521](https://github.com/anza-xyz/kit/pull/521) [`98bde94`](https://github.com/anza-xyz/kit/commit/98bde94bc4cd5f5f7e646c774bc50fef21112dd1) Thanks [@tao-stones](https://github.com/tao-stones)! - Add loadedAccountsDataSize to simulateTransaction response\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b), [`c035ab8`](https://github.com/anza-xyz/kit/commit/c035ab8a488486d160ca0361408493115cd09383), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`cfc1d92`](https://github.com/anza-xyz/kit/commit/cfc1d9249e55c79d27ac840806f198a5c5895e56), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df), [`9e8bfe4`](https://github.com/anza-xyz/kit/commit/9e8bfe460886124d1d12e444e7452db631c0ac6f), [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013)]:\n    - @solana/transactions@4.0.0\n    - @solana/errors@4.0.0\n    - @solana/keys@4.0.0\n    - @solana/transaction-messages@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/signers@4.0.0\n    - @solana/transaction-confirmation@4.0.0\n    - @solana/rpc-subscriptions@4.0.0\n    - @solana/instruction-plans@4.0.0\n    - @solana/accounts@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/instructions@4.0.0\n    - @solana/programs@4.0.0\n    - @solana/rpc@4.0.0\n    - @solana/sysvars@4.0.0\n    - @solana/rpc-parsed-types@4.0.0\n    - @solana/codecs@4.0.0\n    - @solana/functional@4.0.0\n    - @solana/rpc-spec-types@4.0.0\n\n## 3.0.0\n\n### Major Changes\n\n- [#482](https://github.com/anza-xyz/kit/pull/482) [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: Transactions must now satisfy the `SendableTransaction` type before being provided to helper functions that send transactions to the network. On top of ensuring the transaction is fully signed, this type also ensures the transaction is within size limit.\n\n- [#594](https://github.com/anza-xyz/kit/pull/594) [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Extract lifetime token from `CompiledTransactionMessage`. `CompiledTransactionMessage & CompiledTransactionMessageWithLifetime` may now be used to refer to a compiled transaction message with a lifetime token. This enables `CompiledTransactionMessages` to be encoded without the need to specify a mock lifetime token.\n\n- [#462](https://github.com/anza-xyz/kit/pull/462) [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: The `FullySignedTransaction` no longer extends the `Transaction` type so it can be composed with other flags that also narrow transaction types. This means, whenever `FullySignedTransaction` is used on its own, it will need to be replaced with `FullySignedTransaction & Transaction`.\n\n- [#691](https://github.com/anza-xyz/kit/pull/691) [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: Removes the `getComputeUnitEstimateForTransactionMessageFactory` deprecated function.\n\n### Minor Changes\n\n- [#725](https://github.com/anza-xyz/kit/pull/725) [`ce8f9db`](https://github.com/anza-xyz/kit/commit/ce8f9db3a1f7b397aa080548a54c4d3d2aa6ad7d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Re-export `@solana/instruction-plans` from `@solana/kit`.\n\n### Patch Changes\n\n- [#584](https://github.com/anza-xyz/kit/pull/584) [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate `CompilableTransactionMessage` in favour of `TransactionMessage & TransactionMessageWithFeePayer`\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`358df82`](https://github.com/anza-xyz/kit/commit/358df829770c4164fde50e57be04fe0782ddd4b5), [`93ae6f9`](https://github.com/anza-xyz/kit/commit/93ae6f96859019b6c7ea9a596ffb9b1be7a35e64), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`12d06d1`](https://github.com/anza-xyz/kit/commit/12d06d11d6a5fcf6ce06e9f9698175720666de39), [`018479f`](https://github.com/anza-xyz/kit/commit/018479f56dc7f487b9a9ec444184cea7f13d9f3a), [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`c6e8568`](https://github.com/anza-xyz/kit/commit/c6e8568214c1647b42e259f464f7e5f220627525), [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6), [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`24967d1`](https://github.com/anza-xyz/kit/commit/24967d166e9a7035bab2cdababbaae4b46d0deaa), [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845), [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf), [`81c83b1`](https://github.com/anza-xyz/kit/commit/81c83b12dd0e145bf7d08182e01824f2f14e5ee5), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`7d48ccd`](https://github.com/anza-xyz/kit/commit/7d48ccd47f08de8d7e9105567d3766ee6ff1e64f), [`a4310a5`](https://github.com/anza-xyz/kit/commit/a4310a571268c03e8d31b64ab450c922079de9c3), [`f79d05a`](https://github.com/anza-xyz/kit/commit/f79d05a92387522ef05816d1d20b75e050da42f3)]:\n    - @solana/transaction-messages@3.0.0\n    - @solana/instruction-plans@3.0.0\n    - @solana/signers@3.0.0\n    - @solana/instructions@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/transactions@3.0.0\n    - @solana/rpc-spec-types@3.0.0\n    - @solana/programs@3.0.0\n    - @solana/transaction-confirmation@3.0.0\n    - @solana/accounts@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/keys@3.0.0\n    - @solana/rpc@3.0.0\n    - @solana/rpc-subscriptions@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/sysvars@3.0.0\n    - @solana/codecs@3.0.0\n    - @solana/rpc-parsed-types@3.0.0\n    - @solana/functional@3.0.0\n\n## 2.3.0\n\n### Minor Changes\n\n- [#426](https://github.com/anza-xyz/kit/pull/426) [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate the `I` prefix of four transaction message types to stay consistent with the rest of them. Namely, the following types are renamed and their old names are marked as deprecated:\n    - `ITransactionMessageWithFeePayer` -> `TransactionMessageWithFeePayer`\n    - `ITransactionMessageWithFeePayerSigner` -> `TransactionMessageWithFeePayerSigner`\n    - `ITransactionMessageWithSigners` -> `TransactionMessageWithSigners`\n    - `ITransactionMessageWithSingleSendingSigner` -> `TransactionMessageWithSingleSendingSigner`\n\n- [#488](https://github.com/anza-xyz/kit/pull/488) [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove the `I` prefix on the following types: `IInstruction`, `IInstructionWithAccounts`, `IInstructionWithData`, `IInstructionWithSigners`, `IAccountMeta`, `IAccountLookupMeta` and `IAccountSignerMeta`. The old names are kept as aliases but marked as deprecated.\n\n### Patch Changes\n\n- [#520](https://github.com/anza-xyz/kit/pull/520) [`043d8c1`](https://github.com/anza-xyz/kit/commit/043d8c13d45c5058130154ab0507b86a1adefbf5) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate the `getComputeUnitEstimateForTransactionMessageFactory` function in favor of the `estimateComputeUnitLimitFactory` function from the `@solana-program/compute-budget` client.\n\n- Updated dependencies [[`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a), [`53e1336`](https://github.com/anza-xyz/kit/commit/53e1336149878c84048e0fde5c7e7ace6cc1e97f), [`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eb61d94`](https://github.com/anza-xyz/kit/commit/eb61d94786e212fc23778d445a94b86d2b1b024f), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`bbcb913`](https://github.com/anza-xyz/kit/commit/bbcb913839d33abc746f38d6e65e7bfd30cd2ac6), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`e6c0568`](https://github.com/anza-xyz/kit/commit/e6c0568ef34fdc04075af27eb102851123a02be0), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/transaction-messages@2.3.0\n    - @solana/transactions@2.3.0\n    - @solana/signers@2.3.0\n    - @solana/errors@2.3.0\n    - @solana/instructions@2.3.0\n    - @solana/programs@2.3.0\n    - @solana/transaction-confirmation@2.3.0\n    - @solana/accounts@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/keys@2.3.0\n    - @solana/rpc@2.3.0\n    - @solana/rpc-subscriptions@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/sysvars@2.3.0\n    - @solana/rpc-parsed-types@2.3.0\n    - @solana/codecs@2.3.0\n    - @solana/functional@2.3.0\n    - @solana/rpc-spec-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-subscriptions@2.2.1\n    - @solana/transaction-confirmation@2.2.1\n    - @solana/accounts@2.2.1\n    - @solana/addresses@2.2.1\n    - @solana/codecs@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/functional@2.2.1\n    - @solana/instructions@2.2.1\n    - @solana/keys@2.2.1\n    - @solana/programs@2.2.1\n    - @solana/rpc@2.2.1\n    - @solana/rpc-parsed-types@2.2.1\n    - @solana/rpc-spec-types@2.2.1\n    - @solana/rpc-types@2.2.1\n    - @solana/signers@2.2.1\n    - @solana/sysvars@2.2.1\n    - @solana/transaction-messages@2.2.1\n    - @solana/transactions@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/addresses@2.2.0\n    - @solana/keys@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/signers@2.2.0\n    - @solana/transaction-messages@2.2.0\n    - @solana/transactions@2.2.0\n    - @solana/accounts@2.2.0\n    - @solana/instructions@2.2.0\n    - @solana/programs@2.2.0\n    - @solana/rpc-parsed-types@2.2.0\n    - @solana/rpc-subscriptions@2.2.0\n    - @solana/sysvars@2.2.0\n    - @solana/transaction-confirmation@2.2.0\n    - @solana/rpc@2.2.0\n    - @solana/codecs@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/functional@2.2.0\n    - @solana/rpc-spec-types@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#409](https://github.com/anza-xyz/kit/pull/409) [`24a329d`](https://github.com/anza-xyz/kit/commit/24a329dda1434aaf450d1d35b022ee77556ac415) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Loosen lifetime constraint on sendAndConfirmTransaction to only require lastValidBlockHeight\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`2fb1fbc`](https://github.com/anza-xyz/kit/commit/2fb1fbcf06b12f3f892776e89d2ee32797d032a3), [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`24a329d`](https://github.com/anza-xyz/kit/commit/24a329dda1434aaf450d1d35b022ee77556ac415), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`e143797`](https://github.com/anza-xyz/kit/commit/e1437975c60b9fe1beaabb45d513a840000b25a3), [`776e18d`](https://github.com/anza-xyz/kit/commit/776e18d75c759a839608069c61da3f70b775540b), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/sysvars@2.1.1\n    - @solana/transaction-confirmation@2.1.1\n    - @solana/transaction-messages@2.1.1\n    - @solana/rpc-subscriptions@2.1.1\n    - @solana/rpc-parsed-types@2.1.1\n    - @solana/rpc-spec-types@2.1.1\n    - @solana/instructions@2.1.1\n    - @solana/transactions@2.1.1\n    - @solana/functional@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/accounts@2.1.1\n    - @solana/programs@2.1.1\n    - @solana/signers@2.1.1\n    - @solana/codecs@2.1.1\n    - @solana/errors@2.1.1\n    - @solana/keys@2.1.1\n    - @solana/rpc@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [#101](https://github.com/anza-xyz/kit/pull/101) [`4662f52`](https://github.com/anza-xyz/kit/commit/4662f52f8cdd6fd0b267adb896bc9606f1e86b5e) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a new function `fetchAddressesForLookupTables` to fetch the addresses contained in a list of lookup tables'\n\n- Updated dependencies [[`a1e45a1`](https://github.com/anza-xyz/kit/commit/a1e45a1d91ba1ac530eea0986b2ffeafb9713aec), [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`70eb596`](https://github.com/anza-xyz/kit/commit/70eb596bdff9d95d607a937615190a0d8111ad3c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b), [`c880687`](https://github.com/anza-xyz/kit/commit/c880687184239a2b2908e85b460bc0b97c07f371)]:\n    - @solana/signers@2.1.0\n    - @solana/addresses@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/keys@2.1.0\n    - @solana/sysvars@2.1.0\n    - @solana/transaction-confirmation@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/accounts@2.1.0\n    - @solana/rpc-subscriptions@2.1.0\n    - @solana/rpc@2.1.0\n    - @solana/transaction-messages@2.1.0\n    - @solana/instructions@2.1.0\n    - @solana/programs@2.1.0\n    - @solana/rpc-parsed-types@2.1.0\n    - @solana/transactions@2.1.0\n    - @solana/codecs@2.1.0\n    - @solana/functional@2.1.0\n    - @solana/rpc-spec-types@2.1.0\n\n## 2.0.0\n\n### Major Changes\n\n- [`4e7ec14`](https://github.com/solana-labs/solana-web3.js/commit/4e7ec14d9c1a74122d8b9b6cd177928bd1087c4b) Thanks [@steveluscher](https://github.com/steveluscher)! - This version of the `@solana/web3.js` Technology Preview fixes a bug with the default RPC transport, adds a utility that you can use to get an estimate of a transaction message's compute unit cost, and introduces `@solana/react` hooks for interacting with Wallet Standard wallets.\n\n    To install the fourth Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp4\n    ```\n\n    For an example of how to use the new `@solana/react` package to interact with wallets in a React application, see the example application in [`examples/react-app`](https://github.com/solana-labs/solana-web3.js/tree/master/examples/react-app#readme). We hope to see similar wallet-connection packages patterned off `@solana/react` for other application frameworks soon.\n\n    Try a demo of Technology Preview 4 in your browser at [CodeSandbox](https://codesandbox.io/p/sandbox/solana-javascript-sdk-technology-preview-4-h8cz4v?file=%2Fsrc%2Findex.ts%3A21%2C8).\n    - [#2858](https://github.com/solana-labs/solana-web3.js/pull/2858) [`22a34aa`](https://github.com/solana-labs/solana-web3.js/commit/22a34aa08d1be7e9b43ccfea94a99eaa2694e491) Thanks [@steveluscher](https://github.com/steveluscher)! - Transaction signers' methods now take `minContextSlot` as an option. This is important for signers that simulate transactions, like wallets. They might be interested in knowing the slot at which the transaction was prepared, lest they run simulation at too early a slot.\n    - [#2852](https://github.com/solana-labs/solana-web3.js/pull/2852) [`cec9048`](https://github.com/solana-labs/solana-web3.js/commit/cec9048b2f83535df7e499db5488c336981dfb5a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - The `signAndSendTransactionMessageWithSigners` function now automatically asserts that the provided transaction message contains a single sending signer and fails otherwise.\n    - [#2707](https://github.com/solana-labs/solana-web3.js/pull/2707) [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow creating keypairs and keys from ReadonlyUint8Array\n    - [#2715](https://github.com/solana-labs/solana-web3.js/pull/2715) [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Consolidated `getNullableCodec` and `getOptionCodec` with their `Zeroable` counterparts and added more configurations\n\n        Namely, the `prefix` option can now be set to `null` and the `fixed` option was replaced with the `noneValue` option which can be set to `\"zeroes\"` for `Zeroable` codecs or a custom byte array for custom representations of none values. This means the `getZeroableNullableCodec` and `getZeroableOptionCodec` functions were removed in favor of the new options.\n\n        ```ts\n        // Before.\n        getZeroableNullableCodec(getU16Codec());\n\n        // After.\n        getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n        ```\n\n        Additionally, it is now possible to create nullable codecs that have no `prefix` nor `noneValue`. In this case, the existence of the nullable item is indicated by the presence of any remaining bytes left to decode.\n\n        ```ts\n        const codec = getNullableCodec(getU16Codec(), { prefix: null });\n        codec.encode(42); // 0x2a00\n        codec.encode(null); // Encodes nothing.\n        codec.decode(new Uint8Array([42, 0])); // 42\n        codec.decode(new Uint8Array([])); // null\n        ```\n\n        Also note that it is now possible for custom `noneValue` byte arrays to be of any length — previously, it had to match the fixed-size of the nullable item.\n\n        Here is a recap of all supported scenarios, using a `u16` codec as an example:\n\n        | `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n        | ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n        | `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n        | Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n        | No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n        Reciprocal changes were made with `getOptionCodec`.\n\n    - [#2785](https://github.com/solana-labs/solana-web3.js/pull/2785) [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df) Thanks [@steveluscher](https://github.com/steveluscher)! - The development mode error message printer no longer fatals on Safari &lt; 16.4.\n    - [#2867](https://github.com/solana-labs/solana-web3.js/pull/2867) [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418) Thanks [@steveluscher](https://github.com/steveluscher)! - The `innerInstructions` property of JSON-RPC errors used snake case rather than camelCase for `stackHeight` and `programId`. This has been corrected.\n    - [#2728](https://github.com/solana-labs/solana-web3.js/pull/2728) [`f1e9ac2`](https://github.com/solana-labs/solana-web3.js/commit/f1e9ac2af579e4fbfb5550cbdbd971a87a4e4432) Thanks [@joncinque](https://github.com/joncinque)! - Simulate with the maximum quantity of compute units (1.4M) instead of `u32::MAX`\n    - [#2703](https://github.com/solana-labs/solana-web3.js/pull/2703) [`0908628`](https://github.com/solana-labs/solana-web3.js/commit/09086289a230aa1b780c1035408b48243ab960f2) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a utility function to estimate the compute unit consumption of a transaction message\n    - [#2795](https://github.com/solana-labs/solana-web3.js/pull/2795) [`ce876d9`](https://github.com/solana-labs/solana-web3.js/commit/ce876d99f04d539292abd810acd77a319c52f50d) Thanks [@steveluscher](https://github.com/steveluscher)! - Added React hooks to which you can pass a Wallet Standard `UiWalletAccount` and obtain a `MessageModifyingSigner`, `TransactionModifyingSigner`, or `TransactionSendingSigner` for use in constructing, signing, and sending Solana transactions and messages\n    - [#2772](https://github.com/solana-labs/solana-web3.js/pull/2772) [`8fe4551`](https://github.com/solana-labs/solana-web3.js/commit/8fe4551217a3ad8bfdcd1609ac7b23e8fd044c72) Thanks [@steveluscher](https://github.com/steveluscher)! - Added a series of React hooks to which you can pass a Wallet Standard `UiWalletAccount` to extract its `signMessage`, `signTransaction`, and `signAndSendTransaction` features\n    - [#2819](https://github.com/solana-labs/solana-web3.js/pull/2819) [`7ee47ae`](https://github.com/solana-labs/solana-web3.js/commit/7ee47ae24ad73b429ee863342f300a6f6c49e3d2) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug where coalesced RPC calls could end up aborted even though there were still interested consumers. This would happen if the consumer count fell to zero, then rose above zero again, in the same runloop.\n    - [#2868](https://github.com/solana-labs/solana-web3.js/pull/2868) [`91fb1f3`](https://github.com/solana-labs/solana-web3.js/commit/91fb1f39bb174cf1e899a21365153a7b3bbf3571) Thanks [@steveluscher](https://github.com/steveluscher)! - The `simulateTransaction` RPC method now accepts an `innerInstructions` param. When `true`, the simulation result will include an array of inner instructions, if any.\n    - [#2866](https://github.com/solana-labs/solana-web3.js/pull/2866) [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677) Thanks [@steveluscher](https://github.com/steveluscher)! - The `TransactionInstruction` RPC type now has `stackHeight`\n    - [#2751](https://github.com/solana-labs/solana-web3.js/pull/2751) [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow Rpc Request params to be any type, instead of requiring an array\n\n### Patch Changes\n\n- [#2728](https://github.com/solana-labs/solana-web3.js/pull/2728) [`f1e9ac2`](https://github.com/solana-labs/solana-web3.js/commit/f1e9ac2af579e4fbfb5550cbdbd971a87a4e4432) Thanks [@joncinque](https://github.com/joncinque)! - Simulate with the maximum quantity of compute units (1.4M) instead of `u32::MAX`\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2905](https://github.com/solana-labs/solana-web3.js/pull/2905) [`56fde06`](https://github.com/solana-labs/solana-web3.js/commit/56fde06003841228d4e7de162059dda648f1043d) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed the type of `config` on `getComputeUnitEstimateForTransactionMessage`. It is now optional and does not include `transactionMessage`.\n\n- [#3453](https://github.com/solana-labs/solana-web3.js/pull/3453) [`bafefed`](https://github.com/solana-labs/solana-web3.js/commit/bafefed88574009ba5a983023e439d91b65fada2) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Rename decodeTransactionMessage to decompileTransactionMessageFetchingLookupTables\n\n- [#2504](https://github.com/solana-labs/solana-web3.js/pull/2504) [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763) Thanks [@steveluscher](https://github.com/steveluscher)! - Replaced `fast-stable-stringify` with our fork\n\n- [#3290](https://github.com/solana-labs/solana-web3.js/pull/3290) [`2368163`](https://github.com/solana-labs/solana-web3.js/commit/23681637fa3ee0e2242b3b6bf087a066393bcbd8) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Throw an error if a transaction fails when being simulated to estimate CUs\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#2703](https://github.com/solana-labs/solana-web3.js/pull/2703) [`0908628`](https://github.com/solana-labs/solana-web3.js/commit/09086289a230aa1b780c1035408b48243ab960f2) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a utility function to estimate the compute unit consumption of a transaction message\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`42a70f4`](https://github.com/solana-labs/solana-web3.js/commit/42a70f4c3004e55fe6ce5a8e500f5610765ec66f), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`1ad523d`](https://github.com/solana-labs/solana-web3.js/commit/1ad523dc5792d9152a66e9dc2b83294e3eba4db0), [`7ee47ae`](https://github.com/solana-labs/solana-web3.js/commit/7ee47ae24ad73b429ee863342f300a6f6c49e3d2), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`696c72c`](https://github.com/solana-labs/solana-web3.js/commit/696c72ce25c96f06442785bddffbc890ceb802f3), [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`2040f96`](https://github.com/solana-labs/solana-web3.js/commit/2040f96cc22e4195749577d265cd6a76d8a08b87), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`1672346`](https://github.com/solana-labs/solana-web3.js/commit/1672346246fe9444b018d726ab7bfcd4bb092ec2), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`af9fa3b`](https://github.com/solana-labs/solana-web3.js/commit/af9fa3b7e83220d69eab67b37d3a36beac0e848c), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`500a991`](https://github.com/solana-labs/solana-web3.js/commit/500a991d292638eaee1fa48a7b94acfe2ff83cb7), [`c122c75`](https://github.com/solana-labs/solana-web3.js/commit/c122c75936e8fa5364edf114a5182cf119b26922), [`0b02de1`](https://github.com/solana-labs/solana-web3.js/commit/0b02de140887654f19f8eda374f40c6f5a8f5e92), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`8f94a9e`](https://github.com/solana-labs/solana-web3.js/commit/8f94a9ede71b32662bff991e6def68bc9e8bc921), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`cec9048`](https://github.com/solana-labs/solana-web3.js/commit/cec9048b2f83535df7e499db5488c336981dfb5a), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`44c8772`](https://github.com/solana-labs/solana-web3.js/commit/44c8772c8711b99e68dce3348e17bfc5b1d2a833), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`4decebb`](https://github.com/solana-labs/solana-web3.js/commit/4decebb9b619972f49c740323b59cf470696e105), [`d4965ec`](https://github.com/solana-labs/solana-web3.js/commit/d4965ece9abaf81e3006442db15f3f77d89a622c), [`9239e6e`](https://github.com/solana-labs/solana-web3.js/commit/9239e6ec972b4de9f0d15b197fbef1d2871759d9), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`22a34aa`](https://github.com/solana-labs/solana-web3.js/commit/22a34aa08d1be7e9b43ccfea94a99eaa2694e491), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/transactions@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/rpc@2.0.0\n    - @solana/rpc-subscriptions@2.0.0\n    - @solana/rpc-spec-types@2.0.0\n    - @solana/keys@2.0.0\n    - @solana/signers@2.0.0\n    - @solana/transaction-confirmation@2.0.0\n    - @solana/transaction-messages@2.0.0\n    - @solana/accounts@2.0.0\n    - @solana/codecs@2.0.0\n    - @solana/programs@2.0.0\n    - @solana/rpc-parsed-types@2.0.0\n    - @solana/instructions@2.0.0\n    - @solana/functional@2.0.0\n    - @solana/sysvars@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/accounts@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/instructions@2.0.0-rc.4\n    - @solana/keys@2.0.0-rc.4\n    - @solana/programs@2.0.0-rc.4\n    - @solana/rpc@2.0.0-rc.4\n    - @solana/rpc-subscriptions@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/signers@2.0.0-rc.4\n    - @solana/sysvars@2.0.0-rc.4\n    - @solana/transaction-confirmation@2.0.0-rc.4\n    - @solana/transaction-messages@2.0.0-rc.4\n    - @solana/transactions@2.0.0-rc.4\n    - @solana/rpc-parsed-types@2.0.0-rc.4\n    - @solana/codecs@2.0.0-rc.4\n    - @solana/functional@2.0.0-rc.4\n    - @solana/rpc-spec-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-subscriptions@2.0.0-rc.3\n    - @solana/rpc-spec-types@2.0.0-rc.3\n    - @solana/transaction-confirmation@2.0.0-rc.3\n    - @solana/rpc@2.0.0-rc.3\n    - @solana/accounts@2.0.0-rc.3\n    - @solana/sysvars@2.0.0-rc.3\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/functional@2.0.0-rc.3\n    - @solana/instructions@2.0.0-rc.3\n    - @solana/keys@2.0.0-rc.3\n    - @solana/programs@2.0.0-rc.3\n    - @solana/rpc-parsed-types@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n    - @solana/signers@2.0.0-rc.3\n    - @solana/transaction-messages@2.0.0-rc.3\n    - @solana/transactions@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3453](https://github.com/solana-labs/solana-web3.js/pull/3453) [`bafefed`](https://github.com/solana-labs/solana-web3.js/commit/bafefed88574009ba5a983023e439d91b65fada2) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Rename decodeTransactionMessage to decompileTransactionMessageFetchingLookupTables\n\n- [#3290](https://github.com/solana-labs/solana-web3.js/pull/3290) [`2368163`](https://github.com/solana-labs/solana-web3.js/commit/23681637fa3ee0e2242b3b6bf087a066393bcbd8) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Throw an error if a transaction fails when being simulated to estimate CUs\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`696c72c`](https://github.com/solana-labs/solana-web3.js/commit/696c72ce25c96f06442785bddffbc890ceb802f3), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`500a991`](https://github.com/solana-labs/solana-web3.js/commit/500a991d292638eaee1fa48a7b94acfe2ff83cb7), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`8f94a9e`](https://github.com/solana-labs/solana-web3.js/commit/8f94a9ede71b32662bff991e6def68bc9e8bc921), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`44c8772`](https://github.com/solana-labs/solana-web3.js/commit/44c8772c8711b99e68dce3348e17bfc5b1d2a833), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`4decebb`](https://github.com/solana-labs/solana-web3.js/commit/4decebb9b619972f49c740323b59cf470696e105), [`d4965ec`](https://github.com/solana-labs/solana-web3.js/commit/d4965ece9abaf81e3006442db15f3f77d89a622c), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/rpc-subscriptions@2.0.0-rc.2\n    - @solana/rpc-spec-types@2.0.0-rc.2\n    - @solana/rpc@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/transaction-confirmation@2.0.0-rc.2\n    - @solana/accounts@2.0.0-rc.2\n    - @solana/transaction-messages@2.0.0-rc.2\n    - @solana/rpc-parsed-types@2.0.0-rc.2\n    - @solana/sysvars@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/instructions@2.0.0-rc.2\n    - @solana/transactions@2.0.0-rc.2\n    - @solana/functional@2.0.0-rc.2\n    - @solana/programs@2.0.0-rc.2\n    - @solana/signers@2.0.0-rc.2\n    - @solana/codecs@2.0.0-rc.2\n    - @solana/keys@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies [[`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`1ad523d`](https://github.com/solana-labs/solana-web3.js/commit/1ad523dc5792d9152a66e9dc2b83294e3eba4db0), [`c122c75`](https://github.com/solana-labs/solana-web3.js/commit/c122c75936e8fa5364edf114a5182cf119b26922), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302)]:\n    - @solana/keys@2.0.0-rc.1\n    - @solana/signers@2.0.0-rc.1\n    - @solana/transaction-confirmation@2.0.0-rc.1\n    - @solana/rpc-subscriptions@2.0.0-rc.1\n    - @solana/transactions@2.0.0-rc.1\n    - @solana/rpc@2.0.0-rc.1\n    - @solana/sysvars@2.0.0-rc.1\n    - @solana/accounts@2.0.0-rc.1\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/functional@2.0.0-rc.1\n    - @solana/instructions@2.0.0-rc.1\n    - @solana/programs@2.0.0-rc.1\n    - @solana/rpc-parsed-types@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n    - @solana/transaction-messages@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2905](https://github.com/solana-labs/solana-web3.js/pull/2905) [`56fde06`](https://github.com/solana-labs/solana-web3.js/commit/56fde06003841228d4e7de162059dda648f1043d) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed the type of `config` on `getComputeUnitEstimateForTransactionMessage`. It is now optional and does not include `transactionMessage`.\n\n- Updated dependencies [[`42a70f4`](https://github.com/solana-labs/solana-web3.js/commit/42a70f4c3004e55fe6ce5a8e500f5610765ec66f), [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`9239e6e`](https://github.com/solana-labs/solana-web3.js/commit/9239e6ec972b4de9f0d15b197fbef1d2871759d9)]:\n    - @solana/rpc@2.0.0-rc.0\n    - @solana/transaction-messages@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/rpc-subscriptions@2.0.0-rc.0\n    - @solana/programs@2.0.0-rc.0\n    - @solana/transaction-confirmation@2.0.0-rc.0\n    - @solana/signers@2.0.0-rc.0\n    - @solana/transactions@2.0.0-rc.0\n    - @solana/accounts@2.0.0-rc.0\n    - @solana/sysvars@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/instructions@2.0.0-rc.0\n    - @solana/keys@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n    - @solana/rpc-parsed-types@2.0.0-rc.0\n    - @solana/codecs@2.0.0-rc.0\n    - @solana/functional@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Major Changes\n\n- This version of the `@solana/web3.js` Technology Preview fixes a bug with the default RPC transport, adds a utility that you can use to get an estimate of a transaction message's compute unit cost, and introduces `@solana/react` hooks for interacting with Wallet Standard wallets.\n\n    To install the fourth Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp4\n    ```\n\n    For an example of how to use the new `@solana/react` package to interact with wallets in a React application, see the example application in [`examples/react-app`](https://github.com/solana-labs/solana-web3.js/tree/master/examples/react-app#readme). We hope to see similar wallet-connection packages patterned off `@solana/react` for other application frameworks soon.\n\n    Try a demo of Technology Preview 4 in your browser at [CodeSandbox](https://codesandbox.io/p/sandbox/solana-javascript-sdk-technology-preview-4-h8cz4v?file=%2Fsrc%2Findex.ts%3A21%2C8).\n    - [#2858](https://github.com/solana-labs/solana-web3.js/pull/2858) [`22a34aa`](https://github.com/solana-labs/solana-web3.js/commit/22a34aa08d1be7e9b43ccfea94a99eaa2694e491) Thanks [@steveluscher](https://github.com/steveluscher)! - Transaction signers' methods now take `minContextSlot` as an option. This is important for signers that simulate transactions, like wallets. They might be interested in knowing the slot at which the transaction was prepared, lest they run simulation at too early a slot.\n    - [#2852](https://github.com/solana-labs/solana-web3.js/pull/2852) [`cec9048`](https://github.com/solana-labs/solana-web3.js/commit/cec9048b2f83535df7e499db5488c336981dfb5a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - The `signAndSendTransactionMessageWithSigners` function now automatically asserts that the provided transaction message contains a single sending signer and fails otherwise.\n    - [#2707](https://github.com/solana-labs/solana-web3.js/pull/2707) [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow creating keypairs and keys from ReadonlyUint8Array\n    - [#2715](https://github.com/solana-labs/solana-web3.js/pull/2715) [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Consolidated `getNullableCodec` and `getOptionCodec` with their `Zeroable` counterparts and added more configurations\n\n        Namely, the `prefix` option can now be set to `null` and the `fixed` option was replaced with the `noneValue` option which can be set to `\"zeroes\"` for `Zeroable` codecs or a custom byte array for custom representations of none values. This means the `getZeroableNullableCodec` and `getZeroableOptionCodec` functions were removed in favor of the new options.\n\n        ```ts\n        // Before.\n        getZeroableNullableCodec(getU16Codec());\n\n        // After.\n        getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n        ```\n\n        Additionally, it is now possible to create nullable codecs that have no `prefix` nor `noneValue`. In this case, the existence of the nullable item is indicated by the presence of any remaining bytes left to decode.\n\n        ```ts\n        const codec = getNullableCodec(getU16Codec(), { prefix: null });\n        codec.encode(42); // 0x2a00\n        codec.encode(null); // Encodes nothing.\n        codec.decode(new Uint8Array([42, 0])); // 42\n        codec.decode(new Uint8Array([])); // null\n        ```\n\n        Also note that it is now possible for custom `noneValue` byte arrays to be of any length — previously, it had to match the fixed-size of the nullable item.\n\n        Here is a recap of all supported scenarios, using a `u16` codec as an example:\n\n        | `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n        | ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n        | `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n        | Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n        | No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n        Reciprocal changes were made with `getOptionCodec`.\n\n    - [#2785](https://github.com/solana-labs/solana-web3.js/pull/2785) [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df) Thanks [@steveluscher](https://github.com/steveluscher)! - The development mode error message printer no longer fatals on Safari &lt; 16.4.\n    - [#2867](https://github.com/solana-labs/solana-web3.js/pull/2867) [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418) Thanks [@steveluscher](https://github.com/steveluscher)! - The `innerInstructions` property of JSON-RPC errors used snake case rather than camelCase for `stackHeight` and `programId`. This has been corrected.\n    - [#2728](https://github.com/solana-labs/solana-web3.js/pull/2728) [`f1e9ac2`](https://github.com/solana-labs/solana-web3.js/commit/f1e9ac2af579e4fbfb5550cbdbd971a87a4e4432) Thanks [@joncinque](https://github.com/joncinque)! - Simulate with the maximum quantity of compute units (1.4M) instead of `u32::MAX`\n    - [#2703](https://github.com/solana-labs/solana-web3.js/pull/2703) [`0908628`](https://github.com/solana-labs/solana-web3.js/commit/09086289a230aa1b780c1035408b48243ab960f2) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a utility function to estimate the compute unit consumption of a transaction message\n    - [#2795](https://github.com/solana-labs/solana-web3.js/pull/2795) [`ce876d9`](https://github.com/solana-labs/solana-web3.js/commit/ce876d99f04d539292abd810acd77a319c52f50d) Thanks [@steveluscher](https://github.com/steveluscher)! - Added React hooks to which you can pass a Wallet Standard `UiWalletAccount` and obtain a `MessageModifyingSigner`, `TransactionModifyingSigner`, or `TransactionSendingSigner` for use in constructing, signing, and sending Solana transactions and messages\n    - [#2772](https://github.com/solana-labs/solana-web3.js/pull/2772) [`8fe4551`](https://github.com/solana-labs/solana-web3.js/commit/8fe4551217a3ad8bfdcd1609ac7b23e8fd044c72) Thanks [@steveluscher](https://github.com/steveluscher)! - Added a series of React hooks to which you can pass a Wallet Standard `UiWalletAccount` to extract its `signMessage`, `signTransaction`, and `signAndSendTransaction` features\n    - [#2819](https://github.com/solana-labs/solana-web3.js/pull/2819) [`7ee47ae`](https://github.com/solana-labs/solana-web3.js/commit/7ee47ae24ad73b429ee863342f300a6f6c49e3d2) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug where coalesced RPC calls could end up aborted even though there were still interested consumers. This would happen if the consumer count fell to zero, then rose above zero again, in the same runloop.\n    - [#2868](https://github.com/solana-labs/solana-web3.js/pull/2868) [`91fb1f3`](https://github.com/solana-labs/solana-web3.js/commit/91fb1f39bb174cf1e899a21365153a7b3bbf3571) Thanks [@steveluscher](https://github.com/steveluscher)! - The `simulateTransaction` RPC method now accepts an `innerInstructions` param. When `true`, the simulation result will include an array of inner instructions, if any.\n    - [#2866](https://github.com/solana-labs/solana-web3.js/pull/2866) [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677) Thanks [@steveluscher](https://github.com/steveluscher)! - The `TransactionInstruction` RPC type now has `stackHeight`\n    - [#2751](https://github.com/solana-labs/solana-web3.js/pull/2751) [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow Rpc Request params to be any type, instead of requiring an array\n\n### Patch Changes\n\n- [#2728](https://github.com/solana-labs/solana-web3.js/pull/2728) [`f1e9ac2`](https://github.com/solana-labs/solana-web3.js/commit/f1e9ac2af579e4fbfb5550cbdbd971a87a4e4432) Thanks [@joncinque](https://github.com/joncinque)! - Simulate with the maximum quantity of compute units (1.4M) instead of `u32::MAX`\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#2703](https://github.com/solana-labs/solana-web3.js/pull/2703) [`0908628`](https://github.com/solana-labs/solana-web3.js/commit/09086289a230aa1b780c1035408b48243ab960f2) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a utility function to estimate the compute unit consumption of a transaction message\n\n- Updated dependencies [[`7ee47ae`](https://github.com/solana-labs/solana-web3.js/commit/7ee47ae24ad73b429ee863342f300a6f6c49e3d2), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`cec9048`](https://github.com/solana-labs/solana-web3.js/commit/cec9048b2f83535df7e499db5488c336981dfb5a), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`22a34aa`](https://github.com/solana-labs/solana-web3.js/commit/22a34aa08d1be7e9b43ccfea94a99eaa2694e491)]:\n    - @solana/rpc@2.0.0-preview.4\n    - @solana/codecs@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/signers@2.0.0-preview.4\n    - @solana/keys@2.0.0-preview.4\n    - @solana/transaction-messages@2.0.0-preview.4\n    - @solana/transaction-confirmation@2.0.0-preview.4\n    - @solana/rpc-subscriptions@2.0.0-preview.4\n    - @solana/rpc-parsed-types@2.0.0-preview.4\n    - @solana/instructions@2.0.0-preview.4\n    - @solana/transactions@2.0.0-preview.4\n    - @solana/functional@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n    - @solana/accounts@2.0.0-preview.4\n    - @solana/programs@2.0.0-preview.4\n    - @solana/sysvars@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2504](https://github.com/solana-labs/solana-web3.js/pull/2504) [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763) Thanks [@steveluscher](https://github.com/steveluscher)! - Replaced `fast-stable-stringify` with our fork\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`2040f96`](https://github.com/solana-labs/solana-web3.js/commit/2040f96cc22e4195749577d265cd6a76d8a08b87), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`1672346`](https://github.com/solana-labs/solana-web3.js/commit/1672346246fe9444b018d726ab7bfcd4bb092ec2), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`af9fa3b`](https://github.com/solana-labs/solana-web3.js/commit/af9fa3b7e83220d69eab67b37d3a36beac0e848c), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`0b02de1`](https://github.com/solana-labs/solana-web3.js/commit/0b02de140887654f19f8eda374f40c6f5a8f5e92), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/transactions@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/programs@2.0.0-preview.3\n    - @solana/codecs@2.0.0-preview.3\n    - @solana/transaction-confirmation@2.0.0-preview.3\n    - @solana/transaction-messages@2.0.0-preview.3\n    - @solana/rpc-subscriptions@2.0.0-preview.3\n    - @solana/rpc@2.0.0-preview.3\n    - @solana/keys@2.0.0-preview.3\n    - @solana/accounts@2.0.0-preview.3\n    - @solana/instructions@2.0.0-preview.3\n    - @solana/signers@2.0.0-preview.3\n    - @solana/rpc-parsed-types@2.0.0-preview.3\n    - @solana/functional@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/accounts@2.0.0-preview.2\n    - @solana/addresses@2.0.0-preview.2\n    - @solana/codecs@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n    - @solana/functional@2.0.0-preview.2\n    - @solana/instructions@2.0.0-preview.2\n    - @solana/keys@2.0.0-preview.2\n    - @solana/programs@2.0.0-preview.2\n    - @solana/rpc@2.0.0-preview.2\n    - @solana/rpc-parsed-types@2.0.0-preview.2\n    - @solana/rpc-subscriptions@2.0.0-preview.2\n    - @solana/rpc-types@2.0.0-preview.2\n    - @solana/signers@2.0.0-preview.2\n    - @solana/transaction-confirmation@2.0.0-preview.2\n    - @solana/transactions@2.0.0-preview.2\n"
  },
  {
    "path": "packages/kit/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/kit/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/kit?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/kit?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/kit\n\n# @solana/kit\n\nThis is the JavaScript SDK for building Solana apps for Node, web, and React Native.\n\n## Functions\n\nIn addition to re-exporting functions from packages in the `@solana/*` namespace, this package offers additional helpers for building Solana applications, with sensible defaults.\n\n### `airdropFactory({rpc, rpcSubscriptions})`\n\nReturns a function that you can call to airdrop a certain amount of `Lamports` to a Solana address.\n\n```ts\nimport { address, airdropFactory, createSolanaRpc, createSolanaRpcSubscriptions, devnet, lamports } from '@solana/kit';\n\nconst rpc = createSolanaRpc(devnet('http://127.0.0.1:8899'));\nconst rpcSubscriptions = createSolanaRpcSubscriptions(devnet('ws://127.0.0.1:8900'));\n\nconst airdrop = airdropFactory({ rpc, rpcSubscriptions });\n\nawait airdrop({\n    commitment: 'confirmed',\n    recipientAddress: address('FnHyam9w4NZoWR6mKN1CuGBritdsEWZQa4Z4oawLZGxa'),\n    lamports: lamports(10_000_000n),\n});\n```\n\n> [!NOTE] This only works on test clusters.\n\n### `createReactiveStoreWithInitialValueAndSlotTracking(config)`\n\nCreates a `ReactiveStreamStore` that combines an initial RPC fetch with an ongoing subscription to keep its state up to date. Uses slot-based comparison to ensure only the most recent value is kept, regardless of whether it came from the RPC response or a subscription notification.\n\nThe returned store is compatible with React's `useSyncExternalStore`, Svelte stores, Solid's `from()`, and any other reactive primitive that expects a `{ subscribe, getState }` contract.\n\n```ts\nimport {\n    address,\n    createReactiveStoreWithInitialValueAndSlotTracking,\n    createSolanaRpc,\n    createSolanaRpcSubscriptions,\n} from '@solana/kit';\n\nconst rpc = createSolanaRpc('http://127.0.0.1:8899');\nconst rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');\nconst myAddress = address('FnHyam9w4NZoWR6mKN1CuGBritdsEWZQa4Z4oawLZGxa');\n\nconst balanceStore = createReactiveStoreWithInitialValueAndSlotTracking({\n    abortSignal: AbortSignal.timeout(60_000),\n    rpcRequest: rpc.getBalance(myAddress, { commitment: 'confirmed' }),\n    rpcValueMapper: lamports => lamports,\n    rpcSubscriptionRequest: rpcSubscriptions.accountNotifications(myAddress),\n    rpcSubscriptionValueMapper: ({ lamports }) => lamports,\n});\n\nconst unsubscribe = balanceStore.subscribe(() => {\n    const error = balanceStore.getError();\n    if (error) console.error('Error:', error);\n    else console.log('Balance:', balanceStore.getState());\n});\n```\n\n### `decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, config)`\n\nReturns a `TransactionMessage` from a `CompiledTransactionMessage`. If any of the accounts in the compiled message require an address lookup table to find their address, this function will use the supplied RPC instance to fetch the contents of the address lookup table from the network.\n\n### `fetchLookupTables(lookupTableAddresses, rpc, config)`\n\nGiven a list of addresses belonging to address lookup tables, returns a map of lookup table addresses to an ordered array of the addresses they contain.\n\n### `getMinimumBalanceForRentExemption(space)` (Deprecated)\n\n> **Deprecated**: The minimum balance for an account is being actively reduced (see [SIMD-0437](https://github.com/solana-foundation/solana-improvement-documents/pull/437)) and is expected to become dynamic in future Solana upgrades (see [SIMD-0194](https://github.com/solana-foundation/solana-improvement-documents/pull/194) and [SIMD-0389](https://github.com/solana-foundation/solana-improvement-documents/pull/389)), meaning a hardcoded local computation will no longer return accurate results. Use the `getMinimumBalanceForRentExemption` RPC method or a `ClientWithGetMinimumBalance` plugin instead. This function will be removed in v7.\n\nCalculates the minimum `Lamports` required to make an account rent exempt for a given data size, without performing an RPC call.\n\n```ts\nimport { getMinimumBalanceForRentExemption } from '@solana/kit';\n\nconst mintSize = 82n;\nconst rentExemptLamports = getMinimumBalanceForRentExemption(mintSize);\n```\n\n### Compute Unit Limit Estimation\n\nCorrectly budgeting a compute unit limit for your transaction message can increase the probability that your transaction will be accepted for processing. If you don't declare a compute unit limit on your transaction, validators will assume an upper limit of 200K compute units (CU) per instruction.\n\nSince validators have an incentive to pack as many transactions into each block as possible, they may choose to include transactions that they know will fit into the remaining compute budget for the current block over transactions that might not. For this reason, you should set a compute unit limit on each of your transaction messages, whenever possible.\n\n#### `estimateComputeUnitLimitFactory({rpc})`\n\nReturns a function that estimates the compute units consumed by a transaction message by simulating it. The estimator temporarily sets the compute unit limit to the maximum (1,400,000) before simulating, so the simulation does not fail due to compute unit exhaustion.\n\n```ts\nimport { createSolanaRpc, estimateComputeUnitLimitFactory, setTransactionMessageComputeUnitLimit } from '@solana/kit';\n\nconst rpc = createSolanaRpc('http://127.0.0.1:8899');\nconst estimateComputeUnitLimit = estimateComputeUnitLimitFactory({ rpc });\n\nconst computeUnitsEstimate = await estimateComputeUnitLimit(transactionMessage);\n\nconst transactionMessageWithComputeUnitLimit = setTransactionMessageComputeUnitLimit(\n    computeUnitsEstimate,\n    transactionMessage,\n);\n```\n\n> [!NOTE]\n> For legacy and v0 transactions, if the transaction message does not already have a `SetComputeUnitLimit` instruction, the estimator will add one before simulation. This ensures that the compute unit consumption of the instruction itself is included in the estimate.\n\n#### `estimateAndSetComputeUnitLimitFactory(estimator)`\n\nReturns a function that estimates the compute unit limit for a transaction message and sets it directly on the message. If the message already has an explicit compute unit limit (one that is not the provisory value of `0` or the maximum of `1,400,000`), the message is returned unchanged. This is designed to work with `fillTransactionMessageProvisoryComputeUnitLimit`.\n\n```ts\nimport { estimateAndSetComputeUnitLimitFactory, estimateComputeUnitLimitFactory } from '@solana/kit';\n\nconst estimator = estimateComputeUnitLimitFactory({ rpc });\nconst estimateAndSetComputeUnitLimit = estimateAndSetComputeUnitLimitFactory(estimator);\n\nconst updatedMessage = await estimateAndSetComputeUnitLimit(transactionMessage);\n```\n\n#### `fillTransactionMessageProvisoryComputeUnitLimit(transactionMessage)`\n\nSets the compute unit limit to a provisory value of `0` if no compute unit limit is currently set on the transaction message. This is useful during transaction construction to reserve space for a compute unit limit that will later be replaced with an actual estimate.\n\n```ts\nimport { fillTransactionMessageProvisoryComputeUnitLimit } from '@solana/kit';\n\nconst messageWithProvisoryLimit = fillTransactionMessageProvisoryComputeUnitLimit(transactionMessage);\n```\n\n> [!WARNING]\n> The compute unit estimate is just that -- an estimate. The compute unit consumption of the actual transaction might be higher or lower than what was observed in simulation. Unless you are confident that your particular transaction message will consume the same or fewer compute units as was estimated, you might like to augment the estimate by either a fixed number of CUs or a multiplier.\n\n> [!NOTE]\n> If you are preparing an _unsigned_ transaction, destined to be signed and submitted to the network by a wallet, you might like to leave it up to the wallet to determine the compute unit limit. Consider that the wallet might have a more global view of how many compute units certain types of transactions consume, and might be able to make better estimates of an appropriate compute unit budget.\n\n### `sendAndConfirmTransactionFactory({rpc, rpcSubscriptions})`\n\nReturns a function that you can call to send a blockhash-based transaction to the network and to wait until it has been confirmed.\n\n```ts\nimport { isSolanaError, sendAndConfirmTransactionFactory, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED } from '@solana/kit';\n\nconst sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n\ntry {\n    await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {\n        console.error('This transaction depends on a blockhash that has expired');\n    } else {\n        throw e;\n    }\n}\n```\n\n### `sendAndConfirmDurableNonceTransactionFactory({rpc, rpcSubscriptions})`\n\nReturns a function that you can call to send a nonce-based transaction to the network and to wait until it has been confirmed.\n\n```ts\nimport {\n    isSolanaError,\n    sendAndConfirmDurableNonceTransactionFactory,\n    SOLANA_ERROR__INVALID_NONCE,\n    SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND,\n} from '@solana/kit';\n\nconst sendAndConfirmNonceTransaction = sendAndConfirmDurableNonceTransactionFactory({ rpc, rpcSubscriptions });\n\ntry {\n    await sendAndConfirmNonceTransaction(transaction, { commitment: 'confirmed' });\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND)) {\n        console.error(\n            'The lifetime specified by this transaction refers to a nonce account ' +\n                `\\`${e.context.nonceAccountAddress}\\` that does not exist`,\n        );\n    } else if (isSolanaError(e, SOLANA_ERROR__INVALID_NONCE)) {\n        console.error('This transaction depends on a nonce that is no longer valid');\n    } else {\n        throw e;\n    }\n}\n```\n\n### `sendTransactionWithoutConfirmingFactory({rpc, rpcSubscriptions})`\n\nReturns a function that you can call to send a transaction with any kind of lifetime to the network without waiting for it to be confirmed.\n\n```ts\nimport {\n    sendTransactionWithoutConfirmingFactory,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n} from '@solana/kit';\n\nconst sendTransaction = sendTransactionWithoutConfirmingFactory({ rpc });\n\ntry {\n    await sendTransaction(transaction, { commitment: 'confirmed' });\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE)) {\n        console.error('The transaction failed in simulation', e.cause);\n    } else {\n        throw e;\n    }\n}\n```\n"
  },
  {
    "path": "packages/kit/package.json",
    "content": "{\n    \"name\": \"@solana/kit\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Solana Javascript API\",\n    \"homepage\": \"https://www.solanakit.com\",\n    \"exports\": {\n        \".\": {\n            \"edge-light\": {\n                \"import\": \"./dist/index.node.mjs\",\n                \"require\": \"./dist/index.node.cjs\"\n            },\n            \"workerd\": {\n                \"import\": \"./dist/index.node.mjs\",\n                \"require\": \"./dist/index.node.cjs\"\n            },\n            \"browser\": {\n                \"import\": \"./dist/index.browser.mjs\",\n                \"require\": \"./dist/index.browser.cjs\"\n            },\n            \"node\": {\n                \"import\": \"./dist/index.node.mjs\",\n                \"require\": \"./dist/index.node.cjs\"\n            },\n            \"react-native\": \"./dist/index.native.mjs\",\n            \"types\": \"./dist/types/index.d.ts\"\n        },\n        \"./program-client-core\": {\n            \"edge-light\": {\n                \"import\": \"./dist/program-client-core.node.mjs\",\n                \"require\": \"./dist/program-client-core.node.cjs\"\n            },\n            \"workerd\": {\n                \"import\": \"./dist/program-client-core.node.mjs\",\n                \"require\": \"./dist/program-client-core.node.cjs\"\n            },\n            \"browser\": {\n                \"import\": \"./dist/program-client-core.browser.mjs\",\n                \"require\": \"./dist/program-client-core.browser.cjs\"\n            },\n            \"node\": {\n                \"import\": \"./dist/program-client-core.node.mjs\",\n                \"require\": \"./dist/program-client-core.node.cjs\"\n            },\n            \"react-native\": \"./dist/program-client-core.native.mjs\",\n            \"types\": \"./dist/types/program-client-core.d.ts\"\n        }\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\",\n        \"./dist/program-client-core.node.cjs\": \"./dist/program-client-core.browser.cjs\",\n        \"./dist/program-client-core.node.mjs\": \"./dist/program-client-core.browser.mjs\"\n    },\n    \"jsdelivr\": \"./dist/index.production.min.js\",\n    \"umd\": \"./dist/index.production.min.js\",\n    \"unpkg\": \"./dist/index.production.min.js\",\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.library.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/accounts\": \"workspace:*\",\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/functional\": \"workspace:*\",\n        \"@solana/instruction-plans\": \"workspace:*\",\n        \"@solana/instructions\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/offchain-messages\": \"workspace:*\",\n        \"@solana/plugin-core\": \"workspace:*\",\n        \"@solana/plugin-interfaces\": \"workspace:*\",\n        \"@solana/program-client-core\": \"workspace:*\",\n        \"@solana/programs\": \"workspace:*\",\n        \"@solana/rpc\": \"workspace:*\",\n        \"@solana/rpc-api\": \"workspace:*\",\n        \"@solana/rpc-parsed-types\": \"workspace:*\",\n        \"@solana/rpc-spec-types\": \"workspace:*\",\n        \"@solana/rpc-subscriptions\": \"workspace:*\",\n        \"@solana/subscribable\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/signers\": \"workspace:*\",\n        \"@solana/sysvars\": \"workspace:*\",\n        \"@solana/transaction-confirmation\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/kit/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/kit/src/__tests__/airdrop-internal-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { GetSignatureStatusesApi, RequestAirdropApi, Rpc } from '@solana/rpc';\nimport { lamports } from '@solana/rpc-types';\n\nimport { requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT } from '../airdrop-internal';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('requestAndConfirmAirdrop', () => {\n    let confirmSignatureOnlyTransaction: jest.Mock;\n    let rpc: Rpc<GetSignatureStatusesApi & RequestAirdropApi>;\n    let requestAirdrop: jest.Mock;\n    let sendAirdropRequest: jest.Mock;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        confirmSignatureOnlyTransaction = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        sendAirdropRequest = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        requestAirdrop = jest.fn().mockReturnValue({ send: sendAirdropRequest });\n        rpc = {\n            getSignatureStatuses: jest.fn().mockReturnValue({ send: jest.fn() }),\n            requestAirdrop,\n        };\n    });\n    it('aborts the `requestAirdrop` request when aborted', () => {\n        const abortController = new AbortController();\n        requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            confirmSignatureOnlyTransaction,\n            lamports: lamports(1n),\n            recipientAddress: '123' as Address,\n            rpc,\n        }).catch(() => {});\n        expect(sendAirdropRequest).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: false }),\n        });\n        abortController.abort();\n        expect(sendAirdropRequest).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: true }),\n        });\n    });\n    it('aborts the `confirmSignatureOnlyTransaction` call when aborted', async () => {\n        expect.assertions(2);\n        const abortController = new AbortController();\n        sendAirdropRequest.mockResolvedValue('abc' as Signature);\n        requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            confirmSignatureOnlyTransaction,\n            lamports: lamports(1n),\n            recipientAddress: '123' as Address,\n            rpc,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(confirmSignatureOnlyTransaction).toHaveBeenCalledWith(\n            expect.objectContaining({\n                abortSignal: expect.objectContaining({ aborted: false }),\n            }),\n        );\n        abortController.abort();\n        expect(confirmSignatureOnlyTransaction).toHaveBeenCalledWith(\n            expect.objectContaining({\n                abortSignal: expect.objectContaining({ aborted: true }),\n            }),\n        );\n    });\n    it('passes the expected input to the airdrop request', () => {\n        sendAirdropRequest.mockResolvedValue('abc' as Signature);\n        requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            confirmSignatureOnlyTransaction,\n            lamports: lamports(1n),\n            recipientAddress: '123' as Address,\n            rpc,\n        }).catch(() => {});\n        expect(requestAirdrop).toHaveBeenCalledWith('123', 1n, { commitment: 'finalized' });\n    });\n    it('passes the expected input to the transaction confirmer', async () => {\n        expect.assertions(1);\n        sendAirdropRequest.mockResolvedValue('abc' as Signature);\n        requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            confirmSignatureOnlyTransaction,\n            lamports: lamports(1n),\n            recipientAddress: '123' as Address,\n            rpc,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(confirmSignatureOnlyTransaction).toHaveBeenCalledWith({\n            abortSignal: expect.any(AbortSignal),\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        });\n    });\n    it('returns the airdrop transaction signature on success', async () => {\n        expect.assertions(1);\n        sendAirdropRequest.mockResolvedValue('abc' as Signature);\n        confirmSignatureOnlyTransaction.mockResolvedValue(undefined);\n        const airdropPromise = requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            confirmSignatureOnlyTransaction,\n            lamports: lamports(1n),\n            recipientAddress: '123' as Address,\n            rpc,\n        });\n        await expect(airdropPromise).resolves.toBe('abc');\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/compute-unit-limit-estimation-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT,\n    SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\nimport type { Rpc, SimulateTransactionApi } from '@solana/rpc';\nimport type { Blockhash, TransactionError } from '@solana/rpc-types';\nimport {\n    getTransactionMessageComputeUnitLimit,\n    type Nonce,\n    setTransactionMessageComputeUnitLimit,\n    type TransactionMessage,\n    type TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport {\n    Base64EncodedWireTransaction,\n    compileTransaction,\n    getBase64EncodedWireTransaction,\n    Transaction,\n} from '@solana/transactions';\n\nimport {\n    estimateAndSetComputeUnitLimitFactory,\n    estimateComputeUnitLimitFactory,\n    fillTransactionMessageProvisoryComputeUnitLimit,\n} from '../compute-unit-limit-estimation';\n\njest.mock('@solana/transactions', () => ({\n    ...jest.requireActual('@solana/transactions'),\n    compileTransaction: jest.fn(),\n    getBase64EncodedWireTransaction: jest.fn(),\n}));\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\nconst MOCK_BLOCKHASH_LIFETIME_CONSTRAINT = {\n    blockhash: 'GNtuHnNyW68wviopST3ki37Afv7LPphxfSwiHAkX5Q9H' as Blockhash,\n    lastValidBlockHeight: 0n,\n} as const;\n\nconst MOCK_TRANSACTION_MESSAGE: TransactionMessage & TransactionMessageWithFeePayer = {\n    feePayer: { address: '7U8VWgTUucttJPt5Bbkt48WknWqRGBfstBt8qqLHnfPT' as Address },\n    instructions: [],\n    version: 0,\n};\n\ndescribe('estimateComputeUnitLimitFactory', () => {\n    let sendSimulateTransactionRequest: jest.Mock;\n    let rpc: Rpc<SimulateTransactionApi>;\n    let simulateTransaction: jest.Mock;\n    beforeEach(() => {\n        jest.clearAllMocks();\n        jest.mocked(compileTransaction).mockReturnValue({} as Transaction);\n        jest.mocked(getBase64EncodedWireTransaction).mockReturnValue('MOCK_WIRE_BYTES' as Base64EncodedWireTransaction);\n        sendSimulateTransactionRequest = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        simulateTransaction = jest.fn().mockReturnValue({ send: sendSimulateTransactionRequest });\n        rpc = { simulateTransaction } as unknown as Rpc<SimulateTransactionApi>;\n    });\n\n    it('aborts the simulateTransaction request when aborted', () => {\n        const abortController = new AbortController();\n        const message = { ...MOCK_TRANSACTION_MESSAGE, lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME_CONSTRAINT };\n        estimateComputeUnitLimitFactory({ rpc })(message, { abortSignal: abortController.signal }).catch(() => {});\n        expect(sendSimulateTransactionRequest).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: false }),\n        });\n        abortController.abort();\n        expect(sendSimulateTransactionRequest).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: true }),\n        });\n    });\n\n    it('passes the expected config to the simulation request', () => {\n        const message = { ...MOCK_TRANSACTION_MESSAGE, lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME_CONSTRAINT };\n        estimateComputeUnitLimitFactory({ rpc })(message, {\n            commitment: 'finalized',\n            minContextSlot: 42n,\n        }).catch(() => {});\n        expect(simulateTransaction).toHaveBeenCalledWith(\n            expect.any(String),\n            expect.objectContaining({\n                commitment: 'finalized',\n                encoding: 'base64',\n                minContextSlot: 42n,\n                sigVerify: false,\n            }),\n        );\n    });\n\n    it('appends a set compute unit limit instruction when one does not exist', () => {\n        const message = { ...MOCK_TRANSACTION_MESSAGE, lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME_CONSTRAINT };\n        estimateComputeUnitLimitFactory({ rpc })(message).catch(() => {});\n        expect(compileTransaction).toHaveBeenCalledWith(\n            expect.objectContaining({\n                instructions: [\n                    {\n                        data:\n                            // prettier-ignore\n                            new Uint8Array([\n                                0x02, // SetComputeUnitLimit instruction index\n                                0xc0, 0x5c, 0x15, 0x00, // 1,400,000 (MAX_COMPUTE_UNIT_LIMIT)\n                            ]),\n                        programAddress: 'ComputeBudget111111111111111111111111111111',\n                    },\n                ],\n            }),\n        );\n    });\n\n    it('replaces an existing compute unit limit instruction with max before simulating', () => {\n        const message = {\n            ...MOCK_TRANSACTION_MESSAGE,\n            instructions: [\n                { programAddress: '4Kk4nA3F2nWHCcuyT8nR6oF7HQUQHmmzAVD5k8FQPKB2' as Address },\n                {\n                    data:\n                        // prettier-ignore\n                        new Uint8Array([\n                            0x02, // SetComputeUnitLimit instruction index\n                            0x01, 0x02, 0x03, 0x04, // ComputeUnits(u32)\n                        ]),\n                    programAddress: 'ComputeBudget111111111111111111111111111111' as Address,\n                },\n                { programAddress: '4Kk4nA3F2nWHCcuyT8nR6oF7HQUQHmmzAVD5k8FQPKB2' as Address },\n            ],\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME_CONSTRAINT,\n        };\n        estimateComputeUnitLimitFactory({ rpc })(message).catch(() => {});\n        expect(compileTransaction).toHaveBeenCalledWith(\n            expect.objectContaining({\n                instructions: [\n                    message.instructions[0],\n                    {\n                        ...message.instructions[1],\n                        data: new Uint8Array([0x02, 0xc0, 0x5c, 0x15, 0x00]), // Replaced with MAX_COMPUTE_UNIT_LIMIT\n                    },\n                    message.instructions[2],\n                ],\n            }),\n        );\n    });\n\n    it('does not ask for a replacement blockhash when the transaction message is a durable nonce transaction', () => {\n        const message = {\n            ...MOCK_TRANSACTION_MESSAGE,\n            instructions: [\n                {\n                    accounts: [\n                        {\n                            address: '7wJFRFuAE9x5Ptnz2VoBWsfecTCfuuM2sQCpECGypnTU' as Address,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: 'HzMoc78z1VNNf9nwD4Czt6CDYEb9LVD8KsVGP46FEmyJ' as Address,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: '11111111111111111111111111111111' as Address,\n                },\n            ],\n            lifetimeConstraint: {\n                nonce: 'BzAqD6382v5r1pcELoi8HWrBDV4dSL9NGemMn2JYAhxc' as Nonce,\n            },\n        };\n        estimateComputeUnitLimitFactory({ rpc })(message).catch(() => {});\n        expect(simulateTransaction).toHaveBeenCalledWith(\n            expect.anything(),\n            expect.objectContaining({ replaceRecentBlockhash: false }),\n        );\n    });\n\n    it('asks for a replacement blockhash when the transaction message has a blockhash lifetime', () => {\n        const message = { ...MOCK_TRANSACTION_MESSAGE, lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME_CONSTRAINT };\n        estimateComputeUnitLimitFactory({ rpc })(message).catch(() => {});\n        expect(simulateTransaction).toHaveBeenCalledWith(\n            expect.anything(),\n            expect.objectContaining({ replaceRecentBlockhash: true }),\n        );\n    });\n\n    it('asks for a replacement blockhash when the transaction message has no lifetime', () => {\n        estimateComputeUnitLimitFactory({ rpc })(MOCK_TRANSACTION_MESSAGE).catch(() => {});\n        expect(simulateTransaction).toHaveBeenCalledWith(\n            expect.anything(),\n            expect.objectContaining({ replaceRecentBlockhash: true }),\n        );\n    });\n\n    it('returns the estimated compute units on success', async () => {\n        expect.assertions(1);\n        sendSimulateTransactionRequest.mockResolvedValue({ value: { unitsConsumed: 42n } });\n        const estimatePromise = estimateComputeUnitLimitFactory({ rpc })(MOCK_TRANSACTION_MESSAGE);\n        await expect(estimatePromise).resolves.toBe(42);\n    });\n\n    it('caps the estimated compute units to u32 max', async () => {\n        expect.assertions(1);\n        sendSimulateTransactionRequest.mockResolvedValue({ value: { unitsConsumed: 5_000_000_000n } });\n        const estimatePromise = estimateComputeUnitLimitFactory({ rpc })(MOCK_TRANSACTION_MESSAGE);\n        await expect(estimatePromise).resolves.toBe(4_294_967_295);\n    });\n\n    it('throws with the transaction error as cause when the transaction fails in simulation', async () => {\n        expect.assertions(1);\n        const transactionError: TransactionError = 'AccountNotFound';\n        sendSimulateTransactionRequest.mockResolvedValue({\n            value: { err: transactionError, unitsConsumed: 42n },\n        });\n        const estimatePromise = estimateComputeUnitLimitFactory({ rpc })(MOCK_TRANSACTION_MESSAGE);\n        await expect(estimatePromise).rejects.toThrow(\n            expect.objectContaining({\n                context: expect.objectContaining({\n                    __code: SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n                    unitsConsumed: 42n,\n                }),\n            }),\n        );\n    });\n\n    it('throws with the cause when simulation fails', async () => {\n        expect.assertions(1);\n        const simulationError = new Error('RPC connection failed');\n        sendSimulateTransactionRequest.mockRejectedValue(simulationError);\n        const estimatePromise = estimateComputeUnitLimitFactory({ rpc })(MOCK_TRANSACTION_MESSAGE);\n        await expect(estimatePromise).rejects.toThrow(\n            expect.objectContaining({\n                context: expect.objectContaining({\n                    __code: SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT,\n                }),\n            }),\n        );\n    });\n});\n\ndescribe('estimateAndSetComputeUnitLimitFactory', () => {\n    it('sets the compute unit limit when none exists', async () => {\n        expect.assertions(1);\n        const mockEstimator = jest.fn().mockResolvedValue(42);\n        const estimateAndSet = estimateAndSetComputeUnitLimitFactory(mockEstimator);\n        const result = await estimateAndSet(MOCK_TRANSACTION_MESSAGE);\n        expect(getTransactionMessageComputeUnitLimit(result)).toBe(42);\n    });\n\n    it('updates when compute unit limit is set to provisory value (0)', async () => {\n        expect.assertions(1);\n        const mockEstimator = jest.fn().mockResolvedValue(42);\n        const estimateAndSet = estimateAndSetComputeUnitLimitFactory(mockEstimator);\n        const message = setTransactionMessageComputeUnitLimit(0, MOCK_TRANSACTION_MESSAGE);\n        const result = await estimateAndSet(message);\n        expect(getTransactionMessageComputeUnitLimit(result)).toBe(42);\n    });\n\n    it('updates when compute unit limit is set to max (1_400_000)', async () => {\n        expect.assertions(1);\n        const mockEstimator = jest.fn().mockResolvedValue(42);\n        const estimateAndSet = estimateAndSetComputeUnitLimitFactory(mockEstimator);\n        const message = setTransactionMessageComputeUnitLimit(1_400_000, MOCK_TRANSACTION_MESSAGE);\n        const result = await estimateAndSet(message);\n        expect(getTransactionMessageComputeUnitLimit(result)).toBe(42);\n    });\n\n    it('does not update when compute unit limit is set to an explicit value', async () => {\n        expect.assertions(2);\n        const mockEstimator = jest.fn().mockResolvedValue(42);\n        const estimateAndSet = estimateAndSetComputeUnitLimitFactory(mockEstimator);\n        const message = setTransactionMessageComputeUnitLimit(123_456, MOCK_TRANSACTION_MESSAGE);\n        const result = await estimateAndSet(message);\n        expect(mockEstimator).not.toHaveBeenCalled();\n        expect(getTransactionMessageComputeUnitLimit(result)).toBe(123_456);\n    });\n\n    it('forwards the abort signal to the estimator', async () => {\n        expect.assertions(1);\n        const mockEstimator = jest.fn().mockResolvedValue(42);\n        const estimateAndSet = estimateAndSetComputeUnitLimitFactory(mockEstimator);\n        const abortController = new AbortController();\n        await estimateAndSet(MOCK_TRANSACTION_MESSAGE, { abortSignal: abortController.signal });\n        expect(mockEstimator).toHaveBeenCalledWith(\n            expect.anything(),\n            expect.objectContaining({ abortSignal: abortController.signal }),\n        );\n    });\n});\n\ndescribe('fillTransactionMessageProvisoryComputeUnitLimit', () => {\n    it('sets compute unit limit to 0 when none exists', () => {\n        const result = fillTransactionMessageProvisoryComputeUnitLimit(MOCK_TRANSACTION_MESSAGE);\n        expect(getTransactionMessageComputeUnitLimit(result)).toBe(0);\n    });\n\n    it('returns the same reference when a compute unit limit already exists', () => {\n        const message = setTransactionMessageComputeUnitLimit(200_000, MOCK_TRANSACTION_MESSAGE);\n        const result = fillTransactionMessageProvisoryComputeUnitLimit(message);\n        expect(result).toBe(message);\n    });\n\n    it('returns the same reference when provisory limit is already set', () => {\n        const message = setTransactionMessageComputeUnitLimit(0, MOCK_TRANSACTION_MESSAGE);\n        const result = fillTransactionMessageProvisoryComputeUnitLimit(message);\n        expect(result).toBe(message);\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/create-async-generator-with-initial-value-and-slot-tracking-test.ts",
    "content": "import type { PendingRpcRequest } from '@solana/rpc';\nimport type { PendingRpcSubscriptionsRequest } from '@solana/rpc-subscriptions';\nimport type { SolanaRpcResponse } from '@solana/rpc-types';\n\nimport { createAsyncGeneratorWithInitialValueAndSlotTracking } from '../create-async-generator-with-initial-value-and-slot-tracking';\n\ntype TestValue = { count: number };\n\nfunction createMockRpcRequest(): {\n    mockRequest: PendingRpcRequest<SolanaRpcResponse<TestValue>>;\n    reject(error: unknown): void;\n    resolve(response: SolanaRpcResponse<TestValue>): void;\n} {\n    const { promise, resolve, reject } = Promise.withResolvers<SolanaRpcResponse<TestValue>>();\n    return {\n        mockRequest: {\n            reactiveStore: jest.fn().mockImplementation(() => {\n                throw new Error('not implemented');\n            }),\n            send: jest.fn().mockReturnValue(promise),\n        },\n        reject,\n        resolve,\n    };\n}\n\nfunction createMockSubscriptionRequest(): {\n    complete(): void;\n    error(err: unknown): void;\n    mockRequest: PendingRpcSubscriptionsRequest<SolanaRpcResponse<TestValue>>;\n    pushNotification(notification: SolanaRpcResponse<TestValue>): void;\n} {\n    const notifications: SolanaRpcResponse<TestValue>[] = [];\n    let waitingResolve: ((value: IteratorResult<SolanaRpcResponse<TestValue>>) => void) | null = null;\n    let waitingReject: ((reason: unknown) => void) | null = null;\n    let done = false;\n    let errorValue: unknown;\n    let hasError = false;\n\n    const asyncIterable: AsyncIterable<SolanaRpcResponse<TestValue>> = {\n        [Symbol.asyncIterator]() {\n            return {\n                next() {\n                    if (notifications.length > 0) {\n                        return Promise.resolve({ done: false, value: notifications.shift()! } as const);\n                    }\n                    if (done) {\n                        return Promise.resolve({ done: true, value: undefined } as const);\n                    }\n                    if (hasError) {\n                        return Promise.reject(errorValue as Error);\n                    }\n                    return new Promise<IteratorResult<SolanaRpcResponse<TestValue>>>((resolve, reject) => {\n                        waitingResolve = resolve;\n                        waitingReject = reject;\n                    });\n                },\n            };\n        },\n    };\n\n    const pushNotification = (notification: SolanaRpcResponse<TestValue>) => {\n        if (waitingResolve) {\n            const resolve = waitingResolve;\n            waitingResolve = null;\n            resolve({ done: false, value: notification });\n        } else {\n            notifications.push(notification);\n        }\n    };\n\n    const error = (err: unknown) => {\n        hasError = true;\n        errorValue = err;\n        if (waitingReject) {\n            const reject = waitingReject;\n            waitingResolve = null;\n            waitingReject = null;\n            reject(err);\n        }\n    };\n\n    const complete = () => {\n        done = true;\n        if (waitingResolve) {\n            const resolve = waitingResolve;\n            waitingResolve = null;\n            resolve({ done: true, value: undefined });\n        }\n    };\n\n    return {\n        complete,\n        error,\n        mockRequest: {\n            reactive: jest.fn().mockRejectedValue(new Error('not implemented')),\n            reactiveStore: jest.fn().mockImplementation(() => {\n                throw new Error('not implemented');\n            }),\n            subscribe: jest.fn().mockResolvedValue(asyncIterable),\n        },\n        pushNotification,\n    };\n}\n\nfunction rpcResponse(slot: number, value: TestValue): SolanaRpcResponse<TestValue> {\n    return { context: { slot: BigInt(slot) }, value };\n}\n\n/** Build the expected `{ context: { slot }, value }` shape for a yielded value. */\nfunction expectedResponse(slot: number, value: number) {\n    return { context: { slot: BigInt(slot) }, value };\n}\n\n/** Collect all values yielded by the generator until it's done (or collect `n` values). */\nasync function collectValues<T>(gen: AsyncGenerator<T>, n?: number): Promise<T[]> {\n    const values: T[] = [];\n    for await (const value of gen) {\n        values.push(value);\n        if (n !== undefined && values.length >= n) break;\n    }\n    return values;\n}\n\njest.useFakeTimers();\n\ndescribe('createAsyncGeneratorWithInitialValueAndSlotTracking', () => {\n    let abortController: AbortController;\n\n    beforeEach(() => {\n        abortController = new AbortController();\n    });\n\n    afterEach(() => {\n        abortController.abort();\n    });\n\n    describe('yielded values', () => {\n        it('yields the RPC response value', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            const values = await collectValues(gen, 1);\n            expect(values).toEqual([expectedResponse(100, 42)]);\n        });\n        it('yields subscription notification values', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            // Start consuming — the generator won't yield until a value arrives.\n            const valuesPromise = collectValues(gen, 1);\n            // await jest.runAllTimersAsync();\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(100, { count: 99 }));\n            const values = await valuesPromise;\n            expect(values).toEqual([expectedResponse(100, 99)]);\n        });\n        it('yields values from both sources in order of arrival', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            const valuesPromise = collectValues(gen, 2);\n            // await jest.runAllTimersAsync()\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(200, { count: 99 }));\n            const values = await valuesPromise;\n            expect(values).toEqual([expectedResponse(100, 42), expectedResponse(200, 99)]);\n        });\n        it('silently drops the RPC response when a newer subscription notification has already arrived', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification, complete } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const valuesPromise = collectValues(gen);\n            await jest.runAllTimersAsync();\n            // Subscription notification arrives first at slot 200\n            pushNotification(rpcResponse(200, { count: 99 }));\n            await jest.runAllTimersAsync();\n            // RPC response arrives later at older slot 100 — should be dropped\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            complete();\n            const values = await valuesPromise;\n            expect(values).toEqual([expectedResponse(200, 99)]);\n        });\n        it('silently drops a subscription notification when the RPC response was at a newer slot', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification, complete } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const valuesPromise = collectValues(gen);\n            // RPC response arrives first at slot 200\n            resolve(rpcResponse(200, { count: 42 }));\n            await jest.runAllTimersAsync();\n            // Subscription notification at older slot — should be dropped\n            pushNotification(rpcResponse(100, { count: 99 }));\n            await jest.runAllTimersAsync();\n            complete();\n            const values = await valuesPromise;\n            expect(values).toEqual([expectedResponse(200, 42)]);\n        });\n        it('silently drops older subscription notifications while yielding newer ones', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification, complete } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const valuesPromise = collectValues(gen);\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(100, { count: 1 }));\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(300, { count: 3 }));\n            await jest.runAllTimersAsync();\n            // Slot 200 is older than 300 — should be dropped\n            pushNotification(rpcResponse(200, { count: 2 }));\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(400, { count: 4 }));\n            await jest.runAllTimersAsync();\n            // Resolve RPC at old slot (dropped) so the generator can complete.\n            resolve(rpcResponse(0, { count: 0 }));\n            await jest.runAllTimersAsync();\n            complete();\n            const values = await valuesPromise;\n            expect(values).toEqual([expectedResponse(100, 1), expectedResponse(300, 3), expectedResponse(400, 4)]);\n        });\n        it('buffers values that arrive while the consumer has not yet called next, then yields them', async () => {\n            expect.assertions(4);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification, complete } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            // Start the generator — it enters the await.\n            const firstNext = gen.next();\n            await jest.runAllTimersAsync();\n            // First notification resolves the waiting promise; the generator yields it.\n            pushNotification(rpcResponse(100, { count: 1 }));\n            await expect(firstNext).resolves.toEqual({ done: false, value: expectedResponse(100, 1) });\n            // Generator is now suspended at the yield. Push more values — these\n            // buffer into the internal queue because the consumer hasn't called next().\n            pushNotification(rpcResponse(200, { count: 2 }));\n            pushNotification(rpcResponse(300, { count: 3 }));\n            await jest.runAllTimersAsync();\n            // Consume — values should drain from the queue.\n            await expect(gen.next()).resolves.toEqual({ done: false, value: expectedResponse(200, 2) });\n            await expect(gen.next()).resolves.toEqual({ done: false, value: expectedResponse(300, 3) });\n            // Resolve RPC at old slot (dropped) and complete subscription.\n            resolve(rpcResponse(0, { count: 0 }));\n            await jest.runAllTimersAsync();\n            complete();\n            await expect(gen.next()).resolves.toEqual({ done: true, value: undefined });\n        });\n    });\n\n    describe('error handling', () => {\n        it('throws when the RPC request fails', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, reject } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const error = new Error('rpc failed');\n            reject(error);\n            await expect(collectValues(gen)).rejects.toBe(error);\n        });\n        it('throws when the subscription fails', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const valuesPromise = collectValues(gen);\n            await jest.runAllTimersAsync();\n            const subscriptionError = new Error('subscription failed');\n            error(subscriptionError);\n            await expect(valuesPromise).rejects.toBe(subscriptionError);\n        });\n        it('throws the error even after yielding values', async () => {\n            expect.assertions(2);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            // Collect one value, then wait for the next (which will be an error).\n            const firstResult = await gen.next();\n            expect(firstResult).toEqual({ done: false, value: expectedResponse(100, 42) });\n            await jest.runAllTimersAsync();\n            error(new Error('subscription failed'));\n            await expect(gen.next()).rejects.toEqual(new Error('subscription failed'));\n        });\n    });\n\n    describe('completion', () => {\n        it('completes when the subscription ends', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, complete } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            const valuesPromise = collectValues(gen);\n            await jest.runAllTimersAsync();\n            complete();\n            const values = await valuesPromise;\n            expect(values).toEqual([expectedResponse(100, 42)]);\n        });\n        it('completes when both the subscription and RPC end while the consumer has not yet called next', async () => {\n            expect.assertions(3);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification, complete } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            // Start the generator — it enters the await.\n            const firstNext = gen.next();\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(100, { count: 1 }));\n            await expect(firstNext).resolves.toEqual({ done: false, value: expectedResponse(100, 1) });\n            // Resolve RPC at older slot (will be dropped) and complete the subscription.\n            resolve(rpcResponse(50, { count: 0 }));\n            await jest.runAllTimersAsync();\n            complete();\n            await jest.runAllTimersAsync();\n            // Next call should see done=true and return.\n            await expect(gen.next()).resolves.toEqual({ done: true, value: undefined });\n            // Subsequent calls also return done.\n            await expect(gen.next()).resolves.toEqual({ done: true, value: undefined });\n        });\n        it('yields the RPC response when the subscription ends before the RPC resolves', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, complete } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const valuesPromise = collectValues(gen);\n            await jest.runAllTimersAsync();\n            // Subscription ends before the RPC responds.\n            complete();\n            await jest.runAllTimersAsync();\n            // RPC resolves after the subscription is already done.\n            resolve(rpcResponse(100, { count: 42 }));\n            const values = await valuesPromise;\n            expect(values).toEqual([expectedResponse(100, 42)]);\n        });\n        it('does not complete until both the RPC and subscription have completed', async () => {\n            expect.assertions(2);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification, complete } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const firstNext = gen.next();\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(100, { count: 1 }));\n            await expect(firstNext).resolves.toEqual({ done: false, value: expectedResponse(100, 1) });\n            // Complete the subscription — generator should NOT be done because RPC is pending.\n            complete();\n            await jest.runAllTimersAsync();\n            // Resolve the RPC at a newer slot — should be yielded, then generator completes.\n            resolve(rpcResponse(200, { count: 42 }));\n            await expect(gen.next()).resolves.toEqual({ done: false, value: expectedResponse(200, 42) });\n        });\n        it('returns immediately if the abort signal is already aborted', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: AbortSignal.abort(),\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const values = await collectValues(gen);\n            expect(values).toEqual([]);\n        });\n    });\n\n    describe('abort signal', () => {\n        it('completes without error when the abort signal fires', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const valuesPromise = collectValues(gen);\n            await jest.runAllTimersAsync();\n            abortController.abort();\n            const values = await valuesPromise;\n            expect(values).toEqual([]);\n        });\n        it('yields values received before abort, then completes', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            // Collect the first value.\n            const firstResult = await gen.next();\n            expect(firstResult).toEqual({ done: false, value: expectedResponse(100, 42) });\n            abortController.abort();\n        });\n        it('drains buffered values after abort before completing', async () => {\n            expect.assertions(3);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            // Pull the first value — generator enters the await.\n            const firstNext = gen.next();\n            await jest.runAllTimersAsync();\n            // Push three notifications at once. The first resolves the generator's\n            // waiting promise; the other two are buffered in the mock.\n            pushNotification(rpcResponse(100, { count: 1 }));\n            pushNotification(rpcResponse(200, { count: 2 }));\n            pushNotification(rpcResponse(300, { count: 3 }));\n            // Flush so the for-await loop processes all three notifications.\n            // The generator yields slot 100 (via waitingResolve) and the loop\n            // enqueues slots 200 and 300 into the internal queue.\n            await jest.runAllTimersAsync();\n            await firstNext;\n            // Abort while slots 200 and 300 are sitting in the queue.\n            abortController.abort();\n            // Buffered values should still be yielded.\n            await expect(gen.next()).resolves.toEqual({ done: false, value: expectedResponse(200, 2) });\n            await expect(gen.next()).resolves.toEqual({ done: false, value: expectedResponse(300, 3) });\n            // Then the generator completes.\n            await expect(gen.next()).resolves.toEqual({ done: true, value: undefined });\n        });\n        it('does not yield values that arrive after abort', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const valuesPromise = collectValues(gen);\n            await jest.runAllTimersAsync();\n            abortController.abort();\n            // RPC resolves after abort.\n            resolve(rpcResponse(100, { count: 42 }));\n            const values = await valuesPromise;\n            expect(values).toEqual([]);\n        });\n        it('aborts the signal passed to the RPC request', async () => {\n            expect.assertions(2);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const nextPromise = gen.next();\n            const rpcSignal = (rpcRequest.send as jest.Mock).mock.calls[0][0].abortSignal;\n            expect(rpcSignal.aborted).toBe(false);\n            abortController.abort('test reason');\n            expect(rpcSignal.aborted).toBe(true);\n            await nextPromise;\n        });\n        it('aborts the signal passed to the subscription request', async () => {\n            expect.assertions(2);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const nextPromise = gen.next();\n            await jest.runAllTimersAsync();\n            const subscriptionSignal = (rpcSubscriptionRequest.subscribe as jest.Mock).mock.calls[0][0].abortSignal;\n            expect(subscriptionSignal.aborted).toBe(false);\n            abortController.abort('test reason');\n            expect(subscriptionSignal.aborted).toBe(true);\n            await nextPromise;\n        });\n        it('cleans up when the consumer breaks out of the loop', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const gen = createAsyncGeneratorWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            // Collect only 1 value (simulates breaking out of the loop).\n            await collectValues(gen, 1);\n            await jest.runAllTimersAsync();\n            const rpcSignal = (rpcRequest.send as jest.Mock).mock.calls[0][0].abortSignal;\n            expect(rpcSignal.aborted).toBe(true);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/create-reactive-store-with-initial-value-and-slot-tracking-test.ts",
    "content": "import type { PendingRpcRequest } from '@solana/rpc';\nimport type { PendingRpcSubscriptionsRequest } from '@solana/rpc-subscriptions';\nimport type { SolanaRpcResponse } from '@solana/rpc-types';\n\nimport { createReactiveStoreWithInitialValueAndSlotTracking } from '../create-reactive-store-with-initial-value-and-slot-tracking';\n\ntype TestValue = { count: number };\n\nfunction createMockRpcRequest(): {\n    mockRequest: PendingRpcRequest<SolanaRpcResponse<TestValue>>;\n    reject(error: unknown): void;\n    resolve(response: SolanaRpcResponse<TestValue>): void;\n} {\n    const { promise, resolve, reject } = Promise.withResolvers<SolanaRpcResponse<TestValue>>();\n    return {\n        mockRequest: {\n            reactiveStore: jest.fn().mockImplementation(() => {\n                throw new Error('not implemented');\n            }),\n            send: jest.fn().mockReturnValue(promise),\n        },\n        reject,\n        resolve,\n    };\n}\n\nfunction createMockSubscriptionRequest(): {\n    complete(): void;\n    error(err: unknown): void;\n    mockRequest: PendingRpcSubscriptionsRequest<SolanaRpcResponse<TestValue>>;\n    pushNotification(notification: SolanaRpcResponse<TestValue>): void;\n} {\n    const notifications: SolanaRpcResponse<TestValue>[] = [];\n    let waitingResolve: ((value: IteratorResult<SolanaRpcResponse<TestValue>>) => void) | null = null;\n    let waitingReject: ((reason: unknown) => void) | null = null;\n    let done = false;\n    let errorValue: unknown;\n    let hasError = false;\n\n    const asyncIterable: AsyncIterable<SolanaRpcResponse<TestValue>> = {\n        [Symbol.asyncIterator]() {\n            return {\n                next() {\n                    if (notifications.length > 0) {\n                        return Promise.resolve({ done: false, value: notifications.shift()! } as const);\n                    }\n                    if (done) {\n                        return Promise.resolve({ done: true, value: undefined } as const);\n                    }\n                    if (hasError) {\n                        return Promise.reject(errorValue as Error);\n                    }\n                    return new Promise<IteratorResult<SolanaRpcResponse<TestValue>>>((resolve, reject) => {\n                        waitingResolve = resolve;\n                        waitingReject = reject;\n                    });\n                },\n            };\n        },\n    };\n\n    const pushNotification = (notification: SolanaRpcResponse<TestValue>) => {\n        if (waitingResolve) {\n            const resolve = waitingResolve;\n            waitingResolve = null;\n            resolve({ done: false, value: notification });\n        } else {\n            notifications.push(notification);\n        }\n    };\n\n    const error = (err: unknown) => {\n        hasError = true;\n        errorValue = err;\n        if (waitingReject) {\n            const reject = waitingReject;\n            waitingResolve = null;\n            waitingReject = null;\n            reject(err);\n        }\n    };\n\n    const complete = () => {\n        done = true;\n        if (waitingResolve) {\n            const resolve = waitingResolve;\n            waitingResolve = null;\n            resolve({ done: true, value: undefined });\n        }\n    };\n\n    return {\n        complete,\n        error,\n        mockRequest: {\n            reactive: jest.fn().mockRejectedValue(new Error('not implemented')),\n            reactiveStore: jest.fn().mockImplementation(() => {\n                throw new Error('not implemented');\n            }),\n            subscribe: jest.fn().mockResolvedValue(asyncIterable),\n        },\n        pushNotification,\n    };\n}\n\nfunction rpcResponse(slot: number, value: TestValue): SolanaRpcResponse<TestValue> {\n    return { context: { slot: BigInt(slot) }, value };\n}\n\njest.useFakeTimers();\n\ndescribe('createReactiveStoreWithInitialValueAndSlotTracking', () => {\n    let abortController: AbortController;\n\n    beforeEach(() => {\n        abortController = new AbortController();\n    });\n\n    afterEach(() => {\n        abortController.abort();\n    });\n\n    describe('getState()', () => {\n        it('returns `undefined` before any data arrives', () => {\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            expect(store.getState()).toBeUndefined();\n        });\n        it('updates with the RPC response value', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toEqual({ context: { slot: 100n }, value: 42 });\n        });\n        it('updates with a subscription notification value', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(100, { count: 99 }));\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toEqual({ context: { slot: 100n }, value: 99 });\n        });\n        it('ignores the RPC response when a newer subscription notification has already arrived', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(200, { count: 99 }));\n            await jest.runAllTimersAsync();\n            // RPC response arrives later at an older slot\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toEqual({ context: { slot: 200n }, value: 99 });\n        });\n        it('ignores a subscription notification when the RPC response was at a newer slot', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(200, { count: 42 }));\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(100, { count: 99 }));\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toEqual({ context: { slot: 200n }, value: 42 });\n        });\n        it('preserves the last known value after an error', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            error(new Error('subscription failed'));\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toEqual({ context: { slot: 100n }, value: 42 });\n        });\n    });\n\n    describe('getError()', () => {\n        it('returns `undefined` before any error', () => {\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            expect(store.getError()).toBeUndefined();\n        });\n        it('captures an error from the RPC request', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, reject } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const error = new Error('rpc failed');\n            reject(error);\n            await jest.runAllTimersAsync();\n            expect(store.getError()).toBe(error);\n        });\n        it('captures an error from the subscription', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            await jest.runAllTimersAsync();\n            const subscriptionError = new Error('subscription failed');\n            error(subscriptionError);\n            await jest.runAllTimersAsync();\n            expect(store.getError()).toBe(subscriptionError);\n        });\n        it('only captures the first error when RPC fails then subscription fails', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, reject: rejectRpc } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error: errorSubscription } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            await jest.runAllTimersAsync();\n            rejectRpc(new Error('rpc error'));\n            await jest.runAllTimersAsync();\n            errorSubscription(new Error('subscription error'));\n            await jest.runAllTimersAsync();\n            expect(store.getError()).toEqual(new Error('rpc error'));\n        });\n        it('only captures the first error when subscription fails then RPC fails', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, reject: rejectRpc } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error: errorSubscription } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            await jest.runAllTimersAsync();\n            errorSubscription(new Error('subscription error'));\n            await jest.runAllTimersAsync();\n            rejectRpc(new Error('rpc error'));\n            await jest.runAllTimersAsync();\n            expect(store.getError()).toEqual(new Error('subscription error'));\n        });\n    });\n\n    describe('subscribe()', () => {\n        it('calls the subscriber when the RPC response arrives', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('calls the subscriber when a subscription notification arrives', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            await jest.runAllTimersAsync();\n            pushNotification(rpcResponse(100, { count: 99 }));\n            await jest.runAllTimersAsync();\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('does not call the subscriber when an out-of-order notification is skipped', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            resolve(rpcResponse(200, { count: 42 }));\n            await jest.runAllTimersAsync();\n            subscriber.mockClear();\n            await jest.runAllTimersAsync();\n            // This notification is at an older slot and should be skipped\n            pushNotification(rpcResponse(100, { count: 99 }));\n            await jest.runAllTimersAsync();\n            expect(subscriber).not.toHaveBeenCalled();\n        });\n        it('calls the subscriber when an error occurs', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, reject } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            reject(new Error('fail'));\n            await jest.runAllTimersAsync();\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('calls the subscriber when a subscription error occurs', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            await jest.runAllTimersAsync();\n            error(new Error('fail'));\n            await jest.runAllTimersAsync();\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('stops calling the subscriber after unsubscribe', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriber = jest.fn();\n            const unsubscribe = store.subscribe(subscriber);\n            unsubscribe();\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            expect(subscriber).not.toHaveBeenCalled();\n        });\n        it('the unsubscribe function is idempotent', () => {\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const unsubscribe = store.subscribe(jest.fn());\n            expect(() => {\n                unsubscribe();\n                unsubscribe();\n            }).not.toThrow();\n        });\n    });\n\n    describe('abort signal', () => {\n        it('aborts the signal passed to the RPC request when the caller aborts', () => {\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const rpcSignal = (rpcRequest.send as jest.Mock).mock.calls[0][0].abortSignal;\n            expect(rpcSignal.aborted).toBe(false);\n            abortController.abort('test reason');\n            expect(rpcSignal.aborted).toBe(true);\n            expect(rpcSignal.reason).toBe('test reason');\n        });\n        it('aborts the signal passed to the subscription request when the caller aborts', () => {\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriptionSignal = (rpcSubscriptionRequest.subscribe as jest.Mock).mock.calls[0][0].abortSignal;\n            expect(subscriptionSignal.aborted).toBe(false);\n            abortController.abort('test reason');\n            expect(subscriptionSignal.aborted).toBe(true);\n            expect(subscriptionSignal.reason).toBe('test reason');\n        });\n        it('swallows errors from the RPC request when the caller aborts', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, reject } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            abortController.abort();\n            reject(new Error('aborted'));\n            await jest.runAllTimersAsync();\n            expect(store.getError()).toBeUndefined();\n        });\n        it('swallows errors from the subscription when the caller aborts', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            await jest.runAllTimersAsync();\n            abortController.abort();\n            error(new Error('aborted'));\n            await jest.runAllTimersAsync();\n            expect(store.getError()).toBeUndefined();\n        });\n        it('does not update state when the RPC response arrives after abort', async () => {\n            expect.assertions(2);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            abortController.abort();\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toBeUndefined();\n            expect(subscriber).not.toHaveBeenCalled();\n        });\n        it('does not update state when a subscription notification arrives after abort', async () => {\n            expect.assertions(2);\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, pushNotification } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            await jest.runAllTimersAsync();\n            abortController.abort();\n            pushNotification(rpcResponse(100, { count: 99 }));\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toBeUndefined();\n            expect(subscriber).not.toHaveBeenCalled();\n        });\n    });\n\n    describe('getUnifiedState()', () => {\n        it('starts in `loading` status', () => {\n            const { mockRequest: rpcRequest } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'loading',\n            });\n        });\n        it('transitions to `loaded` after the RPC response arrives', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { context: { slot: 100n }, value: 42 },\n                error: undefined,\n                status: 'loaded',\n            });\n        });\n        it('transitions to `error` on RPC failure, preserving nothing (no prior data)', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, reject } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const failure = new Error('rpc failed');\n            reject(failure);\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: failure,\n                status: 'error',\n            });\n        });\n        it('transitions to `error` on subscription failure, preserving the RPC value', async () => {\n            expect.assertions(1);\n            const { mockRequest: rpcRequest, resolve } = createMockRpcRequest();\n            const { mockRequest: rpcSubscriptionRequest, error } = createMockSubscriptionRequest();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            const failure = new Error('subscription failed');\n            error(failure);\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { context: { slot: 100n }, value: 42 },\n                error: failure,\n                status: 'error',\n            });\n        });\n    });\n\n    describe('retry()', () => {\n        // Helper: returns mocks where each invocation of rpcRequest.send() /\n        // rpcSubscriptionRequest.subscribe() yields a fresh controllable instance — needed to\n        // exercise retry, which re-invokes both.\n        function createRetryableMocks() {\n            const rpcInstances: {\n                reject(error: unknown): void;\n                resolve(response: SolanaRpcResponse<TestValue>): void;\n            }[] = [];\n            const subscriptionInstances: {\n                error(err: unknown): void;\n                pushNotification(notification: SolanaRpcResponse<TestValue>): void;\n            }[] = [];\n            const rpcRequest: PendingRpcRequest<SolanaRpcResponse<TestValue>> = {\n                reactiveStore: jest.fn().mockImplementation(() => {\n                    throw new Error('not implemented');\n                }),\n                send: jest.fn().mockImplementation(() => {\n                    const { promise, resolve, reject } = Promise.withResolvers<SolanaRpcResponse<TestValue>>();\n                    rpcInstances.push({ reject, resolve });\n                    return promise;\n                }),\n            };\n            const rpcSubscriptionRequest: PendingRpcSubscriptionsRequest<SolanaRpcResponse<TestValue>> = {\n                reactive: jest.fn().mockRejectedValue(new Error('not implemented')),\n                reactiveStore: jest.fn().mockImplementation(() => {\n                    throw new Error('not implemented');\n                }),\n                subscribe: jest.fn().mockImplementation(() => {\n                    const instance = createMockSubscriptionRequest();\n                    subscriptionInstances.push({\n                        error: instance.error,\n                        pushNotification: instance.pushNotification,\n                    });\n                    return (instance.mockRequest.subscribe as jest.Mock)();\n                }),\n            };\n            return { rpcInstances, rpcRequest, rpcSubscriptionRequest, subscriptionInstances };\n        }\n\n        it('is a no-op when the store is not in error state', async () => {\n            expect.assertions(1);\n            const { rpcRequest, rpcSubscriptionRequest } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            await jest.runAllTimersAsync();\n            store.retry();\n            expect(rpcRequest.send).toHaveBeenCalledTimes(1);\n        });\n        it('transitions to `retrying` with preserved data and clears the error', async () => {\n            expect.assertions(1);\n            const { rpcInstances, rpcRequest, rpcSubscriptionRequest, subscriptionInstances } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            rpcInstances[0].resolve(rpcResponse(100, { count: 42 }));\n            await jest.runAllTimersAsync();\n            subscriptionInstances[0].error(new Error('stream died'));\n            await jest.runAllTimersAsync();\n            store.retry();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { context: { slot: 100n }, value: 42 },\n                error: undefined,\n                status: 'retrying',\n            });\n        });\n        it('re-invokes the RPC request and subscription on retry', async () => {\n            expect.assertions(2);\n            const { rpcInstances, rpcRequest, rpcSubscriptionRequest } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            rpcInstances[0].reject(new Error('boom'));\n            await jest.runAllTimersAsync();\n            store.retry();\n            await jest.runAllTimersAsync();\n            expect(rpcRequest.send).toHaveBeenCalledTimes(2);\n            expect(rpcSubscriptionRequest.subscribe).toHaveBeenCalledTimes(2);\n        });\n        it('recovers to `loaded` when the retried RPC succeeds', async () => {\n            expect.assertions(1);\n            const { rpcInstances, rpcRequest, rpcSubscriptionRequest } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            rpcInstances[0].reject(new Error('first failure'));\n            await jest.runAllTimersAsync();\n            store.retry();\n            await jest.runAllTimersAsync();\n            rpcInstances[1].resolve(rpcResponse(200, { count: 99 }));\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { context: { slot: 200n }, value: 99 },\n                error: undefined,\n                status: 'loaded',\n            });\n        });\n        it('transitions to `error` again when the retried RPC also fails', async () => {\n            expect.assertions(1);\n            const { rpcInstances, rpcRequest, rpcSubscriptionRequest } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            rpcInstances[0].reject(new Error('first'));\n            await jest.runAllTimersAsync();\n            store.retry();\n            await jest.runAllTimersAsync();\n            const secondFailure = new Error('second');\n            rpcInstances[1].reject(secondFailure);\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: secondFailure,\n                status: 'error',\n            });\n        });\n        it('notifies subscribers on the retrying transition', async () => {\n            expect.assertions(1);\n            const { rpcInstances, rpcRequest, rpcSubscriptionRequest } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            rpcInstances[0].reject(new Error('fail'));\n            await jest.runAllTimersAsync();\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            store.retry();\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('does not re-invoke the RPC request after the caller has aborted', async () => {\n            expect.assertions(1);\n            const { rpcInstances, rpcRequest, rpcSubscriptionRequest } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            rpcInstances[0].reject(new Error('fail'));\n            await jest.runAllTimersAsync();\n            abortController.abort();\n            store.retry();\n            await jest.runAllTimersAsync();\n            expect(rpcRequest.send).toHaveBeenCalledTimes(1);\n        });\n        it('leaves the store in `error` state after the caller has aborted', async () => {\n            expect.assertions(1);\n            const { rpcInstances, rpcRequest, rpcSubscriptionRequest } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            const failure = new Error('fail');\n            rpcInstances[0].reject(failure);\n            await jest.runAllTimersAsync();\n            abortController.abort();\n            store.retry();\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: failure,\n                status: 'error',\n            });\n        });\n        it('does not notify subscribers after the caller has aborted', async () => {\n            expect.assertions(1);\n            const { rpcInstances, rpcRequest, rpcSubscriptionRequest } = createRetryableMocks();\n            const store = createReactiveStoreWithInitialValueAndSlotTracking({\n                abortSignal: abortController.signal,\n                rpcRequest,\n                rpcSubscriptionRequest,\n                rpcSubscriptionValueMapper: v => v.count,\n                rpcValueMapper: v => v.count,\n            });\n            rpcInstances[0].reject(new Error('fail'));\n            await jest.runAllTimersAsync();\n            abortController.abort();\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            store.retry();\n            await jest.runAllTimersAsync();\n            expect(subscriber).not.toHaveBeenCalled();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/decompile-transaction-message-fetching-lookup-tables-test.ts",
    "content": "import { FetchAccountsConfig, fetchJsonParsedAccounts } from '@solana/accounts';\nimport type { Address } from '@solana/addresses';\nimport type { GetMultipleAccountsApi, Rpc } from '@solana/rpc';\nimport type { Blockhash, Lamports } from '@solana/rpc-types';\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    decompileTransactionMessage,\n    TransactionMessage,\n} from '@solana/transaction-messages';\n\nimport { decompileTransactionMessageFetchingLookupTables } from '../decompile-transaction-message-fetching-lookup-tables';\n\njest.mock('@solana/accounts');\njest.mock('@solana/transaction-messages');\n\ndescribe('decompileTransactionMessageFetchingLookupTables', () => {\n    const blockhash = 'abc' as Blockhash;\n    const rpc: Rpc<GetMultipleAccountsApi> = {\n        getMultipleAccounts: jest.fn(),\n    };\n\n    describe('for a legacy transaction', () => {\n        const compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime = {\n            // no `addressTableLookups` field\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            instructions: [],\n            lifetimeToken: blockhash,\n            staticAccounts: [],\n            version: 'legacy',\n        };\n\n        const transactionMessage = { version: 'legacy' } as unknown as TransactionMessage;\n\n        beforeEach(() => {\n            (decompileTransactionMessage as jest.Mock).mockReturnValue(transactionMessage);\n            // reset mock calls\n            jest.clearAllMocks();\n        });\n\n        it('should return the result of `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await expect(\n                decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc),\n            ).resolves.toStrictEqual(transactionMessage);\n        });\n\n        it('should not call the `fetchJsonParsedAccounts` function', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(fetchJsonParsedAccounts).not.toHaveBeenCalled();\n        });\n\n        it('should call `decompileTransactionMessage` with the input transaction', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                compiledTransactionMessage,\n                expect.any(Object), // config\n            );\n        });\n\n        it('should call the `decompileTransactionMessage` with no lookup tables', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    addressesByLookupTableAddress: {},\n                }),\n            );\n        });\n\n        it('should pass `lastValidBlockHeight` to `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, {\n                lastValidBlockHeight: 100n,\n            });\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    lastValidBlockHeight: 100n,\n                }),\n            );\n        });\n    });\n\n    describe('for a v0 transaction with no `addressTableLookups` field', () => {\n        const compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime = {\n            // no `addressTableLookups` field\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            instructions: [],\n            lifetimeToken: blockhash,\n            staticAccounts: [],\n            version: 0,\n        };\n\n        const transactionMessage = { version: 0 } as unknown as TransactionMessage;\n\n        beforeEach(() => {\n            (decompileTransactionMessage as jest.Mock).mockReturnValue(transactionMessage);\n            // reset mock calls\n            jest.clearAllMocks();\n        });\n\n        it('should return the result of `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await expect(\n                decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc),\n            ).resolves.toStrictEqual(transactionMessage);\n        });\n\n        it('should not call the `fetchJsonParsedAccounts` function', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(fetchJsonParsedAccounts).not.toHaveBeenCalled();\n        });\n\n        it('should call `decompileTransactionMessage` with the input transaction', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                compiledTransactionMessage,\n                expect.any(Object), // config\n            );\n        });\n\n        it('should call `decompileTransactionMessage` with no lookup tables', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    addressesByLookupTableAddress: {},\n                }),\n            );\n        });\n\n        it('should pass `lastValidBlockHeight` to `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, {\n                lastValidBlockHeight: 100n,\n            });\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    lastValidBlockHeight: 100n,\n                }),\n            );\n        });\n    });\n\n    describe('for a v0 transaction with empty `addressTableLookups`', () => {\n        const compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime = {\n            addressTableLookups: [],\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            instructions: [],\n            lifetimeToken: blockhash,\n            staticAccounts: [],\n            version: 0,\n        };\n\n        const transactionMessage = { version: 0 } as unknown as TransactionMessage;\n\n        beforeEach(() => {\n            (decompileTransactionMessage as jest.Mock).mockReturnValue(transactionMessage);\n            // reset mock calls\n            jest.clearAllMocks();\n        });\n\n        it('should return the result of `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await expect(\n                decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc),\n            ).resolves.toStrictEqual(transactionMessage);\n        });\n\n        it('should not call the `fetchJsonParsedAccounts` function', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(fetchJsonParsedAccounts).not.toHaveBeenCalled();\n        });\n\n        it('should call `decompileTransactionMessage` with the input transaction', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                compiledTransactionMessage,\n                expect.any(Object), // config\n            );\n        });\n\n        it('should call `decompileTransactionMessage` with no lookup tables', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    addressesByLookupTableAddress: {},\n                }),\n            );\n        });\n\n        it('should pass `lastValidBlockHeight` to `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, {\n                lastValidBlockHeight: 100n,\n            });\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    lastValidBlockHeight: 100n,\n                }),\n            );\n        });\n    });\n\n    describe('for a v0 transaction with non-empty `addressTableLookups`', () => {\n        const lookupTableAddress1 = '1111' as Address;\n        const lookupTableAddress2 = '2222' as Address;\n\n        const compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime = {\n            addressTableLookups: [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n                {\n                    lookupTableAddress: lookupTableAddress2,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n            ],\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            instructions: [],\n            lifetimeToken: blockhash,\n            staticAccounts: [],\n            version: 0,\n        };\n\n        const transactionMessage = { version: 0 } as unknown as TransactionMessage;\n\n        const addressInLookup1 = '3333' as Address;\n        const addressInLookup2 = '4444' as Address;\n\n        const fetchedLookupTables: Awaited<ReturnType<typeof fetchJsonParsedAccounts>> = [\n            {\n                address: lookupTableAddress1,\n                data: {\n                    addresses: [addressInLookup1],\n                },\n                executable: false,\n                exists: true,\n                lamports: 0n as Lamports,\n                programAddress: 'program' as Address,\n                space: 0n,\n            },\n            {\n                address: lookupTableAddress2,\n                data: {\n                    addresses: [addressInLookup2],\n                },\n                executable: false,\n                exists: true,\n                lamports: 0n as Lamports,\n                programAddress: 'program' as Address,\n                space: 0n,\n            },\n        ];\n\n        beforeEach(() => {\n            (decompileTransactionMessage as jest.Mock).mockReturnValue(transactionMessage);\n            (fetchJsonParsedAccounts as jest.Mock).mockResolvedValue(fetchedLookupTables);\n\n            // reset mock calls\n            jest.clearAllMocks();\n        });\n\n        it('should return the result of `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await expect(\n                decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc),\n            ).resolves.toStrictEqual(transactionMessage);\n        });\n\n        it('should call `fetchJsonParsedAccounts` with the lookup table addresses', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(fetchJsonParsedAccounts).toHaveBeenCalledWith(rpc, [lookupTableAddress1, lookupTableAddress2], {});\n        });\n\n        it('should pass config to `fetchJsonParsedAccounts`', async () => {\n            expect.assertions(1);\n            const fetchAccountsConfig: FetchAccountsConfig = {\n                abortSignal: new AbortController().signal,\n                commitment: 'confirmed',\n                minContextSlot: 100n,\n            };\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, {\n                ...fetchAccountsConfig,\n                lastValidBlockHeight: 100n,\n            });\n            expect(fetchJsonParsedAccounts).toHaveBeenCalledWith(\n                rpc,\n                [lookupTableAddress1, lookupTableAddress2],\n                fetchAccountsConfig,\n            );\n        });\n\n        it('should call `decompileTransactionMessage` with the input transaction', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                compiledTransactionMessage,\n                expect.any(Object), // config\n            );\n        });\n\n        it('should call `decompileTransactionMessage` with the addresses from the lookup tables', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    addressesByLookupTableAddress: {\n                        [lookupTableAddress1]: [addressInLookup1],\n                        [lookupTableAddress2]: [addressInLookup2],\n                    },\n                }),\n            );\n        });\n\n        it('should pass `lastValidBlockHeight` to `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, {\n                lastValidBlockHeight: 100n,\n            });\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    lastValidBlockHeight: 100n,\n                }),\n            );\n        });\n    });\n\n    describe('for a v1 transaction', () => {\n        const compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime = {\n            // no `addressTableLookups` field\n            configMask: 0,\n            configValues: [],\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            instructionHeaders: [],\n            instructionPayloads: [],\n            lifetimeToken: blockhash,\n            numInstructions: 0,\n            numStaticAccounts: 0,\n            staticAccounts: [],\n            version: 1,\n        };\n\n        const transactionMessage = { version: 1 } as unknown as TransactionMessage;\n\n        beforeEach(() => {\n            (decompileTransactionMessage as jest.Mock).mockReturnValue(transactionMessage);\n            // reset mock calls\n            jest.clearAllMocks();\n        });\n\n        it('should return the result of `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await expect(\n                decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc),\n            ).resolves.toStrictEqual(transactionMessage);\n        });\n\n        it('should not call the `fetchJsonParsedAccounts` function', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(fetchJsonParsedAccounts).not.toHaveBeenCalled();\n        });\n\n        it('should call `decompileTransactionMessage` with the input transaction', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                compiledTransactionMessage,\n                expect.any(Object), // config\n            );\n        });\n\n        it('should call the `decompileTransactionMessage` with no lookup tables', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    addressesByLookupTableAddress: {},\n                }),\n            );\n        });\n\n        it('should pass `lastValidBlockHeight` to `decompileTransactionMessage`', async () => {\n            expect.assertions(1);\n            await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc, {\n                lastValidBlockHeight: 100n,\n            });\n            expect(decompileTransactionMessage).toHaveBeenCalledWith(\n                expect.any(Object), // transaction\n                expect.objectContaining({\n                    lastValidBlockHeight: 100n,\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/fetch-lookup-tables-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED,\n    SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND,\n    SolanaError,\n} from '@solana/errors';\nimport { GetMultipleAccountsApi, Rpc } from '@solana/rpc';\n\nimport { fetchAddressesForLookupTables } from '../fetch-lookup-tables';\n\ndescribe('fetchAddressesForLookupTables', () => {\n    describe('when no lookup table addresses are provided', () => {\n        it('returns an empty object', async () => {\n            expect.assertions(1);\n            const rpc = {\n                getMultipleAccounts: jest.fn(),\n            };\n\n            const lookupTableAddresses: Address[] = [];\n            const lookupTables = await fetchAddressesForLookupTables(lookupTableAddresses, rpc);\n            expect(lookupTables).toEqual({});\n        });\n\n        it('does not call the RPC', async () => {\n            expect.assertions(1);\n            const rpc = {\n                getMultipleAccounts: jest.fn(),\n            };\n\n            const lookupTableAddresses: Address[] = [];\n            await fetchAddressesForLookupTables(lookupTableAddresses, rpc);\n            expect(rpc.getMultipleAccounts).not.toHaveBeenCalled();\n        });\n    });\n\n    describe('when lookup table addresses are provided', () => {\n        it('returns an object with the lookup table addresses as keys and the addresses as values', async () => {\n            expect.assertions(1);\n\n            const rpc: Rpc<GetMultipleAccountsApi> = {\n                getMultipleAccounts: jest.fn().mockReturnValue({\n                    send: jest.fn().mockResolvedValue({\n                        value: [\n                            {\n                                data: {\n                                    parsed: {\n                                        info: {\n                                            addresses: ['1111', '2222'],\n                                        },\n                                    },\n                                },\n                            },\n                            {\n                                data: {\n                                    parsed: {\n                                        info: {\n                                            addresses: ['3333'],\n                                        },\n                                    },\n                                },\n                            },\n                        ],\n                    }),\n                }),\n            };\n\n            const lookupTableAddresses: Address[] = ['abc' as Address, 'def' as Address];\n            const lookupTables = await fetchAddressesForLookupTables(lookupTableAddresses, rpc);\n\n            expect(lookupTables).toEqual({\n                abc: ['1111', '2222'],\n                def: ['3333'],\n            });\n        });\n\n        it('throws when the RPC returns invalid data', async () => {\n            expect.assertions(1);\n\n            const rpc: Rpc<GetMultipleAccountsApi> = {\n                getMultipleAccounts: jest.fn().mockReturnValue({\n                    send: jest.fn().mockResolvedValue({\n                        value: [\n                            {\n                                data: {\n                                    parsed: {\n                                        info: {\n                                            addresses: ['1111', '2222'],\n                                        },\n                                    },\n                                },\n                            },\n                            {\n                                data: ['', 'base64'],\n                            },\n                        ],\n                    }),\n                }),\n            };\n\n            const lookupTableAddresses: Address[] = ['abc' as Address, 'def' as Address];\n            await expect(fetchAddressesForLookupTables(lookupTableAddresses, rpc)).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__ACCOUNTS__EXPECTED_ALL_ACCOUNTS_TO_BE_DECODED, {\n                    addresses: ['def'],\n                }),\n            );\n        });\n\n        it('throws when the RPC returns missing data', async () => {\n            expect.assertions(1);\n\n            const rpc: Rpc<GetMultipleAccountsApi> = {\n                getMultipleAccounts: jest.fn().mockReturnValue({\n                    send: jest.fn().mockResolvedValue({\n                        value: [\n                            // returns abc, not def\n                            {\n                                data: {\n                                    parsed: {\n                                        info: {\n                                            addresses: ['1111', '2222'],\n                                        },\n                                    },\n                                },\n                            },\n                            null,\n                        ],\n                    }),\n                }),\n            };\n\n            const lookupTableAddresses: Address[] = ['abc' as Address, 'def' as Address];\n            await expect(fetchAddressesForLookupTables(lookupTableAddresses, rpc)).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND, { addresses: ['def'] }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/get-minimum-balance-for-rent-exemption-test.ts",
    "content": "import type { Lamports } from '@solana/rpc-types';\n\nimport { getMinimumBalanceForRentExemption } from '../get-minimum-balance-for-rent-exemption';\n\ndescribe('getMinimumBalanceForRentExemption', () => {\n    it.each`\n        space     | lamports\n        ${0n}     | ${890_880n}\n        ${100n}   | ${890_880n + 100n * 3_480n * 2n}\n        ${1_024n} | ${890_880n + 1_024n * 3_480n * 2n}\n    `('calculates the correct rent for an account with $space bytes of space allocated', ({ space, lamports }) => {\n        expect.assertions(1);\n        expect(getMinimumBalanceForRentExemption(space)).toBe(lamports as unknown as Lamports);\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/program-client-core-subpath-export-test.node.ts",
    "content": "import { createRequire } from 'node:module';\nimport path from 'node:path';\n\nconst kitPackageFolder = path.resolve(__dirname, '../../');\nconst requireFromKit = createRequire(path.join(kitPackageFolder, 'package.json'));\n\ndescribe('@solana/kit program-client-core subpath export', () => {\n    it('resolves `@solana/kit/program-client-core` to its dedicated dist entrypoint', () => {\n        const resolvedSubpathExport = requireFromKit.resolve('@solana/kit/program-client-core');\n        expect(resolvedSubpathExport).toBe(path.join(kitPackageFolder, 'dist', 'program-client-core.node.cjs'));\n    });\n\n    it('keeps root and subpath exports distinct', () => {\n        const resolvedRootExport = requireFromKit.resolve('@solana/kit');\n        const resolvedSubpathExport = requireFromKit.resolve('@solana/kit/program-client-core');\n\n        expect(resolvedRootExport).toBe(path.join(kitPackageFolder, 'dist', 'index.node.cjs'));\n        expect(resolvedRootExport).not.toBe(resolvedSubpathExport);\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/send-and-confirm-durable-nonce-transaction-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__INVALID_NONCE, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport type { GetAccountInfoApi, GetSignatureStatusesApi, Rpc, SendTransactionApi } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport {\n    createNonceInvalidationPromiseFactory,\n    createRecentSignatureConfirmationPromiseFactory,\n} from '@solana/transaction-confirmation';\nimport { Nonce } from '@solana/transaction-messages';\nimport { SendableTransaction, Transaction, TransactionWithDurableNonceLifetime } from '@solana/transactions';\n\nimport { sendAndConfirmDurableNonceTransactionFactory } from '../send-and-confirm-durable-nonce-transaction';\n\n// Partially mock the transaction-confirmation module - keep the real waitForDurableNonceTransactionConfirmation\njest.mock('@solana/transaction-confirmation', () => ({\n    ...jest.requireActual('@solana/transaction-confirmation'),\n    createNonceInvalidationPromiseFactory: jest.fn(),\n    createRecentSignatureConfirmationPromiseFactory: jest.fn(),\n}));\n\njest.mock('@solana/transactions', () => ({\n    ...jest.requireActual('@solana/transactions'),\n    getBase64EncodedWireTransaction: jest.fn().mockReturnValue('MOCK_WIRE_TRANSACTION'),\n}));\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\nconst DELAYED_SIGNATURE_INTERVAL = 1000;\n\ndescribe('sendAndConfirmDurableNonceTransactionFactory', () => {\n    const MOCK_DURABLE_NONCE_TRANSACTION = {\n        lifetimeConstraint: { nonce: 'abc' as Nonce },\n        signatures: {\n            ['1234' as Address]: new Uint8Array() as SignatureBytes,\n        },\n    } as SendableTransaction & Transaction & TransactionWithDurableNonceLifetime;\n\n    let mockGetNonceInvalidationPromise: jest.Mock;\n    let mockGetRecentSignatureConfirmationPromise: jest.Mock;\n    let getSignatureStatusesMock: jest.Mock;\n    let sendTransactionMock: jest.Mock;\n    let rpc: Rpc<GetAccountInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\n    let rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi & SignatureNotificationsApi>;\n\n    beforeEach(() => {\n        jest.useFakeTimers();\n\n        // Setup mock for nonce invalidation promise factory\n        mockGetNonceInvalidationPromise = jest.fn();\n        jest.mocked(createNonceInvalidationPromiseFactory).mockReturnValue(mockGetNonceInvalidationPromise);\n\n        // Setup mock for signature confirmation promise factory\n        mockGetRecentSignatureConfirmationPromise = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        jest.mocked(createRecentSignatureConfirmationPromiseFactory).mockReturnValue(\n            mockGetRecentSignatureConfirmationPromise,\n        );\n\n        // Mock RPC methods\n        getSignatureStatusesMock = jest.fn();\n        sendTransactionMock = jest.fn();\n\n        rpc = {\n            getAccountInfo: jest.fn().mockReturnValue({ send: jest.fn() }),\n            getSignatureStatuses: jest.fn().mockReturnValue({ send: getSignatureStatusesMock }),\n            sendTransaction: jest.fn().mockReturnValue({ send: sendTransactionMock }),\n        } as unknown as Rpc<GetAccountInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\n\n        rpcSubscriptions = {} as unknown as RpcSubscriptions<AccountNotificationsApi & SignatureNotificationsApi>;\n    });\n\n    describe('race condition handling', () => {\n        it('resolves when nonce invalidation rejects but transaction exists with sufficient commitment', async () => {\n            expect.assertions(1);\n\n            // Setup: nonce invalidation throws INVALID_NONCE\n            mockGetNonceInvalidationPromise.mockRejectedValue(\n                new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                    actualNonceValue: 'xyz',\n                    expectedNonceValue: 'abc',\n                }),\n            );\n\n            // Setup: getSignatureStatuses shows transaction exists with finalized commitment\n            getSignatureStatusesMock.mockResolvedValue({\n                value: [\n                    {\n                        confirmationStatus: 'finalized',\n                        err: null,\n                    },\n                ],\n            });\n\n            const sendAndConfirm = sendAndConfirmDurableNonceTransactionFactory({\n                rpc,\n                rpcSubscriptions,\n            });\n\n            const resultPromise = sendAndConfirm(MOCK_DURABLE_NONCE_TRANSACTION, {\n                commitment: 'finalized',\n            });\n\n            await jest.runAllTimersAsync();\n\n            // Should resolve without throwing because tx exists with sufficient commitment\n            await expect(resultPromise).resolves.toBeUndefined();\n        });\n\n        it('continues waiting for signature confirmation when transaction exists but commitment not met', async () => {\n            expect.assertions(2);\n\n            // Setup: nonce invalidation throws INVALID_NONCE\n            mockGetNonceInvalidationPromise.mockRejectedValue(\n                new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                    actualNonceValue: 'xyz',\n                    expectedNonceValue: 'abc',\n                }),\n            );\n\n            // Setup: getSignatureStatuses shows transaction exists but only 'confirmed' (not 'finalized')\n            getSignatureStatusesMock.mockResolvedValue({\n                value: [\n                    {\n                        confirmationStatus: 'confirmed',\n                        err: null,\n                    },\n                ],\n            });\n\n            // Setup: signature confirmation resolves AFTER nonce invalidation rejects\n            // Using a delayed promise to ensure proper ordering\n            mockGetRecentSignatureConfirmationPromise.mockImplementation(\n                () => new Promise(resolve => setTimeout(resolve, DELAYED_SIGNATURE_INTERVAL)),\n            );\n\n            const sendAndConfirm = sendAndConfirmDurableNonceTransactionFactory({\n                rpc,\n                rpcSubscriptions,\n            });\n\n            const resultPromise = sendAndConfirm(MOCK_DURABLE_NONCE_TRANSACTION, {\n                commitment: 'finalized',\n            });\n\n            // First, let the nonce invalidation reject and our wrapper check getSignatureStatuses\n            await jest.advanceTimersByTimeAsync(0);\n\n            // Verify getSignatureStatuses was called to check tx status\n            expect(rpc.getSignatureStatuses).toHaveBeenCalled();\n\n            // Now advance time to let signature confirmation resolve\n            await jest.advanceTimersByTimeAsync(DELAYED_SIGNATURE_INTERVAL);\n\n            // Should resolve when signature confirmation completes\n            await expect(resultPromise).resolves.toBeUndefined();\n        });\n\n        it('throws INVALID_NONCE when nonce invalidation rejects and transaction does not exist', async () => {\n            expect.assertions(1);\n\n            // Setup: nonce invalidation throws INVALID_NONCE\n            const invalidNonceError = new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                actualNonceValue: 'xyz',\n                expectedNonceValue: 'abc',\n            });\n            mockGetNonceInvalidationPromise.mockRejectedValue(invalidNonceError);\n\n            // Setup: getSignatureStatuses returns null (transaction doesn't exist)\n            getSignatureStatusesMock.mockResolvedValue({\n                value: [null],\n            });\n\n            const sendAndConfirm = sendAndConfirmDurableNonceTransactionFactory({\n                rpc,\n                rpcSubscriptions,\n            });\n\n            // Should throw INVALID_NONCE because transaction doesn't exist\n            await expect(\n                sendAndConfirm(MOCK_DURABLE_NONCE_TRANSACTION, {\n                    commitment: 'finalized',\n                }),\n            ).rejects.toThrow(invalidNonceError);\n        });\n\n        it('throws transaction error when transaction exists but failed on-chain', async () => {\n            expect.assertions(1);\n\n            // Setup: nonce invalidation throws INVALID_NONCE\n            mockGetNonceInvalidationPromise.mockRejectedValue(\n                new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                    actualNonceValue: 'xyz',\n                    expectedNonceValue: 'abc',\n                }),\n            );\n\n            // Setup: getSignatureStatuses shows transaction exists but has error\n            getSignatureStatusesMock.mockResolvedValue({\n                value: [\n                    {\n                        confirmationStatus: 'finalized',\n                        err: { InstructionError: [0, 'InvalidAccountData'] },\n                    },\n                ],\n            });\n\n            const sendAndConfirm = sendAndConfirmDurableNonceTransactionFactory({\n                rpc,\n                rpcSubscriptions,\n            });\n\n            // Should throw the transaction error (not INVALID_NONCE)\n            await expect(\n                sendAndConfirm(MOCK_DURABLE_NONCE_TRANSACTION, {\n                    commitment: 'finalized',\n                }),\n            ).rejects.toThrow(SolanaError);\n        });\n\n        it('throws INVALID_NONCE when getSignatureStatuses RPC call fails', async () => {\n            expect.assertions(2);\n\n            // Setup: nonce invalidation throws INVALID_NONCE\n            const invalidNonceError = new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                actualNonceValue: 'xyz',\n                expectedNonceValue: 'abc',\n            });\n            mockGetNonceInvalidationPromise.mockRejectedValue(invalidNonceError);\n\n            // Setup: getSignatureStatuses throws\n            getSignatureStatusesMock.mockRejectedValue(new Error('RPC connection failed'));\n\n            const sendAndConfirm = sendAndConfirmDurableNonceTransactionFactory({\n                rpc,\n                rpcSubscriptions,\n            });\n\n            // Should throw INVALID_NONCE (not the RPC error)\n            await expect(\n                sendAndConfirm(MOCK_DURABLE_NONCE_TRANSACTION, {\n                    commitment: 'finalized',\n                }),\n            ).rejects.toThrow(invalidNonceError);\n\n            // Verify getSignatureStatuses was called (the RPC error was caught and ignored)\n            expect(rpc.getSignatureStatuses).toHaveBeenCalled();\n        });\n\n        it('does not throw when transaction exists with an error at an earlier commitment', async () => {\n            expect.assertions(2);\n\n            // Setup: nonce invalidation throws INVALID_NONCE\n            mockGetNonceInvalidationPromise.mockRejectedValue(\n                new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                    actualNonceValue: 'xyz',\n                    expectedNonceValue: 'abc',\n                }),\n            );\n\n            // Setup: getSignatureStatuses shows transaction exists and has an error, but only 'confirmed' (not 'finalized')\n            getSignatureStatusesMock.mockResolvedValue({\n                value: [\n                    {\n                        confirmationStatus: 'processed',\n                        err: { InstructionError: [0, 'InvalidAccountData'] },\n                    },\n                ],\n            });\n\n            // Setup: signature confirmation resolves (without an error) AFTER nonce invalidation rejects\n            // Using a delayed promise to ensure proper ordering\n            mockGetRecentSignatureConfirmationPromise.mockImplementation(\n                () => new Promise(resolve => setTimeout(resolve, DELAYED_SIGNATURE_INTERVAL)),\n            );\n\n            const sendAndConfirm = sendAndConfirmDurableNonceTransactionFactory({\n                rpc,\n                rpcSubscriptions,\n            });\n\n            const resultPromise = sendAndConfirm(MOCK_DURABLE_NONCE_TRANSACTION, {\n                commitment: 'finalized',\n            });\n\n            // First, let the nonce invalidation reject and our wrapper check getSignatureStatuses\n            await jest.advanceTimersByTimeAsync(0);\n\n            // Verify getSignatureStatuses was called to check tx status\n            expect(rpc.getSignatureStatuses).toHaveBeenCalled();\n\n            // Now advance time to let signature confirmation resolve\n            await jest.advanceTimersByTimeAsync(DELAYED_SIGNATURE_INTERVAL);\n\n            // Should resolve when signature confirmation completes\n            await expect(resultPromise).resolves.toBeUndefined();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__tests__/send-transaction-internal-test.ts",
    "content": "import { Signature } from '@solana/keys';\nimport type { Rpc, SendTransactionApi } from '@solana/rpc';\nimport type { Commitment } from '@solana/rpc-types';\nimport {\n    Base64EncodedWireTransaction,\n    getBase64EncodedWireTransaction,\n    SendableTransaction,\n    Transaction,\n    TransactionWithBlockhashLifetime,\n    TransactionWithDurableNonceLifetime,\n} from '@solana/transactions';\n\nimport {\n    sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT,\n    sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT,\n} from '../send-transaction-internal';\n\njest.mock('@solana/transactions');\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('sendAndConfirmTransaction', () => {\n    const MOCK_TRANSACTION = {} as SendableTransaction & Transaction & TransactionWithBlockhashLifetime;\n    let confirmRecentTransaction: jest.Mock;\n    let createPendingRequest: jest.Mock;\n    let rpc: Rpc<SendTransactionApi>;\n    let sendTransaction: jest.Mock;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        confirmRecentTransaction = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        sendTransaction = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        createPendingRequest = jest.fn().mockReturnValue({ send: sendTransaction });\n        rpc = {\n            sendTransaction: createPendingRequest,\n        };\n        jest.mocked(getBase64EncodedWireTransaction).mockReturnValue(\n            'MOCK_WIRE_TRANSACTION' as Base64EncodedWireTransaction,\n        );\n    });\n    it('encodes the transaction into wire format before sending', () => {\n        sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            confirmRecentTransaction,\n            rpc,\n            transaction: MOCK_TRANSACTION,\n        }).catch(() => {});\n        expect(getBase64EncodedWireTransaction).toHaveBeenCalledWith(MOCK_TRANSACTION);\n        expect(createPendingRequest).toHaveBeenCalledWith('MOCK_WIRE_TRANSACTION', expect.anything());\n    });\n    it('calls `sendTransaction` with the expected inputs', () => {\n        const sendTransactionConfig = {\n            maxRetries: 42n,\n            minContextSlot: 123n,\n            preflightCommitment: 'confirmed' as Commitment,\n            skipPreflight: false,\n        } as Parameters<SendTransactionApi['sendTransaction']>[1];\n        sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n            ...sendTransactionConfig,\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized' as Commitment,\n            confirmRecentTransaction,\n            rpc,\n            transaction: MOCK_TRANSACTION,\n        }).catch(() => {});\n        expect(getBase64EncodedWireTransaction).toHaveBeenCalledWith(MOCK_TRANSACTION);\n        expect(createPendingRequest).toHaveBeenCalledWith('MOCK_WIRE_TRANSACTION', {\n            ...sendTransactionConfig,\n            encoding: 'base64',\n        });\n    });\n    it('calls `confirmRecentTransaction` with the expected inputs', async () => {\n        expect.assertions(1);\n        const sendTransactionConfig = {\n            maxRetries: 42n,\n            minContextSlot: 123n,\n            preflightCommitment: 'confirmed' as Commitment,\n            skipPreflight: false,\n        } as Parameters<SendTransactionApi['sendTransaction']>[1];\n        sendTransaction.mockResolvedValue('abc' as Signature);\n        const abortSignal = new AbortController().signal;\n        sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n            ...sendTransactionConfig,\n            abortSignal,\n            commitment: 'finalized' as Commitment,\n            confirmRecentTransaction,\n            rpc,\n            transaction: MOCK_TRANSACTION,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(confirmRecentTransaction).toHaveBeenCalledWith({\n            abortSignal,\n            commitment: 'finalized',\n            transaction: MOCK_TRANSACTION,\n        });\n    });\n    it.each`\n        commitment     | expectedPreflightCommitment\n        ${'processed'} | ${'processed'}\n        ${'confirmed'} | ${'confirmed'}\n    `(\n        'when missing a `preflightCommitment` and the commitment is $commitment, applies a downgraded `preflightCommitment`',\n        ({ commitment, expectedPreflightCommitment }) => {\n            sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n                abortSignal: new AbortController().signal,\n                commitment,\n                confirmRecentTransaction,\n                rpc,\n                transaction: MOCK_TRANSACTION,\n            }).catch(() => {});\n            expect(createPendingRequest).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    preflightCommitment: expectedPreflightCommitment,\n                }),\n            );\n        },\n    );\n    it.each`\n        commitment     | preflightCommitment | expectedPreflightCommitment\n        ${'processed'} | ${'processed'}      | ${'processed'}\n        ${'processed'} | ${'confirmed'}      | ${'confirmed'}\n        ${'processed'} | ${'finalized'}      | ${'finalized'}\n        ${'confirmed'} | ${'processed'}      | ${'processed'}\n        ${'confirmed'} | ${'confirmed'}      | ${'confirmed'}\n        ${'confirmed'} | ${'finalized'}      | ${'finalized'}\n        ${'finalized'} | ${'processed'}      | ${'processed'}\n        ${'finalized'} | ${'confirmed'}      | ${'confirmed'}\n        ${'finalized'} | ${'finalized'}      | ${'finalized'}\n    `(\n        'honours the explicit `preflightCommitment` no matter that the commitment is $commitment',\n        ({ commitment, preflightCommitment, expectedPreflightCommitment }) => {\n            sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n                abortSignal: new AbortController().signal,\n                commitment,\n                confirmRecentTransaction,\n                preflightCommitment,\n                rpc,\n                transaction: MOCK_TRANSACTION,\n            }).catch(() => {});\n            expect(createPendingRequest).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    preflightCommitment: expectedPreflightCommitment,\n                }),\n            );\n        },\n    );\n    it('when missing a `preflightCommitment` and the commitment is the same as the server default for `preflightCommitment`, does not apply a `preflightCommitment`', () => {\n        expect.assertions(1);\n        sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            confirmRecentTransaction,\n            rpc,\n            transaction: MOCK_TRANSACTION,\n        }).catch(() => {});\n        expect(createPendingRequest.mock.lastCall![1]).not.toHaveProperty('preflightCommitment');\n    });\n    it('returns the signature of the transaction', async () => {\n        expect.assertions(1);\n        sendTransaction.mockResolvedValue('abc');\n        confirmRecentTransaction.mockResolvedValue(undefined);\n        await expect(\n            sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n                abortSignal: new AbortController().signal,\n                commitment: 'finalized',\n                confirmRecentTransaction,\n                rpc,\n                transaction: MOCK_TRANSACTION,\n            }),\n        ).resolves.toBe('abc');\n    });\n});\n\ndescribe('sendAndConfirmDurableNonceTransaction', () => {\n    const MOCK_DURABLE_NONCE_TRANSACTION = {} as unknown as SendableTransaction &\n        Transaction &\n        TransactionWithDurableNonceLifetime;\n    let confirmDurableNonceTransaction: jest.Mock;\n    let createPendingRequest: jest.Mock;\n    let rpc: Rpc<SendTransactionApi>;\n    let sendTransaction: jest.Mock;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        confirmDurableNonceTransaction = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        sendTransaction = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        createPendingRequest = jest.fn().mockReturnValue({ send: sendTransaction });\n        rpc = {\n            sendTransaction: createPendingRequest,\n        };\n        jest.mocked(getBase64EncodedWireTransaction).mockReturnValue(\n            'MOCK_WIRE_TRANSACTION' as Base64EncodedWireTransaction,\n        );\n    });\n    it('encodes the transaction into wire format before sending', () => {\n        sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            confirmDurableNonceTransaction,\n            rpc,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        }).catch(() => {});\n        expect(getBase64EncodedWireTransaction).toHaveBeenCalledWith(MOCK_DURABLE_NONCE_TRANSACTION);\n        expect(createPendingRequest).toHaveBeenCalledWith('MOCK_WIRE_TRANSACTION', expect.anything());\n    });\n    it('calls `sendTransaction` with the expected inputs', () => {\n        const sendTransactionConfig = {\n            maxRetries: 42n,\n            minContextSlot: 123n,\n            preflightCommitment: 'confirmed' as Commitment,\n            skipPreflight: false,\n        } as Parameters<SendTransactionApi['sendTransaction']>[1];\n        sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n            ...sendTransactionConfig,\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized' as Commitment,\n            confirmDurableNonceTransaction,\n            rpc,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        }).catch(() => {});\n        expect(getBase64EncodedWireTransaction).toHaveBeenCalledWith(MOCK_DURABLE_NONCE_TRANSACTION);\n        expect(createPendingRequest).toHaveBeenCalledWith('MOCK_WIRE_TRANSACTION', {\n            ...sendTransactionConfig,\n            encoding: 'base64',\n        });\n    });\n    it('calls `confirmDurableNonceTransaction` with the expected inputs', async () => {\n        expect.assertions(1);\n        const sendTransactionConfig = {\n            maxRetries: 42n,\n            minContextSlot: 123n,\n            preflightCommitment: 'confirmed' as Commitment,\n            skipPreflight: false,\n        } as Parameters<SendTransactionApi['sendTransaction']>[1];\n        sendTransaction.mockResolvedValue('abc' as Signature);\n        const abortSignal = new AbortController().signal;\n        sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n            ...sendTransactionConfig,\n            abortSignal,\n            commitment: 'finalized' as Commitment,\n            confirmDurableNonceTransaction,\n            rpc,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(confirmDurableNonceTransaction).toHaveBeenCalledWith({\n            abortSignal,\n            commitment: 'finalized',\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        });\n    });\n    it.each`\n        commitment     | expectedPreflightCommitment\n        ${'processed'} | ${'processed'}\n        ${'confirmed'} | ${'confirmed'}\n    `(\n        'when missing a `preflightCommitment` and the commitment is $commitment, applies a downgraded `preflightCommitment`',\n        ({ commitment, expectedPreflightCommitment }) => {\n            sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n                abortSignal: new AbortController().signal,\n                commitment,\n                confirmDurableNonceTransaction,\n                rpc,\n                transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n            }).catch(() => {});\n            expect(createPendingRequest).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    preflightCommitment: expectedPreflightCommitment,\n                }),\n            );\n        },\n    );\n    it.each`\n        commitment     | preflightCommitment | expectedPreflightCommitment\n        ${'processed'} | ${'processed'}      | ${'processed'}\n        ${'processed'} | ${'confirmed'}      | ${'confirmed'}\n        ${'processed'} | ${'finalized'}      | ${'finalized'}\n        ${'confirmed'} | ${'processed'}      | ${'processed'}\n        ${'confirmed'} | ${'confirmed'}      | ${'confirmed'}\n        ${'confirmed'} | ${'finalized'}      | ${'finalized'}\n        ${'finalized'} | ${'processed'}      | ${'processed'}\n        ${'finalized'} | ${'confirmed'}      | ${'confirmed'}\n        ${'finalized'} | ${'finalized'}      | ${'finalized'}\n    `(\n        'honours the explicit `preflightCommitment` no matter that the commitment is $commitment',\n        ({ commitment, preflightCommitment, expectedPreflightCommitment }) => {\n            sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n                abortSignal: new AbortController().signal,\n                commitment,\n                confirmDurableNonceTransaction,\n                preflightCommitment,\n                rpc,\n                transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n            }).catch(() => {});\n            expect(createPendingRequest).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    preflightCommitment: expectedPreflightCommitment,\n                }),\n            );\n        },\n    );\n    it('when missing a `preflightCommitment` and the commitment is the same as the server default for `preflightCommitment`, does not apply a `preflightCommitment`', () => {\n        expect.assertions(1);\n        sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            confirmDurableNonceTransaction,\n            rpc,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        }).catch(() => {});\n        expect(createPendingRequest.mock.lastCall![1]).not.toHaveProperty('preflightCommitment');\n    });\n    it('returns the signature of the transaction', async () => {\n        expect.assertions(1);\n        sendTransaction.mockResolvedValue('abc');\n        confirmDurableNonceTransaction.mockResolvedValue(undefined);\n        await expect(\n            sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n                abortSignal: new AbortController().signal,\n                commitment: 'finalized',\n                confirmDurableNonceTransaction,\n                rpc,\n                transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n            }),\n        ).resolves.toBe('abc');\n    });\n});\n"
  },
  {
    "path": "packages/kit/src/__typetests__/airdrop-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport { GetSignatureStatusesApi, RequestAirdropApi, Rpc, RpcDevnet, RpcMainnet, RpcTestnet } from '@solana/rpc';\nimport {\n    RpcSubscriptions,\n    RpcSubscriptionsDevnet,\n    RpcSubscriptionsMainnet,\n    RpcSubscriptionsTestnet,\n    SignatureNotificationsApi,\n} from '@solana/rpc-subscriptions';\n\nimport { airdropFactory } from '../airdrop';\n\nconst rpc = null as unknown as Rpc<GetSignatureStatusesApi & RequestAirdropApi>;\nconst rpcDevnet = null as unknown as RpcDevnet<GetSignatureStatusesApi & RequestAirdropApi>;\nconst rpcTestnet = null as unknown as RpcTestnet<GetSignatureStatusesApi & RequestAirdropApi>;\nconst rpcMainnet = null as unknown as RpcMainnet<GetSignatureStatusesApi /* note lack of `RequestAirdropApi` here */>;\n// No sense discriminating against RPCs who decide to offer mainnet airdrops!\nconst rpcMainnetWithAirdrop = null as unknown as RpcMainnet<GetSignatureStatusesApi & RequestAirdropApi>;\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<SignatureNotificationsApi>;\nconst rpcSubscriptionsDevnet = null as unknown as RpcSubscriptionsDevnet<SignatureNotificationsApi>;\nconst rpcSubscriptionsMainnet = null as unknown as RpcSubscriptionsMainnet<SignatureNotificationsApi>;\nconst rpcSubscriptionsTestnet = null as unknown as RpcSubscriptionsTestnet<SignatureNotificationsApi>;\n\n// [DESCRIBE] airdropFactory\n{\n    {\n        // It typechecks when the RPC clusters match and have the `RequestAirdropApi`\n        airdropFactory({ rpc, rpcSubscriptions });\n        airdropFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        airdropFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        airdropFactory({ rpc: rpcMainnetWithAirdrop, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It typechecks when either RPC is generic\n        airdropFactory({ rpc, rpcSubscriptions });\n        airdropFactory({ rpc: rpcDevnet, rpcSubscriptions });\n        airdropFactory({ rpc: rpcTestnet, rpcSubscriptions });\n        airdropFactory({ rpc, rpcSubscriptions: rpcSubscriptionsDevnet });\n        airdropFactory({ rpc, rpcSubscriptions: rpcSubscriptionsTestnet });\n    }\n    {\n        // It fails to typecheck when used with an RPC that doesn't have `RequestAirdropApi`\n        // @ts-expect-error\n        airdropFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It fails to typecheck when explicit RPC clusters mismatch\n        // @ts-expect-error\n        airdropFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        // @ts-expect-error\n        airdropFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        airdropFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        airdropFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        airdropFactory({ rpc: rpcMainnetWithAirdrop, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        airdropFactory({ rpc: rpcMainnetWithAirdrop, rpcSubscriptions: rpcSubscriptionsTestnet });\n    }\n}\n"
  },
  {
    "path": "packages/kit/src/__typetests__/decompile-transaction-message-fetching-lookup-tables-typetest.ts",
    "content": "import { Rpc } from '@solana/rpc';\nimport { GetMultipleAccountsApi } from '@solana/rpc-api';\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    isTransactionMessageWithBlockhashLifetime,\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithLifetime,\n} from '@solana/transaction-messages';\n\nimport { decompileTransactionMessageFetchingLookupTables } from '../decompile-transaction-message-fetching-lookup-tables';\n\n// [DESCRIBE] decompileTransactionMessageFetchingLookupTables\n{\n    const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n        CompiledTransactionMessageWithLifetime;\n\n    const rpc = null as unknown as Rpc<GetMultipleAccountsApi>;\n\n    // Returns a TransactionMessage\n    void (async () => {\n        const transactionMessage = await decompileTransactionMessageFetchingLookupTables(\n            compiledTransactionMessage,\n            rpc,\n        );\n        transactionMessage satisfies TransactionMessage;\n    })();\n\n    // Has a fee payer\n    void (async () => {\n        const transactionMessage = await decompileTransactionMessageFetchingLookupTables(\n            compiledTransactionMessage,\n            rpc,\n        );\n        transactionMessage satisfies TransactionMessageWithFeePayer;\n    })();\n\n    // Has a lifetime\n    void (async () => {\n        const transactionMessage = await decompileTransactionMessageFetchingLookupTables(\n            compiledTransactionMessage,\n            rpc,\n        );\n        transactionMessage satisfies TransactionMessageWithLifetime;\n    })();\n\n    // Lifetime can be narrowed\n    void (async () => {\n        // Given a function that only accepts a transaction message with a blockhash lifetime\n        function acceptsTransactionMessageWithBlockhashLifetime(_msg: TransactionMessageWithBlockhashLifetime) {}\n\n        const transactionMessage = await decompileTransactionMessageFetchingLookupTables(\n            compiledTransactionMessage,\n            rpc,\n        );\n        // @ts-expect-error Lifetime could be different\n        acceptsTransactionMessageWithBlockhashLifetime(transactionMessage);\n        if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n            acceptsTransactionMessageWithBlockhashLifetime(transactionMessage);\n        }\n    })();\n\n    // The version can be narrowed\n    void (async () => {\n        // Given a function that only accepts a non-legacy transaction message\n        type TransactionMessageNotLegacy = Exclude<TransactionMessage, { version: 'legacy' }>;\n        function acceptsNonLegacyTransactionMessage(_msg: TransactionMessageNotLegacy) {}\n\n        const transactionMessage = await decompileTransactionMessageFetchingLookupTables(\n            compiledTransactionMessage,\n            rpc,\n        );\n        // @ts-expect-error Version could be legacy\n        acceptsNonLegacyTransactionMessage(transactionMessage);\n        if (transactionMessage.version === 0) {\n            acceptsNonLegacyTransactionMessage(transactionMessage);\n        }\n    })();\n}\n"
  },
  {
    "path": "packages/kit/src/__typetests__/scenarios/transaction-message-decompile-modify-typetest.ts",
    "content": "// [DESCRIBE] A scenario testing the types of transaction-message functionality\n// Based on discussion/examples from https://github.com/anza-xyz/kit/pull/1103\n\nimport { Address } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport { Instruction } from '@solana/instructions';\nimport { GetMultipleAccountsApi, Rpc } from '@solana/rpc';\nimport { setTransactionMessageFeePayerSigner, TransactionSigner } from '@solana/signers';\nimport {\n    appendTransactionMessageInstruction,\n    appendTransactionMessageInstructions,\n    BlockhashLifetimeConstraint,\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    prependTransactionMessageInstruction,\n    prependTransactionMessageInstructions,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n    setTransactionMessageLifetimeUsingDurableNonce,\n    TransactionMessage,\n} from '@solana/transaction-messages';\n\nimport { decompileTransactionMessageFetchingLookupTables } from '../../decompile-transaction-message-fetching-lookup-tables';\n\nconst compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n    CompiledTransactionMessageWithLifetime;\nconst rpc = null as unknown as Rpc<GetMultipleAccountsApi>;\n\ntype TransactionMessageNotLegacy = Exclude<TransactionMessage, { version: 'legacy' }>;\n\nvoid (async () => {\n    const transactionMessage = await decompileTransactionMessageFetchingLookupTables(compiledTransactionMessage, rpc);\n\n    // @ts-expect-error Transaction has an unknown version\n    transactionMessage satisfies TransactionMessageNotLegacy;\n    if (transactionMessage.version === 0) {\n        // It typechecks when the transaction message is known to be v0\n        transactionMessage satisfies TransactionMessageNotLegacy;\n    }\n\n    // We update the transaction message using update functions to ensure the types flow correctly\n    const blockhash = null as unknown as BlockhashLifetimeConstraint;\n    const durableNonce = null as unknown as Parameters<typeof setTransactionMessageLifetimeUsingDurableNonce>[0];\n    const feePayer = null as unknown as Address;\n    const instruction = null as unknown as Instruction;\n    const signer = null as unknown as TransactionSigner;\n\n    const updatedMessage = pipe(\n        transactionMessage,\n        m => setTransactionMessageLifetimeUsingBlockhash(blockhash, m),\n        m => setTransactionMessageLifetimeUsingDurableNonce(durableNonce, m),\n        m => setTransactionMessageFeePayer(feePayer, m),\n        m => appendTransactionMessageInstruction(instruction, m),\n        m => appendTransactionMessageInstructions([instruction], m),\n        m => prependTransactionMessageInstruction(instruction, m),\n        m => prependTransactionMessageInstructions([instruction], m),\n        m => setTransactionMessageFeePayerSigner(signer, m),\n    );\n\n    // @ts-expect-error Transaction has an unknown version\n    updatedMessage satisfies TransactionMessageNotLegacy;\n    if (updatedMessage.version === 0) {\n        // It typechecks when the transaction message is known to be v0\n        updatedMessage satisfies TransactionMessageNotLegacy;\n    }\n})();\n"
  },
  {
    "path": "packages/kit/src/__typetests__/scenarios/transaction-signers-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport { Instruction } from '@solana/instructions';\nimport {\n    InstructionWithSigners,\n    setTransactionMessageFeePayerSigner,\n    TransactionMessageWithSigners,\n    TransactionSigner,\n} from '@solana/signers';\nimport {\n    appendTransactionMessageInstructions,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionVersion,\n} from '@solana/transaction-messages';\n\n// Temporary, until we support v1 transactions in `createTransactionMessage`\n// When this is removed, use `TransactionVersion`\ntype TransactionVersionWithoutV1 = Exclude<TransactionVersion, 1>;\n\n// [DESCRIBE] TransactionMessageWithSigners type\n{\n    // It is satisfied by a transaction message from `createTransactionMessage`\n    {\n        const result = createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 });\n        result satisfies TransactionMessage & TransactionMessageWithSigners;\n    }\n\n    // It is satisfied after adding an address fee payer\n    {\n        const result = pipe(createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }), m =>\n            setTransactionMessageFeePayer(null as unknown as Address, m),\n        );\n        result satisfies TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners;\n    }\n\n    // It is satisfied after adding a signer fee payer\n    {\n        const result = pipe(createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }), m =>\n            setTransactionMessageFeePayerSigner(null as unknown as TransactionSigner, m),\n        );\n        result satisfies TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners;\n    }\n\n    // It is satisfied after appending instructions\n    {\n        const result = pipe(createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }), m =>\n            appendTransactionMessageInstructions(null as unknown as Instruction[], m),\n        );\n        result satisfies TransactionMessage & TransactionMessageWithSigners;\n    }\n\n    // It is satisfied after appending instructions with signers\n    {\n        const result = pipe(createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }), m =>\n            appendTransactionMessageInstructions(null as unknown as (Instruction & InstructionWithSigners)[], m),\n        );\n        result satisfies TransactionMessage & TransactionMessageWithSigners;\n    }\n\n    // It is satisfied after adding a fee payer and instructions\n    {\n        const result = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageFeePayer(null as unknown as Address, m),\n            m => appendTransactionMessageInstructions(null as unknown as Instruction[], m),\n        );\n        result satisfies TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners;\n    }\n\n    // It is satisfied after adding a signer fee payer and instructions\n    {\n        const result = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageFeePayerSigner(null as unknown as TransactionSigner, m),\n            m => appendTransactionMessageInstructions(null as unknown as (Instruction & InstructionWithSigners)[], m),\n        );\n        result satisfies TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners;\n    }\n\n    // It is satisfied after adding a fee payer and instructions with signers\n    {\n        const result = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageFeePayer(null as unknown as Address, m),\n            m => appendTransactionMessageInstructions(null as unknown as (Instruction & InstructionWithSigners)[], m),\n        );\n        result satisfies TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners;\n    }\n\n    // It is satisfied after adding a signer fee payer and instructions with signers\n    {\n        const result = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageFeePayerSigner(null as unknown as TransactionSigner, m),\n            m => appendTransactionMessageInstructions(null as unknown as (Instruction & InstructionWithSigners)[], m),\n        );\n        result satisfies TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners;\n    }\n}\n"
  },
  {
    "path": "packages/kit/src/__typetests__/send-and-confirm-durable-nonce-transaction-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport {\n    GetAccountInfoApi,\n    GetSignatureStatusesApi,\n    Rpc,\n    RpcDevnet,\n    RpcMainnet,\n    RpcTestnet,\n    SendTransactionApi,\n} from '@solana/rpc';\nimport {\n    AccountNotificationsApi,\n    RpcSubscriptions,\n    RpcSubscriptionsDevnet,\n    RpcSubscriptionsMainnet,\n    RpcSubscriptionsTestnet,\n    SignatureNotificationsApi,\n} from '@solana/rpc-subscriptions';\n\nimport { sendAndConfirmDurableNonceTransactionFactory } from '../send-and-confirm-durable-nonce-transaction';\n\nconst rpc = null as unknown as Rpc<GetAccountInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\nconst rpcDevnet = null as unknown as RpcDevnet<GetAccountInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\nconst rpcTestnet = null as unknown as RpcTestnet<GetAccountInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\nconst rpcMainnet = null as unknown as RpcMainnet<GetAccountInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<AccountNotificationsApi & SignatureNotificationsApi>;\nconst rpcSubscriptionsDevnet = null as unknown as RpcSubscriptionsDevnet<\n    AccountNotificationsApi & SignatureNotificationsApi\n>;\nconst rpcSubscriptionsMainnet = null as unknown as RpcSubscriptionsMainnet<\n    AccountNotificationsApi & SignatureNotificationsApi\n>;\nconst rpcSubscriptionsTestnet = null as unknown as RpcSubscriptionsTestnet<\n    AccountNotificationsApi & SignatureNotificationsApi\n>;\n\n// [DESCRIBE] sendAndConfirmDurableNonceTransactionFactory\n{\n    {\n        // It typechecks when the RPC clusters match.\n        sendAndConfirmDurableNonceTransactionFactory({ rpc, rpcSubscriptions });\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It typechecks when either RPC is generic.\n        sendAndConfirmDurableNonceTransactionFactory({ rpc, rpcSubscriptions });\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcDevnet, rpcSubscriptions });\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcTestnet, rpcSubscriptions });\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcMainnet, rpcSubscriptions });\n    }\n    {\n        // It fails to typecheck when explicit RPC clusters mismatch.\n        // @ts-expect-error\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        // @ts-expect-error\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        sendAndConfirmDurableNonceTransactionFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n    }\n}\n"
  },
  {
    "path": "packages/kit/src/__typetests__/send-and-confirm-transaction-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport {\n    GetEpochInfoApi,\n    GetSignatureStatusesApi,\n    Rpc,\n    RpcDevnet,\n    RpcMainnet,\n    RpcTestnet,\n    SendTransactionApi,\n} from '@solana/rpc';\nimport {\n    RpcSubscriptions,\n    RpcSubscriptionsDevnet,\n    RpcSubscriptionsMainnet,\n    RpcSubscriptionsTestnet,\n    SignatureNotificationsApi,\n    SlotNotificationsApi,\n} from '@solana/rpc-subscriptions';\n\nimport { sendAndConfirmTransactionFactory } from '../send-and-confirm-transaction';\n\nconst rpc = null as unknown as Rpc<GetEpochInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\nconst rpcDevnet = null as unknown as RpcDevnet<GetEpochInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\nconst rpcTestnet = null as unknown as RpcTestnet<GetEpochInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\nconst rpcMainnet = null as unknown as RpcMainnet<GetEpochInfoApi & GetSignatureStatusesApi & SendTransactionApi>;\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<SignatureNotificationsApi & SlotNotificationsApi>;\nconst rpcSubscriptionsDevnet = null as unknown as RpcSubscriptionsDevnet<\n    SignatureNotificationsApi & SlotNotificationsApi\n>;\nconst rpcSubscriptionsMainnet = null as unknown as RpcSubscriptionsMainnet<\n    SignatureNotificationsApi & SlotNotificationsApi\n>;\nconst rpcSubscriptionsTestnet = null as unknown as RpcSubscriptionsTestnet<\n    SignatureNotificationsApi & SlotNotificationsApi\n>;\n\n// [DESCRIBE] sendAndConfirmTransactionFactory\n{\n    {\n        // It typechecks when the RPC clusters match.\n        sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n        sendAndConfirmTransactionFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        sendAndConfirmTransactionFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        sendAndConfirmTransactionFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It typechecks when either RPC is generic.\n        sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n        sendAndConfirmTransactionFactory({ rpc: rpcDevnet, rpcSubscriptions });\n        sendAndConfirmTransactionFactory({ rpc: rpcTestnet, rpcSubscriptions });\n        sendAndConfirmTransactionFactory({ rpc: rpcMainnet, rpcSubscriptions });\n    }\n    {\n        // It fails to typecheck when explicit RPC clusters mismatch.\n        // @ts-expect-error\n        sendAndConfirmTransactionFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        // @ts-expect-error\n        sendAndConfirmTransactionFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        sendAndConfirmTransactionFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        sendAndConfirmTransactionFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        sendAndConfirmTransactionFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        sendAndConfirmTransactionFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n    }\n}\n"
  },
  {
    "path": "packages/kit/src/airdrop-internal.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { RequestAirdropApi, Rpc } from '@solana/rpc';\nimport type { Commitment, Lamports } from '@solana/rpc-types';\nimport { waitForRecentTransactionConfirmationUntilTimeout } from '@solana/transaction-confirmation';\n\ntype RequestAndConfirmAirdropConfig = Readonly<{\n    abortSignal?: AbortSignal;\n    commitment: Commitment;\n    confirmSignatureOnlyTransaction: (\n        config: Omit<\n            Parameters<typeof waitForRecentTransactionConfirmationUntilTimeout>[0],\n            'getRecentSignatureConfirmationPromise' | 'getTimeoutPromise'\n        >,\n    ) => Promise<void>;\n    lamports: Lamports;\n    recipientAddress: Address;\n    rpc: Rpc<RequestAirdropApi>;\n}>;\n\nexport async function requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({\n    abortSignal,\n    commitment,\n    confirmSignatureOnlyTransaction,\n    lamports,\n    recipientAddress,\n    rpc,\n}: RequestAndConfirmAirdropConfig): Promise<Signature> {\n    const airdropTransactionSignature = await rpc\n        .requestAirdrop(recipientAddress, lamports, { commitment })\n        .send({ abortSignal });\n    await confirmSignatureOnlyTransaction({\n        abortSignal,\n        commitment,\n        signature: airdropTransactionSignature,\n    });\n    return airdropTransactionSignature;\n}\n"
  },
  {
    "path": "packages/kit/src/airdrop.ts",
    "content": "import type { Signature } from '@solana/keys';\nimport type { GetSignatureStatusesApi, RequestAirdropApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport {\n    createRecentSignatureConfirmationPromiseFactory,\n    getTimeoutPromise,\n    waitForRecentTransactionConfirmationUntilTimeout,\n} from '@solana/transaction-confirmation';\n\nimport { requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT } from './airdrop-internal';\n\ntype AirdropFunction = (\n    config: Omit<\n        Parameters<typeof requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT>[0],\n        'confirmSignatureOnlyTransaction' | 'rpc'\n    >,\n) => Promise<Signature>;\n\ntype AirdropFactoryConfig<TCluster> = {\n    /** An object that supports the {@link GetSignatureStatusesApi} and the {@link RequestAirdropApi} of the Solana RPC API */\n    rpc: Rpc<GetSignatureStatusesApi & RequestAirdropApi> & { '~cluster'?: TCluster };\n    /** An object that supports the {@link SignatureNotificationsApi} of the Solana RPC Subscriptions API */\n    rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\n/**\n * Returns a function that you can call to airdrop a certain amount of {@link Lamports} to a Solana\n * address.\n *\n * > [!NOTE] This only works on test clusters.\n *\n * @param config\n *\n * @example\n * ```ts\n * import { address, airdropFactory, createSolanaRpc, createSolanaRpcSubscriptions, devnet, lamports } from '@solana/kit';\n *\n * const rpc = createSolanaRpc(devnet('http://127.0.0.1:8899'));\n * const rpcSubscriptions = createSolanaRpcSubscriptions(devnet('ws://127.0.0.1:8900'));\n *\n * const airdrop = airdropFactory({ rpc, rpcSubscriptions });\n *\n * await airdrop({\n *     commitment: 'confirmed',\n *     recipientAddress: address('FnHyam9w4NZoWR6mKN1CuGBritdsEWZQa4Z4oawLZGxa'),\n *     lamports: lamports(10_000_000n),\n * });\n * ```\n */\nexport function airdropFactory({ rpc, rpcSubscriptions }: AirdropFactoryConfig<'devnet'>): AirdropFunction;\nexport function airdropFactory({ rpc, rpcSubscriptions }: AirdropFactoryConfig<'mainnet'>): AirdropFunction;\nexport function airdropFactory({ rpc, rpcSubscriptions }: AirdropFactoryConfig<'testnet'>): AirdropFunction;\nexport function airdropFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n    rpc,\n    rpcSubscriptions,\n}: AirdropFactoryConfig<TCluster>): AirdropFunction {\n    const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({\n        rpc,\n        rpcSubscriptions,\n    } as Parameters<typeof createRecentSignatureConfirmationPromiseFactory>[0]);\n    async function confirmSignatureOnlyTransaction(\n        config: Omit<\n            Parameters<typeof waitForRecentTransactionConfirmationUntilTimeout>[0],\n            'getRecentSignatureConfirmationPromise' | 'getTimeoutPromise'\n        >,\n    ) {\n        await waitForRecentTransactionConfirmationUntilTimeout({\n            ...config,\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n        });\n    }\n    return async function airdrop(config) {\n        return await requestAndConfirmAirdrop_INTERNAL_ONLY_DO_NOT_EXPORT({\n            ...config,\n            confirmSignatureOnlyTransaction,\n            rpc,\n        });\n    };\n}\n"
  },
  {
    "path": "packages/kit/src/compute-unit-limit-estimation.ts",
    "content": "import {\n    getSolanaErrorFromTransactionError,\n    isSolanaError,\n    type RpcSimulateTransactionResult,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT,\n    SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT,\n    SolanaError,\n} from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport type { Rpc, SimulateTransactionApi } from '@solana/rpc';\nimport type { Commitment, Slot } from '@solana/rpc-types';\nimport {\n    getTransactionMessageComputeUnitLimit,\n    isTransactionMessageWithDurableNonceLifetime,\n    setTransactionMessageComputeUnitLimit,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\nimport { compileTransaction, getBase64EncodedWireTransaction } from '@solana/transactions';\n\nconst PROVISORY_COMPUTE_UNIT_LIMIT = 0;\nconst MAX_COMPUTE_UNIT_LIMIT = 1_400_000;\n\ntype EstimateComputeUnitLimitFactoryConfig = Readonly<{\n    rpc: Rpc<SimulateTransactionApi>;\n}>;\n\ntype EstimateComputeUnitLimitConfig = Readonly<{\n    abortSignal?: AbortSignal;\n    commitment?: Commitment;\n    minContextSlot?: Slot;\n}>;\n\ntype EstimateComputeUnitLimitFunction = (\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer,\n    config?: EstimateComputeUnitLimitConfig,\n) => Promise<number>;\n\n/**\n * Returns a function that estimates the compute units consumed by a transaction message by\n * simulating it.\n *\n * The estimator sets the compute unit limit to the maximum (1,400,000) before simulating, so the\n * simulation does not fail due to compute unit exhaustion. For blockhash-lifetime transactions, the\n * RPC is asked to replace the blockhash during simulation, so any blockhash value will work. For\n * durable nonce transactions, the actual nonce value is used.\n *\n * @param factoryConfig - An object containing the RPC instance to use for simulation.\n * @return A function that accepts a transaction message and returns the estimated compute units.\n *\n * @example\n * ```ts\n * import { estimateComputeUnitLimitFactory } from '@solana/kit';\n *\n * const estimateComputeUnitLimit = estimateComputeUnitLimitFactory({ rpc });\n * const estimatedUnits = await estimateComputeUnitLimit(transactionMessage);\n * ```\n */\nexport function estimateComputeUnitLimitFactory({\n    rpc,\n}: EstimateComputeUnitLimitFactoryConfig): EstimateComputeUnitLimitFunction {\n    return async function estimateComputeUnitLimit(transactionMessage, config) {\n        const { abortSignal, ...simulateConfig } = config ?? {};\n        const replaceRecentBlockhash = !isTransactionMessageWithDurableNonceLifetime(transactionMessage);\n\n        const transaction = pipe(\n            transactionMessage,\n            m => setTransactionMessageComputeUnitLimit(MAX_COMPUTE_UNIT_LIMIT, m),\n            compileTransaction,\n        );\n        const wireTransactionBytes = getBase64EncodedWireTransaction(transaction);\n\n        try {\n            const response = await rpc\n                .simulateTransaction(wireTransactionBytes, {\n                    ...simulateConfig,\n                    encoding: 'base64',\n                    replaceRecentBlockhash,\n                    sigVerify: false,\n                })\n                .send({ abortSignal });\n            // The API response type varies based on config (eg. `replacementBlockhash` is only\n            // present when `replaceRecentBlockhash` is true), but `RpcSimulateTransactionResult`\n            // is a flat superset. Cast through `unknown` to bridge the structural gap.\n            const { err: transactionError, ...simulationResult } =\n                response.value as unknown as RpcSimulateTransactionResult;\n\n            if (simulationResult.unitsConsumed == null) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT);\n            }\n\n            if (transactionError) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT, {\n                    ...simulationResult,\n                    cause: getSolanaErrorFromTransactionError(transactionError),\n                });\n            }\n\n            // Downcast from bigint to number, capping at u32 max.\n            return simulationResult.unitsConsumed > 4_294_967_295n\n                ? 4_294_967_295\n                : Number(simulationResult.unitsConsumed);\n        } catch (e) {\n            if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_COMPUTE_LIMIT)) {\n                throw e;\n            }\n            throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT, {\n                cause: e,\n            });\n        }\n    };\n}\n\n/**\n * Returns a function that estimates the compute unit limit for a transaction message and sets it on\n * the message. If the message already has an explicit compute unit limit set (one that is not the\n * provisory value of 0, and not the maximum of 1,400,000), the message is returned unchanged.\n *\n * This is designed to work with {@link fillTransactionMessageProvisoryComputeUnitLimit}: first add a provisory limit\n * during transaction construction, then later estimate and replace it before sending.\n *\n * @param estimateComputeUnitLimit - The estimator function, typically created by\n *   {@link estimateComputeUnitLimitFactory}. You can also pass a custom wrapper that adds a buffer\n *   (e.g. multiply the estimate by 1.1).\n * @return A function that accepts a transaction message and returns it with the compute unit limit\n *   set to the estimated value.\n *\n * @example\n * ```ts\n * import { estimateAndSetComputeUnitLimitFactory, estimateComputeUnitLimitFactory } from '@solana/kit';\n *\n * const estimator = estimateComputeUnitLimitFactory({ rpc });\n * const estimateAndSet = estimateAndSetComputeUnitLimitFactory(estimator);\n * const updatedMessage = await estimateAndSet(transactionMessage);\n * ```\n */\nexport function estimateAndSetComputeUnitLimitFactory(\n    estimateComputeUnitLimit: EstimateComputeUnitLimitFunction,\n): <TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer>(\n    transactionMessage: TTransactionMessage,\n    config?: EstimateComputeUnitLimitConfig,\n) => Promise<TTransactionMessage> {\n    return async function estimateAndSetComputeUnitLimit(transactionMessage, config) {\n        const existingLimit = getTransactionMessageComputeUnitLimit(transactionMessage);\n\n        // If a non-provisory, non-max CU limit is already set, leave it as-is.\n        if (existingLimit && existingLimit !== MAX_COMPUTE_UNIT_LIMIT) {\n            return transactionMessage;\n        }\n\n        const estimatedUnits = await estimateComputeUnitLimit(transactionMessage, config);\n        return setTransactionMessageComputeUnitLimit(estimatedUnits, transactionMessage);\n    };\n}\n\n/**\n * Sets the compute unit limit to a provisory value of 0 if no compute unit limit is currently set\n * on the transaction message. If a limit is already set (any value, including 0), the message is\n * returned unchanged.\n *\n * This is useful during transaction construction to reserve space for a compute unit limit that\n * will later be replaced with an actual estimate via\n * {@link estimateAndSetComputeUnitLimitFactory}.\n *\n * @param transactionMessage - The transaction message to add a provisory limit to.\n * @return The transaction message with a provisory compute unit limit set, or unchanged if one was\n *   already present.\n *\n * @example\n * ```ts\n * import { fillTransactionMessageProvisoryComputeUnitLimit } from '@solana/kit';\n *\n * const messageWithProvisoryLimit = fillTransactionMessageProvisoryComputeUnitLimit(transactionMessage);\n * ```\n */\nexport function fillTransactionMessageProvisoryComputeUnitLimit<TTransactionMessage extends TransactionMessage>(\n    transactionMessage: TTransactionMessage,\n): TTransactionMessage {\n    if (getTransactionMessageComputeUnitLimit(transactionMessage) !== undefined) {\n        return transactionMessage;\n    }\n    return setTransactionMessageComputeUnitLimit(PROVISORY_COMPUTE_UNIT_LIMIT, transactionMessage);\n}\n"
  },
  {
    "path": "packages/kit/src/create-async-generator-with-initial-value-and-slot-tracking.ts",
    "content": "import type { PendingRpcRequest } from '@solana/rpc';\nimport type { PendingRpcSubscriptionsRequest } from '@solana/rpc-subscriptions';\nimport type { SolanaRpcResponse } from '@solana/rpc-types';\n\ntype CreateAsyncGeneratorWithInitialValueAndSlotTrackingConfig<TRpcValue, TSubscriptionValue, TItem> = Readonly<{\n    /**\n     * Triggering this abort signal will cancel the pending RPC request and subscription, and\n     * cause the async generator to return (complete without error).\n     */\n    abortSignal: AbortSignal;\n    /**\n     * A pending RPC request whose response will be yielded as the generator's first value\n     * (unless a subscription notification with a newer slot arrives first).\n     * The response must be a {@link SolanaRpcResponse} so that its slot can be compared with\n     * subscription notifications.\n     */\n    rpcRequest: PendingRpcRequest<SolanaRpcResponse<TRpcValue>>;\n    /**\n     * A pending RPC subscription request whose notifications will be yielded as they arrive.\n     * Each notification must be a {@link SolanaRpcResponse} so that its slot can be compared\n     * with the initial RPC response and other notifications.\n     */\n    rpcSubscriptionRequest: PendingRpcSubscriptionsRequest<SolanaRpcResponse<TSubscriptionValue>>;\n    /**\n     * Maps the value from a subscription notification to the item type yielded by the generator.\n     */\n    rpcSubscriptionValueMapper: (value: TSubscriptionValue) => TItem;\n    /**\n     * Maps the value from the RPC response to the item type yielded by the generator.\n     */\n    rpcValueMapper: (value: TRpcValue) => TItem;\n}>;\n\n/**\n * Creates an async generator that combines an initial RPC fetch with an ongoing subscription,\n * yielding values as they arrive from either source.\n *\n * The generator uses slot-based comparison to ensure that only the most recent values are yielded.\n * Any value at a slot older than a previously yielded value is silently dropped.\n * This prevents stale data from appearing when the RPC response and subscription notifications\n * arrive out of order.\n *\n * Things to note:\n *\n * - The generator yields {@link SolanaRpcResponse} values from both the RPC response and\n *   subscription notifications, each containing the slot context and the mapped value.\n * - Out-of-order values (by slot) are silently dropped — they are never yielded.\n * - On error from either source, the generator throws the error.\n * - Triggering the caller's abort signal causes the generator to return (complete without error).\n * - The generator completes when the subscription ends, an error occurs, or the abort signal fires.\n *\n * @param config\n *\n * @example\n * ```ts\n * import {\n *     address,\n *     createAsyncGeneratorWithInitialValueAndSlotTracking,\n *     createSolanaRpc,\n *     createSolanaRpcSubscriptions,\n * } from '@solana/kit';\n *\n * const rpc = createSolanaRpc('http://127.0.0.1:8899');\n * const rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');\n * const myAddress = address('FnHyam9w4NZoWR6mKN1CuGBritdsEWZQa4Z4oawLZGxa');\n *\n * const abortController = new AbortController();\n * for await (const balance of createAsyncGeneratorWithInitialValueAndSlotTracking({\n *     abortSignal: abortController.signal,\n *     rpcRequest: rpc.getBalance(myAddress, { commitment: 'confirmed' }),\n *     rpcValueMapper: lamports => lamports,\n *     rpcSubscriptionRequest: rpcSubscriptions.accountNotifications(myAddress),\n *     rpcSubscriptionValueMapper: ({ lamports }) => lamports,\n * })) {\n *     console.log(`Balance at slot ${balance.context.slot}:`, balance.value);\n * }\n * ```\n */\nexport async function* createAsyncGeneratorWithInitialValueAndSlotTracking<TRpcValue, TSubscriptionValue, TItem>({\n    abortSignal,\n    rpcRequest,\n    rpcValueMapper,\n    rpcSubscriptionRequest,\n    rpcSubscriptionValueMapper,\n}: CreateAsyncGeneratorWithInitialValueAndSlotTrackingConfig<TRpcValue, TSubscriptionValue, TItem>): AsyncGenerator<\n    SolanaRpcResponse<TItem>\n> {\n    if (abortSignal.aborted) return;\n\n    let lastUpdateSlot = -1n;\n\n    // Shared queue for merging values from the RPC response and subscription notifications.\n    const queue: SolanaRpcResponse<TItem>[] = [];\n    let waitingResolve: ((value: IteratorResult<SolanaRpcResponse<TItem>>) => void) | null = null;\n    let waitingReject: ((reason: unknown) => void) | null = null;\n    let rpcDone = false;\n    let subscriptionDone = false;\n    let done = false;\n    let pendingError: unknown;\n\n    function markSourcesDone() {\n        done = true;\n        if (waitingResolve) {\n            const resolve = waitingResolve;\n            waitingResolve = null;\n            waitingReject = null;\n            resolve({ done: true, value: undefined });\n        }\n    }\n\n    const abortController = new AbortController();\n    const signal = abortController.signal;\n\n    function onAbort() {\n        done = true;\n        abortController.abort(abortSignal.reason);\n        if (waitingResolve) {\n            const resolve = waitingResolve;\n            waitingResolve = null;\n            waitingReject = null;\n            resolve({ done: true, value: undefined });\n        }\n    }\n    abortSignal.addEventListener('abort', onAbort);\n\n    function enqueue(item: SolanaRpcResponse<TItem>) {\n        if (done || signal.aborted) return;\n        if (waitingResolve) {\n            // generator is waiting for a value, so resolve immediately\n            const resolve = waitingResolve;\n            waitingResolve = null;\n            waitingReject = null;\n            resolve({ done: false, value: item });\n        } else {\n            // No pending generator pull, so enqueue the item for future delivery\n            queue.push(item);\n        }\n    }\n\n    function handleError(err: unknown) {\n        if (signal.aborted) return;\n        done = true;\n        pendingError = err;\n        abortController.abort(err);\n        if (waitingReject) {\n            // generator is waiting for a value, so reject immediately\n            const reject = waitingReject;\n            waitingResolve = null;\n            waitingReject = null;\n            reject(err);\n        }\n    }\n\n    // Start both sources concurrently.\n    rpcRequest\n        .send({ abortSignal: signal })\n        .then(({ context: { slot }, value }) => {\n            if (signal.aborted) return;\n            if (slot < lastUpdateSlot) return;\n            lastUpdateSlot = slot;\n            enqueue({ context: { slot }, value: rpcValueMapper(value) });\n        })\n        .then(() => {\n            rpcDone = true;\n            if (subscriptionDone) markSourcesDone();\n        })\n        .catch(handleError);\n\n    rpcSubscriptionRequest\n        .subscribe({ abortSignal: signal })\n        .then(async notifications => {\n            for await (const {\n                context: { slot },\n                value,\n            } of notifications) {\n                if (signal.aborted) return;\n                if (slot < lastUpdateSlot) continue;\n                lastUpdateSlot = slot;\n                enqueue({ context: { slot }, value: rpcSubscriptionValueMapper(value) });\n            }\n            // Subscription completed normally.\n            subscriptionDone = true;\n            if (rpcDone) markSourcesDone();\n        })\n        .catch(handleError);\n\n    try {\n        while (true) {\n            if (pendingError) throw pendingError;\n            if (queue.length > 0) {\n                yield queue.shift()!;\n            } else if (done) {\n                return;\n            } else {\n                // if no value queued or error, wait for the next value or error\n                const result: IteratorResult<SolanaRpcResponse<TItem>> = await new Promise((resolve, reject) => {\n                    waitingResolve = resolve;\n                    waitingReject = reject;\n                });\n                if (result.done) return;\n                yield result.value;\n            }\n        }\n    } finally {\n        abortSignal.removeEventListener('abort', onAbort);\n        if (!signal.aborted) {\n            abortController.abort();\n        }\n    }\n}\n"
  },
  {
    "path": "packages/kit/src/create-reactive-store-with-initial-value-and-slot-tracking.ts",
    "content": "import type { PendingRpcRequest } from '@solana/rpc';\nimport type { PendingRpcSubscriptionsRequest } from '@solana/rpc-subscriptions';\nimport type { SolanaRpcResponse } from '@solana/rpc-types';\nimport type { ReactiveState, ReactiveStreamStore } from '@solana/subscribable';\n\ntype CreateReactiveStoreWithInitialValueAndSlotTrackingConfig<TRpcValue, TSubscriptionValue, TItem> = Readonly<{\n    /**\n     * Triggering this abort signal will cancel the pending RPC request and subscription, and\n     * disconnect the store from further updates.\n     */\n    abortSignal: AbortSignal;\n    /**\n     * A pending RPC request whose response will be used to set the store's initial state.\n     * The response must be a {@link SolanaRpcResponse} so that its slot can be compared with\n     * subscription notifications.\n     */\n    rpcRequest: PendingRpcRequest<SolanaRpcResponse<TRpcValue>>;\n    /**\n     * A pending RPC subscription request whose notifications will be used to keep the store\n     * up to date. Each notification must be a {@link SolanaRpcResponse} so that its slot can be\n     * compared with the initial RPC response and other notifications.\n     */\n    rpcSubscriptionRequest: PendingRpcSubscriptionsRequest<SolanaRpcResponse<TSubscriptionValue>>;\n    /**\n     * Maps the value from a subscription notification to the item type stored in the reactive store.\n     */\n    rpcSubscriptionValueMapper: (value: TSubscriptionValue) => TItem;\n    /**\n     * Maps the value from the RPC response to the item type stored in the reactive store.\n     */\n    rpcValueMapper: (value: TRpcValue) => TItem;\n}>;\n\nconst LOADING_STATE: ReactiveState<never> = Object.freeze({\n    data: undefined,\n    error: undefined,\n    status: 'loading',\n});\n\n/**\n * Creates a {@link ReactiveStreamStore} that combines an initial RPC fetch with an ongoing subscription\n * to keep its state up to date.\n *\n * The store uses slot-based comparison to ensure that only the most recent value is kept,\n * regardless of whether it came from the initial RPC response or a subscription notification.\n * This prevents stale data from overwriting newer data when the RPC response and subscription\n * notifications arrive out of order.\n *\n * Things to note:\n *\n * - `getUnifiedState()` starts in `status: 'loading'` until the first response or notification\n *   arrives. Once data arrives it transitions to `status: 'loaded'` with a\n *   {@link SolanaRpcResponse} containing the value and the slot context at which it was observed.\n * - On error from either source, the store transitions to `status: 'error'` preserving the last\n *   known value. Only the first error per connection window is captured.\n * - Calling {@link ReactiveStreamStore.retry | `retry()`} while in `status: 'error'` re-sends the RPC\n *   request and re-subscribes to the subscription using a fresh inner abort signal. The store\n *   transitions through `status: 'retrying'` back to `loaded`/`error`.\n * - Triggering the caller's abort signal disconnects the store permanently; subsequent `retry()`\n *   calls are no-ops.\n *\n * @param config\n *\n * @example\n * ```ts\n * import {\n *     address,\n *     createReactiveStoreWithInitialValueAndSlotTracking,\n *     createSolanaRpc,\n *     createSolanaRpcSubscriptions,\n * } from '@solana/kit';\n *\n * const rpc = createSolanaRpc('http://127.0.0.1:8899');\n * const rpcSubscriptions = createSolanaRpcSubscriptions('ws://127.0.0.1:8900');\n * const myAddress = address('FnHyam9w4NZoWR6mKN1CuGBritdsEWZQa4Z4oawLZGxa');\n *\n * const balanceStore = createReactiveStoreWithInitialValueAndSlotTracking({\n *     abortSignal: AbortSignal.timeout(60_000),\n *     rpcRequest: rpc.getBalance(myAddress, { commitment: 'confirmed' }),\n *     rpcValueMapper: lamports => lamports,\n *     rpcSubscriptionRequest: rpcSubscriptions.accountNotifications(myAddress),\n *     rpcSubscriptionValueMapper: ({ lamports }) => lamports,\n * });\n *\n * const unsubscribe = balanceStore.subscribe(() => {\n *     const state = balanceStore.getUnifiedState();\n *     if (state.status === 'error') {\n *         console.error('Error:', state.error);\n *         balanceStore.retry();\n *     } else if (state.status === 'loaded') {\n *         console.log(`Balance at slot ${state.data.context.slot}:`, state.data.value);\n *     }\n * });\n * ```\n *\n * @see {@link ReactiveStreamStore}\n */\nexport function createReactiveStoreWithInitialValueAndSlotTracking<TRpcValue, TSubscriptionValue, TItem>({\n    abortSignal,\n    rpcRequest,\n    rpcValueMapper,\n    rpcSubscriptionRequest,\n    rpcSubscriptionValueMapper,\n}: CreateReactiveStoreWithInitialValueAndSlotTrackingConfig<TRpcValue, TSubscriptionValue, TItem>): ReactiveStreamStore<\n    SolanaRpcResponse<TItem>\n> {\n    let currentState: ReactiveState<SolanaRpcResponse<TItem>> = LOADING_STATE;\n    let lastUpdateSlot = -1n;\n    const subscribers = new Set<() => void>();\n\n    const outerController = new AbortController();\n    abortSignal.addEventListener('abort', () => outerController.abort(abortSignal.reason));\n\n    function notify() {\n        subscribers.forEach(cb => cb());\n    }\n\n    function connect() {\n        if (outerController.signal.aborted) return;\n        const innerController = new AbortController();\n        const forwardAbort = () => innerController.abort(outerController.signal.reason);\n        outerController.signal.addEventListener('abort', forwardAbort, { signal: innerController.signal });\n        const innerSignal = innerController.signal;\n\n        function handleError(err: unknown) {\n            if (innerSignal.aborted) return;\n            if (currentState.status === 'error') return;\n            currentState = { data: currentState.data, error: err, status: 'error' };\n            innerController.abort(err);\n            notify();\n        }\n\n        function handleValue(value: SolanaRpcResponse<TItem>) {\n            currentState = { data: value, error: undefined, status: 'loaded' };\n            notify();\n        }\n\n        rpcRequest\n            .send({ abortSignal: innerSignal })\n            .then(({ context: { slot }, value }) => {\n                if (innerSignal.aborted) return;\n                // `lastUpdateSlot` persists across retries so the store never regresses. If the\n                // retried RPC returns a slot older than one we've already seen, we wait for the\n                // subscription to deliver something newer before leaving `retrying`.\n                if (slot < lastUpdateSlot) return;\n                lastUpdateSlot = slot;\n                handleValue({ context: { slot }, value: rpcValueMapper(value) });\n            })\n            .catch(handleError);\n\n        rpcSubscriptionRequest\n            .subscribe({ abortSignal: innerSignal })\n            .then(async notifications => {\n                for await (const {\n                    context: { slot },\n                    value,\n                } of notifications) {\n                    if (innerSignal.aborted) return;\n                    if (slot < lastUpdateSlot) continue;\n                    lastUpdateSlot = slot;\n                    handleValue({ context: { slot }, value: rpcSubscriptionValueMapper(value) });\n                }\n            })\n            .catch(handleError);\n    }\n\n    connect();\n\n    return {\n        getError(): unknown {\n            return currentState.error;\n        },\n        getState(): SolanaRpcResponse<TItem> | undefined {\n            return currentState.data;\n        },\n        getUnifiedState(): ReactiveState<SolanaRpcResponse<TItem>> {\n            return currentState;\n        },\n        retry(): void {\n            if (outerController.signal.aborted) return;\n            if (currentState.status !== 'error') return;\n            currentState = { data: currentState.data, error: undefined, status: 'retrying' };\n            notify();\n            connect();\n        },\n        subscribe(callback: () => void): () => void {\n            subscribers.add(callback);\n            return () => {\n                subscribers.delete(callback);\n            };\n        },\n    };\n}\n"
  },
  {
    "path": "packages/kit/src/decompile-transaction-message-fetching-lookup-tables.ts",
    "content": "import { type FetchAccountsConfig } from '@solana/accounts';\nimport type { GetMultipleAccountsApi, Rpc } from '@solana/rpc';\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    decompileTransactionMessage,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithLifetime,\n} from '@solana/transaction-messages';\n\nimport { fetchAddressesForLookupTables } from './fetch-lookup-tables';\n\ntype DecompileTransactionMessageFetchingLookupTablesConfig = FetchAccountsConfig & {\n    lastValidBlockHeight?: bigint;\n};\n\n/**\n * Returns a {@link TransactionMessage} from a {@link CompiledTransactionMessage}. If any of the\n * accounts in the compiled message require an address lookup table to find their address, this\n * function will use the supplied RPC instance to fetch the contents of the address lookup table\n * from the network.\n *\n * @param rpc An object that supports the {@link GetMultipleAccountsApi} of the Solana RPC API\n * @param config\n */\nexport async function decompileTransactionMessageFetchingLookupTables(\n    compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime,\n    rpc: Rpc<GetMultipleAccountsApi>,\n    config?: DecompileTransactionMessageFetchingLookupTablesConfig,\n): Promise<TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime> {\n    const lookupTables =\n        'addressTableLookups' in compiledTransactionMessage &&\n        compiledTransactionMessage.addressTableLookups !== undefined &&\n        compiledTransactionMessage.addressTableLookups.length > 0\n            ? compiledTransactionMessage.addressTableLookups\n            : [];\n    const lookupTableAddresses = lookupTables.map(l => l.lookupTableAddress);\n\n    const { lastValidBlockHeight, ...fetchAccountsConfig } = config ?? {};\n    const addressesByLookupTableAddress =\n        lookupTableAddresses.length > 0\n            ? await fetchAddressesForLookupTables(lookupTableAddresses, rpc, fetchAccountsConfig)\n            : {};\n\n    return decompileTransactionMessage(compiledTransactionMessage, {\n        addressesByLookupTableAddress,\n        lastValidBlockHeight,\n    });\n}\n"
  },
  {
    "path": "packages/kit/src/fetch-lookup-tables.ts",
    "content": "import {\n    assertAccountsDecoded,\n    assertAccountsExist,\n    type FetchAccountsConfig,\n    fetchJsonParsedAccounts,\n} from '@solana/accounts';\nimport type { Address } from '@solana/addresses';\nimport type { GetMultipleAccountsApi, Rpc } from '@solana/rpc';\nimport { type AddressesByLookupTableAddress } from '@solana/transaction-messages';\n\ntype FetchedAddressLookup = {\n    addresses: Address[];\n};\n\n/**\n * Given a list of addresses belonging to address lookup tables, returns a map of lookup table\n * addresses to an ordered array of the addresses they contain.\n *\n * @param rpc An object that supports the {@link GetMultipleAccountsApi} of the Solana RPC API\n * @param config\n */\nexport async function fetchAddressesForLookupTables(\n    lookupTableAddresses: Address[],\n    rpc: Rpc<GetMultipleAccountsApi>,\n    config?: FetchAccountsConfig,\n): Promise<AddressesByLookupTableAddress> {\n    if (lookupTableAddresses.length === 0) {\n        return {};\n    }\n\n    const fetchedLookupTables = await fetchJsonParsedAccounts<FetchedAddressLookup[]>(\n        rpc,\n        lookupTableAddresses,\n        config,\n    );\n\n    assertAccountsDecoded(fetchedLookupTables);\n    assertAccountsExist(fetchedLookupTables);\n\n    return fetchedLookupTables.reduce<AddressesByLookupTableAddress>((acc, lookup) => {\n        return {\n            ...acc,\n            [lookup.address]: lookup.data.addresses,\n        };\n    }, {});\n}\n"
  },
  {
    "path": "packages/kit/src/get-minimum-balance-for-rent-exemption.ts",
    "content": "import type { Lamports } from '@solana/rpc-types';\n\n/**\n * Calculates the minimum {@link Lamports | lamports} required to make an account rent exempt for a\n * given data size, without performing an RPC call.\n *\n * Values are sourced from the on-chain rent parameters in the Solana runtime:\n * https://github.com/anza-xyz/solana-sdk/blob/c07f692e41d757057c8700211a9300cdcd6d33b1/rent/src/lib.rs#L93-L97\n *\n * Note that this logic may change, or be incorrect depending on the cluster you are connected to.\n * You can always use the RPC method `getMinimumBalanceForRentExemption` to get the current value.\n *\n * @deprecated The minimum balance for an account is being actively reduced\n * (see {@link https://github.com/solana-foundation/solana-improvement-documents/pull/437 | SIMD-0437})\n * and is expected to become dynamic in future Solana upgrades\n * (see {@link https://github.com/solana-foundation/solana-improvement-documents/pull/194 | SIMD-0194}\n * and {@link https://github.com/solana-foundation/solana-improvement-documents/pull/389 | SIMD-0389}),\n * meaning a hardcoded local computation will no longer return accurate results. Use the\n * {@link GetMinimumBalanceForRentExemptionApi.getMinimumBalanceForRentExemption | getMinimumBalanceForRentExemption}\n * RPC method or a `ClientWithGetMinimumBalance` plugin instead. This function will be removed in v7.\n *\n * @param space The number of bytes of account data.\n */\nexport function getMinimumBalanceForRentExemption(space: bigint): Lamports {\n    const RENT = {\n        ACCOUNT_STORAGE_OVERHEAD: 128n,\n        DEFAULT_EXEMPTION_THRESHOLD: 2n,\n        DEFAULT_LAMPORTS_PER_BYTE_YEAR: 3_480n,\n    } as const;\n    const requiredLamports =\n        (RENT.ACCOUNT_STORAGE_OVERHEAD + space) *\n        RENT.DEFAULT_LAMPORTS_PER_BYTE_YEAR *\n        RENT.DEFAULT_EXEMPTION_THRESHOLD;\n    return requiredLamports as Lamports;\n}\n"
  },
  {
    "path": "packages/kit/src/index.ts",
    "content": "/**\n * This is the JavaScript SDK for building Solana apps for Node, web, and React Native.\n *\n * In addition to re-exporting functions from packages in the `@solana/*` namespace, this package\n * offers additional helpers for building Solana applications, with sensible defaults.\n *\n * @packageDocumentation\n */\nexport * from '@solana/accounts';\nexport * from '@solana/addresses';\nexport * from '@solana/codecs';\nexport * from '@solana/errors';\nexport * from '@solana/functional';\nexport * from '@solana/instructions';\nexport * from '@solana/instruction-plans';\nexport * from '@solana/keys';\nexport * from '@solana/offchain-messages';\nexport * from '@solana/plugin-core';\nexport type * from '@solana/plugin-interfaces';\nexport * from '@solana/programs';\nexport * from '@solana/rpc';\nexport * from '@solana/rpc-parsed-types';\nexport * from '@solana/rpc-subscriptions';\nexport * from '@solana/rpc-types';\nexport * from '@solana/signers';\nexport * from '@solana/transaction-messages';\nexport * from '@solana/transactions';\nexport * from './create-async-generator-with-initial-value-and-slot-tracking';\nexport * from './create-reactive-store-with-initial-value-and-slot-tracking';\nexport * from './airdrop';\nexport * from './compute-unit-limit-estimation';\nexport * from './decompile-transaction-message-fetching-lookup-tables';\nexport * from './fetch-lookup-tables';\nexport * from './get-minimum-balance-for-rent-exemption';\nexport * from './send-and-confirm-durable-nonce-transaction';\nexport * from './send-and-confirm-transaction';\nexport * from './send-transaction-without-confirming';\n\nexport type {\n    RpcRequest,\n    RpcRequestTransformer,\n    RpcResponse,\n    RpcResponseData,\n    RpcResponseTransformer,\n} from '@solana/rpc-spec-types';\nexport { createRpcMessage } from '@solana/rpc-spec-types';\n"
  },
  {
    "path": "packages/kit/src/program-client-core.ts",
    "content": "export * from '@solana/program-client-core';\n"
  },
  {
    "path": "packages/kit/src/send-and-confirm-durable-nonce-transaction.ts",
    "content": "import { getSolanaErrorFromTransactionError, isSolanaError, SOLANA_ERROR__INVALID_NONCE } from '@solana/errors';\nimport { Signature } from '@solana/keys';\nimport type { GetAccountInfoApi, GetSignatureStatusesApi, Rpc, SendTransactionApi } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { commitmentComparator } from '@solana/rpc-types';\nimport {\n    createNonceInvalidationPromiseFactory,\n    createRecentSignatureConfirmationPromiseFactory,\n    waitForDurableNonceTransactionConfirmation,\n} from '@solana/transaction-confirmation';\nimport {\n    getSignatureFromTransaction,\n    SendableTransaction,\n    Transaction,\n    TransactionWithDurableNonceLifetime,\n} from '@solana/transactions';\n\nimport { sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT } from './send-transaction-internal';\n\ntype SendAndConfirmDurableNonceTransactionFunction = (\n    transaction: SendableTransaction & Transaction & TransactionWithDurableNonceLifetime,\n    config: Omit<\n        Parameters<typeof sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT>[0],\n        'confirmDurableNonceTransaction' | 'rpc' | 'transaction'\n    >,\n) => Promise<void>;\n\ntype SendAndConfirmDurableNonceTransactionFactoryConfig<TCluster> = {\n    /** An object that supports the {@link GetSignatureStatusesApi} and the {@link SendTransactionApi} of the Solana RPC API */\n    rpc: Rpc<GetAccountInfoApi & GetSignatureStatusesApi & SendTransactionApi> & { '~cluster'?: TCluster };\n    /** An object that supports the {@link AccountNotificationsApi} and the {@link SignatureNotificationsApi} of the Solana RPC Subscriptions API */\n    rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi & SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\n/**\n * Returns a function that you can call to send a nonce-based transaction to the network and to wait\n * until it has been confirmed.\n *\n * @param config\n *\n * @example\n * ```ts\n * import {\n *     isSolanaError,\n *     sendAndConfirmDurableNonceTransactionFactory,\n *     SOLANA_ERROR__INVALID_NONCE,\n *     SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND,\n * } from '@solana/kit';\n *\n * const sendAndConfirmNonceTransaction = sendAndConfirmDurableNonceTransactionFactory({ rpc, rpcSubscriptions });\n *\n * try {\n *     await sendAndConfirmNonceTransaction(transaction, { commitment: 'confirmed' });\n * } catch (e) {\n *     if (isSolanaError(e, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND)) {\n *         console.error(\n *             'The lifetime specified by this transaction refers to a nonce account ' +\n *                 `\\`${e.context.nonceAccountAddress}\\` that does not exist`,\n *         );\n *     } else if (isSolanaError(e, SOLANA_ERROR__INVALID_NONCE)) {\n *         console.error('This transaction depends on a nonce that is no longer valid');\n *     } else {\n *         throw e;\n *     }\n * }\n * ```\n */\nexport function sendAndConfirmDurableNonceTransactionFactory({\n    rpc,\n    rpcSubscriptions,\n}: SendAndConfirmDurableNonceTransactionFactoryConfig<'devnet'>): SendAndConfirmDurableNonceTransactionFunction;\nexport function sendAndConfirmDurableNonceTransactionFactory({\n    rpc,\n    rpcSubscriptions,\n}: SendAndConfirmDurableNonceTransactionFactoryConfig<'testnet'>): SendAndConfirmDurableNonceTransactionFunction;\nexport function sendAndConfirmDurableNonceTransactionFactory({\n    rpc,\n    rpcSubscriptions,\n}: SendAndConfirmDurableNonceTransactionFactoryConfig<'mainnet'>): SendAndConfirmDurableNonceTransactionFunction;\nexport function sendAndConfirmDurableNonceTransactionFactory<\n    TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n    rpc,\n    rpcSubscriptions,\n}: SendAndConfirmDurableNonceTransactionFactoryConfig<TCluster>): SendAndConfirmDurableNonceTransactionFunction {\n    const getNonceInvalidationPromise = createNonceInvalidationPromiseFactory({ rpc, rpcSubscriptions } as Parameters<\n        typeof createNonceInvalidationPromiseFactory\n    >[0]);\n    const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({\n        rpc,\n        rpcSubscriptions,\n    } as Parameters<typeof createRecentSignatureConfirmationPromiseFactory>[0]);\n\n    /**\n     * Creates a wrapped version of getNonceInvalidationPromise that handles the race condition\n     * where the nonce account update notification arrives before the signature confirmation.\n     *\n     * When the nonce changes, we check if our transaction actually landed on-chain.\n     * If it did, we don't throw - letting the signature confirmation promise continue.\n     */\n    function createNonceInvalidationPromiseHandlingRaceCondition(\n        signature: Signature,\n    ): typeof getNonceInvalidationPromise {\n        return async function wrappedGetNonceInvalidationPromise(config) {\n            try {\n                return await getNonceInvalidationPromise(config);\n            } catch (e) {\n                // If nonce became invalid, check if our transaction actually landed\n                if (isSolanaError(e, SOLANA_ERROR__INVALID_NONCE)) {\n                    let status;\n                    try {\n                        const { value: statuses } = await rpc\n                            .getSignatureStatuses([signature])\n                            .send({ abortSignal: config.abortSignal });\n                        status = statuses[0];\n                    } catch {\n                        // RPC failed - propagate the original nonce error\n                        throw e;\n                    }\n\n                    if (status === null || status === undefined) {\n                        // Transaction doesn't exist - nonce was truly invalid\n                        throw e;\n                    }\n\n                    // Check if status meets required commitment\n                    if (\n                        status.confirmationStatus !== null &&\n                        commitmentComparator(status.confirmationStatus, config.commitment) >= 0\n                    ) {\n                        // Transaction failed on-chain, throw the error from the transaction\n                        if (status.err !== null) {\n                            throw getSolanaErrorFromTransactionError(status.err);\n                        }\n                        // Transaction succeeded, resolve the promise successfully\n                        return;\n                    }\n\n                    // Commitment not met yet - return a never-resolving promise\n                    // This lets the signature confirmation promise continue\n                    return await new Promise(() => {});\n                }\n                throw e;\n            }\n        };\n    }\n\n    async function confirmDurableNonceTransaction(\n        config: Omit<\n            Parameters<typeof waitForDurableNonceTransactionConfirmation>[0],\n            'getNonceInvalidationPromise' | 'getRecentSignatureConfirmationPromise'\n        >,\n    ) {\n        const wrappedGetNonceInvalidationPromise = createNonceInvalidationPromiseHandlingRaceCondition(\n            getSignatureFromTransaction(config.transaction),\n        );\n\n        await waitForDurableNonceTransactionConfirmation({\n            ...config,\n            getNonceInvalidationPromise: wrappedGetNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n        });\n    }\n    return async function sendAndConfirmDurableNonceTransaction(transaction, config) {\n        await sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n            ...config,\n            confirmDurableNonceTransaction,\n            rpc,\n            transaction,\n        });\n    };\n}\n"
  },
  {
    "path": "packages/kit/src/send-and-confirm-transaction.ts",
    "content": "import type { GetEpochInfoApi, GetSignatureStatusesApi, Rpc, SendTransactionApi } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport {\n    createBlockHeightExceedencePromiseFactory,\n    createRecentSignatureConfirmationPromiseFactory,\n    TransactionWithLastValidBlockHeight,\n    waitForRecentTransactionConfirmation,\n} from '@solana/transaction-confirmation';\nimport { SendableTransaction, Transaction } from '@solana/transactions';\n\nimport { sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT } from './send-transaction-internal';\n\ntype SendAndConfirmTransactionWithBlockhashLifetimeFunction = (\n    transaction: SendableTransaction & Transaction & TransactionWithLastValidBlockHeight,\n    config: Omit<\n        Parameters<typeof sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT>[0],\n        'confirmRecentTransaction' | 'rpc' | 'transaction'\n    >,\n) => Promise<void>;\n\ntype SendAndConfirmTransactionWithBlockhashLifetimeFactoryConfig<TCluster> = {\n    /** An object that supports the {@link GetSignatureStatusesApi} and the {@link SendTransactionApi} of the Solana RPC API */\n    rpc: Rpc<GetEpochInfoApi & GetSignatureStatusesApi & SendTransactionApi> & { '~cluster'?: TCluster };\n    /** An object that supports the {@link SignatureNotificationsApi} and the {@link SlotNotificationsApi} of the Solana RPC Subscriptions API */\n    rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi & SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\n/**\n * Returns a function that you can call to send a blockhash-based transaction to the network and to\n * wait until it has been confirmed.\n *\n * @param config\n *\n * @example\n * ```ts\n * import { isSolanaError, sendAndConfirmTransactionFactory, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED } from '@solana/kit';\n *\n * const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });\n *\n * try {\n *     await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch (e) {\n *     if (isSolanaError(e, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {\n *         console.error('This transaction depends on a blockhash that has expired');\n *     } else {\n *         throw e;\n *     }\n * }\n * ```\n */\nexport function sendAndConfirmTransactionFactory({\n    rpc,\n    rpcSubscriptions,\n}: SendAndConfirmTransactionWithBlockhashLifetimeFactoryConfig<'devnet'>): SendAndConfirmTransactionWithBlockhashLifetimeFunction;\nexport function sendAndConfirmTransactionFactory({\n    rpc,\n    rpcSubscriptions,\n}: SendAndConfirmTransactionWithBlockhashLifetimeFactoryConfig<'testnet'>): SendAndConfirmTransactionWithBlockhashLifetimeFunction;\nexport function sendAndConfirmTransactionFactory({\n    rpc,\n    rpcSubscriptions,\n}: SendAndConfirmTransactionWithBlockhashLifetimeFactoryConfig<'mainnet'>): SendAndConfirmTransactionWithBlockhashLifetimeFunction;\nexport function sendAndConfirmTransactionFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n    rpc,\n    rpcSubscriptions,\n}: SendAndConfirmTransactionWithBlockhashLifetimeFactoryConfig<TCluster>): SendAndConfirmTransactionWithBlockhashLifetimeFunction {\n    const getBlockHeightExceedencePromise = createBlockHeightExceedencePromiseFactory({\n        rpc,\n        rpcSubscriptions,\n    } as Parameters<typeof createBlockHeightExceedencePromiseFactory>[0]);\n    const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({\n        rpc,\n        rpcSubscriptions,\n    } as Parameters<typeof createRecentSignatureConfirmationPromiseFactory>[0]);\n    async function confirmRecentTransaction(\n        config: Omit<\n            Parameters<typeof waitForRecentTransactionConfirmation>[0],\n            'getBlockHeightExceedencePromise' | 'getRecentSignatureConfirmationPromise'\n        >,\n    ) {\n        await waitForRecentTransactionConfirmation({\n            ...config,\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n        });\n    }\n    return async function sendAndConfirmTransaction(transaction, config) {\n        await sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n            ...config,\n            confirmRecentTransaction,\n            rpc,\n            transaction,\n        });\n    };\n}\n"
  },
  {
    "path": "packages/kit/src/send-transaction-internal.ts",
    "content": "import type { Signature } from '@solana/keys';\nimport type { Rpc, SendTransactionApi } from '@solana/rpc';\nimport { Commitment, commitmentComparator } from '@solana/rpc-types';\nimport {\n    TransactionWithLastValidBlockHeight,\n    waitForDurableNonceTransactionConfirmation,\n    waitForRecentTransactionConfirmation,\n} from '@solana/transaction-confirmation';\nimport {\n    getBase64EncodedWireTransaction,\n    SendableTransaction,\n    Transaction,\n    TransactionWithDurableNonceLifetime,\n} from '@solana/transactions';\n\ninterface SendAndConfirmDurableNonceTransactionConfig\n    extends SendTransactionBaseConfig, SendTransactionConfigWithoutEncoding {\n    confirmDurableNonceTransaction: (\n        config: Omit<\n            Parameters<typeof waitForDurableNonceTransactionConfirmation>[0],\n            'getNonceInvalidationPromise' | 'getRecentSignatureConfirmationPromise'\n        >,\n    ) => Promise<void>;\n    transaction: SendableTransaction & Transaction & TransactionWithDurableNonceLifetime;\n}\n\ninterface SendAndConfirmTransactionWithBlockhashLifetimeConfig\n    extends SendTransactionBaseConfig, SendTransactionConfigWithoutEncoding {\n    confirmRecentTransaction: (\n        config: Omit<\n            Parameters<typeof waitForRecentTransactionConfirmation>[0],\n            'getBlockHeightExceedencePromise' | 'getRecentSignatureConfirmationPromise'\n        >,\n    ) => Promise<void>;\n    transaction: SendableTransaction & Transaction & TransactionWithLastValidBlockHeight;\n}\n\ninterface SendTransactionBaseConfig extends SendTransactionConfigWithoutEncoding {\n    abortSignal?: AbortSignal;\n    commitment: Commitment;\n    rpc: Rpc<SendTransactionApi>;\n    transaction: SendableTransaction & Transaction;\n}\n\ntype SendTransactionConfigWithoutEncoding = Omit<\n    NonNullable<Parameters<SendTransactionApi['sendTransaction']>[1]>,\n    'encoding'\n>;\n\nfunction getSendTransactionConfigWithAdjustedPreflightCommitment(\n    commitment: Commitment,\n    config?: SendTransactionConfigWithoutEncoding,\n): SendTransactionConfigWithoutEncoding | void {\n    if (\n        // The developer has supplied no value for `preflightCommitment`.\n        !config?.preflightCommitment &&\n        // The value of `commitment` is lower than the server default of `preflightCommitment`.\n        commitmentComparator(commitment, 'finalized' /* default value of `preflightCommitment` */) < 0\n    ) {\n        return {\n            ...config,\n            // In the common case, it is unlikely that you want to simulate a transaction at\n            // `finalized` commitment when your standard of commitment for confirming the\n            // transaction is lower. Cap the simulation commitment level to the level of the\n            // confirmation commitment.\n            preflightCommitment: commitment,\n        };\n    }\n    // The commitment at which the developer wishes to confirm the transaction is at least as\n    // high as the commitment at which they want to simulate it. Honour the config as-is.\n    return config;\n}\n\nexport async function sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n    abortSignal,\n    commitment,\n    rpc,\n    transaction,\n    ...sendTransactionConfig\n}: SendTransactionBaseConfig): Promise<Signature> {\n    const base64EncodedWireTransaction = getBase64EncodedWireTransaction(transaction);\n    return await rpc\n        .sendTransaction(base64EncodedWireTransaction, {\n            ...getSendTransactionConfigWithAdjustedPreflightCommitment(commitment, sendTransactionConfig),\n            encoding: 'base64',\n        })\n        .send({ abortSignal });\n}\n\nexport async function sendAndConfirmDurableNonceTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n    abortSignal,\n    commitment,\n    confirmDurableNonceTransaction,\n    rpc,\n    transaction,\n    ...sendTransactionConfig\n}: SendAndConfirmDurableNonceTransactionConfig): Promise<Signature> {\n    const transactionSignature = await sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n        ...sendTransactionConfig,\n        abortSignal,\n        commitment,\n        rpc,\n        transaction,\n    });\n    await confirmDurableNonceTransaction({\n        abortSignal,\n        commitment,\n        transaction,\n    });\n    return transactionSignature;\n}\n\nexport async function sendAndConfirmTransactionWithBlockhashLifetime_INTERNAL_ONLY_DO_NOT_EXPORT({\n    abortSignal,\n    commitment,\n    confirmRecentTransaction,\n    rpc,\n    transaction,\n    ...sendTransactionConfig\n}: SendAndConfirmTransactionWithBlockhashLifetimeConfig): Promise<Signature> {\n    const transactionSignature = await sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n        ...sendTransactionConfig,\n        abortSignal,\n        commitment,\n        rpc,\n        transaction,\n    });\n    await confirmRecentTransaction({\n        abortSignal,\n        commitment,\n        transaction,\n    });\n    return transactionSignature;\n}\n"
  },
  {
    "path": "packages/kit/src/send-transaction-without-confirming.ts",
    "content": "import type { Rpc, SendTransactionApi } from '@solana/rpc';\nimport { SendableTransaction, Transaction } from '@solana/transactions';\n\nimport { sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT } from './send-transaction-internal';\n\ntype SendTransactionWithoutConfirmingFunction = (\n    transaction: SendableTransaction & Transaction,\n    config: Omit<Parameters<typeof sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT>[0], 'rpc' | 'transaction'>,\n) => Promise<void>;\n\ninterface SendTransactionWithoutConfirmingFactoryConfig {\n    /** An object that supports the {@link SendTransactionApi} of the Solana RPC API */\n    rpc: Rpc<SendTransactionApi>;\n}\n\n/**\n * Returns a function that you can call to send a transaction with any kind of lifetime to the\n * network without waiting for it to be confirmed.\n *\n * @param config\n *\n * @example\n * ```ts\n * import {\n *     sendTransactionWithoutConfirmingFactory,\n *     SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n * } from '@solana/kit';\n *\n * const sendTransaction = sendTransactionWithoutConfirmingFactory({ rpc });\n *\n * try {\n *     await sendTransaction(transaction, { commitment: 'confirmed' });\n * } catch (e) {\n *     if (isSolanaError(e, SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE)) {\n *         console.error('The transaction failed in simulation', e.cause);\n *     } else {\n *         throw e;\n *     }\n * }\n * ```\n */\nexport function sendTransactionWithoutConfirmingFactory({\n    rpc,\n}: SendTransactionWithoutConfirmingFactoryConfig): SendTransactionWithoutConfirmingFunction {\n    return async function sendTransactionWithoutConfirming(transaction, config) {\n        await sendTransaction_INTERNAL_ONLY_DO_NOT_EXPORT({\n            ...config,\n            rpc,\n            transaction,\n        });\n    };\n}\n"
  },
  {
    "path": "packages/kit/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\", \"src/program-client-core.ts\"]\n}\n"
  },
  {
    "path": "packages/kit/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2020\", \"ES2022.Error\", \"ES2024\"]\n    },\n    \"display\": \"@solana/kit\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/kit/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/nominal-types/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/nominal-types/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/nominal-types/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/nominal-types/CHANGELOG.md",
    "content": "# @solana/nominal-types\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n## 6.6.0\n\n## 6.5.0\n\n## 6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n## 6.1.0\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n## 5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n## 5.3.0\n\n## 5.2.0\n\n## 5.1.0\n\n## 5.0.0\n\n## 4.0.0\n\n## 3.0.0\n\n## 2.3.0\n\n## 2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- [`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893) Thanks [@nickfrosty](https://github.com/nickfrosty)! - Added `AffinePoint`; a nominal type that you can use to tag a value as representing an affine point over some field that is either valid or invalid from the perspective of some curve. Typically this will be used to tag an address as either on or off curve.\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n"
  },
  {
    "path": "packages/nominal-types/LICENSE",
    "content": "Copyright (c) 2025 Anza Technology, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/nominal-types/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/nominal-types?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/nominal-types?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/nominal-types\n\n# @solana/nominal-types\n\nThis package contains type utilities for creating nominal types in TypeScript.\n\n## Brands make otherwise equal values distinct at the type level\n\nUse the `Brand` utility to produce a new type that satisfies the original type, but not the other way around. That is to say, the branded type is acceptable wherever the original type is specified, but wherever the branded type is specified, the original type will be insufficient.\n\nYou can use this to create specialized instances of strings, numbers, objects, and more which you would like to assert are special in some way (eg. numbers that are non-negative, strings which represent the names of foods, objects that have passed validation).\n\n```ts\nconst unverifiedName = 'Alice';\nconst verifiedName = unverifiedName as Brand<'Alice', 'VerifiedName'>;\n\n'Alice' satisfies Brand<string, 'VerifiedName'>; // ERROR\n'Alice' satisfies Brand<'Alice', 'VerifiedName'>; // ERROR\nunverifiedName satisfies Brand<string, 'VerifiedName'>; // ERROR\nverifiedName satisfies Brand<'Bob', 'VerifiedName'>; // ERROR\nverifiedName satisfies Brand<'Alice', 'VerifiedName'>; // OK\nverifiedName satisfies Brand<string, 'VerifiedName'>; // OK\n```\n\n## Values can be tagged as compressed data\n\nUse the `CompressedData` utility to produce a new type that satisfies the original type, but adds extra type information that marks the type as containing compressed data.\n\n```ts\nconst untaggedData = new Uint8Array([/ ... *\\/]);\nconst compressedData = untaggedData as CompressedData<typeof untaggedData, 'zstd'>;\n\ncompressedData satisfies CompressedData<Uint8Array, 'zstd'>; // OK\nuntaggedData satisfies CompressedData<Uint8Array, 'zstd'>; // ERROR\n```\n\n## Strings can be tagged as being encoded using a particular scheme\n\n```ts\nconst untaggedString = 'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92';\nconst encodedString = untaggedString as EncodedString<typeof untaggedString, 'base58'>;\n\nencodedString satisfies EncodedString<'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92', 'base58'>; // OK\nencodedString satisfies EncodedString<string, 'base58'>; // OK\nencodedString satisfies EncodedString<string, 'base64'>; // ERROR\nuntaggedString satisfies EncodedString<string, 'base58'>; // ERROR\n```\n\n## Brands, compression, and encodings can be combined\n\n```ts\nconst encodedCompressedString = 'abc' as Brand<\n    EncodedString<CompressedData<'abc', 'zstd'>, 'base64'>,\n    'Base64ZstdCompressedData'\n>;\n\nencodedCompressedString satisfies Brand<'abc', 'Base64ZstdCompressedData'>; // OK\nencodedCompressedString satisfies Brand<string, 'Base64ZstdCompressedData'>; // OK\nencodedCompressedString satisfies CompressedData<'abc', 'zstd'>; // OK\nencodedCompressedString satisfies CompressedData<string, 'zstd'>; // OK\nencodedCompressedString satisfies EncodedString<'abc', 'base64'>; // OK\nencodedCompressedString satisfies EncodedString<string, 'base64'>; // OK\nencodedCompressedString satisfies EncodedString<string, 'base58'>; // ERROR\n```\n\n## Custom nominal types\n\n```ts\ntype SweeteningSubstance = 'aspartame' | 'cane-sugar' | 'stevia';\ntype Sweetener<T extends SweeteningSubstance> = NominalType<'sweetener', T>;\n\n// This function accepts sweetened foods, except those with aspartame.\ndeclare function eat(food: string & Sweetener<Exclude<SweeteningSubstance, 'aspartame'>>): void;\n\nconst artificiallySweetenedDessert = 'ice-cream' as string & Sweetener<'aspartame'>;\neat(artificiallySweetenedDessert); // ERROR\n```\n"
  },
  {
    "path": "packages/nominal-types/package.json",
    "content": "{\n    \"name\": \"@solana/nominal-types\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Type utilties for creating nominal/branded types in TypeScript\",\n    \"homepage\": \"https://www.solanakit.com/api#solananominal-types\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/nominal-types/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/nominal-types/src/__typetests__/brand-typetest.ts",
    "content": "import { Brand } from '../index';\n\n// [DESCRIBE] Brand.\n{\n    // Unbranded values do not satisfy a branded type\n    {\n        // @ts-expect-error The base value is identical, but the brand differs\n        'abc' satisfies Brand<'abc', 'Brand'>;\n    }\n\n    // Identical base values only satisfy their own brand.\n    {\n        const a = 'abc' as Brand<'abc', 'BrandA'>;\n        // @ts-expect-error The base value is identical, but the brand differs\n        a satisfies Brand<'abc', 'BrandB'>;\n    }\n}\n"
  },
  {
    "path": "packages/nominal-types/src/__typetests__/nominal-type-typetest.ts",
    "content": "import { NominalType } from '../index';\n\n// [DESCRIBE] NominalType.\n{\n    // It adds a particularly named readonly property/value to any type\n    {\n        const typedValue = null as unknown as NominalType<'foo', 'bar'>;\n        typedValue satisfies { readonly ['__foo:@solana/kit']: 'bar' };\n    }\n}\n"
  },
  {
    "path": "packages/nominal-types/src/index.ts",
    "content": "/**\n * This package contains type utilities for creating nominal types in TypeScript.\n *\n * @example Brands, compression, and encodings can be combined\n * ```ts\n * const encodedCompressedString = 'abc' as Brand<\n *     EncodedString<CompressedData<'abc', 'zstd'>, 'base64'>,\n *     'Base64ZstdCompressedData'\n * >;\n *\n * encodedCompressedString satisfies Brand<'abc', 'Base64ZstdCompressedData'>; // OK\n * encodedCompressedString satisfies Brand<string, 'Base64ZstdCompressedData'>; // OK\n * encodedCompressedString satisfies CompressedData<'abc', 'zstd'>; // OK\n * encodedCompressedString satisfies CompressedData<string, 'zstd'>; // OK\n * encodedCompressedString satisfies EncodedString<'abc', 'base64'>; // OK\n * encodedCompressedString satisfies EncodedString<string, 'base64'>; // OK\n * encodedCompressedString satisfies EncodedString<string, 'base58'>; // ERROR\n * ```\n *\n * @packageDocumentation\n */\n\ntype AffinePointValidity = 'invalid' | 'valid';\ntype CompressionFormat = 'zstd';\ntype StringEncoding = 'base58' | 'base64';\n\n/**\n * Use this to produce a new type that satisfies the original type, but adds extra type information\n * that marks the type as being an affine point over a field that either lies on a given curve\n * (is valid) or does not (is invalid).\n *\n * @typeParam T - The underlying type\n * @typeParam TValidity - Whether the point is valid or invalid\n *\n * @example\n * ```ts\n * const address = 'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92';\n * const onCurveAddress = address as AffinePoint<typeof address, 'valid'>;\n *\n * onCurveAddress satisfies AffinePoint<'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92', 'valid'>; // OK\n * onCurveAddress satisfies AffinePoint<string, 'valid'>; // OK\n * onCurveAddress satisfies AffinePoint<string, 'invalid'>; // ERROR\n * address satisfies AffinePoint<string, 'valid'>; // ERROR\n * address satisfies AffinePoint<string, 'invalid'>; // ERROR\n * ```\n */\nexport type AffinePoint<T, TValidity extends AffinePointValidity> = NominalType<'affinePoint', TValidity> & T;\n\n/**\n * Use this to produce a new type that satisfies the original type, but not the other way around.\n * That is to say, the branded type is acceptable wherever the original type is specified, but\n * wherever the branded type is specified, the original type will be insufficient.\n *\n * You can use this to create specialized instances of strings, numbers, objects, and more which\n * you would like to assert are special in some way (eg. numbers that are non-negative, strings\n * which represent the names of foods, objects that have passed validation).\n *\n * @typeParam T - The base type to brand\n * @typeParam TBrandName - A string that identifies a particular brand. Branded types with identical\n * names will satisfy each other so long as their base types satisfy each other. Branded types with\n * different names will never satisfy each other.\n *\n * @example\n * ```ts\n * const unverifiedName = 'Alice';\n * const verifiedName = unverifiedName as Brand<'Alice', 'VerifiedName'>;\n *\n * 'Alice' satisfies Brand<string, 'VerifiedName'>; // ERROR\n * 'Alice' satisfies Brand<'Alice', 'VerifiedName'>; // ERROR\n * unverifiedName satisfies Brand<string, 'VerifiedName'>; // ERROR\n * verifiedName satisfies Brand<'Bob', 'VerifiedName'>; // ERROR\n * verifiedName satisfies Brand<'Alice', 'VerifiedName'>; // OK\n * verifiedName satisfies Brand<string, 'VerifiedName'>; // OK\n * ```\n */\nexport type Brand<T, TBrandName extends string> = NominalType<'brand', TBrandName> & T;\n\n/**\n * Use this to produce a new type that satisfies the original type, but adds extra type information\n * that marks the type as containing compressed data.\n *\n * @typeParam T - The base type to mark as representing compressed data\n * @typeParam TFormat - The compression format of the underlying data\n *\n * @example\n * ```ts\n * const untaggedData = new Uint8Array([/* ... *\\/]);\n * const compressedData = untaggedData as CompressedData<typeof untaggedData, 'zstd'>;\n *\n * compressedData satisfies CompressedData<Uint8Array, 'zstd'>; // OK\n * untaggedData satisfies CompressedData<Uint8Array, 'zstd'>; // ERROR\n * ```\n */\nexport type CompressedData<T, TFormat extends CompressionFormat> = NominalType<'compressionFormat', TFormat> & T;\n\n/**\n * Use this to produce a new type that satisfies the original string type, but adds extra type\n * information that marks the string as being encoded in a particular format.\n *\n * @typeParam T - The underlying string type\n * @typeParam TEncoding - The encoding format of the string\n *\n * @example\n * ```ts\n * const untaggedString = 'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92';\n * const encodedString = untaggedString as EncodedString<typeof untaggedString, 'base58'>;\n *\n * encodedString satisfies EncodedString<'dv1ZAGvdsz5hHLwWXsVnM94hWf1pjbKVau1QVkaMJ92', 'base58'>; // OK\n * encodedString satisfies EncodedString<string, 'base58'>; // OK\n * encodedString satisfies EncodedString<string, 'base64'>; // ERROR\n * untaggedString satisfies EncodedString<string, 'base58'>; // ERROR\n * ```\n */\nexport type EncodedString<T extends string, TEncoding extends StringEncoding> = NominalType<\n    'stringEncoding',\n    TEncoding\n> &\n    T;\n\n/**\n * Use this to produce a nominal type.\n *\n * This can be intersected with other base types to produce custom branded types.\n *\n * @typeParam TKey - The name of the nominal type. This distinguishes one nominal type from another.\n * @typeParam TMarker - The type of the value the nominal type can take.\n *\n * @example\n * ```ts\n * type SweeteningSubstance = 'aspartame' | 'cane-sugar' | 'stevia';\n * type Sweetener<T extends SweeteningSubstance> = NominalType<'sweetener', T>;\n *\n * // This function accepts sweetened foods, except those with aspartame.\n * declare function eat(food: string & Sweetener<Exclude<SweeteningSubstance, 'aspartame'>>): void;\n *\n * const artificiallySweetenedDessert = 'ice-cream' as string & Sweetener<'aspartame'>;\n * eat(artificiallySweetenedDessert); // ERROR\n * ```\n */\nexport type NominalType<TKey extends string, TMarker extends string> = {\n    readonly [K in `__${TKey}:@solana/kit`]: TMarker;\n};\n"
  },
  {
    "path": "packages/nominal-types/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/nominal-types/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/nominal-types\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "packages/nominal-types/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/offchain-messages/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/offchain-messages/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/offchain-messages/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/offchain-messages/CHANGELOG.md",
    "content": "# @solana/offchain-messages\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-data-structures@6.9.0\n    - @solana/codecs-numbers@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/nominal-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-data-structures@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/nominal-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-data-structures@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/nominal-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-data-structures@6.6.0\n    - @solana/codecs-numbers@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/nominal-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-data-structures@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/nominal-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/codecs-data-structures@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/nominal-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-data-structures@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/nominal-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-data-structures@6.3.0\n    - @solana/codecs-numbers@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/nominal-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`5390602`](https://github.com/anza-xyz/kit/commit/53906024cffc3facb7259ab65ab974b6b1038f56), [`3f4c5f0`](https://github.com/anza-xyz/kit/commit/3f4c5f003e343c21a785e8f339f84c8d6bd3a3b1), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-data-structures@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/nominal-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`70b1ed8`](https://github.com/anza-xyz/kit/commit/70b1ed83be4c5445f81c600a8ca70127dbdf3463), [`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75), [`7ce7545`](https://github.com/anza-xyz/kit/commit/7ce75455659ace9776042def6774678a81c43a4a)]:\n    - @solana/codecs-data-structures@6.1.0\n    - @solana/errors@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-numbers@6.1.0\n    - @solana/codecs-strings@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/nominal-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-data-structures@6.0.1\n    - @solana/codecs-numbers@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/nominal-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-data-structures@6.0.0\n    - @solana/codecs-numbers@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/nominal-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-data-structures@5.5.1\n    - @solana/codecs-numbers@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/nominal-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-data-structures@5.5.0\n    - @solana/codecs-numbers@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/nominal-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-data-structures@5.4.0\n    - @solana/codecs-numbers@5.4.0\n    - @solana/codecs-strings@5.4.0\n    - @solana/nominal-types@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-data-structures@5.3.0\n    - @solana/codecs-numbers@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/nominal-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-numbers@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/codecs-data-structures@5.2.0\n    - @solana/nominal-types@5.2.0\n\n## 5.1.0\n\n### Minor Changes\n\n- [#880](https://github.com/anza-xyz/kit/pull/880) [`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Added codecs for encoding and decoding Solana Offchain Messages (see https://github.com/solana-foundation/SRFCs/discussions/3)\n\n- [#984](https://github.com/anza-xyz/kit/pull/984) [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df) Thanks [@steveluscher](https://github.com/steveluscher)! - Added the capability to sign Solana Offchain Messages using a `CryptoKey`\n\n### Patch Changes\n\n- [#1040](https://github.com/anza-xyz/kit/pull/1040) [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c) Thanks [@OrmEmbaar](https://github.com/OrmEmbaar)! - Add a function called bytesEqual to codecs-core that you can use to compare two byte arrays for equality.\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/codecs-data-structures@5.1.0\n    - @solana/codecs-numbers@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/nominal-types@5.1.0\n"
  },
  {
    "path": "packages/offchain-messages/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/offchain-messages/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/offchain-messages?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/offchain-messages?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/offchain-messages\n\n# @solana/offchain-messages\n\nThis package contains utilities for encoding and decoding messages according to the offchain message [specification](https://github.com/solana-foundation/SRFCs/discussions/3). It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n"
  },
  {
    "path": "packages/offchain-messages/package.json",
    "content": "{\n    \"name\": \"@solana/offchain-messages\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for encoding and decoding messages according to the offchain message specification\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaoffchain-messages\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-data-structures\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/nominal-types\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/offchain-messages/src/__tests__/content-test.ts",
    "content": "import { getUtf8Codec } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax,\n    assertIsOffchainMessageContentUtf8Of1232BytesMax,\n    assertIsOffchainMessageContentUtf8Of65535BytesMax,\n    isOffchainMessageContentRestrictedAsciiOf1232BytesMax,\n    isOffchainMessageContentUtf8Of1232BytesMax,\n    isOffchainMessageContentUtf8Of65535BytesMax,\n    OffchainMessageContentFormat,\n} from '../content';\n\nconst UTF8_LONGER_THAN_65535 = [\n    '!'.repeat(65535 + 1),\n    '😘'.repeat(16383 + 1),\n    '€'.repeat(21845 + 1),\n    '✌🏿'.repeat(9362 + 1),\n];\nconst UTF8_WITHIN_65535 = ['!'.repeat(65535), '😘'.repeat(16383), '€'.repeat(21845), '✌🏿'.repeat(9362)];\n\nconst UTF8_LONGER_THAN_1232 = ['!'.repeat(1232 + 1), '😘'.repeat(308 + 1), '€'.repeat(410 + 1), '✌🏿'.repeat(176 + 1)];\nconst UTF8_WITHIN_1232 = ['!'.repeat(1232), '😘'.repeat(308), '€'.repeat(410), '✌🏿'.repeat(176)];\n\ndescribe('assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax()', () => {\n    it.each([OffchainMessageContentFormat.UTF8_1232_BYTES_MAX, OffchainMessageContentFormat.UTF8_65535_BYTES_MAX])(\n        'throws a format mismatch error when the format is %j',\n        format => {\n            expect(() =>\n                assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                    format,\n                    text: 'Hello world',\n                }),\n            ).toThrow(\n                new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {\n                    actualMessageFormat: format,\n                    expectedMessageFormat: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                }),\n            );\n        },\n    );\n    it('throws a length exceeded error when the content is over 1232 characters', () => {\n        expect(() =>\n            assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '!'.repeat(1232 + 1),\n            }),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n                actualBytes: 1232 + 1,\n                maxBytes: 1232,\n            }),\n        );\n    });\n    it('does not throw a length exceeded error when the content is exactly 1232 characters', () => {\n        expect(() =>\n            assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '!'.repeat(1232),\n            }),\n        ).not.toThrow();\n    });\n    it('throws a non-empty error when the content is empty', () => {\n        expect(() =>\n            assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '',\n            }),\n        ).toThrow(new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY));\n    });\n    it.each(['\\x19', '\\x7f'])('throws when the content contains out of range character %j', char => {\n        expect(() =>\n            assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: char,\n            }),\n        ).toThrow(new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE));\n    });\n    it.each(Array.from({ length: 0x7e - 0x20 + 1 }, (_, ii) => String.fromCharCode(0x20 + ii)))(\n        'does not throw when the content contains allowed character %j',\n        char => {\n            expect(() =>\n                assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                    format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                    text: char,\n                }),\n            ).not.toThrow();\n        },\n    );\n});\n\ndescribe('isOffchainMessageContentRestrictedAsciiOf1232BytesMax()', () => {\n    it.each([OffchainMessageContentFormat.UTF8_1232_BYTES_MAX, OffchainMessageContentFormat.UTF8_65535_BYTES_MAX])(\n        'returns `false` when the format is %j',\n        format => {\n            expect(\n                isOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                    format,\n                    text: 'Hello world',\n                }),\n            ).toBe(false);\n        },\n    );\n    it('returns `false` when the content exceeds 1232 characters', () => {\n        expect(\n            isOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '!'.repeat(1232 + 1),\n            }),\n        ).toBe(false);\n    });\n    it('returns `true` when the content is exactly 1232 characters', () => {\n        expect(\n            isOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '!'.repeat(1232),\n            }),\n        ).toBe(true);\n    });\n    it('returns `false` when the content is empty', () => {\n        expect(\n            isOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '',\n            }),\n        ).toBe(false);\n    });\n    it.each(['\\x19', '\\x7f'])('returns `false` when the content contains out of range character %j', char => {\n        expect(\n            isOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: char,\n            }),\n        ).toBe(false);\n    });\n    it.each(Array.from({ length: 0x7e - 0x20 + 1 }, (_, ii) => String.fromCharCode(0x20 + ii)))(\n        'does not throw when the content contains allowed character %j',\n        char => {\n            expect(\n                isOffchainMessageContentRestrictedAsciiOf1232BytesMax({\n                    format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                    text: char,\n                }),\n            ).toBe(true);\n        },\n    );\n});\n\ndescribe('assertIsOffchainMessageContentUtf8Of1232BytesMax()', () => {\n    it.each([\n        OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n        OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n    ])('throws a format mismatch error when the format is %j', format => {\n        expect(() =>\n            assertIsOffchainMessageContentUtf8Of1232BytesMax({\n                format,\n                text: 'Hello world',\n            }),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {\n                actualMessageFormat: format,\n                expectedMessageFormat: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n            }),\n        );\n    });\n    it.each(UTF8_LONGER_THAN_1232)('throws a length exceeded error when the content is \"%s\"', text => {\n        expect(() =>\n            assertIsOffchainMessageContentUtf8Of1232BytesMax({\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text,\n            }),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n                actualBytes: getUtf8Codec().getSizeFromValue(text),\n                maxBytes: 1232,\n            }),\n        );\n    });\n    it('throws a non-empty error when the content is empty', () => {\n        expect(() =>\n            assertIsOffchainMessageContentUtf8Of1232BytesMax({\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text: '',\n            }),\n        ).toThrow(new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY));\n    });\n    it.each(UTF8_WITHIN_1232)('does not throw a length exceeded error when the content is \"%s\"', text => {\n        expect(() =>\n            assertIsOffchainMessageContentUtf8Of1232BytesMax({\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text,\n            }),\n        ).not.toThrow();\n    });\n});\n\ndescribe('isOffchainMessageContentUtf8Of1232BytesMax()', () => {\n    it.each([\n        OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n        OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n    ])('returns `false` when the format is %j', format => {\n        expect(\n            isOffchainMessageContentUtf8Of1232BytesMax({\n                format,\n                text: 'Hello world',\n            }),\n        ).toBe(false);\n    });\n    it.each(UTF8_LONGER_THAN_1232)('returns `false` when the content is \"%s\"', text => {\n        expect(\n            isOffchainMessageContentUtf8Of1232BytesMax({\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text,\n            }),\n        ).toBe(false);\n    });\n    it('returns `false` when the content is empty', () => {\n        expect(\n            isOffchainMessageContentUtf8Of1232BytesMax({\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text: '',\n            }),\n        ).toBe(false);\n    });\n    it.each(UTF8_WITHIN_1232)('returns `true` when the content is \"%s\"', text => {\n        expect(\n            isOffchainMessageContentUtf8Of1232BytesMax({\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text,\n            }),\n        ).toBe(true);\n    });\n});\n\ndescribe('assertIsOffchainMessageContentUtf8Of65535BytesMax()', () => {\n    it.each([\n        OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n        OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n    ])('throws a format mismatch error when the format is %j', format => {\n        expect(() =>\n            assertIsOffchainMessageContentUtf8Of65535BytesMax({\n                format,\n                text: 'Hello world',\n            }),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {\n                actualMessageFormat: format,\n                expectedMessageFormat: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n            }),\n        );\n    });\n    it.each(UTF8_LONGER_THAN_65535)('throws a length exceeded error when the content is \"%s\"', text => {\n        expect(() =>\n            assertIsOffchainMessageContentUtf8Of65535BytesMax({\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text,\n            }),\n        ).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n                actualBytes: getUtf8Codec().getSizeFromValue(text),\n                maxBytes: 65535,\n            }),\n        );\n    });\n    it('throws a non-empty error when the content is empty', () => {\n        expect(() =>\n            assertIsOffchainMessageContentUtf8Of65535BytesMax({\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text: '',\n            }),\n        ).toThrow(new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY));\n    });\n    it.each(UTF8_WITHIN_65535)('does not throw a length exceeded error when the content is \"%s\"', text => {\n        expect(() =>\n            assertIsOffchainMessageContentUtf8Of65535BytesMax({\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text,\n            }),\n        ).not.toThrow();\n    });\n});\n\ndescribe('isOffchainMessageContentUtf8Of65535BytesMax()', () => {\n    it.each([\n        OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n        OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n    ])('returns `false` when the format is %j', format => {\n        expect(\n            isOffchainMessageContentUtf8Of65535BytesMax({\n                format,\n                text: 'Hello world',\n            }),\n        ).toBe(false);\n    });\n    it.each(UTF8_LONGER_THAN_65535)('returns `false` when the content is \"%s\"', text => {\n        expect(\n            isOffchainMessageContentUtf8Of65535BytesMax({\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text,\n            }),\n        ).toBe(false);\n    });\n    it('returns `false` when the content is empty', () => {\n        expect(\n            isOffchainMessageContentUtf8Of65535BytesMax({\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text: '',\n            }),\n        ).toBe(false);\n    });\n    it.each(UTF8_WITHIN_65535)('returns `true` when the content is \"%s\"', text => {\n        expect(\n            isOffchainMessageContentUtf8Of65535BytesMax({\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text,\n            }),\n        ).toBe(true);\n    });\n});\n"
  },
  {
    "path": "packages/offchain-messages/src/__tests__/envelope-codec-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array, VariableSizeDecoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { getOffchainMessageEnvelopeDecoder, getOffchainMessageEnvelopeEncoder } from '../codecs/envelope';\nimport { OffchainMessageEnvelope } from '../envelope';\nimport { OffchainMessageBytes } from '../message';\n\n// The string `'\\xffsolana offchain'`\nconst OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES: ReadonlyUint8Array = new Uint8Array([\n    0xff, 0x73, 0x6f, 0x6c, 0x61, 0x6e, 0x61, 0x20, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,\n]);\n\nconst APPLICATION_DOMAIN_BYTES = new Uint8Array([\n    0x0d, 0x3b, 0x73, 0x0b, 0x9e, 0x88, 0x9b, 0x4b, 0x66, 0x1e, 0xd2, 0xa3, 0xce, 0x19, 0x1f, 0x68, 0xd3, 0x7d, 0xa7,\n    0x44, 0x32, 0x06, 0xa1, 0x82, 0xb9, 0x46, 0x89, 0x1e, 0x00, 0x00, 0x00, 0x00,\n]);\n\nconst SIGNER_A =\n    'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address<'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'>;\nconst SIGNER_A_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x55, 0x0e, 0x94, 0xc7, 0x25, 0x63, 0x9a, 0x4b, 0xd1, 0x1d, 0x4e, 0xa5, 0xa6, 0x38,\n    0x36, 0x51, 0xc3, 0x08, 0xb7, 0x18, 0xc3, 0xae, 0xf2, 0x86, 0xbc, 0xa1, 0xaf,\n]);\nconst SIGNER_B =\n    'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address<'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'>;\nconst SIGNER_B_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x5c, 0x95, 0xef, 0xb9, 0x72, 0xc0, 0xc5, 0xb7, 0xae, 0x0f, 0xd5, 0x20, 0xd9, 0x7e,\n    0x94, 0x8f, 0xd8, 0xbb, 0x2c, 0x10, 0xa1, 0x01, 0x02, 0xce, 0x98, 0xb3, 0xa6,\n]);\n\ndescribe('getOffchainMessageEnvelopeDecoder()', () => {\n    let decoder: VariableSizeDecoder<OffchainMessageEnvelope>;\n    beforeEach(() => {\n        decoder = getOffchainMessageEnvelopeDecoder();\n    });\n    it('decodes a well-formed encoded message envelope according to spec', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const encodedMessageEnvelope =\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x02,\n                    // Signatures\n                    ...new Uint8Array(64).fill(0x00),\n                    ...new Uint8Array(64).fill(0x02),\n                ...encodedMessage,\n            ]);\n        expect(decoder.decode(encodedMessageEnvelope)).toStrictEqual({\n            content: encodedMessage,\n            signatures: {\n                [SIGNER_A]: null,\n                [SIGNER_B]: new Uint8Array(64).fill(0x02),\n            },\n        });\n    });\n    it('freezes the decoded envelope', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const encodedMessageEnvelope =\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x02,\n                    // Signatures\n                    ...new Uint8Array(64).fill(0x00),\n                    ...new Uint8Array(64).fill(0x02),\n                ...encodedMessage,\n            ]);\n        const decodedEnvelope = decoder.decode(encodedMessageEnvelope);\n        expect(decodedEnvelope).toBeFrozenObject();\n        expect(decodedEnvelope.signatures).toBeFrozenObject();\n    });\n    it('orders the keys in the signatures map in the order they are specified by the message', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_B_BYTES,\n                    ...SIGNER_A_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const encodedMessageEnvelope =\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x02,\n                    // Signatures\n                    ...new Uint8Array(64).fill(0x02),\n                    ...new Uint8Array(64).fill(0x01),\n                ...encodedMessage,\n            ]);\n        const offchainMessageEnvelope = decoder.decode(encodedMessageEnvelope);\n        expect(Object.keys(offchainMessageEnvelope.signatures)).toStrictEqual([SIGNER_B, SIGNER_A]);\n    });\n    it('throws when the message specfifies no signers', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x00,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const encodedMessageEnvelope =\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x02,\n                    // Signatures\n                    ...new Uint8Array(64).fill(0x02),\n                    ...new Uint8Array(64).fill(0x01),\n                ...encodedMessage,\n            ]);\n        expect(() => {\n            decoder.decode(encodedMessageEnvelope);\n        }).toThrow(new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO));\n    });\n    it('throws when the envelope has no signatures', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x00,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const encodedMessageEnvelope =\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x00,\n                ...encodedMessage,\n            ]);\n        expect(() => {\n            decoder.decode(encodedMessageEnvelope);\n        }).toThrow(new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO));\n    });\n    it('throws when the number of required signatures specified by the message and the number of signatures in the envelope mismatch', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const encodedMessageEnvelope =\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x01,\n                    // Signatures\n                    ...new Uint8Array(64),\n                ...encodedMessage,\n            ]);\n        expect(() => {\n            decoder.decode(encodedMessageEnvelope);\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH, {\n                numRequiredSignatures: 2,\n                signatoryAddresses: [SIGNER_A, SIGNER_B],\n                signaturesLength: 1,\n            }),\n        );\n    });\n    it.each(\n        Array.from({ length: 255 - 1 /* highest supported version */ })\n            .map((_, ii) => 255 - ii)\n            .reverse(),\n    )('throws if the preamble is of version `%s`', putativeVersion => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version (unrecognized)\n                putativeVersion,\n            ]);\n        const encodedMessageEnvelope =\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x01,\n                    // Signatures\n                    ...new Uint8Array(64),\n                ...encodedMessage,\n            ]);\n        expect(() => {\n            decoder.decode(encodedMessageEnvelope);\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: putativeVersion,\n            }),\n        );\n    });\n});\n\ndescribe('getOffchainMessageEnvelopeEncoder()', () => {\n    let encoder: VariableSizeEncoder<OffchainMessageEnvelope>;\n    beforeEach(() => {\n        encoder = getOffchainMessageEnvelopeEncoder();\n    });\n    it('encodes a well-formed message envelope according to spec', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const envelope: OffchainMessageEnvelope = {\n            content: encodedMessage as unknown as OffchainMessageBytes,\n            signatures: {\n                [SIGNER_A]: null,\n                [SIGNER_B]: new Uint8Array(64).fill(0x02) as SignatureBytes,\n            },\n        };\n        expect(encoder.encode(envelope)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x02,\n                // Signatures\n                    ...new Uint8Array(64).fill(0x00),\n                    ...new Uint8Array(64).fill(0x02),\n                ...encodedMessage,\n            ]),\n        );\n    });\n    it('encodes the signatures in the order specified by the preable, regardless of the order in the signatures map', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const envelope: OffchainMessageEnvelope = {\n            content: encodedMessage as unknown as OffchainMessageBytes,\n            signatures: {\n                [SIGNER_B]: new Uint8Array(64).fill(0x02) as SignatureBytes,\n                // eslint-disable-next-line sort-keys-fix/sort-keys-fix\n                [SIGNER_A]: null,\n            },\n        };\n        expect(encoder.encode(envelope)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // Signer count\n                0x02,\n                // Signatures\n                    ...new Uint8Array(64).fill(0x00),\n                    ...new Uint8Array(64).fill(0x02),\n                ...encodedMessage,\n            ]),\n        );\n    });\n    it('throws when the envelope has no signatures', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const envelope: OffchainMessageEnvelope = {\n            content: encodedMessage as unknown as OffchainMessageBytes,\n            signatures: {},\n        };\n        expect(() => {\n            encoder.encode(envelope);\n        }).toThrow(new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO));\n    });\n    it('throws when the signature addresses in the envelope do not match the required signatures in the preamble', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const SIGNER_C =\n            'signerCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC' as Address<'signerCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'>;\n        const envelope: OffchainMessageEnvelope = {\n            content: encodedMessage as unknown as OffchainMessageBytes,\n            signatures: {\n                [SIGNER_C]: null,\n                // eslint-disable-next-line sort-keys-fix/sort-keys-fix\n                [SIGNER_A]: null,\n            },\n        };\n        expect(() => {\n            encoder.encode(envelope);\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH, {\n                missingRequiredSigners: [SIGNER_B],\n                unexpectedSigners: [SIGNER_C],\n            }),\n        );\n    });\n    it.each(\n        Array.from({ length: 255 - 1 /* highest supported version */ })\n            .map((_, ii) => 255 - ii)\n            .reverse(),\n    )('throws if the envelope is of version `%s`', putativeVersion => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version (unrecognized)\n                putativeVersion,\n            ]);\n        expect(() => {\n            encoder.encode({\n                content: encodedMessage as unknown as OffchainMessageBytes,\n                signatures: {\n                    [SIGNER_A]: null,\n                },\n            });\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: putativeVersion,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/offchain-messages/src/__tests__/message-codec-test.ts",
    "content": "import { ReadonlyUint8Array, VariableSizeDecoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport { getOffchainMessageDecoder, getOffchainMessageEncoder } from '../codecs/message';\nimport { getOffchainMessageV0Decoder, getOffchainMessageV0Encoder } from '../codecs/message-v0';\nimport { getOffchainMessageV1Decoder, getOffchainMessageV1Encoder } from '../codecs/message-v1';\nimport { OffchainMessage } from '../message';\nimport { OffchainMessageV0 } from '../message-v0';\nimport { OffchainMessageV1 } from '../message-v1';\n\njest.mock('../codecs/message-v0');\njest.mock('../codecs/message-v1');\n\n// The string `'\\xffsolana offchain'`\nconst OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES: ReadonlyUint8Array = new Uint8Array([\n    0xff, 0x73, 0x6f, 0x6c, 0x61, 0x6e, 0x61, 0x20, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,\n]);\n\ndescribe('getOffchainMessageDecoder', () => {\n    let decoder: VariableSizeDecoder<OffchainMessage>;\n    beforeEach(() => {\n        decoder = getOffchainMessageDecoder();\n    });\n    it('delegates to the version 0 message decoder when the preamble is of version 0', () => {\n        const expectedResult = 123;\n        const mockDecoder = jest.fn().mockReturnValue(expectedResult);\n        const mockReader = jest.fn().mockReturnValue([\n            expectedResult,\n            OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES.byteLength +\n                // Version\n                1 +\n                // Padding\n                1,\n        ]);\n        jest.mocked(getOffchainMessageV0Decoder).mockReturnValue({ decode: mockDecoder, read: mockReader });\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                    // Padding\n                    0xff,\n                    // Signing domain\n                    ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                    // Version\n                    0x00,\n                ]);\n        const result = decoder.decode(encodedMessage, 1);\n        expect(mockReader).toHaveBeenCalledWith(encodedMessage, 1);\n        expect(result).toBe(expectedResult);\n    });\n    it('delegates to the version 1 message decoder when the preamble is of version 1', () => {\n        const expectedResult = 123;\n        const mockDecoder = jest.fn().mockReturnValue(expectedResult);\n        const mockReader = jest.fn().mockReturnValue([\n            expectedResult,\n            OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES.byteLength +\n                // Version\n                1 +\n                // Padding\n                1,\n        ]);\n        jest.mocked(getOffchainMessageV1Decoder).mockReturnValue({ decode: mockDecoder, read: mockReader });\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                    // Padding\n                    0xff,\n                    // Signing domain\n                    ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                    // Version\n                    0x01,\n                ]);\n        const result = decoder.decode(encodedMessage, 1);\n        expect(mockReader).toHaveBeenCalledWith(encodedMessage, 1);\n        expect(result).toBe(expectedResult);\n    });\n    it.each(\n        Array.from({ length: 255 - 1 /* highest supported version */ })\n            .map((_, ii) => 255 - ii)\n            .reverse(),\n    )('throws if the preamble is of version `%s`', putativeVersion => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                    // Signing domain\n                    ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                    // Version (unrecognized)\n                    putativeVersion,\n                ]);\n        expect(() => {\n            decoder.decode(encodedMessage);\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: putativeVersion,\n            }),\n        );\n    });\n});\n\ndescribe('getOffchainMessageEncoder', () => {\n    let encoder: VariableSizeEncoder<OffchainMessage>;\n    beforeEach(() => {\n        encoder = getOffchainMessageEncoder();\n    });\n    it('delegates to the version 0 message encoder when the message is of version 0', () => {\n        const mockMessage = { version: 0 };\n        const mockWriter = jest.fn().mockImplementation((_message, bytes, offset) => {\n            bytes.set([1, 2, 3], offset);\n        });\n        jest.mocked(getOffchainMessageV0Encoder).mockReturnValue({\n            encode: jest.fn(),\n            getSizeFromValue: jest.fn().mockReturnValue(3),\n            write: mockWriter,\n        });\n        const result = encoder.encode(mockMessage as OffchainMessageV0);\n        expect(mockWriter).toHaveBeenCalledWith(mockMessage, expect.any(Uint8Array), 0 /* offset */);\n        expect(result).toStrictEqual(new Uint8Array([1, 2, 3]));\n    });\n    it('delegates to the version 1 message encoder when the message is of version 1', () => {\n        const mockMessage = { version: 1 };\n        const mockWriter = jest.fn().mockImplementation((_message, bytes, offset) => {\n            bytes.set([1, 2, 3], offset);\n        });\n        jest.mocked(getOffchainMessageV1Encoder).mockReturnValue({\n            encode: jest.fn(),\n            getSizeFromValue: jest.fn().mockReturnValue(3),\n            write: mockWriter,\n        });\n        const result = encoder.encode(mockMessage as OffchainMessageV1);\n        expect(mockWriter).toHaveBeenCalledWith(mockMessage, expect.any(Uint8Array), 0 /* offset */);\n        expect(result).toStrictEqual(new Uint8Array([1, 2, 3]));\n    });\n    it.each(\n        Array.from({ length: 255 - 1 /* highest supported version */ })\n            .map((_, ii) => 255 - ii)\n            .reverse(),\n    )('throws if the preamble is of version `%s`', putativeVersion => {\n        expect(() => {\n            encoder.encode({ version: putativeVersion } as OffchainMessage);\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: putativeVersion,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/offchain-messages/src/__tests__/message-v0-codec-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array, VariableSizeDecoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getBase16Decoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_CONSTANT,\n    SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED,\n    SolanaError,\n} from '@solana/errors';\n\nimport { OffchainMessageApplicationDomain } from '../application-domain';\nimport { getOffchainMessageV0Decoder, getOffchainMessageV0Encoder } from '../codecs/message-v0';\nimport {\n    OffchainMessageContentFormat,\n    OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n    OffchainMessageContentUtf8Of1232BytesMax,\n    OffchainMessageContentUtf8Of65535BytesMax,\n} from '../content';\nimport { OffchainMessageV0 } from '../message-v0';\n\n// The string `'\\xffsolana offchain'`\nconst OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES: ReadonlyUint8Array = new Uint8Array([\n    0xff, 0x73, 0x6f, 0x6c, 0x61, 0x6e, 0x61, 0x20, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,\n]);\n\nconst APPLICATION_DOMAIN = 'testdomain111111111111111111111111111111111' as OffchainMessageApplicationDomain;\nconst APPLICATION_DOMAIN_BYTES = new Uint8Array([\n    0x0d, 0x3b, 0x73, 0x0b, 0x9e, 0x88, 0x9b, 0x4b, 0x66, 0x1e, 0xd2, 0xa3, 0xce, 0x19, 0x1f, 0x68, 0xd3, 0x7d, 0xa7,\n    0x44, 0x32, 0x06, 0xa1, 0x82, 0xb9, 0x46, 0x89, 0x1e, 0x00, 0x00, 0x00, 0x00,\n]);\n\nconst SIGNER_A =\n    'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address<'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'>;\nconst SIGNER_A_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x55, 0x0e, 0x94, 0xc7, 0x25, 0x63, 0x9a, 0x4b, 0xd1, 0x1d, 0x4e, 0xa5, 0xa6, 0x38,\n    0x36, 0x51, 0xc3, 0x08, 0xb7, 0x18, 0xc3, 0xae, 0xf2, 0x86, 0xbc, 0xa1, 0xaf,\n]);\nconst SIGNER_B =\n    'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address<'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'>;\nconst SIGNER_B_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x5c, 0x95, 0xef, 0xb9, 0x72, 0xc0, 0xc5, 0xb7, 0xae, 0x0f, 0xd5, 0x20, 0xd9, 0x7e,\n    0x94, 0x8f, 0xd8, 0xbb, 0x2c, 0x10, 0xa1, 0x01, 0x02, 0xce, 0x98, 0xb3, 0xa6,\n]);\n\ndescribe('getOffchainMessageV0Decoder()', () => {\n    let decoder: VariableSizeDecoder<OffchainMessageV0>;\n    beforeEach(() => {\n        decoder = getOffchainMessageV0Decoder();\n    });\n    it('decodes a well-formed ASCII encoded message according to spec', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(decoder.decode(encodedMessage)).toStrictEqual({\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: 'Hello world',\n            },\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        });\n    });\n    it('freezes the decoded message', () => {\n        expect.assertions(5);\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const decodedMessage = decoder.decode(encodedMessage);\n        expect(decodedMessage).toBeFrozenObject();\n        expect(decodedMessage.content).toBeFrozenObject();\n        expect(decodedMessage.requiredSignatories).toBeFrozenObject();\n        decodedMessage.requiredSignatories.forEach(signer => expect(signer).toBeFrozenObject());\n    });\n    it('throws when decoding an encoded message with a malformed signing domain', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain (malformed)\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES.toReversed(),\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (1 character)\n                0x01, 0x00,\n                    // Message (horizontal tab character)\n                    0x09,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_CONSTANT, {\n                constant: OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                data: encodedMessage,\n                hexConstant: getBase16Decoder().decode(OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES),\n                hexData: getBase16Decoder().decode(encodedMessage),\n                offset: 0,\n            }),\n        );\n    });\n    it('throws when decoding an ASCII encoded message whose message content is outside the restricted set', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (1 character)\n                0x01, 0x00,\n                    // Message (horizontal tab character)\n                    0x09,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE),\n        );\n    });\n    it('throws when decoding an ASCII encoded message with a non-zero version', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                 // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION, {\n                actualVersion: 1,\n                expectedVersion: 0,\n            }),\n        );\n    });\n    it('throws when decoding an ASCII encoded message with an unsupported version', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0xFF,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                 // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: 255,\n            }),\n        );\n    });\n    it('throws when decoding an ASCII encoded message whose message content length is zero', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (0 characters)\n                0x00, 0x00,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY),\n        );\n    });\n    it('throws when decoding an ASCII encoded message whose required signers length is zero', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x00,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO),\n        );\n    });\n    it('throws when decoding an ASCII encoded message whose message content is too long', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (1232 + 1 characters)\n                0xd1, 0x04,\n                    // Message\n                    ...Array.from<number>({ length: 1232 + 1 }).fill(0x21 /* exclamation point */), \n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n                actualBytes: 1232 + 1,\n                maxBytes: 1232,\n            }),\n        );\n    });\n    it('throws when decoding an ASCII encoded message whose message content does not match the length specified in the preamble', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (12 characters)\n                    ...Array.from<number>({ length: 12 }).fill(0x21 /* exclamation point */), \n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH, {\n                actualLength: 12,\n                specifiedLength: 11,\n            }),\n        );\n    });\n    it('decodes a well-formed 1232-byte-max UTF-8 message according to spec', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 1232-byte-max)\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (✌🏿cool)\n                    0xe2, 0x9c, 0x8c, 0xf0, 0x9f, 0x8f, 0xbf, 0x63, 0x6f, 0x6f, 0x6c,\n            ]);\n        expect(decoder.decode(encodedMessage)).toStrictEqual({\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text: '✌🏿cool',\n            },\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        });\n    });\n    it('throws when decoding a 1232-byte-max UTF-8 message whose message content length is zero', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 1232-byte-max)\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (0 characters)\n                0x00, 0x00,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY),\n        );\n    });\n    it('throws when decoding a 1232-byte-max UTF-8 message whose message content is too long', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 1232-byte-max)\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (1232 + 1 characters)\n                0xd1, 0x04,\n                    // Message\n                    ...Array.from<number>({ length: 1232 + 1 }).fill(0x21 /* exclamation point */), \n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n                actualBytes: 1232 + 1,\n                maxBytes: 1232,\n            }),\n        );\n    });\n    it('throws when decoding a 1232-byte-max UTF-8 message whose message content does not match the length specified in the preamble', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 1232-byte-max)\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (12 characters)\n                    ...Array.from<number>({ length: 12 }).fill(0x21 /* exclamation point */), \n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH, {\n                actualLength: 12,\n                specifiedLength: 11,\n            }),\n        );\n    });\n    it('decodes a well-formed 65535-byte-max UTF-8 message according to spec', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 65535-byte-max)\n                0x02,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (✌🏿cool)\n                    0xe2, 0x9c, 0x8c, 0xf0, 0x9f, 0x8f, 0xbf, 0x63, 0x6f, 0x6f, 0x6c,\n            ]);\n        expect(decoder.decode(encodedMessage)).toStrictEqual({\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text: '✌🏿cool',\n            },\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        });\n    });\n    it('throws when decoding a 65535-byte-max UTF-8 message whose message content length is zero', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 65535-byte-max)\n                0x02,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (0 characters)\n                0x00, 0x00,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY),\n        );\n    });\n    it('throws when decoding a 65535-byte-max UTF-8 message whose message content does not match the length specified in the preamble', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 65535-byte-max)\n                0x02,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (12 characters)\n                    ...Array.from<number>({ length: 12 }).fill(0x21 /* exclamation point */), \n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH, {\n                actualLength: 12,\n                specifiedLength: 11,\n            }),\n        );\n    });\n});\n\ndescribe('getOffchainMessageEncoder()', () => {\n    let encoder: VariableSizeEncoder<OffchainMessageV0>;\n    beforeEach(() => {\n        encoder = getOffchainMessageV0Encoder();\n    });\n    it('encodes a well-formed ASCII encoded message according to spec', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: 'Hello world',\n            } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(encoder.encode(offchainMessage)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]),\n        );\n    });\n    it('throws when encoding an ASCII encoded message whose application domain is not base58', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: '0'.repeat(32) as OffchainMessageApplicationDomain,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: 'Hello world',\n            } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',\n                base: 58,\n                value: '0'.repeat(32),\n            }),\n        );\n    });\n    it.each([31, 45])(\n        'throws when encoding an ASCII encoded message whose application domain is %s characters',\n        length => {\n            const offchainMessage: OffchainMessageV0 = {\n                applicationDomain: '1'.repeat(length) as OffchainMessageApplicationDomain,\n                content: {\n                    format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                    text: 'Hello world',\n                } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n                requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n                version: 0,\n            };\n            expect(() => encoder.encode(offchainMessage)).toThrow(\n                new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE, {\n                    actualLength: length,\n                }),\n            );\n        },\n    );\n    it.each([\n        [31, 'tVojvhToWjQ8Xvo4UPx2Xz9eRy7auyYMmZBjc2XfN'],\n        [33, 'JJEfe6DcPM2ziB2vfUWDV6aHVerXRGkv3TcyvJUNGHZz'],\n    ])(\n        'throws when encoding an ASCII encoded message whose application domain encodes to have %s bytes',\n        (actualLength, applicationDomain) => {\n            const offchainMessage: OffchainMessageV0 = {\n                applicationDomain: applicationDomain as OffchainMessageApplicationDomain,\n                content: {\n                    format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                    text: 'Hello world',\n                } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n                requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n                version: 0,\n            };\n            expect(() => encoder.encode(offchainMessage)).toThrow(\n                new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH, {\n                    actualLength,\n                }),\n            );\n        },\n    );\n    it('throws when encoding an ASCII encoded message with a non-zero version', () => {\n        const offchainMessage = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: 'Hello world',\n            } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 1,\n        };\n        expect(() => encoder.encode(offchainMessage as unknown as OffchainMessageV0)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION, {\n                actualVersion: 1,\n                expectedVersion: 0,\n            }),\n        );\n    });\n    it('throws when encoding an ASCII encoded message with an unsupported version', () => {\n        const offchainMessage = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: 'Hello world',\n            } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 255,\n        };\n        expect(() => encoder.encode(offchainMessage as unknown as OffchainMessageV0)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: 255,\n            }),\n        );\n    });\n    it('throws when encoding an ASCII encoded message with no required signers', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: 'Hello world',\n            } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n            requiredSignatories: [],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO),\n        );\n    });\n    it('throws when encoding an ASCII encoded message whose message content is outside the restricted set', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '\\t',\n            } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE),\n        );\n    });\n    it('throws when encoding an ASCII encoded message whose message content length is zero', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '',\n            } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY),\n        );\n    });\n    it('throws when encoding an ASCII encoded message whose message content is too long', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n                text: '!'.repeat(1232 + 1),\n            } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n                actualBytes: 1232 + 1,\n                maxBytes: 1232,\n            }),\n        );\n    });\n    it('encodes a well-formed 1232-byte-max UTF-8 message according to spec', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text: '✌🏿cool',\n            } as OffchainMessageContentUtf8Of1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(encoder.encode(offchainMessage)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 1232-byte-max)\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (✌🏿cool)\n                    0xe2, 0x9c, 0x8c, 0xf0, 0x9f, 0x8f, 0xbf, 0x63, 0x6f, 0x6f, 0x6c,\n            ]),\n        );\n    });\n    it('throws when encoding a 1232-byte-max UTF-8 message whose message content length is zero', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text: '',\n            } as OffchainMessageContentUtf8Of1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY),\n        );\n    });\n    it('throws when encoding a 1232-byte-max UTF-8 message whose message content is too long', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n                text: '\\t'.repeat(1232 + 1),\n            } as OffchainMessageContentUtf8Of1232BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n                actualBytes: 1232 + 1,\n                maxBytes: 1232,\n            }),\n        );\n    });\n    it('encodes a well-formed 65535-byte-max UTF-8 message according to spec', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text: '✌🏿cool',\n            } as OffchainMessageContentUtf8Of65535BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(encoder.encode(offchainMessage)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (UTF-8, 65535-byte-max)\n                0x02,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (✌🏿cool)\n                    0xe2, 0x9c, 0x8c, 0xf0, 0x9f, 0x8f, 0xbf, 0x63, 0x6f, 0x6f, 0x6c,\n            ]),\n        );\n    });\n    it('throws when encoding a 65535-byte-max UTF-8 message whose message content length is zero', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text: '',\n            } as OffchainMessageContentUtf8Of65535BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY),\n        );\n    });\n    it('throws when encoding a 65535-byte-max UTF-8 message whose message content is too long', () => {\n        const offchainMessage: OffchainMessageV0 = {\n            applicationDomain: APPLICATION_DOMAIN,\n            content: {\n                format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n                text: '\\t'.repeat(65535 + 1),\n            } as OffchainMessageContentUtf8Of65535BytesMax,\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n                actualBytes: 65535 + 1,\n                maxBytes: 65535,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/offchain-messages/src/__tests__/message-v1-codec-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array, VariableSizeDecoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getBase16Decoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_CONSTANT,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED,\n    SolanaError,\n} from '@solana/errors';\n\nimport { getOffchainMessageV1Decoder, getOffchainMessageV1Encoder } from '../codecs/message-v1';\nimport { OffchainMessageV1 } from '../message-v1';\n\n// The string `'\\xffsolana offchain'`\nconst OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES: ReadonlyUint8Array = new Uint8Array([\n    0xff, 0x73, 0x6f, 0x6c, 0x61, 0x6e, 0x61, 0x20, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,\n]);\n\nconst SIGNER_A =\n    'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address<'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'>;\nconst SIGNER_A_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x55, 0x0e, 0x94, 0xc7, 0x25, 0x63, 0x9a, 0x4b, 0xd1, 0x1d, 0x4e, 0xa5, 0xa6, 0x38,\n    0x36, 0x51, 0xc3, 0x08, 0xb7, 0x18, 0xc3, 0xae, 0xf2, 0x86, 0xbc, 0xa1, 0xaf,\n]);\nconst SIGNER_B =\n    'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address<'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'>;\nconst SIGNER_B_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x5c, 0x95, 0xef, 0xb9, 0x72, 0xc0, 0xc5, 0xb7, 0xae, 0x0f, 0xd5, 0x20, 0xd9, 0x7e,\n    0x94, 0x8f, 0xd8, 0xbb, 0x2c, 0x10, 0xa1, 0x01, 0x02, 0xce, 0x98, 0xb3, 0xa6,\n]);\n\ndescribe('getOffchainMessageV1Decoder()', () => {\n    let decoder: VariableSizeDecoder<OffchainMessageV1>;\n    beforeEach(() => {\n        decoder = getOffchainMessageV1Decoder();\n    });\n    it('decodes a well-formed message according to spec', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message (Hello\\nworld)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0A, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(decoder.decode(encodedMessage)).toStrictEqual({\n            content: 'Hello\\nworld',\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 1,\n        });\n    });\n    it('freezes the decoded message', () => {\n        expect.assertions(5);\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message (Hello\\nworld)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0A, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        const decodedMessage = decoder.decode(encodedMessage);\n        expect(decodedMessage).toBeFrozenObject();\n        expect(decodedMessage.content).toBeFrozenObject();\n        expect(decodedMessage.requiredSignatories).toBeFrozenObject();\n        decodedMessage.requiredSignatories.forEach(signer => expect(signer).toBeFrozenObject());\n    });\n    it('throws when decoding an encoded message with a malformed signing domain', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain (malformed)\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES.toReversed(),\n                // Version\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message (horizontal tab character)\n                    0x09,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_CONSTANT, {\n                constant: OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                data: encodedMessage,\n                hexConstant: getBase16Decoder().decode(OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES),\n                hexData: getBase16Decoder().decode(encodedMessage),\n                offset: 0,\n            }),\n        );\n    });\n    it('throws when decoding an message with a version other than 1', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message (Hello\\nworld)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0A, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION, {\n                actualVersion: 0,\n                expectedVersion: 1,\n            }),\n        );\n    });\n    it('throws when decoding an message with duplicate signatories', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_A_BYTES,\n                // Message (Hello\\nworld)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0A, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE),\n        );\n    });\n    it('throws when decoding an message with an unsupported version', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0xFF,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message (Hello\\nworld)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0A, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: 255,\n            }),\n        );\n    });\n    it('throws when decoding an message whose required signers length is zero', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x00,\n                // Message (Hello\\nworld)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0A, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO),\n        );\n    });\n    it('throws when decoding a message whose message content length is zero', () => {\n        const encodedMessage =\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n            ]);\n        expect(() => decoder.decode(encodedMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY),\n        );\n    });\n});\n\ndescribe('getOffchainMessageEncoder()', () => {\n    let encoder: VariableSizeEncoder<OffchainMessageV1>;\n    beforeEach(() => {\n        encoder = getOffchainMessageV1Encoder();\n    });\n    it('encodes a well-formed message according to spec', () => {\n        const offchainMessage: OffchainMessageV1 = {\n            content: 'Hello\\nworld',\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 1,\n        };\n        expect(encoder.encode(offchainMessage)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message (Hello\\nworld)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0A, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]),\n        );\n    });\n    it('encodes a well-formed UTF-8 message according to spec', () => {\n        const offchainMessage: OffchainMessageV1 = {\n            content: '✌🏿cool',\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 1,\n        };\n        expect(encoder.encode(offchainMessage)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message (✌🏿cool)\n                    0xe2, 0x9c, 0x8c, 0xf0, 0x9f, 0x8f, 0xbf, 0x63, 0x6f, 0x6f, 0x6c,\n            ]),\n        );\n    });\n    it('throws when encoding an message with a version other than 1', () => {\n        const offchainMessage = {\n            content: 'Hello\\nworld',\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 0,\n        };\n        expect(() => encoder.encode(offchainMessage as unknown as OffchainMessageV1)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION, {\n                actualVersion: 0,\n                expectedVersion: 1,\n            }),\n        );\n    });\n    it('throws when encoding an message with an unsupported version', () => {\n        const offchainMessage = {\n            content: 'Hello\\nworld',\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 255,\n        };\n        expect(() => encoder.encode(offchainMessage as unknown as OffchainMessageV1)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: 255,\n            }),\n        );\n    });\n    it('throws when encoding an message with no required signers', () => {\n        const offchainMessage: OffchainMessageV1 = {\n            content: 'Hello\\nworld',\n            requiredSignatories: [],\n            version: 1,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO),\n        );\n    });\n    it('throws when encoding an message whose message content length is zero', () => {\n        const offchainMessage: OffchainMessageV1 = {\n            content: '',\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_B }],\n            version: 1,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY),\n        );\n    });\n    it('throws when there are duplicate signatories', () => {\n        const offchainMessage: OffchainMessageV1 = {\n            content: 'Hello\\nworld',\n            requiredSignatories: [{ address: SIGNER_A }, { address: SIGNER_A }],\n            version: 1,\n        };\n        expect(() => encoder.encode(offchainMessage)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE),\n        );\n    });\n    it('sorts the signatories in lexicographical order in the output', () => {\n        const offchainMessage: OffchainMessageV1 = {\n            content: 'Hello\\nworld',\n            requiredSignatories:\n                // Out of order in the JS array\n                [{ address: SIGNER_B }, { address: SIGNER_A }],\n            version: 1,\n        };\n        expect(encoder.encode(offchainMessage)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x02,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                // Message (Hello\\nWorld)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x0A, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/offchain-messages/src/__tests__/preamble-test.ts",
    "content": "import { getSignatoriesComparator } from '../codecs/preamble-common';\n\ndescribe('getSignatoriesComparator', () => {\n    function arr(a: ArrayLike<number>) {\n        return new Uint8Array(a);\n    }\n    it('sorts byte arrays lexicographically', () => {\n        expect(\n            [\n                arr([0, 0]),\n                arr([1]),\n                arr([1, 1, 0]),\n                arr([0, 1, 0]),\n                arr([0, 0, 0]),\n                arr([1, 1, 1]),\n                arr([0]),\n                arr([0, 1, 1]),\n                arr([0, 0, 1]),\n            ].toSorted(getSignatoriesComparator()),\n        ).toEqual([\n            arr([0]),\n            arr([1]),\n            arr([0, 0]),\n            arr([0, 0, 0]),\n            arr([0, 0, 1]),\n            arr([0, 1, 0]),\n            arr([0, 1, 1]),\n            arr([1, 1, 0]),\n            arr([1, 1, 1]),\n        ]);\n    });\n});\n"
  },
  {
    "path": "packages/offchain-messages/src/__tests__/signatures-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address, getAddressFromPublicKey, getPublicKeyFromAddress } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_CONSTANT,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes, signBytes, verifySignature } from '@solana/keys';\n\nimport { OffchainMessageEnvelope } from '../envelope';\nimport { OffchainMessageBytes } from '../message';\nimport {\n    assertIsFullySignedOffchainMessageEnvelope,\n    isFullySignedOffchainMessageEnvelope,\n    partiallySignOffchainMessageEnvelope,\n    signOffchainMessageEnvelope,\n    verifyOffchainMessageEnvelope,\n} from '../signatures';\n\njest.mock('@solana/addresses', () => ({\n    ...jest.requireActual('@solana/addresses'),\n    __esModule: true,\n    getAddressFromPublicKey: jest.fn(),\n    getPublicKeyFromAddress: jest.fn(),\n}));\njest.mock('@solana/keys');\n\n// The string `'\\xffsolana offchain'`\nconst OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES: ReadonlyUint8Array = new Uint8Array([\n    0xff, 0x73, 0x6f, 0x6c, 0x61, 0x6e, 0x61, 0x20, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,\n]);\n\nconst APPLICATION_DOMAIN_BYTES = new Uint8Array([\n    0x0d, 0x3b, 0x73, 0x0b, 0x9e, 0x88, 0x9b, 0x4b, 0x66, 0x1e, 0xd2, 0xa3, 0xce, 0x19, 0x1f, 0x68, 0xd3, 0x7d, 0xa7,\n    0x44, 0x32, 0x06, 0xa1, 0x82, 0xb9, 0x46, 0x89, 0x1e, 0x00, 0x00, 0x00, 0x00,\n]);\n\nconst SIGNER_A_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x55, 0x0e, 0x94, 0xc7, 0x25, 0x63, 0x9a, 0x4b, 0xd1, 0x1d, 0x4e, 0xa5, 0xa6, 0x38,\n    0x36, 0x51, 0xc3, 0x08, 0xb7, 0x18, 0xc3, 0xae, 0xf2, 0x86, 0xbc, 0xa1, 0xaf,\n]);\nconst SIGNER_B_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x5c, 0x95, 0xef, 0xb9, 0x72, 0xc0, 0xc5, 0xb7, 0xae, 0x0f, 0xd5, 0x20, 0xd9, 0x7e,\n    0x94, 0x8f, 0xd8, 0xbb, 0x2c, 0x10, 0xa1, 0x01, 0x02, 0xce, 0x98, 0xb3, 0xa6,\n]);\nconst SIGNER_C_BYTES = new Uint8Array([\n    0x0c, 0xfe, 0x2c, 0xc9, 0x52, 0x64, 0x1d, 0x4a, 0xab, 0xc0, 0x1d, 0xf1, 0x23, 0x8b, 0x02, 0x5b, 0x9c, 0x0c, 0xc4,\n    0xf2, 0xcd, 0xee, 0x6d, 0xa1, 0x08, 0x7e, 0x53, 0x13, 0x16, 0x74, 0xc5, 0x9d,\n]);\n\ndescribe('partiallySignOffchainMessageEnvelope', () => {\n    const MOCK_SIGNATURE_A = new Uint8Array(Array(64).fill(1)) as SignatureBytes;\n    const MOCK_SIGNATURE_B = new Uint8Array(Array(64).fill(2)) as SignatureBytes;\n    const MOCK_SIGNATURE_C = new Uint8Array(Array(64).fill(3)) as SignatureBytes;\n    const MOCK_SIGNATURE_D = new Uint8Array(Array(64).fill(3)) as SignatureBytes;\n    const MOCK_SIGNATURE_E = new Uint8Array(Array(64).fill(3)) as SignatureBytes;\n    const mockKeyPairA = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairB = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairC = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairD = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairE = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockPublicKeyAddressA =\n        'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address<'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'>;\n    const mockPublicKeyAddressB =\n        'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address<'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'>;\n    const mockPublicKeyAddressC =\n        'signerCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC' as Address<'signerCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'>;\n    const mockPublicKeyAddressD =\n        'signerDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD' as Address<'signerDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD'>;\n    const mockPublicKeyAddressE =\n        'signerEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE' as Address<'signerEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE'>;\n    const mockEncodedMessage =\n        // prettier-ignore\n        new Uint8Array([\n            // Signing domain\n            ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n            // Version\n            0x00,\n            // Application domain\n            ...APPLICATION_DOMAIN_BYTES,\n            // Message format (Restricted ASCII, 1232-byte-max)\n            0x00,\n            // Signer count\n            0x03,\n                // Signer addresses\n                ...SIGNER_A_BYTES,\n                ...SIGNER_B_BYTES,\n                ...SIGNER_C_BYTES,\n        ]) as ReadonlyUint8Array as OffchainMessageBytes;\n    beforeEach(() => {\n        (getAddressFromPublicKey as jest.Mock).mockImplementation(publicKey => {\n            switch (publicKey) {\n                case mockKeyPairA.publicKey:\n                    return mockPublicKeyAddressA;\n                case mockKeyPairB.publicKey:\n                    return mockPublicKeyAddressB;\n                case mockKeyPairC.publicKey:\n                    return mockPublicKeyAddressC;\n                case mockKeyPairD.publicKey:\n                    return mockPublicKeyAddressD;\n                case mockKeyPairE.publicKey:\n                    return mockPublicKeyAddressE;\n                default:\n                    return '99999999999999999999999999999999' as Address<'99999999999999999999999999999999'>;\n            }\n        });\n        (signBytes as jest.Mock).mockImplementation(secretKey => {\n            switch (secretKey) {\n                case mockKeyPairA.privateKey:\n                    return MOCK_SIGNATURE_A;\n                case mockKeyPairB.privateKey:\n                    return MOCK_SIGNATURE_B;\n                case mockKeyPairC.privateKey:\n                    return MOCK_SIGNATURE_C;\n                case mockKeyPairD.privateKey:\n                    return MOCK_SIGNATURE_D;\n                case mockKeyPairE.privateKey:\n                    return MOCK_SIGNATURE_E;\n                default:\n                    return new Uint8Array(Array(64).fill(0xff));\n            }\n        });\n        (signBytes as jest.Mock).mockClear();\n    });\n    it('fatals when the message bytes do not begin with the signing domain', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content:\n                // prettier-ignore\n                new Uint8Array([\n                    // Trying to trick you into signing a transaction message.\n                    1, 0, 1, 2, 12, 254, 44, 201, 82, 85, 14, 148, 199, 37, 99, 154, 75, 209, 29, 78, 165, 166, 56, 54, 81, 195, 8, 183, 24, 195, 174, 242, 134, 188, 161, 175, 5, 74, 83, 90, 153, 41, 33, 6, 77, 36, 232, 113, 96, 218, 56, 124, 124, 53, 181, 221, 188, 146, 187, 129, 228, 31, 168, 64, 65, 5, 68, 141, 165, 245, 142, 160, 76, 82, 157, 113, 135, 56, 193, 165, 8, 243, 90, 59, 182, 100, 24, 27, 122, 61, 151, 206, 91, 112, 238, 152, 97, 89, 88, 36, 1, 1, 0, 11, 72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100\n                ]) as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        await expect(partiallySignOffchainMessageEnvelope([mockKeyPairD], offchainMessageEnvelope)).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__CODECS__INVALID_CONSTANT, {\n                constant: OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                data: offchainMessageEnvelope.content,\n                hexConstant: 'ff736f6c616e61206f6666636861696e',\n                hexData:\n                    '010001020cfe2cc952550e94c725639a4bd11d4ea5a6383651c308b718c3aef286bca1af054a535a992921064d24e87160da387c7c35b5ddbc92bb81e41fa8404105448da5f58ea04c529d718738c1a508f35a3bb664181b7a3d97ce5b70ee98615958240101000b48656c6c6f20776f726c64',\n                offset: 0,\n            }),\n        );\n    });\n    it(\"returns a signed OffchainMessageEnvelope object having the first signer's signature\", async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n\n        const partiallySignedOffchainMessageEnvelopePromise = partiallySignOffchainMessageEnvelope(\n            [mockKeyPairA],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            }),\n        );\n    });\n    it('returns unchanged compiled message bytes', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = partiallySignOffchainMessageEnvelope(\n            [mockKeyPairA],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'content',\n            mockEncodedMessage,\n        );\n    });\n    it('returns a signed OffchainMessageEnvelope object having null for the missing signers', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n                [mockPublicKeyAddressC]: null,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = partiallySignOffchainMessageEnvelope(\n            [mockKeyPairA],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressB]: null,\n                [mockPublicKeyAddressC]: null,\n            }),\n        );\n    });\n    it(\"returns a OffchainMessageEnvelope object having the second signer's signature\", async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = partiallySignOffchainMessageEnvelope(\n            [mockKeyPairB],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressB]: MOCK_SIGNATURE_B,\n            }),\n        );\n    });\n    it('returns a OffchainMessageEnvelope object having multiple signatures', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n                [mockPublicKeyAddressC]: null,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = partiallySignOffchainMessageEnvelope(\n            [mockKeyPairA, mockKeyPairB, mockKeyPairC],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n                [mockPublicKeyAddressB]: MOCK_SIGNATURE_B,\n                [mockPublicKeyAddressC]: MOCK_SIGNATURE_C,\n            }),\n        );\n    });\n    it('stores the signatures in the order specified on the compiled message', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n                [mockPublicKeyAddressC]: null,\n            },\n        };\n        const { signatures } = await partiallySignOffchainMessageEnvelope(\n            [mockKeyPairC, mockKeyPairB, mockKeyPairA],\n            offchainMessageEnvelope,\n        );\n        const orderedAddresses = Object.keys(signatures);\n        expect(orderedAddresses).toEqual([mockPublicKeyAddressA, mockPublicKeyAddressB, mockPublicKeyAddressC]);\n    });\n    it('does not modify an existing signature when the signature is the same', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = partiallySignOffchainMessageEnvelope(\n            [mockKeyPairB],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            }),\n        );\n    });\n    it('produces a new signature for an existing signer', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            },\n        };\n        await partiallySignOffchainMessageEnvelope([mockKeyPairA], offchainMessageEnvelope);\n        expect(signBytes as jest.Mock).toHaveBeenCalledTimes(1);\n    });\n    it('modifies the existing signature when the signature is different', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: new Uint8Array([1, 2, 3, 4]) as ReadonlyUint8Array as SignatureBytes,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = partiallySignOffchainMessageEnvelope(\n            [mockKeyPairA],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            }),\n        );\n    });\n    it('produces a signature for a new signer when there is an existing one', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = partiallySignOffchainMessageEnvelope(\n            [mockKeyPairB],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressB]: MOCK_SIGNATURE_B,\n            }),\n        );\n    });\n    it('freezes the object', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        await expect(\n            partiallySignOffchainMessageEnvelope([mockKeyPairA], offchainMessageEnvelope),\n        ).resolves.toBeFrozenObject();\n    });\n    it('returns the input OffchainMessageEnvelope object if no signatures changed', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            },\n        };\n        await expect(partiallySignOffchainMessageEnvelope([mockKeyPairA], offchainMessageEnvelope)).resolves.toBe(\n            offchainMessageEnvelope,\n        );\n    });\n    it('throws if a keypair is for an address that is not in the signatures of the OffchainMessageEnvelope', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        await expect(partiallySignOffchainMessageEnvelope([mockKeyPairD], offchainMessageEnvelope)).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE, {\n                expectedAddresses: [mockPublicKeyAddressA],\n                unexpectedAddresses: [mockPublicKeyAddressD],\n            }),\n        );\n    });\n    it('throws with multiple addresses if there are multiple keypairs that are not in the signatures', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        await expect(\n            partiallySignOffchainMessageEnvelope([mockKeyPairD, mockKeyPairE], offchainMessageEnvelope),\n        ).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE, {\n                expectedAddresses: [mockPublicKeyAddressA],\n                unexpectedAddresses: [mockPublicKeyAddressD, mockPublicKeyAddressE],\n            }),\n        );\n    });\n});\n\ndescribe('signOffchainMessageEnvelope', () => {\n    const mockPublicKeyAddressA =\n        'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address<'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'>;\n    const mockPublicKeyAddressB =\n        'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address<'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'>;\n    const MOCK_SIGNATURE_A = new Uint8Array(Array(64).fill(1)) as SignatureBytes;\n    const MOCK_SIGNATURE_B = new Uint8Array(Array(64).fill(2)) as SignatureBytes;\n    const mockKeyPairA = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairB = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockEncodedMessage =\n        // prettier-ignore\n        new Uint8Array([\n            // Signing domain\n            ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n            // Version\n            0x00,\n            // Application domain\n            ...APPLICATION_DOMAIN_BYTES,\n            // Message format (Restricted ASCII, 1232-byte-max)\n            0x00,\n            // Signer count\n            0x02,\n                // Signer addresses\n                ...SIGNER_A_BYTES,\n                ...SIGNER_B_BYTES,\n        ]) as ReadonlyUint8Array as OffchainMessageBytes;\n    beforeEach(() => {\n        (getAddressFromPublicKey as jest.Mock).mockImplementation(publicKey => {\n            switch (publicKey) {\n                case mockKeyPairA.publicKey:\n                    return mockPublicKeyAddressA;\n                case mockKeyPairB.publicKey:\n                    return mockPublicKeyAddressB;\n                default:\n                    return '99999999999999999999999999999999' as Address<'99999999999999999999999999999999'>;\n            }\n        });\n        (signBytes as jest.Mock).mockImplementation(secretKey => {\n            switch (secretKey) {\n                case mockKeyPairA.privateKey:\n                    return MOCK_SIGNATURE_A;\n                case mockKeyPairB.privateKey:\n                    return MOCK_SIGNATURE_B;\n                default:\n                    return new Uint8Array(Array(64).fill(0xff));\n            }\n        });\n    });\n    it('fatals when missing a signer', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const signedOffchainMessageEnvelopePromise = signOffchainMessageEnvelope(\n            [mockKeyPairA],\n            offchainMessageEnvelope,\n        );\n        await expect(signedOffchainMessageEnvelopePromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING, {\n                addresses: [mockPublicKeyAddressB],\n            }),\n        );\n    });\n    it('returns a signed OffchainMessageEnvelope object with multiple signatures', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = signOffchainMessageEnvelope(\n            [mockKeyPairA, mockKeyPairB],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n                [mockPublicKeyAddressB]: MOCK_SIGNATURE_B,\n            }),\n        );\n    });\n    it('returns a signed OffchainMessageEnvelope object with the compiled message bytes', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedOffchainMessageEnvelopePromise = signOffchainMessageEnvelope(\n            [mockKeyPairA, mockKeyPairB],\n            offchainMessageEnvelope,\n        );\n        await expect(partiallySignedOffchainMessageEnvelopePromise).resolves.toHaveProperty(\n            'content',\n            mockEncodedMessage,\n        );\n    });\n    it('stores the signatures in the order specified on the compiled message', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const { signatures } = await signOffchainMessageEnvelope([mockKeyPairB, mockKeyPairA], offchainMessageEnvelope);\n        const orderedAddresses = Object.keys(signatures);\n        expect(orderedAddresses).toEqual([mockPublicKeyAddressA, mockPublicKeyAddressB]);\n    });\n    it('freezes the object', async () => {\n        expect.assertions(1);\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: mockEncodedMessage,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        await expect(\n            signOffchainMessageEnvelope([mockKeyPairA, mockKeyPairB], offchainMessageEnvelope),\n        ).resolves.toBeFrozenObject();\n    });\n});\n\ndescribe('isFullySignedOffchainMessageEnvelope', () => {\n    const mockPublicKeyAddressA = 'A' as Address;\n    const mockSignatureA = new Uint8Array(0) as SignatureBytes;\n    const mockPublicKeyAddressB = 'B' as Address;\n    const mockSignatureB = new Uint8Array(1) as SignatureBytes;\n\n    it('returns false if the OffchainMessageEnvelope has missing signatures', () => {\n        const signatures: OffchainMessageEnvelope['signatures'] = {};\n        signatures[mockPublicKeyAddressA] = null;\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures,\n        };\n\n        expect(isFullySignedOffchainMessageEnvelope(offchainMessageEnvelope)).toBe(false);\n    });\n\n    it('returns true if the OffchainMessageEnvelope is signed by all its signers', () => {\n        const signatures: OffchainMessageEnvelope['signatures'] = {};\n        signatures[mockPublicKeyAddressA] = mockSignatureA;\n        signatures[mockPublicKeyAddressB] = mockSignatureB;\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures,\n        };\n\n        expect(isFullySignedOffchainMessageEnvelope(offchainMessageEnvelope)).toBe(true);\n    });\n\n    it('return true if the OffchainMessageEnvelope has no signatures', () => {\n        const signatures: OffchainMessageEnvelope['signatures'] = {};\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures,\n        };\n\n        expect(isFullySignedOffchainMessageEnvelope(offchainMessageEnvelope)).toBe(true);\n    });\n});\n\ndescribe('assertIsFullySignedOffchainMessageEnvelope', () => {\n    const mockPublicKeyAddressA = 'A' as Address;\n    const mockSignatureA = new Uint8Array(0) as SignatureBytes;\n    const mockPublicKeyAddressB = 'B' as Address;\n    const mockSignatureB = new Uint8Array(1) as SignatureBytes;\n\n    it('throws all missing signers if the OffchainMessageEnvelope has no signature for multiple signers', () => {\n        const signatures: OffchainMessageEnvelope['signatures'] = {};\n        signatures[mockPublicKeyAddressA] = null;\n        signatures[mockPublicKeyAddressB] = null;\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures,\n        };\n\n        expect(() => assertIsFullySignedOffchainMessageEnvelope(offchainMessageEnvelope)).toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING, {\n                addresses: [mockPublicKeyAddressA, mockPublicKeyAddressB],\n            }),\n        );\n    });\n\n    it('does not throw if the OffchainMessageEnvelope is signed by its only signer', () => {\n        const signatures: OffchainMessageEnvelope['signatures'] = {};\n        signatures[mockPublicKeyAddressA] = mockSignatureA;\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures,\n        };\n\n        expect(() => assertIsFullySignedOffchainMessageEnvelope(offchainMessageEnvelope)).not.toThrow();\n    });\n\n    it('does not throw if the OffchainMessageEnvelope is signed by all its signers', () => {\n        const signatures: OffchainMessageEnvelope['signatures'] = {};\n        signatures[mockPublicKeyAddressA] = mockSignatureA;\n        signatures[mockPublicKeyAddressB] = mockSignatureB;\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures,\n        };\n\n        expect(() => assertIsFullySignedOffchainMessageEnvelope(offchainMessageEnvelope)).not.toThrow();\n    });\n\n    it('does not throw if the OffchainMessageEnvelope has no signatures', () => {\n        const signatures: OffchainMessageEnvelope['signatures'] = {};\n        const offchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as ReadonlyUint8Array as OffchainMessageBytes,\n            signatures,\n        };\n        expect(() => assertIsFullySignedOffchainMessageEnvelope(offchainMessageEnvelope)).not.toThrow();\n    });\n});\n\ndescribe('verifyOffchainMessageEnvelope', () => {\n    const mockPublicKeyAddressA =\n        'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address<'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'>;\n    const mockPublicKeyAddressB =\n        'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address<'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'>;\n    const mockPublicKeyAddressC =\n        'signerCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC' as Address<'signerCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'>;\n    const mockKeyPairA = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairB = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairC = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockValidSignatureA = new Uint8Array(64) as SignatureBytes;\n    const mockValidSignatureB = new Uint8Array(64) as SignatureBytes;\n    const mockValidSignatureC = new Uint8Array(64) as SignatureBytes;\n    const mockInvalidSignature = new Uint8Array(64) as SignatureBytes;\n    beforeEach(() => {\n        (getPublicKeyFromAddress as jest.Mock).mockImplementation(address => {\n            switch (address) {\n                case mockPublicKeyAddressA:\n                    return mockKeyPairA.publicKey;\n                case mockPublicKeyAddressB:\n                    return mockKeyPairB.publicKey;\n                case mockPublicKeyAddressC:\n                    return mockKeyPairC.publicKey;\n                default:\n                    return { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n            }\n        });\n        (verifySignature as jest.Mock).mockImplementation((publicKey, signature) => {\n            switch (signature) {\n                case mockValidSignatureA:\n                    return publicKey === mockKeyPairA.publicKey;\n                case mockValidSignatureB:\n                    return publicKey === mockKeyPairB.publicKey;\n                case mockValidSignatureC:\n                    return publicKey === mockKeyPairC.publicKey;\n                default:\n                    return false;\n            }\n        });\n    });\n    describe.each([\n        [\n            'v0',\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x00,\n                // Application domain\n                ...APPLICATION_DOMAIN_BYTES,\n                // Message format (Restricted ASCII, 1232-byte-max)\n                0x00,\n                // Signer count\n                0x03,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                    ...SIGNER_C_BYTES,\n                // Message length (11 characters)\n                0x0b, 0x00,\n                    // Message (Hello world)\n                    0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]) as ReadonlyUint8Array as OffchainMessageBytes,\n        ],\n        [\n            'v1',\n            // prettier-ignore\n            new Uint8Array([\n                // Signing domain\n                ...OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES,\n                // Version\n                0x01,\n                // Signer count\n                0x03,\n                    // Signer addresses\n                    ...SIGNER_A_BYTES,\n                    ...SIGNER_B_BYTES,\n                    ...SIGNER_C_BYTES,\n                // Message (Hello world)\n                0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n            ]) as ReadonlyUint8Array as OffchainMessageBytes,\n        ],\n    ])('given a %s message', (_, content) => {\n        it('returns when a valid signature is supplied for every required signatory', async () => {\n            expect.assertions(1);\n            const valid = verifyOffchainMessageEnvelope({\n                content,\n                signatures: {\n                    [mockPublicKeyAddressA]: mockValidSignatureA,\n                    [mockPublicKeyAddressB]: mockValidSignatureB,\n                    [mockPublicKeyAddressC]: mockValidSignatureC,\n                },\n            });\n            await expect(valid).resolves.toBeUndefined();\n        });\n        it('throws when when a signature is invalid or missing', async () => {\n            expect.assertions(1);\n            const valid = verifyOffchainMessageEnvelope({\n                content,\n                signatures: {\n                    [mockPublicKeyAddressA]: mockInvalidSignature,\n                    // `mockPublicKeyAddressB` missing from the signatures map altogether.\n                    [mockPublicKeyAddressC]: null,\n                },\n            });\n            await expect(valid).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE, {\n                    signatoriesWithInvalidSignatures: [mockPublicKeyAddressA],\n                    signatoriesWithMissingSignatures: [mockPublicKeyAddressB, mockPublicKeyAddressC],\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/offchain-messages/src/__typetests__/message-codec-typetest.ts",
    "content": "import { ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { getOffchainMessageDecoder, getOffchainMessageEncoder } from '../codecs/message';\nimport { OffchainMessage } from '../message';\nimport { OffchainMessageV0 } from '../message-v0';\nimport { OffchainMessageV1 } from '../message-v1';\n\n// [DESCRIBE] getOffchainMessageEncoder.\n{\n    // It is compatible with messages of unknown version\n    {\n        const message = null as unknown as OffchainMessage;\n        getOffchainMessageEncoder().encode(message);\n    }\n\n    // It is compatible with version 0 messages\n    {\n        const message = null as unknown as OffchainMessageV0;\n        getOffchainMessageEncoder().encode(message);\n    }\n\n    // It is compatible with version 1 messages\n    {\n        const message = null as unknown as OffchainMessageV1;\n        getOffchainMessageEncoder().encode(message);\n    }\n\n    // It returns a `ReadonlyUint8Array`\n    {\n        const message = null as unknown as OffchainMessage;\n        const bytes = getOffchainMessageEncoder().encode(message);\n        bytes satisfies ReadonlyUint8Array;\n    }\n}\n\n// [DESCRIBE] getOffchainMessageDecoder.\n{\n    // It returns an `OffchainMessage`\n    {\n        const message = getOffchainMessageDecoder().decode(new Uint8Array([]));\n        message satisfies OffchainMessage;\n    }\n\n    // It returns a message that is the union of all versions; no particular version\n    {\n        const message = getOffchainMessageDecoder().decode(new Uint8Array([]));\n        message satisfies OffchainMessage;\n        // @ts-expect-error It's unclear until refined what version message you decoded.\n        message satisfies OffchainMessageV0;\n        // @ts-expect-error It's unclear until refined what version message you decoded.\n        message satisfies OffchainMessageV1;\n    }\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/__typetests__/message-typetest.ts",
    "content": "import { OffchainMessage } from '../message';\nimport { OffchainMessageV0 } from '../message-v0';\nimport { OffchainMessageV1 } from '../message-v1';\n\n// [DESCRIBE] `OffchainMessage`.\n{\n    // Can be refined by asserting on its version number\n    {\n        const message = null as unknown as OffchainMessage;\n        // @ts-expect-error It's unclear until refined what version message you decoded.\n        message satisfies OffchainMessageV0;\n        if (message.version === 0) {\n            message satisfies OffchainMessageV0;\n        }\n        // @ts-expect-error It's unclear until refined what version message you decoded.\n        message satisfies OffchainMessageV1;\n        if (message.version === 1) {\n            message satisfies OffchainMessageV1;\n        }\n    }\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/__typetests__/message-v0-codec-typetest.ts",
    "content": "import { ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { getOffchainMessageV0Decoder, getOffchainMessageV0Encoder } from '../codecs/message-v0';\nimport { OffchainMessage } from '../message';\nimport { OffchainMessageV0 } from '../message-v0';\n\n// [DESCRIBE] getOffchainMessageV0Encoder.\n{\n    // It is incompatible with messages where the version is unknown\n    {\n        const message = null as unknown as OffchainMessage;\n        // @ts-expect-error It's unclear until refined what version message you decoded.\n        getOffchainMessageV0Encoder().encode(message);\n    }\n\n    // It returns a `ReadonlyUint8Array`\n    {\n        const message = null as unknown as OffchainMessageV0;\n        const bytes = getOffchainMessageV0Encoder().encode(message);\n        bytes satisfies ReadonlyUint8Array;\n    }\n}\n\n// [DESCRIBE] getOffchainMessageV0Decoder.\n{\n    // It returns an `OffchainMessage` of version 0\n    {\n        const message = getOffchainMessageV0Decoder().decode(new Uint8Array([]));\n        message satisfies OffchainMessage;\n        message satisfies OffchainMessageV0;\n    }\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/__typetests__/message-v1-codec-typetest.ts",
    "content": "import { ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { getOffchainMessageV1Decoder, getOffchainMessageV1Encoder } from '../codecs/message-v1';\nimport { OffchainMessage } from '../message';\nimport { OffchainMessageV1 } from '../message-v1';\n\n// [DESCRIBE] getOffchainMessageV1Encoder.\n{\n    // It is incompatible with messages where the version is unknown\n    {\n        const message = null as unknown as OffchainMessage;\n        // @ts-expect-error It's unclear until refined what version message you decoded.\n        getOffchainMessageV1Encoder().encode(message);\n    }\n\n    // It returns a `ReadonlyUint8Array`\n    {\n        const message = null as unknown as OffchainMessageV1;\n        const bytes = getOffchainMessageV1Encoder().encode(message);\n        bytes satisfies ReadonlyUint8Array;\n    }\n}\n\n// [DESCRIBE] getOffchainMessageV1Decoder.\n{\n    // It returns an `OffchainMessage` of version 1\n    {\n        const message = getOffchainMessageV1Decoder().decode(new Uint8Array([]));\n        message satisfies OffchainMessage;\n        message satisfies OffchainMessageV1;\n    }\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/application-domain.ts",
    "content": "import { assertIsAddress, isAddress } from '@solana/addresses';\nimport {\n    isSolanaError,\n    SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH,\n    SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\n/**\n * A 32-byte array identifying the application requesting off-chain message signing.\n *\n * This may be any arbitrary bytes. For instance the on-chain address of a program, DAO instance,\n * Candy Machine, et cetera.\n *\n * This field SHOULD be displayed to users as a base58-encoded ASCII string rather than interpreted\n * otherwise.\n */\nexport type OffchainMessageApplicationDomain = Brand<\n    EncodedString<string, 'base58'>,\n    'OffchainMessageApplicationDomain'\n>;\n\n/**\n * A type guard that returns `true` if the input string conforms to the\n * {@link OffchainMessageApplicationDomain} type, and refines its type for use in your program.\n *\n * @example\n * ```ts\n * import { isOffchainMessageApplicationDomain, OffchainMessageV0 } from '@solana/offchain-messages';\n *\n * if (isOffchainMessageApplicationDomain(applicationDomain)) {\n *     // At this point, `applicationDomain` has been refined to an\n *     // `OffchainMessageApplcationDomain` that can be used to craft a message.\n *     const offchainMessage: OffchainMessageV0 = {\n *         applicationDomain:\n *             offchainMessageApplicationDomain('HgHLLXT3BVA5m7x66tEp3YNatXLth1hJwVeCva2T9RNx'),\n *             // ...\n *     };\n * } else {\n *     setError(`${applicationDomain} is not a valid application domain for an offchain message`);\n * }\n * ```\n */\nexport function isOffchainMessageApplicationDomain(\n    putativeApplicationDomain: string,\n): putativeApplicationDomain is OffchainMessageApplicationDomain {\n    return isAddress(putativeApplicationDomain);\n}\n\n/**\n * From time to time you might acquire a string, that you expect to validate as an offchain message\n * application domain, from an untrusted network API or user input. Use this function to assert that\n * such an arbitrary string is a base58-encoded application domain.\n *\n * @example\n * ```ts\n * import { assertIsOffchainMessageApplicationDomain, OffchainMessageV0 } from '@solana/offchain-messages';\n *\n * // Imagine a function that determines whether an application domain is valid.\n * function handleSubmit() {\n *     // We know only that what the user typed conforms to the `string` type.\n *     const applicationDomain: string = applicationDomainInput.value;\n *     try {\n *         // If this type assertion function doesn't throw, then\n *         // Typescript will upcast `applicationDomain` to `OffchainMessageApplicationDomain`.\n *         assertIsOffchainMessageApplicationDomain(applicationDomain);\n *         // At this point, `applicationDomain` is a `OffchainMessageApplicationDomain` that can be\n *         // used to craft an offchain message.\n *         const offchainMessage: OffchainMessageV0 = {\n *             applicationDomain:\n *                 offchainMessageApplicationDomain('HgHLLXT3BVA5m7x66tEp3YNatXLth1hJwVeCva2T9RNx'),\n *             // ...\n *         };\n *     } catch (e) {\n *         // `applicationDomain` turned out not to be a base58-encoded application domain\n *     }\n * }\n * ```\n */\nexport function assertIsOffchainMessageApplicationDomain(\n    putativeApplicationDomain: string,\n): asserts putativeApplicationDomain is OffchainMessageApplicationDomain {\n    try {\n        assertIsAddress(putativeApplicationDomain);\n    } catch (error) {\n        if (isSolanaError(error, SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE)) {\n            throw new SolanaError(\n                SOLANA_ERROR__OFFCHAIN_MESSAGE__APPLICATION_DOMAIN_STRING_LENGTH_OUT_OF_RANGE,\n                error.context,\n            );\n        }\n        if (isSolanaError(error, SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH)) {\n            throw new SolanaError(\n                SOLANA_ERROR__OFFCHAIN_MESSAGE__INVALID_APPLICATION_DOMAIN_BYTE_LENGTH,\n                error.context,\n            );\n        }\n        throw error;\n    }\n}\n\n/**\n * Combines _asserting_ that a string is an offchain message application domain with _coercing_ it\n * to the {@link OffchainMessageApplicationDomain} type. It's most useful with untrusted input.\n *\n * @example\n * ```ts\n * import { offchainMessageApplicationDomain, OffchainMessageV0 } from '@solana/offchain-messages';\n *\n * const offchainMessage: OffchainMessageV0 = {\n *     applicationDomain:\n *         offchainMessageApplicationDomain('HgHLLXT3BVA5m7x66tEp3YNatXLth1hJwVeCva2T9RNx'),\n *     // ...\n * };\n * ```\n *\n * > [!TIP]\n * > When starting from a known-good application domain as a string, it's more efficient to typecast\n * > it rather than to use the {@link offchainMessageApplicationDomain} helper, because the helper\n * > unconditionally performs validation on its input.\n * >\n * > ```ts\n * > import { OffchainMessageApplicationDomain } from '@solana/offchain-messages';\n * >\n * > const applicationDomain =\n * >     'HgHLLXT3BVA5m7x66tEp3YNatXLth1hJwVeCva2T9RNx' as OffchainMessageApplicationDomain;\n * > ```\n */\nexport function offchainMessageApplicationDomain(putativeApplicationDomain: string): OffchainMessageApplicationDomain {\n    assertIsOffchainMessageApplicationDomain(putativeApplicationDomain);\n    return putativeApplicationDomain;\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/application-domain.ts",
    "content": "import { Address, getAddressDecoder, getAddressEncoder } from '@solana/addresses';\nimport {\n    combineCodec,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformEncoder,\n} from '@solana/codecs-core';\n\nimport { OffchainMessageApplicationDomain, offchainMessageApplicationDomain } from '../application-domain';\n\n/**\n * Returns an encoder that you can use to encode a base58-encoded offchain message application\n * domain to a byte array.\n *\n * @example\n * ```ts\n * import { getOffchainMessageApplicationDomainEncoder } from '@solana/offchain-messages';\n *\n * const offchainMessageApplicationDomain =\n *     'HgHLLXT3BVA5m7x66tEp3YNatXLth1hJwVeCva2T9RNx' as OffchainMessageApplicationDomain;\n * const offchainMessageApplicationDomainEncoder = getOffchainMessageApplicationDomainEncoder();\n * const offchainMessageApplicationDomainBytes =\n *     offchainMessageApplicationDomainEncoder.encode(offchainMessageApplicationDomain);\n * // Uint8Array(32) [\n * //   247, 203,  28,  80,  52, 240, 169,  19,\n * //    21, 103, 107, 119,  91, 235,  13,  48,\n * //   194, 169, 148, 160,  78, 105, 235,  37,\n * //   232, 160,  49,  47,  64,  89,  18, 153,\n * // ]\n * ```\n */\nexport function getOffchainMessageApplicationDomainEncoder(): FixedSizeEncoder<OffchainMessageApplicationDomain, 32> {\n    return transformEncoder(\n        getAddressEncoder(),\n        putativeApplicationDomain => offchainMessageApplicationDomain(putativeApplicationDomain) as string as Address,\n    );\n}\n\n/**\n * Returns a decoder that you can use to convert an array of 32 bytes representing an offchain\n * message application domain to the base58-encoded representation of that application domain.\n *\n * @example\n * ```ts\n * import { getOffchainMessageApplicationDomainDecoder } from '@solana/offchain-messages';\n *\n * const offchainMessageApplicationDomainBytes = new Uint8Array([\n *     247, 203,  28,  80,  52, 240, 169,  19,\n *      21, 103, 107, 119,  91, 235,  13,  48,\n *     194, 169, 148, 160,  78, 105, 235,  37,\n *     232, 160,  49,  47,  64,  89,  18, 153,\n * ]);\n * const offchainMessageApplicationDomainDecoder = getOffchainMessageApplicationDomainDecoder();\n * const offchainMessageApplicationDomain =\n *     offchainMessageApplicationDomainDecoder.decode(offchainMessageApplicationDomainBytes);\n *     // HgHLLXT3BVA5m7x66tEp3YNatXLth1hJwVeCva2T9RNx\n * ```\n */\nexport function getOffchainMessageApplicationDomainDecoder(): FixedSizeDecoder<OffchainMessageApplicationDomain, 32> {\n    return getAddressDecoder() as FixedSizeDecoder<string, 32> as FixedSizeDecoder<\n        OffchainMessageApplicationDomain,\n        32\n    >;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a base-58 encoded offchain message\n * application domain.\n *\n * @see {@link getOffchainMessageApplicationDomainDecoder}\n * @see {@link getOffchainMessageApplicationDomainEncoder}\n */\nexport function getOffchainMessageApplicationDomainCodec(): FixedSizeCodec<\n    OffchainMessageApplicationDomain,\n    OffchainMessageApplicationDomain,\n    32\n> {\n    return combineCodec(getOffchainMessageApplicationDomainEncoder(), getOffchainMessageApplicationDomainDecoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/content.ts",
    "content": "import { combineCodec, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\nimport { getEnumDecoder, getEnumEncoder } from '@solana/codecs-data-structures';\n\nimport { OffchainMessageContentFormat } from '../content';\n\nexport function getOffchainMessageContentFormatDecoder(): FixedSizeDecoder<OffchainMessageContentFormat, 1> {\n    return getEnumDecoder(OffchainMessageContentFormat, {\n        useValuesAsDiscriminators: true,\n    });\n}\n\nexport function getOffchainMessageContentFormatEncoder(): FixedSizeEncoder<OffchainMessageContentFormat, 1> {\n    return getEnumEncoder(OffchainMessageContentFormat, {\n        useValuesAsDiscriminators: true,\n    });\n}\n\nexport function getOffchainMessageContentFormatCodec(): FixedSizeCodec<\n    OffchainMessageContentFormat,\n    OffchainMessageContentFormat,\n    1\n> {\n    return combineCodec(getOffchainMessageContentFormatEncoder(), getOffchainMessageContentFormatDecoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/envelope.ts",
    "content": "import { Address, address } from '@solana/addresses';\nimport {\n    combineCodec,\n    fixDecoderSize,\n    ReadonlyUint8Array,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    getArrayDecoder,\n    getBytesDecoder,\n    getBytesEncoder,\n    getStructDecoder,\n    getStructEncoder,\n} from '@solana/codecs-data-structures';\nimport { getU8Decoder } from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { OffchainMessageEnvelope } from '../envelope';\nimport { OffchainMessageBytes } from '../message';\nimport { decodeRequiredSignatoryAddresses } from './preamble-common';\nimport { getSignaturesEncoder } from './signatures';\n\n/**\n * Returns an encoder that you can use to encode an {@link OffchainMessageEnvelope} to a byte array\n * appropriate for sharing with a third party for validation.\n */\nexport function getOffchainMessageEnvelopeEncoder(): VariableSizeEncoder<OffchainMessageEnvelope> {\n    return transformEncoder(\n        getStructEncoder([\n            ['signatures', getSignaturesEncoder()],\n            ['content', getBytesEncoder()],\n        ]),\n        envelope => {\n            const signaturesMapAddresses = Object.keys(envelope.signatures).map(address);\n            if (signaturesMapAddresses.length === 0) {\n                throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO);\n            }\n            const signatoryAddresses = decodeAndValidateRequiredSignatoryAddresses(envelope.content);\n            const missingRequiredSigners = [];\n            const unexpectedSigners = [];\n            for (const address of signatoryAddresses) {\n                if (!signaturesMapAddresses.includes(address)) {\n                    missingRequiredSigners.push(address);\n                }\n            }\n            for (const address of signaturesMapAddresses) {\n                if (!signatoryAddresses.includes(address)) {\n                    unexpectedSigners.push(address);\n                }\n            }\n            if (missingRequiredSigners.length || unexpectedSigners.length) {\n                throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__ENVELOPE_SIGNERS_MISMATCH, {\n                    missingRequiredSigners,\n                    unexpectedSigners,\n                });\n            }\n            const orderedSignatureMap: OffchainMessageEnvelope['signatures'] = {};\n            for (const address of signatoryAddresses) {\n                orderedSignatureMap[address] = envelope.signatures[address];\n            }\n            return {\n                ...envelope,\n                signatures: orderedSignatureMap,\n            };\n        },\n    );\n}\n\n/**\n * Returns a decoder that you can use to convert a byte array in the Solana offchain message format\n * to a {@link OffchainMessageEnvelope} object.\n *\n * @example\n * ```ts\n * import { getOffchainMessageEnvelopeDecoder } from '@solana/offchain-messages';\n *\n * const offchainMessageEnvelopeDecoder = getOffchainMessageEnvelopeDecoder();\n * const offchainMessageEnvelope = offchainMessageEnvelopeDecoder.decode(offchainMessageEnvelopeBytes);\n * for (const [address, signature] in Object.entries(offchainMessageEnvelope.signatures)) {\n *     console.log(`Signature by ${address}`, signature);\n * }\n * ```\n */\nexport function getOffchainMessageEnvelopeDecoder(): VariableSizeDecoder<OffchainMessageEnvelope> {\n    return transformDecoder(\n        getStructDecoder([\n            ['signatures', getArrayDecoder(fixDecoderSize(getBytesDecoder(), 64), { size: getU8Decoder() })],\n            ['content', getBytesDecoder()],\n        ]),\n        decodePartiallyDecodedOffchainMessageEnvelope,\n    );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to an {@link OffchainMessageEnvelope}\n *\n * @see {@link getOffchainMessageEnvelopeDecoder}\n * @see {@link getOffchainMessageEnvelopeEncoder}\n */\nexport function getOffchainMessageEnvelopeCodec() {\n    return combineCodec(getOffchainMessageEnvelopeEncoder(), getOffchainMessageEnvelopeDecoder());\n}\n\ntype PartiallyDecodedOffchainMessageEnvelope = {\n    content: ReadonlyUint8Array;\n    signatures: ReadonlyUint8Array[];\n};\n\nfunction decodePartiallyDecodedOffchainMessageEnvelope(\n    offchainMessageEnvelope: PartiallyDecodedOffchainMessageEnvelope,\n): OffchainMessageEnvelope {\n    const { content, signatures } = offchainMessageEnvelope;\n\n    if (signatures.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO);\n    }\n\n    const signatoryAddresses = decodeAndValidateRequiredSignatoryAddresses(content);\n\n    // Signer addresses and signatures must be the same length\n    // We encode an all-zero signature when the signature is missing\n    if (signatoryAddresses.length !== signatures.length) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_SIGNATURES_MISMATCH, {\n            numRequiredSignatures: signatoryAddresses.length,\n            signatoryAddresses,\n            signaturesLength: signatures.length,\n        });\n    }\n\n    // Combine the signer addresses + signatures into the signatures map\n    const signaturesMap: OffchainMessageEnvelope['signatures'] = {};\n    signatoryAddresses.forEach((address, index) => {\n        const signatureForAddress = signatures[index];\n        if (signatureForAddress.every(b => b === 0)) {\n            signaturesMap[address] = null;\n        } else {\n            signaturesMap[address] = signatureForAddress as SignatureBytes;\n        }\n    });\n\n    return Object.freeze({\n        content: content as OffchainMessageBytes,\n        signatures: Object.freeze(signaturesMap),\n    });\n}\n\nfunction decodeAndValidateRequiredSignatoryAddresses(bytes: ReadonlyUint8Array): readonly Address[] {\n    const signatoryAddresses = decodeRequiredSignatoryAddresses(bytes);\n\n    if (signatoryAddresses.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);\n    }\n\n    return signatoryAddresses;\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/message-v0.ts",
    "content": "import {\n    combineCodec,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getTupleDecoder, getTupleEncoder } from '@solana/codecs-data-structures';\nimport { getUtf8Decoder, getUtf8Encoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH,\n    SolanaError,\n} from '@solana/errors';\n\nimport { OffchainMessageContentFormat } from '../content';\nimport {\n    assertIsOffchainMessageRestrictedAsciiOf1232BytesMax,\n    assertIsOffchainMessageUtf8Of1232BytesMax,\n    assertIsOffchainMessageUtf8Of65535BytesMax,\n    OffchainMessageV0,\n} from '../message-v0';\nimport { getOffchainMessageV0PreambleDecoder, getOffchainMessageV0PreambleEncoder } from './preamble-v0';\n\n/**\n * Returns a decoder that you can use to convert a byte array (eg. one that conforms to the\n * {@link OffchainMessageBytes} type) to an {@link OffchainMessageV0} object.\n *\n * @example\n * ```ts\n * import { getOffchainMessageV0Decoder } from '@solana/offchain-messages';\n *\n * const offchainMessageDecoder = getOffchainMessageV0Decoder();\n * const offchainMessage = offchainMessageDecoder.decode(\n *     offchainMessageEnvelope.content,\n * );\n * console.log(`Decoded a v0 offchain message`);\n * ```\n *\n * Throws in the event that the message bytes represent a message of a version other than 0.\n */\nexport function getOffchainMessageV0Decoder(): VariableSizeDecoder<OffchainMessageV0> {\n    return transformDecoder(\n        getTupleDecoder([getOffchainMessageV0PreambleDecoder(), getUtf8Decoder()]),\n        ([{ messageLength, messageFormat, requiredSignatories, ...preambleRest }, text]) => {\n            const actualLength = getUtf8Encoder().getSizeFromValue(text);\n            if (messageLength !== actualLength) {\n                throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_LENGTH_MISMATCH, {\n                    actualLength: actualLength,\n                    specifiedLength: messageLength,\n                });\n            }\n            const offchainMessage: Omit<OffchainMessageV0, 'content'> &\n                Readonly<{\n                    content: {\n                        format: OffchainMessageContentFormat;\n                        text: string;\n                    };\n                }> = Object.freeze({\n                ...preambleRest,\n                content: Object.freeze({\n                    format: messageFormat,\n                    text,\n                }),\n                requiredSignatories: Object.freeze(requiredSignatories),\n            });\n            switch (messageFormat) {\n                case OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX: {\n                    assertIsOffchainMessageRestrictedAsciiOf1232BytesMax(offchainMessage);\n                    return offchainMessage;\n                }\n                case OffchainMessageContentFormat.UTF8_1232_BYTES_MAX: {\n                    assertIsOffchainMessageUtf8Of1232BytesMax(offchainMessage);\n                    return offchainMessage;\n                }\n                case OffchainMessageContentFormat.UTF8_65535_BYTES_MAX: {\n                    assertIsOffchainMessageUtf8Of65535BytesMax(offchainMessage);\n                    return offchainMessage;\n                }\n                default: {\n                    throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, {\n                        unexpectedValue: messageFormat satisfies never,\n                    });\n                }\n            }\n        },\n    );\n}\n\n/**\n * Returns an encoder that you can use to encode an {@link OffchainMessageV0} to a byte array\n * appropriate for inclusion in an {@link OffchainMessageEnvelope}.\n */\nexport function getOffchainMessageV0Encoder(): VariableSizeEncoder<OffchainMessageV0> {\n    return transformEncoder(\n        getTupleEncoder([getOffchainMessageV0PreambleEncoder(), getUtf8Encoder()]),\n        offchainMessage => {\n            const { content, ...preamble } = offchainMessage;\n            switch (offchainMessage.content.format) {\n                case OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX: {\n                    assertIsOffchainMessageRestrictedAsciiOf1232BytesMax(offchainMessage);\n                    break;\n                }\n                case OffchainMessageContentFormat.UTF8_1232_BYTES_MAX: {\n                    assertIsOffchainMessageUtf8Of1232BytesMax(offchainMessage);\n                    break;\n                }\n                case OffchainMessageContentFormat.UTF8_65535_BYTES_MAX: {\n                    assertIsOffchainMessageUtf8Of65535BytesMax(offchainMessage);\n                    break;\n                }\n                default: {\n                    throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, {\n                        unexpectedValue: offchainMessage.content satisfies never,\n                    });\n                }\n            }\n            const messageLength = getUtf8Encoder().getSizeFromValue(content.text);\n            const compiledPreamble = {\n                ...preamble,\n                messageFormat: content.format,\n                messageLength,\n            };\n            return [compiledPreamble, content.text] as const;\n        },\n    );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to an {@link OffchainMessageV0}\n *\n * @see {@link getOffchainMessageV0Decoder}\n * @see {@link getOffchainMessageV0Encoder}\n */\nexport function getOffchainMessageV0Codec(): VariableSizeCodec<OffchainMessageV0> {\n    return combineCodec(getOffchainMessageV0Encoder(), getOffchainMessageV0Decoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/message-v1.ts",
    "content": "import {\n    combineCodec,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getTupleDecoder, getTupleEncoder } from '@solana/codecs-data-structures';\nimport { getUtf8Decoder, getUtf8Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY, SolanaError } from '@solana/errors';\n\nimport { OffchainMessageV1 } from '../message-v1';\nimport { getOffchainMessageV1PreambleDecoder, getOffchainMessageV1PreambleEncoder } from './preamble-v1';\n\n/**\n * Returns a decoder that you can use to convert a byte array (eg. one that conforms to the\n * {@link OffchainMessageBytes} type) to an {@link OffchainMessageV1} object.\n *\n * @example\n * ```ts\n * import { getOffchainMessageV1Decoder } from '@solana/offchain-messages';\n *\n * const offchainMessageDecoder = getOffchainMessageV1Decoder();\n * const offchainMessage = offchainMessageDecoder.decode(\n *     offchainMessageEnvelope.content,\n * );\n * console.log(`Decoded a v1 offchain message`);\n * ```\n *\n * Throws in the event that the message bytes represent a message of a version other than 1.\n */\nexport function getOffchainMessageV1Decoder(): VariableSizeDecoder<OffchainMessageV1> {\n    return transformDecoder(\n        getTupleDecoder([getOffchainMessageV1PreambleDecoder(), getUtf8Decoder()]),\n        ([{ requiredSignatories, ...preambleRest }, text]) => {\n            if (text.length === 0) {\n                throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);\n            }\n            return Object.freeze({\n                ...preambleRest,\n                content: text,\n                requiredSignatories: Object.freeze(requiredSignatories),\n            });\n        },\n    );\n}\n\n/**\n * Returns an encoder that you can use to encode an {@link OffchainMessageV1} to a byte array\n * appropriate for inclusion in an {@link OffchainMessageEnvelope}.\n */\nexport function getOffchainMessageV1Encoder(): VariableSizeEncoder<OffchainMessageV1> {\n    return transformEncoder(\n        getTupleEncoder([getOffchainMessageV1PreambleEncoder(), getUtf8Encoder()]),\n        offchainMessage => {\n            const { content, ...compiledPreamble } = offchainMessage;\n            if (content.length === 0) {\n                throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);\n            }\n            return [compiledPreamble, content] as const;\n        },\n    );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to an {@link OffchainMessageV1}\n *\n * @see {@link getOffchainMessageV1Decoder}\n * @see {@link getOffchainMessageV1Encoder}\n */\nexport function getOffchainMessageV1Codec(): VariableSizeCodec<OffchainMessageV1> {\n    return combineCodec(getOffchainMessageV1Encoder(), getOffchainMessageV1Decoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/message.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getHiddenPrefixDecoder } from '@solana/codecs-data-structures';\nimport { getU8Decoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport { OffchainMessage } from '../message';\nimport { getOffchainMessageV0Decoder, getOffchainMessageV0Encoder } from './message-v0';\nimport { getOffchainMessageV1Decoder, getOffchainMessageV1Encoder } from './message-v1';\nimport { getOffchainMessageSigningDomainDecoder } from './signing-domain';\n\n/**\n * Returns a decoder that you can use to convert a byte array (eg. one that conforms to the\n * {@link OffchainMessageBytes} type) to an {@link OffchainMessage} object.\n *\n * @example\n * ```ts\n * import { getOffchainMessageDecoder } from '@solana/offchain-messages';\n *\n * const offchainMessageDecoder = getOffchainMessageDecoder();\n * const offchainMessage = offchainMessageDecoder.decode(\n *     offchainMessageEnvelope.content,\n * );\n * console.log(`Decoded an offchain message (version: ${offchainMessage.version}`);\n * ```\n *\n * @remarks\n * If the offchain message version is known ahead of time, use one of the decoders specific to that\n * version so as not to bundle more code than you need.\n */\nexport function getOffchainMessageDecoder(): VariableSizeDecoder<OffchainMessage> {\n    return createDecoder({\n        read(bytes, offset): [OffchainMessage, number] {\n            const version = getHiddenPrefixDecoder(getU8Decoder(), [\n                // Discard the signing domain\n                getOffchainMessageSigningDomainDecoder(),\n            ]).decode(bytes, offset);\n            switch (version) {\n                case 0:\n                    return getOffchainMessageV0Decoder().read(bytes, offset);\n                case 1:\n                    return getOffchainMessageV1Decoder().read(bytes, offset);\n                default:\n                    throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                        unsupportedVersion: version,\n                    });\n            }\n        },\n    });\n}\n\n/**\n * Returns an encoder that you can use to encode an {@link OffchainMessage} to a byte array\n * appropriate for inclusion in an {@link OffchainMessageEnvelope}.\n *\n * @remarks\n * If the offchain message version is known ahead of time, use one of the encoders specific to that\n * version so as not to bundle more code than you need.\n */\nexport function getOffchainMessageEncoder(): VariableSizeEncoder<OffchainMessage> {\n    return createEncoder({\n        getSizeFromValue: offchainMessage => {\n            const { version } = offchainMessage;\n            switch (version) {\n                case 0:\n                    return getOffchainMessageV0Encoder().getSizeFromValue(offchainMessage);\n                case 1:\n                    return getOffchainMessageV1Encoder().getSizeFromValue(offchainMessage);\n                default:\n                    throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                        unsupportedVersion: version satisfies never,\n                    });\n            }\n        },\n        write: (offchainMessage, bytes, offset) => {\n            const { version } = offchainMessage;\n            switch (version) {\n                case 0:\n                    return getOffchainMessageV0Encoder().write(offchainMessage, bytes, offset);\n                case 1:\n                    return getOffchainMessageV1Encoder().write(offchainMessage, bytes, offset);\n                default:\n                    throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                        unsupportedVersion: version satisfies never,\n                    });\n            }\n        },\n    });\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to an {@link OffchainMessage}\n *\n * @see {@link getOffchainMessageDecoder}\n * @see {@link getOffchainMessageEncoder}\n *\n * @remarks\n * If the offchain message version is known ahead of time, use one of the codecs specific to that\n * version so as not to bundle more code than you need.\n */\nexport function getOffchainMessageCodec(): VariableSizeCodec<OffchainMessage> {\n    return combineCodec(getOffchainMessageEncoder(), getOffchainMessageDecoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/preamble-common.ts",
    "content": "import { Address, getAddressDecoder } from '@solana/addresses';\nimport {\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    offsetDecoder,\n    ReadonlyUint8Array,\n    transformDecoder,\n    transformEncoder,\n} from '@solana/codecs-core';\nimport {\n    getArrayDecoder,\n    getBytesDecoder,\n    getHiddenPrefixDecoder,\n    getHiddenPrefixEncoder,\n    getStructDecoder,\n    getStructEncoder,\n} from '@solana/codecs-data-structures';\nimport { getU8Decoder, getU8Encoder } from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED,\n    SolanaError,\n} from '@solana/errors';\n\nimport { OffchainMessageVersion } from '../version';\nimport { getOffchainMessageSigningDomainDecoder, getOffchainMessageSigningDomainEncoder } from './signing-domain';\n\ntype TDecoderFields = Parameters<typeof getStructDecoder>[0];\ntype TEncoderFields = Parameters<typeof getStructEncoder>[0];\n\nfunction getSigningDomainPrefixedDecoder<const T extends TDecoderFields>(...fields: T) {\n    return getHiddenPrefixDecoder(getStructDecoder(fields), [getOffchainMessageSigningDomainDecoder()]);\n}\n\nfunction getSigningDomainPrefixedEncoder<const T extends TEncoderFields>(...fields: T) {\n    return getHiddenPrefixEncoder(getStructEncoder(fields), [getOffchainMessageSigningDomainEncoder()]);\n}\n\nfunction getVersionTransformer(fixedVersion?: OffchainMessageVersion) {\n    return (version: number) => {\n        if (version > 1) {\n            throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n                unsupportedVersion: version,\n            });\n        }\n        if (fixedVersion != null && version !== fixedVersion) {\n            throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__UNEXPECTED_VERSION, {\n                actualVersion: version,\n                expectedVersion: fixedVersion,\n            });\n        }\n        return version;\n    };\n}\n\nexport function createOffchainMessagePreambleDecoder<\n    const TVersion extends OffchainMessageVersion,\n    const TFields extends TDecoderFields,\n>(version: TVersion, ...fields: TFields) {\n    return getSigningDomainPrefixedDecoder(\n        ['version', transformDecoder(getU8Decoder(), getVersionTransformer(version)) as FixedSizeDecoder<TVersion, 1>],\n        ...fields,\n    );\n}\n\nexport function createOffchainMessagePreambleEncoder<\n    const TVersion extends OffchainMessageVersion,\n    const TFields extends TEncoderFields,\n>(version: TVersion, ...fields: TFields) {\n    return getSigningDomainPrefixedEncoder(\n        ['version', transformEncoder(getU8Encoder(), getVersionTransformer(version)) as FixedSizeEncoder<TVersion, 1>],\n        ...fields,\n    );\n}\n\nexport function decodeRequiredSignatoryAddresses(bytes: ReadonlyUint8Array): readonly Address[] {\n    const { version, bytesAfterVersion } = getSigningDomainPrefixedDecoder(\n        ['version', transformDecoder(getU8Decoder(), getVersionTransformer())],\n        ['bytesAfterVersion', getBytesDecoder()],\n    ).decode(bytes);\n    return offsetDecoder(\n        transformDecoder(getArrayDecoder(getAddressDecoder(), { size: getU8Decoder() }), signatoryAddresses => {\n            if (signatoryAddresses.length === 0) {\n                throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);\n            }\n            return signatoryAddresses;\n        }),\n        {\n            preOffset: ({ preOffset }) =>\n                preOffset +\n                (version === 0\n                    ? 32 + 1 // skip the application domain and message format of v0 messages\n                    : 0),\n        },\n    ).decode(bytesAfterVersion);\n}\n\nexport function getSignatoriesComparator(): (a: ReadonlyUint8Array, b: ReadonlyUint8Array) => -1 | 0 | 1 {\n    return (x, y) => {\n        if (x.length !== y.length) {\n            return x.length < y.length ? -1 : 1;\n        }\n        for (let ii = 0; ii < x.length; ii++) {\n            if (x[ii] === y[ii]) {\n                continue;\n            } else {\n                return x[ii] < y[ii] ? -1 : 1;\n            }\n        }\n        return 0;\n    };\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/preamble-v0.ts",
    "content": "import { getAddressDecoder, getAddressEncoder } from '@solana/addresses';\nimport {\n    combineCodec,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder } from '@solana/codecs-data-structures';\nimport { getU8Decoder, getU8Encoder, getU16Decoder, getU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO, SolanaError } from '@solana/errors';\n\nimport { OffchainMessagePreambleV0 } from '../preamble-v0';\nimport {\n    getOffchainMessageApplicationDomainDecoder,\n    getOffchainMessageApplicationDomainEncoder,\n} from './application-domain';\nimport { getOffchainMessageContentFormatDecoder, getOffchainMessageContentFormatEncoder } from './content';\nimport { createOffchainMessagePreambleDecoder, createOffchainMessagePreambleEncoder } from './preamble-common';\n\nexport function getOffchainMessageV0PreambleDecoder(): VariableSizeDecoder<OffchainMessagePreambleV0> {\n    return createOffchainMessagePreambleDecoder(\n        /* version */ 0,\n        ['applicationDomain', getOffchainMessageApplicationDomainDecoder()],\n        ['messageFormat', getOffchainMessageContentFormatDecoder()],\n        [\n            'requiredSignatories',\n            transformDecoder(getArrayDecoder(getAddressDecoder(), { size: getU8Decoder() }), signatoryAddresses => {\n                if (signatoryAddresses.length === 0) {\n                    throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);\n                }\n                return signatoryAddresses.map(address => Object.freeze({ address }));\n            }),\n        ],\n        ['messageLength', getU16Decoder()],\n    );\n}\n\nexport function getOffchainMessageV0PreambleEncoder(): VariableSizeEncoder<OffchainMessagePreambleV0> {\n    return createOffchainMessagePreambleEncoder(\n        /* version */ 0,\n        ['applicationDomain', getOffchainMessageApplicationDomainEncoder()],\n        ['messageFormat', getOffchainMessageContentFormatEncoder()],\n        [\n            'requiredSignatories',\n            transformEncoder(\n                getArrayEncoder(getAddressEncoder(), { size: getU8Encoder() }),\n                (signatoryAddresses: OffchainMessagePreambleV0['requiredSignatories']) => {\n                    if (signatoryAddresses.length === 0) {\n                        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);\n                    }\n                    return signatoryAddresses.map(({ address }) => address);\n                },\n            ),\n        ],\n        ['messageLength', getU16Encoder()],\n    );\n}\n\nexport function getOffchainMessageV0PreambleCodec(): VariableSizeCodec<OffchainMessagePreambleV0> {\n    return combineCodec(getOffchainMessageV0PreambleEncoder(), getOffchainMessageV0PreambleDecoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/preamble-v1.ts",
    "content": "import { getAddressDecoder, getAddressEncoder } from '@solana/addresses';\nimport {\n    combineCodec,\n    fixDecoderSize,\n    ReadonlyUint8Array,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder, getBytesDecoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getU8Decoder, getU8Encoder } from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_SORTED,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { OffchainMessagePreambleV1 } from '../preamble-v1';\nimport {\n    createOffchainMessagePreambleDecoder,\n    createOffchainMessagePreambleEncoder,\n    getSignatoriesComparator,\n} from './preamble-common';\n\nexport function getOffchainMessageV1PreambleDecoder(): VariableSizeDecoder<OffchainMessagePreambleV1> {\n    return createOffchainMessagePreambleDecoder(/* version */ 1, [\n        'requiredSignatories',\n        transformDecoder(\n            getArrayDecoder(fixDecoderSize(getBytesDecoder(), 32), { size: getU8Decoder() }),\n            signatoryAddressesBytes => {\n                if (signatoryAddressesBytes.length === 0) {\n                    throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);\n                }\n                const comparator = getSignatoriesComparator();\n                for (let ii = 0; ii < signatoryAddressesBytes.length - 1; ii++) {\n                    switch (comparator(signatoryAddressesBytes[ii], signatoryAddressesBytes[ii + 1])) {\n                        case 0:\n                            throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE);\n                        case 1:\n                            throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_SORTED);\n                    }\n                }\n                const addressDecoder = getAddressDecoder();\n                return signatoryAddressesBytes.map(addressBytes =>\n                    Object.freeze({\n                        address: addressDecoder.decode(addressBytes),\n                    }),\n                );\n            },\n        ),\n    ]);\n}\n\nexport function getOffchainMessageV1PreambleEncoder(): VariableSizeEncoder<OffchainMessagePreambleV1> {\n    return createOffchainMessagePreambleEncoder(/* version */ 1, [\n        'requiredSignatories',\n        transformEncoder(\n            transformEncoder(\n                getArrayEncoder(getBytesEncoder(), { size: getU8Encoder() }),\n                (signatoryAddressesBytes: readonly ReadonlyUint8Array[]) => {\n                    return signatoryAddressesBytes.toSorted(getSignatoriesComparator());\n                },\n            ),\n            (signatoryAddresses: OffchainMessagePreambleV1['requiredSignatories']) => {\n                if (signatoryAddresses.length === 0) {\n                    throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_REQUIRED_SIGNERS_CANNOT_BE_ZERO);\n                }\n                const seenSignatories = new Set();\n                for (const { address } of signatoryAddresses) {\n                    if (seenSignatories.has(address)) {\n                        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATORIES_MUST_BE_UNIQUE);\n                    }\n                    seenSignatories.add(address);\n                }\n                const addressEncoder = getAddressEncoder();\n                return signatoryAddresses.map(({ address }) => addressEncoder.encode(address));\n            },\n        ),\n    ]);\n}\n\nexport function getOffchainMessageV1PreambleCodec(): VariableSizeCodec<OffchainMessagePreambleV1> {\n    return combineCodec(getOffchainMessageV1PreambleEncoder(), getOffchainMessageV1PreambleDecoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/signatures.ts",
    "content": "import { fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getU8Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { OffchainMessageEnvelope } from '../envelope';\n\nfunction getSignaturesToEncode(signaturesMap: OffchainMessageEnvelope['signatures']): SignatureBytes[] {\n    const signatures = Object.values(signaturesMap);\n    if (signatures.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__NUM_ENVELOPE_SIGNATURES_CANNOT_BE_ZERO);\n    }\n\n    return signatures.map(signature => {\n        if (!signature) {\n            return new Uint8Array(64).fill(0) as SignatureBytes;\n        }\n        return signature;\n    });\n}\n\nexport function getSignaturesEncoder(): VariableSizeEncoder<OffchainMessageEnvelope['signatures']> {\n    return transformEncoder(\n        getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getU8Encoder() }),\n        getSignaturesToEncode,\n    );\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/signing-domain.ts",
    "content": "import {\n    combineCodec,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    ReadonlyUint8Array,\n} from '@solana/codecs-core';\nimport { getConstantDecoder, getConstantEncoder } from '@solana/codecs-data-structures';\n\n// The string `'\\xffsolana offchain'`\nconst OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES: ReadonlyUint8Array = new Uint8Array([\n    0xff, 0x73, 0x6f, 0x6c, 0x61, 0x6e, 0x61, 0x20, 0x6f, 0x66, 0x66, 0x63, 0x68, 0x61, 0x69, 0x6e,\n]);\n\nexport function getOffchainMessageSigningDomainDecoder(): FixedSizeDecoder<void, 16> {\n    return getConstantDecoder(OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES) as FixedSizeDecoder<void, 16>;\n}\n\nexport function getOffchainMessageSigningDomainEncoder(): FixedSizeEncoder<void, 16> {\n    return getConstantEncoder(OFFCHAIN_MESSAGE_SIGNING_DOMAIN_BYTES) as FixedSizeEncoder<void, 16>;\n}\n\nexport function getOffchainMessageSigningDomainCodec(): FixedSizeCodec<void, void, 16> {\n    return combineCodec(getOffchainMessageSigningDomainEncoder(), getOffchainMessageSigningDomainDecoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/codecs/version.ts",
    "content": "import {\n    combineCodec,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n} from '@solana/codecs-core';\nimport { getU8Decoder, getU8Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport { OffchainMessageVersion } from '../version';\n\nfunction assertOffchainMessageVersion(putativeVersion: number): asserts putativeVersion is OffchainMessageVersion {\n    if (putativeVersion !== 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__VERSION_NUMBER_NOT_SUPPORTED, {\n            unsupportedVersion: putativeVersion,\n        });\n    }\n}\n\n/**\n * Returns an encoder that you can use to encode an {@link OffchainMessageVersion} to a byte array.\n */\nexport function getOffchainMessageVersionEncoder(): FixedSizeEncoder<OffchainMessageVersion, 1> {\n    return transformEncoder(getU8Encoder(), version => {\n        assertOffchainMessageVersion(version);\n        return version;\n    });\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing an\n * {@link OffchainMessageVersion}.\n */\nexport function getOffchainMessageVersionDecoder(): FixedSizeDecoder<OffchainMessageVersion> {\n    return transformDecoder(getU8Decoder(), value => {\n        assertOffchainMessageVersion(value);\n        return value;\n    });\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to an {@link OffchainMessageVersion}\n *\n * @see {@link getOffchainMessageVersionDecoder}\n * @see {@link getOffchainMessageVersionEncoder}\n */\nexport function getOffchainMessageVersionCodec(): FixedSizeCodec<OffchainMessageVersion> {\n    return combineCodec(getOffchainMessageVersionEncoder(), getOffchainMessageVersionDecoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/content.ts",
    "content": "import { getUtf8Encoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\nimport { Brand } from '@solana/nominal-types';\n\nconst MAX_BODY_BYTES =\n    // Largest 16-bit unsigned integer\n    0xffff;\nconst MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE =\n    // Space remaining in the mininum IPv6 MTU after network header overhead\n    1232;\n\n/**\n * A restriction on what characters the message text can contain and how long it can be.\n *\n * The aim of this restriction is to make a message more likely to be signable by a hardware wallet\n * that imposes limits on message size. In the case of wanting a message to be clear-signable,\n * restricting the character set to ASCII may ensure that certain models of hardware wallet without\n * extended character sets can display it onscreen.\n *\n * @remarks This only applies to v0 messages.\n */\nexport enum OffchainMessageContentFormat {\n    RESTRICTED_ASCII_1232_BYTES_MAX = 0,\n    UTF8_1232_BYTES_MAX = 1,\n    UTF8_65535_BYTES_MAX = 2,\n}\n\n/**\n * Describes message text that is no more than 1232 bytes long and made up of characters with ASCII\n * character codes in the range [0x20, 0x7e].\n *\n * @remarks This type aims to restrict text to that which can be clear-signed by hardware wallets\n * that can only display ASCII characters onscreen.\n */\nexport type OffchainMessageContentRestrictedAsciiOf1232BytesMax<TContent extends string = string> = Readonly<{\n    format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX;\n    text: Brand<TContent, 'offchainMessageContentRestrictedAsciiOf1232BytesMax'>;\n}>;\n\n/**\n * Describes message text that is no more than 1232 bytes long and mdae up of any UTF-8 characters.\n */\nexport type OffchainMessageContentUtf8Of1232BytesMax<TContent extends string = string> = Readonly<{\n    format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX;\n    text: Brand<TContent, 'offchainMessageContentUtf8Of1232BytesMax'>;\n}>;\n\n/**\n * Describes message text that is no more than 65535 bytes long and mdae up of any UTF-8 characters.\n */\nexport type OffchainMessageContentUtf8Of65535BytesMax<TContent extends string = string> = Readonly<{\n    format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX;\n    text: Brand<TContent, 'offchainMessageContentUtf8Of65535BytesMax'>;\n}>;\n\nexport type OffchainMessageContent =\n    | OffchainMessageContentRestrictedAsciiOf1232BytesMax\n    | OffchainMessageContentUtf8Of1232BytesMax\n    | OffchainMessageContentUtf8Of65535BytesMax;\n\n/**\n * In the event that you receive content of a v0 offchain message from an untrusted source, use this\n * function to assert that it conforms to the\n * {@link OffchainMessageContentRestrictedAsciiOf1232BytesMax} type.\n *\n * @see {@link OffchainMessageContentRestrictedAsciiOf1232BytesMax} for more detail.\n */\nexport function assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax(putativeContent: {\n    format: OffchainMessageContentFormat;\n    text: string;\n}): asserts putativeContent is OffchainMessageContentRestrictedAsciiOf1232BytesMax {\n    if (putativeContent.format !== OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {\n            actualMessageFormat: putativeContent.format,\n            expectedMessageFormat: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n        });\n    }\n    if (putativeContent.text.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);\n    }\n    if (isTextRestrictedAscii(putativeContent.text) === false) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__RESTRICTED_ASCII_BODY_CHARACTER_OUT_OF_RANGE);\n    }\n    const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);\n    if (length > MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n            actualBytes: length,\n            maxBytes: MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE,\n        });\n    }\n}\n\n/**\n * A type guard that returns `true` when supplied content of a v0 offchain message that conforms to\n * the {@link OffchainMessageContentRestrictedAsciiOf1232BytesMax} type, and refines its type for use in your\n * program.\n *\n * @see {@link OffchainMessageContentRestrictedAsciiOf1232BytesMax} for more detail.\n */\nexport function isOffchainMessageContentRestrictedAsciiOf1232BytesMax(putativeContent: {\n    format: OffchainMessageContentFormat;\n    text: string;\n}): putativeContent is OffchainMessageContentRestrictedAsciiOf1232BytesMax {\n    if (\n        putativeContent.format !== OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX ||\n        putativeContent.text.length === 0 ||\n        isTextRestrictedAscii(putativeContent.text) === false\n    ) {\n        return false;\n    }\n    const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);\n    return length <= MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE;\n}\n\n/**\n * Combines _asserting_ that the content of a v0 offchain message is restricted ASCII with\n * _coercing_ it to the {@link OffchainMessageContentRestrictedAsciiOf1232BytesMax} type. It's most\n * useful with untrusted input.\n *\n * @example\n * ```ts\n * import { offchainMessageContentRestrictedAsciiOf1232BytesMax, OffchainMessageV0 } from '@solana/offchain-messages';\n *\n * function handleSubmit() {\n *     // We know only that what the user typed conforms to the `string` type.\n *     const text: string = textInput.value;\n *     try {\n *         const offchainMessage: OffchainMessageV0 = {\n *             content: offchainMessageContentRestrictedAsciiOf1232BytesMax(text),\n *             // ...\n *         };\n *     } catch (e) {\n *         // `text` turned out not to conform to\n *         // `OffchainMessageContentRestrictedAsciiOf1232BytesMax`\n *     }\n * }\n * ```\n *\n * > [!TIP]\n * > When starting from known-good ASCII content as a string, it's more efficient to typecast it\n * > rather than to use the {@link offchainMessageContentRestrictedAsciiOf1232BytesMax} helper,\n * > because the helper unconditionally performs validation on its input.\n * >\n * > ```ts\n * > import { OffchainMessageContentFormat, OffchainMessageV0 } from '@solana/offchain-messages';\n * >\n * > const offchainMessage: OffchainMessageV0 = {\n * >     /* ... *\\/\n * >     content: Object.freeze({\n * >         format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n * >         text: 'Hello world',\n * >     } as OffchainMessageContentRestrictedAsciiOf1232BytesMax<'Hello world'>),\n * > };\n * > ```\n */\nexport function offchainMessageContentRestrictedAsciiOf1232BytesMax<TText extends string>(\n    text: TText,\n): OffchainMessageContentRestrictedAsciiOf1232BytesMax<TText> {\n    const putativeContent = Object.freeze({\n        format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n        text,\n    });\n    assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax(putativeContent);\n    return putativeContent;\n}\n\n/**\n * In the event that you receive content of a v0 offchain message from an untrusted source, use this\n * function to assert that it conforms to the {@link OffchainMessageContentUtf8Of1232BytesMax} type.\n *\n * @see {@link OffchainMessageContentUtf8Of1232BytesMax} for more detail.\n */\nexport function assertIsOffchainMessageContentUtf8Of1232BytesMax(putativeContent: {\n    format: OffchainMessageContentFormat;\n    text: string;\n}): asserts putativeContent is OffchainMessageContentUtf8Of1232BytesMax {\n    if (putativeContent.text.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);\n    }\n    if (putativeContent.format !== OffchainMessageContentFormat.UTF8_1232_BYTES_MAX) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {\n            actualMessageFormat: putativeContent.format,\n            expectedMessageFormat: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n        });\n    }\n    const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);\n    if (length > MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n            actualBytes: length,\n            maxBytes: MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE,\n        });\n    }\n}\n\n/**\n * A type guard that returns `true` when supplied content of a v0 offchain message that conforms to\n * the {@link OffchainMessageContentUtf8Of1232BytesMax} type, and refines its type for use in your\n * program.\n *\n * @see {@link OffchainMessageContentUtf8Of1232BytesMax} for more detail.\n */\nexport function isOffchainMessageContentUtf8Of1232BytesMax(putativeContent: {\n    format: OffchainMessageContentFormat;\n    text: string;\n}): putativeContent is OffchainMessageContentUtf8Of1232BytesMax {\n    if (\n        putativeContent.format !== OffchainMessageContentFormat.UTF8_1232_BYTES_MAX ||\n        putativeContent.text.length === 0\n    ) {\n        return false;\n    }\n    const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);\n    return length <= MAX_BODY_BYTES_HARDWARE_WALLET_SIGNABLE;\n}\n\n/**\n * Combines _asserting_ that the content of a v0 offchain message is UTF-8 of up to 1232 characters\n * with _coercing_ it to the {@link OffchainMessageContentUtf8Of1232BytesMax} type. It's most useful\n * with untrusted input.\n *\n * @example\n * ```ts\n * import { OffchainMessageContentUtf8Of1232BytesMax, OffchainMessageV0 } from '@solana/offchain-messages';\n *\n * function handleSubmit() {\n *     // We know only that what the user typed conforms to the `string` type.\n *     const text: string = textInput.value;\n *     try {\n *         const offchainMessage: OffchainMessageV0 = {\n *             content: OffchainMessageContentUtf8Of1232BytesMax(text),\n *             // ...\n *         };\n *     } catch (e) {\n *         // `text` turned out not to conform to\n *         // `OffchainMessageContentUtf8Of1232BytesMax`\n *     }\n * }\n * ```\n *\n * > [!TIP]\n * > When starting from known-good UTF-8 content as a string up to 1232 bytes, it's more efficient\n * > to typecast it rather than to use the {@link offchainMessageContentUtf8Of1232BytesMax} helper,\n * > because the helper unconditionally performs validation on its input.\n * >\n * > ```ts\n * > import { OffchainMessageContentFormat, OffchainMessageV0 } from '@solana/offchain-messages';\n * >\n * > const offchainMessage: OffchainMessageV0 = {\n * >     /* ... *\\/\n * >     content: Object.freeze({\n * >         format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n * >         text: '✌🏿cool',\n * >     } as OffchainMessageContentUtf8Of1232BytesMax<'✌🏿cool'>),\n * > };\n * > ```\n */\nexport function offchainMessageContentUtf8Of1232BytesMax<TText extends string>(\n    text: TText,\n): OffchainMessageContentUtf8Of1232BytesMax<TText> {\n    const putativeContent = Object.freeze({\n        format: OffchainMessageContentFormat.UTF8_1232_BYTES_MAX,\n        text,\n    });\n    assertIsOffchainMessageContentUtf8Of1232BytesMax(putativeContent);\n    return putativeContent;\n}\n\n/**\n * In the event that you receive content of a v0 offchain message from an untrusted source, use this\n * function to assert that it conforms to the {@link OffchainMessageContentUtf8Of65535BytesMax}\n * type.\n *\n * @see {@link OffchainMessageContentUtf8Of65535BytesMax} for more detail.\n */\nexport function assertIsOffchainMessageContentUtf8Of65535BytesMax(putativeContent: {\n    format: OffchainMessageContentFormat;\n    text: string;\n}): asserts putativeContent is OffchainMessageContentUtf8Of65535BytesMax {\n    if (putativeContent.format !== OffchainMessageContentFormat.UTF8_65535_BYTES_MAX) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_FORMAT_MISMATCH, {\n            actualMessageFormat: putativeContent.format,\n            expectedMessageFormat: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n        });\n    }\n    if (putativeContent.text.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MESSAGE_MUST_BE_NON_EMPTY);\n    }\n    const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);\n    if (length > MAX_BODY_BYTES) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__MAXIMUM_LENGTH_EXCEEDED, {\n            actualBytes: length,\n            maxBytes: MAX_BODY_BYTES,\n        });\n    }\n}\n\n/**\n * A type guard that returns `true` when supplied content of a v0 offchain message that conforms to\n * the {@link OffchainMessageContentUtf8Of65535BytesMax} type, and refines its type for use in your\n * program.\n *\n * @see {@link OffchainMessageContentUtf8Of65535BytesMax} for more detail.\n */\nexport function isOffchainMessageContentUtf8Of65535BytesMax(putativeContent: {\n    format: OffchainMessageContentFormat;\n    text: string;\n}): putativeContent is OffchainMessageContentUtf8Of65535BytesMax {\n    if (\n        putativeContent.format !== OffchainMessageContentFormat.UTF8_65535_BYTES_MAX ||\n        putativeContent.text.length === 0\n    ) {\n        return false;\n    }\n    const length = getUtf8Encoder().getSizeFromValue(putativeContent.text);\n    return length <= MAX_BODY_BYTES;\n}\n\n/**\n * Combines _asserting_ that the content of a v0 offchain message is UTF-8 of up to 65535 characters\n * with _coercing_ it to the {@link OffchainMessageContentUtf8Of65535BytesMax} type. It's most useful\n * with untrusted input.\n *\n * @example\n * ```ts\n * import { OffchainMessageContentUtf8Of65535BytesMax, OffchainMessageV0 } from '@solana/offchain-messages';\n *\n * function handleSubmit() {\n *     // We know only that what the user typed conforms to the `string` type.\n *     const text: string = textInput.value;\n *     try {\n *         const offchainMessage: OffchainMessageV0 = {\n *             content: OffchainMessageContentUtf8Of65535BytesMax(text),\n *             // ...\n *         };\n *     } catch (e) {\n *         // `text` turned out not to conform to\n *         // `OffchainMessageContentUtf8Of65535BytesMax`\n *     }\n * }\n * ```\n *\n * > [!TIP]\n * > When starting from known-good UTF-8 content as a string up to 65535 bytes, it's more efficient\n * > to typecast it rather than to use the {@link OffchainMessageContentUtf8Of65535BytesMax} helper,\n * > because the helper unconditionally performs validation on its input.\n * >\n * > ```ts\n * > import { OffchainMessageContentFormat, OffchainMessageV0 } from '@solana/offchain-messages';\n * >\n * > const offchainMessage: OffchainMessageV0 = {\n * >     /* ... *\\/\n * >     content: Object.freeze({\n * >         format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n * >         text: '✌🏿cool',\n * >     } as OffchainMessageContentUtf8Of65535BytesMax<'✌🏿cool'>),\n * > };\n * > ```\n */\nexport function offchainMessageContentUtf8Of65535BytesMax<TText extends string>(\n    text: TText,\n): OffchainMessageContentUtf8Of65535BytesMax<TText> {\n    const putativeContent = Object.freeze({\n        format: OffchainMessageContentFormat.UTF8_65535_BYTES_MAX,\n        text,\n    });\n    assertIsOffchainMessageContentUtf8Of65535BytesMax(putativeContent);\n    return putativeContent;\n}\n\nfunction isTextRestrictedAscii(putativeRestrictedAsciiString: string): boolean {\n    return /^[\\x20-\\x7e]+$/.test(putativeRestrictedAsciiString);\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/envelope-common.ts",
    "content": "import { VariableSizeEncoder } from '@solana/codecs-core';\n\nimport { OffchainMessageEnvelope } from './envelope';\nimport { OffchainMessage, OffchainMessageBytes } from './message';\n\nexport function compileOffchainMessageEnvelopeUsingEncoder<T extends OffchainMessage>(\n    offchainMessage: T,\n    encoder: VariableSizeEncoder<T>,\n) {\n    const offchainMessageBytes = encoder.encode(offchainMessage) as OffchainMessageBytes;\n    const signatures: OffchainMessageEnvelope['signatures'] = {};\n    for (const { address } of offchainMessage.requiredSignatories) {\n        signatures[address] = null;\n    }\n    return Object.freeze({\n        content: offchainMessageBytes,\n        signatures: Object.freeze(signatures),\n    });\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/envelope-v0.ts",
    "content": "import { getOffchainMessageV0Encoder } from './codecs/message-v0';\nimport { OffchainMessageEnvelope } from './envelope';\nimport { compileOffchainMessageEnvelopeUsingEncoder } from './envelope-common';\nimport { OffchainMessageV0 } from './message-v0';\n\n/**\n * Returns an {@link OffchainMessageEnvelope} object for a given {@link OffchainMessageV0}.\n *\n * This includes the compiled bytes of the offchain message, and a map of signatures. This map will\n * have a key for each address that is required to sign the message. The message envelope will not\n * yet have signatures for any of these signatories.\n */\nexport function compileOffchainMessageV0Envelope(offchainMessage: OffchainMessageV0): OffchainMessageEnvelope {\n    return compileOffchainMessageEnvelopeUsingEncoder(offchainMessage, getOffchainMessageV0Encoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/envelope-v1.ts",
    "content": "import { getOffchainMessageV1Encoder } from './codecs/message-v1';\nimport { OffchainMessageEnvelope } from './envelope';\nimport { compileOffchainMessageEnvelopeUsingEncoder } from './envelope-common';\nimport { OffchainMessageV1 } from './message-v1';\n\n/**\n * Returns an {@link OffchainMessageEnvelope} object for a given {@link OffchainMessageV1}.\n *\n * This includes the compiled bytes of the offchain message, and a map of signatures. This map will\n * have a key for each address that is required to sign the message. The message envelope will not\n * yet have signatures for any of these signatories.\n */\nexport function compileOffchainMessageV1Envelope(offchainMessage: OffchainMessageV1): OffchainMessageEnvelope {\n    return compileOffchainMessageEnvelopeUsingEncoder(offchainMessage, getOffchainMessageV1Encoder());\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/envelope.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { compileOffchainMessageV0Envelope } from './envelope-v0';\nimport { compileOffchainMessageV1Envelope } from './envelope-v1';\nimport { OffchainMessage, OffchainMessageBytes } from './message';\n\ntype OrderedMap<K extends string, V> = Record<K, V>;\ntype OffchainMessageSignaturesMap = OrderedMap<Address, SignatureBytes | null>;\n\nexport interface OffchainMessageEnvelope {\n    /** The bytes of the combined offchain message preamble and content */\n    readonly content: OffchainMessageBytes;\n    /**\n     * A map between the addresses of an offchain message's signers, and the 64-byte Ed25519\n     * signature of the combined message preamble and message content by the private key associated\n     * with each.\n     */\n    readonly signatures: OffchainMessageSignaturesMap;\n}\n\n/**\n * Returns an {@link OffchainMessageEnvelope} object for a given {@link OffchainMessage}.\n *\n * This includes the compiled bytes of the offchain message, and a map of signatures. This map will\n * have a key for each address that is required to sign the message. The message envelope will not\n * yet have signatures for any of these signatories.\n *\n * @remarks\n * If the offchain message version is known ahead of time, use one of the compile functions\n * specific to that version so as not to bundle more code than you need.\n */\nexport function compileOffchainMessageEnvelope(offchainMessage: OffchainMessage): OffchainMessageEnvelope {\n    const { version } = offchainMessage;\n    switch (version) {\n        case 0:\n            return compileOffchainMessageV0Envelope(offchainMessage);\n        case 1:\n            return compileOffchainMessageV1Envelope(offchainMessage);\n        default:\n            throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, {\n                unexpectedValue: version satisfies never,\n            });\n    }\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/index.ts",
    "content": "/**\n * This package contains utilities for encoding and decoding messages according to the offchain\n * message [specification](https://github.com/solana-foundation/SRFCs/discussions/3).\n * It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './application-domain';\nexport * from './codecs/application-domain';\nexport * from './codecs/envelope';\nexport * from './codecs/message';\nexport * from './codecs/message-v0';\nexport * from './codecs/message-v1';\nexport * from './content';\nexport * from './envelope';\nexport * from './envelope-v0';\nexport * from './envelope-v1';\nexport * from './message';\nexport * from './message-v0';\nexport * from './message-v1';\nexport * from './signatures';\nexport * from './version';\n"
  },
  {
    "path": "packages/offchain-messages/src/message-v0.ts",
    "content": "import {\n    assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax,\n    assertIsOffchainMessageContentUtf8Of1232BytesMax,\n    assertIsOffchainMessageContentUtf8Of65535BytesMax,\n    OffchainMessageContentFormat,\n    OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n    OffchainMessageContentUtf8Of1232BytesMax,\n    OffchainMessageContentUtf8Of65535BytesMax,\n} from './content';\nimport { OffchainMessagePreambleV0 } from './preamble-v0';\nimport { OffchainMessageWithRequiredSignatories } from './signatures';\n\nexport type BaseOffchainMessageV0 = Omit<\n    OffchainMessagePreambleV0,\n    'messageFormat' | 'messageLength' | 'requiredSignatories'\n>;\n\n/**\n * An offchain message whose content conforms to\n * {@link OffchainMessageContentRestrictedAsciiOf1232BytesMax}\n */\nexport interface OffchainMessageWithRestrictedAsciiOf1232BytesMaxContent {\n    readonly content: OffchainMessageContentRestrictedAsciiOf1232BytesMax;\n}\n\n/**\n * An offchain message whose content conforms to\n * {@link offchainMessageContentUtf8Of1232BytesMax}\n */\nexport interface OffchainMessageWithUtf8Of1232BytesMaxContent {\n    readonly content: OffchainMessageContentUtf8Of1232BytesMax;\n}\n\n/**\n * An offchain message whose content conforms to\n * {@link OffchainMessageContentUtf8Of65535BytesMax}\n */\nexport interface OffchainMessageWithUtf8Of65535BytesMaxContent {\n    readonly content: OffchainMessageContentUtf8Of65535BytesMax;\n}\n\n/**\n * A union of the formats a v0 message's contents can take.\n *\n * @remarks From v1 and onward, an offchain message has only one format: UTF-8 text of arbitrary\n * length.\n */\nexport type OffchainMessageWithContent =\n    | OffchainMessageWithRestrictedAsciiOf1232BytesMaxContent\n    | OffchainMessageWithUtf8Of1232BytesMaxContent\n    | OffchainMessageWithUtf8Of65535BytesMaxContent;\n\nexport type OffchainMessageV0 = BaseOffchainMessageV0 &\n    OffchainMessageWithContent &\n    OffchainMessageWithRequiredSignatories;\n\n/**\n * In the event that you receive a v0 offchain message from an untrusted source, use this function\n * to assert that it is one whose content conforms to the\n * {@link OffchainMessageContentRestrictedAsciiOf1232BytesMax} type.\n *\n * @see {@link OffchainMessageContentRestrictedAsciiOf1232BytesMax} for more detail.\n */\nexport function assertIsOffchainMessageRestrictedAsciiOf1232BytesMax<TMessage extends OffchainMessageV0>(\n    putativeMessage: Omit<TMessage, 'content'> &\n        Readonly<{\n            content: {\n                format: OffchainMessageContentFormat;\n                text: string;\n            };\n        }>,\n): asserts putativeMessage is OffchainMessageWithRestrictedAsciiOf1232BytesMaxContent & Omit<TMessage, 'content'> {\n    assertIsOffchainMessageContentRestrictedAsciiOf1232BytesMax(putativeMessage.content);\n}\n\n/**\n * In the event that you receive a v0 offchain message from an untrusted source, use this function\n * to assert that it is one whose content conforms to the\n * {@link offchainMessageContentUtf8Of1232BytesMax} type.\n *\n * @see {@link offchainMessageContentUtf8Of1232BytesMax} for more detail.\n */\nexport function assertIsOffchainMessageUtf8Of1232BytesMax<TMessage extends OffchainMessageV0>(\n    putativeMessage: Omit<TMessage, 'content'> &\n        Readonly<{\n            content: {\n                format: OffchainMessageContentFormat;\n                text: string;\n            };\n            version: number;\n        }>,\n): asserts putativeMessage is OffchainMessageWithUtf8Of1232BytesMaxContent & Omit<TMessage, 'content'> {\n    assertIsOffchainMessageContentUtf8Of1232BytesMax(putativeMessage.content);\n}\n\n/**\n * In the event that you receive a v0 offchain message from an untrusted source, use this function\n * to assert that it is one whose content conforms to the\n * {@link OffchainMessageContentUtf8Of65535BytesMax} type.\n *\n * @see {@link OffchainMessageContentUtf8Of65535BytesMax} for more detail.\n */\nexport function assertIsOffchainMessageUtf8Of65535BytesMax<TMessage extends OffchainMessageV0>(\n    putativeMessage: Omit<TMessage, 'content'> &\n        Readonly<{\n            content: {\n                format: OffchainMessageContentFormat;\n                text: string;\n            };\n            version: number;\n        }>,\n): asserts putativeMessage is OffchainMessageWithUtf8Of65535BytesMaxContent & Omit<TMessage, 'content'> {\n    assertIsOffchainMessageContentUtf8Of65535BytesMax(putativeMessage.content);\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/message-v1.ts",
    "content": "import { OffchainMessagePreambleV1 } from './preamble-v1';\nimport { OffchainMessageWithRequiredSignatories } from './signatures';\n\nexport type BaseOffchainMessageV1 = Omit<OffchainMessagePreambleV1, 'requiredSignatories'>;\n\nexport type OffchainMessageV1 = BaseOffchainMessageV1 &\n    OffchainMessageWithRequiredSignatories &\n    Readonly<{\n        content: string;\n    }>;\n"
  },
  {
    "path": "packages/offchain-messages/src/message.ts",
    "content": "import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { Brand } from '@solana/nominal-types';\n\nimport { OffchainMessageV0 } from './message-v0';\nimport { OffchainMessageV1 } from './message-v1';\n\nexport type OffchainMessage = OffchainMessageV0 | OffchainMessageV1;\nexport type OffchainMessageBytes = Brand<ReadonlyUint8Array, 'OffchainMessageBytes'>;\n"
  },
  {
    "path": "packages/offchain-messages/src/preamble-v0.ts",
    "content": "import { OffchainMessageApplicationDomain } from './application-domain';\nimport { OffchainMessageContentFormat } from './content';\nimport { OffchainMessageWithRequiredSignatories } from './signatures';\n\nexport interface OffchainMessagePreambleV0 extends OffchainMessageWithRequiredSignatories {\n    applicationDomain: OffchainMessageApplicationDomain;\n    messageFormat: OffchainMessageContentFormat;\n    messageLength: number;\n    version: 0;\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/preamble-v1.ts",
    "content": "import { OffchainMessageWithRequiredSignatories } from './signatures';\n\nexport interface OffchainMessagePreambleV1 extends OffchainMessageWithRequiredSignatories {\n    version: 1;\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/signatures.ts",
    "content": "import { Address, getAddressFromPublicKey, getPublicKeyFromAddress } from '@solana/addresses';\nimport { bytesEqual } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE,\n    SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes, signBytes, verifySignature } from '@solana/keys';\nimport { NominalType } from '@solana/nominal-types';\n\nimport { decodeRequiredSignatoryAddresses } from './codecs/preamble-common';\nimport { OffchainMessageEnvelope } from './envelope';\n\n/**\n * Represents an offchain message envelope that is signed by all of its required signers.\n */\nexport type FullySignedOffchainMessageEnvelope = NominalType<'offchainMessageEnvelopeSignedness', 'fullySigned'>;\n\n/**\n * Represents an address that is required to sign an offchain message for it to be valid.\n */\nexport type OffchainMessageSignatory<TAddress extends string = string> = Readonly<{\n    address: Address<TAddress>;\n}>;\n\n/**\n * An offchain message having a list of accounts that must sign it in order for it to be valid.\n */\nexport interface OffchainMessageWithRequiredSignatories<\n    TSignatory extends OffchainMessageSignatory = OffchainMessageSignatory,\n> {\n    requiredSignatories: readonly TSignatory[];\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign an offchain message, this method will return a new signed offchain message\n * envelope of type {@link OffchainMessageEnvelope}.\n *\n * Though the resulting message might be signed by all required signers, this function will not\n * assert that it is. A partially signed message is not complete, but can be serialized and\n * deserialized.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { partiallySignOffchainMessageEnvelope } from '@solana/offchain-messages';\n *\n * const partiallySignedOffchainMessage = await partiallySignOffchainMessageEnvelope(\n *     [myPrivateKey],\n *     offchainMessageEnvelope,\n * );\n * ```\n *\n * @see {@link signOffchainMessageEnvelope} if you want to assert that the message is signed by all\n * its required signers after signing.\n */\nexport async function partiallySignOffchainMessageEnvelope<TOffchainMessageEnvelope extends OffchainMessageEnvelope>(\n    keyPairs: CryptoKeyPair[],\n    offchainMessageEnvelope: TOffchainMessageEnvelope,\n): Promise<TOffchainMessageEnvelope> {\n    let newSignatures: Record<Address, SignatureBytes> | undefined;\n    let unexpectedSigners: Set<Address> | undefined;\n\n    const requiredSignatoryAddresses = decodeRequiredSignatoryAddresses(offchainMessageEnvelope.content);\n\n    await Promise.all(\n        keyPairs.map(async keyPair => {\n            const address = await getAddressFromPublicKey(keyPair.publicKey);\n\n            // Check if the address is expected to sign the message\n            if (!requiredSignatoryAddresses.includes(address)) {\n                // address is not an expected signer for this message\n                unexpectedSigners ||= new Set();\n                unexpectedSigners.add(address);\n                return;\n            }\n\n            // Return if there are any unexpected signers already since we won't be using signatures\n            if (unexpectedSigners) {\n                return;\n            }\n\n            const existingSignature = offchainMessageEnvelope.signatures[address];\n            const newSignature = await signBytes(keyPair.privateKey, offchainMessageEnvelope.content);\n\n            if (existingSignature != null && bytesEqual(newSignature, existingSignature)) {\n                // already have the same signature set\n                return;\n            }\n\n            newSignatures ||= {};\n            newSignatures[address] = newSignature;\n        }),\n    );\n\n    if (unexpectedSigners && unexpectedSigners.size > 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__ADDRESSES_CANNOT_SIGN_OFFCHAIN_MESSAGE, {\n            expectedAddresses: requiredSignatoryAddresses,\n            unexpectedAddresses: [...unexpectedSigners],\n        });\n    }\n\n    if (!newSignatures) {\n        return offchainMessageEnvelope;\n    }\n\n    return Object.freeze({\n        ...offchainMessageEnvelope,\n        signatures: Object.freeze({\n            ...offchainMessageEnvelope.signatures,\n            ...newSignatures,\n        }),\n    });\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign an offchain message envelope, this method will return a new signed envelope of\n * type {@link FullySignedOffchainMessageEnvelope}.\n *\n * This function will throw unless the resulting message is fully signed.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { signOffchainMessageEnvelope } from '@solana/offchain-messages';\n *\n * const signedOffchainMessage = await signOffchainMessageEnvelope(\n *     [myPrivateKey],\n *     offchainMessageEnvelope,\n * );\n * ```\n *\n * @see {@link partiallySignOffchainMessageEnvelope} if you want to sign the message without\n * asserting that the resulting message envelope is fully signed.\n */\nexport async function signOffchainMessageEnvelope<TOffchainMessageEnvelope extends OffchainMessageEnvelope>(\n    keyPairs: CryptoKeyPair[],\n    offchainMessageEnvelope: TOffchainMessageEnvelope,\n): Promise<FullySignedOffchainMessageEnvelope & TOffchainMessageEnvelope> {\n    const out = await partiallySignOffchainMessageEnvelope(keyPairs, offchainMessageEnvelope);\n    assertIsFullySignedOffchainMessageEnvelope(out);\n    Object.freeze(out);\n    return out;\n}\n\n/**\n * A type guard that returns `true` if the input {@link OffchainMessageEnvelope} is fully signed,\n * and refines its type for use in your program, adding the\n * {@link FullySignedOffchainMessageEnvelope} type.\n *\n * @example\n * ```ts\n * import { isFullySignedOffchainMessageEnvelope } from '@solana/offchain-messages';\n *\n * const offchainMessageEnvelope = getOffchainMessageDecoder().decode(offchainMessageBytes);\n * if (isFullySignedOffchainMessageEnvelope(offchainMessageEnvelope)) {\n *   // At this point we know that the offchain message is fully signed.\n * }\n * ```\n */\nexport function isFullySignedOffchainMessageEnvelope<TEnvelope extends OffchainMessageEnvelope>(\n    offchainMessage: TEnvelope,\n): offchainMessage is FullySignedOffchainMessageEnvelope & TEnvelope {\n    return Object.entries(offchainMessage.signatures).every(([_, signatureBytes]) => !!signatureBytes);\n}\n\n/**\n * From time to time you might acquire a {@link OffchainMessageEnvelope}, that you expect to be\n * fully signed, from an untrusted network API or user input. Use this function to assert that such\n * an offchain message is fully signed.\n *\n * @example\n * ```ts\n * import { assertIsFullySignedOffchainMessage } from '@solana/offchain-messages';\n *\n * const offchainMessageEnvelope = getOffchainMessageDecoder().decode(offchainMessageBytes);\n * try {\n *     // If this type assertion function doesn't throw, then Typescript will upcast\n *     // `offchainMessageEnvelope` to `FullySignedOffchainMessageEnvelope`.\n *     assertIsFullySignedOffchainMessageEnvelope(offchainMessage);\n *     // At this point we know that the offchain message is signed by all required signers.\n * } catch(e) {\n *     if (isSolanaError(e, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING)) {\n *         setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n *     } else {\n *         throw e;\n *     }\n * }\n * ```\n */\nexport function assertIsFullySignedOffchainMessageEnvelope<TEnvelope extends OffchainMessageEnvelope>(\n    offchainMessage: TEnvelope,\n): asserts offchainMessage is FullySignedOffchainMessageEnvelope & TEnvelope {\n    const missingSigs: Address[] = [];\n    Object.entries(offchainMessage.signatures).forEach(([address, signatureBytes]) => {\n        if (!signatureBytes) {\n            missingSigs.push(address as Address);\n        }\n    });\n\n    if (missingSigs.length > 0) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING, {\n            addresses: missingSigs,\n        });\n    }\n}\n\n/**\n * Asserts that there are signatures present for all of an offchain message's required signatories,\n * and that those signatures are valid given the message.\n *\n * @example\n * ```ts\n * import { isSolanaError, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE } from '@solana/errors';\n * import { verifyOffchainMessageEnvelope } from '@solana/offchain-messages';\n *\n * try {\n *     await verifyOffchainMessageEnvelope(offchainMessageEnvelope);\n *     // At this point the message is valid and signed by all of the required signatories.\n * } catch (e) {\n *     if (isSolanaError(e, SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE)) {\n *         if (e.context.signatoriesWithMissingSignatures.length) {\n *             console.error(\n *                 'Missing signatures for the following addresses',\n *                 e.context.signatoriesWithMissingSignatures,\n *             );\n *         }\n *         if (e.context.signatoriesWithInvalidSignatures.length) {\n *             console.error(\n *                 'Signatures for the following addresses are invalid',\n *                 e.context.signatoriesWithInvalidSignatures,\n *             );\n *         }\n *     }\n *     throw e;\n * }\n */\nexport async function verifyOffchainMessageEnvelope(offchainMessageEnvelope: OffchainMessageEnvelope): Promise<void> {\n    let errorContext;\n    const requiredSignatories = decodeRequiredSignatoryAddresses(offchainMessageEnvelope.content);\n    await Promise.all(\n        requiredSignatories.map(async address => {\n            const signature = offchainMessageEnvelope.signatures[address];\n            if (signature == null) {\n                errorContext ||= {};\n                errorContext.signatoriesWithMissingSignatures ||= [];\n                errorContext.signatoriesWithMissingSignatures.push(address);\n            } else {\n                const publicKey = await getPublicKeyFromAddress(address);\n                if (await verifySignature(publicKey, signature, offchainMessageEnvelope.content)) {\n                    return true;\n                } else {\n                    errorContext ||= {};\n                    errorContext.signatoriesWithInvalidSignatures ||= [];\n                    errorContext.signatoriesWithInvalidSignatures.push(address);\n                }\n            }\n        }),\n    );\n    if (errorContext) {\n        throw new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURE_VERIFICATION_FAILURE, errorContext);\n    }\n}\n"
  },
  {
    "path": "packages/offchain-messages/src/version.ts",
    "content": "export type OffchainMessageVersion = 0 | 1;\n"
  },
  {
    "path": "packages/offchain-messages/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/offchain-messages/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/offchain-messages\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/offchain-messages/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/options/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/options/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/options/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/options/CHANGELOG.md",
    "content": "# @solana/options\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-data-structures@6.9.0\n    - @solana/codecs-numbers@6.9.0\n    - @solana/codecs-strings@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-data-structures@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-data-structures@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-data-structures@6.6.0\n    - @solana/codecs-numbers@6.6.0\n    - @solana/codecs-strings@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-data-structures@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/codecs-data-structures@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-data-structures@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-data-structures@6.3.0\n    - @solana/codecs-numbers@6.3.0\n    - @solana/codecs-strings@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`5390602`](https://github.com/anza-xyz/kit/commit/53906024cffc3facb7259ab65ab974b6b1038f56), [`3f4c5f0`](https://github.com/anza-xyz/kit/commit/3f4c5f003e343c21a785e8f339f84c8d6bd3a3b1), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-data-structures@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n    - @solana/codecs-strings@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`70b1ed8`](https://github.com/anza-xyz/kit/commit/70b1ed83be4c5445f81c600a8ca70127dbdf3463), [`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75), [`7ce7545`](https://github.com/anza-xyz/kit/commit/7ce75455659ace9776042def6774678a81c43a4a)]:\n    - @solana/codecs-data-structures@6.1.0\n    - @solana/errors@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-numbers@6.1.0\n    - @solana/codecs-strings@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-data-structures@6.0.1\n    - @solana/codecs-numbers@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-data-structures@6.0.0\n    - @solana/codecs-numbers@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-data-structures@5.5.1\n    - @solana/codecs-numbers@5.5.1\n    - @solana/codecs-strings@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-data-structures@5.5.0\n    - @solana/codecs-numbers@5.5.0\n    - @solana/codecs-strings@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-data-structures@5.4.0\n    - @solana/codecs-numbers@5.4.0\n    - @solana/codecs-strings@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-data-structures@5.3.0\n    - @solana/codecs-numbers@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-numbers@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/codecs-data-structures@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/codecs-data-structures@5.1.0\n    - @solana/codecs-numbers@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-data-structures@5.0.0\n    - @solana/codecs-numbers@5.0.0\n    - @solana/codecs-strings@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/codecs-data-structures@4.0.0\n    - @solana/codecs-numbers@4.0.0\n    - @solana/codecs-strings@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`9205484`](https://github.com/anza-xyz/kit/commit/9205484d33af9426fc9de9594bab204b8f954faf), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-data-structures@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/codecs-numbers@3.0.0\n    - @solana/codecs-strings@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-data-structures@2.3.0\n    - @solana/codecs-numbers@2.3.0\n    - @solana/codecs-strings@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-data-structures@2.2.1\n    - @solana/codecs-numbers@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-data-structures@2.2.0\n    - @solana/codecs-numbers@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-data-structures@2.1.1\n    - @solana/codecs-numbers@2.1.1\n    - @solana/codecs-strings@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`cfe6910`](https://github.com/anza-xyz/kit/commit/cfe691010a493d06983a8a2728cda9751135906d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-data-structures@2.1.0\n    - @solana/codecs-numbers@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2715](https://github.com/solana-labs/solana-web3.js/pull/2715) [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Consolidated `getNullableCodec` and `getOptionCodec` with their `Zeroable` counterparts and added more configurations\n\n    Namely, the `prefix` option can now be set to `null` and the `fixed` option was replaced with the `noneValue` option which can be set to `\"zeroes\"` for `Zeroable` codecs or a custom byte array for custom representations of none values. This means the `getZeroableNullableCodec` and `getZeroableOptionCodec` functions were removed in favor of the new options.\n\n    ```ts\n    // Before.\n    getZeroableNullableCodec(getU16Codec());\n\n    // After.\n    getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n    ```\n\n    Additionally, it is now possible to create nullable codecs that have no `prefix` nor `noneValue`. In this case, the existence of the nullable item is indicated by the presence of any remaining bytes left to decode.\n\n    ```ts\n    const codec = getNullableCodec(getU16Codec(), { prefix: null });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // Encodes nothing.\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([])); // null\n    ```\n\n    Also note that it is now possible for custom `noneValue` byte arrays to be of any length — previously, it had to match the fixed-size of the nullable item.\n\n    Here is a recap of all supported scenarios, using a `u16` codec as an example:\n\n    | `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n    | ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n    | `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n    | Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n    | No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n    Reciprocal changes were made with `getOptionCodec`.\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2573](https://github.com/solana-labs/solana-web3.js/pull/2573) [`a29bfee`](https://github.com/solana-labs/solana-web3.js/commit/a29bfeeb2119d99906a31fb1e5103d8ebf783ceb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Fix missing export of Zeroable Option codecs\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2412](https://github.com/solana-labs/solana-web3.js/pull/2412) [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed the size option of `getBytesCodec`\n\n    The `getBytesCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode byte arrays. In order to fix or prefix the size of a `getBytesCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getBytesCodec(); // Variable.\n    getBytesCodec({ size: 5 }); // Fixed.\n    getBytesCodec({ size: getU16Codec() }); // Prefixed.\n\n    // After.\n    getBytesCodec(); // Variable.\n    fixCodecSize(getBytesCodec(), 5); // Fixed.\n    addCodecSizePrefix(getBytesCodec(), getU16Codec()); // Prefixed.\n    ```\n\n- [#2410](https://github.com/solana-labs/solana-web3.js/pull/2410) [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `getZeroableNullableCodec` and `getZeroableOptionCodec` functions\n\n    These functions rely on a zero value to represent `None` or `null` values as opposed to using a boolean prefix.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec());\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0x0000\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.encode(new Uint8Array([0, 0])); // null\n    ```\n\n    Both functions can also be provided with a custom definition of the zero value using the `zeroValue` option.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec(), {\n        zeroValue: new Uint8Array([255, 255]),\n    });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0xfffff\n    codec.encode(new Uint8Array([0, 0])); // 0\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([255, 255])); // null\n    ```\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6), [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-data-structures@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/codecs-numbers@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-data-structures@2.0.0-rc.4\n    - @solana/codecs-numbers@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-data-structures@2.0.0-rc.3\n    - @solana/codecs-numbers@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-data-structures@2.0.0-rc.2\n    - @solana/codecs-numbers@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-data-structures@2.0.0-rc.1\n    - @solana/codecs-numbers@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-data-structures@2.0.0-rc.0\n    - @solana/codecs-numbers@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2715](https://github.com/solana-labs/solana-web3.js/pull/2715) [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Consolidated `getNullableCodec` and `getOptionCodec` with their `Zeroable` counterparts and added more configurations\n\n    Namely, the `prefix` option can now be set to `null` and the `fixed` option was replaced with the `noneValue` option which can be set to `\"zeroes\"` for `Zeroable` codecs or a custom byte array for custom representations of none values. This means the `getZeroableNullableCodec` and `getZeroableOptionCodec` functions were removed in favor of the new options.\n\n    ```ts\n    // Before.\n    getZeroableNullableCodec(getU16Codec());\n\n    // After.\n    getNullableCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n    ```\n\n    Additionally, it is now possible to create nullable codecs that have no `prefix` nor `noneValue`. In this case, the existence of the nullable item is indicated by the presence of any remaining bytes left to decode.\n\n    ```ts\n    const codec = getNullableCodec(getU16Codec(), { prefix: null });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // Encodes nothing.\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([])); // null\n    ```\n\n    Also note that it is now possible for custom `noneValue` byte arrays to be of any length — previously, it had to match the fixed-size of the nullable item.\n\n    Here is a recap of all supported scenarios, using a `u16` codec as an example:\n\n    | `encode(42)` / `encode(null)` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n    | ----------------------------- | ------------------------ | --------------------------- | --------------------------- |\n    | `u8` prefix (default)         | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n    | Custom `prefix` (`u16`)       | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n    | No `prefix`                   | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\n    Reciprocal changes were made with `getOptionCodec`.\n\n- [#2573](https://github.com/solana-labs/solana-web3.js/pull/2573) [`a29bfee`](https://github.com/solana-labs/solana-web3.js/commit/a29bfeeb2119d99906a31fb1e5103d8ebf783ceb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Fix missing export of Zeroable Option codecs\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/codecs-data-structures@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/codecs-numbers@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2412](https://github.com/solana-labs/solana-web3.js/pull/2412) [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed the size option of `getBytesCodec`\n\n    The `getBytesCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode byte arrays. In order to fix or prefix the size of a `getBytesCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getBytesCodec(); // Variable.\n    getBytesCodec({ size: 5 }); // Fixed.\n    getBytesCodec({ size: getU16Codec() }); // Prefixed.\n\n    // After.\n    getBytesCodec(); // Variable.\n    fixCodecSize(getBytesCodec(), 5); // Fixed.\n    addCodecSizePrefix(getBytesCodec(), getU16Codec()); // Prefixed.\n    ```\n\n- [#2410](https://github.com/solana-labs/solana-web3.js/pull/2410) [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Added new `getZeroableNullableCodec` and `getZeroableOptionCodec` functions\n\n    These functions rely on a zero value to represent `None` or `null` values as opposed to using a boolean prefix.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec());\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0x0000\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.encode(new Uint8Array([0, 0])); // null\n    ```\n\n    Both functions can also be provided with a custom definition of the zero value using the `zeroValue` option.\n\n    ```ts\n    const codec = getZeroableNullableCodec(getU16Codec(), {\n        zeroValue: new Uint8Array([255, 255]),\n    });\n    codec.encode(42); // 0x2a00\n    codec.encode(null); // 0xfffff\n    codec.encode(new Uint8Array([0, 0])); // 0\n    codec.decode(new Uint8Array([42, 0])); // 42\n    codec.decode(new Uint8Array([255, 255])); // null\n    ```\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6), [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-data-structures@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/codecs-numbers@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-numbers@2.0.0-preview.2\n"
  },
  {
    "path": "packages/options/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/options/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/options?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/options?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/options\n\n# @solana/options\n\nThis package allows us to manage and serialize Rust-like Option types in JavaScript. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nThis package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs) which acts as an entry point for all codec packages as well as for their documentation.\n\n## Creating options\n\nIn Rust, we define optional values as an `Option<T>` type which can either be `Some(T)` or `None`. This is usually represented as `T | null` in the JavaScript world. The issue with this approach is it doesn't work with nested options. For instance, an `Option<Option<T>>` in Rust would become a `T | null | null` in JavaScript which is equivalent to `T | null`. That means, there is no way for us to represent the `Some(None)` value in JavaScript or any other nested option.\n\nTo solve this issue, this library provides an `Option<T>` union type that works very similarly to the Rust `Option<T>` type. It is defined as follows:\n\n```ts\ntype Option<T> = Some<T> | None;\ntype Some<T> = { __option: 'Some'; value: T };\ntype None = { __option: 'None' };\n```\n\nTo improve the developer experience, helper functions are available to help you create options. The type `T` of the option can either be inferred by TypeScript or explicitly provided.\n\n```ts\n// Create an option with a value.\nsome('Hello World');\nsome<number | string>(123);\n\n// Create an empty option.\nnone();\nnone<number | string>();\n```\n\n## Option helpers\n\nThis library also provides helper functions to help us identify and manage `Option` types.\n\nFor instance, you can use the `isSome` and `isNone` type guards to check whether a given `Option` is of the desired type.\n\n```ts\nisSome(some('Hello World')); // true\nisSome(none()); // false\n\nisNone(some('Hello World')); // false\nisNone(none()); // true\n```\n\nIf you are given a type `T | null`, you may also use the `wrapNullable` helper function to transform it into an `Option<T>` type.\n\n```ts\nwrapNullable('Hello world'); // Some<string>\nwrapNullable(null); // None\n```\n\n## Unwrapping options\n\nSeveral helpers are available to help you unwrap your options and access their potential value. For instance, the `unwrapOption` function transforms an `Option<T>` type into `T` if the value exits and `null` otherwise.\n\n```ts\nunwrapOption(some('Hello World')); // \"Hello World\"\nunwrapOption(none()); // null\n```\n\nIf `null` isn’t the value you want to use for `None` options, you may provide a custom fallback function as the second argument. Its return value will be assigned to `None` options.\n\n```ts\nunwrapOption(some('Hello World'), () => 'Default'); // \"Hello World\"\nunwrapOption(none(), () => 'Default'); // \"Default\"\n```\n\nNote that this `unwrapOption` function does not recursively unwrap nested options. You may use the `unwrapOptionRecursively` function for that purpose instead.\n\n```ts\nunwrapOptionRecursively(some(some(some('Hello World')))); // \"Hello World\"\nunwrapOptionRecursively(some(some(none<string>()))); // null\n```\n\nThe `unwrapOptionRecursively` function also walks any object and array it encounters and recursively unwraps any option it identifies in its journey without mutating any object or array.\n\n```ts\nunwrapOptionRecursively({\n    a: 'hello',\n    b: none(),\n    c: [{ c1: some(42) }, { c2: none() }],\n});\n// { a: \"hello\", b: null, c: [{ c1: 42 }, { c2: null }] }\n```\n\nThe `unwrapOptionRecursively` also accepts a fallback function as a second argument to provide custom values for `None` options.\n\n```ts\nunwrapOptionRecursively(\n    {\n        a: 'hello',\n        b: none(),\n        c: [{ c1: some(42) }, { c2: none() }],\n    },\n    () => 'Default',\n);\n// { a: \"hello\", b: \"Default\", c: [{ c1: 42 }, { c2: \"Default\" }] }\n```\n\n## Option codec\n\nThe `getOptionCodec` function behaves exactly the same as the [`getNullableCodec`](https://github.com/anza-xyz/kit/tree/main/packages/codecs-data-structures#nullable-codec) except that it encodes `Option<T>` types instead of `T | null` types.\n\nNamely, it accepts a codec of type `T` and returns a codec of type `Option<T>`. Note that, when encoding, `T` or `null` may also be provided directly as input and will be interpreted as `Some(T)` or `None` respectively. However, when decoding, the output will always be an `Option<T>` type.\n\nIt stores whether or not the item exists as a boolean prefix using a `u8` by default.\n\n```ts\nconst stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n\ngetOptionCodec(stringCodec).encode('Hi');\ngetOptionCodec(stringCodec).encode(some('Hi'));\n// 0x01020000004869\n//   | |       └-- utf8 string content (\"Hi\").\n//   | └-- u32 string prefix (2 characters).\n//   └-- 1-byte prefix (Some).\n\ngetOptionCodec(stringCodec).encode(null);\ngetOptionCodec(stringCodec).encode(none());\n// 0x00\n//   └-- 1-byte prefix (None).\n```\n\nYou may provide a number codec as the `prefix` option of the `getOptionCodec` function to configure how to store the boolean prefix.\n\n```ts\nconst u32OptionStringCodec = getOptionCodec(stringCodec, {\n    prefix: getU32Codec(),\n});\n\nu32OptionStringCodec.encode(some('Hi'));\n// 0x01000000020000004869\n//   └------┘ 4-byte prefix (Some).\n\nu32OptionStringCodec.encode(none());\n// 0x00000000\n//   └------┘ 4-byte prefix (None).\n```\n\nAdditionally, if the item is a `FixedSizeCodec`, you may set the `noneValue` option to `\"zeroes\"` to also make the returned Option codec a `FixedSizeCodec`. To do so, it will pad `None` values with zeroes to match the length of existing values.\n\n```ts\nconst codec = getOptionCodec(\n    fixCodecSize(getUtf8Codec(), 8), // Only works with fixed-size items.\n    { noneValue: 'zeroes' },\n);\n\ncodec.encode(some('Hi'));\n// 0x014869000000000000\n//   | └-- 8-byte utf8 string content (\"Hi\").\n//   └-- 1-byte prefix (Some).\n\ncodec.encode(none());\n// 0x000000000000000000\n//   | └-- 8-byte of padding to make a fixed-size codec.\n//   └-- 1-byte prefix (None).\n```\n\nThe `noneValue` option can also be set to an explicit byte array to use as the padding for `None` values. Note that, in this case, the returned codec will not be a `FixedSizeCodec` as the byte array representing `None` values may be of any length.\n\n```ts\nconst codec = getOptionCodec(getUtf8Codec(), {\n    noneValue: new Uint8Array([255]), // 0xff means None.\n});\n\ncodec.encode(some('Hi'));\n// 0x014869\n//   | └-- 2-byte utf8 string content (\"Hi\").\n//   └-- 1-byte prefix (Some).\n\ncodec.encode(none());\n// 0x00ff\n//   | └-- 1-byte representing None (0xff).\n//   └-- 1-byte prefix (None).\n```\n\nLast but not least, the `prefix` option of the `getOptionCodec` function can also be set to `null`, meaning no prefix will be used to determine whether the item exists. In this case, the codec will rely on the `noneValue` option to determine whether the item is `None`.\n\n```ts\nconst codecWithZeroNoneValue = getOptionCodec(getU16Codec(), {\n    noneValue: 'zeroes', // 0x0000 means None.\n    prefix: null,\n});\ncodecWithZeroNoneValue.encode(some(42)); // 0x2a00\ncodecWithZeroNoneValue.encode(none()); // 0x0000\n\nconst codecWithCustomNoneValue = getOptionCodec(getU16Codec(), {\n    noneValue: new Uint8Array([255]), // 0xff means None.\n    prefix: null,\n});\ncodecWithCustomNoneValue.encode(some(42)); // 0x2a00\ncodecWithCustomNoneValue.encode(none()); // 0xff\n```\n\nFinally, note that if `prefix` is set to `null` and no `noneValue` is provided, the codec assume that the item exists if and only if some remaining bytes are available to decode. This could be useful to describe data structures that may or may not have additional data to the end of the buffer.\n\n```ts\nconst codec = getOptionCodec(getU16Codec(), { prefix: null });\ncodec.encode(some(42)); // 0x2a00\ncodec.encode(none()); // Encodes nothing.\ncodec.decode(new Uint8Array([42, 0])); // some(42)\ncodec.decode(new Uint8Array([])); // none()\n```\n\nTo recap, here are all the possible configurations of the `getOptionCodec` function, using a `u16` codec as an example.\n\n| `encode(some(42))` / `encode(none())` | No `noneValue` (default) | `noneValue: \"zeroes\"`       | Custom `noneValue` (`0xff`) |\n| ------------------------------------- | ------------------------ | --------------------------- | --------------------------- |\n| `u8` prefix (default)                 | `0x012a00` / `0x00`      | `0x012a00` / `0x000000`     | `0x012a00` / `0x00ff`       |\n| Custom `prefix` (`u16`)               | `0x01002a00` / `0x0000`  | `0x01002a00` / `0x00000000` | `0x01002a00` / `0x0000ff`   |\n| No `prefix`                           | `0x2a00` / `0x`          | `0x2a00` / `0x0000`         | `0x2a00` / `0xff`           |\n\nSeparate `getOptionEncoder` and `getOptionDecoder` functions are also available.\n\n```ts\nconst bytes = getOptionEncoder(getU32Encoder()).encode(some(42));\nconst value = getOptionDecoder(getU32Decoder()).decode(bytes);\n```\n\nTo read more about the available codecs and how to use them, check out the documentation of the main [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs).\n"
  },
  {
    "path": "packages/options/package.json",
    "content": "{\n    \"name\": \"@solana/options\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Managing and serializing Rust-like Option types in JavaScript\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaoptions\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.node.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.native.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-data-structures\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/options/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/options/src/__tests__/__setup__.ts",
    "content": "import { Codec, createCodec } from '@solana/codecs-core';\nimport { getBase16Codec } from '@solana/codecs-strings';\n\nexport const base16 = getBase16Codec();\nexport const b = (s: string) => base16.encode(s);\n\nexport const getMockCodec = (\n    config: {\n        defaultValue?: string;\n        description?: string;\n        size?: number | null;\n    } = {},\n) =>\n    createCodec({\n        ...(config.size != null ? { fixedSize: config.size } : { getSizeFromValue: jest.fn().mockReturnValue(0) }),\n        read: jest.fn().mockReturnValue([config.defaultValue ?? '', 0]),\n        write: jest.fn().mockReturnValue(0),\n    }) as Codec<unknown> & {\n        readonly getSizeFromValue: jest.Mock;\n        readonly read: jest.Mock;\n        readonly write: jest.Mock;\n    };\n"
  },
  {
    "path": "packages/options/src/__tests__/option-codec-test.ts",
    "content": "import { getShortU16Codec, getU8Codec, getU16Codec, getU32Codec, getU64Codec } from '@solana/codecs-numbers';\nimport { getUtf8Codec } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH, SolanaError } from '@solana/errors';\n\nimport { none, some } from '../option';\nimport { getOptionCodec } from '../option-codec';\nimport { b } from './__setup__';\n\ndescribe('getOptionCodec', () => {\n    describe('with prefix', () => {\n        it('encodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec());\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(some(0))).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00'));\n            expect(codec.encode(none())).toStrictEqual(b('00'));\n        });\n\n        it('decodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec());\n            expect(codec.decode(b('010000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('012a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('00'))).toStrictEqual(none());\n        });\n\n        it('encodes option numbers with explicit prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { prefix: getU8Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(some(0))).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00'));\n            expect(codec.encode(none())).toStrictEqual(b('00'));\n        });\n\n        it('decodes option numbers with explicit prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { prefix: getU8Codec() });\n            expect(codec.decode(b('010000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('012a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('00'))).toStrictEqual(none());\n        });\n\n        it('encodes option numbers with custom prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { prefix: getU32Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000000000'));\n            expect(codec.encode(some(0))).toStrictEqual(b('010000000000'));\n            expect(codec.encode(42)).toStrictEqual(b('010000002a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('010000002a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00000000'));\n            expect(codec.encode(none())).toStrictEqual(b('00000000'));\n        });\n\n        it('decodes option numbers with custom prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { prefix: getU32Codec() });\n            expect(codec.decode(b('010000000000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('010000002a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('00000000'))).toStrictEqual(none());\n        });\n\n        it('encodes option variable strings', () => {\n            const codec = getOptionCodec(getUtf8Codec());\n            expect(codec.encode('Hello')).toStrictEqual(b('0148656c6c6f'));\n            expect(codec.encode(some('Hello'))).toStrictEqual(b('0148656c6c6f'));\n            expect(codec.encode(null)).toStrictEqual(b('00'));\n            expect(codec.encode(none())).toStrictEqual(b('00'));\n        });\n\n        it('decodes option variable strings', () => {\n            const codec = getOptionCodec(getUtf8Codec());\n            expect(codec.decode(b('0148656c6c6f'))).toStrictEqual(some('Hello'));\n            expect(codec.decode(b('00'))).toStrictEqual(none());\n        });\n\n        it('encodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec()));\n            expect(codec.encode(42)).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(some(42)))).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(null))).toStrictEqual(b('0100'));\n            expect(codec.encode(some(none()))).toStrictEqual(b('0100'));\n            expect(codec.encode(null)).toStrictEqual(b('00'));\n            expect(codec.encode(none())).toStrictEqual(b('00'));\n        });\n\n        it('decodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec()));\n            expect(codec.decode(b('01012a00'))).toStrictEqual(some(some(42)));\n            expect(codec.decode(b('0100'))).toStrictEqual(some(none()));\n            expect(codec.decode(b('00'))).toStrictEqual(none());\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getOptionCodec(getU16Codec());\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(6);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(4);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getOptionCodec(getU16Codec());\n            expect(codec.read(b('ffff01010100'), 2)).toStrictEqual([some(257), 5]);\n            expect(codec.read(b('ffff00'), 2)).toStrictEqual([none(), 3]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getOptionCodec(getU64Codec());\n            expect(codec.encode(2)).toStrictEqual(b('010200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('010200000000000000'));\n            expect(codec.decode(b('010200000000000000'))).toStrictEqual(some(2n));\n        });\n\n        it('returns a variable size codec with max size', () => {\n            const codec = getOptionCodec(getU16Codec());\n            expect(codec.getSizeFromValue(null)).toBe(1);\n            expect(codec.getSizeFromValue(42)).toBe(3);\n            expect(codec.maxSize).toBe(3);\n        });\n    });\n\n    describe('with zeroable none value', () => {\n        it('encodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('2a00'));\n            expect(codec.encode(null)).toStrictEqual(b('0000'));\n            expect(codec.encode(none())).toStrictEqual(b('0000'));\n        });\n\n        it('decodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.decode(b('2a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('0000'))).toStrictEqual(none());\n        });\n\n        it('can end up encoding the none value', () => {\n            // ...because the item codec could use offsets to update the bytes in different ways.\n            // Therefore checking that the encoded value is the same as the none value is not enough.\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.encode(0)).toStrictEqual(b('0000'));\n        });\n\n        it('encodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null }), {\n                noneValue: 'zeroes',\n                prefix: null,\n            });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(some(42)))).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(null))).toStrictEqual(b('0000'));\n            expect(codec.encode(some(none()))).toStrictEqual(b('0000'));\n            expect(codec.encode(null)).toStrictEqual(b('0000'));\n            expect(codec.encode(none())).toStrictEqual(b('0000'));\n        });\n\n        it('decodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null }), {\n                noneValue: 'zeroes',\n                prefix: null,\n            });\n            expect(codec.decode(b('2a00'))).toStrictEqual(some(some(42)));\n            expect(codec.decode(b('0000'))).toStrictEqual(none());\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(5);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(5);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.read(b('ffff010100'), 2)).toStrictEqual([some(257), 4]);\n            expect(codec.read(b('ffff000000'), 2)).toStrictEqual([none(), 4]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getOptionCodec(getU64Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.encode(2)).toStrictEqual(b('0200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('0200000000000000'));\n            expect(codec.decode(b('0200000000000000'))).toStrictEqual(some(2n));\n        });\n\n        it('returns a fixed size codec', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: null });\n            expect(codec.fixedSize).toBe(2);\n        });\n\n        it('fails if the items is not fixed', () => {\n            // @ts-expect-error It cannot wrap a variable size item when fixed is true.\n            expect(() => getOptionCodec(getUtf8Codec(), { noneValue: 'zeroes', prefix: null })).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH),\n            );\n        });\n    });\n\n    describe('with custom none value', () => {\n        it('encodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('2a00'));\n            expect(codec.encode(null)).toStrictEqual(b('ffff'));\n            expect(codec.encode(none())).toStrictEqual(b('ffff'));\n        });\n\n        it('decodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.decode(b('2a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('ffff'))).toStrictEqual(none());\n        });\n\n        it('can end up encoding the none value', () => {\n            // ...because the item codec could use offsets to update the bytes in different ways.\n            // Therefore checking that the encoded value is the same as the none value is not enough.\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.encode(65535)).toStrictEqual(b('ffff'));\n        });\n\n        it('encodes option variable strings', () => {\n            const codec = getOptionCodec(getUtf8Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.encode('Hello')).toStrictEqual(b('48656c6c6f'));\n            expect(codec.encode(some('Hello'))).toStrictEqual(b('48656c6c6f'));\n            expect(codec.encode(null)).toStrictEqual(b('ffff'));\n            expect(codec.encode(none())).toStrictEqual(b('ffff'));\n        });\n\n        it('decodes option variable strings', () => {\n            const codec = getOptionCodec(getUtf8Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.decode(b('48656c6c6f'))).toStrictEqual(some('Hello'));\n            expect(codec.decode(b('ffff'))).toStrictEqual(none());\n        });\n\n        it('encodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null }), {\n                noneValue: b('ffff'),\n                prefix: null,\n            });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(some(42)))).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(null))).toStrictEqual(b('ffff'));\n            expect(codec.encode(some(none()))).toStrictEqual(b('ffff'));\n            expect(codec.encode(null)).toStrictEqual(b('ffff'));\n            expect(codec.encode(none())).toStrictEqual(b('ffff'));\n        });\n\n        it('decodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null }), {\n                noneValue: b('ffff'),\n                prefix: null,\n            });\n            expect(codec.decode(b('2a00'))).toStrictEqual(some(some(42)));\n            expect(codec.decode(b('ffff'))).toStrictEqual(none());\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(5);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(5);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('aaaa'), prefix: null });\n            expect(codec.read(b('ffff010100'), 2)).toStrictEqual([some(257), 4]);\n            expect(codec.read(b('ffffaaaa00'), 2)).toStrictEqual([none(), 4]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getOptionCodec(getU64Codec(), { noneValue: b('ffff'), prefix: null });\n            expect(codec.encode(2)).toStrictEqual(b('0200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('0200000000000000'));\n            expect(codec.decode(b('0200000000000000'))).toStrictEqual(some(2n));\n        });\n\n        it('returns a variable size codec', () => {\n            // ...because the item and the none value do not need to have the same length.\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffffffff'), prefix: null });\n            expect(codec.getSizeFromValue(null)).toBe(4);\n            expect(codec.getSizeFromValue(42)).toBe(2);\n            expect(codec.maxSize).toBe(4);\n        });\n    });\n\n    describe('with prefix and zeroable none value', () => {\n        it('encodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(some(0))).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('000000'));\n            expect(codec.encode(none())).toStrictEqual(b('000000'));\n        });\n\n        it('decodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.decode(b('010000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('012a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('000000'))).toStrictEqual(none());\n        });\n\n        it('encodes option numbers with explicit prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getU8Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(some(0))).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('000000'));\n            expect(codec.encode(none())).toStrictEqual(b('000000'));\n        });\n\n        it('decodes option numbers with explicit prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getU8Codec() });\n            expect(codec.decode(b('010000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('012a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('000000'))).toStrictEqual(none());\n        });\n\n        it('encodes option numbers with custom prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getU32Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000000000'));\n            expect(codec.encode(42)).toStrictEqual(b('010000002a00'));\n            expect(codec.encode(null)).toStrictEqual(b('000000000000'));\n        });\n\n        it('decodes option numbers with custom prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getU32Codec() });\n            expect(codec.decode(b('010000000000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('010000002a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('000000000000'))).toStrictEqual(none());\n        });\n\n        it('encodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { noneValue: 'zeroes' }), {\n                noneValue: 'zeroes',\n            });\n            expect(codec.encode(42)).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(some(42)))).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(null))).toStrictEqual(b('01000000'));\n            expect(codec.encode(some(none()))).toStrictEqual(b('01000000'));\n            expect(codec.encode(null)).toStrictEqual(b('00000000'));\n            expect(codec.encode(none())).toStrictEqual(b('00000000'));\n        });\n\n        it('decodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { noneValue: 'zeroes' }), {\n                noneValue: 'zeroes',\n            });\n            expect(codec.decode(b('01012a00'))).toStrictEqual(some(some(42)));\n            expect(codec.decode(b('01000000'))).toStrictEqual(some(none()));\n            expect(codec.decode(b('00000000'))).toStrictEqual(none());\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(6);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(6);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.read(b('ffff01010100'), 2)).toStrictEqual([some(257), 5]);\n            expect(codec.read(b('ffff00000000'), 2)).toStrictEqual([none(), 5]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getOptionCodec(getU64Codec(), { noneValue: 'zeroes' });\n            expect(codec.encode(2)).toStrictEqual(b('010200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('010200000000000000'));\n            expect(codec.decode(b('010200000000000000'))).toStrictEqual(some(2n));\n        });\n\n        it('returns a fixed size codec if the prefix is fixed', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes' });\n            expect(codec.fixedSize).toBe(3);\n        });\n\n        it('returns a variable size codec if the prefix is variable', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes', prefix: getShortU16Codec() });\n            expect(codec.getSizeFromValue(null)).toBe(3);\n            expect(codec.getSizeFromValue(42)).toBe(3);\n            expect(codec.maxSize).toBe(5);\n        });\n\n        it('fails if the items is not fixed', () => {\n            // @ts-expect-error It cannot wrap a variable size item when fixed is true.\n            expect(() => getOptionCodec(getUtf8Codec(), { noneValue: 'zeroes' })).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH),\n            );\n        });\n    });\n\n    describe('with prefix and custom none value', () => {\n        it('encodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff') });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(some(0))).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00ffff'));\n            expect(codec.encode(none())).toStrictEqual(b('00ffff'));\n        });\n\n        it('decodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff') });\n            expect(codec.decode(b('010000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('012a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('00ffff'))).toStrictEqual(none());\n        });\n\n        it('encodes option numbers with explicit prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: getU8Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000'));\n            expect(codec.encode(some(0))).toStrictEqual(b('010000'));\n            expect(codec.encode(42)).toStrictEqual(b('012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('012a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00ffff'));\n            expect(codec.encode(none())).toStrictEqual(b('00ffff'));\n        });\n\n        it('decodes option numbers with explicit prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: getU8Codec() });\n            expect(codec.decode(b('010000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('012a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('00ffff'))).toStrictEqual(none());\n        });\n\n        it('encodes option numbers with custom prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: getU32Codec() });\n            expect(codec.encode(0)).toStrictEqual(b('010000000000'));\n            expect(codec.encode(some(0))).toStrictEqual(b('010000000000'));\n            expect(codec.encode(42)).toStrictEqual(b('010000002a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('010000002a00'));\n            expect(codec.encode(null)).toStrictEqual(b('00000000ffff'));\n            expect(codec.encode(none())).toStrictEqual(b('00000000ffff'));\n        });\n\n        it('decodes option numbers with custom prefix', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff'), prefix: getU32Codec() });\n            expect(codec.decode(b('010000000000'))).toStrictEqual(some(0));\n            expect(codec.decode(b('010000002a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b('00000000ffff'))).toStrictEqual(none());\n        });\n\n        it('encodes option variable strings', () => {\n            const codec = getOptionCodec(getUtf8Codec(), { noneValue: b('ffff') });\n            expect(codec.encode('Hello')).toStrictEqual(b('0148656c6c6f'));\n            expect(codec.encode(some('Hello'))).toStrictEqual(b('0148656c6c6f'));\n            expect(codec.encode(null)).toStrictEqual(b('00ffff'));\n            expect(codec.encode(none())).toStrictEqual(b('00ffff'));\n        });\n\n        it('decodes option variable strings', () => {\n            const codec = getOptionCodec(getUtf8Codec(), { noneValue: b('ffff') });\n            expect(codec.decode(b('0148656c6c6f'))).toStrictEqual(some('Hello'));\n            expect(codec.decode(b('00ffff'))).toStrictEqual(none());\n        });\n\n        it('encodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { noneValue: b('ffff') }), {\n                noneValue: b('ffff'),\n            });\n            expect(codec.encode(42)).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(some(42)))).toStrictEqual(b('01012a00'));\n            expect(codec.encode(some(null))).toStrictEqual(b('0100ffff'));\n            expect(codec.encode(some(none()))).toStrictEqual(b('0100ffff'));\n            expect(codec.encode(null)).toStrictEqual(b('00ffff'));\n            expect(codec.encode(none())).toStrictEqual(b('00ffff'));\n        });\n\n        it('decodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { noneValue: b('ffff') }), {\n                noneValue: b('ffff'),\n            });\n            expect(codec.decode(b('01012a00'))).toStrictEqual(some(some(42)));\n            expect(codec.decode(b('0100ffff'))).toStrictEqual(some(none()));\n            expect(codec.decode(b('00ffff'))).toStrictEqual(none());\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffff') });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(6);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(6);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('aaaa') });\n            expect(codec.read(b('ffff01010100'), 2)).toStrictEqual([some(257), 5]);\n            expect(codec.read(b('ffff00aaaa00'), 2)).toStrictEqual([none(), 5]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getOptionCodec(getU64Codec(), { noneValue: b('ffff') });\n            expect(codec.encode(2)).toStrictEqual(b('010200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('010200000000000000'));\n            expect(codec.decode(b('010200000000000000'))).toStrictEqual(some(2n));\n        });\n\n        it('returns a variable size codec', () => {\n            // ...because the item and the none value do not need to have the same length.\n            const codec = getOptionCodec(getU16Codec(), { noneValue: b('ffffffff') });\n            expect(codec.getSizeFromValue(null)).toBe(5);\n            expect(codec.getSizeFromValue(42)).toBe(3);\n            expect(codec.maxSize).toBe(5);\n        });\n    });\n\n    describe('with no prefix nor none value', () => {\n        it('encodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { prefix: null });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('2a00'));\n            expect(codec.encode(null)).toStrictEqual(b(''));\n            expect(codec.encode(none())).toStrictEqual(b(''));\n        });\n\n        it('decodes option numbers', () => {\n            const codec = getOptionCodec(getU16Codec(), { prefix: null });\n            expect(codec.decode(b('2a00'))).toStrictEqual(some(42));\n            expect(codec.decode(b(''))).toStrictEqual(none());\n        });\n\n        it('encodes option variable strings', () => {\n            const codec = getOptionCodec(getUtf8Codec(), { prefix: null });\n            expect(codec.encode('Hello')).toStrictEqual(b('48656c6c6f'));\n            expect(codec.encode(some('Hello'))).toStrictEqual(b('48656c6c6f'));\n            expect(codec.encode(null)).toStrictEqual(b(''));\n            expect(codec.encode(none())).toStrictEqual(b(''));\n        });\n\n        it('decodes option variable strings', () => {\n            const codec = getOptionCodec(getUtf8Codec(), { prefix: null });\n            expect(codec.decode(b('48656c6c6f'))).toStrictEqual(some('Hello'));\n            expect(codec.decode(b(''))).toStrictEqual(none());\n        });\n\n        it('encodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { prefix: null }), { prefix: null });\n            expect(codec.encode(42)).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(42))).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(some(42)))).toStrictEqual(b('2a00'));\n            expect(codec.encode(some(null))).toStrictEqual(b(''));\n            expect(codec.encode(some(none()))).toStrictEqual(b(''));\n            expect(codec.encode(null)).toStrictEqual(b(''));\n            expect(codec.encode(none())).toStrictEqual(b(''));\n        });\n\n        it('decodes nested option numbers', () => {\n            const codec = getOptionCodec(getOptionCodec(getU16Codec(), { prefix: null }), { prefix: null });\n            expect(codec.decode(b('2a00'))).toStrictEqual(some(some(42)));\n            expect(codec.decode(b(''))).toStrictEqual(none());\n        });\n\n        it('pushes the offset forward when writing', () => {\n            const codec = getOptionCodec(getU16Codec(), { prefix: null });\n            expect(codec.write(257, new Uint8Array(10), 3)).toBe(5);\n            expect(codec.write(null, new Uint8Array(10), 3)).toBe(3);\n        });\n\n        it('pushes the offset forward when reading', () => {\n            const codec = getOptionCodec(getU16Codec(), { prefix: null });\n            expect(codec.read(b('ffff010100'), 2)).toStrictEqual([some(257), 4]);\n            expect(codec.read(b('ffff'), 2)).toStrictEqual([none(), 2]);\n        });\n\n        it('encodes and decodes different from and to types', () => {\n            const codec = getOptionCodec(getU64Codec(), { prefix: null });\n            expect(codec.encode(2)).toStrictEqual(b('0200000000000000'));\n            expect(codec.encode(2n)).toStrictEqual(b('0200000000000000'));\n            expect(codec.decode(b('0200000000000000'))).toStrictEqual(some(2n));\n        });\n\n        it('returns a variable size codec', () => {\n            // ...because the item and the none value do not need to have the same length.\n            const codec = getOptionCodec(getU16Codec(), { prefix: null });\n            expect(codec.getSizeFromValue(null)).toBe(0);\n            expect(codec.getSizeFromValue(42)).toBe(2);\n            expect(codec.maxSize).toBe(2);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/options/src/__tests__/option-test.ts",
    "content": "import { isNone, isSome, none, Option, some } from '../option';\n\ndescribe('Option', () => {\n    it('can create Some and None options', () => {\n        const optionA: Option<number> = some(42);\n        expect(optionA).toStrictEqual({ __option: 'Some', value: 42 });\n\n        const optionB: Option<null> = some(null);\n        expect(optionB).toStrictEqual({ __option: 'Some', value: null });\n\n        const optionC: Option<unknown> = none();\n        expect(optionC).toStrictEqual({ __option: 'None' });\n\n        const optionD: Option<string> = none<string>();\n        expect(optionD).toStrictEqual({ __option: 'None' });\n    });\n\n    it('can check if an option is Some or None', () => {\n        const optionA = some(42);\n        expect(isSome(optionA)).toBe(true);\n        expect(isNone(optionA)).toBe(false);\n\n        const optionB = none<number>();\n        expect(isSome(optionB)).toBe(false);\n        expect(isNone(optionB)).toBe(true);\n    });\n});\n"
  },
  {
    "path": "packages/options/src/__tests__/unwrap-option-recursively-test.ts",
    "content": "import { none, some } from '../option';\nimport { unwrapOptionRecursively } from '../unwrap-option-recursively';\n\ndescribe('unwrapOptionRecursively', () => {\n    it('can unwrap options recursively', () => {\n        // Some.\n        expect(unwrapOptionRecursively(some(null))).toBeNull();\n        expect(unwrapOptionRecursively(some(42))).toBe(<number | null>42);\n        expect(unwrapOptionRecursively(some('hello'))).toBe(<string | null>'hello');\n\n        // None.\n        expect(unwrapOptionRecursively(none())).toBeNull();\n        expect(unwrapOptionRecursively(none<number>()) satisfies number | null).toBeNull();\n        expect(unwrapOptionRecursively(none<string>()) satisfies string | null).toBeNull();\n\n        // Nested Some and None.\n        expect(unwrapOptionRecursively(some(some(some(false))))).toBe(<boolean | null>false);\n        expect(unwrapOptionRecursively(some(some(none<42>()))) satisfies 42 | null).toBeNull();\n\n        // Scalars.\n        expect(unwrapOptionRecursively(1)).toBe(1);\n        expect(unwrapOptionRecursively('hello')).toBe('hello');\n        expect(unwrapOptionRecursively(true)).toBe(true);\n        expect(unwrapOptionRecursively(false)).toBe(false);\n        expect(unwrapOptionRecursively(null)).toBeNull();\n        expect(unwrapOptionRecursively(undefined)).toBeUndefined();\n\n        // TypedArrays.\n        expect(unwrapOptionRecursively(new Uint8Array([1, 2, 3]))).toStrictEqual(new Uint8Array([1, 2, 3]));\n\n        // Functions.\n        const fn = () => 42;\n        expect(unwrapOptionRecursively(fn)).toStrictEqual(fn);\n\n        // Objects.\n        expect(unwrapOptionRecursively({ foo: 'hello' })).toStrictEqual({ foo: 'hello' });\n        expect(unwrapOptionRecursively({ foo: [1, true, '3'] })).toStrictEqual({ foo: [1, true, '3'] });\n        expect(unwrapOptionRecursively({ foo: none<string>() })).toStrictEqual({ foo: null });\n        expect(unwrapOptionRecursively({ foo: some(none<string>()) })).toStrictEqual({ foo: null });\n        expect(unwrapOptionRecursively(some({ baz: none<number>(), foo: some('bar') }))).toStrictEqual(<\n            { baz: number | null; foo: string | null } | null\n        >{ baz: null, foo: 'bar' });\n\n        // Arrays.\n        expect(unwrapOptionRecursively([1, true, '3'])).toStrictEqual([1, true, '3']);\n        expect(unwrapOptionRecursively([some('a'), none<boolean>(), some(some(3)), 'b'])).toStrictEqual([\n            'a',\n            null,\n            3,\n            'b',\n        ]);\n        expect(unwrapOptionRecursively([some('a'), none<boolean>(), some(some(3)), 'b'] as const)).toStrictEqual(<\n            [string | null, boolean | null, number | null, string]\n        >['a', null, 3, 'b']);\n\n        // Combination.\n        const person = {\n            address: {\n                city: 'Edmonton',\n                country: 'Canada',\n                phone: none<string>(),\n                region: some('Alberta'),\n                street: '11215 104 Ave NW',\n                zipcode: 'T5K 2S1',\n            },\n            age: 42,\n            gender: none<string>(),\n            interests: [\n                { category: some('IT'), name: 'Programming' },\n                { category: some('Music'), name: 'Modular Synths' },\n                { category: none<string>(), name: 'Popping bubble wrap' },\n            ],\n            name: 'Roo',\n        };\n        const unwrappedPerson = unwrapOptionRecursively(person);\n        type ExpectedUnwrappedPerson = {\n            address: {\n                city: string;\n                country: string;\n                phone: string | null;\n                region: string | null;\n                street: string;\n                zipcode: string;\n            };\n            age: number;\n            gender: string | null;\n            interests: Array<{ category: string | null; name: string }>;\n            name: string;\n        };\n        expect(unwrappedPerson).toStrictEqual(<ExpectedUnwrappedPerson>{\n            address: {\n                city: 'Edmonton',\n                country: 'Canada',\n                phone: null,\n                region: 'Alberta',\n                street: '11215 104 Ave NW',\n                zipcode: 'T5K 2S1',\n            },\n            age: 42,\n            gender: null,\n            interests: [\n                { category: 'IT', name: 'Programming' },\n                { category: 'Music', name: 'Modular Synths' },\n                { category: null, name: 'Popping bubble wrap' },\n            ],\n            name: 'Roo',\n        });\n    });\n\n    it('can unwrap options recursively whilst using a custom fallback', () => {\n        const fallback = () => 42 as const;\n\n        // Some.\n        expect(unwrapOptionRecursively(some(null), fallback)).toBeNull();\n        expect(unwrapOptionRecursively(some(100), fallback)).toBe(100 satisfies number);\n        expect(unwrapOptionRecursively(some('hello'), fallback)).toBe('hello' satisfies string | 42);\n\n        // None.\n        expect(unwrapOptionRecursively(none(), fallback)).toBe(42 satisfies unknown);\n        expect(unwrapOptionRecursively(none<number>(), fallback)).toBe(42 satisfies number);\n        expect(unwrapOptionRecursively(none<string>(), fallback)).toBe(42 satisfies string | 42);\n\n        // Nested Some and None.\n        expect(unwrapOptionRecursively(some(some(some(false))), fallback)).toBe(false satisfies boolean | 42);\n        expect(unwrapOptionRecursively(some(some(none<100>())), fallback)).toBe(42 satisfies 42 | 100);\n\n        // Combination.\n        const person = {\n            address: {\n                city: 'Edmonton',\n                country: 'Canada',\n                phone: none<string>(),\n                region: some('Alberta'),\n                street: '11215 104 Ave NW',\n                zipcode: 'T5K 2S1',\n            },\n            age: 42,\n            gender: none<string>(),\n            interests: [\n                { category: some('IT'), name: 'Programming' },\n                { category: some('Music'), name: 'Modular Synths' },\n                { category: none<string>(), name: 'Popping bubble wrap' },\n            ],\n            name: 'Roo',\n        };\n        const unwrappedPerson = unwrapOptionRecursively(person, fallback);\n        type ExpectedUnwrappedPerson = {\n            address: {\n                city: string;\n                country: string;\n                phone: string | 42;\n                region: string | 42;\n                street: string;\n                zipcode: string;\n            };\n            age: number;\n            gender: string | 42;\n            interests: Array<{ category: string | 42; name: string }>;\n            name: string;\n        };\n        expect(unwrappedPerson).toStrictEqual({\n            address: {\n                city: 'Edmonton',\n                country: 'Canada',\n                phone: 42,\n                region: 'Alberta',\n                street: '11215 104 Ave NW',\n                zipcode: 'T5K 2S1',\n            },\n            age: 42,\n            gender: 42,\n            interests: [\n                { category: 'IT', name: 'Programming' },\n                { category: 'Music', name: 'Modular Synths' },\n                { category: 42, name: 'Popping bubble wrap' },\n            ],\n            name: 'Roo',\n        } satisfies ExpectedUnwrappedPerson);\n    });\n});\n"
  },
  {
    "path": "packages/options/src/__tests__/unwrap-option-test.ts",
    "content": "import { none, some } from '../option';\nimport { unwrapOption, wrapNullable } from '../unwrap-option';\n\ndescribe('unwrapOption', () => {\n    it('can unwrap an Option as a Nullable', () => {\n        expect(unwrapOption(some(42))).toBe(42);\n        expect(unwrapOption(some(null))).toBeNull();\n        expect(unwrapOption(some('hello'))).toBe('hello');\n        expect(unwrapOption(none())).toBeNull();\n        expect(unwrapOption(none<number>())).toBeNull();\n        expect(unwrapOption(none<string>())).toBeNull();\n    });\n\n    it('can unwrap an Option using a fallback callback', () => {\n        const fallbackA = () => 42 as const;\n        expect(unwrapOption(some(1), fallbackA)).toBe(1 satisfies number);\n        expect(unwrapOption(some('A'), fallbackA)).toBe('A' satisfies string | 42);\n        expect(unwrapOption(none(), fallbackA)).toBe(42 satisfies unknown);\n\n        const fallbackB = () => {\n            throw new Error('Fallback Error');\n        };\n        expect(unwrapOption(some(1), fallbackB)).toBe(1);\n        expect(unwrapOption(some('A'), fallbackB)).toBe('A');\n        expect(() => unwrapOption(none(), fallbackB)).toThrow('Fallback Error');\n    });\n\n    it('can wrap a Nullable as an Option', () => {\n        expect(wrapNullable(42)).toStrictEqual(some(42));\n        expect(wrapNullable('hello')).toStrictEqual(some('hello'));\n        expect(wrapNullable(false)).toStrictEqual(some(false));\n        expect(wrapNullable(undefined)).toStrictEqual(some(undefined));\n        expect(wrapNullable<string>(null)).toStrictEqual(none<string>());\n        expect(wrapNullable<number>(null)).toStrictEqual(none<number>());\n    });\n});\n"
  },
  {
    "path": "packages/options/src/__typetests__/option-codec-typetest.ts",
    "content": "import {\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport { Option, OptionOrNullable } from '../option';\nimport { getOptionCodec, getOptionDecoder, getOptionEncoder } from '../option-codec';\n\n{\n    // [getOptionEncoder]: It knows if the encoder is fixed size or variable size.\n    getOptionEncoder({} as FixedSizeEncoder<string>, { noneValue: 'zeroes' }) satisfies FixedSizeEncoder<\n        OptionOrNullable<string>\n    >;\n    getOptionEncoder({} as FixedSizeEncoder<string, 42>, {\n        noneValue: 'zeroes',\n        prefix: null,\n    }) satisfies FixedSizeEncoder<OptionOrNullable<string>, 42>;\n    getOptionEncoder({} as FixedSizeEncoder<string>) satisfies VariableSizeEncoder<OptionOrNullable<string>>;\n}\n\n{\n    // [getOptionDecoder]: It knows if the decoder is fixed size or variable size.\n    getOptionDecoder({} as FixedSizeDecoder<string>, { noneValue: 'zeroes' }) satisfies FixedSizeDecoder<\n        Option<string>\n    >;\n    getOptionDecoder({} as FixedSizeDecoder<string, 42>, {\n        noneValue: 'zeroes',\n        prefix: null,\n    }) satisfies FixedSizeDecoder<Option<string>, 42>;\n    getOptionDecoder({} as FixedSizeDecoder<string>) satisfies VariableSizeDecoder<Option<string>>;\n}\n\n{\n    // [getOptionCodec]: It knows if the codec is fixed size or variable size.\n    getOptionCodec({} as FixedSizeCodec<string>, { noneValue: 'zeroes' }) satisfies FixedSizeCodec<\n        OptionOrNullable<string>,\n        Option<string>\n    >;\n    getOptionCodec({} as FixedSizeCodec<string, string, 42>, {\n        noneValue: 'zeroes',\n        prefix: null,\n    }) satisfies FixedSizeCodec<OptionOrNullable<string>, Option<string>, 42>;\n    getOptionCodec({} as FixedSizeCodec<string>) satisfies VariableSizeCodec<OptionOrNullable<string>, Option<string>>;\n}\n"
  },
  {
    "path": "packages/options/src/index.ts",
    "content": "/**\n * This package allows us to manage and serialize Rust-like Option types in JavaScript.\n * It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * This package is also part of the [`@solana/codecs` package](https://github.com/anza-xyz/kit/tree/main/packages/codecs)\n * which acts as an entry point for all codec packages as well as for their documentation.\n *\n * @packageDocumentation\n */\nexport * from './option';\nexport * from './option-codec';\nexport * from './unwrap-option';\nexport * from './unwrap-option-recursively';\n"
  },
  {
    "path": "packages/options/src/option-codec.ts",
    "content": "import {\n    assertIsFixedSize,\n    Codec,\n    combineCodec,\n    containsBytes,\n    Decoder,\n    Encoder,\n    fixDecoderSize,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    fixEncoderSize,\n    ReadonlyUint8Array,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    getBooleanDecoder,\n    getBooleanEncoder,\n    getConstantDecoder,\n    getConstantEncoder,\n    getTupleDecoder,\n    getTupleEncoder,\n    getUnionDecoder,\n    getUnionEncoder,\n    getUnitDecoder,\n    getUnitEncoder,\n} from '@solana/codecs-data-structures';\nimport {\n    FixedSizeNumberCodec,\n    FixedSizeNumberDecoder,\n    FixedSizeNumberEncoder,\n    getU8Decoder,\n    getU8Encoder,\n    NumberCodec,\n    NumberDecoder,\n    NumberEncoder,\n} from '@solana/codecs-numbers';\n\nimport { isOption, isSome, None, none, Option, OptionOrNullable, Some, some } from './option';\nimport { wrapNullable } from './unwrap-option';\n\n/**\n * Defines the configuration options for {@link Option} codecs.\n *\n * The `getOptionCodec` function behaves similarly to {@link getNullableCodec}\n * but encodes `Option<T>` types instead of `T | null` types.\n *\n * This configuration controls how {@link None} values are encoded and how presence\n * is determined when decoding.\n *\n * @typeParam TPrefix - A number codec, encoder, or decoder used as the presence prefix.\n *\n * @see {@link getOptionEncoder}\n * @see {@link getOptionDecoder}\n * @see {@link getOptionCodec}\n */\nexport type OptionCodecConfig<TPrefix extends NumberCodec | NumberDecoder | NumberEncoder> = {\n    /**\n     * Specifies how {@link None} values are represented in the encoded data.\n     *\n     * - By default, {@link None} values are omitted from encoding.\n     * - `'zeroes'`: The bytes allocated for the value are filled with zeroes. This requires a fixed-size codec for the item.\n     * - Custom byte array: {@link None} values are replaced with a predefined byte sequence. This results in a variable-size codec.\n     *\n     * @defaultValue No explicit `noneValue` is used; {@link None} values are omitted.\n     */\n    noneValue?: ReadonlyUint8Array | 'zeroes';\n\n    /**\n     * The presence prefix used to distinguish between {@link None} and present values.\n     *\n     * - By default, a `u8` prefix is used (`0 = None`, `1 = Some`).\n     * - Custom number codec: Allows defining a different number size for the prefix.\n     * - `null`: No prefix is used; `noneValue` (if provided) determines {@link None}.\n     *   If no `noneValue` is set, {@link None} is identified by the absence of bytes.\n     *\n     * @defaultValue `u8` prefix.\n     */\n    prefix?: TPrefix | null;\n};\n\n/**\n * Returns an encoder for optional values using the {@link Option} type.\n *\n * This encoder serializes an {@link OptionOrNullable} value using a configurable approach:\n * - By default, a `u8` prefix is used (`0 = None`, `1 = Some`). This can be customized or disabled.\n * - If `noneValue: 'zeroes'` is set, {@link None} values are encoded as zeroes.\n * - If `noneValue` is a byte array, {@link None} values are replaced with the provided constant.\n *\n * Unlike {@link getNullableEncoder}, this encoder accepts both {@link Option} and {@link Nullable} values.\n *\n * For more details, see {@link getOptionCodec}.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n *\n * @param item - The encoder for the value that may be present.\n * @param config - Configuration options for encoding optional values.\n * @returns A `FixedSizeEncoder` or `VariableSizeEncoder` for encoding option values.\n *\n * @example\n * Encoding an optional string.\n * ```ts\n * const stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const encoder = getOptionEncoder(stringCodec);\n *\n * encoder.encode(some('Hi'));\n * encoder.encode('Hi');\n * // 0x01020000004869\n * //   | |       └-- utf8 string content (\"Hi\").\n * //   | └-- u32 string prefix (2 characters).\n * //   └-- 1-byte prefix (Some).\n *\n * encoder.encode(none());\n * encoder.encode(null);\n * // 0x00\n * //   └-- 1-byte prefix (None).\n * ```\n *\n * @see {@link getOptionCodec}\n */\nexport function getOptionEncoder<TFrom, TSize extends number>(\n    item: FixedSizeEncoder<TFrom, TSize>,\n    config: OptionCodecConfig<NumberEncoder> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeEncoder<OptionOrNullable<TFrom>, TSize>;\nexport function getOptionEncoder<TFrom>(\n    item: FixedSizeEncoder<TFrom>,\n    config: OptionCodecConfig<FixedSizeNumberEncoder> & { noneValue: 'zeroes' },\n): FixedSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n    item: FixedSizeEncoder<TFrom>,\n    config: OptionCodecConfig<NumberEncoder> & { noneValue: 'zeroes' },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config?: OptionCodecConfig<NumberEncoder> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeEncoder<OptionOrNullable<TFrom>>;\nexport function getOptionEncoder<TFrom>(\n    item: Encoder<TFrom>,\n    config: OptionCodecConfig<NumberEncoder> = {},\n): Encoder<OptionOrNullable<TFrom>> {\n    const prefix = (() => {\n        if (config.prefix === null) {\n            return transformEncoder(getUnitEncoder(), (_boolean: boolean) => undefined);\n        }\n        return getBooleanEncoder({ size: config.prefix ?? getU8Encoder() });\n    })();\n    const noneValue = (() => {\n        if (config.noneValue === 'zeroes') {\n            assertIsFixedSize(item);\n            return fixEncoderSize(getUnitEncoder(), item.fixedSize);\n        }\n        if (!config.noneValue) {\n            return getUnitEncoder();\n        }\n        return getConstantEncoder(config.noneValue);\n    })();\n\n    return getUnionEncoder(\n        [\n            transformEncoder(getTupleEncoder([prefix, noneValue]), (_value: None | null): [boolean, void] => [\n                false,\n                undefined,\n            ]),\n            transformEncoder(getTupleEncoder([prefix, item]), (value: Some<TFrom> | TFrom): [boolean, TFrom] => [\n                true,\n                isOption(value) && isSome(value) ? value.value : value,\n            ]),\n        ],\n        variant => {\n            const option = isOption<TFrom>(variant) ? variant : wrapNullable(variant);\n            return Number(isSome(option));\n        },\n    );\n}\n\n/**\n * Returns a decoder for optional values using the {@link Option} type.\n *\n * This decoder deserializes an `Option<T>` value using a configurable approach:\n * - By default, a `u8` prefix is used (`0 = None`, `1 = Some`). This can be customized or disabled.\n * - If `noneValue: 'zeroes'` is set, `None` values are identified by zeroes.\n * - If `noneValue` is a byte array, `None` values match the provided constant.\n *\n * Unlike {@link getNullableDecoder}, this decoder always outputs an {@link Option} type.\n *\n * For more details, see {@link getOptionCodec}.\n *\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param item - The decoder for the value that may be present.\n * @param config - Configuration options for decoding optional values.\n * @returns A `FixedSizeDecoder` or `VariableSizeDecoder` for decoding option values.\n *\n * @example\n * Decoding an optional string with a size prefix.\n * ```ts\n * const stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const decoder = getOptionDecoder(stringCodec);\n *\n * decoder.decode(new Uint8Array([0x01, 0x02, 0x00, 0x00, 0x00, 0x48, 0x69]));\n * // some('Hi')\n *\n * decoder.decode(new Uint8Array([0x00]));\n * // none()\n * ```\n *\n * @see {@link getOptionCodec}\n */\nexport function getOptionDecoder<TTo, TSize extends number>(\n    item: FixedSizeDecoder<TTo, TSize>,\n    config: OptionCodecConfig<NumberDecoder> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeDecoder<Option<TTo>, TSize>;\nexport function getOptionDecoder<TTo>(\n    item: FixedSizeDecoder<TTo>,\n    config: OptionCodecConfig<FixedSizeNumberDecoder> & { noneValue: 'zeroes' },\n): FixedSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n    item: FixedSizeDecoder<TTo>,\n    config: OptionCodecConfig<NumberDecoder> & { noneValue: 'zeroes' },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n    item: Decoder<TTo>,\n    config?: OptionCodecConfig<NumberDecoder> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeDecoder<Option<TTo>>;\nexport function getOptionDecoder<TTo>(\n    item: Decoder<TTo>,\n    config: OptionCodecConfig<NumberDecoder> = {},\n): Decoder<Option<TTo>> {\n    const prefix = (() => {\n        if (config.prefix === null) {\n            return transformDecoder(getUnitDecoder(), () => false);\n        }\n        return getBooleanDecoder({ size: config.prefix ?? getU8Decoder() });\n    })();\n    const noneValue = (() => {\n        if (config.noneValue === 'zeroes') {\n            assertIsFixedSize(item);\n            return fixDecoderSize(getUnitDecoder(), item.fixedSize);\n        }\n        if (!config.noneValue) {\n            return getUnitDecoder();\n        }\n        return getConstantDecoder(config.noneValue);\n    })();\n\n    return getUnionDecoder(\n        [\n            transformDecoder(getTupleDecoder([prefix, noneValue]), () => none<TTo>()),\n            transformDecoder(getTupleDecoder([prefix, item]), ([, value]) => some(value)),\n        ],\n        (bytes, offset) => {\n            if (config.prefix === null && !config.noneValue) {\n                return Number(offset < bytes.length);\n            }\n            if (config.prefix === null && config.noneValue != null) {\n                const zeroValue =\n                    config.noneValue === 'zeroes' ? new Uint8Array(noneValue.fixedSize).fill(0) : config.noneValue;\n                return containsBytes(bytes, zeroValue, offset) ? 0 : 1;\n            }\n            return Number(prefix.read(bytes, offset)[0]);\n        },\n    );\n}\n\n/**\n * Returns a codec for encoding and decoding optional values using the {@link Option} type.\n *\n * This codec serializes and deserializes `Option<T>` values using a configurable approach:\n * - By default, a `u8` prefix is used (`0 = None`, `1 = Some`).\n * - If `noneValue: 'zeroes'` is set, `None` values are encoded/decoded as zeroes.\n * - If `noneValue` is a byte array, `None` values are represented by the provided constant.\n * - If `prefix: null` is set, the codec determines `None` values solely from `noneValue` or the presence of bytes.\n *\n * For more details on the configuration options, see {@link OptionCodecConfig}.\n *\n * Note that this behaves similarly to {@link getNullableCodec}, except it\n * encodes {@link OptionOrNullable} values and decodes {@link Option} values.\n *\n * @typeParam TFrom - The type of the main value being encoded.\n * @typeParam TTo - The type of the main value being decoded.\n *\n * @param item - The codec for the value that may be present.\n * @param config - Configuration options for encoding and decoding option values.\n * @returns A `FixedSizeCodec` or `VariableSizeCodec` for encoding and decoding option values.\n *\n * @example\n * Encoding and decoding an optional string with a size prefix.\n * ```ts\n * const stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const codec = getOptionCodec(stringCodec);\n *\n * const someBytes = codec.encode(some('Hi'));\n * // 0x01020000004869\n * //   | |       └-- utf8 string content (\"Hi\").\n * //   | └-- u32 string prefix (2 characters).\n * //   └-- 1-byte prefix (Some).\n *\n * const noneBytes = codec.encode(none());\n * // 0x00\n * //   └-- 1-byte prefix (None).\n *\n * codec.decode(someBytes); // some('Hi')\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @example\n * Encoding nullable values.\n * ```ts\n * const stringCodec = addCodecSizePrefix(getUtf8Codec(), getU32Codec());\n * const codec = getOptionCodec(stringCodec);\n *\n * const someBytes = codec.encode('Hi'); // 0x01020000004869\n * const noneBytes = codec.encode(null); // 0x00\n *\n * codec.decode(someBytes); // some('Hi')\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @example\n * Encoding and decoding an optional number with a fixed size.\n * ```ts\n * const codec = getOptionCodec(getU16Codec(), { noneValue: 'zeroes' });\n *\n * const someBytes = codec.encode(some(42)); // 0x012a00\n * const noneBytes = codec.encode(none());   // 0x000000\n *\n * codec.decode(someBytes); // some(42)\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @example\n * Encoding and decoding {@link None} values with a custom byte sequence and no prefix.\n * ```ts\n * const codec = getOptionCodec(getU16Codec(), {\n *   noneValue: new Uint8Array([0xff, 0xff]),\n *   prefix: null,\n * });\n *\n * const someBytes = codec.encode(some(42)); // 0x2a00\n * const noneBytes = codec.encode(none());   // 0xffff\n *\n * codec.decode(someBytes); // some(42)\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @example\n * Identifying {@link None} values by the absence of bytes.\n * ```ts\n * const codec = getOptionCodec(getU16Codec(), { prefix: null });\n *\n * const someBytes = codec.encode(some(42)); // 0x2a00\n * const noneBytes = codec.encode(none());   // new Uint8Array(0)\n *\n * codec.decode(someBytes); // some(42)\n * codec.decode(noneBytes); // none()\n * ```\n *\n * @remarks\n * Separate {@link getOptionEncoder} and {@link getOptionDecoder} functions are available.\n *\n * ```ts\n * const bytes = getOptionEncoder(getU32Encoder()).encode(some(42));\n * const value = getOptionDecoder(getU32Decoder()).decode(bytes);\n * ```\n *\n * @see {@link getOptionEncoder}\n * @see {@link getOptionDecoder}\n */\nexport function getOptionCodec<TFrom, TTo extends TFrom, TSize extends number>(\n    item: FixedSizeCodec<TFrom, TTo, TSize>,\n    config: OptionCodecConfig<NumberCodec> & { noneValue: 'zeroes'; prefix: null },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>, TSize>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: FixedSizeCodec<TFrom, TTo>,\n    config: OptionCodecConfig<FixedSizeNumberCodec> & { noneValue: 'zeroes' },\n): FixedSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: FixedSizeCodec<TFrom, TTo>,\n    config: OptionCodecConfig<NumberCodec> & { noneValue: 'zeroes' },\n): VariableSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config?: OptionCodecConfig<NumberCodec> & { noneValue?: ReadonlyUint8Array },\n): VariableSizeCodec<OptionOrNullable<TFrom>, Option<TTo>>;\nexport function getOptionCodec<TFrom, TTo extends TFrom = TFrom>(\n    item: Codec<TFrom, TTo>,\n    config: OptionCodecConfig<NumberCodec> = {},\n): Codec<OptionOrNullable<TFrom>, Option<TTo>> {\n    type ConfigCast = OptionCodecConfig<NumberCodec> & { noneValue?: ReadonlyUint8Array };\n    return combineCodec(\n        getOptionEncoder<TFrom>(item, config as ConfigCast),\n        getOptionDecoder<TTo>(item, config as ConfigCast),\n    );\n}\n"
  },
  {
    "path": "packages/options/src/option.ts",
    "content": "/**\n * An implementation of the Rust `Option<T>` type in JavaScript.\n *\n * In Rust, optional values are represented using `Option<T>`, which can be either:\n * - `Some(T)`, indicating a present value.\n * - `None`, indicating the absence of a value.\n *\n * In JavaScript, this is typically represented as `T | null`. However, this approach fails with nested options.\n * For example, `Option<Option<T>>` in Rust would translate to `T | null | null` in JavaScript, which is equivalent to `T | null`.\n * This means there is no way to differentiate between `Some(None)` and `None`, making nested options impossible.\n *\n * This `Option` type helps solve this by mirroring Rust’s `Option<T>` type.\n *\n * ```ts\n * type Option<T> = Some<T> | None;\n * type Some<T> = { __option: 'Some'; value: T };\n * type None = { __option: 'None' };\n * ```\n *\n * @typeParam T - The type of the contained value.\n *\n * @example\n * Here's how you can create `Option` values.\n *\n * To improve developer experience, helper functions are available.\n * TypeScript can infer the type of `T` or it can be explicitly provided.\n *\n * ```ts\n * // Create an option with a value.\n * some('Hello World');\n * some<number | string>(123);\n *\n * // Create an empty option.\n * none();\n * none<number | string>();\n * ```\n *\n * @see {@link Some}\n * @see {@link None}\n * @see {@link some}\n * @see {@link none}\n */\nexport type Option<T> = None | Some<T>;\n\n/**\n * A flexible type that allows working with {@link Option} values or nullable values.\n *\n * It defines a looser type that can be used when encoding {@link Option | Options}.\n * This allows us to pass `null` or the nested value directly whilst still\n * supporting the Option type for use-cases that need more type safety.\n *\n * @typeParam T - The type of the contained value.\n *\n * @example\n * Accepting both `Option<T>` and `T | null` as input.\n * ```ts\n * function double(value: OptionOrNullable<number>) {\n *   const option = isOption(value) ? value : wrapNullable(value);\n *   return isSome(option) ? option.value * 2 : 'No value';\n * }\n *\n * double(42);       // 84\n * double(some(21)); // 42\n * double(none());   // \"No value\"\n * double(null);     // \"No value\"\n * ```\n *\n * @see {@link Option}\n * @see {@link isOption}\n * @see {@link wrapNullable}\n */\nexport type OptionOrNullable<T> = Option<T> | T | null;\n\n/**\n * Represents an {@link Option} that contains a value.\n *\n * This type mirrors Rust’s `Some(T)`, indicating that a value is present.\n *\n * For more details, see {@link Option}.\n *\n * @typeParam T - The type of the contained value.\n *\n * @example\n * Creating a `Some` value.\n * ```ts\n * const value = some(42);\n * isSome(value); // true\n * isNone(value); // false\n * ```\n *\n * @see {@link Option}\n * @see {@link some}\n * @see {@link isSome}\n */\nexport type Some<T> = Readonly<{ __option: 'Some'; value: T }>;\n\n/**\n * Represents an {@link Option} that contains no value.\n *\n * This type mirrors Rust’s `None`, indicating the absence of a value.\n *\n * For more details, see {@link Option}.\n *\n * @example\n * Creating a `None` value.\n * ```ts\n * const empty = none();\n * isNone(empty); // true\n * isSome(empty); // false\n * ```\n *\n * @see {@link Option}\n * @see {@link none}\n * @see {@link isNone}\n */\nexport type None = Readonly<{ __option: 'None' }>;\n\n/**\n * Creates a new {@link Option} that contains a value.\n *\n * This function explicitly wraps a value in an {@link Option} type.\n *\n * @typeParam T - The type of the contained value.\n *\n * @param value - The value to wrap in an {@link Option}.\n * @returns An {@link Option} containing the provided value.\n *\n * @example\n * Wrapping a value in an `Option`.\n * ```ts\n * const option = some('Hello');\n * option.value;     // \"Hello\"\n * isOption(option); // true\n * isSome(option);   // true\n * isNone(option);   // false\n * ```\n *\n * @see {@link Option}\n * @see {@link Some}\n */\nexport const some = <T>(value: T): Option<T> => ({ __option: 'Some', value });\n\n/**\n * Creates a new {@link Option} that contains no value.\n *\n * This function explicitly represents an absent value.\n *\n * @typeParam T - The type of the expected absent value.\n *\n * @returns An {@link Option} containing no value.\n *\n * @example\n * Creating an empty `Option`.\n * ```ts\n * const empty = none<number>();\n * isOption(empty); // true\n * isSome(empty);   // false\n * isNone(empty);   // true\n * ```\n *\n * @see {@link Option}\n * @see {@link None}\n */\nexport const none = <T>(): Option<T> => ({ __option: 'None' });\n\n/**\n * Checks whether the given value is an {@link Option}.\n *\n * This function determines whether an input follows the `Option<T>` structure.\n *\n * @typeParam T - The type of the contained value.\n *\n * @param input - The value to check.\n * @returns `true` if the value is an {@link Option}, `false` otherwise.\n *\n * @example\n * Checking for `Option` values.\n * ```ts\n * isOption(some(42));        // true\n * isOption(none());          // true\n * isOption(42);              // false\n * isOption(null);            // false\n * isOption(\"anything else\"); // false\n * ```\n *\n * @see {@link Option}\n */\nexport const isOption = <T = unknown>(input: unknown): input is Option<T> =>\n    !!(\n        input &&\n        typeof input === 'object' &&\n        '__option' in input &&\n        ((input.__option === 'Some' && 'value' in input) || input.__option === 'None')\n    );\n\n/**\n * Checks whether the given {@link Option} contains a value.\n *\n * This function acts as a type guard, ensuring the value is a {@link Some}.\n *\n * @typeParam T - The type of the contained value.\n *\n * @param option - The {@link Option} to check.\n * @returns `true` if the option is a {@link Some}, `false` otherwise.\n *\n * @example\n * Checking for `Some` values.\n * ```ts\n * isSome(some(42)); // true\n * isSome(none());   // false\n * ```\n *\n * @see {@link Option}\n * @see {@link Some}\n */\nexport const isSome = <T>(option: Option<T>): option is Some<T> => option.__option === 'Some';\n\n/**\n * Checks whether the given {@link Option} contains no value.\n *\n * This function acts as a type guard, ensuring the value is a {@link None}.\n *\n * @typeParam T - The type of the expected value.\n *\n * @param option - The {@link Option} to check.\n * @returns `true` if the option is a {@link None}, `false` otherwise.\n *\n * @example\n * Checking for `None` values.\n * ```ts\n * isNone(some(42)); // false\n * isNone(none());   // true\n * ```\n *\n * @see {@link Option}\n * @see {@link None}\n */\nexport const isNone = <T>(option: Option<T>): option is None => option.__option === 'None';\n"
  },
  {
    "path": "packages/options/src/unwrap-option-recursively.ts",
    "content": "import { isOption, isSome, None, Some } from './option';\n\n/**\n * Defines types that should not be recursively unwrapped.\n *\n * These types are preserved as-is when using {@link unwrapOptionRecursively}.\n *\n * @see {@link unwrapOptionRecursively}\n */\ntype UnUnwrappables =\n    | Date\n    | Int8Array\n    | Int16Array\n    | Int32Array\n    | Uint8Array\n    | Uint16Array\n    | Uint32Array\n    | bigint\n    | boolean\n    | number\n    | string\n    | symbol\n    | null\n    | undefined;\n\n/**\n * A type that recursively unwraps nested {@link Option} types.\n *\n * This type resolves all nested {@link Option} values, ensuring\n * that deeply wrapped values are properly extracted.\n *\n * - If `T` is an {@link Option}, it resolves to the contained value.\n * - If `T` is a known primitive or immutable type, it remains unchanged.\n * - If `T` is an object or array, it recursively unwraps any options found.\n *\n * The fallback type `U` (default: `null`) is used in place of `None` values.\n *\n * @typeParam T - The type to be unwrapped.\n * @typeParam U - The fallback type for `None` values (defaults to `null`).\n *\n * @example\n * Resolving nested `Option` types.\n * ```ts\n * UnwrappedOption<Some<Some<string>>>; // string\n * UnwrappedOption<None>;               // null\n * ```\n *\n * @example\n * Resolving options inside objects and arrays.\n * ```ts\n * UnwrappedOption<{ a: Some<number>; b: None }>; // { a: number; b: null }\n * UnwrappedOption<[Some<number>, None]>;         // [number, null]\n * ```\n *\n * @see {@link unwrapOptionRecursively}\n */\nexport type UnwrappedOption<T, U = null> =\n    T extends Some<infer TValue>\n        ? UnwrappedOption<TValue, U>\n        : T extends None\n          ? U\n          : T extends UnUnwrappables\n            ? T\n            : T extends object\n              ? { [key in keyof T]: UnwrappedOption<T[key], U> }\n              : T extends Array<infer TItem>\n                ? Array<UnwrappedOption<TItem, U>>\n                : T;\n\n/**\n * Recursively unwraps all nested {@link Option} types within a value.\n *\n * This function traverses a given value and removes all instances\n * of {@link Option}, replacing them with their contained values.\n *\n * - If an {@link Option} is encountered, its value is extracted.\n * - If an array or object is encountered, its elements are traversed recursively.\n * - If `None` is encountered, it is replaced with the fallback value (default: `null`).\n *\n * @typeParam T - The type of the input value.\n * @typeParam U - The fallback type for `None` values (defaults to `null`).\n *\n * @param input - The value to unwrap.\n * @param fallback - A function that provides a fallback value for `None` options.\n * @returns The recursively unwrapped value.\n *\n * @example\n * Recursively unwrapping nested options.\n * ```ts\n * unwrapOptionRecursively(some(some('Hello World'))); // \"Hello World\"\n * unwrapOptionRecursively(some(none<string>()));      // null\n * ```\n *\n * @example\n * Recursively unwrapping options inside objects and arrays.\n * ```ts\n * unwrapOptionRecursively({\n *   a: 'hello',\n *   b: none(),\n *   c: [{ c1: some(42) }, { c2: none() }],\n * });\n * // { a: \"hello\", b: null, c: [{ c1: 42 }, { c2: null }] }\n * ```\n *\n * @example\n * Using a fallback value for `None` options.\n * ```ts\n * unwrapOptionRecursively(\n *   {\n *     a: 'hello',\n *     b: none(),\n *     c: [{ c1: some(42) }, { c2: none() }],\n *   },\n *   () => 'Default',\n * );\n * // { a: \"hello\", b: \"Default\", c: [{ c1: 42 }, { c2: \"Default\" }] }\n * ```\n *\n * @remarks\n * This function does not mutate objects or arrays.\n *\n * @see {@link Option}\n * @see {@link UnwrappedOption}\n */\nexport function unwrapOptionRecursively<T>(input: T): UnwrappedOption<T>;\nexport function unwrapOptionRecursively<T, U>(input: T, fallback: () => U): UnwrappedOption<T, U>;\nexport function unwrapOptionRecursively<T, U = null>(input: T, fallback?: () => U): UnwrappedOption<T, U> {\n    // Types to bypass.\n    if (!input || ArrayBuffer.isView(input)) {\n        return input as UnwrappedOption<T, U>;\n    }\n\n    const next = <X>(x: X) =>\n        (fallback ? unwrapOptionRecursively(x, fallback) : unwrapOptionRecursively(x)) as UnwrappedOption<X, U>;\n\n    // Handle Option.\n    if (isOption(input)) {\n        if (isSome(input)) return next(input.value) as UnwrappedOption<T, U>;\n        return (fallback ? fallback() : null) as UnwrappedOption<T, U>;\n    }\n\n    // Walk.\n    if (Array.isArray(input)) {\n        return input.map(next) as UnwrappedOption<T, U>;\n    }\n    if (typeof input === 'object') {\n        return Object.fromEntries(Object.entries(input).map(([k, v]) => [k, next(v)])) as UnwrappedOption<T, U>;\n    }\n    return input as UnwrappedOption<T, U>;\n}\n"
  },
  {
    "path": "packages/options/src/unwrap-option.ts",
    "content": "import { isSome, none, Option, some } from './option';\n\n/**\n * Unwraps the value of an {@link Option}, returning its contained value or a fallback.\n *\n * This function extracts the value `T` from an `Option<T>` type.\n * - If the option is {@link Some}, it returns the contained value `T`.\n * - If the option is {@link None}, it returns the fallback value `U`, which defaults to `null`.\n *\n * @typeParam T - The type of the contained value.\n * @typeParam U - The type of the fallback value (defaults to `null`).\n *\n * @param option - The {@link Option} to unwrap.\n * @param fallback - A function that provides a fallback value if the option is {@link None}.\n * @returns The contained value if {@link Some}, otherwise the fallback value.\n *\n * @example\n * Unwrapping an `Option` with no fallback.\n * ```ts\n * unwrapOption(some('Hello World')); // \"Hello World\"\n * unwrapOption(none());              // null\n * ```\n *\n * @example\n * Providing a custom fallback value.\n * ```ts\n * unwrapOption(some('Hello World'), () => 'Default'); // \"Hello World\"\n * unwrapOption(none(), () => 'Default');              // \"Default\"\n * ```\n *\n * @see {@link Option}\n * @see {@link Some}\n * @see {@link None}\n */\nexport function unwrapOption<T>(option: Option<T>): T | null;\nexport function unwrapOption<T, U>(option: Option<T>, fallback: () => U): T | U;\nexport function unwrapOption<T, U = null>(option: Option<T>, fallback?: () => U): T | U {\n    if (isSome(option)) return option.value;\n    return fallback ? fallback() : (null as U);\n}\n\n/**\n * Wraps a nullable value into an {@link Option}.\n *\n * - If the input value is `null`, this function returns {@link None}.\n * - Otherwise, it wraps the value in {@link Some}.\n *\n * @typeParam T - The type of the contained value.\n *\n * @param nullable - The nullable value to wrap.\n * @returns An {@link Option} wrapping the value.\n *\n * @example\n * Wrapping nullable values.\n * ```ts\n * wrapNullable('Hello World'); // Option<string> (Some)\n * wrapNullable<string>(null);  // Option<string> (None)\n * ```\n *\n * @see {@link Option}\n * @see {@link Some}\n * @see {@link None}\n */\nexport const wrapNullable = <T>(nullable: T | null): Option<T> => (nullable !== null ? some(nullable) : none<T>());\n"
  },
  {
    "path": "packages/options/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/options/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2019\"]\n    },\n    \"display\": \"@solana/options\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/options/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/plugin-core/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/plugin-core/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/plugin-core/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/plugin-core/CHANGELOG.md",
    "content": "# @solana/plugin-core\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- [#1569](https://github.com/anza-xyz/kit/pull/1569) [`b1ae82b`](https://github.com/anza-xyz/kit/commit/b1ae82bbb2159f17a3e0f337c5f8677613b5b32d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Fix `extendClient` so that a later plugin can override a key previously set by an earlier plugin. Previously, chaining two plugins that set the same key threw `TypeError: Cannot redefine property` because the frozen client's non-configurable property descriptors were copied verbatim onto the intermediate object.\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n### Minor Changes\n\n- [#1509](https://github.com/anza-xyz/kit/pull/1509) [`2763d0c`](https://github.com/anza-xyz/kit/commit/2763d0c92b60089f4b20f6241cb5f91232cc2e75) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `createClient` function that replaces `createEmptyClient` and accepts an optional initial value. The old `createEmptyClient` is preserved as a deprecated re-export.\n\n## 6.6.0\n\n### Minor Changes\n\n- [#1480](https://github.com/anza-xyz/kit/pull/1480) [`9c4fd6e`](https://github.com/anza-xyz/kit/commit/9c4fd6e67a6f70b1386f0745cf5afe0f93c75e36) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `withCleanup` function to `@solana/plugin-core`. Plugin authors can use it to register teardown logic (e.g. closing connections or clearing timers) on a client, making it `Disposable`. If the client already implements `Symbol.dispose`, the new cleanup function is chained so both run on disposal.\n\n## 6.5.0\n\n## 6.4.0\n\n### Minor Changes\n\n- [#1479](https://github.com/anza-xyz/kit/pull/1479) [`abeca1b`](https://github.com/anza-xyz/kit/commit/abeca1b28725f675128f68e4e73d2f655e500eaa) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `extendClient` helper for plugin authors to merge client objects while preserving property descriptors (getters, symbol-keyed properties, and non-enumerable properties).\n\n    Plugin authors should migrate plugins to use this instead of spreading the input client.\n\n    ```diff\n    - return { ...client, rpc };\n    + return extendClient(client, { rpc });\n    ```\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n## 6.1.0\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n## 5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n## 5.3.0\n\n## 5.2.0\n\n### Minor Changes\n\n- [#1113](https://github.com/anza-xyz/kit/pull/1113) [`b1937c7`](https://github.com/anza-xyz/kit/commit/b1937c7385050b911f50ac36913a6cfe4575036d) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `@solana/plugin-core` package enabling us to create modular Kit clients that can be extended with plugins.\n"
  },
  {
    "path": "packages/plugin-core/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/plugin-core/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/plugin-core?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/plugin-core?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/plugin-core\n\n# @solana/plugin-core\n\nThis package contains utilities for creating modular Kit clients that can be extended with plugins. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n"
  },
  {
    "path": "packages/plugin-core/package.json",
    "content": "{\n    \"name\": \"@solana/plugin-core\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Core helpers for creating and extending Kit clients with plugins\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaplugin-core\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/plugin-core/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/plugin-core/src/__tests__/client-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { createClient, extendClient, withCleanup } from '../client';\n\ndescribe('createClient', () => {\n    it('creates an empty object with a use function', () => {\n        const emptyClient = createClient();\n        expect(typeof emptyClient).toBe('object');\n        const attributes = Object.getOwnPropertyNames(emptyClient);\n        expect(attributes).toStrictEqual(['use']);\n        expect(typeof emptyClient.use).toBe('function');\n    });\n\n    it('creates an client from an existing object', () => {\n        const client = createClient({ fruit: 'banana' as const });\n        expect(typeof client).toBe('object');\n        const attributes = Object.getOwnPropertyNames(client);\n        expect(attributes).toStrictEqual(['fruit', 'use']);\n        expect(typeof client.use).toBe('function');\n        expect(client.fruit).toBe('banana');\n    });\n\n    it('evolves when using plugins', () => {\n        expect(\n            createClient()\n                .use(c => ({ ...c, fruit: 'apple' as const }))\n                .use(c => ({ ...c, vegetable: 'carrot' as const })),\n        ).toStrictEqual({\n            fruit: 'apple',\n            use: expect.any(Function),\n            vegetable: 'carrot',\n        });\n    });\n\n    it('can be overriden by subsequent plugins', () => {\n        expect(\n            createClient()\n                .use(() => ({ fruit: 'apple' as const }))\n                .use(() => ({ vegetable: 'carrot' as const })),\n        ).toStrictEqual({\n            use: expect.any(Function),\n            vegetable: 'carrot',\n        });\n    });\n\n    it('allows plugins to enforce input type constraints', () => {\n        expect(\n            createClient()\n                .use(c => ({ ...c, fruit: 'apple' as const }))\n                .use(<T extends { fruit: 'apple' }>(c: T) => ({ ...c, dessert: 'apple cake' as const })),\n        ).toStrictEqual({\n            dessert: 'apple cake',\n            fruit: 'apple',\n            use: expect.any(Function),\n        });\n    });\n\n    it('preserves getter properties from plugins', () => {\n        const client = createClient()\n            // Make fruit a get() property\n            .use(c => {\n                const result = { ...c };\n                Object.defineProperty(result, 'fruit', { configurable: true, enumerable: true, get: () => 'apple' });\n                return result;\n            })\n            // Make dessert a normal property\n            .use(c => {\n                // Use Object.defineProperties to preserve the getter on fruit\n                const result: typeof c = Object.defineProperties({}, Object.getOwnPropertyDescriptors(c));\n                Object.defineProperty(result, 'dessert', { configurable: true, enumerable: true, value: 'apple cake' });\n                return result;\n            });\n        expect(Object.getOwnPropertyDescriptor(client, 'fruit')?.get).toBeInstanceOf(Function);\n        expect((client as unknown as { fruit: string }).fruit).toBe('apple');\n        expect((client as unknown as { dessert: string }).dessert).toBe('apple cake');\n    });\n\n    it('preserves symbol-keyed properties from plugins', () => {\n        const sym = Symbol('fruit');\n\n        const client = createClient()\n            // Add the fruit symbol property\n            .use(c => ({ ...c, [sym]: 'apple' }))\n            // Add dessert as a normal property\n            .use(c => {\n                // Use Object.defineProperties to preserve the symbol on fruit\n                const result = Object.defineProperties({}, Object.getOwnPropertyDescriptors(c)) as typeof c;\n                Object.defineProperty(result, 'dessert', { configurable: true, enumerable: true, value: 'apple cake' });\n                return result;\n            });\n        expect((client as Record<symbol, unknown>)[sym]).toBe('apple');\n        expect((client as unknown as { dessert: string }).dessert).toBe('apple cake');\n    });\n\n    it('supports asynchronous plugins', async () => {\n        expect.assertions(1);\n        await expect(\n            createClient()\n                .use(c => Promise.resolve({ ...c, fruit: 'apple' as const }))\n                .use(c => Promise.resolve({ ...c, vegetable: 'carrot' as const })),\n        ).resolves.toStrictEqual({\n            fruit: 'apple',\n            use: expect.any(Function),\n            vegetable: 'carrot',\n        });\n    });\n\n    it('supports a mixture of synchronous and asynchronous plugins', async () => {\n        expect.assertions(1);\n        await expect(\n            createClient()\n                .use(c => ({ ...c, fruit: 'apple' as const }))\n                .use(c => Promise.resolve({ ...c, vegetable: 'carrot' as const }))\n                .use(c => ({ ...c, grain: 'rice' as const }))\n                .use(c => Promise.resolve({ ...c, protein: 'beans' as const })),\n        ).resolves.toStrictEqual({\n            fruit: 'apple',\n            grain: 'rice',\n            protein: 'beans',\n            use: expect.any(Function),\n            vegetable: 'carrot',\n        });\n    });\n\n    it('can catch synchronous errors', () => {\n        expect(() =>\n            createClient().use(() => {\n                throw new Error('Missing fruit');\n            }),\n        ).toThrow('Missing fruit');\n    });\n\n    it('can catch asynchronous errors', async () => {\n        expect.assertions(1);\n        await expect(\n            createClient().use(() => {\n                return Promise.reject(new Error('Missing fruit'));\n            }),\n        ).rejects.toThrow('Missing fruit');\n    });\n\n    it('can chain the then function on the async client', async () => {\n        expect.assertions(1);\n        const thenFn = jest.fn();\n        await createClient()\n            .use(() => Promise.resolve({ fruit: 'apple' as const }))\n            .then(thenFn);\n        expect(thenFn).toHaveBeenNthCalledWith(1, expect.objectContaining({ fruit: 'apple' }));\n    });\n\n    it('can chain the catch function on the async client', async () => {\n        expect.assertions(1);\n        const catchFn = jest.fn();\n        await createClient()\n            .use(() => Promise.reject(new Error('Missing fruit')))\n            .catch(catchFn);\n        expect(catchFn).toHaveBeenNthCalledWith(1, expect.objectContaining({ message: 'Missing fruit' }));\n    });\n\n    it('can chain the finally function on the async client when successful', async () => {\n        expect.assertions(1);\n        const finallyFn = jest.fn();\n        await createClient()\n            .use(() => Promise.resolve({ fruit: 'apple' as const }))\n            .finally(finallyFn);\n        expect(finallyFn).toHaveBeenCalledTimes(1);\n    });\n\n    it('can chain the finally function on the async client when unsuccessful', async () => {\n        expect.assertions(1);\n        const finallyFn = jest.fn();\n        await createClient()\n            .use(() => Promise.reject(new Error('Missing fruit')))\n            .finally(finallyFn)\n            .catch(() => {});\n        expect(finallyFn).toHaveBeenCalledTimes(1);\n    });\n\n    it('does not resolve subsequent asynchronous plugins after an error', async () => {\n        expect.assertions(1);\n        const subsequentPlugin = jest.fn();\n        await createClient()\n            .use(() => Promise.reject(new Error('Missing fruit')))\n            .use(subsequentPlugin)\n            .catch(() => {});\n        expect(subsequentPlugin).not.toHaveBeenCalled();\n    });\n\n    it('allows plugins to use createClient internally to offer plugin bundles', () => {\n        const fruitPlugin = <T extends object>(c: T) => ({ ...c, fruit: 'apple' as const });\n        const vegetablePlugin = <T extends object>(c: T) => ({ ...c, vegetable: 'carrot' as const });\n        const proteinPlugin = <T extends object>(c: T) => ({ ...c, protein: 'tofu' as const });\n        const foodPlugin = <T extends object>(c: T) =>\n            createClient(c).use(fruitPlugin).use(vegetablePlugin).use(proteinPlugin);\n\n        expect(createClient().use(foodPlugin)).toStrictEqual({\n            fruit: 'apple',\n            protein: 'tofu',\n            use: expect.any(Function),\n            vegetable: 'carrot',\n        });\n    });\n\n    it('returns a frozen object when empty', () => {\n        expect(createClient()).toBeFrozenObject();\n    });\n\n    it('returns a frozen object when extended by a plugin', () => {\n        expect(createClient().use(() => ({ fruit: 'apple' as const }))).toBeFrozenObject();\n    });\n\n    it('returns a frozen object when extended by an asynchronous plugin', () => {\n        expect(createClient().use(() => Promise.resolve({ fruit: 'apple' as const }))).toBeFrozenObject();\n    });\n});\n\ndescribe('extendClient', () => {\n    it('merges client and additions into a new object', () => {\n        expect(extendClient({ fruit: 'apple' as const }, { vegetable: 'carrot' as const })).toStrictEqual({\n            fruit: 'apple',\n            vegetable: 'carrot',\n        });\n    });\n\n    it('additions override client on key conflict', () => {\n        expect(extendClient({ fruit: 'apple' as const }, { fruit: 'banana' as const })).toStrictEqual({\n            fruit: 'banana',\n        });\n    });\n\n    it('client properties not present in additions are preserved', () => {\n        expect(\n            extendClient({ fruit: 'apple' as const, vegetable: 'carrot' as const }, { fruit: 'banana' as const }),\n        ).toStrictEqual(expect.objectContaining({ fruit: 'banana', vegetable: 'carrot' }));\n    });\n\n    it('preserves getter from client', () => {\n        const client = Object.defineProperty({} as { fruit: string }, 'fruit', {\n            configurable: true,\n            enumerable: true,\n            get: () => 'apple',\n        });\n        const result = extendClient(client, { vegetable: 'carrot' as const });\n        expect(Object.getOwnPropertyDescriptor(result, 'fruit')?.get).toBeInstanceOf(Function);\n        expect(result.fruit).toBe('apple');\n    });\n\n    it('preserves getter from additions', () => {\n        const additions = Object.defineProperty({} as { vegetable: string }, 'vegetable', {\n            configurable: true,\n            enumerable: true,\n            get: () => 'carrot',\n        });\n        const result = extendClient({ fruit: 'apple' as const }, additions);\n        expect(Object.getOwnPropertyDescriptor(result, 'vegetable')?.get).toBeInstanceOf(Function);\n        expect(result.vegetable).toBe('carrot');\n    });\n\n    it('preserves symbol-keyed property from client', () => {\n        const sym = Symbol('tag');\n        const result = extendClient({ [sym]: 'apple' }, { vegetable: 'carrot' as const });\n        expect((result as Record<symbol, unknown>)[sym]).toBe('apple');\n        expect(result.vegetable).toBe('carrot');\n    });\n\n    it('includes symbol-keyed property from additions', () => {\n        const sym = Symbol('tag');\n        const result = extendClient({ fruit: 'apple' as const }, { [sym]: 'carrot' });\n        expect((result as Record<symbol, unknown>)[sym]).toBe('carrot');\n    });\n\n    it('preserves non-enumerable property from client', () => {\n        const client = Object.defineProperty({}, 'secret', {\n            configurable: true,\n            enumerable: false,\n            value: 'hidden',\n            writable: true,\n        });\n        const result = extendClient(client, { vegetable: 'carrot' as const });\n        expect(Object.getOwnPropertyDescriptor(result, 'secret')?.enumerable).toBe(false);\n        expect((result as Record<string, unknown>)['secret']).toBe('hidden');\n    });\n\n    it('returns a frozen object', () => {\n        expect(extendClient({ fruit: 'apple' as const }, { vegetable: 'carrot' as const })).toBeFrozenObject();\n    });\n\n    it('allows a later plugin to override a key set by an earlier plugin', () => {\n        const client = createClient()\n            .use(c => extendClient(c, { payer: 'A' as const }))\n            .use(c => extendClient(c, { payer: 'B' as const }));\n        expect(client.payer).toBe('B');\n    });\n\n    it('allows override when the earlier plugin set multiple keys', () => {\n        const client = createClient()\n            .use(c => extendClient(c, { identity: 'X' as const, payer: 'A' as const }))\n            .use(c => extendClient(c, { payer: 'B' as const }));\n        expect(client.identity).toBe('X');\n        expect(client.payer).toBe('B');\n    });\n});\n\ndescribe('withCleanup', () => {\n    it('calls the cleanup function when disposed', () => {\n        const cleanup = jest.fn();\n        const result = withCleanup({}, cleanup);\n        result[Symbol.dispose]();\n        expect(cleanup).toHaveBeenCalledTimes(1);\n    });\n\n    it('disposes using the `using` syntax', () => {\n        const cleanup = jest.fn();\n        {\n            // eslint-disable-next-line @typescript-eslint/no-unused-vars\n            using _ = withCleanup({}, cleanup);\n        }\n        expect(cleanup).toHaveBeenCalledTimes(1);\n    });\n\n    it('does not call the cleanup function before dispose is invoked', () => {\n        const cleanup = jest.fn();\n        withCleanup({}, cleanup);\n        expect(cleanup).not.toHaveBeenCalled();\n    });\n\n    it('chains parent Symbol.dispose when client already has one', () => {\n        const callOrder: string[] = [];\n        const parentDispose = jest.fn(() => callOrder.push('parent'));\n        const cleanup = jest.fn(() => callOrder.push('cleanup'));\n        const client = { [Symbol.dispose]: parentDispose };\n        const result = withCleanup(client, cleanup);\n        result[Symbol.dispose]();\n        expect(cleanup).toHaveBeenCalledTimes(1);\n        expect(parentDispose).toHaveBeenCalledTimes(1);\n        expect(callOrder).toStrictEqual(['cleanup', 'parent']);\n    });\n\n    it('does not throw when client has no Symbol.dispose', () => {\n        const cleanup = jest.fn();\n        const result = withCleanup({}, cleanup);\n        expect(() => result[Symbol.dispose]()).not.toThrow();\n    });\n\n    it('preserves existing client properties', () => {\n        const result = withCleanup({ fruit: 'apple' as const }, () => {});\n        expect(result.fruit).toBe('apple');\n    });\n\n    it('symbol.dispose is a function on the result', () => {\n        const result = withCleanup({}, () => {});\n        expect(typeof result[Symbol.dispose]).toBe('function');\n    });\n\n    it('returns a frozen object', () => {\n        expect(withCleanup({ fruit: 'apple' as const }, () => {})).toBeFrozenObject();\n    });\n\n    it('calls all cleanup functions when withCleanup is called multiple times', () => {\n        const cleanup1 = jest.fn();\n        const cleanup2 = jest.fn();\n        const client = withCleanup({}, cleanup1);\n        const result = withCleanup(client, cleanup2);\n        result[Symbol.dispose]();\n        expect(cleanup1).toHaveBeenCalledTimes(1);\n        expect(cleanup2).toHaveBeenCalledTimes(1);\n    });\n\n    it('calls multiple cleanups in LIFO order', () => {\n        const callOrder: string[] = [];\n        const cleanup1 = jest.fn(() => callOrder.push('cleanup1'));\n        const cleanup2 = jest.fn(() => callOrder.push('cleanup2'));\n        const client = withCleanup({}, cleanup1);\n        const result = withCleanup(client, cleanup2);\n        result[Symbol.dispose]();\n        expect(callOrder).toStrictEqual(['cleanup2', 'cleanup1']);\n    });\n\n    it('calls multiple cleanups and existing parent dispose in the correct order', () => {\n        const callOrder: string[] = [];\n        const parentDispose = jest.fn(() => callOrder.push('parent'));\n        const cleanup1 = jest.fn(() => callOrder.push('cleanup1'));\n        const cleanup2 = jest.fn(() => callOrder.push('cleanup2'));\n        const client = withCleanup({ [Symbol.dispose]: parentDispose }, cleanup1);\n        const result = withCleanup(client, cleanup2);\n        result[Symbol.dispose]();\n        expect(callOrder).toStrictEqual(['cleanup2', 'cleanup1', 'parent']);\n    });\n});\n"
  },
  {
    "path": "packages/plugin-core/src/__typetests__/client-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { type AsyncClient, type Client, type ClientPlugin, createClient, extendClient, withCleanup } from '../client';\n\nconst EMPTY_CLIENT = null as unknown as Client<object>;\nconst EMPTY_ASYNC_CLIENT = null as unknown as AsyncClient<object>;\n\n// [DESCRIBE] ClientPlugin\n{\n    // A plugin can be the identity function.\n    {\n        const plugin = (c: object) => c;\n        plugin satisfies ClientPlugin<object, object>;\n    }\n\n    // A plugin can extend the input object.\n    {\n        const plugin = (c: { fruit: 'apple' }) => ({ ...c, vegetable: 'carrot' as const });\n        plugin satisfies ClientPlugin<{ fruit: 'apple' }, { fruit: 'apple'; vegetable: 'carrot' }>;\n    }\n\n    // A plugin can override the input object.\n    {\n        const plugin = (c: { fruit: 'apple' }) => ({ ...c, fruit: 'banana' as const });\n        plugin satisfies ClientPlugin<{ fruit: 'apple' }, { fruit: 'banana' }>;\n        // @ts-expect-error - output fruit is no longer an apple.\n        plugin satisfies ClientPlugin<{ fruit: 'apple' }, { fruit: 'apple' }>;\n    }\n\n    // A plugin can have requirements on the input object.\n    {\n        const plugin = <T extends { fruit: 'apple' }>(c: T) => ({ ...c, dessert: 'apple cake' as const });\n        plugin satisfies ClientPlugin<{ fruit: 'apple' }, { dessert: 'apple cake'; fruit: 'apple' }>;\n    }\n\n    // A plugin may be asynchronous.\n    {\n        const plugin = (c: { fruit: 'apple' }) => Promise.resolve({ ...c, vegetable: 'carrot' as const });\n        plugin satisfies ClientPlugin<{ fruit: 'apple' }, Promise<{ fruit: 'apple'; vegetable: 'carrot' }>>;\n    }\n\n    // A plugin must accept an object.\n    {\n        const plugin = (c: number) => c;\n        // @ts-expect-error - input is not an object.\n        plugin satisfies ClientPlugin<object, object>;\n    }\n\n    // A plugin must return an object.\n    {\n        const plugin = (c: object): number => Object.getOwnPropertyNames(c).length;\n        // @ts-expect-error - output is not an object.\n        plugin satisfies ClientPlugin<object, object>;\n    }\n}\n\n// [DESCRIBE] Client\n{\n    // It returns a modified Client when using a plugin.\n    {\n        const client = EMPTY_CLIENT.use(c => ({ ...c, fruit: 'apple' as const }));\n        client satisfies Client<{ fruit: 'apple' }>;\n    }\n\n    // It returns a new AsyncClient when using an asynchronous plugin.\n    {\n        const client = EMPTY_CLIENT.use(c => Promise.resolve({ ...c, fruit: 'apple' as const }));\n        client satisfies AsyncClient<{ fruit: 'apple' }>;\n    }\n\n    // It does not accept plugins with invalid inputs.\n    {\n        // @ts-expect-error - input is not an object.\n        EMPTY_CLIENT.use((value: 42) => ({ value }));\n        // @ts-expect-error - input is not an object.\n        EMPTY_CLIENT.use((value: 'hello') => ({ value }));\n        // @ts-expect-error - input is not an object.\n        EMPTY_CLIENT.use((value: true) => ({ value }));\n        // @ts-expect-error - input is not an object.\n        EMPTY_CLIENT.use((value: null) => ({ value }));\n        // @ts-expect-error - input is not an object.\n        EMPTY_CLIENT.use((value: undefined) => ({ value }));\n    }\n\n    // It does not accept plugins with invalid outputs.\n    {\n        // @ts-expect-error - output is not an object.\n        EMPTY_CLIENT.use(() => 42);\n        // @ts-expect-error - output is not an object.\n        EMPTY_CLIENT.use(() => 'hello');\n        // @ts-expect-error - output is not an object.\n        EMPTY_CLIENT.use(() => true);\n        // @ts-expect-error - output is not an object.\n        EMPTY_CLIENT.use(() => null);\n        // @ts-expect-error - output is not an object.\n        EMPTY_CLIENT.use(() => undefined);\n    }\n\n    // It evolves through multiple plugins.\n    {\n        const client = EMPTY_CLIENT.use(c => ({ ...c, fruit: 'apple' as const }))\n            .use(c => ({ ...c, vegetable: 'carrot' as const }))\n            .use(c => ({ ...c, grain: 'rice' as const }));\n        client satisfies Client<{ fruit: 'apple'; grain: 'rice'; vegetable: 'carrot' }>;\n    }\n\n    // It accepts plugins when input type constraints are satisfied.\n    {\n        const apple = <T>(p: T) => ({ ...p, fruit: 'apple' as const });\n        const appleCake = <T extends { fruit: 'apple' }>(p: T) => ({ ...p, dessert: 'apple cake' as const });\n        const client = EMPTY_CLIENT.use(apple).use(appleCake);\n        client satisfies Client<{ dessert: 'apple cake'; fruit: 'apple' }>;\n    }\n\n    // It rejects plugins when input type constraints are not satisfied.\n    {\n        const banana = <T>(p: T) => ({ ...p, fruit: 'banana' as const });\n        const appleCake = <T extends { fruit: 'apple' }>(p: T) => ({ ...p, dessert: 'apple cake' as const });\n        const bananaClient = EMPTY_CLIENT.use(banana);\n        // @ts-expect-error - banana does not satisfy apple cake input type.\n        bananaClient.use(appleCake);\n    }\n}\n\n// [DESCRIBE] AsyncClient\n{\n    // It is a Promise.\n    {\n        EMPTY_ASYNC_CLIENT satisfies Promise<object>;\n        null as unknown as AsyncClient<{ fruit: 'apple' }> satisfies Promise<{ fruit: 'apple' }>;\n    }\n\n    // It returns a modified AsyncClient when using a synchronous plugin.\n    {\n        const client = EMPTY_ASYNC_CLIENT.use(c => ({ ...c, fruit: 'apple' as const }));\n        client satisfies AsyncClient<{ fruit: 'apple' }>;\n    }\n\n    // It returns a modified AsyncClient when using an asynchronous plugin.\n    {\n        const client = EMPTY_ASYNC_CLIENT.use(c => Promise.resolve({ ...c, fruit: 'apple' as const }));\n        client satisfies AsyncClient<{ fruit: 'apple' }>;\n    }\n\n    // It does not accept plugins with invalid inputs.\n    {\n        // @ts-expect-error - input is not an object.\n        EMPTY_ASYNC_CLIENT.use((value: 42) => ({ value }));\n        // @ts-expect-error - input is not an object.\n        EMPTY_ASYNC_CLIENT.use((value: 'hello') => ({ value }));\n        // @ts-expect-error - input is not an object.\n        EMPTY_ASYNC_CLIENT.use((value: true) => ({ value }));\n        // @ts-expect-error - input is not an object.\n        EMPTY_ASYNC_CLIENT.use((value: null) => ({ value }));\n        // @ts-expect-error - input is not an object.\n        EMPTY_ASYNC_CLIENT.use((value: undefined) => ({ value }));\n    }\n\n    // It does not accept plugins with invalid outputs.\n    {\n        // @ts-expect-error - output is not an object.\n        EMPTY_ASYNC_CLIENT.use(() => 42);\n        // @ts-expect-error - output is not an object.\n        EMPTY_ASYNC_CLIENT.use(() => 'hello');\n        // @ts-expect-error - output is not an object.\n        EMPTY_ASYNC_CLIENT.use(() => true);\n        // @ts-expect-error - output is not an object.\n        EMPTY_ASYNC_CLIENT.use(() => null);\n        // @ts-expect-error - output is not an object.\n        EMPTY_ASYNC_CLIENT.use(() => undefined);\n    }\n\n    // It evolves through multiple plugins.\n    {\n        const client = EMPTY_ASYNC_CLIENT.use(c => ({ ...c, fruit: 'apple' as const }))\n            .use(c => Promise.resolve({ ...c, vegetable: 'carrot' as const }))\n            .use(c => ({ ...c, grain: 'rice' as const }));\n        client satisfies AsyncClient<{ fruit: 'apple'; grain: 'rice'; vegetable: 'carrot' }>;\n    }\n\n    // It accepts plugins when input type constraints are satisfied.\n    {\n        const apple = <T>(p: T) => ({ ...p, fruit: 'apple' as const });\n        const appleCake = <T extends { fruit: 'apple' }>(p: T) =>\n            Promise.resolve({ ...p, dessert: 'apple cake' as const });\n        const client = EMPTY_ASYNC_CLIENT.use(apple).use(appleCake);\n        client satisfies AsyncClient<{ dessert: 'apple cake'; fruit: 'apple' }>;\n    }\n\n    // It rejects plugins when input type constraints are not satisfied.\n    {\n        const banana = <T>(p: T) => ({ ...p, fruit: 'banana' as const });\n        const appleCake = <T extends { fruit: 'apple' }>(p: T) =>\n            Promise.resolve({ ...p, dessert: 'apple cake' as const });\n        const bananaClient = EMPTY_ASYNC_CLIENT.use(banana);\n        // @ts-expect-error - banana does not satisfy apple cake input type.\n        bananaClient.use(appleCake);\n    }\n}\n\n// [DESCRIBE] createClient\n{\n    // It returns an empty Client (See typetests above).\n    {\n        createClient() satisfies typeof EMPTY_CLIENT;\n    }\n\n    // It creates a Client from an existing object.\n    {\n        createClient({ fruit: 'banana' as const }) satisfies Client<{ fruit: 'banana' }>;\n    }\n}\n\n// [DESCRIBE] extendClient\n{\n    // It merges both types into the result.\n    {\n        const result = extendClient({ fruit: 'apple' as const }, { vegetable: 'carrot' as const });\n        result satisfies { fruit: 'apple'; vegetable: 'carrot' };\n    }\n\n    // It allows the second type to override the first.\n    {\n        const result = extendClient({ fruit: 'apple' as const }, { fruit: 'banana' as const });\n        result satisfies { fruit: 'banana' };\n        // @ts-expect-error - fruit is no longer an apple.\n        result satisfies { fruit: 'apple' };\n    }\n\n    // It rejects non-object clients.\n    {\n        // @ts-expect-error - client is not an object.\n        extendClient(42, {});\n    }\n\n    // It rejects non-object additions.\n    {\n        // @ts-expect-error - additions is not an object.\n        extendClient({}, 'hello');\n    }\n}\n\n// [Describe] withCleanup\n{\n    // It returns a Disposable client\n    {\n        const client = null as unknown as Client<object>;\n        withCleanup(client, () => {}) satisfies Client<object> & Disposable;\n    }\n\n    // It accepts an already Disposable client\n    {\n        const client = null as unknown as Client<object> & Disposable;\n        withCleanup(client, () => {}) satisfies Client<object> & Disposable;\n    }\n\n    // It accepts an AsyncClient\n    {\n        const client = null as unknown as AsyncClient<object>;\n        withCleanup(client, () => {}) satisfies AsyncClient<object> & Disposable;\n    }\n}\n"
  },
  {
    "path": "packages/plugin-core/src/client.ts",
    "content": "/**\n * Defines a plugin that transforms or extends a client with additional functionality.\n *\n * For instance, plugins may add RPC capabilities, wallet integration, transaction building,\n * or other features necessary for interacting with the Solana blockchain.\n *\n * Plugins are functions that take a client object as input and return a new client object\n * or a promise that resolves to a new client object. This allows for both synchronous\n * and asynchronous transformations and extensions of the client.\n *\n * Plugins are usually applied using the `use` method on a {@link Client} or {@link AsyncClient}\n * instance, which {@link createClient} provides as a starting point.\n *\n * @typeParam TInput - The input client object type that this plugin accepts.\n * @typeParam TOutput - The output type. Either a new client object or a promise resolving to one.\n *\n * @example Basic RPC plugin\n * Given an RPC endpoint, this plugin adds an `rpc` property to the client.\n *\n * ```ts\n * import { createClient, createSolanaRpc } from '@solana/kit';\n *\n * // Define a simple RPC plugin.\n * function rpcPlugin(endpoint: string) {\n *     return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n *\n * // Use the plugin.\n * const client = createClient().use(rpcPlugin('https://api.mainnet-beta.solana.com'));\n * await client.rpc.getLatestBlockhash().send();\n * ```\n *\n * @example Async plugin that generates a payer wallet\n * The following plugin shows how to create an asynchronous plugin that generates a new keypair signer.\n *\n * ```ts\n * import { createClient, generateKeypairSigner } from '@solana/kit';\n *\n * // Define a plugin that generates a new keypair signer.\n * function generatedPayerPlugin() {\n *     return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n *\n * // Use the plugin.\n * const client = await createClient().use(generatedPayerPlugin());\n * console.log(client.payer.address);\n * ```\n *\n * @example Plugins with input requirements\n * A plugin can specify required properties on the input client. The example below requires the\n * client to already have a `payer` signer attached to the client in order to perform an airdrop.\n *\n * ```ts\n * import { createClient, TransactionSigner, Lamports, lamports } from '@solana/kit';\n *\n * // Define a plugin that airdrops lamports to the payer set on the client.\n * function airdropPayerPlugin(lamports: Lamports) {\n *     return async <T extends { payer: TransactionSigner }>(client: T) => {\n *         await myAirdropFunction(client.payer, lamports);\n *         return client;\n *     };\n * }\n *\n * // Use the plugins.\n * const client = await createClient()\n *     .use(generatedPayerPlugin()) // This is required before using the airdrop plugin.\n *     .use(airdropPayerPlugin(lamports(1_000_000_000n)));\n * ```\n *\n * @example Chaining plugins\n * Multiple plugins — asynchronous or not — can be chained together to build up complex clients.\n * The example below demonstrates how to gradually build a client with multiple plugins.\n * Notice how, despite having multiple asynchronous plugins, we only need to `await` the final result.\n * This is because the `use` method on `AsyncClient` returns another `AsyncClient`, allowing for seamless chaining.\n *\n * ```ts\n * import { createClient, createSolanaRpc, createSolanaRpcSubscriptions, generateKeypairSigner } from '@solana/kit';\n *\n * // Define multiple plugins.\n * function rpcPlugin(endpoint: string) {\n *     return <T extends object>(client: T) => ({...client, rpc: createSolanaRpc(endpoint) });\n * }\n * function rpcSubscriptionsPlugin(endpoint: string) {\n *     return <T extends object>(client: T) => ({...client, rpc: createSolanaRpcSubscriptions(endpoint) });\n * }\n * function generatedPayerPlugin() {\n *     return async <T extends object>(client: T) => ({...client, payer: await generateKeypairSigner() });\n * }\n * function generatedAuthorityPlugin() {\n *     return async <T extends object>(client: T) => ({...client, authority: await generateKeypairSigner() });\n * }\n *\n * // Chain plugins together.\n * const client = await createClient()\n *     .use(rpcPlugin('https://api.mainnet-beta.solana.com'))\n *     .use(rpcSubscriptionsPlugin('wss://api.mainnet-beta.solana.com'))\n *     .use(generatedPayerPlugin())\n *     .use(generatedAuthorityPlugin());\n * ```\n */\nexport type ClientPlugin<TInput extends object, TOutput extends Promise<object> | object> = (input: TInput) => TOutput;\n\n/**\n * A client that can be extended with plugins.\n *\n * The `Client` type represents a client object that can be built up through\n * the application of one or more plugins. It provides a `use` method to\n * apply plugins, either synchronously (returning a new `Client`) or\n * asynchronously (returning an {@link AsyncClient}).\n *\n * @typeParam TSelf - The current shape of the client object including all applied plugins.\n */\nexport type Client<TSelf extends object> = TSelf & {\n    /**\n     * Applies a plugin to extend or transform the client.\n     *\n     * @param plugin The plugin function to apply to this client.\n     * @returns Either a new `Client` (for sync plugins) or {@link AsyncClient} (for async plugins).\n     */\n    readonly use: <TOutput extends Promise<object> | object>(\n        plugin: ClientPlugin<TSelf, TOutput>,\n    ) => TOutput extends Promise<infer U> ? AsyncClient<U extends object ? U : never> : Client<TOutput>;\n};\n\n/**\n * An asynchronous wrapper that represents a promise of a client.\n *\n * The `AsyncClient` type is returned when an async plugin is applied to a client.\n * It behaves like a `Promise<Client<TSelf>>` but with an additional `use` method\n * that allows chaining more plugins before the promise resolves.\n *\n * This enables fluent chaining of both synchronous and asynchronous plugins\n * without having to await intermediate promises.\n *\n * @typeParam TSelf - The shape of the client object that this async client will resolve to.\n */\nexport type AsyncClient<TSelf extends object> = Promise<Client<TSelf>> & {\n    /**\n     * Applies a plugin to the client once it resolves.\n     *\n     * @param plugin The plugin function to apply to the resolved client.\n     * @returns A new `AsyncClient` representing the result of applying the plugin.\n     */\n    readonly use: <TOutput extends Promise<object> | object>(\n        plugin: ClientPlugin<TSelf, TOutput>,\n    ) => AsyncClient<TOutput extends Promise<infer U> ? (U extends object ? U : never) : TOutput>;\n};\n\n/** @deprecated This function has been renamed. Use `createClient` instead. It behaves identically. */\nexport const createEmptyClient = () => createClient();\n\n/**\n * Creates a new empty client that can be extended with plugins.\n *\n * This serves as an entry point for building Solana clients.\n * Start with an empty client and chain the `.use()` method\n * to apply plugins that add various functionalities such as RPC\n * connectivity, wallet integration, transaction building, and more.\n *\n * See {@link ClientPlugin} for detailed examples on creating and using plugins.\n *\n * @returns An empty client object with only the `use` method available.\n *\n * @example Basic client setup\n * ```ts\n * import { createClient } from '@solana/client';\n * import { generatedPayer } from '@solana/kit-plugin-payer';\n * import { rpc } from '@solana/kit-plugin-rpc';\n *\n * const client = await createClient()\n *     .use(generatedPayer())\n *     .use(rpc('https://api.mainnet-beta.solana.com'));\n * ```\n */\nexport function createClient<TSelf extends object = object>(value?: TSelf): Client<TSelf> {\n    return addUse(value ?? ({} as TSelf));\n}\n\nfunction addUse<TSelf extends object>(value: TSelf): Client<TSelf> {\n    return Object.freeze(\n        Object.defineProperties(\n            {},\n            {\n                ...Object.getOwnPropertyDescriptors(value),\n                use: {\n                    configurable: false,\n                    enumerable: true,\n                    value: function <TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n                        const result = plugin(value);\n                        return result instanceof Promise ? createAsyncClient(result) : addUse(result);\n                    },\n                    writable: false,\n                },\n            },\n        ),\n    ) as Client<TSelf>;\n}\n\nfunction createAsyncClient<TSelf extends object>(promise: Promise<TSelf>): AsyncClient<TSelf> {\n    return Object.freeze({\n        catch(onrejected) {\n            return promise.then(v => addUse(v)).catch(onrejected);\n        },\n        finally(onfinally) {\n            return promise.then(v => addUse(v)).finally(onfinally);\n        },\n        then(onfulfilled, onrejected) {\n            return promise.then(v => addUse(v)).then(onfulfilled, onrejected);\n        },\n        use<TOutput extends Promise<object> | object>(plugin: ClientPlugin<TSelf, TOutput>) {\n            return createAsyncClient(promise.then(plugin));\n        },\n    } as AsyncClient<TSelf>);\n}\n\n/**\n * Extends a client object with additional properties, preserving property descriptors\n * (getters, symbol-keyed properties, and non-enumerable properties) from both objects.\n *\n * Use this inside plugins instead of plain object spread (`{...client, ...additions}`)\n * when the client may carry getters or symbol-keyed properties that spread would flatten or lose.\n * When the same key exists on both, `additions` wins.\n *\n * @typeParam TClient - The type of the original client.\n * @typeParam TAdditions - The type of the properties being added.\n * @param client - The original client object to extend.\n * @param additions - The properties to add or override on the client.\n * @returns A new object combining both, with `additions` taking precedence on conflicts.\n *\n * @example\n * ```ts\n * function rpcPlugin(endpoint: string) {\n *     return <T extends object>(client: T) =>\n *         extendClient(client, { rpc: createSolanaRpc(endpoint) });\n * }\n * ```\n *\n * @see {@link ClientPlugin}\n */\nexport function extendClient<TClient extends object, TAdditions extends object>(\n    client: TClient,\n    additions: TAdditions,\n): Omit<TClient, keyof TAdditions> & TAdditions {\n    const result = Object.defineProperties({}, toConfigurableDescriptors(Object.getOwnPropertyDescriptors(client)));\n    Object.defineProperties(result, Object.getOwnPropertyDescriptors(additions));\n    return Object.freeze(result) as Omit<TClient, keyof TAdditions> & TAdditions;\n}\n\nfunction toConfigurableDescriptors<T extends PropertyDescriptorMap>(descriptors: T): T {\n    const result = {} as Record<string | symbol, PropertyDescriptor>;\n    for (const key of Reflect.ownKeys(descriptors)) {\n        result[key] = { ...descriptors[key as keyof T], configurable: true };\n    }\n    return result as T;\n}\n\n/**\n * Wraps a client with a cleanup function, making it {@link Disposable}.\n *\n * Plugin authors can use this to register teardown logic (e.g. closing\n * connections or clearing timers) that runs when the client is disposed.\n * If the client already implements `Symbol.dispose`, the existing dispose\n * logic is chained so that it runs after the new `cleanup` function.\n *\n * @typeParam TClient - The type of the original client.\n * @param client - The client to wrap.\n * @param cleanup - The cleanup function to run when the client is disposed.\n * @return A new client that extends `TClient` and implements `Disposable`.\n *\n * @example\n * Register a cleanup function in a plugin that opens a WebSocket connection.\n * ```ts\n * function myPlugin() {\n *     return <T extends object>(client: T) => {\n *         const socket = new WebSocket('wss://api.example.com');\n *         return withCleanup(\n *             extendClient(client, { socket }),\n *             () => socket.close(),\n *         );\n *     };\n * }\n *\n * // Later, when the client is no longer needed:\n * using client = createClient().use(myPlugin();\n * // `socket.close()` is called automatically when `client` goes out of scope.\n * ```\n *\n * @see {@link extendClient}\n */\nexport function withCleanup<TClient extends object>(client: TClient, cleanup: () => void): Disposable & TClient {\n    if (DISPOSABLE_STACK_PROPERTY in client) {\n        return addCleanupToClientWithExistingStack(\n            client as Record<typeof DISPOSABLE_STACK_PROPERTY, DisposableStack> & TClient,\n            cleanup,\n        );\n    } else {\n        return addCleanupToClientWithoutExistingStack(client, cleanup);\n    }\n}\n\nconst DISPOSABLE_STACK_PROPERTY = '__PRIVATE__DISPOSABLE_STACK' as const;\n\nfunction addCleanupToClientWithExistingStack<TClient extends Record<typeof DISPOSABLE_STACK_PROPERTY, DisposableStack>>(\n    client: TClient,\n    cleanup: () => void,\n): Disposable & TClient {\n    // If we already have the stack, add the new cleanup to it\n    client[DISPOSABLE_STACK_PROPERTY].defer(cleanup);\n    // We assume we already added a dispose method when we added the stack\n    return client as Disposable & TClient;\n}\n\nfunction addCleanupToClientWithoutExistingStack<TClient extends object>(\n    client: TClient,\n    cleanup: () => void,\n): Disposable & TClient {\n    const stack = new DisposableStack();\n\n    // If the client has an existing dispose method but not our stack, we maintain this existing cleanup by deferring it to the new stack\n    if (Symbol.dispose in client) {\n        const existingDispose = (client as Disposable)[Symbol.dispose];\n        stack.defer(() => existingDispose.call(client));\n    }\n\n    // Add the new cleanup to the stack\n    stack.defer(cleanup);\n\n    // We add our stack to the client, and replace any existing dispose method with our stack dispose\n    const additions = {\n        [DISPOSABLE_STACK_PROPERTY]: stack,\n        [Symbol.dispose]() {\n            stack[Symbol.dispose]();\n        },\n    };\n\n    return extendClient(client, additions) as unknown as Disposable & TClient;\n}\n"
  },
  {
    "path": "packages/plugin-core/src/index.ts",
    "content": "/**\n * This package contains utilities for creating modular Kit clients that can be extended\n * with plugins. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './client';\n"
  },
  {
    "path": "packages/plugin-core/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/plugin-core/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2019.Array\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/plugin-core\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/plugin-core/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/plugin-interfaces/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/plugin-interfaces/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/plugin-interfaces/CHANGELOG.md",
    "content": "# @solana/plugin-interfaces\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1551](https://github.com/anza-xyz/kit/pull/1551) [`d24f908`](https://github.com/anza-xyz/kit/commit/d24f908a4fbbddddd9e8bacc57485de6d8e022b4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `ClientWithSubscribeToPayer` and `ClientWithSubscribeToIdentity` interfaces. These are a framework-agnostic convention for plugins that mutate `client.payer` / `client.identity` reactively — they install a sibling `subscribeToPayer` / `subscribeToIdentity` function so consumers can observe changes without naming the specific plugin that provides them.\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/addresses@6.9.0\n    - @solana/instruction-plans@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/rpc-spec@6.9.0\n    - @solana/rpc-subscriptions-spec@6.9.0\n    - @solana/rpc-types@6.9.0\n    - @solana/signers@6.9.0\n\n## 6.8.0\n\n### Minor Changes\n\n- [#1530](https://github.com/anza-xyz/kit/pull/1530) [`f8d6131`](https://github.com/anza-xyz/kit/commit/f8d61310a0ca7dfeb86f7e7d3f5975b8a140370a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `ClientWithIdentity` interface for clients that provide a default identity signer. Whereas `ClientWithPayer` describes the signer responsible for paying transaction fees and storage costs, `ClientWithIdentity` describes the signer whose assets the application is acting upon — such as the authority over accounts, tokens, or other on-chain assets owned by the current user. In many apps the payer and identity refer to the same signer, but they can differ when a service pays fees on behalf of a user.\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`f53ce07`](https://github.com/anza-xyz/kit/commit/f53ce0796c782e79490e1cf11a55e28fb62b8c8f), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439)]:\n    - @solana/signers@6.8.0\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/instruction-plans@6.8.0\n    - @solana/rpc-spec@6.8.0\n    - @solana/rpc-subscriptions-spec@6.8.0\n    - @solana/rpc-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/instruction-plans@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/rpc-spec@6.7.0\n    - @solana/rpc-subscriptions-spec@6.7.0\n    - @solana/rpc-types@6.7.0\n    - @solana/signers@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`0fa54a4`](https://github.com/anza-xyz/kit/commit/0fa54a469937db3989f42afc4248882736f719f5), [`f055201`](https://github.com/anza-xyz/kit/commit/f055201c2dd3a4a69b9894d66b622ae81c13b8cd)]:\n    - @solana/instruction-plans@6.6.0\n    - @solana/signers@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/rpc-spec@6.6.0\n    - @solana/rpc-subscriptions-spec@6.6.0\n    - @solana/rpc-types@6.6.0\n\n## 6.5.0\n\n### Minor Changes\n\n- [#1486](https://github.com/anza-xyz/kit/pull/1486) [`10cb920`](https://github.com/anza-xyz/kit/commit/10cb92045bba4710a6c6157a3963d9e3a61f755e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `ClientWithGetMinimumBalance` plugin interface for computing the minimum balance required for an account. Implementations can use any strategy (e.g., RPC call, cached value) to provide this value through a uniform API.\n\n### Patch Changes\n\n- Updated dependencies [[`9e05736`](https://github.com/anza-xyz/kit/commit/9e057365a1a4e350f8a0ccc233b262e09b0134fa)]:\n    - @solana/signers@6.5.0\n    - @solana/addresses@6.5.0\n    - @solana/instruction-plans@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/rpc-spec@6.5.0\n    - @solana/rpc-subscriptions-spec@6.5.0\n    - @solana/rpc-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`896412d`](https://github.com/anza-xyz/kit/commit/896412da20ced2b81f9f529e9b5feef16b7e790f)]:\n    - @solana/instruction-plans@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/signers@6.4.0\n    - @solana/rpc-spec@6.4.0\n    - @solana/rpc-subscriptions-spec@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies [[`a557a62`](https://github.com/anza-xyz/kit/commit/a557a62e0f42d2d526f0b8fbdd0a9fcc08ac9ef7)]:\n    - @solana/instruction-plans@6.3.1\n    - @solana/addresses@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/rpc-spec@6.3.1\n    - @solana/rpc-subscriptions-spec@6.3.1\n    - @solana/rpc-types@6.3.1\n    - @solana/signers@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/instruction-plans@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/rpc-spec@6.3.0\n    - @solana/rpc-subscriptions-spec@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/signers@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`98a8869`](https://github.com/anza-xyz/kit/commit/98a8869d5a728a65b7a525d87ed481616112503c), [`79db829`](https://github.com/anza-xyz/kit/commit/79db8292b2064145f615576589d8ecbf32196dc1), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/instruction-plans@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/rpc-spec@6.2.0\n    - @solana/rpc-subscriptions-spec@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/signers@6.2.0\n\n## 6.1.0\n\n### Minor Changes\n\n- [#1339](https://github.com/anza-xyz/kit/pull/1339) [`ee558a1`](https://github.com/anza-xyz/kit/commit/ee558a1ea8a95295db0e7b0751b32ac9d6342911) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `@solana/plugin-interfaces` package with TypeScript interfaces for building pluggable Solana clients. Includes `ClientWithPayer`, `ClientWithAirdrop`, `ClientWithRpc`, `ClientWithRpcSubscriptions`, `ClientWithTransactionPlanning`, and `ClientWithTransactionSending` interfaces.\n\n### Patch Changes\n\n- Updated dependencies [[`1f6cd4b`](https://github.com/anza-xyz/kit/commit/1f6cd4bc7f41e865ff81ecd819dd9f728c27af77), [`50010b5`](https://github.com/anza-xyz/kit/commit/50010b5b791ff0e6d8636ded3af33158f2380e4e), [`33234f5`](https://github.com/anza-xyz/kit/commit/33234f50760e34a21072304e6aaf1a31b7a410f1)]:\n    - @solana/instruction-plans@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/rpc-spec@6.1.0\n    - @solana/rpc-subscriptions-spec@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/signers@6.1.0\n"
  },
  {
    "path": "packages/plugin-interfaces/LICENSE",
    "content": "Copyright (c) 2025 Anza Technology, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/plugin-interfaces/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/plugin-interfaces?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/plugin-interfaces?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/plugin-interfaces\n\n# @solana/plugin-interfaces\n\nThis package defines common TypeScript interfaces for features that Kit plugins can provide or require. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Overview\n\nWhen building Solana applications, different environments require different capabilities. A browser wallet might support signing but not RPC calls. A testing environment might support airdrops. A full client might support everything.\n\nThese interfaces serve two purposes:\n\n- **Plugins can provide capabilities**: A plugin can implement these interfaces to add features to a client (e.g., a plugin that adds airdrop support implements `ClientWithAirdrop`).\n- **Plugins can require capabilities**: A plugin can declare which capabilities it needs from the client to function (e.g., a token plugin might require `ClientWithRpc` to fetch account data).\n\nThis enables a composable plugin architecture where plugins can build on top of each other's capabilities.\n\n## Installation\n\n```bash\nnpm install @solana/plugin-interfaces\n```\n\n## Interfaces\n\n### `ClientWithPayer`\n\nRepresents a client that provides a default transaction payer.\n\n```ts\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithPayer } from '@solana/plugin-interfaces';\n\nfunction memoPlugin() {\n    return <T extends ClientWithPayer>(client: T) =>\n        extendClient(client, {\n            sendMemo: (message: string) => {\n                // Use client.payer as the fee payer for the memo transaction\n                const feePayer = client.payer;\n                // ...\n            },\n        });\n}\n```\n\n### `ClientWithIdentity`\n\nRepresents a client that provides a default identity signer — the wallet that owns things in the application, such as the authority over accounts, tokens, or other on-chain assets owned by the current user. Unlike `ClientWithPayer`, which describes the signer responsible for paying transaction fees and storage costs, the identity describes the signer whose assets the application is acting upon. In many apps, the payer and identity refer to the same signer, but they can differ — for example, when a service pays fees on behalf of a user.\n\n```ts\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithIdentity } from '@solana/plugin-interfaces';\n\nfunction nftPlugin() {\n    return <T extends ClientWithIdentity>(client: T) =>\n        extendClient(client, {\n            transferNft: (mint: Address, recipient: Address) => {\n                // Use client.identity as the current owner of the NFT\n                const owner = client.identity;\n                // ...\n            },\n        });\n}\n```\n\n### `ClientWithSubscribeToPayer` / `ClientWithSubscribeToIdentity`\n\nSome plugins set `client.payer` or `client.identity` reactively — the connected wallet may change, an account may be swapped, or a signer may be cleared on disconnect. Plugins that participate in this pattern advertise it by installing a sibling `subscribeTo<Capability>` function on the client:\n\n| Type                            | Sibling function      | Advertises that…                       |\n| ------------------------------- | --------------------- | -------------------------------------- |\n| `ClientWithSubscribeToPayer`    | `subscribeToPayer`    | `client.payer` may change over time    |\n| `ClientWithSubscribeToIdentity` | `subscribeToIdentity` | `client.identity` may change over time |\n\nReactive consumers (framework hooks, stores, effects) can then observe changes without having to know which plugin installed the capability — they duck-type on the subscribe function:\n\n```ts\nimport { ClientWithPayer, ClientWithSubscribeToPayer } from '@solana/plugin-interfaces';\n\nfunction observePayer() {\n    return <T extends ClientWithPayer & ClientWithSubscribeToPayer>(client: T) => {\n        client.subscribeToPayer(() => {\n            console.log('payer is now', client.payer);\n        });\n        return client;\n    };\n}\n```\n\nPlugins that leave the signer fixed for the lifetime of the client do **not** need to install these hooks — there is nothing to subscribe to. The convention is meant for plugins that reassign `client.payer` / `client.identity` as the user connects, switches accounts, or disconnects.\n\n### `ClientWithAirdrop`\n\nRepresents a client that can request SOL airdrops (typically on devnet/testnet). The airdrop succeeds when the promise resolves. Some implementations (e.g., LiteSVM) update balances directly without a transaction, so no signature is returned in those cases.\n\n```ts\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithAirdrop, ClientWithPayer } from '@solana/plugin-interfaces';\n\nfunction faucetPlugin() {\n    return <T extends ClientWithAirdrop & ClientWithPayer>(client: T) =>\n        extendClient(client, {\n            fundMyself: async (amount: Lamports) => {\n                await client.airdrop(client.payer.address, amount);\n            },\n        });\n}\n```\n\n### `ClientWithGetMinimumBalance`\n\nRepresents a client that can compute the minimum balance required for an account to be exempt from deletion. Different implementations may compute this differently — for example, by calling the `getMinimumBalanceForRentExemption` RPC method, or by using a locally cached value.\n\nBy default, the 128-byte account header is added on top of the provided `space`. Pass `{ withoutHeader: true }` to skip adding the header bytes.\n\n```ts\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithGetMinimumBalance } from '@solana/plugin-interfaces';\n\nfunction accountCreationPlugin() {\n    return <T extends ClientWithGetMinimumBalance>(client: T) =>\n        extendClient(client, {\n            getAccountCreationCost: async (dataSize: number) => {\n                const minimumBalance = await client.getMinimumBalance(dataSize);\n                console.log(`Minimum balance for ${dataSize} bytes: ${minimumBalance} lamports`);\n                return minimumBalance;\n            },\n        });\n}\n```\n\n### `ClientWithRpc<TRpcMethods>`\n\nRepresents a client with access to a Solana RPC endpoint.\n\n```ts\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithRpc } from '@solana/plugin-interfaces';\nimport { GetBalanceApi } from '@solana/rpc-api';\n\nfunction balancePlugin() {\n    return <T extends ClientWithRpc<GetBalanceApi>>(client: T) =>\n        extendClient(client, {\n            getBalance: async (address: Address): Promise<Lamports> => {\n                const { value } = await client.rpc.getBalance(address).send();\n                return value;\n            },\n        });\n}\n```\n\n### `ClientWithRpcSubscriptions<TRpcSubscriptionsMethods>`\n\nRepresents a client that provides access to Solana RPC subscriptions for real-time notifications such as account changes, slot updates, and transaction confirmations.\n\n```ts\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithRpcSubscriptions } from '@solana/plugin-interfaces';\nimport { AccountNotificationsApi } from '@solana/rpc-subscriptions-api';\n\nfunction accountWatcherPlugin() {\n    return <T extends ClientWithRpcSubscriptions<AccountNotificationsApi>>(client: T) =>\n        extendClient(client, {\n            onAccountChange: async (address: Address, callback: (lamports: Lamports) => void) => {\n                const subscription = await client.rpcSubscriptions.accountNotifications(address).subscribe();\n                for await (const notification of subscription) {\n                    callback(notification.value.lamports);\n                }\n            },\n        });\n}\n```\n\n### `ClientWithTransactionPlanning`\n\nRepresents a client that can convert instructions or instruction plans into transaction plans.\n\n```ts\nimport { flattenTransactionPlan } from '@solana/instruction-plans';\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithTransactionPlanning } from '@solana/plugin-interfaces';\n\nfunction transactionCounterPlugin() {\n    return <T extends ClientWithTransactionPlanning>(client: T) =>\n        extendClient(client, {\n            countTransactions: async (instructions: IInstruction[]) => {\n                const plan = await client.planTransactions(instructions);\n                return flattenTransactionPlan(plan).length;\n            },\n        });\n}\n```\n\n### `ClientWithTransactionSending`\n\nRepresents a client that can send transactions to the Solana network. It supports flexible input formats including instructions, instruction plans, transaction messages, or transaction plans.\n\n```ts\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithPayer, ClientWithTransactionSending } from '@solana/plugin-interfaces';\n\nfunction transferPlugin() {\n    return <T extends ClientWithPayer & ClientWithTransactionSending>(client: T) =>\n        extendClient(client, {\n            transfer: async (recipient: Address, amount: Lamports) => {\n                const instruction = getTransferSolInstruction({\n                    source: client.payer,\n                    destination: recipient,\n                    amount,\n                });\n                const result = await client.sendTransaction(instruction);\n                return result.context.signature;\n            },\n        });\n}\n```\n\n## Combining Interfaces\n\nUse TypeScript intersection types to require multiple capabilities from the client:\n\n```ts\nimport { extendClient } from '@solana/plugin-core';\nimport { ClientWithPayer, ClientWithRpc, ClientWithTransactionSending } from '@solana/plugin-interfaces';\nimport { GetAccountInfoApi } from '@solana/rpc-api';\n\nfunction tokenTransferPlugin() {\n    return <T extends ClientWithPayer & ClientWithRpc<GetAccountInfoApi> & ClientWithTransactionSending>(client: T) =>\n        extendClient(client, {\n            transferToken: async (mint: Address, recipient: Address, amount: bigint) => {\n                // Use client.rpc to fetch token accounts\n                // Use client.payer as the token owner\n                // Use client.sendTransaction to execute the transfer\n            },\n        });\n}\n```\n"
  },
  {
    "path": "packages/plugin-interfaces/package.json",
    "content": "{\n    \"name\": \"@solana/plugin-interfaces\",\n    \"version\": \"6.9.0\",\n    \"description\": \"TypeScript interfaces for building pluggable Solana clients\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaplugin-interfaces\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/instruction-plans\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/rpc-spec\": \"workspace:*\",\n        \"@solana/rpc-subscriptions-spec\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/signers\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/plugin-interfaces/src/__typetests__/airdrop-typetest.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { Lamports } from '@solana/rpc-types';\n\nimport type { ClientWithAirdrop } from '../airdrop';\n\nconst address = null as unknown as Address;\nconst amount = null as unknown as Lamports;\n\n// [DESCRIBE] ClientWithAirdrop.\n{\n    // It provides an airdrop method with the correct signature.\n    {\n        const client = null as unknown as ClientWithAirdrop;\n        void (client.airdrop(address, amount) satisfies Promise<Signature | undefined>);\n    }\n\n    // It accepts an optional AbortSignal.\n    {\n        const client = null as unknown as ClientWithAirdrop;\n        const abortController = new AbortController();\n        void (client.airdrop(address, amount, abortController.signal) satisfies Promise<Signature | undefined>);\n    }\n\n    // It can be combined with other interfaces via intersection.\n    {\n        type CustomClient = ClientWithAirdrop & { otherMethod(): string };\n        const client = null as unknown as CustomClient;\n        client.airdrop satisfies ClientWithAirdrop['airdrop'];\n        client.otherMethod satisfies () => string;\n    }\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/src/__typetests__/get-minimum-balance-typetest.ts",
    "content": "import type { Lamports } from '@solana/rpc-types';\n\nimport type { ClientWithGetMinimumBalance } from '../get-minimum-balance';\n\n// [DESCRIBE] ClientWithGetMinimumBalance.\n{\n    // It provides a getMinimumBalance method with the correct signature.\n    {\n        const client = null as unknown as ClientWithGetMinimumBalance;\n        void (client.getMinimumBalance(0) satisfies Promise<Lamports>);\n    }\n\n    // It accepts an optional config parameter.\n    {\n        const client = null as unknown as ClientWithGetMinimumBalance;\n        void (client.getMinimumBalance(100, { withoutHeader: true }) satisfies Promise<Lamports>);\n    }\n\n    // It can be combined with other interfaces via intersection.\n    {\n        type CustomClient = ClientWithGetMinimumBalance & { otherMethod(): string };\n        const client = null as unknown as CustomClient;\n        client.getMinimumBalance satisfies ClientWithGetMinimumBalance['getMinimumBalance'];\n        client.otherMethod satisfies () => string;\n    }\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/src/__typetests__/identity-typetest.ts",
    "content": "import type { TransactionSigner } from '@solana/signers';\n\nimport type { ClientWithIdentity } from '../identity';\n\n// [DESCRIBE] ClientWithIdentity.\n{\n    // It provides an identity property that is a TransactionSigner.\n    {\n        const client = null as unknown as ClientWithIdentity;\n        client.identity satisfies TransactionSigner;\n    }\n\n    // It can be combined with other interfaces via intersection.\n    {\n        type CustomClient = ClientWithIdentity & { customMethod(): void };\n        const client = null as unknown as CustomClient;\n        client.identity satisfies TransactionSigner;\n        client.customMethod satisfies () => void;\n    }\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/src/__typetests__/instruction-plans-typetest.ts",
    "content": "import type {\n    InstructionPlanInput,\n    SingleTransactionPlan,\n    SuccessfulSingleTransactionPlanResult,\n    TransactionPlan,\n    TransactionPlanInput,\n    TransactionPlanResult,\n} from '@solana/instruction-plans';\n\nimport type { ClientWithTransactionPlanning, ClientWithTransactionSending } from '../instruction-plans';\n\n// [DESCRIBE] ClientWithTransactionPlanning.\n{\n    // It provides a planTransaction method that returns a transaction message.\n    {\n        const client = null as unknown as ClientWithTransactionPlanning;\n        const input = null as unknown as InstructionPlanInput;\n        void (client.planTransaction(input) satisfies Promise<SingleTransactionPlan['message']>);\n    }\n\n    // It provides a planTransactions method that returns a transaction plan.\n    {\n        const client = null as unknown as ClientWithTransactionPlanning;\n        const input = null as unknown as InstructionPlanInput;\n        void (client.planTransactions(input) satisfies Promise<TransactionPlan>);\n    }\n\n    // Both methods accept an optional config with abortSignal.\n    {\n        const client = null as unknown as ClientWithTransactionPlanning;\n        const input = null as unknown as InstructionPlanInput;\n        const abortController = new AbortController();\n        void (client.planTransaction(input, {\n            abortSignal: abortController.signal,\n        }) satisfies Promise<SingleTransactionPlan['message']>);\n        void (client.planTransactions(input, {\n            abortSignal: abortController.signal,\n        }) satisfies Promise<TransactionPlan>);\n    }\n}\n\n// [DESCRIBE] ClientWithTransactionSending.\n{\n    // sendTransaction accepts InstructionPlanInput.\n    {\n        const client = null as unknown as ClientWithTransactionSending;\n        const input = null as unknown as InstructionPlanInput;\n        void (client.sendTransaction(input) satisfies Promise<SuccessfulSingleTransactionPlanResult>);\n    }\n\n    // sendTransaction accepts SingleTransactionPlan.\n    {\n        const client = null as unknown as ClientWithTransactionSending;\n        const plan = null as unknown as SingleTransactionPlan;\n        void (client.sendTransaction(plan) satisfies Promise<SuccessfulSingleTransactionPlanResult>);\n    }\n\n    // sendTransaction accepts SingleTransactionPlan['message'].\n    {\n        const client = null as unknown as ClientWithTransactionSending;\n        const message = null as unknown as SingleTransactionPlan['message'];\n        void (client.sendTransaction(message) satisfies Promise<SuccessfulSingleTransactionPlanResult>);\n    }\n\n    // sendTransactions accepts InstructionPlanInput.\n    {\n        const client = null as unknown as ClientWithTransactionSending;\n        const input = null as unknown as InstructionPlanInput;\n        void (client.sendTransactions(input) satisfies Promise<TransactionPlanResult>);\n    }\n\n    // sendTransactions accepts TransactionPlanInput.\n    {\n        const client = null as unknown as ClientWithTransactionSending;\n        const input = null as unknown as TransactionPlanInput;\n        void (client.sendTransactions(input) satisfies Promise<TransactionPlanResult>);\n    }\n\n    // Both methods accept an optional config with abortSignal.\n    {\n        const client = null as unknown as ClientWithTransactionSending;\n        const input = null as unknown as InstructionPlanInput;\n        const abortController = new AbortController();\n        void (client.sendTransaction(input, {\n            abortSignal: abortController.signal,\n        }) satisfies Promise<SuccessfulSingleTransactionPlanResult>);\n        void (client.sendTransactions(input, {\n            abortSignal: abortController.signal,\n        }) satisfies Promise<TransactionPlanResult>);\n    }\n}\n\n// [DESCRIBE] Combining ClientWithTransactionPlanning and ClientWithTransactionSending.\n{\n    // They can be combined into a single client type.\n    {\n        type FullTransactionClient = ClientWithTransactionPlanning & ClientWithTransactionSending;\n        const client = null as unknown as FullTransactionClient;\n\n        client.planTransaction satisfies ClientWithTransactionPlanning['planTransaction'];\n        client.planTransactions satisfies ClientWithTransactionPlanning['planTransactions'];\n        client.sendTransaction satisfies ClientWithTransactionSending['sendTransaction'];\n        client.sendTransactions satisfies ClientWithTransactionSending['sendTransactions'];\n    }\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/src/__typetests__/payer-typetest.ts",
    "content": "import type { TransactionSigner } from '@solana/signers';\n\nimport type { ClientWithPayer } from '../payer';\n\n// [DESCRIBE] ClientWithPayer.\n{\n    // It provides a payer property that is a TransactionSigner.\n    {\n        const client = null as unknown as ClientWithPayer;\n        client.payer satisfies TransactionSigner;\n    }\n\n    // It can be combined with other interfaces via intersection.\n    {\n        type CustomClient = ClientWithPayer & { customMethod(): void };\n        const client = null as unknown as CustomClient;\n        client.payer satisfies TransactionSigner;\n        client.customMethod satisfies () => void;\n    }\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/src/__typetests__/rpc-typetest.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\nimport type { RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport type { ClientWithRpc, ClientWithRpcSubscriptions } from '../rpc';\n\ntype TestRpcMethods = {\n    getBalance(address: string): bigint;\n    getSlot(): number;\n};\n\ntype TestSubscriptionMethods = {\n    accountNotifications(address: string): { lamports: bigint };\n    slotNotifications(): number;\n};\n\n// [DESCRIBE] ClientWithRpc.\n{\n    // It provides an rpc property typed with the given RPC methods.\n    {\n        const client = null as unknown as ClientWithRpc<TestRpcMethods>;\n        client.rpc satisfies Rpc<TestRpcMethods>;\n    }\n\n    // It can be combined with other interfaces via intersection.\n    {\n        type CombinedClient = ClientWithRpc<TestRpcMethods> & { payer: { address: string } };\n        const client = null as unknown as CombinedClient;\n        client.rpc satisfies Rpc<TestRpcMethods>;\n        client.payer.address satisfies string;\n    }\n}\n\n// [DESCRIBE] ClientWithRpcSubscriptions.\n{\n    // It provides an rpcSubscriptions property typed with the given subscription methods.\n    {\n        const client = null as unknown as ClientWithRpcSubscriptions<TestSubscriptionMethods>;\n        client.rpcSubscriptions satisfies RpcSubscriptions<TestSubscriptionMethods>;\n    }\n\n    // It can be combined with ClientWithRpc.\n    {\n        type FullRpcClient = ClientWithRpc<TestRpcMethods> & ClientWithRpcSubscriptions<TestSubscriptionMethods>;\n        const client = null as unknown as FullRpcClient;\n        client.rpc satisfies Rpc<TestRpcMethods>;\n        client.rpcSubscriptions satisfies RpcSubscriptions<TestSubscriptionMethods>;\n    }\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/src/__typetests__/subscribe-to-typetest.ts",
    "content": "import type { ClientWithSubscribeToIdentity, ClientWithSubscribeToPayer, SubscribeToFn } from '../subscribe-to';\n\n// [DESCRIBE] SubscribeToFn.\n{\n    // It takes a listener and returns an unsubscribe function.\n    {\n        const subscribe = null as unknown as SubscribeToFn;\n        const unsubscribe = subscribe(() => {});\n        unsubscribe satisfies () => void;\n    }\n}\n\n// [DESCRIBE] ClientWithSubscribeToPayer.\n{\n    // It exposes a readonly `subscribeToPayer` of type `SubscribeToFn`.\n    {\n        const client = null as unknown as ClientWithSubscribeToPayer;\n        client.subscribeToPayer satisfies SubscribeToFn;\n    }\n\n    // It can be combined with other interfaces via intersection.\n    {\n        type CustomClient = ClientWithSubscribeToPayer & { customMethod(): void };\n        const client = null as unknown as CustomClient;\n        client.subscribeToPayer satisfies SubscribeToFn;\n        client.customMethod satisfies () => void;\n    }\n}\n\n// [DESCRIBE] ClientWithSubscribeToIdentity.\n{\n    // It exposes a readonly `subscribeToIdentity` of type `SubscribeToFn`.\n    {\n        const client = null as unknown as ClientWithSubscribeToIdentity;\n        client.subscribeToIdentity satisfies SubscribeToFn;\n    }\n\n    // It can be combined with other interfaces via intersection.\n    {\n        type CustomClient = ClientWithSubscribeToIdentity & { customMethod(): void };\n        const client = null as unknown as CustomClient;\n        client.subscribeToIdentity satisfies SubscribeToFn;\n        client.customMethod satisfies () => void;\n    }\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/src/airdrop.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Signature } from '@solana/keys';\nimport { Lamports } from '@solana/rpc-types';\n\n/**\n * Represents a client that can request airdrops of SOL to a specified address.\n *\n * The airdrop capability is typically available on test networks (devnet, testnet)\n * and local validators. It allows funding accounts with SOL for testing purposes.\n *\n * @example\n * ```ts\n * async function fundAccount(client: ClientWithAirdrop, address: Address) {\n *     const signature = await client.airdrop(address, lamports(1_000_000_000n));\n *     console.log(`Airdrop confirmed: ${signature ?? '[no signature]'}`);\n * }\n * ```\n */\nexport type ClientWithAirdrop = {\n    /**\n     * Requests an airdrop of SOL to the specified address.\n     *\n     * The returned promise resolves when the airdrop succeeds and rejects on failure.\n     * Some implementations (e.g., LiteSVM) update account balances directly without\n     * sending a transaction, in which case no signature is returned.\n     *\n     * @param address - The address to receive the airdrop.\n     * @param amount - The amount of lamports to airdrop.\n     * @param abortSignal - An optional signal to abort the airdrop request.\n     * @returns A promise resolving to the transaction signature if the airdrop was\n     *          performed via a transaction, or `undefined` if no transaction was used.\n     */\n    airdrop: (address: Address, amount: Lamports, abortSignal?: AbortSignal) => Promise<Signature | undefined>;\n};\n"
  },
  {
    "path": "packages/plugin-interfaces/src/get-minimum-balance.ts",
    "content": "import { Lamports } from '@solana/rpc-types';\n\n/**\n * Configuration options for {@link ClientWithGetMinimumBalance.getMinimumBalance}.\n */\nexport type GetMinimumBalanceConfig = {\n    /**\n     * When `true`, the 128-byte account header is not added to the provided `space` value.\n     *\n     * By default, the account header (128 bytes) is included in the minimum balance computation\n     * on top of the provided `space`. Set this to `true` if the provided `space` already accounts\n     * for the header or if you want the minimum balance for the data portion only.\n     *\n     * @see {@link @solana/accounts#BASE_ACCOUNT_SIZE | BASE_ACCOUNT_SIZE} for the account header size constant.\n     */\n    withoutHeader?: boolean;\n};\n\n/**\n * Represents a client that can compute the minimum balance required for an account to be\n * exempt from deletion.\n *\n * Different implementations may compute this value differently — for example, by calling the\n * `getMinimumBalanceForRentExemption` RPC method, or by using a locally cached value.\n *\n * @example\n * ```ts\n * async function logAccountCost(client: ClientWithGetMinimumBalance, dataSize: number) {\n *     const minimumBalance = await client.getMinimumBalance(dataSize);\n *     console.log(`Minimum balance for ${dataSize} bytes: ${minimumBalance} lamports`);\n * }\n * ```\n */\nexport type ClientWithGetMinimumBalance = {\n    /**\n     * Computes the minimum lamports required for an account with the given data size.\n     *\n     * By default, the 128-byte account header is added on top of the provided `space`. Pass\n     * `{ withoutHeader: true }` to skip adding the header bytes.\n     *\n     * @param space - The number of bytes of account data.\n     * @param config - Optional configuration for the computation.\n     * @returns A promise resolving to the minimum {@link Lamports} required.\n     *\n     * @see {@link @solana/accounts#BASE_ACCOUNT_SIZE | BASE_ACCOUNT_SIZE} for the account header size constant.\n     */\n    getMinimumBalance: (space: number, config?: GetMinimumBalanceConfig) => Promise<Lamports>;\n};\n"
  },
  {
    "path": "packages/plugin-interfaces/src/identity.ts",
    "content": "import { TransactionSigner } from '@solana/signers';\n\n/**\n * Represents a client that provides a default identity signer.\n *\n * The identity is a {@link TransactionSigner} representing the wallet that owns\n * things in the application — for instance, the authority over accounts, tokens,\n * or other on-chain assets owned by the current user. Unlike {@link ClientWithPayer},\n * which describes the signer responsible for paying transaction fees and storage\n * costs, the identity describes the signer whose assets the application is acting\n * upon. In many apps, the payer and identity refer to the same signer, but they\n * can differ — for example, when a service pays fees on behalf of a user.\n *\n * @example\n * ```ts\n * function getOwnerAddress(client: ClientWithIdentity): Address {\n *     return client.identity.address;\n * }\n * ```\n *\n * @see {@link ClientWithPayer}\n */\nexport type ClientWithIdentity = { identity: TransactionSigner };\n"
  },
  {
    "path": "packages/plugin-interfaces/src/index.ts",
    "content": "/**\n * This package defines common TypeScript interfaces for features that Kit plugins\n * can provide or require. It can be used standalone, but it is also exported as part\n * of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './airdrop';\nexport * from './instruction-plans';\nexport * from './get-minimum-balance';\nexport * from './identity';\nexport * from './payer';\nexport * from './rpc';\nexport * from './subscribe-to';\n"
  },
  {
    "path": "packages/plugin-interfaces/src/instruction-plans.ts",
    "content": "import type {\n    InstructionPlanInput,\n    SingleTransactionPlan,\n    SuccessfulSingleTransactionPlanResult,\n    TransactionPlan,\n    TransactionPlanInput,\n    TransactionPlanResult,\n} from '@solana/instruction-plans';\n\ntype Config = { abortSignal?: AbortSignal };\n\n/**\n * Represents a client that can plan transactions from instruction inputs.\n *\n * Transaction planning converts high-level instruction plans into concrete\n * transaction messages, handling concerns like blockhash fetching, transaction\n * splitting for size limits, and instruction ordering.\n *\n * @example\n * ```ts\n * async function prepareTransfer(client: ClientWithTransactionPlanning) {\n *     const instructions = [createTransferInstruction(...)];\n *\n *     // Plan a single transaction\n *     const message = await client.planTransaction(instructions);\n *\n *     // Or plan potentially multiple transactions if needed\n *     const plan = await client.planTransactions(instructions);\n * }\n * ```\n */\nexport type ClientWithTransactionPlanning = {\n    /**\n     * Plans a single transaction from the given instruction input.\n     *\n     * Use this when you expect all instructions to fit in a single transaction.\n     *\n     * @param input - The instruction plan input (instructions or instruction plans).\n     * @param config - Optional configuration including an abort signal.\n     * @returns A promise resolving to the planned transaction message.\n     *\n     * @see {@link InstructionPlanInput}\n     */\n    planTransaction: (input: InstructionPlanInput, config?: Config) => Promise<SingleTransactionPlan['message']>;\n\n    /**\n     * Plans one or more transactions from the given instruction input.\n     *\n     * Use this when instructions might need to be split across multiple\n     * transactions due to size limits.\n     *\n     * @param input - The instruction plan input (instructions or instruction plans).\n     * @param config - Optional configuration including an abort signal.\n     * @returns A promise resolving to the full transaction plan.\n     *\n     * @see {@link InstructionPlanInput}\n     */\n    planTransactions: (input: InstructionPlanInput, config?: Config) => Promise<TransactionPlan>;\n};\n\n/**\n * Represents a client that can send transactions to the Solana network.\n *\n * Transaction sending handles signing, submission, and confirmation of\n * transactions. It supports flexible input formats including instructions,\n * instruction plans, transaction messages or transaction plans.\n *\n * @example\n * ```ts\n * async function executeTransfer(client: ClientWithTransactionSending) {\n *     const instructions = [createTransferInstruction(...)];\n *\n *     // Send a single transaction\n *     const result = await client.sendTransaction(instructions);\n *     console.log(`Transaction confirmed: ${result.context.signature}`);\n *\n *     // Or send potentially multiple transactions\n *     const results = await client.sendTransactions(instructions);\n * }\n * ```\n */\nexport type ClientWithTransactionSending = {\n    /**\n     * Sends a single transaction to the network.\n     *\n     * Accepts flexible input: instructions, instruction plans, a single\n     * transaction message or a single transaction plan.\n     *\n     * @param input - Instructions, a transaction plan, or a transaction message.\n     * @param config - Optional configuration including an abort signal.\n     * @returns A promise resolving to the successful transaction result.\n     *\n     * @see {@link InstructionPlanInput}\n     * @see {@link SingleTransactionPlan}\n     */\n    sendTransaction: (\n        input: InstructionPlanInput | SingleTransactionPlan | SingleTransactionPlan['message'],\n        config?: Config,\n    ) => Promise<SuccessfulSingleTransactionPlanResult>;\n\n    /**\n     * Sends one or more transactions to the network.\n     *\n     * Accepts flexible input: instructions, instruction plans, transaction messages\n     * or transaction plans.\n     *\n     * @param input - Any instruction or a transaction plan input.\n     * @param config - Optional configuration including an abort signal.\n     * @returns A promise resolving to the results for all transactions.\n     *\n     * @see {@link InstructionPlanInput}\n     * @see {@link TransactionPlanInput}\n     */\n    sendTransactions: (\n        input: InstructionPlanInput | TransactionPlanInput,\n        config?: Config,\n    ) => Promise<TransactionPlanResult>;\n};\n"
  },
  {
    "path": "packages/plugin-interfaces/src/payer.ts",
    "content": "import { TransactionSigner } from '@solana/signers';\n\n/**\n * Represents a client that provides a default transaction payer.\n *\n * The payer is a {@link TransactionSigner} used to sign and pay for transactions.\n * Clients implementing this interface can automatically fund transactions\n * without requiring callers to specify a fee payer explicitly. Unlike\n * {@link ClientWithIdentity}, which describes the signer whose assets the\n * application is acting upon, the payer describes the signer responsible for\n * paying transaction fees as well as storage costs — i.e. the minimum balance\n * required to keep newly created accounts alive based on their size.\n * In many apps the payer and identity refer to the same signer, but they can\n * differ — for example, when a service pays fees on behalf of a user.\n *\n * @example\n * ```ts\n * function createTransfer(client: ClientWithPayer, recipient: Address, amount: Lamports) {\n *     const feePayer = client.payer;\n *     // Use feePayer.address as the transaction fee payer\n * }\n * ```\n *\n * @see {@link ClientWithIdentity}\n */\nexport type ClientWithPayer = { payer: TransactionSigner };\n"
  },
  {
    "path": "packages/plugin-interfaces/src/rpc.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\nimport type { RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\n/**\n * Represents a client that provides access to a Solana RPC endpoint.\n *\n * The RPC interface allows making JSON-RPC calls to a Solana validator,\n * such as fetching account data, sending transactions, and querying blockchain state.\n *\n * @typeParam TRpcMethods - The RPC methods available on this client. Use specific\n *            method types from `@solana/rpc-api` for the Solana JSON-RPC API.\n *\n * @example\n * ```ts\n * import { SolanaRpcApi } from '@solana/rpc-api';\n *\n * async function getBalance(client: ClientWithRpc<SolanaRpcApi>, address: Address) {\n *     const { value: balance } = await client.rpc.getBalance(address).send();\n *     return balance;\n * }\n * ```\n */\nexport type ClientWithRpc<TRpcMethods> = { rpc: Rpc<TRpcMethods> };\n\n/**\n * Represents a client that provides access to Solana RPC subscriptions.\n *\n * RPC subscriptions enable real-time notifications from the Solana validator,\n * such as account changes, slot updates, and transaction confirmations.\n *\n * @typeParam TRpcSubscriptionsMethods - The subscription methods available on this client.\n *            Use specific method types from `@solana/rpc-subscriptions-api` for the Solana\n *            subscription API.\n *\n * @example\n * ```ts\n * import { SolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\n *\n * async function subscribeToAccount(\n *     client: ClientWithRpcSubscriptions<SolanaRpcSubscriptionsApi>,\n *     address: Address,\n * ) {\n *     const subscription = await client.rpcSubscriptions.accountNotifications(address).subscribe();\n *     for await (const notification of subscription) {\n *         console.log('Account changed:', notification);\n *     }\n * }\n * ```\n */\nexport type ClientWithRpcSubscriptions<TRpcSubscriptionsMethods> = {\n    rpcSubscriptions: RpcSubscriptions<TRpcSubscriptionsMethods>;\n};\n"
  },
  {
    "path": "packages/plugin-interfaces/src/subscribe-to.ts",
    "content": "/**\n * Convention for advertising that a client capability is reactive.\n *\n * A plugin whose capability can change over time (for example, a wallet\n * plugin whose `client.payer` is reassigned as the user connects, switches\n * accounts, or disconnects) installs a sibling\n * `subscribeTo<Capability>(listener): () => void` function alongside the\n * capability itself. Reactive consumers (framework hooks, stores, effects)\n * can then observe changes without having to name the specific plugin that\n * installed the capability — they duck-type on the subscribe hook.\n *\n * The listener is invoked whenever the observable value of the capability\n * may have changed; consumers should re-read the capability to get the\n * current value. Over-notification is acceptable — consumers that bail on\n * reference-equal snapshots (such as React's `useSyncExternalStore`) will\n * filter redundant notifications out for free.\n *\n * Plugins whose capability is fixed for the lifetime of the client (e.g. a\n * static `payer(signer)` plugin) do not need to install this function.\n * Consumers that care about reactivity should fall back to a no-op subscribe\n * and read the capability once.\n *\n * This module defines the convention for `client.payer` and `client.identity`.\n * See {@link ClientWithSubscribeToPayer} and {@link ClientWithSubscribeToIdentity}.\n */\n\n/**\n * Registers a listener for changes to a reactive client capability. Returns\n * an unsubscribe function.\n *\n * Calling the returned unsubscribe more than once is safe — it must be\n * idempotent.\n */\nexport type SubscribeToFn = (listener: () => void) => () => void;\n\n/**\n * Represents a client that advertises `client.payer` as reactive.\n *\n * A plugin that can mutate `client.payer` over time installs this sibling\n * function so that reactive consumers can re-read the capability without\n * having to know which plugin installed it.\n *\n * The listener is invoked whenever the observable value of `client.payer`\n * may have changed; consumers should re-read `client.payer` to get the\n * current value.\n *\n * @example\n * ```ts\n * import { type ClientWithPayer, type ClientWithSubscribeToPayer } from '@solana/plugin-interfaces';\n *\n * function observePayer(client: ClientWithPayer & ClientWithSubscribeToPayer) {\n *     return client.subscribeToPayer(() => {\n *         console.log('payer is now', client.payer);\n *     });\n * }\n * ```\n *\n * @see {@link ClientWithPayer}\n * @see {@link ClientWithSubscribeToIdentity}\n */\nexport type ClientWithSubscribeToPayer = {\n    /**\n     * Registers a listener to be called whenever `client.payer` may have\n     * changed. Returns an unsubscribe function.\n     */\n    readonly subscribeToPayer: SubscribeToFn;\n};\n\n/**\n * Represents a client that advertises `client.identity` as reactive.\n *\n * A plugin that can mutate `client.identity` over time installs this sibling\n * function so that reactive consumers can re-read the capability without\n * having to know which plugin installed it.\n *\n * The listener is invoked whenever the observable value of `client.identity`\n * may have changed; consumers should re-read `client.identity` to get the\n * current value.\n *\n * @example\n * ```ts\n * import { type ClientWithIdentity, type ClientWithSubscribeToIdentity } from '@solana/plugin-interfaces';\n *\n * function observeIdentity(client: ClientWithIdentity & ClientWithSubscribeToIdentity) {\n *     return client.subscribeToIdentity(() => {\n *         console.log('identity is now', client.identity);\n *     });\n * }\n * ```\n *\n * @see {@link ClientWithIdentity}\n * @see {@link ClientWithSubscribeToPayer}\n */\nexport type ClientWithSubscribeToIdentity = {\n    /**\n     * Registers a listener to be called whenever `client.identity` may have\n     * changed. Returns an unsubscribe function.\n     */\n    readonly subscribeToIdentity: SubscribeToFn;\n};\n"
  },
  {
    "path": "packages/plugin-interfaces/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/plugin-interfaces\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "packages/plugin-interfaces/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/program-client-core/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/program-client-core/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/program-client-core/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/program-client-core/CHANGELOG.md",
    "content": "# @solana/program-client-core\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`d24f908`](https://github.com/anza-xyz/kit/commit/d24f908a4fbbddddd9e8bacc57485de6d8e022b4), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/rpc-api@6.9.0\n    - @solana/plugin-interfaces@6.9.0\n    - @solana/accounts@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/instruction-plans@6.9.0\n    - @solana/instructions@6.9.0\n    - @solana/signers@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc), [`f8d6131`](https://github.com/anza-xyz/kit/commit/f8d61310a0ca7dfeb86f7e7d3f5975b8a140370a)]:\n    - @solana/signers@6.8.0\n    - @solana/accounts@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/instruction-plans@6.8.0\n    - @solana/instructions@6.8.0\n    - @solana/plugin-interfaces@6.8.0\n    - @solana/rpc-api@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@6.7.0\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/instruction-plans@6.7.0\n    - @solana/instructions@6.7.0\n    - @solana/plugin-interfaces@6.7.0\n    - @solana/rpc-api@6.7.0\n    - @solana/signers@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad), [`0fa54a4`](https://github.com/anza-xyz/kit/commit/0fa54a469937db3989f42afc4248882736f719f5), [`f055201`](https://github.com/anza-xyz/kit/commit/f055201c2dd3a4a69b9894d66b622ae81c13b8cd)]:\n    - @solana/instruction-plans@6.6.0\n    - @solana/errors@6.6.0\n    - @solana/signers@6.6.0\n    - @solana/plugin-interfaces@6.6.0\n    - @solana/rpc-api@6.6.0\n    - @solana/accounts@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/instructions@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`10cb920`](https://github.com/anza-xyz/kit/commit/10cb92045bba4710a6c6157a3963d9e3a61f755e), [`9e05736`](https://github.com/anza-xyz/kit/commit/9e057365a1a4e350f8a0ccc233b262e09b0134fa)]:\n    - @solana/plugin-interfaces@6.5.0\n    - @solana/signers@6.5.0\n    - @solana/accounts@6.5.0\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/instruction-plans@6.5.0\n    - @solana/instructions@6.5.0\n    - @solana/rpc-api@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c), [`896412d`](https://github.com/anza-xyz/kit/commit/896412da20ced2b81f9f529e9b5feef16b7e790f)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/instruction-plans@6.4.0\n    - @solana/accounts@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/instructions@6.4.0\n    - @solana/rpc-api@6.4.0\n    - @solana/signers@6.4.0\n    - @solana/plugin-interfaces@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies [[`a557a62`](https://github.com/anza-xyz/kit/commit/a557a62e0f42d2d526f0b8fbdd0a9fcc08ac9ef7)]:\n    - @solana/instruction-plans@6.3.1\n    - @solana/plugin-interfaces@6.3.1\n    - @solana/accounts@6.3.1\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/instructions@6.3.1\n    - @solana/rpc-api@6.3.1\n    - @solana/signers@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/instruction-plans@6.3.0\n    - @solana/accounts@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/instructions@6.3.0\n    - @solana/rpc-api@6.3.0\n    - @solana/signers@6.3.0\n    - @solana/plugin-interfaces@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`98a8869`](https://github.com/anza-xyz/kit/commit/98a8869d5a728a65b7a525d87ed481616112503c), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`79db829`](https://github.com/anza-xyz/kit/commit/79db8292b2064145f615576589d8ecbf32196dc1), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/instruction-plans@6.2.0\n    - @solana/accounts@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/instructions@6.2.0\n    - @solana/rpc-api@6.2.0\n    - @solana/signers@6.2.0\n    - @solana/plugin-interfaces@6.2.0\n\n## 6.1.0\n\n### Minor Changes\n\n- [#1345](https://github.com/anza-xyz/kit/pull/1345) [`d3314a6`](https://github.com/anza-xyz/kit/commit/d3314a6e22d32219a11953e4a7ef8274b82f4b37) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `@solana/program-client-core` package containing types and utilities for building Solana program clients. This is mainly used by the JavaScript Codama renderer to generate Kit-compatible program clients.\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`1f6cd4b`](https://github.com/anza-xyz/kit/commit/1f6cd4bc7f41e865ff81ecd819dd9f728c27af77), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75), [`ee558a1`](https://github.com/anza-xyz/kit/commit/ee558a1ea8a95295db0e7b0751b32ac9d6342911), [`50010b5`](https://github.com/anza-xyz/kit/commit/50010b5b791ff0e6d8636ded3af33158f2380e4e), [`33234f5`](https://github.com/anza-xyz/kit/commit/33234f50760e34a21072304e6aaf1a31b7a410f1)]:\n    - @solana/errors@6.1.0\n    - @solana/instruction-plans@6.1.0\n    - @solana/plugin-interfaces@6.1.0\n    - @solana/accounts@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/instructions@6.1.0\n    - @solana/rpc-api@6.1.0\n    - @solana/signers@6.1.0\n"
  },
  {
    "path": "packages/program-client-core/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/program-client-core/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/program-client-core?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/program-client-core?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/program-client-core\n\n# @solana/program-client-core\n\nThis package contains types and utilities for building Solana program clients. This is mainly used by the JavaScript Codama renderer to generate Kit-compatible program clients.\n"
  },
  {
    "path": "packages/program-client-core/package.json",
    "content": "{\n    \"name\": \"@solana/program-client-core\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Core utilities for building Solana program clients\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaprogram-client-core\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/accounts\": \"workspace:*\",\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/instructions\": \"workspace:*\",\n        \"@solana/instruction-plans\": \"workspace:*\",\n        \"@solana/plugin-interfaces\": \"workspace:*\",\n        \"@solana/rpc-api\": \"workspace:*\",\n        \"@solana/signers\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/codecs-data-structures\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/program-client-core/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/program-client-core/src/__tests__/instruction-input-resolution-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { type Address, address, ProgramDerivedAddressBump } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL,\n    SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\n\nimport {\n    getAccountMetaFactory,\n    getAddressFromResolvedInstructionAccount,\n    getNonNullResolvedInstructionInput,\n    getResolvedInstructionAccountAsProgramDerivedAddress,\n    getResolvedInstructionAccountAsTransactionSigner,\n} from '../instruction-input-resolution';\n\nconst mockAddress = address('FiRHXPUxuo42VfWp3vvPVb5he5zvhvMw6DzNigN7nEpe');\nconst mockPda = [mockAddress, 255 as ProgramDerivedAddressBump] as const;\nconst mockSigner = {\n    address: mockAddress,\n    signTransactions: () => Promise.resolve([]),\n};\n\ndescribe('getNonNullResolvedInstructionInput', () => {\n    it('returns the value as-is when it is not null or undefined', () => {\n        expect(getNonNullResolvedInstructionInput('test', 'hello')).toBe('hello');\n        expect(getNonNullResolvedInstructionInput('test', 42)).toBe(42);\n        expect(getNonNullResolvedInstructionInput('test', mockAddress)).toBe(mockAddress);\n    });\n\n    it('throws when the value is null or undefined', () => {\n        expect(() => getNonNullResolvedInstructionInput('myInput', null)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL, {\n                inputName: 'myInput',\n            }),\n        );\n        expect(() => getNonNullResolvedInstructionInput('myInput', undefined)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL, {\n                inputName: 'myInput',\n            }),\n        );\n    });\n});\n\ndescribe('getAddressFromResolvedInstructionAccount', () => {\n    it('returns the address when given an Address', () => {\n        expect(getAddressFromResolvedInstructionAccount('test', mockAddress)).toBe(mockAddress);\n    });\n\n    it('extracts the address from a ProgramDerivedAddress', () => {\n        expect(getAddressFromResolvedInstructionAccount('test', mockPda)).toBe(mockAddress);\n    });\n\n    it('extracts the address from a TransactionSigner', () => {\n        expect(getAddressFromResolvedInstructionAccount('test', mockSigner)).toBe(mockAddress);\n    });\n\n    it('throws when the value is null or undefined', () => {\n        expect(() => getAddressFromResolvedInstructionAccount('myInput', null)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL, {\n                inputName: 'myInput',\n            }),\n        );\n        expect(() => getAddressFromResolvedInstructionAccount('myInput', undefined)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL, {\n                inputName: 'myInput',\n            }),\n        );\n    });\n});\n\ndescribe('getResolvedInstructionAccountAsProgramDerivedAddress', () => {\n    it('returns the PDA when given a ProgramDerivedAddress', () => {\n        expect(getResolvedInstructionAccountAsProgramDerivedAddress('test', mockPda)).toBe(mockPda);\n    });\n\n    it('throws when the value is not a PDA', () => {\n        expect(() => getResolvedInstructionAccountAsProgramDerivedAddress('myInput', mockAddress)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n                expectedType: 'ProgramDerivedAddress',\n                inputName: 'myInput',\n            }),\n        );\n        expect(() => getResolvedInstructionAccountAsProgramDerivedAddress('myInput', mockSigner)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n                expectedType: 'ProgramDerivedAddress',\n                inputName: 'myInput',\n            }),\n        );\n    });\n\n    it('throws when the value is null or undefined', () => {\n        expect(() => getResolvedInstructionAccountAsProgramDerivedAddress('myInput', null)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n                expectedType: 'ProgramDerivedAddress',\n                inputName: 'myInput',\n            }),\n        );\n        expect(() => getResolvedInstructionAccountAsProgramDerivedAddress('myInput', undefined)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n                expectedType: 'ProgramDerivedAddress',\n                inputName: 'myInput',\n            }),\n        );\n    });\n});\n\ndescribe('getResolvedInstructionAccountAsTransactionSigner', () => {\n    it('returns the signer when given a TransactionSigner', () => {\n        expect(getResolvedInstructionAccountAsTransactionSigner('test', mockSigner)).toBe(mockSigner);\n    });\n\n    it('throws when the value is not a TransactionSigner', () => {\n        expect(() => getResolvedInstructionAccountAsTransactionSigner('myInput', mockAddress)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n                expectedType: 'TransactionSigner',\n                inputName: 'myInput',\n            }),\n        );\n        expect(() => getResolvedInstructionAccountAsTransactionSigner('myInput', mockPda)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n                expectedType: 'TransactionSigner',\n                inputName: 'myInput',\n            }),\n        );\n    });\n\n    it('throws when the value is null or undefined', () => {\n        expect(() => getResolvedInstructionAccountAsTransactionSigner('myInput', null)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n                expectedType: 'TransactionSigner',\n                inputName: 'myInput',\n            }),\n        );\n        expect(() => getResolvedInstructionAccountAsTransactionSigner('myInput', undefined)).toThrow(\n            new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n                expectedType: 'TransactionSigner',\n                inputName: 'myInput',\n            }),\n        );\n    });\n});\n\ndescribe('getAccountMetaFactory', () => {\n    it('creates account meta for an Address with the correct role', () => {\n        const toAccountMeta = getAccountMetaFactory(mockAddress, 'programId');\n\n        const readonlyMeta = toAccountMeta('test', { isWritable: false, value: mockAddress });\n        expect(readonlyMeta).toEqual({ address: mockAddress, role: AccountRole.READONLY });\n\n        const writableMeta = toAccountMeta('test', { isWritable: true, value: mockAddress });\n        expect(writableMeta).toEqual({ address: mockAddress, role: AccountRole.WRITABLE });\n    });\n\n    it('creates account meta for a TransactionSigner with the signer role', () => {\n        const toAccountMeta = getAccountMetaFactory(mockAddress, 'programId');\n\n        const readonlySignerMeta = toAccountMeta('test', { isWritable: false, value: mockSigner });\n        expect(readonlySignerMeta).toEqual({\n            address: mockAddress,\n            role: AccountRole.READONLY_SIGNER,\n            signer: mockSigner,\n        });\n\n        const writableSignerMeta = toAccountMeta('test', { isWritable: true, value: mockSigner });\n        expect(writableSignerMeta).toEqual({\n            address: mockAddress,\n            role: AccountRole.WRITABLE_SIGNER,\n            signer: mockSigner,\n        });\n    });\n\n    it('extracts the address from a PDA', () => {\n        const toAccountMeta = getAccountMetaFactory(mockAddress, 'programId');\n        const meta = toAccountMeta('test', { isWritable: false, value: mockPda });\n        expect(meta).toEqual({ address: mockAddress, role: AccountRole.READONLY });\n    });\n\n    it('returns undefined for null accounts with omitted strategy', () => {\n        const toAccountMeta = getAccountMetaFactory(mockAddress, 'omitted');\n        const meta = toAccountMeta('test', { isWritable: false, value: null });\n        expect(meta).toBeUndefined();\n    });\n\n    it('returns program address for null accounts with programId strategy', () => {\n        const programAddress = address('11111111111111111111111111111111') as Address;\n        const toAccountMeta = getAccountMetaFactory(programAddress, 'programId');\n        const meta = toAccountMeta('test', { isWritable: false, value: null });\n        expect(meta).toEqual({ address: programAddress, role: AccountRole.READONLY });\n    });\n\n    it('freezes the returned meta object', () => {\n        const toAccountMeta = getAccountMetaFactory(mockAddress, 'programId');\n        const meta = toAccountMeta('test', { isWritable: false, value: mockAddress });\n        expect(meta).toBeFrozenObject();\n    });\n\n    it('freezes the returned meta object when using the program address as null', () => {\n        const programAddress = address('11111111111111111111111111111111') as Address;\n        const toAccountMeta = getAccountMetaFactory(programAddress, 'programId');\n        const meta = toAccountMeta('test', { isWritable: false, value: null });\n        expect(meta).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/program-client-core/src/__tests__/self-fetch-functions-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { fetchEncodedAccount, fetchEncodedAccounts, type MaybeEncodedAccount } from '@solana/accounts';\nimport type { Address } from '@solana/addresses';\nimport { getStructCodec } from '@solana/codecs-data-structures';\nimport { getU8Codec } from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND,\n    SolanaError,\n} from '@solana/errors';\nimport type { ClientWithRpc } from '@solana/plugin-interfaces';\nimport type { GetAccountInfoApi, GetMultipleAccountsApi } from '@solana/rpc-api';\n\nimport { addSelfFetchFunctions } from '../index';\n\njest.mock('@solana/accounts', () => ({\n    ...jest.requireActual('@solana/accounts'),\n    fetchEncodedAccount: jest.fn(),\n    fetchEncodedAccounts: jest.fn(),\n}));\n\nconst mockClient = { rpc: {} } as ClientWithRpc<GetAccountInfoApi & GetMultipleAccountsApi>;\nconst mockAddressA = '1111' as Address<'1111'>;\nconst mockAddressB = '2222' as Address<'2222'>;\nconst mockAddressMissing = '3333' as Address<'3333'>;\n\nfunction getMockCodec() {\n    return getStructCodec([['value', getU8Codec()]]);\n}\n\nfunction fetchEncodedAccountImpl(address: Address): MaybeEncodedAccount {\n    switch (address) {\n        case mockAddressA:\n            return { address, data: new Uint8Array([1]), exists: true } as MaybeEncodedAccount;\n        case mockAddressB:\n            return { address, data: new Uint8Array([2]), exists: true } as MaybeEncodedAccount;\n        default:\n            return { address, exists: false };\n    }\n}\n\ndescribe('addSelfFetchFunctions', () => {\n    beforeEach(() => {\n        jest.clearAllMocks();\n        jest.mocked(fetchEncodedAccount).mockImplementation((_rpc, address) =>\n            Promise.resolve(fetchEncodedAccountImpl(address)),\n        );\n        jest.mocked(fetchEncodedAccounts).mockImplementation((_rpc, addresses) =>\n            Promise.resolve(addresses.map(fetchEncodedAccountImpl)),\n        );\n    });\n\n    describe('fetch', () => {\n        it('fetches and decodes a single account', async () => {\n            expect.assertions(2);\n            const codec = addSelfFetchFunctions(mockClient, getMockCodec());\n            const config = { commitment: 'confirmed' as const };\n            const result = await codec.fetch(mockAddressA, config);\n\n            expect(fetchEncodedAccount).toHaveBeenCalledWith(mockClient.rpc, mockAddressA, config);\n            expect(result).toMatchObject({ address: mockAddressA, data: { value: 1 } });\n        });\n\n        it('throws when account does not exist', async () => {\n            expect.assertions(1);\n            const codec = addSelfFetchFunctions(mockClient, getMockCodec());\n\n            await expect(codec.fetch(mockAddressMissing)).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__ACCOUNTS__ACCOUNT_NOT_FOUND, { address: mockAddressMissing }),\n            );\n        });\n    });\n\n    describe('fetchMaybe', () => {\n        it('fetches and decodes a single account without asserting existence', async () => {\n            expect.assertions(2);\n            const codec = addSelfFetchFunctions(mockClient, getMockCodec());\n            const config = { commitment: 'confirmed' as const };\n            const result = await codec.fetchMaybe(mockAddressA, config);\n\n            expect(fetchEncodedAccount).toHaveBeenCalledWith(mockClient.rpc, mockAddressA, config);\n            expect(result).toMatchObject({ address: mockAddressA, data: { value: 1 }, exists: true });\n        });\n\n        it('returns a MaybeAccount for missing accounts without throwing', async () => {\n            expect.assertions(1);\n            const codec = addSelfFetchFunctions(mockClient, getMockCodec());\n            const result = await codec.fetchMaybe(mockAddressMissing);\n\n            expect(result).toStrictEqual({ address: mockAddressMissing, exists: false });\n        });\n    });\n\n    describe('fetchAll', () => {\n        it('fetches and decodes multiple accounts', async () => {\n            expect.assertions(4);\n            const codec = addSelfFetchFunctions(mockClient, getMockCodec());\n            const addresses = [mockAddressA, mockAddressB];\n            const config = { commitment: 'confirmed' as const };\n            const result = await codec.fetchAll(addresses, config);\n\n            expect(fetchEncodedAccounts).toHaveBeenCalledWith(mockClient.rpc, addresses, config);\n            expect(result).toHaveLength(2);\n            expect(result[0]).toMatchObject({ address: mockAddressA, data: { value: 1 } });\n            expect(result[1]).toMatchObject({ address: mockAddressB, data: { value: 2 } });\n        });\n\n        it('throws when any account does not exist', async () => {\n            expect.assertions(1);\n            const codec = addSelfFetchFunctions(mockClient, getMockCodec());\n\n            await expect(codec.fetchAll([mockAddressA, mockAddressMissing])).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__ACCOUNTS__ONE_OR_MORE_ACCOUNTS_NOT_FOUND, {\n                    addresses: [mockAddressMissing],\n                }),\n            );\n        });\n    });\n\n    describe('fetchAllMaybe', () => {\n        it('fetches and decodes multiple accounts without asserting existence', async () => {\n            expect.assertions(4);\n            const codec = addSelfFetchFunctions(mockClient, getMockCodec());\n            const addresses = [mockAddressA, mockAddressB];\n            const config = { commitment: 'confirmed' as const };\n            const result = await codec.fetchAllMaybe(addresses, config);\n\n            expect(fetchEncodedAccounts).toHaveBeenCalledWith(mockClient.rpc, addresses, config);\n            expect(result).toHaveLength(2);\n            expect(result[0]).toMatchObject({ address: mockAddressA, data: { value: 1 }, exists: true });\n            expect(result[1]).toMatchObject({ address: mockAddressB, data: { value: 2 }, exists: true });\n        });\n\n        it('returns MaybeAccounts including missing accounts without throwing', async () => {\n            expect.assertions(3);\n            const codec = addSelfFetchFunctions(mockClient, getMockCodec());\n            const result = await codec.fetchAllMaybe([mockAddressA, mockAddressMissing]);\n\n            expect(result).toHaveLength(2);\n            expect(result[0]).toMatchObject({ address: mockAddressA, data: { value: 1 }, exists: true });\n            expect(result[1]).toStrictEqual({ address: mockAddressMissing, exists: false });\n        });\n    });\n\n    describe('codec preservation', () => {\n        it('preserves the original codec methods', () => {\n            const originalCodec = getMockCodec();\n            const result = addSelfFetchFunctions(mockClient, originalCodec);\n\n            expect(result.encode).toBe(originalCodec.encode);\n            expect(result.decode).toBe(originalCodec.decode);\n            expect(result.read).toBe(originalCodec.read);\n            expect(result.write).toBe(originalCodec.write);\n            expect(result.fixedSize).toBe(originalCodec.fixedSize);\n        });\n\n        it('preserves custom properties from the codec', () => {\n            const customCodec = { ...getMockCodec(), custom: 42 };\n            const result = addSelfFetchFunctions(mockClient, customCodec);\n\n            expect(result.custom).toBe(42);\n        });\n\n        it('returns a frozen object', () => {\n            const result = addSelfFetchFunctions(mockClient, getMockCodec());\n\n            expect(result).toBeFrozenObject();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/program-client-core/src/__tests__/self-plan-and-send-functions-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport type { InstructionPlan } from '@solana/instruction-plans';\nimport type { Instruction } from '@solana/instructions';\nimport type { ClientWithTransactionPlanning, ClientWithTransactionSending } from '@solana/plugin-interfaces';\n\nimport { addSelfPlanAndSendFunctions } from '../self-plan-and-send-functions';\n\nconst mockInstruction: Instruction = {\n    programAddress: '11111111111111111111111111111111' as Instruction['programAddress'],\n};\n\nconst mockInstructionPlan: InstructionPlan = {\n    instruction: mockInstruction,\n    kind: 'single',\n    planType: 'instructionPlan',\n};\n\nfunction createMockClient() {\n    return {\n        planTransaction: jest.fn().mockResolvedValue({ message: 'planned' }),\n        planTransactions: jest.fn().mockResolvedValue({ plan: 'transactions' }),\n        sendTransaction: jest.fn().mockResolvedValue({ result: 'sent' }),\n        sendTransactions: jest.fn().mockResolvedValue({ results: 'sent-all' }),\n    } as unknown as ClientWithTransactionPlanning & ClientWithTransactionSending;\n}\n\ndescribe('addSelfPlanAndSendFunctions', () => {\n    describe('with synchronous inputs', () => {\n        it('adds planTransaction method that delegates to the client', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const result = addSelfPlanAndSendFunctions(client, mockInstruction);\n            const config = { abortSignal: new AbortController().signal };\n            await result.planTransaction(config);\n\n            expect(client.planTransaction).toHaveBeenCalledWith(mockInstruction, config);\n        });\n\n        it('adds planTransactions method that delegates to the client', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const result = addSelfPlanAndSendFunctions(client, mockInstruction);\n            const config = { abortSignal: new AbortController().signal };\n            await result.planTransactions(config);\n\n            expect(client.planTransactions).toHaveBeenCalledWith(mockInstruction, config);\n        });\n\n        it('adds sendTransaction method that delegates to the client', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const result = addSelfPlanAndSendFunctions(client, mockInstruction);\n            const config = { abortSignal: new AbortController().signal };\n            await result.sendTransaction(config);\n\n            expect(client.sendTransaction).toHaveBeenCalledWith(mockInstruction, config);\n        });\n\n        it('adds sendTransactions method that delegates to the client', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const result = addSelfPlanAndSendFunctions(client, mockInstruction);\n            const config = { abortSignal: new AbortController().signal };\n            await result.sendTransactions(config);\n\n            expect(client.sendTransactions).toHaveBeenCalledWith(mockInstruction, config);\n        });\n\n        it('works with instruction plans', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const result = addSelfPlanAndSendFunctions(client, mockInstructionPlan);\n            await result.sendTransaction();\n\n            expect(client.sendTransaction).toHaveBeenCalledWith(mockInstructionPlan, undefined);\n        });\n\n        it('preserves the original instruction properties', () => {\n            const client = createMockClient();\n            const result = addSelfPlanAndSendFunctions(client, { ...mockInstruction, custom: 42 });\n\n            expect(result.custom).toBe(42);\n        });\n\n        it('preserves the original instruction plan properties', () => {\n            const client = createMockClient();\n            const result = addSelfPlanAndSendFunctions(client, { ...mockInstructionPlan, custom: 42 });\n\n            expect(result.custom).toBe(42);\n        });\n\n        it('returns a frozen object', () => {\n            const client = createMockClient();\n            const result = addSelfPlanAndSendFunctions(client, mockInstruction);\n\n            expect(result).toBeFrozenObject();\n        });\n    });\n\n    describe('with promise-like inputs', () => {\n        it('adds planTransaction method that awaits the input before delegating', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const instructionPromise = Promise.resolve(mockInstruction);\n            const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n            const config = { abortSignal: new AbortController().signal };\n            await result.planTransaction(config);\n\n            expect(client.planTransaction).toHaveBeenCalledWith(mockInstruction, config);\n        });\n\n        it('adds planTransactions method that awaits the input before delegating', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const instructionPromise = Promise.resolve(mockInstruction);\n            const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n            const config = { abortSignal: new AbortController().signal };\n            await result.planTransactions(config);\n\n            expect(client.planTransactions).toHaveBeenCalledWith(mockInstruction, config);\n        });\n\n        it('adds sendTransaction method that awaits the input before delegating', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const instructionPromise = Promise.resolve(mockInstruction);\n            const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n            const config = { abortSignal: new AbortController().signal };\n            await result.sendTransaction(config);\n\n            expect(client.sendTransaction).toHaveBeenCalledWith(mockInstruction, config);\n        });\n\n        it('adds sendTransactions method that awaits the input before delegating', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const instructionPromise = Promise.resolve(mockInstruction);\n            const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n            const config = { abortSignal: new AbortController().signal };\n            await result.sendTransactions(config);\n\n            expect(client.sendTransactions).toHaveBeenCalledWith(mockInstruction, config);\n        });\n\n        it('works with promise-like instruction plans', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const planPromise = Promise.resolve(mockInstructionPlan);\n            const result = addSelfPlanAndSendFunctions(client, planPromise);\n            await result.sendTransaction();\n\n            expect(client.sendTransaction).toHaveBeenCalledWith(mockInstructionPlan, undefined);\n        });\n\n        it('preserves the original promise', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const instructionPromise = Promise.resolve(mockInstruction);\n            const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n            const resolved = await result;\n\n            expect(resolved).toBe(mockInstruction);\n        });\n\n        it('works with custom promise-like objects', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const customPromiseLike: PromiseLike<Instruction> = {\n                then(onFulfilled) {\n                    return Promise.resolve(mockInstruction).then(onFulfilled);\n                },\n            };\n            const result = addSelfPlanAndSendFunctions(client, customPromiseLike);\n            await result.sendTransaction();\n\n            expect(client.sendTransaction).toHaveBeenCalledWith(mockInstruction, undefined);\n        });\n\n        it('preserves the original instruction properties', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const instructionPromise = Promise.resolve({ ...mockInstruction, custom: 42 });\n            const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n            const resolved = await result;\n\n            expect(resolved.custom).toBe(42);\n        });\n\n        it('preserves the original instruction plan properties', async () => {\n            expect.assertions(1);\n            const client = createMockClient();\n            const instructionPlanPromise = Promise.resolve({ ...mockInstructionPlan, custom: 42 });\n            const result = addSelfPlanAndSendFunctions(client, instructionPlanPromise);\n            const resolved = await result;\n\n            expect(resolved.custom).toBe(42);\n        });\n\n        it('does not freeze promises', () => {\n            const client = createMockClient();\n            const instructionPromise = Promise.resolve({ ...mockInstruction, custom: 42 });\n            const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n\n            expect(result).not.toBeFrozenObject();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/program-client-core/src/__typetests__/instruction-input-resolution-typetest.ts",
    "content": "import type { Address, ProgramDerivedAddress } from '@solana/addresses';\nimport type { AccountMeta } from '@solana/instructions';\nimport type { AccountSignerMeta, TransactionSigner } from '@solana/signers';\n\nimport {\n    getAccountMetaFactory,\n    getAddressFromResolvedInstructionAccount,\n    getNonNullResolvedInstructionInput,\n    getResolvedInstructionAccountAsProgramDerivedAddress,\n    getResolvedInstructionAccountAsTransactionSigner,\n    ResolvedInstructionAccount,\n} from '../index';\n\nconst mockAddress = null as unknown as Address<'1111'>;\nconst mockPda = null as unknown as ProgramDerivedAddress<'2222'>;\nconst mockSigner = null as unknown as TransactionSigner<'3333'>;\n\n// [DESCRIBE] getNonNullResolvedInstructionInput\n{\n    // It returns the value with its original type.\n    {\n        getNonNullResolvedInstructionInput('test', mockAddress) satisfies Address<'1111'>;\n    }\n\n    // It accepts null or undefined as input (runtime will throw an error).\n    {\n        getNonNullResolvedInstructionInput<string>('test', null) satisfies string;\n        getNonNullResolvedInstructionInput<string>('test', undefined) satisfies string;\n    }\n}\n\n// [DESCRIBE] getAddressFromResolvedInstructionAccount\n{\n    // It extracts an address from an Address value.\n    {\n        getAddressFromResolvedInstructionAccount('test', mockAddress) satisfies Address<'1111'>;\n    }\n\n    // It extracts an address from a ProgramDerivedAddress value.\n    {\n        getAddressFromResolvedInstructionAccount('test', mockPda) satisfies Address<'2222'>;\n    }\n\n    // It extracts an address from a TransactionSigner value.\n    {\n        getAddressFromResolvedInstructionAccount('test', mockSigner) satisfies Address<'3333'>;\n    }\n\n    // It accepts null or undefined as input (runtime will throw an error).\n    {\n        getAddressFromResolvedInstructionAccount('test', null) satisfies Address;\n        getAddressFromResolvedInstructionAccount('test', undefined) satisfies Address;\n    }\n}\n\n// [DESCRIBE] getResolvedInstructionAccountAsProgramDerivedAddress\n{\n    // It returns a ProgramDerivedAddress.\n    {\n        getResolvedInstructionAccountAsProgramDerivedAddress('test', mockPda) satisfies ProgramDerivedAddress<'2222'>;\n    }\n\n    // It accepts null or undefined as input (runtime will throw an error).\n    {\n        getResolvedInstructionAccountAsProgramDerivedAddress('test', null) satisfies ProgramDerivedAddress;\n        getResolvedInstructionAccountAsProgramDerivedAddress('test', undefined) satisfies ProgramDerivedAddress;\n    }\n}\n\n// [DESCRIBE] getResolvedInstructionAccountAsTransactionSigner\n{\n    // It returns a TransactionSigner.\n    {\n        getResolvedInstructionAccountAsTransactionSigner('test', mockSigner) satisfies TransactionSigner<'3333'>;\n    }\n\n    // It accepts null or undefined as input (runtime will throw an error).\n    {\n        getResolvedInstructionAccountAsTransactionSigner('test', null) satisfies TransactionSigner;\n        getResolvedInstructionAccountAsTransactionSigner('test', undefined) satisfies TransactionSigner;\n    }\n}\n\n// [DESCRIBE] ResolvedInstructionAccount\n{\n    // It defaults to allowing Address, ProgramDerivedAddress, TransactionSigner, or null.\n    {\n        const account: ResolvedInstructionAccount = { isWritable: true, value: mockAddress };\n        account satisfies { isWritable: boolean; value: Address | ProgramDerivedAddress | TransactionSigner | null };\n    }\n\n    // It can be narrowed to a specific value type.\n    {\n        const account: ResolvedInstructionAccount<'1111', Address<'1111'>> = { isWritable: false, value: mockAddress };\n        account satisfies { isWritable: boolean; value: Address<'1111'> };\n    }\n}\n\n// [DESCRIBE] getAccountMetaFactory\n{\n    // It returns a factory that produces AccountMeta or AccountSignerMeta.\n    {\n        const toAccountMeta = getAccountMetaFactory(mockAddress, 'programId');\n        const meta = toAccountMeta('test', { isWritable: true, value: mockAddress });\n        meta satisfies AccountMeta | AccountSignerMeta | undefined;\n    }\n}\n"
  },
  {
    "path": "packages/program-client-core/src/__typetests__/instructions-typetest.ts",
    "content": "import type { InstructionWithByteDelta } from '../index';\n\n// [DESCRIBE] InstructionWithByteDelta\n{\n    // It contains a byteDelta property.\n    {\n        ({ byteDelta: 100 }) satisfies InstructionWithByteDelta;\n    }\n\n    // It accepts negative byte deltas.\n    {\n        ({ byteDelta: -50 }) satisfies InstructionWithByteDelta;\n    }\n}\n"
  },
  {
    "path": "packages/program-client-core/src/__typetests__/self-fetch-functions-typetest.ts",
    "content": "import type { Account, FetchAccountConfig, FetchAccountsConfig, MaybeAccount } from '@solana/accounts';\nimport type { Address } from '@solana/addresses';\nimport type { Codec, FixedSizeCodec, ReadonlyUint8Array, VariableSizeCodec } from '@solana/codecs-core';\nimport type { ClientWithRpc } from '@solana/plugin-interfaces';\nimport type { GetAccountInfoApi, GetMultipleAccountsApi } from '@solana/rpc-api';\n\nimport { addSelfFetchFunctions, type SelfFetchFunctions } from '../index';\n\ntype RpcClient = ClientWithRpc<GetAccountInfoApi & GetMultipleAccountsApi>;\n\ntype MyAccountData = { age: number; name: string };\n\n// [DESCRIBE] SelfFetchFunctions.\n{\n    // It provides a fetch method that returns a promise of an Account.\n    {\n        const self = null as unknown as SelfFetchFunctions<MyAccountData, MyAccountData>;\n        const address = null as unknown as Address<'1111'>;\n        void (self.fetch(address) satisfies Promise<Account<MyAccountData, '1111'>>);\n    }\n\n    // It provides a fetchMaybe method that returns a promise of a MaybeAccount.\n    {\n        const self = null as unknown as SelfFetchFunctions<MyAccountData, MyAccountData>;\n        const address = null as unknown as Address<'1111'>;\n        void (self.fetchMaybe(address) satisfies Promise<MaybeAccount<MyAccountData, '1111'>>);\n    }\n\n    // It provides a fetchAll method that returns a promise of an array of Accounts.\n    {\n        const self = null as unknown as SelfFetchFunctions<MyAccountData, MyAccountData>;\n        const addresses = null as unknown as Address[];\n        void (self.fetchAll(addresses) satisfies Promise<Account<MyAccountData>[]>);\n    }\n\n    // It provides a fetchAllMaybe method that returns a promise of an array of MaybeAccounts.\n    {\n        const self = null as unknown as SelfFetchFunctions<MyAccountData, MyAccountData>;\n        const addresses = null as unknown as Address[];\n        void (self.fetchAllMaybe(addresses) satisfies Promise<MaybeAccount<MyAccountData>[]>);\n    }\n\n    // All single-account methods accept an optional FetchAccountConfig.\n    {\n        const self = null as unknown as SelfFetchFunctions<MyAccountData, MyAccountData>;\n        const address = null as unknown as Address<'1111'>;\n        const config: FetchAccountConfig = { commitment: 'confirmed' };\n        void (self.fetch(address, config) satisfies Promise<Account<MyAccountData, '1111'>>);\n        void (self.fetchMaybe(address, config) satisfies Promise<MaybeAccount<MyAccountData, '1111'>>);\n    }\n\n    // All multi-account methods accept an optional FetchAccountsConfig.\n    {\n        const self = null as unknown as SelfFetchFunctions<MyAccountData, MyAccountData>;\n        const addresses = null as unknown as Address[];\n        const config: FetchAccountsConfig = { commitment: 'confirmed' };\n        void (self.fetchAll(addresses, config) satisfies Promise<Account<MyAccountData>[]>);\n        void (self.fetchAllMaybe(addresses, config) satisfies Promise<MaybeAccount<MyAccountData>[]>);\n    }\n\n    // It supports different TFrom and TTo types.\n    {\n        type MyAccountInput = { age: bigint | number; name: string };\n        const self = null as unknown as SelfFetchFunctions<MyAccountInput, MyAccountData>;\n        const address = null as unknown as Address<'1111'>;\n        // The decoded type should be TTo (MyAccountData), not TFrom (MyAccountInput).\n        void (self.fetch(address) satisfies Promise<Account<MyAccountData, '1111'>>);\n    }\n}\n\n// [DESCRIBE] addSelfFetchFunctions.\n{\n    // It returns a Codec with SelfFetchFunctions when given a Codec.\n    {\n        const client = null as unknown as RpcClient;\n        const codec = null as unknown as FixedSizeCodec<MyAccountData>;\n        const result = addSelfFetchFunctions(client, codec);\n        result satisfies Codec<MyAccountData> & SelfFetchFunctions<MyAccountData, MyAccountData>;\n    }\n\n    // It preserves the specific codec type.\n    {\n        type MyCodec = FixedSizeCodec<MyAccountData> & { custom: 42 };\n        const client = null as unknown as RpcClient;\n        const codec = null as unknown as MyCodec;\n        const result = addSelfFetchFunctions(client, codec);\n        result satisfies MyCodec;\n    }\n\n    // It supports codecs with different TFrom and TTo types.\n    {\n        type MyAccountInput = { age: bigint | number; name: string };\n        const client = null as unknown as RpcClient;\n        const codec = null as unknown as Codec<MyAccountInput, MyAccountData>;\n        const result = addSelfFetchFunctions(client, codec);\n        result satisfies Codec<MyAccountInput, MyAccountData> & SelfFetchFunctions<MyAccountInput, MyAccountData>;\n    }\n\n    // The fetch methods use the TTo type for Account data.\n    {\n        type MyAccountInput = { age: bigint | number; name: string };\n        const client = null as unknown as RpcClient;\n        const codec = null as unknown as Codec<MyAccountInput, MyAccountData>;\n        const result = addSelfFetchFunctions(client, codec);\n        const address = null as unknown as Address<'1111'>;\n        // The fetched account should have TTo (MyAccountData) as its data type.\n        void (result.fetch(address) satisfies Promise<Account<MyAccountData, '1111'>>);\n    }\n\n    // It retains codec methods like encode, decode and size attributes.\n    {\n        const client = null as unknown as RpcClient;\n        const codec = null as unknown as VariableSizeCodec<MyAccountData>;\n        const result = addSelfFetchFunctions(client, codec);\n        // Should still be able to use codec methods.\n        result.encode({ age: 30, name: 'Alice' }) satisfies ReadonlyUint8Array;\n        result.decode(new Uint8Array()) satisfies MyAccountData;\n        result.getSizeFromValue({ age: 30, name: 'Alice' }) satisfies number;\n    }\n\n    // It works with a codec factory function that returns a Codec.\n    {\n        type MyAccountInput = { age: bigint | number; name: string };\n        const client = null as unknown as RpcClient;\n        const getMyAccountCodec = null as unknown as () => FixedSizeCodec<MyAccountInput, MyAccountData>;\n        const result = addSelfFetchFunctions(client, getMyAccountCodec());\n        result satisfies ReturnType<typeof getMyAccountCodec> & SelfFetchFunctions<MyAccountInput, MyAccountData>;\n    }\n}\n"
  },
  {
    "path": "packages/program-client-core/src/__typetests__/self-plan-and-send-functions-typetest.ts",
    "content": "import type {\n    InstructionPlan,\n    SingleInstructionPlan,\n    SingleTransactionPlan,\n    SuccessfulSingleTransactionPlanResult,\n    TransactionPlan,\n    TransactionPlanResult,\n} from '@solana/instruction-plans';\nimport type { Instruction } from '@solana/instructions';\nimport type { ClientWithTransactionPlanning, ClientWithTransactionSending } from '@solana/plugin-interfaces';\n\nimport { addSelfPlanAndSendFunctions, type SelfPlanAndSendFunctions } from '../index';\n\ntype FullClient = ClientWithTransactionPlanning & ClientWithTransactionSending;\n\n// [DESCRIBE] SelfPlanAndSendFunctions.\n{\n    // It provides a planTransaction method that returns a promise of a transaction message.\n    {\n        const self = null as unknown as SelfPlanAndSendFunctions;\n        void (self.planTransaction() satisfies Promise<SingleTransactionPlan['message']>);\n    }\n\n    // It provides a planTransactions method that returns a promise of a transaction plan.\n    {\n        const self = null as unknown as SelfPlanAndSendFunctions;\n        void (self.planTransactions() satisfies Promise<TransactionPlan>);\n    }\n\n    // It provides a sendTransaction method that returns a promise of a single successful result.\n    {\n        const self = null as unknown as SelfPlanAndSendFunctions;\n        void (self.sendTransaction() satisfies Promise<SuccessfulSingleTransactionPlanResult>);\n    }\n\n    // It provides a sendTransactions method that returns a promise of a transaction plan result.\n    {\n        const self = null as unknown as SelfPlanAndSendFunctions;\n        void (self.sendTransactions() satisfies Promise<TransactionPlanResult>);\n    }\n\n    // All methods accept an optional config with abortSignal.\n    {\n        const self = null as unknown as SelfPlanAndSendFunctions;\n        const abortController = new AbortController();\n        void (self.planTransaction({\n            abortSignal: abortController.signal,\n        }) satisfies Promise<SingleTransactionPlan['message']>);\n        void (self.planTransactions({\n            abortSignal: abortController.signal,\n        }) satisfies Promise<TransactionPlan>);\n        void (self.sendTransaction({\n            abortSignal: abortController.signal,\n        }) satisfies Promise<SuccessfulSingleTransactionPlanResult>);\n        void (self.sendTransactions({\n            abortSignal: abortController.signal,\n        }) satisfies Promise<TransactionPlanResult>);\n    }\n}\n\n// [DESCRIBE] addSelfPlanAndSendFunctions.\n{\n    // It returns an Instruction with SelfPlanAndSendFunctions when given an Instruction.\n    {\n        const client = null as unknown as FullClient;\n        const instruction = null as unknown as Instruction;\n        const result = addSelfPlanAndSendFunctions(client, instruction);\n        result satisfies Instruction & SelfPlanAndSendFunctions;\n    }\n\n    // It returns an InstructionPlan with SelfPlanAndSendFunctions when given an InstructionPlan.\n    {\n        const client = null as unknown as FullClient;\n        const plan = null as unknown as InstructionPlan;\n        const result = addSelfPlanAndSendFunctions(client, plan);\n        result satisfies InstructionPlan & SelfPlanAndSendFunctions;\n    }\n\n    // It returns a PromiseLike<Instruction> with SelfPlanAndSendFunctions when given a PromiseLike<Instruction>.\n    {\n        const client = null as unknown as FullClient;\n        const instructionPromise = null as unknown as PromiseLike<Instruction>;\n        const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n        result satisfies PromiseLike<Instruction> & SelfPlanAndSendFunctions;\n    }\n\n    // It returns a PromiseLike<InstructionPlan> with SelfPlanAndSendFunctions when given a PromiseLike<InstructionPlan>.\n    {\n        const client = null as unknown as FullClient;\n        const planPromise = null as unknown as PromiseLike<InstructionPlan>;\n        const result = addSelfPlanAndSendFunctions(client, planPromise);\n        result satisfies PromiseLike<InstructionPlan> & SelfPlanAndSendFunctions;\n    }\n\n    // It preserves the specific instruction type.\n    {\n        type MyInstruction = Instruction<'MyProgram111111111111111111111111'> & { custom: 42 };\n        const client = null as unknown as FullClient;\n        const instruction = null as unknown as MyInstruction;\n        const result = addSelfPlanAndSendFunctions(client, instruction);\n        result satisfies MyInstruction;\n    }\n\n    // It preserves the specific instruction plan type.\n    {\n        type MyPlan = SingleInstructionPlan & { custom: 42 };\n        const client = null as unknown as FullClient;\n        const plan = null as unknown as MyPlan;\n        const result = addSelfPlanAndSendFunctions(client, plan);\n        result satisfies MyPlan;\n    }\n\n    // It preserves the Promise type with specific instruction.\n    {\n        type MyInstruction = Instruction<'MyProgram111111111111111111111111'>;\n        const client = null as unknown as FullClient;\n        const instructionPromise = null as unknown as Promise<MyInstruction>;\n        const result = addSelfPlanAndSendFunctions(client, instructionPromise);\n        void (result satisfies Promise<MyInstruction>);\n    }\n}\n"
  },
  {
    "path": "packages/program-client-core/src/index.ts",
    "content": "/**\n * This package contains types and utilities for building Solana program clients.\n * This is mainly used by the JavaScript Codama renderer to generate\n * Kit-compatible program clients.\n *\n * @packageDocumentation\n */\nexport * from './instruction-input-resolution';\nexport * from './instructions';\nexport * from './self-fetch-functions';\nexport * from './self-plan-and-send-functions';\n"
  },
  {
    "path": "packages/program-client-core/src/instruction-input-resolution.ts",
    "content": "import { type Address, isProgramDerivedAddress, type ProgramDerivedAddress } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL,\n    SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE,\n    SolanaError,\n} from '@solana/errors';\nimport { type AccountMeta, AccountRole, upgradeRoleToSigner } from '@solana/instructions';\nimport { type AccountSignerMeta, isTransactionSigner, type TransactionSigner } from '@solana/signers';\n\n/**\n * Ensures a resolved instruction input is not null or undefined.\n *\n * This function is used during instruction resolution to validate that\n * required inputs have been properly resolved to a non-null value.\n *\n * @typeParam T - The expected type of the resolved input value.\n *\n * @param inputName - The name of the instruction input, used in error messages.\n * @param value - The resolved value to validate.\n * @returns The validated non-null value.\n *\n * @throws Throws a {@link SolanaError} if the value is null or undefined.\n *\n * @example\n * ```ts\n * const resolvedAuthority = getNonNullResolvedInstructionInput(\n *   'authority',\n *   maybeAuthority\n * );\n * // resolvedAuthority is guaranteed to be non-null here.\n * ```\n */\nexport function getNonNullResolvedInstructionInput<T>(inputName: string, value: T | null | undefined): T {\n    if (value === null || value === undefined) {\n        throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__RESOLVED_INSTRUCTION_INPUT_MUST_BE_NON_NULL, {\n            inputName,\n        });\n    }\n    return value;\n}\n\n/**\n * Extracts the address from a resolved instruction account.\n *\n * A resolved instruction account can be an {@link Address}, a {@link ProgramDerivedAddress},\n * or a {@link TransactionSigner}. This function extracts the underlying address from\n * any of these types.\n *\n * @typeParam T - The address type, defaults to `string`.\n *\n * @param inputName - The name of the instruction input, used in error messages.\n * @param value - The resolved account value to extract the address from.\n * @returns The extracted address.\n *\n * @throws Throws a {@link SolanaError} if the value is null or undefined.\n *\n * @example\n * ```ts\n * const address = getAddressFromResolvedInstructionAccount('mint', resolvedMint);\n * ```\n */\nexport function getAddressFromResolvedInstructionAccount<T extends string = string>(\n    inputName: string,\n    value: ResolvedInstructionAccount<T>['value'] | undefined,\n): Address<T> {\n    const nonNullValue = getNonNullResolvedInstructionInput(inputName, value);\n    if (typeof value === 'object' && 'address' in nonNullValue) {\n        return nonNullValue.address;\n    }\n    if (Array.isArray(nonNullValue)) {\n        return nonNullValue[0] as Address<T>;\n    }\n    return nonNullValue as Address<T>;\n}\n\n/**\n * Extracts a {@link ProgramDerivedAddress} from a resolved instruction account.\n *\n * This function validates that the resolved account is a PDA and returns it.\n * Use this when you need access to both the address and the bump seed of a PDA.\n *\n * @typeParam T - The address type, defaults to `string`.\n *\n * @param inputName - The name of the instruction input, used in error messages.\n * @param value - The resolved account value expected to be a PDA.\n * @returns The program-derived address.\n *\n * @throws Throws a {@link SolanaError} if the value is not a {@link ProgramDerivedAddress}.\n *\n * @example\n * ```ts\n * const pda = getResolvedInstructionAccountAsProgramDerivedAddress('metadata', resolvedMetadata);\n * const [address, bump] = pda;\n * ```\n */\nexport function getResolvedInstructionAccountAsProgramDerivedAddress<T extends string = string>(\n    inputName: string,\n    value: ResolvedInstructionAccount<T>['value'] | undefined,\n): ProgramDerivedAddress<T> {\n    if (!isProgramDerivedAddress(value)) {\n        throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n            expectedType: 'ProgramDerivedAddress',\n            inputName,\n        });\n    }\n    return value;\n}\n\n/**\n * Extracts a {@link TransactionSigner} from a resolved instruction account.\n *\n * This function validates that the resolved account is a transaction signer and returns it.\n * Use this when you need the resolved account to be a signer.\n *\n * @typeParam T - The address type, defaults to `string`.\n *\n * @param inputName - The name of the instruction input, used in error messages.\n * @param value - The resolved account value expected to be a signer.\n * @returns The transaction signer.\n *\n * @throws Throws a {@link SolanaError} if the value is not a {@link TransactionSigner}.\n *\n * @example\n * ```ts\n * const signer = getResolvedInstructionAccountAsTransactionSigner('authority', resolvedAuthority);\n * ```\n */\nexport function getResolvedInstructionAccountAsTransactionSigner<T extends string = string>(\n    inputName: string,\n    value: ResolvedInstructionAccount<T>['value'] | undefined,\n): TransactionSigner<T> {\n    if (!isResolvedInstructionAccountSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNEXPECTED_RESOLVED_INSTRUCTION_INPUT_TYPE, {\n            expectedType: 'TransactionSigner',\n            inputName,\n        });\n    }\n    return value;\n}\n\n/**\n * Represents a resolved account input for an instruction.\n *\n * During instruction building, account inputs are resolved to this type which\n * captures both the account value and whether it should be marked as writable.\n * The value can be an {@link Address}, a {@link ProgramDerivedAddress}, a\n * {@link TransactionSigner}, or `null` for optional accounts.\n *\n * @typeParam TAddress - The address type, defaults to `string`.\n * @typeParam TValue - The type of the resolved value.\n *\n * @example\n * ```ts\n * const mintAccount: ResolvedInstructionAccount = {\n *   value: mintAddress,\n *   isWritable: true,\n * };\n * ```\n */\nexport type ResolvedInstructionAccount<\n    TAddress extends string = string,\n    TValue extends Address<TAddress> | ProgramDerivedAddress<TAddress> | TransactionSigner<TAddress> | null =\n        | Address<TAddress>\n        | ProgramDerivedAddress<TAddress>\n        | TransactionSigner<TAddress>\n        | null,\n> = {\n    isWritable: boolean;\n    value: TValue;\n};\n\n/**\n * Creates a factory function that converts resolved instruction accounts to account metas.\n *\n * The factory handles the conversion of {@link ResolvedInstructionAccount} objects into\n * {@link AccountMeta} or {@link AccountSignerMeta} objects suitable for building instructions.\n * It also determines how to handle optional accounts based on the provided strategy.\n *\n * @param programAddress - The program address, used when optional accounts use the `programId` strategy.\n * @param optionalAccountStrategy - How to handle null account values:\n *   - `'omitted'`: Optional accounts are excluded from the instruction entirely.\n *   - `'programId'`: Optional accounts are replaced with the program address as a read-only account.\n * @returns A factory function that converts a resolved account to an account meta.\n *\n * @example\n * ```ts\n * const toAccountMeta = getAccountMetaFactory(programAddress, 'programId');\n * const mintMeta = toAccountMeta('mint', resolvedMint);\n * ```\n */\nexport function getAccountMetaFactory(programAddress: Address, optionalAccountStrategy: 'omitted' | 'programId') {\n    return (inputName: string, account: ResolvedInstructionAccount): AccountMeta | AccountSignerMeta | undefined => {\n        if (!account.value) {\n            if (optionalAccountStrategy === 'omitted') return;\n            return Object.freeze({ address: programAddress, role: AccountRole.READONLY });\n        }\n\n        const writableRole = account.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;\n        const isSigner = isResolvedInstructionAccountSigner(account.value);\n        return Object.freeze({\n            address: getAddressFromResolvedInstructionAccount(inputName, account.value),\n            role: isSigner ? upgradeRoleToSigner(writableRole) : writableRole,\n            ...(isSigner ? { signer: account.value } : {}),\n        });\n    };\n}\n\nfunction isResolvedInstructionAccountSigner(value: unknown): value is TransactionSigner {\n    return (\n        !!value &&\n        typeof value === 'object' &&\n        'address' in value &&\n        typeof value.address === 'string' &&\n        isTransactionSigner(value as { address: Address })\n    );\n}\n"
  },
  {
    "path": "packages/program-client-core/src/instructions.ts",
    "content": "/**\n * An instruction that tracks how many bytes it adds or removes from on-chain accounts.\n *\n * The `byteDelta` indicates the net change in account storage size. A positive value\n * means bytes are being allocated, while a negative value means bytes are being freed.\n * This is useful for calculating how much balance a storage payer must have for a\n * transaction to succeed.\n */\nexport type InstructionWithByteDelta = {\n    byteDelta: number;\n};\n"
  },
  {
    "path": "packages/program-client-core/src/self-fetch-functions.ts",
    "content": "import {\n    type Account,\n    assertAccountExists,\n    assertAccountsExist,\n    decodeAccount,\n    type FetchAccountConfig,\n    type FetchAccountsConfig,\n    fetchEncodedAccount,\n    fetchEncodedAccounts,\n    type MaybeAccount,\n} from '@solana/accounts';\nimport type { Address } from '@solana/addresses';\nimport type { Codec } from '@solana/codecs-core';\nimport type { ClientWithRpc } from '@solana/plugin-interfaces';\nimport type { GetAccountInfoApi, GetMultipleAccountsApi } from '@solana/rpc-api';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyObjectCodec = Codec<any, object>;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferTFrom<T> = T extends Codec<infer TFrom, any> ? TFrom : never;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype InferTTo<T> = T extends Codec<any, infer TTo> ? TTo : never;\n\n/**\n * Methods that allow a codec to fetch and decode accounts directly.\n *\n * These methods are added to codec objects via {@link addSelfFetchFunctions},\n * enabling a fluent API where you can call `.fetch()` directly on a codec\n * to retrieve and decode accounts in one step.\n *\n * @typeParam TFrom - The type that the codec encodes from.\n * @typeParam TTo - The type that the codec decodes to.\n *\n * @example\n * Fetching a single account and asserting it exists.\n * ```ts\n * const account = await myAccountCodec.fetch(address);\n * // account.data is of type TTo.\n * ```\n *\n * @example\n * Fetching a single account that may not exist.\n * ```ts\n * const maybeAccount = await myAccountCodec.fetchMaybe(address);\n * if (maybeAccount.exists) {\n *     // maybeAccount.data is of type TTo.\n * }\n * ```\n *\n * @example\n * Fetching multiple accounts at once.\n * ```ts\n * const accounts = await myAccountCodec.fetchAll([addressA, addressB]);\n * // All accounts exist.\n * ```\n *\n * @see {@link addSelfFetchFunctions}\n */\nexport type SelfFetchFunctions<TFrom extends object, TTo extends TFrom> = {\n    /** Fetches and decodes a single account, throwing if it does not exist. */\n    readonly fetch: <TAddress extends string>(\n        address: Address<TAddress>,\n        config?: FetchAccountConfig,\n    ) => Promise<Account<TTo, TAddress>>;\n    /** Fetches and decodes multiple accounts, throwing if any do not exist. */\n    readonly fetchAll: (addresses: Address[], config?: FetchAccountsConfig) => Promise<Account<TTo>[]>;\n    /** Fetches and decodes multiple accounts, returning {@link MaybeAccount} for each. */\n    readonly fetchAllMaybe: (addresses: Address[], config?: FetchAccountsConfig) => Promise<MaybeAccount<TTo>[]>;\n    /** Fetches and decodes a single account, returning a {@link MaybeAccount}. */\n    readonly fetchMaybe: <TAddress extends string>(\n        address: Address<TAddress>,\n        config?: FetchAccountConfig,\n    ) => Promise<MaybeAccount<TTo, TAddress>>;\n};\n\n/**\n * Adds self-fetching methods to a codec for retrieving and decoding accounts.\n *\n * This function augments the provided codec with methods that allow it to fetch\n * accounts from the network and decode them in one step. It enables a fluent API\n * where you can call methods like `.fetch()` directly on the codec.\n *\n * @typeParam TFrom - The type that the codec encodes from.\n * @typeParam TTo - The type that the codec decodes to.\n * @typeParam TCodec - The codec type being augmented.\n *\n * @param client - A client that provides RPC access for fetching accounts.\n * @param codec - The codec to augment with self-fetch methods.\n * @returns The codec augmented with {@link SelfFetchFunctions} methods.\n *\n * @example\n * Adding self-fetch functions to an account codec.\n * ```ts\n * import { addSelfFetchFunctions } from '@solana/program-client-core';\n *\n * const myAccountCodec = addSelfFetchFunctions(client, getMyAccountCodec());\n *\n * // Fetch and decode an account in one step.\n * const account = await myAccountCodec.fetch(accountAddress);\n * ```\n *\n * @example\n * Handling accounts that may not exist.\n * ```ts\n * const myAccountCodec = addSelfFetchFunctions(client, getMyAccountCodec());\n *\n * const maybeAccount = await myAccountCodec.fetchMaybe(accountAddress);\n * if (maybeAccount.exists) {\n *     console.log('Account data:', maybeAccount.data);\n * } else {\n *     console.log(`Account ${maybeAccount.address} does not exist`);\n * }\n * ```\n *\n * @example\n * Fetching multiple accounts at once.\n * ```ts\n * const myAccountCodec = addSelfFetchFunctions(client, getMyAccountCodec());\n *\n * // Throws if any account does not exist.\n * const accounts = await myAccountCodec.fetchAll([addressA, addressB, addressC]);\n *\n * // Returns MaybeAccount for each, allowing some to not exist.\n * const maybeAccounts = await myAccountCodec.fetchAllMaybe([addressA, addressB]);\n * ```\n *\n * @see {@link SelfFetchFunctions}\n */\nexport function addSelfFetchFunctions<TCodec extends AnyObjectCodec>(\n    client: ClientWithRpc<GetAccountInfoApi & GetMultipleAccountsApi>,\n    codec: TCodec,\n): SelfFetchFunctions<InferTFrom<TCodec>, InferTTo<TCodec>> & TCodec {\n    type Functions = SelfFetchFunctions<InferTFrom<TCodec>, InferTTo<TCodec>>;\n    type InferredCodec = Codec<InferTFrom<TCodec>, InferTTo<TCodec>>;\n    const fetchMaybe: Functions['fetchMaybe'] = async (address, config?) => {\n        const maybeAccount = await fetchEncodedAccount(client.rpc, address, config);\n        return decodeAccount(maybeAccount, codec as InferredCodec);\n    };\n    const fetchAllMaybe: Functions['fetchAllMaybe'] = async (addresses, config?) => {\n        const maybeAccounts = await fetchEncodedAccounts(client.rpc, addresses, config);\n        return maybeAccounts.map(maybeAccount => decodeAccount(maybeAccount, codec as InferredCodec));\n    };\n    const fetch: Functions['fetch'] = async (address, config?) => {\n        const maybeAccount = await fetchMaybe(address, config);\n        assertAccountExists(maybeAccount);\n        return maybeAccount;\n    };\n    const fetchAll: Functions['fetchAll'] = async (addresses, config?) => {\n        const maybeAccounts = await fetchAllMaybe(addresses, config);\n        assertAccountsExist(maybeAccounts);\n        return maybeAccounts;\n    };\n\n    const out = { ...codec, fetch, fetchAll, fetchAllMaybe, fetchMaybe };\n    return Object.freeze<typeof out>(out);\n}\n"
  },
  {
    "path": "packages/program-client-core/src/self-plan-and-send-functions.ts",
    "content": "import type { InstructionPlan } from '@solana/instruction-plans';\nimport type { Instruction } from '@solana/instructions';\nimport type { ClientWithTransactionPlanning, ClientWithTransactionSending } from '@solana/plugin-interfaces';\n\ntype PlanTransaction = ClientWithTransactionPlanning['planTransaction'];\ntype PlanTransactions = ClientWithTransactionPlanning['planTransactions'];\ntype SendTransaction = ClientWithTransactionSending['sendTransaction'];\ntype SendTransactions = ClientWithTransactionSending['sendTransactions'];\n\n/**\n * Methods that allow an instruction or instruction plan to plan and send itself.\n *\n * These methods are added to instruction or instruction plan objects via\n * {@link addSelfPlanAndSendFunctions}, enabling a fluent API where you can call\n * `.sendTransaction()` directly on an instruction without passing it to a separate function.\n *\n * @example\n * Sending a transfer instruction directly.\n * ```ts\n * const result = await getTransferInstruction({ source, destination, amount }).sendTransaction();\n * ```\n *\n * @example\n * Planning multiple transactions from an instruction plan.\n * ```ts\n * const plan = await getComplexInstructionPlan(/* ... *\\/).planTransactions();\n * ```\n *\n * @see {@link addSelfPlanAndSendFunctions}\n */\nexport type SelfPlanAndSendFunctions = {\n    /** Plans a single transaction. */\n    planTransaction: (config?: Parameters<PlanTransaction>[1]) => ReturnType<PlanTransaction>;\n    /** Plans one or more transactions. */\n    planTransactions: (config?: Parameters<PlanTransactions>[1]) => ReturnType<PlanTransactions>;\n    /** Sends a single transaction. */\n    sendTransaction: (config?: Parameters<SendTransaction>[1]) => ReturnType<SendTransaction>;\n    /** Sends one or more transactions. */\n    sendTransactions: (config?: Parameters<SendTransactions>[1]) => ReturnType<SendTransactions>;\n};\n\n/**\n * Adds self-planning and self-sending methods to an instruction or instruction plan.\n *\n * This function augments the provided instruction or instruction plan with methods\n * that allow it to plan and send itself using the provided client. It enables a fluent API\n * where you can call methods like `.sendTransaction()` directly on the instruction.\n *\n * The function supports both synchronous inputs (instructions, instruction plans) and\n * promise-like inputs, making it suitable for use with async instruction builders.\n *\n * @typeParam TItem - The type of the instruction, instruction plan, or a promise resolving to one.\n *\n * @param client - A client that provides transaction planning and sending capabilities.\n * @param input - The instruction, instruction plan, or promise to augment with self-plan/send methods.\n * @returns The input augmented with {@link SelfPlanAndSendFunctions} methods.\n *\n * @example\n * Adding self-plan and send to a transfer instruction.\n * ```ts\n * import { addSelfPlanAndSendFunctions } from '@solana/program-client-core';\n *\n * const transferInstruction = addSelfPlanAndSendFunctions(\n *     client,\n *     getTransferInstruction({ payer, source, destination, amount })\n * );\n *\n * // Now you can send directly from the instruction.\n * const result = await transferInstruction.sendTransaction();\n * ```\n *\n * @example\n * Using with an async instruction builder.\n * ```ts\n * const asyncInstruction = addSelfPlanAndSendFunctions(\n *     client,\n *     fetchAndBuildInstruction(/* ... *\\/)\n * );\n *\n * // The promise is augmented with self-plan/send methods.\n * const result = await asyncInstruction.sendTransaction();\n * ```\n *\n * @see {@link SelfPlanAndSendFunctions}\n */\nexport function addSelfPlanAndSendFunctions<\n    TItem extends Instruction | InstructionPlan | PromiseLike<Instruction> | PromiseLike<InstructionPlan>,\n>(\n    client: ClientWithTransactionPlanning & ClientWithTransactionSending,\n    input: TItem,\n): SelfPlanAndSendFunctions & TItem {\n    if (isPromiseLike(input)) {\n        const newInput = input as SelfPlanAndSendFunctions & TItem;\n        newInput.planTransaction = async config => await client.planTransaction(await input, config);\n        newInput.planTransactions = async config => await client.planTransactions(await input, config);\n        newInput.sendTransaction = async config => await client.sendTransaction(await input, config);\n        newInput.sendTransactions = async config => await client.sendTransactions(await input, config);\n        return newInput;\n    }\n\n    return Object.freeze(<SelfPlanAndSendFunctions & (Instruction | InstructionPlan)>{\n        ...input,\n        planTransaction: config => client.planTransaction(input, config),\n        planTransactions: config => client.planTransactions(input, config),\n        sendTransaction: config => client.sendTransaction(input, config),\n        sendTransactions: config => client.sendTransactions(input, config),\n    }) as unknown as SelfPlanAndSendFunctions & TItem;\n}\n\nfunction isPromiseLike(\n    item: Instruction | InstructionPlan | PromiseLike<Instruction> | PromiseLike<InstructionPlan>,\n): item is PromiseLike<Instruction> | PromiseLike<InstructionPlan> {\n    return (\n        !!item &&\n        (typeof item === 'object' || typeof item === 'function') &&\n        typeof (item as PromiseLike<unknown>).then === 'function'\n    );\n}\n"
  },
  {
    "path": "packages/program-client-core/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/program-client-core/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2019.Array\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/program-client-core\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/program-client-core/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/programs/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/programs/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/programs/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/programs/CHANGELOG.md",
    "content": "# @solana/programs\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/addresses@6.8.0\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/addresses@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/addresses@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/addresses@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.1\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.0\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/addresses@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n    - @solana/addresses@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/addresses@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/addresses@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/addresses@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f)]:\n    - @solana/errors@3.0.0\n    - @solana/addresses@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/addresses@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/addresses@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/addresses@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2491](https://github.com/solana-labs/solana-web3.js/pull/2491) [`2040f96`](https://github.com/solana-labs/solana-web3.js/commit/2040f96cc22e4195749577d265cd6a76d8a08b87) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove program types and `resolveTransactionError` helper\n\n- [#2490](https://github.com/solana-labs/solana-web3.js/pull/2490) [`1672346`](https://github.com/solana-labs/solana-web3.js/commit/1672346246fe9444b018d726ab7bfcd4bb092ec2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `isProgramError` helper function to `@solana/programs`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#2968](https://github.com/solana-labs/solana-web3.js/pull/2968) [`9239e6e`](https://github.com/solana-labs/solana-web3.js/commit/9239e6ec972b4de9f0d15b197fbef1d2871759d9) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Tighten return type of isProgramError\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/addresses@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2968](https://github.com/solana-labs/solana-web3.js/pull/2968) [`9239e6e`](https://github.com/solana-labs/solana-web3.js/commit/9239e6ec972b4de9f0d15b197fbef1d2871759d9) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Tighten return type of isProgramError\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2491](https://github.com/solana-labs/solana-web3.js/pull/2491) [`2040f96`](https://github.com/solana-labs/solana-web3.js/commit/2040f96cc22e4195749577d265cd6a76d8a08b87) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove program types and `resolveTransactionError` helper\n\n- [#2490](https://github.com/solana-labs/solana-web3.js/pull/2490) [`1672346`](https://github.com/solana-labs/solana-web3.js/commit/1672346246fe9444b018d726ab7bfcd4bb092ec2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `isProgramError` helper function to `@solana/programs`\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n"
  },
  {
    "path": "packages/programs/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/programs/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/programs?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/programs?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/programs\n\n# @solana/programs\n\nThis package contains helpers for identifying custom program errors. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Functions\n\n### `isProgramError()`\n\nThis function identifies whether an error -- typically caused by a transaction failure -- is a custom program error from the provided program address. It takes the following parameters:\n\n- The `error` to identify.\n- The `transactionMessage` object that failed to execute. Since the RPC response only provides the index of the failed instruction, the transaction message is required to determine its program address.\n- The `programAddress` of the program from which the error is expected to have originated.\n- Optionally, the expected error `code` of the custom program error. When provided, the function will check that the custom program error code matches the given value.\n\n```ts\ntry {\n    // Send and confirm your transaction.\n} catch (error) {\n    if (isProgramError(error, transactionMessage, myProgramAddress, 42)) {\n        // Handle custom program error 42 from this program.\n    } else if (isProgramError(error, transactionMessage, myProgramAddress)) {\n        // Handle all other custom program errors from this program.\n    } else {\n        throw error;\n    }\n}\n```\n"
  },
  {
    "path": "packages/programs/package.json",
    "content": "{\n    \"name\": \"@solana/programs\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for defining programs and resolving program errors\",\n    \"homepage\": \"https://www.solanakit.com/api#solanaprograms\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/functional\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/programs/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/programs/src/__tests__/program-error-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, SolanaError } from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport { appendTransactionMessageInstruction, createTransactionMessage } from '@solana/transaction-messages';\n\nimport { isProgramError } from '../program-error';\n\ndescribe('isProgramError', () => {\n    it('identifies an error as a custom program error', () => {\n        // Given a transaction message with a single instruction.\n        const programAddress = '1111' as Address;\n        const tx = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction({ programAddress }, tx),\n        );\n\n        // And a custom program error on the instruction.\n        const error = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, {\n            code: 42,\n            index: 0,\n        });\n\n        // Then we expect the error to be identified as a program error.\n        expect(isProgramError(error, tx, programAddress)).toBe(true);\n    });\n\n    it('matches the provided custom program error code', () => {\n        // Given a transaction message with a single instruction.\n        const programAddress = '1111' as Address;\n        const tx = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction({ programAddress }, tx),\n        );\n\n        // And a custom program error with code 42.\n        const error = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, {\n            code: 42,\n            index: 0,\n        });\n\n        // When we specify the custom program error code 42.\n        const result = isProgramError(error, tx, programAddress, 42);\n\n        // Then we expect the result to be true.\n        expect(result).toBe(true);\n    });\n\n    it('returns false if the program address does not match', () => {\n        // Given a transaction message with a program A instruction.\n        const programA = '1111' as Address;\n        const tx = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction({ programAddress: programA }, tx),\n        );\n\n        // And a custom program error on the instruction.\n        const error = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, {\n            code: 42,\n            index: 0,\n        });\n\n        // When we try to identify the error as a program error for program B.\n        const programB = '2222' as Address;\n        const result = isProgramError(error, tx, programB);\n\n        // Then we expect the result to be false.\n        expect(result).toBe(false);\n    });\n\n    it('returns false if the instruction is missing', () => {\n        // Given a transaction message with a single instruction.\n        const programAddress = '1111' as Address;\n        const tx = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction({ programAddress }, tx),\n        );\n\n        // And a custom program error pointing to a missing instruction.\n        const error = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, {\n            code: 42,\n            index: 999,\n        });\n\n        // Then we expect the error not to be identified as a program error.\n        expect(isProgramError(error, tx, programAddress)).toBe(false);\n    });\n\n    it('returns false if the custom program error code does not match', () => {\n        // Given a transaction message with a single instruction.\n        const programAddress = '1111' as Address;\n        const tx = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction({ programAddress }, tx),\n        );\n\n        // And a custom program error on the instruction with code 42.\n        const error = new SolanaError(SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, {\n            code: 42,\n            index: 0,\n        });\n\n        // When we try to identify the error as a program error with code 43.\n        const result = isProgramError(error, tx, programAddress, 43);\n\n        // Then we expect the result to be false.\n        expect(result).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/programs/src/__typetests__/program-error-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, SolanaError } from '@solana/errors';\nimport { createTransactionMessage, TransactionMessage } from '@solana/transaction-messages';\n\nimport { isProgramError } from '../program-error';\n\nconst tx = {} as TransactionMessage;\nconst programAddress = '1111' as Address;\n\n{\n    // [isProgramError]: It accepts a new TransactionMessage as a second argument.\n    const transactionMessage = createTransactionMessage({ version: 0 });\n    isProgramError(null, transactionMessage, programAddress);\n}\n\n{\n    // [isProgramError]: It narrow down the error type.\n    const error = {} as Error;\n    if (isProgramError(error, tx, programAddress)) {\n        error satisfies SolanaError<typeof SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM>;\n    }\n}\n\n{\n    // [isProgramError]: It narrow down the error type and its custom program error code.\n    const error = {} as Error;\n    if (isProgramError(error, tx, programAddress, 42)) {\n        error satisfies SolanaError<typeof SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM> & {\n            readonly context: { readonly code: 42 };\n        };\n        // @ts-expect-error Expected error to have code 42\n        error satisfies SolanaError<typeof SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM> & {\n            readonly context: { readonly code: 43 };\n        };\n    }\n}\n"
  },
  {
    "path": "packages/programs/src/index.ts",
    "content": "/**\n * This package contains helpers for identifying custom program errors. It can be used standalone,\n * but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './program-error';\n"
  },
  {
    "path": "packages/programs/src/program-error.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { isSolanaError, SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM, SolanaError } from '@solana/errors';\n\n/**\n * Identifies whether an error -- typically caused by a transaction failure -- is a custom program\n * error from the provided program address.\n *\n * @param transactionMessage The transaction message that failed to execute. Since the RPC response\n * only provides the index of the failed instruction, the transaction message is required to\n * determine its program address\n * @param programAddress The address of the program from which the error is expected to have\n * originated\n * @param code The expected error code of the custom program error. When provided, the function will\n * check that the custom program error code matches the given value.\n *\n * @example\n * ```ts\n * try {\n *     // Send and confirm your transaction.\n * } catch (error) {\n *     if (isProgramError(error, transactionMessage, myProgramAddress, 42)) {\n *         // Handle custom program error 42 from this program.\n *     } else if (isProgramError(error, transactionMessage, myProgramAddress)) {\n *         // Handle all other custom program errors from this program.\n *     } else {\n *         throw error;\n *     }\n * }\n * ```\n */\nexport function isProgramError<TProgramErrorCode extends number>(\n    error: unknown,\n    transactionMessage: { instructions: Record<number, { programAddress: Address }> },\n    programAddress: Address,\n    code?: TProgramErrorCode,\n): error is Readonly<{ context: Readonly<{ code: TProgramErrorCode }> }> &\n    SolanaError<typeof SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM> {\n    if (!isSolanaError(error, SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM)) {\n        return false;\n    }\n    const instructionProgramAddress = transactionMessage.instructions[error.context.index]?.programAddress;\n    if (!instructionProgramAddress || instructionProgramAddress !== programAddress) {\n        return false;\n    }\n    return typeof code === 'undefined' || error.context.code === code;\n}\n"
  },
  {
    "path": "packages/programs/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/programs/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/instructions\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/programs/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/promises/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/promises/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/promises/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/promises/CHANGELOG.md",
    "content": "# @solana/promises\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1549](https://github.com/anza-xyz/kit/pull/1549) [`8d73de5`](https://github.com/anza-xyz/kit/commit/8d73de5241d709946431f2fdda74f2a0df5e9529) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Added `isAbortError(err)` — returns `true` if `err` is an `Error` whose `name` is `'AbortError'`. Use it to distinguish abort rejections from other failures without having to `instanceof`-check every platform-specific error class.\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n## 6.6.0\n\n## 6.5.0\n\n## 6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n## 6.1.0\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n## 5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n## 5.3.0\n\n## 5.2.0\n\n## 5.1.0\n\n## 5.0.0\n\n## 4.0.0\n\n## 3.0.0\n\n## 2.3.0\n\n## 2.2.1\n\n## 2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n## 2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3071](https://github.com/solana-labs/solana-web3.js/pull/3071) [`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a helper that you can use to race two or more promises without having to worry about them leaking memory\n\n- [#3070](https://github.com/solana-labs/solana-web3.js/pull/3070) [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a package for dealing with JavaScript Promises, and copied the implementation of `getAbortablePromise` into it\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- [#3071](https://github.com/solana-labs/solana-web3.js/pull/3071) [`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a helper that you can use to race two or more promises without having to worry about them leaking memory\n\n- [#3070](https://github.com/solana-labs/solana-web3.js/pull/3070) [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d) Thanks [@steveluscher](https://github.com/steveluscher)! - Created a package for dealing with JavaScript Promises, and copied the implementation of `getAbortablePromise` into it\n"
  },
  {
    "path": "packages/promises/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/promises/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/promises?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/promises?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/promises\n\n# @solana/promises\n\nThis package contains helpers for using JavaScript promises.\n\n## Functions\n\n### `getAbortablePromise(promise, abortSignal?)`\n\nReturns a new promise that will reject if the abort signal fires before the original promise settles. Resolves or rejects with the value of the original promise otherwise.\n\n```ts\nconst result = await getAbortablePromise(\n    // Resolves or rejects when `fetch` settles.\n    fetch('https://example.com/json').then(r => r.json()),\n    // ...unless it takes longer than 5 seconds, after which the `AbortSignal` is triggered.\n    AbortSignal.timeout(5000),\n);\n```\n\n### `isAbortError(err)`\n\nReturns `true` if `err` is an `Error` whose `name` is `'AbortError'`. Use this to distinguish abort rejections from other failures without having to `instanceof`-check every platform-specific error class.\n\n```ts\ntry {\n    await getAbortablePromise(doWork(), signal);\n} catch (e) {\n    if (isAbortError(e)) {\n        // The operation was aborted; don't surface as an error.\n        return;\n    }\n    throw e;\n}\n```\n\n### `safeRace(...promises)`\n\nAn implementation of `Promise.race` that causes all of the losing promises to settle. This allows them to be released and garbage collected, preventing memory leaks.\n\nRead more here: https://github.com/nodejs/node/issues/17469\n"
  },
  {
    "path": "packages/promises/package.json",
    "content": "{\n    \"name\": \"@solana/promises\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for using JavaScript promises\",\n    \"homepage\": \"https://www.solanakit.com/api#solanapromises\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/promises/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/promises/src/__tests__/abortable-test.browser.ts",
    "content": "import { isAbortError } from '../abortable';\n\ndescribe('isAbortError()', () => {\n    it('returns `true` for a `DOMException` whose `name` is `AbortError`', () => {\n        expect(isAbortError(new DOMException('The operation was aborted.', 'AbortError'))).toBe(true);\n    });\n    it('returns `true` for the default `reason` of an `AbortController` aborted without an argument', () => {\n        const controller = new AbortController();\n        controller.abort();\n        expect(isAbortError(controller.signal.reason)).toBe(true);\n    });\n});\n"
  },
  {
    "path": "packages/promises/src/__tests__/abortable-test.ts",
    "content": "import { getAbortablePromise, isAbortError } from '../abortable';\n\ndescribe('getAbortablePromise()', () => {\n    let promise: Promise<unknown>;\n    let resolve: (value: unknown) => void;\n    let reject: (reason?: unknown) => void;\n    beforeEach(() => {\n        promise = new Promise<unknown>((res, rej) => {\n            resolve = res;\n            reject = rej;\n        });\n    });\n    it('returns the original promise when called with no `AbortSignal`', () => {\n        expect(getAbortablePromise(promise)).toBe(promise);\n    });\n    it('rejects with the `reason` when passed an already-aborted signal with a pending promise', async () => {\n        expect.assertions(1);\n        const signal = AbortSignal.abort('o no');\n        await expect(getAbortablePromise(promise, signal)).rejects.toBe('o no');\n    });\n    it('rejects with the `reason` when passed an already-aborted signal and an already-resolved promise', async () => {\n        expect.assertions(1);\n        const signal = AbortSignal.abort('o no');\n        resolve(123);\n        await expect(getAbortablePromise(promise, signal)).rejects.toBe('o no');\n    });\n    it('rejects with the `reason` when passed an already-aborted signal and an already-rejected promise', async () => {\n        expect.assertions(1);\n        const signal = AbortSignal.abort('o no');\n        reject('mais non');\n        await expect(getAbortablePromise(promise, signal)).rejects.toBe('o no');\n    });\n    it('rejects with the `reason` when the signal aborts before the promise settles', async () => {\n        expect.assertions(2);\n        const controller = new AbortController();\n        const abortablePromise = getAbortablePromise(promise, controller.signal);\n        await expect(Promise.race([Promise.resolve('pending'), abortablePromise])).resolves.toBe('pending');\n        controller.abort('o no');\n        await expect(abortablePromise).rejects.toBe('o no');\n    });\n    it('rejects with the promise rejection when passed an already-rejected promise and a not-yet-aborted signal', async () => {\n        expect.assertions(1);\n        const signal = new AbortController().signal;\n        reject('mais non');\n        await expect(getAbortablePromise(promise, signal)).rejects.toBe('mais non');\n    });\n    it('rejects with the promise rejection when the promise rejects before the signal aborts', async () => {\n        expect.assertions(2);\n        const signal = new AbortController().signal;\n        const abortablePromise = getAbortablePromise(promise, signal);\n        await expect(Promise.race([Promise.resolve('pending'), abortablePromise])).resolves.toBe('pending');\n        reject('mais non');\n        await expect(abortablePromise).rejects.toBe('mais non');\n    });\n    it('resolves with the promise value when passed an already-resolved promise and a not-yet-aborted signal', async () => {\n        expect.assertions(1);\n        const signal = new AbortController().signal;\n        resolve(123);\n        await expect(getAbortablePromise(promise, signal)).resolves.toBe(123);\n    });\n    it('resolves with the promise value when the promise resolves before the signal aborts', async () => {\n        expect.assertions(2);\n        const signal = new AbortController().signal;\n        const abortablePromise = getAbortablePromise(promise, signal);\n        await expect(Promise.race([Promise.resolve('pending'), abortablePromise])).resolves.toBe('pending');\n        resolve(123);\n        await expect(abortablePromise).resolves.toBe(123);\n    });\n    it('pends when neither the promise has resolved nor the signal aborted', async () => {\n        expect.assertions(1);\n        const signal = new AbortController().signal;\n        await expect(Promise.race([Promise.resolve('pending'), getAbortablePromise(promise, signal)])).resolves.toBe(\n            'pending',\n        );\n    });\n});\n\ndescribe('isAbortError()', () => {\n    it('returns `true` for an `Error` whose `name` is `AbortError`', () => {\n        const err = new Error('aborted');\n        err.name = 'AbortError';\n        expect(isAbortError(err)).toBe(true);\n    });\n    it('returns `true` for a subclass of `Error` whose `name` is `AbortError`', () => {\n        class CustomError extends Error {\n            override name = 'AbortError';\n        }\n        expect(isAbortError(new CustomError())).toBe(true);\n    });\n    it('returns `true` for the rejection reason of an aborted fetch-style promise', async () => {\n        expect.assertions(1);\n        const controller = new AbortController();\n        const promise = getAbortablePromise(new Promise(() => {}), controller.signal);\n        controller.abort(Object.assign(new Error('The operation was aborted.'), { name: 'AbortError' }));\n        await expect(promise.catch(e => isAbortError(e))).resolves.toBe(true);\n    });\n    it('returns `false` for a regular `Error`', () => {\n        expect(isAbortError(new Error('nope'))).toBe(false);\n    });\n    it('returns `false` for a `TypeError`', () => {\n        expect(isAbortError(new TypeError('nope'))).toBe(false);\n    });\n    it('returns `false` for a non-`Error` object whose `name` is `AbortError`', () => {\n        expect(isAbortError({ name: 'AbortError' })).toBe(false);\n    });\n    it('returns `false` for `undefined`', () => {\n        expect(isAbortError(undefined)).toBe(false);\n    });\n    it('returns `false` for `null`', () => {\n        expect(isAbortError(null)).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/promises/src/__tests__/race-test.ts",
    "content": "/**\n * Forked from https://github.com/digitalloggers/race-as-promised/tree/master\n *\n * Authored by Brian Kim:\n * https://github.com/nodejs/node/issues/17469#issuecomment-685216777\n *\n * Adapted to module structure.\n *\n * Adjusted to run for a finite time and perform explicit leak checks.\n */\n\nimport { safeRace } from '../race';\n\nasync function randomString(length: number) {\n    await new Promise(resolve => setTimeout(resolve, 1));\n    let result = '';\n    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n    for (let i = 0; i < length; i++) {\n        result += characters.charAt(Math.floor(Math.random() * characters.length));\n    }\n    return result;\n}\n\nconst iterationCount = 1000;\nconst stringSize = 10000;\n\nfunction usageMeaningfullyIncreasing(usages: readonly NodeJS.MemoryUsage[], key: 'heapUsed' | 'rss') {\n    return (\n        usages[2][key] - usages[0][key] > 2 * iterationCount * stringSize &&\n        usages[2][key] - usages[1][key] > (usages[1][key] - usages[0][key]) / 2\n    );\n}\n\nfunction detectLeak(usages: readonly NodeJS.MemoryUsage[]) {\n    return usageMeaningfullyIncreasing(usages, 'rss') || usageMeaningfullyIncreasing(usages, 'heapUsed');\n}\n\nasync function run(race: typeof Promise.race) {\n    const pending = new Promise(() => {});\n    for (let i = 0; i < iterationCount; i++) {\n        // We use random strings to prevent string interning.\n        // Pass a different length string to see effects on memory usage.\n        await race([pending, randomString(stringSize)]);\n    }\n}\n\ndescribe('Promise.race', () => {\n    let nativeRace: typeof Promise.race;\n    beforeEach(() => {\n        nativeRace = Promise.race.bind(Promise);\n    });\n    // FIXME(#3081): This test times out in CI\n    // eslint-disable-next-line jest/no-disabled-tests\n    it.skip('leaks memory', async () => {\n        expect.assertions(1);\n        const usages = [];\n        usages.push(process.memoryUsage());\n        await run(nativeRace);\n        usages.push(process.memoryUsage());\n        await run(nativeRace);\n        usages.push(process.memoryUsage());\n        expect(detectLeak(usages)).toBe(true);\n    }, 60_000 /* timeout */);\n});\n\ndescribe('safeRace', () => {\n    // FIXME(#3081): This test times out in CI\n    // eslint-disable-next-line jest/no-disabled-tests\n    it.skip('does not leak memory', async () => {\n        expect.assertions(1);\n        const usages = [];\n        usages.push(process.memoryUsage());\n        await run(safeRace);\n        usages.push(process.memoryUsage());\n        await run(safeRace);\n        usages.push(process.memoryUsage());\n        expect(detectLeak(usages)).toBe(false);\n    }, 60_000 /* timeout */);\n});\n"
  },
  {
    "path": "packages/promises/src/abortable.ts",
    "content": "import { safeRace } from './race';\n\n/**\n * Returns `true` if the given value is an `Error` whose `name` is `'AbortError'`.\n *\n * When an {@link AbortSignal} fires without a custom `reason`, or when APIs like `fetch` are\n * aborted, they reject with a `DOMException` (or similar `Error` subclass) whose `name` is\n * `'AbortError'`. This helper lets callers distinguish abort rejections from other failures\n * without having to `instanceof`-check every platform-specific error class.\n *\n * @example\n * ```ts\n * try {\n *     await getAbortablePromise(doWork(), signal);\n * } catch (e) {\n *     if (isAbortError(e)) {\n *         // The operation was aborted; don't surface as an error.\n *         return;\n *     }\n *     throw e;\n * }\n * ```\n *\n * @see {@link getAbortablePromise}\n */\nexport function isAbortError(err: unknown): err is Error {\n    return err instanceof Error && err.name === 'AbortError';\n}\n\n/**\n * Returns a new promise that will reject if the abort signal fires before the original promise\n * settles. Resolves or rejects with the value of the original promise otherwise.\n *\n * @example\n * ```ts\n * const result = await getAbortablePromise(\n *     // Resolves or rejects when `fetch` settles.\n *     fetch('https://example.com/json').then(r => r.json()),\n *     // ...unless it takes longer than 5 seconds, after which the `AbortSignal` is triggered.\n *     AbortSignal.timeout(5000),\n * );\n * ```\n */\nexport function getAbortablePromise<T>(promise: Promise<T>, abortSignal?: AbortSignal): Promise<T> {\n    if (!abortSignal) {\n        return promise;\n    } else {\n        return safeRace([\n            // This promise only ever rejects if the signal is aborted. Otherwise it idles forever.\n            // It's important that this come before the input promise; in the event of an abort, we\n            // want to throw even if the input promise's result is ready\n            new Promise<never>((_, reject) => {\n                if (abortSignal.aborted) {\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n                    reject(abortSignal.reason);\n                } else {\n                    abortSignal.addEventListener('abort', function () {\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n                        reject(this.reason);\n                    });\n                }\n            }),\n            promise,\n        ]);\n    }\n}\n"
  },
  {
    "path": "packages/promises/src/index.ts",
    "content": "/**\n * This package contains helpers for using JavaScript promises.\n *\n * @packageDocumentation\n */\nexport * from './abortable';\nexport * from './race';\n"
  },
  {
    "path": "packages/promises/src/race.ts",
    "content": "/**\n * Forked from https://github.com/digitalloggers/race-as-promised/tree/master\n *\n * Authored by Brian Kim:\n * https://github.com/nodejs/node/issues/17469#issuecomment-685216777\n *\n * Adapted to module structure.\n *\n * This is free and unencumbered software released into the public domain.\n *\n * Anyone is free to copy, modify, publish, use, compile, sell, or\n * distribute this software, either in source code form or as a compiled\n * binary, for any purpose, commercial or non-commercial, and by any\n * means.\n *\n * In jurisdictions that recognize copyright laws, the author or authors\n * of this software dedicate any and all copyright interest in the\n * software to the public domain. We make this dedication for the benefit\n * of the public at large and to the detriment of our heirs and\n * successors. We intend this dedication to be an overt act of\n * relinquishment in perpetuity of all present and future rights to this\n * software under copyright law.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n *\n * For more information, please refer to <http://unlicense.org/>\n */\n\ntype Deferred = Readonly<{\n    reject: (reason?: unknown) => void;\n    resolve: (value: unknown) => void;\n}>;\n\nfunction isObject(value: unknown): value is object {\n    return value !== null && (typeof value === 'object' || typeof value === 'function');\n}\n\nfunction addRaceContender(contender: object) {\n    const deferreds = new Set<Deferred>();\n    const record = { deferreds, settled: false };\n\n    // This call to `then` happens once for the lifetime of the value.\n    Promise.resolve(contender).then(\n        value => {\n            for (const { resolve } of deferreds) {\n                resolve(value);\n            }\n\n            deferreds.clear();\n            record.settled = true;\n        },\n        err => {\n            for (const { reject } of deferreds) {\n                reject(err);\n            }\n\n            deferreds.clear();\n            record.settled = true;\n        },\n    );\n    return record;\n}\n\n// Keys are the values passed to race, values are a record of data containing a\n// set of deferreds and whether the value has settled.\nconst wm = new WeakMap<object, { deferreds: Set<Deferred>; settled: boolean }>();\n/**\n * An implementation of [`Promise.race`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race)\n * that causes all of the losing promises to settle. This allows them to be released and garbage\n * collected, preventing memory leaks.\n *\n * Read more here: https://github.com/nodejs/node/issues/17469\n */\nexport async function safeRace<T extends readonly unknown[] | []>(contenders: T): Promise<Awaited<T[number]>> {\n    let deferred: Deferred;\n    const result = new Promise((resolve, reject) => {\n        deferred = { reject, resolve };\n        for (const contender of contenders) {\n            if (!isObject(contender)) {\n                // If the contender is a primitive, attempting to use it as a key in the\n                // weakmap would throw an error. Luckily, it is safe to call\n                // `Promise.resolve(contender).then` on a primitive value multiple times\n                // because the promise fulfills immediately.\n                Promise.resolve(contender).then(resolve, reject);\n                continue;\n            }\n\n            let record = wm.get(contender);\n            if (record === undefined) {\n                record = addRaceContender(contender);\n                record.deferreds.add(deferred);\n                wm.set(contender, record);\n            } else if (record.settled) {\n                // If the value has settled, it is safe to call\n                // `Promise.resolve(contender).then` on it.\n                Promise.resolve(contender).then(resolve, reject);\n            } else {\n                record.deferreds.add(deferred);\n            }\n        }\n    });\n\n    // The finally callback executes when any value settles, preventing any of\n    // the unresolved values from retaining a reference to the resolved value.\n    return await (result.finally(() => {\n        for (const contender of contenders) {\n            if (isObject(contender)) {\n                const record = wm.get(contender)!;\n                record.deferreds.delete(deferred);\n            }\n        }\n    }) as Promise<Awaited<T[number]>>);\n}\n"
  },
  {
    "path": "packages/promises/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/promises/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\"]\n    },\n    \"display\": \"@solana/promises\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/promises/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/react/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/react/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/react/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/react/CHANGELOG.md",
    "content": "# @solana/react\n\n## 6.9.0\n\n### Patch Changes\n\n- Updated dependencies [[`8d73de5`](https://github.com/anza-xyz/kit/commit/8d73de5241d709946431f2fdda74f2a0df5e9529), [`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/promises@6.9.0\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/signers@6.9.0\n    - @solana/transaction-messages@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/signers@6.8.0\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/promises@6.8.0\n    - @solana/transaction-messages@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/promises@6.7.0\n    - @solana/signers@6.7.0\n    - @solana/transaction-messages@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad), [`0fa54a4`](https://github.com/anza-xyz/kit/commit/0fa54a469937db3989f42afc4248882736f719f5)]:\n    - @solana/transactions@6.6.0\n    - @solana/errors@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/signers@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/promises@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`9e05736`](https://github.com/anza-xyz/kit/commit/9e057365a1a4e350f8a0ccc233b262e09b0134fa)]:\n    - @solana/signers@6.5.0\n    - @solana/addresses@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/promises@6.5.0\n    - @solana/transaction-messages@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888)]:\n    - @solana/transaction-messages@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/signers@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/promises@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/promises@6.3.1\n    - @solana/signers@6.3.1\n    - @solana/transaction-messages@6.3.1\n    - @solana/transactions@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/signers@6.3.0\n    - @solana/transaction-messages@6.3.0\n    - @solana/transactions@6.3.0\n    - @solana/promises@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/signers@6.2.0\n    - @solana/transaction-messages@6.2.0\n    - @solana/transactions@6.2.0\n    - @solana/promises@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/transaction-messages@6.1.0\n    - @solana/transactions@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/signers@6.1.0\n    - @solana/promises@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies [[`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492), [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462)]:\n    - @solana/transaction-messages@6.0.1\n    - @solana/signers@6.0.1\n    - @solana/transactions@6.0.1\n    - @solana/addresses@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/promises@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926), [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a), [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db)]:\n    - @solana/transaction-messages@6.0.0\n    - @solana/signers@6.0.0\n    - @solana/transactions@6.0.0\n    - @solana/addresses@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/promises@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/signers@5.5.1\n    - @solana/transaction-messages@5.5.1\n    - @solana/transactions@5.5.1\n    - @solana/promises@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- [#1210](https://github.com/anza-xyz/kit/pull/1210) [`56433e9`](https://github.com/anza-xyz/kit/commit/56433e9c87ddb3f6aeb7bb4dd029db86785341cb) Thanks [@rajgoesout](https://github.com/rajgoesout)! - Return immediately when passing empty array of transactions to `useSignTransactions` and `useSignAndSendTransactions`\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/signers@5.5.0\n    - @solana/transaction-messages@5.5.0\n    - @solana/transactions@5.5.0\n    - @solana/promises@5.5.0\n\n## 5.4.0\n\n### Minor Changes\n\n- [#1154](https://github.com/anza-xyz/kit/pull/1154) [`fec04ae`](https://github.com/anza-xyz/kit/commit/fec04ae9cd0939c556b832e20440d27c4574561a) Thanks [@ningthoujamSwamikumar](https://github.com/ningthoujamSwamikumar)! - Add a context provider `<SelectedWalletAccountContext>` and `useSelectedWalletAccount` to persist a selected wallet account\n\n- [#1105](https://github.com/anza-xyz/kit/pull/1105) [`a301da8`](https://github.com/anza-xyz/kit/commit/a301da85ec21901fd1836d784ba46cc1d8ddddc2) Thanks [@rajgoesout](https://github.com/rajgoesout)! - Add `useSignTransactions` and `useSignAndSendTransactions` hooks that you can use to send multiple transactions to a connected wallet.\n\n### Patch Changes\n\n- [#1199](https://github.com/anza-xyz/kit/pull/1199) [`9bde4d7`](https://github.com/anza-xyz/kit/commit/9bde4d74f8d338495112ff00519177857b78884f) Thanks [@rajgoesout](https://github.com/rajgoesout)! - Correct featureName in `signTransaction` error\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/transaction-messages@5.4.0\n    - @solana/transactions@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/promises@5.4.0\n    - @solana/signers@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/promises@5.3.0\n    - @solana/signers@5.3.0\n    - @solana/transaction-messages@5.3.0\n    - @solana/transactions@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/errors@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/transaction-messages@5.2.0\n    - @solana/transactions@5.2.0\n    - @solana/signers@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/promises@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#1040](https://github.com/anza-xyz/kit/pull/1040) [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c) Thanks [@OrmEmbaar](https://github.com/OrmEmbaar)! - Add a function called bytesEqual to codecs-core that you can use to compare two byte arrays for equality.\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951), [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd)]:\n    - @solana/errors@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/transactions@5.1.0\n    - @solana/transaction-messages@5.1.0\n    - @solana/signers@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/promises@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/signers@5.0.0\n    - @solana/transaction-messages@5.0.0\n    - @solana/transactions@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/keys@5.0.0\n    - @solana/promises@5.0.0\n\n## 4.0.0\n\n### Major Changes\n\n- [#927](https://github.com/anza-xyz/kit/pull/927) [`c035ab8`](https://github.com/anza-xyz/kit/commit/c035ab8a488486d160ca0361408493115cd09383) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the signer API to return Transaction & TransactionWithLifetime\n\n    The `modifyAndSignTransactions` function for a `TransactionModifyingSigner` must now return a `Transaction & TransactionWithLifetime & TransactionWithinSizeLimit`. Previously it technically needed to return a type derived from the input `TransactionMessage`, but this wasn't checked.\n\n    If you have written a `TransactionModifyingSigner` then you should review the changes to `useWalletAccountTransactionSigner` in the React package for guidance. You may need to use the new `getTransactionLifetimeConstraintFromCompiledTransactionMessage` function to obtain a lifetime for the transaction being returned.\n\n    If you are using a `TransactionModifyingSigner` such as `useWalletAccountTransactionSigner`, then you will now receive a transaction with `TransactionWithLifetime` when you would previously have received a type with a lifetime matching the input transaction message. This was never guaranteed to match at runtime, but we incorrectly returned a stronger type than can be guaranteed. You may need to use the new `isTransactionWithBlockhashLifetime` or `isTransactionWithDurableNonceLifetime` functions to check the lifetime type of the returned transaction. For example, if you want to pass it to a function returned by `sendAndConfirmTransactionFactory` then you must use `isTransactionWithBlockhashLifetime` or `assertIsTransactionWithBlockhashLifetime` to check its lifetime first.\n\n### Patch Changes\n\n- [#919](https://github.com/anza-xyz/kit/pull/919) [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update useWalletAccountTransactionSigner to return a LifetimeConstraint for the updated transaction\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b), [`c035ab8`](https://github.com/anza-xyz/kit/commit/c035ab8a488486d160ca0361408493115cd09383), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df), [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013)]:\n    - @solana/transactions@4.0.0\n    - @solana/errors@4.0.0\n    - @solana/keys@4.0.0\n    - @solana/transaction-messages@4.0.0\n    - @solana/signers@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/promises@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`93ae6f9`](https://github.com/anza-xyz/kit/commit/93ae6f96859019b6c7ea9a596ffb9b1be7a35e64), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845), [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485)]:\n    - @solana/signers@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/transactions@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/keys@3.0.0\n    - @solana/promises@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a), [`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`bbcb913`](https://github.com/anza-xyz/kit/commit/bbcb913839d33abc746f38d6e65e7bfd30cd2ac6), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/transactions@2.3.0\n    - @solana/signers@2.3.0\n    - @solana/errors@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/keys@2.3.0\n    - @solana/promises@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/keys@2.2.1\n    - @solana/promises@2.2.1\n    - @solana/signers@2.2.1\n    - @solana/transactions@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/addresses@2.2.0\n    - @solana/keys@2.2.0\n    - @solana/signers@2.2.0\n    - @solana/transactions@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/promises@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/transactions@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/promises@2.1.1\n    - @solana/signers@2.1.1\n    - @solana/errors@2.1.1\n    - @solana/keys@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`a1e45a1`](https://github.com/anza-xyz/kit/commit/a1e45a1d91ba1ac530eea0986b2ffeafb9713aec), [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/signers@2.1.0\n    - @solana/addresses@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/keys@2.1.0\n    - @solana/transactions@2.1.0\n    - @solana/promises@2.1.0\n\n## 2.0.0\n\n### Minor Changes\n\n- [#2928](https://github.com/solana-labs/solana-web3.js/pull/2928) [`bac3747`](https://github.com/solana-labs/solana-web3.js/commit/bac37479dcfad3da86ccd01da5095759f449eb3d) Thanks [@steveluscher](https://github.com/steveluscher)! - Added a `useSignIn` hook that, given a `UiWallet` or `UiWalletAccount`, returns a function that you can call to trigger a wallet's [&lsquo;Sign In With Solana&rsquo;](https://phantom.app/learn/developers/sign-in-with-solana) feature.\n\n    #### Example\n\n    ```tsx\n    import { useSignIn } from '@solana/react';\n\n    function SignInButton({ wallet }) {\n        const csrfToken = useCsrfToken();\n        const signIn = useSignIn(wallet);\n        return (\n            <button\n                onClick={async () => {\n                    try {\n                        const { account, signedMessage, signature } = await signIn({\n                            requestId: csrfToken,\n                        });\n                        // Authenticate the user, typically on the server, by verifying that\n                        // `signedMessage` was signed by the person who holds the private key for\n                        // `account.publicKey`.\n                        //\n                        // Authorize the user, also on the server, by decoding `signedMessage` as the\n                        // text of a Sign In With Solana message, verifying that it was not modified\n                        // from the values your application expects, and that its content is sufficient\n                        // to grant them access.\n                        window.alert(`You are now signed in with the address ${account.address}`);\n                    } catch (e) {\n                        console.error('Failed to sign in', e);\n                    }\n                }}\n            >\n                Sign In\n            </button>\n        );\n    }\n    ```\n\n### Patch Changes\n\n- [#2795](https://github.com/solana-labs/solana-web3.js/pull/2795) [`ce876d9`](https://github.com/solana-labs/solana-web3.js/commit/ce876d99f04d539292abd810acd77a319c52f50d) Thanks [@steveluscher](https://github.com/steveluscher)! - Added React hooks to which you can pass a Wallet Standard `UiWalletAccount` and obtain a `MessageModifyingSigner`, `TransactionModifyingSigner`, or `TransactionSendingSigner` for use in constructing, signing, and sending Solana transactions and messages\n\n- [#2772](https://github.com/solana-labs/solana-web3.js/pull/2772) [`8fe4551`](https://github.com/solana-labs/solana-web3.js/commit/8fe4551217a3ad8bfdcd1609ac7b23e8fd044c72) Thanks [@steveluscher](https://github.com/steveluscher)! - Added a series of React hooks to which you can pass a Wallet Standard `UiWalletAccount` to extract its `signMessage`, `signTransaction`, and `signAndSendTransaction` features\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`1ad523d`](https://github.com/solana-labs/solana-web3.js/commit/1ad523dc5792d9152a66e9dc2b83294e3eba4db0), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`cec9048`](https://github.com/solana-labs/solana-web3.js/commit/cec9048b2f83535df7e499db5488c336981dfb5a), [`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`4decebb`](https://github.com/solana-labs/solana-web3.js/commit/4decebb9b619972f49c740323b59cf470696e105), [`d4965ec`](https://github.com/solana-labs/solana-web3.js/commit/d4965ece9abaf81e3006442db15f3f77d89a622c), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`22a34aa`](https://github.com/solana-labs/solana-web3.js/commit/22a34aa08d1be7e9b43ccfea94a99eaa2694e491), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/transactions@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/keys@2.0.0\n    - @solana/signers@2.0.0\n    - @solana/promises@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/keys@2.0.0-rc.4\n    - @solana/signers@2.0.0-rc.4\n    - @solana/transactions@2.0.0-rc.4\n    - @solana/promises@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/keys@2.0.0-rc.3\n    - @solana/promises@2.0.0-rc.3\n    - @solana/signers@2.0.0-rc.3\n    - @solana/transactions@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`4decebb`](https://github.com/solana-labs/solana-web3.js/commit/4decebb9b619972f49c740323b59cf470696e105), [`d4965ec`](https://github.com/solana-labs/solana-web3.js/commit/d4965ece9abaf81e3006442db15f3f77d89a622c), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/transactions@2.0.0-rc.2\n    - @solana/promises@2.0.0-rc.2\n    - @solana/signers@2.0.0-rc.2\n    - @solana/keys@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies [[`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`1ad523d`](https://github.com/solana-labs/solana-web3.js/commit/1ad523dc5792d9152a66e9dc2b83294e3eba4db0), [`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8), [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302)]:\n    - @solana/keys@2.0.0-rc.1\n    - @solana/signers@2.0.0-rc.1\n    - @solana/promises@2.0.0-rc.1\n    - @solana/transactions@2.0.0-rc.1\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Minor Changes\n\n- [#2928](https://github.com/solana-labs/solana-web3.js/pull/2928) [`bac3747`](https://github.com/solana-labs/solana-web3.js/commit/bac37479dcfad3da86ccd01da5095759f449eb3d) Thanks [@steveluscher](https://github.com/steveluscher)! - Added a `useSignIn` hook that, given a `UiWallet` or `UiWalletAccount`, returns a function that you can call to trigger a wallet's [&lsquo;Sign In With Solana&rsquo;](https://phantom.app/learn/developers/sign-in-with-solana) feature.\n\n    #### Example\n\n    ```tsx\n    import { useSignIn } from '@solana/react';\n\n    function SignInButton({ wallet }) {\n        const csrfToken = useCsrfToken();\n        const signIn = useSignIn(wallet);\n        return (\n            <button\n                onClick={async () => {\n                    try {\n                        const { account, signedMessage, signature } = await signIn({\n                            requestId: csrfToken,\n                        });\n                        // Authenticate the user, typically on the server, by verifying that\n                        // `signedMessage` was signed by the person who holds the private key for\n                        // `account.publicKey`.\n                        //\n                        // Authorize the user, also on the server, by decoding `signedMessage` as the\n                        // text of a Sign In With Solana message, verifying that it was not modified\n                        // from the values your application expects, and that its content is sufficient\n                        // to grant them access.\n                        window.alert(`You are now signed in with the address ${account.address}`);\n                    } catch (e) {\n                        console.error('Failed to sign in', e);\n                    }\n                }}\n            >\n                Sign In\n            </button>\n        );\n    }\n    ```\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/signers@2.0.0-rc.0\n    - @solana/transactions@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/keys@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2795](https://github.com/solana-labs/solana-web3.js/pull/2795) [`ce876d9`](https://github.com/solana-labs/solana-web3.js/commit/ce876d99f04d539292abd810acd77a319c52f50d) Thanks [@steveluscher](https://github.com/steveluscher)! - Added React hooks to which you can pass a Wallet Standard `UiWalletAccount` and obtain a `MessageModifyingSigner`, `TransactionModifyingSigner`, or `TransactionSendingSigner` for use in constructing, signing, and sending Solana transactions and messages\n\n- [#2772](https://github.com/solana-labs/solana-web3.js/pull/2772) [`8fe4551`](https://github.com/solana-labs/solana-web3.js/commit/8fe4551217a3ad8bfdcd1609ac7b23e8fd044c72) Thanks [@steveluscher](https://github.com/steveluscher)! - Added a series of React hooks to which you can pass a Wallet Standard `UiWalletAccount` to extract its `signMessage`, `signTransaction`, and `signAndSendTransaction` features\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`cec9048`](https://github.com/solana-labs/solana-web3.js/commit/cec9048b2f83535df7e499db5488c336981dfb5a), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`22a34aa`](https://github.com/solana-labs/solana-web3.js/commit/22a34aa08d1be7e9b43ccfea94a99eaa2694e491)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/signers@2.0.0-preview.4\n    - @solana/keys@2.0.0-preview.4\n    - @solana/transactions@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n"
  },
  {
    "path": "packages/react/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/react/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/react?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/react?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/react\n\n# @solana/react\n\nThis package contains React hooks for building Solana apps.\n\n## Hooks\n\n### `useSignIn(uiWalletAccount, chain)`\n\nGiven a `UiWallet` or `UiWalletAccount` this hook returns a function that you can call to trigger a wallet's [&lsquo;Sign In With Solana&rsquo;](https://phantom.app/learn/developers/sign-in-with-solana) feature.\n\n#### Example\n\n```tsx\nimport { useSignIn } from '@solana/react';\n\nfunction SignInButton({ wallet }) {\n    const csrfToken = useCsrfToken();\n    const signIn = useSignIn(wallet);\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const { account, signedMessage, signature } = await signIn({\n                        requestId: csrfToken,\n                    });\n                    // Authenticate the user, typically on the server, by verifying that\n                    // `signedMessage` was signed by the person who holds the private key for\n                    // `account.publicKey`.\n                    //\n                    // Authorize the user, also on the server, by decoding `signedMessage` as the\n                    // text of a Sign In With Solana message, verifying that it was not modified\n                    // from the values your application expects, and that its content is sufficient\n                    // to grant them access.\n                    window.alert(`You are now signed in with the address ${account.address}`);\n                } catch (e) {\n                    console.error('Failed to sign in', e);\n                }\n            }}\n        >\n            Sign In\n        </button>\n    );\n}\n```\n\n### `useWalletAccountMessageSigner(uiWalletAccount)`\n\nGiven a `UiWalletAccount`, this hook returns an object that conforms to the `MessageModifyingSigner` interface of `@solana/signers`.\n\n#### Example\n\n```tsx\nimport { useWalletAccountMessageSigner } from '@solana/react';\nimport { createSignableMessage } from '@solana/signers';\n\nfunction SignMessageButton({ account, text }) {\n    const messageSigner = useWalletAccountMessageSigner(account);\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const signableMessage = createSignableMessage(text);\n                    const [signedMessage] = await messageSigner.modifyAndSignMessages([signableMessage]);\n                    const messageWasModified = signableMessage.content !== signedMessage.content;\n                    const signatureBytes = signedMessage.signatures[messageSigner.address];\n                    window.alert(\n                        `Signature bytes: ${signatureBytes.toString()}${\n                            messageWasModified ? ' (message was modified)' : ''\n                        }`,\n                    );\n                } catch (e) {\n                    console.error('Failed to sign message', e);\n                }\n            }}\n        >\n            Sign Message: {text}\n        </button>\n    );\n}\n```\n\n> [!NOTE]\n> The type `MessageModifyingSigner` is returned from this hook instead of `MessageSigner` or `MessagePartialSigner`. This is a conservative assumption based on the fact that your application can not control whether or not the wallet will modify the message before signing it.\n\n### `useWalletAccountTransactionSigner(uiWalletAccount, chain)`\n\nGiven a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns an object that conforms to the `TransactionModifyingSigner` interface of `@solana/signers`.\n\n#### Example\n\n```tsx\nimport { useWalletAccountTransactionSigner } from '@solana/react';\n\nfunction SignTransactionButton({ account, transaction }) {\n    const transactionSigner = useWalletAccountTransactionSigner(account, 'solana:devnet');\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const [{ signatures }] = await transactionSigner.modifyAndSignTransactions([transaction]);\n                    const signatureBytes = signatures[transactionSigner.address];\n                    window.alert(`Signature bytes: ${signatureBytes.toString()}`);\n                } catch (e) {\n                    console.error('Failed to sign transaction', e);\n                }\n            }}\n        >\n            Sign Transaction\n        </button>\n    );\n}\n```\n\n> [!NOTE]\n> The type `TransactionModifyingSigner` is returned from this hook instead of `TransactionSigner` or `TransactionPartialSigner`. This is a conservative assumption based on the fact that your application can not control whether or not the wallet will modify the transaction before signing it (eg. to add guard instructions, or a priority fee budget).\n\n### `useWalletAccountTransactionSendingSigner(uiWalletAccount, chain)`\n\nGiven a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns an object that conforms to the `TransactionSendingSigner` interface of `@solana/signers`.\n\n#### Example\n\n```tsx\nimport { useWalletAccountTransactionSendingSigner } from '@solana/react';\nimport {\n    appendTransactionMessageInstruction,\n    createSolanaRpc,\n    getBase58Decoder,\n    pipe,\n    setTransactionMessageFeePayerSigner,\n    setTransactionMessageLifetimeUsingBlockhash,\n    signAndSendTransactionMessageWithSigners,\n} from '@solana/kit';\n\nfunction RecordMemoButton({ account, rpc, text }) {\n    const signer = useWalletAccountTransactionSendingSigner(account, 'solana:devnet');\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const { value: latestBlockhash } = await createSolanaRpc('https://api.devnet.solana.com')\n                        .getLatestBlockhash()\n                        .send();\n                    const message = pipe(\n                        createTransactionMessage({ version: 'legacy' }),\n                        m => setTransactionMessageFeePayerSigner(signer, m),\n                        m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n                        m => appendTransactionMessageInstruction(getAddMemoInstruction({ memo: text }), m),\n                    );\n                    const signatureBytes = await signAndSendTransactionMessageWithSigners(message);\n                    const base58Signature = getBase58Decoder().decode(signature);\n                    window.alert(`View transaction: https://explorer.solana.com/tx/${base58Signature}?cluster=devnet`);\n                } catch (e) {\n                    console.error('Failed to record memo', e);\n                }\n            }}\n        >\n            Record Memo\n        </button>\n    );\n}\n```\n\n### `useSignMessage(uiWalletAccount)`\n\nGiven a `UiWalletAccount`, this hook returns a function you can call to sign a byte array.\n\n#### Arguments\n\nA config object with the following properties:\n\n- `message`: A `Uint8Array` of bytes to sign\n\n#### Returns\n\nAn object with the following properties:\n\n- `signature`: The 64-byte Ed25519 signature as a `Uint8Array`\n- `signedMessage`: The `Uint8Array` of bytes signed by the wallet. These bytes might differ from the input bytes if the wallet modified the message\n\n#### Example\n\n```tsx\nimport { useSignMessage } from '@solana/react';\n\nfunction SignMessageButton({ account, messageBytes }) {\n    const signMessage = useSignMessage(account);\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const { signature } = await signMessage({\n                        message: messageBytes,\n                    });\n                    window.alert(`Signature bytes: ${signature.toString()}`);\n                } catch (e) {\n                    console.error('Failed to sign message', e);\n                }\n            }}\n        >\n            Sign Message\n        </button>\n    );\n}\n```\n\n### `useSignTransaction(uiWalletAccount, chain)`\n\nGiven a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns a function you can call to sign a serialized transaction.\n\n#### Arguments\n\nA config object with the following properties:\n\n- `options`: An object with the following properties:\n    - `minContextSlot`: A slot at which any blockhash/nonce in the transaction is known to exist. This may be used by the signer and/or RPC to determine the validity of the blockhashes/nonces it has observed.\n- `transaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)\n\n#### Returns\n\nAn object with the following properties:\n\n- `signedTransaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)\n\n#### Example\n\n```tsx\nimport { useSignTransaction } from '@solana/react';\n\nfunction SignTransactionButton({ account, transactionBytes }) {\n    const signTransaction = useSignTransaction(account, 'solana:devnet');\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const { signedTransaction } = await signTransaction({\n                        transaction: transactionBytes,\n                    });\n                    window.alert(`Signed transaction bytes: ${signedTransaction.toString()}`);\n                } catch (e) {\n                    console.error('Failed to sign transaction', e);\n                }\n            }}\n        >\n            Sign Transaction\n        </button>\n    );\n}\n```\n\n### `useSignAndSendTransaction(uiWalletAccount, chain)`\n\nGiven a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns a function you can call to sign and send a serialized transaction.\n\n#### Arguments\n\nA config object with the following properties:\n\n- `options`: An object with the following properties:\n    - `minContextSlot`: A slot at which any blockhash/nonce in the transaction is known to exist. This may be used by the signer and/or RPC to determine the validity of the blockhashes/nonces it has observed.\n- `transaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)\n\n#### Returns\n\nThat function returns an object with the following properties:\n\n- `signature`: A `Uint8Array` of bytes representing the signature of the sent transaction.\n\n#### Example\n\n```tsx\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport { useSignAndSendTransaction } from '@solana/react';\n\nfunction SignAndSendTransactionButton({ account, transactionBytes }) {\n    const signAndSendTransaction = useSignAndSendTransaction(account, 'solana:devnet');\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const { signature } = await signAndSendTransaction({\n                        transaction: transactionBytes,\n                    });\n                    const base58TransactionSignature = getBase58Decoder().decode(signature);\n                    window.alert(\n                        `View transaction: https://explorer.solana.com/tx/${base58TransactionSignature}?cluster=devnet`,\n                    );\n                } catch (e) {\n                    console.error('Failed to send transaction', e);\n                }\n            }}\n        >\n            Sign and Send Transaction\n        </button>\n    );\n}\n```\n\n### `useSignTransactions(uiWalletAccount, chain)`\n\nGiven a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns a function you can call to sign one or more serialized transactions in a single request.\n\n#### Arguments\n\nOne or more config objects with the following properties:\n\n- `options`: An object with the following properties:\n    - `minContextSlot`: A slot at which any blockhash/nonce in the transaction is known to exist. This may be used by the signer and/or RPC to determine the validity of the blockhashes/nonces it has observed.\n- `transaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)\n\n#### Returns\n\nAn array of objects with the following properties:\n\n- `signedTransaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)\n\n#### Example\n\n```tsx\nimport { useSignTransactions } from '@solana/react';\n\nfunction SignTransactionsButton({ account, transactionBytes1, transactionBytes2 }) {\n    const signTransactions = useSignTransactions(account, 'solana:devnet');\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const [{ signedTransaction: first }, { signedTransaction: second }] = await signTransactions(\n                        { transaction: transactionBytes1 },\n                        { transaction: transactionBytes2 },\n                    );\n                    window.alert(`Signed transaction bytes: ${first.toString()} and ${second.toString()}`);\n                } catch (e) {\n                    console.error('Failed to sign transactions', e);\n                }\n            }}\n        >\n            Sign Transactions\n        </button>\n    );\n}\n```\n\n### `useSignAndSendTransactions(uiWalletAccount, chain)`\n\nGiven a `UiWalletAccount` and a chain that begins with `solana:`, this hook returns a function you can call to sign and send one or more serialized transactions in a single request.\n\n#### Arguments\n\nOne or more config objects with the following properties:\n\n- `options`: An object with the following properties:\n    - `minContextSlot`: A slot at which any blockhash/nonce in the transaction is known to exist. This may be used by the signer and/or RPC to determine the validity of the blockhashes/nonces it has observed.\n- `transaction`: A `Uint8Array` of bytes that conforms to the [Solana transaction schema](https://solana.com/docs/core/transactions#transaction)\n\n#### Returns\n\nAn array of objects with the following properties:\n\n- `signature`: A `Uint8Array` of bytes representing the signature of each sent transaction.\n\n#### Example\n\n```tsx\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport { useSignAndSendTransactions } from '@solana/react';\n\nfunction SignAndSendTransactionsButton({ account, transactionBytes1, transactionBytes2 }) {\n    const signAndSendTransactions = useSignAndSendTransactions(account, 'solana:devnet');\n    return (\n        <button\n            onClick={async () => {\n                try {\n                    const [first, second] = await signAndSendTransactions(\n                        { transaction: transactionBytes1 },\n                        { transaction: transactionBytes2 },\n                    );\n                    const [firstSignature, secondSignature] = [first.signature, second.signature].map(signature =>\n                        getBase58Decoder().decode(signature),\n                    );\n                    window.alert(\n                        `View transactions: https://explorer.solana.com/tx/${firstSignature}?cluster=devnet and https://explorer.solana.com/tx/${secondSignature}?cluster=devnet`,\n                    );\n                } catch (e) {\n                    console.error('Error returned by signAndSendTransactions', e);\n                }\n            }}\n        >\n            Sign and Send Transactions\n        </button>\n    );\n}\n```\n\n### `useSelectedWalletAccount()`\n\nThis hook returns the wallet account that is selected, a function to change the selection, and a list of wallets which pass a filter condition you have provided. This hook must be used in a React Component inside `SelectedWalletAccountContextProvider`.\n\n#### Arguments\n\nThis hook doesn't take any arguments.\n\n#### Returns\n\nThe function returns an array consisting of the following elements in the order given:\n\n- `SelectedWalletAccount`: This element could be a `UiWalletAccount` or `undefined`, and represents the selected wallet account.\n- `SetSelectedWalletAccount`: A setter function to set the SelectedWalletAccount state. It takes an argument which could be a callback function `(prevState)=>newState` or `newState`.\n- `filteredWallets`: List of filtered wallets using the function provided as `filterWallet` function in `SelectedWalletAccountContextProvider`\n\n#### Example\n\n```tsx\nimport React from 'react';\nimport { useSelectedWalletAccount } from '@solana/react';\n\nfunction WalletInfo() {\n    const [selectedAccount, setSelectedAccount, filteredWallets] = useSelectedWalletAccount();\n\n    if (!selectedAccount) {\n        return <div>No wallet selected</div>;\n    }\n\n    return (\n        <div>\n            <p>Address: {selectedAccount.address}</p>\n\n            <button onClick={() => setSelectedAccount(undefined)}>Clear selection</button>\n\n            <p>Available wallets: {filteredWallets.length}</p>\n        </div>\n    );\n}\n```\n\n### `SelectedWalletAccountContextProvider`\n\nThis is a react context provider for `SelectedWalletAccountContext`. It provides its children access to the context by using either `useSelectedWalletAccount()` or `useContext(SelectedWalletAccountContext)`.\n\n#### Props\n\nThe provider takes the following props:\n\n- `filterWallet`: a function used to filter supported wallets. For example you might use this to restrict your app to wallets that support `solana:mainnet`.\n- `stateSync`: an object to store the selected wallet, with these properties:\n    - `storeSelectedWallet`: a function used to store a selected wallet account identifier (as a string) into persistent storage. For example this might write to local storage in the browser. The string stored is `${walletName}:${accountAddress}`.\n    - `getSelectedWallet`: a function used to retrieve the persisted wallet account identifier from the persistent storage.\n    - `deleteSelectedWallet`: clears any persisted wallet account identifier from the persistent storage.\n\n#### Example\n\n```tsx\nimport React from 'react';\nimport { SelectedWalletAccountContextProvider } from '@solana/react';\nimport type { UiWallet } from '@wallet-standard/react';\n\nconst STORAGE_KEY = 'solana-wallet-account-id';\n\nexport function App() {\n    return (\n        <SelectedWalletAccountContextProvider\n            filterWallet={(wallet: UiWallet) => wallet.accounts.length > 0}\n            stateSync={{\n                getSelectedWallet: () => localStorage.getItem(STORAGE_KEY),\n                storeSelectedWallet: accountKey => localStorage.setItem(STORAGE_KEY, accountKey),\n                deleteSelectedWallet: () => localStorage.removeItem(STORAGE_KEY),\n            }}\n        >\n            <WalletInfo />\n        </SelectedWalletAccountContextProvider>\n    );\n}\n```\n"
  },
  {
    "path": "packages/react/eslint.config.mjs",
    "content": "export { default } from '@solana/eslint-config/eslint.config.react.mjs';\n"
  },
  {
    "path": "packages/react/package.json",
    "content": "{\n    \"name\": \"@solana/react\",\n    \"version\": \"6.9.0\",\n    \"description\": \"React hooks for building Solana apps\",\n    \"homepage\": \"https://www.solanakit.com/api#solanareact\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/promises\": \"workspace:*\",\n        \"@solana/signers\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\",\n        \"@solana/wallet-standard-features\": \"^1.3.0\",\n        \"@wallet-standard/base\": \"^1.1.0\",\n        \"@wallet-standard/errors\": \"^0.1.1\",\n        \"@wallet-standard/react\": \"^1.0.1\",\n        \"@wallet-standard/ui\": \"^1.0.1\",\n        \"@wallet-standard/ui-registry\": \"^1.0.1\"\n    },\n    \"devDependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/eslint-config\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@testing-library/react\": \"^16.3.2\",\n        \"@types/react\": \"^19.2.14\",\n        \"@types/react-test-renderer\": \"^19.1.0\",\n        \"react\": \"^19.2.6\",\n        \"react-dom\": \"^19.2.6\",\n        \"react-error-boundary\": \"^5.0.0\",\n        \"react-test-renderer\": \"^19.2.5\"\n    },\n    \"peerDependencies\": {\n        \"react\": \">=18\"\n    },\n    \"peerDependenciesMeta\": {\n        \"react\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/react/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/react/src/SelectedWalletAccountContextProvider.tsx",
    "content": "import type { UiWallet, UiWalletAccount } from '@wallet-standard/react';\nimport {\n    getUiWalletAccountStorageKey,\n    uiWalletAccountBelongsToUiWallet,\n    uiWalletAccountsAreSame,\n    useWallets,\n} from '@wallet-standard/react';\nimport React from 'react';\n\nimport { SelectedWalletAccountContext, SelectedWalletAccountState } from './selectedWalletAccountContext';\n\nexport type SelectedWalletAccountContextProviderProps = {\n    filterWallets: (wallet: UiWallet) => boolean;\n    stateSync: {\n        deleteSelectedWallet: () => void;\n        getSelectedWallet: () => string | null;\n        storeSelectedWallet: (accountKey: string) => void;\n    };\n} & { children: React.ReactNode };\n\n/**\n * Returns the saved wallet account when its corresponding wallet, and account is available.\n * @param wallets All wallets available to select in the app\n * @param savedWalletKey The saved wallet account storage key\n * @returns The saved wallet account, or undefined if not found\n */\nfunction findSavedWalletAccount(\n    wallets: readonly UiWallet[],\n    savedWalletKey: string | null,\n): UiWalletAccount | undefined {\n    if (!savedWalletKey) {\n        return;\n    }\n    const [savedWalletName, savedWalletAddress] = savedWalletKey.split(':');\n    if (!savedWalletName || !savedWalletAddress) {\n        return;\n    }\n    for (const wallet of wallets) {\n        if (wallet.name !== savedWalletName) continue;\n        for (const account of wallet.accounts) {\n            if (account.address === savedWalletAddress) {\n                return account;\n            }\n        }\n    }\n}\n\n/**\n * Saves the selected wallet account's storage key to a persistant storage. In future\n * sessions it will try to return that same wallet account, or at least one from the same brand of\n * wallet if the wallet from which it came is still in the Wallet Standard registry.\n * @param children The child components that will have access to the selected wallet account context\n * @param filterWallets A function to filter which wallets are available in the app\n * @param stateSync An object with methods to synchronize the selected wallet account state with persistent storage\n * @returns A React component that provides the selected wallet account context to its children\n */\nexport function SelectedWalletAccountContextProvider({\n    children,\n    filterWallets,\n    stateSync,\n}: SelectedWalletAccountContextProviderProps) {\n    const wallets = useWallets();\n    const filteredWallets = React.useMemo(() => wallets.filter(filterWallets), [wallets, filterWallets]);\n    const wasSetterInvokedRef = React.useRef(false);\n\n    const [selectedWalletAccount, setSelectedWalletAccountInternal] = React.useState<SelectedWalletAccountState>(() => {\n        const savedWalletKey = stateSync.getSelectedWallet();\n        const savedWalletAccount = findSavedWalletAccount(filteredWallets, savedWalletKey);\n        return savedWalletAccount;\n    });\n\n    // Public setter: mark the per-instance ref synchronously to avoid races, then schedule state update.\n    // useCallback stabilises the setter for consumers.\n    const setSelectedWalletAccount: React.Dispatch<React.SetStateAction<SelectedWalletAccountState>> =\n        React.useCallback(\n            setStateAction => {\n                wasSetterInvokedRef.current = true;\n                setSelectedWalletAccountInternal(prevSelectedWalletAccount => {\n                    const nextWalletAccount =\n                        typeof setStateAction === 'function'\n                            ? setStateAction(prevSelectedWalletAccount)\n                            : setStateAction;\n                    return nextWalletAccount;\n                });\n            },\n            [setSelectedWalletAccountInternal],\n        );\n\n    //Sync to persistant storage when selectedWalletAccount changes\n    React.useEffect(() => {\n        if (!wasSetterInvokedRef.current) return;\n\n        const accountKey = selectedWalletAccount ? getUiWalletAccountStorageKey(selectedWalletAccount) : undefined;\n\n        if (accountKey) {\n            stateSync.storeSelectedWallet(accountKey);\n        } else {\n            stateSync.deleteSelectedWallet();\n        }\n    }, [selectedWalletAccount, stateSync]);\n\n    //Auto-restore saved wallet account if it appears later,\n    //and if the user hasn't made an explicit choice yet.\n    React.useEffect(() => {\n        if (wasSetterInvokedRef.current) return;\n        const savedWalletKey = stateSync.getSelectedWallet();\n        const savedAccount = findSavedWalletAccount(filteredWallets, savedWalletKey);\n        if (savedAccount && selectedWalletAccount && uiWalletAccountsAreSame(savedAccount, selectedWalletAccount)) {\n            return;\n        }\n        if (savedAccount) {\n            setSelectedWalletAccountInternal(savedAccount);\n        }\n    }, [filteredWallets, stateSync, selectedWalletAccount]);\n\n    const walletAccount = React.useMemo(() => {\n        if (!selectedWalletAccount) return;\n        for (const wallet of filteredWallets) {\n            for (const account of wallet.accounts) {\n                if (uiWalletAccountsAreSame(account, selectedWalletAccount)) {\n                    return account;\n                }\n            }\n            if (uiWalletAccountBelongsToUiWallet(selectedWalletAccount, wallet) && wallet.accounts[0]) {\n                return wallet.accounts[0];\n            }\n        }\n    }, [selectedWalletAccount, filteredWallets]);\n\n    React.useEffect(() => {\n        // If there is a selected wallet account but the wallet to which it belongs has since\n        // disconnected, clear the selected wallet. This is an automatic cleanup and should not\n        // mark the 'wasSetterInvoked' ref (so we use the internal setter).\n        // Cleanup shouldn't be run if user has made a selection or selectedWalletAccount/walletAccount are loading or undefined\n        if (!selectedWalletAccount) return; //still loading ...\n        if (wasSetterInvokedRef.current) return; //user made a selection\n        if (!walletAccount) {\n            setSelectedWalletAccountInternal(undefined);\n        }\n    }, [selectedWalletAccount, walletAccount]);\n\n    return (\n        <SelectedWalletAccountContext.Provider value={[walletAccount, setSelectedWalletAccount, filteredWallets]}>\n            {children}\n        </SelectedWalletAccountContext.Provider>\n    );\n}\n"
  },
  {
    "path": "packages/react/src/__tests__/SelectedWalletAccountContextProvider-test.browser.tsx",
    "content": "import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';\nimport React from 'react';\n\nimport { useSelectedWalletAccount } from '../selectedWalletAccountContext';\nimport { SelectedWalletAccountContextProvider } from '../SelectedWalletAccountContextProvider';\n\n// Mock wallet-standard/react exports the provider depends on\njest.mock('@wallet-standard/react', () => {\n    return {\n        // The provider itself uses only getUiWalletAccountStorageKey, uiWalletAccountsAreSame, uiWalletAccountBelongsToUiWallet\n        getUiWalletAccountStorageKey: jest.fn(),\n\n        uiWalletAccountBelongsToUiWallet: jest.fn(),\n        uiWalletAccountsAreSame: jest.fn(),\n        useWallets: jest.fn(),\n    };\n});\n\nimport {\n    getUiWalletAccountStorageKey,\n    UiWallet,\n    UiWalletAccount,\n    uiWalletAccountBelongsToUiWallet,\n    uiWalletAccountsAreSame,\n    useWallets,\n} from '@wallet-standard/react';\n\nfunction makeWallet(name: string, accounts: string[]) {\n    return {\n        accounts: accounts.map(addr => ({ address: addr, walletName: name })),\n        name,\n    };\n}\n\n/** Used to track and error out on infinite re-renders */\nlet renderCount = 0;\nfunction Consumer() {\n    renderCount++;\n    if (renderCount > 10) {\n        throw new Error('Too many re-renders');\n    }\n    const [walletAccount, setWalletAccount, filteredWallets] = useSelectedWalletAccount();\n    return (\n        <div>\n            <div data-testid=\"selected\">{walletAccount ? walletAccount.address : 'none'}</div>\n            <button\n                data-testid=\"pick-b\"\n                onClick={() =>\n                    setWalletAccount({ address: 'abc', walletName: 'WalletB' } as unknown as UiWalletAccount)\n                }\n            >\n                Pick B\n            </button>\n            <button data-testid=\"clear\" onClick={() => setWalletAccount(undefined)}>\n                Clear\n            </button>\n            <div data-testid=\"filtered-wallets\">{filteredWallets.map(w => w.name).join(', ')}</div>\n        </div>\n    );\n}\n\ndescribe('SelectedWalletAccountContextProvider', () => {\n    beforeEach(() => {\n        jest.clearAllMocks();\n\n        //Mock implementations for wallet-standard/react functions\n        (getUiWalletAccountStorageKey as jest.Mock).mockImplementation(\n            account => `${account.walletName}:${account.address}`,\n        );\n        (uiWalletAccountsAreSame as jest.Mock).mockImplementation((a, b) => a?.address === b?.address);\n        (uiWalletAccountBelongsToUiWallet as jest.Mock).mockImplementation(\n            (account, wallet) => account?.walletName === wallet?.name,\n        );\n\n        renderCount = 0;\n    });\n\n    test('only filtered wallets are usable', () => {\n        const stateSync = {\n            deleteSelectedWallet: jest.fn(),\n            getSelectedWallet: jest.fn(),\n            storeSelectedWallet: jest.fn(),\n        };\n        const walletA = makeWallet('WalletA', ['123']);\n        const walletB = makeWallet('WalletB', ['abc']);\n\n        const mockWallets = [walletA, walletB];\n        (useWallets as jest.Mock).mockReturnValue(mockWallets);\n        const allowOnlyA = (wallet: UiWallet) => wallet.name === 'WalletA';\n\n        render(\n            <SelectedWalletAccountContextProvider filterWallets={allowOnlyA} stateSync={stateSync}>\n                <Consumer />\n            </SelectedWalletAccountContextProvider>,\n        );\n\n        expect(screen.getByTestId('selected').textContent).toBe('none');\n        expect(screen.getByTestId('filtered-wallets').textContent).toContain('WalletA');\n        expect(screen.getByTestId('filtered-wallets').textContent).not.toContain('WalletB');\n\n        act(() => {\n            fireEvent.click(screen.getByTestId('pick-b'));\n        });\n\n        /** Even if walletB is selected, since it is not available the provider will return 'undefined' for the walletAccount */\n        expect(screen.getByTestId('selected').textContent).toBe('none');\n    });\n\n    test('initializes from saved key', () => {\n        //saved key matchs a wallet that is available from useWallets\n        const stateSync = {\n            deleteSelectedWallet: jest.fn(),\n            getSelectedWallet: jest.fn().mockReturnValue('WalletA:123'),\n            storeSelectedWallet: jest.fn(),\n        };\n\n        const walletA = makeWallet('WalletA', ['123', '456']);\n        const walletB = makeWallet('WalletB', ['abc']);\n\n        const mockWallets = [walletA, walletB];\n        (useWallets as jest.Mock).mockReturnValue(mockWallets);\n\n        const allowWallets = () => true;\n\n        render(\n            <SelectedWalletAccountContextProvider filterWallets={allowWallets} stateSync={stateSync}>\n                <Consumer />\n            </SelectedWalletAccountContextProvider>,\n        );\n\n        expect(screen.getByTestId('selected').textContent).toBe('123');\n        expect(stateSync.getSelectedWallet).toHaveBeenCalled();\n    });\n\n    test('initializes with no selection when saved key is invalid', () => {\n        //saved key matchs a wallet that is available from useWallets\n        const stateSync = {\n            deleteSelectedWallet: jest.fn(),\n            getSelectedWallet: jest.fn().mockReturnValue(null),\n            storeSelectedWallet: jest.fn(),\n        };\n\n        const mockWallets = [makeWallet('WalletA', ['123', '456']), makeWallet('WalletB', ['abc'])];\n        (useWallets as jest.Mock).mockReturnValue(mockWallets);\n\n        const allowWallets = () => true;\n\n        render(\n            <SelectedWalletAccountContextProvider filterWallets={allowWallets} stateSync={stateSync}>\n                <Consumer />\n            </SelectedWalletAccountContextProvider>,\n        );\n\n        expect(screen.getByTestId('selected').textContent).toBe('none');\n        expect(stateSync.getSelectedWallet).toHaveBeenCalled();\n    });\n\n    test('initializes with selected wallet when make a selection from the available wallets', () => {\n        const stateSync = {\n            deleteSelectedWallet: jest.fn(),\n            getSelectedWallet: jest.fn().mockReturnValue(null),\n            storeSelectedWallet: jest.fn((_accountKey: string) => {}),\n        };\n\n        const mockWallets = [makeWallet('WalletA', ['123', '456']), makeWallet('WalletB', ['abc'])];\n        (useWallets as jest.Mock).mockReturnValue(mockWallets);\n\n        const allowWallets = () => true;\n\n        render(\n            <SelectedWalletAccountContextProvider filterWallets={allowWallets} stateSync={stateSync}>\n                <Consumer />\n            </SelectedWalletAccountContextProvider>,\n        );\n\n        expect(screen.getByTestId('selected').textContent).toBe('none');\n        expect(stateSync.getSelectedWallet).toHaveBeenCalled();\n\n        //Make a selection\n        act(() => {\n            fireEvent.click(screen.getByTestId('pick-b'));\n        });\n\n        expect(screen.getByTestId('selected').textContent).toBe('abc');\n        expect(stateSync.storeSelectedWallet).toHaveBeenCalledWith('WalletB:abc');\n    });\n\n    test('allows changing and clearing selection', async () => {\n        const stateSync = {\n            deleteSelectedWallet: jest.fn(),\n            getSelectedWallet: jest.fn().mockReturnValue(null),\n            storeSelectedWallet: jest.fn((_accountKey: string) => {}),\n        };\n\n        const mockWallets = [makeWallet('WalletA', ['123', '456']), makeWallet('WalletB', ['abc'])];\n        (useWallets as jest.Mock).mockReturnValue(mockWallets);\n\n        const allowWallets = () => true;\n\n        render(\n            <SelectedWalletAccountContextProvider filterWallets={allowWallets} stateSync={stateSync}>\n                <Consumer />\n            </SelectedWalletAccountContextProvider>,\n        );\n\n        //Initial state\n        expect(screen.getByTestId('selected').textContent).toBe('none');\n\n        //Pick B\n        fireEvent.click(screen.getByTestId('pick-b'));\n\n        expect(screen.getByTestId('selected').textContent).toBe('abc');\n        await waitFor(() => {\n            expect(stateSync.storeSelectedWallet).toHaveBeenCalledWith('WalletB:abc');\n        });\n\n        //Clear\n        fireEvent.click(screen.getByTestId('clear'));\n\n        expect(screen.getByTestId('selected').textContent).toBe('none');\n        await waitFor(() => expect(stateSync.deleteSelectedWallet).toHaveBeenCalled());\n    });\n\n    test('auto-restores saved wallet when it appears later', () => {\n        const getSelectedWallet = jest.fn().mockReturnValue('WalletA:123');\n        const storeSelectedWallet = jest.fn();\n        const deleteSelectedWallet = jest.fn();\n\n        const allowWallets = () => true;\n\n        //First render with no wallets\n        const mockWallets: UiWallet[] = [];\n        const useWalletsMock = useWallets as jest.Mock;\n        useWalletsMock.mockReturnValue(mockWallets);\n\n        const { rerender } = render(\n            <SelectedWalletAccountContextProvider\n                filterWallets={allowWallets}\n                stateSync={{\n                    deleteSelectedWallet,\n                    getSelectedWallet,\n                    storeSelectedWallet,\n                }}\n            >\n                <Consumer />\n            </SelectedWalletAccountContextProvider>,\n        );\n\n        //nothing selected yet\n        expect(screen.getByTestId('selected').textContent).toContain('none');\n        expect(getSelectedWallet).toHaveBeenCalled();\n\n        //Now update wallets to include the saved one\n        const mockWalletsUpdated = [makeWallet('WalletA', ['123']), makeWallet('WalletB', ['abc'])];\n        useWalletsMock.mockReturnValue(mockWalletsUpdated);\n\n        act(() => {\n            rerender(\n                <SelectedWalletAccountContextProvider\n                    filterWallets={allowWallets}\n                    stateSync={{\n                        deleteSelectedWallet,\n                        getSelectedWallet,\n                        storeSelectedWallet,\n                    }}\n                >\n                    <Consumer />\n                </SelectedWalletAccountContextProvider>,\n            );\n        });\n\n        expect(screen.getByTestId('selected').textContent).toBe('123');\n    });\n\n    test('clears in-memory selection when selected wallet disappears', () => {\n        const getSelectedWallet = jest.fn().mockReturnValue('WalletA:123');\n        const storeSelectedWallet = jest.fn();\n        const deleteSelectedWallet = jest.fn();\n\n        //First render with WalletA present\n        const mockWallets = [makeWallet('WalletA', ['123', '456']), makeWallet('WalletB', ['abc'])];\n        const useWalletsMock = useWallets as jest.Mock;\n        useWalletsMock.mockReturnValue(mockWallets);\n\n        const allowWallets = () => true;\n\n        const { rerender } = render(\n            <SelectedWalletAccountContextProvider\n                filterWallets={allowWallets}\n                stateSync={{\n                    deleteSelectedWallet,\n                    getSelectedWallet,\n                    storeSelectedWallet,\n                }}\n            >\n                <Consumer />\n            </SelectedWalletAccountContextProvider>,\n        );\n\n        //WalletA:123 is selected\n        expect(screen.getByTestId('selected').textContent).toBe('123');\n        expect(getSelectedWallet).toHaveBeenCalled();\n\n        //Now update wallets to remove WalletA\n        const mockWalletsUpdated = [makeWallet('WalletB', ['abc'])];\n        useWalletsMock.mockReturnValue(mockWalletsUpdated);\n\n        act(() => {\n            rerender(\n                <SelectedWalletAccountContextProvider\n                    filterWallets={allowWallets}\n                    stateSync={{\n                        deleteSelectedWallet,\n                        getSelectedWallet,\n                        storeSelectedWallet,\n                    }}\n                >\n                    <Consumer />\n                </SelectedWalletAccountContextProvider>,\n            );\n        });\n\n        expect(screen.getByTestId('selected').textContent).toBe('none');\n    });\n});\n"
  },
  {
    "path": "packages/react/src/__tests__/useSignAndSendTransaction-test.ts",
    "content": "import type { Wallet, WalletAccount, WalletVersion } from '@wallet-standard/base';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED,\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport type { UiWalletAccount } from '@wallet-standard/ui';\nimport {\n    getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n    getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n} from '@wallet-standard/ui-registry';\n\nimport { renderHook } from '../test-renderer';\nimport { useSignAndSendTransaction, useSignAndSendTransactions } from '../useSignAndSendTransaction';\n\njest.mock('@wallet-standard/ui-registry');\n\ndescribe('useSignAndSendTransaction', () => {\n    let mockSignAndSendTransaction: jest.Mock;\n    let mockUiWalletAccount: {\n        address: 'abc';\n        chains: ['solana:danknet'];\n        features: ['solana:signAndSendTransaction'];\n        publicKey: Uint8Array;\n        '~uiWalletHandle': UiWalletAccount['~uiWalletHandle'];\n    };\n    let mockWalletAccount: WalletAccount;\n    beforeEach(() => {\n        mockSignAndSendTransaction = jest.fn().mockResolvedValue([{ signature: 'abc' }]);\n        mockUiWalletAccount = {\n            address: 'abc',\n            chains: ['solana:danknet'] as const,\n            features: ['solana:signAndSendTransaction'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n            '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n        };\n        mockWalletAccount = {\n            address: 'abc',\n            chains: ['solana:danknet'] as const,\n            features: ['solana:signAndSendTransaction'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n        };\n        const mockWallet: Wallet = {\n            accounts: [mockWalletAccount],\n            chains: ['solana:danknet'],\n            features: {\n                ['solana:signAndSendTransaction']: {\n                    signAndSendTransaction: mockSignAndSendTransaction,\n                },\n            },\n            icon: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=',\n            name: 'Mock Wallet',\n            version: '1.0.0' as WalletVersion,\n        };\n        jest.mocked(getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(mockWallet);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            mockWalletAccount,\n        );\n        // Suppresses console output when an `ErrorBoundary` is hit.\n        // See https://stackoverflow.com/a/72632884/802047\n        jest.spyOn(console, 'error').mockImplementation();\n        jest.spyOn(console, 'warn').mockImplementation();\n    });\n    it('fatals when passed a wallet account that does not support the `solana:signAndSendTransaction` feature', () => {\n        const { result } = renderHook(() =>\n            useSignAndSendTransaction({ ...mockUiWalletAccount, features: ['other:feature'] }, 'solana:danknet'),\n        );\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(\n            new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED, {\n                address: 'abc',\n                featureName: 'solana:signAndSendTransaction',\n                supportedChains: ['solana:danknet'],\n                supportedFeatures: ['other:feature'],\n            }),\n        );\n    });\n    it('fatals when passed a wallet account that does not support the specified chain', () => {\n        const { result } = renderHook(() =>\n            useSignAndSendTransaction({ ...mockUiWalletAccount, chains: ['solana:basednet'] }, 'solana:danknet'),\n        );\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(\n            new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n                address: 'abc',\n                chain: 'solana:danknet',\n                featureName: 'solana:signAndSendTransaction',\n                supportedChains: ['solana:basednet'],\n                supportedFeatures: ['solana:signAndSendTransaction'],\n            }),\n        );\n    });\n    it('fatals when the wallet account lookup for the supplied React wallet account fails', () => {\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockImplementation(() => {\n            throw 'o no';\n        });\n        const { result } = renderHook(() => useSignAndSendTransaction(mockUiWalletAccount, 'solana:danknet'));\n        expect(result.__type).toBe('error');\n        expect(result.current).toBe('o no');\n    });\n    describe('the function returned', () => {\n        it(\"calls the wallet's `signAndSendTransaction` implementation\", async () => {\n            expect.assertions(2);\n            const { result } = renderHook(() => useSignAndSendTransaction(mockUiWalletAccount, 'solana:danknet'));\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                const signAndSendTransaction = result.current;\n                signAndSendTransaction({\n                    options: { minContextSlot: 123n },\n                    transaction: new Uint8Array([1, 2, 3]),\n                }).catch(() => {});\n                await jest.runAllTimersAsync();\n                signAndSendTransaction({\n                    options: { minContextSlot: 123n },\n                    transaction: new Uint8Array([1, 2, 3]),\n                }).catch(() => {});\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignAndSendTransaction).toHaveBeenCalledTimes(2);\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignAndSendTransaction).toHaveBeenCalledWith({\n                    account: mockWalletAccount,\n                    chain: 'solana:danknet',\n                    options: { minContextSlot: 123 },\n                    transaction: new Uint8Array([1, 2, 3]),\n                });\n            }\n        });\n    });\n    describe('useSignAndSendTransactions', () => {\n        it('returns empty output without calling the wallet implementation when given no inputs', async () => {\n            expect.assertions(2);\n            const { result } = renderHook(() => useSignAndSendTransactions(mockUiWalletAccount, 'solana:danknet'));\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                const signAndSendTransactions = result.current;\n                const results = await signAndSendTransactions();\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(results).toEqual([]);\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignAndSendTransaction).not.toHaveBeenCalled();\n            }\n        });\n        it(\"passes through multiple inputs to the wallet's `signAndSendTransaction` implementation\", async () => {\n            expect.assertions(3);\n            mockSignAndSendTransaction.mockResolvedValueOnce([{ signature: 'abc' }, { signature: 'def' }]);\n            const { result } = renderHook(() => useSignAndSendTransactions(mockUiWalletAccount, 'solana:danknet'));\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                const signAndSendTransactions = result.current;\n                const promise = signAndSendTransactions(\n                    {\n                        options: { minContextSlot: 123n },\n                        transaction: new Uint8Array([1, 2, 3]),\n                    },\n                    { transaction: new Uint8Array([4, 5, 6]) },\n                );\n                await jest.runAllTimersAsync();\n                const results = await promise;\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignAndSendTransaction).toHaveBeenCalledTimes(1);\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignAndSendTransaction).toHaveBeenCalledWith(\n                    {\n                        account: mockWalletAccount,\n                        chain: 'solana:danknet',\n                        options: { minContextSlot: 123 },\n                        transaction: new Uint8Array([1, 2, 3]),\n                    },\n                    {\n                        account: mockWalletAccount,\n                        chain: 'solana:danknet',\n                        transaction: new Uint8Array([4, 5, 6]),\n                    },\n                );\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(results).toEqual([{ signature: 'abc' }, { signature: 'def' }]);\n            }\n        });\n        it('fatals when passed a wallet account that does not support the specified chain', () => {\n            const { result } = renderHook(() =>\n                useSignAndSendTransactions({ ...mockUiWalletAccount, chains: ['solana:basednet'] }, 'solana:danknet'),\n            );\n            expect(result.__type).toBe('error');\n            expect(result.current).toEqual(\n                new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n                    address: 'abc',\n                    chain: 'solana:danknet',\n                    featureName: 'solana:signAndSendTransaction',\n                    supportedChains: ['solana:basednet'],\n                    supportedFeatures: ['solana:signAndSendTransaction'],\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/react/src/__tests__/useSignIn-test.ts",
    "content": "import { SolanaSignInInput } from '@solana/wallet-standard-features';\nimport type { Wallet, WalletAccount, WalletVersion } from '@wallet-standard/base';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED,\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_FEATURE_UNIMPLEMENTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport type { UiWallet, UiWalletAccount } from '@wallet-standard/ui';\nimport {\n    getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n    getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n} from '@wallet-standard/ui-registry';\n\nimport { renderHook } from '../test-renderer';\nimport { useSignIn } from '../useSignIn';\n\njest.mock('@wallet-standard/ui-registry');\n\ndescribe('useSignIn', () => {\n    let mockSignIn: jest.Mock;\n    let mockUiWallet: UiWallet;\n    let mockUiWalletAccount: {\n        address: 'abc';\n        chains: [];\n        features: ['solana:signIn'];\n        publicKey: Uint8Array;\n        '~uiWalletHandle': UiWalletAccount['~uiWalletHandle'];\n    };\n    let mockWallet: Wallet;\n    let mockWalletAccount: WalletAccount;\n    beforeEach(() => {\n        mockSignIn = jest.fn().mockResolvedValue([{ signature: 'abc' }]);\n        mockUiWalletAccount = {\n            address: 'abc',\n            chains: [] as const,\n            features: ['solana:signIn'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n            '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n        };\n        mockUiWallet = {\n            accounts: [mockUiWalletAccount] as const,\n            chains: [] as const,\n            features: ['solana:signIn'] as const,\n            icon: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=',\n            name: 'Mock Wallet',\n            version: '1.0.0' as WalletVersion,\n            '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n        };\n        mockWalletAccount = {\n            address: 'abc',\n            chains: [] as const,\n            features: ['solana:signIn'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n        };\n        mockWallet = {\n            accounts: [mockWalletAccount],\n            chains: [],\n            features: {\n                ['solana:signIn']: {\n                    signIn: mockSignIn,\n                },\n            },\n            icon: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=',\n            name: 'Mock Wallet',\n            version: '1.0.0' as WalletVersion,\n        };\n        jest.mocked(getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(mockWallet);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            mockWalletAccount,\n        );\n        // Suppresses console output when an `ErrorBoundary` is hit.\n        // See https://stackoverflow.com/a/72632884/802047\n        jest.spyOn(console, 'error').mockImplementation();\n        jest.spyOn(console, 'warn').mockImplementation();\n    });\n    it('fatals when passed a wallet that does not support the `solana:signIn` feature', () => {\n        jest.mocked(getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue({\n            ...mockWallet,\n            features: { ['other:feature']: {} },\n        });\n        const { result } = renderHook(() => useSignIn(mockUiWallet));\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(\n            new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_FEATURE_UNIMPLEMENTED, {\n                featureName: 'solana:signIn',\n                supportedChains: [],\n                supportedFeatures: ['other:feature'],\n                walletName: 'Mock Wallet',\n            }),\n        );\n    });\n    it('fatals when passed a wallet account that does not support the `solana:signIn` feature', () => {\n        const { result } = renderHook(() => useSignIn({ ...mockUiWalletAccount, features: ['other:feature'] }));\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(\n            new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED, {\n                address: 'abc',\n                featureName: 'solana:signIn',\n                supportedChains: [],\n                supportedFeatures: ['other:feature'],\n            }),\n        );\n    });\n    it('fatals when the wallet account lookup for the supplied React wallet account fails', () => {\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockImplementation(() => {\n            throw 'o no';\n        });\n        const { result } = renderHook(() => useSignIn(mockUiWalletAccount));\n        expect(result.__type).toBe('error');\n        expect(result.current).toBe('o no');\n    });\n    describe('when configured with a `UiWallet`', () => {\n        let signIn: ReturnType<typeof useSignIn>;\n        beforeEach(() => {\n            const { result } = renderHook(() => useSignIn(mockUiWallet));\n\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                signIn = result.current;\n            }\n        });\n        describe('the function returned', () => {\n            it(\"calls the wallet's `signIn` implementation\", async () => {\n                expect.assertions(2);\n                signIn({ statement: 'You will really like being signed in' }).catch(() => {});\n                await jest.runAllTimersAsync();\n                signIn({ statement: 'You will really like being signed in' }).catch(() => {});\n\n                expect(mockSignIn).toHaveBeenCalledTimes(2);\n\n                expect(mockSignIn).toHaveBeenCalledWith({\n                    statement: 'You will really like being signed in',\n                });\n            });\n        });\n    });\n    describe('when configured with a `UiWalletAccount`', () => {\n        let signIn: (input?: Omit<SolanaSignInInput, 'address'>) => Promise<{\n            readonly account: WalletAccount;\n            readonly signature: Uint8Array;\n            readonly signedMessage: Uint8Array;\n        }>;\n        beforeEach(() => {\n            const { result } = renderHook(() => useSignIn(mockUiWalletAccount));\n\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                signIn = result.current;\n            }\n        });\n        describe('the function returned', () => {\n            it(\"calls the wallet's `signIn` implementation\", async () => {\n                expect.assertions(2);\n                signIn({ statement: 'You will really like being signed in' }).catch(() => {});\n                await jest.runAllTimersAsync();\n                signIn({ statement: 'You will really like being signed in' }).catch(() => {});\n\n                expect(mockSignIn).toHaveBeenCalledTimes(2);\n\n                expect(mockSignIn).toHaveBeenCalledWith({\n                    address: 'abc',\n                    statement: 'You will really like being signed in',\n                });\n            });\n            it('overrides any supplied `address` input with the address of the account', () => {\n                signIn({\n                    // @ts-expect-error Not allowed by TypeScript, but what if supplied anyway?\n                    address: '123',\n                }).catch(() => {});\n\n                expect(mockSignIn).toHaveBeenCalledWith({ address: 'abc' });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/react/src/__tests__/useSignMessage-test.ts",
    "content": "import type { Wallet, WalletAccount, WalletVersion } from '@wallet-standard/base';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport type { UiWalletAccount } from '@wallet-standard/ui';\nimport {\n    getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n    getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n} from '@wallet-standard/ui-registry';\n\nimport { renderHook } from '../test-renderer';\nimport { useSignMessage } from '../useSignMessage';\n\njest.mock('@wallet-standard/ui-registry');\n\ndescribe('useSignMessage', () => {\n    let mockSignMessage: jest.Mock;\n    let mockUiWalletAccount: UiWalletAccount;\n    let mockWalletAccount: WalletAccount;\n    beforeEach(() => {\n        mockSignMessage = jest.fn().mockResolvedValue([{ signature: 'abc' }]);\n        mockUiWalletAccount = {\n            address: 'abc',\n            chains: ['solana:danknet'] as const,\n            features: ['solana:signMessage'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n            '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n        };\n        mockWalletAccount = {\n            address: 'abc',\n            chains: ['solana:danknet'] as const,\n            features: ['solana:signMessage'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n        };\n        const mockWallet: Wallet = {\n            accounts: [mockWalletAccount],\n            chains: ['solana:danknet'],\n            features: {\n                ['solana:signMessage']: {\n                    signMessage: mockSignMessage,\n                },\n            },\n            icon: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=',\n            name: 'Mock Wallet',\n            version: '1.0.0' as WalletVersion,\n        };\n        jest.mocked(getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(mockWallet);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            mockWalletAccount,\n        );\n        // Suppresses console output when an `ErrorBoundary` is hit.\n        // See https://stackoverflow.com/a/72632884/802047\n        jest.spyOn(console, 'error').mockImplementation();\n        jest.spyOn(console, 'warn').mockImplementation();\n    });\n    it('fatals when passed a wallet account that does not support the `solana:signMessage` feature', () => {\n        const { result } = renderHook(() => useSignMessage({ ...mockUiWalletAccount, features: ['other:feature'] }));\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(\n            new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED, {\n                address: 'abc',\n                featureName: 'solana:signMessage',\n                supportedChains: ['solana:danknet'],\n                supportedFeatures: ['other:feature'],\n            }),\n        );\n    });\n    it('fatals when the wallet account lookup for the supplied React wallet account fails', () => {\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockImplementation(() => {\n            throw 'o no';\n        });\n        const { result } = renderHook(() => useSignMessage(mockUiWalletAccount));\n        expect(result.__type).toBe('error');\n        expect(result.current).toBe('o no');\n    });\n    describe('the function returned', () => {\n        it(\"calls the wallet's `signMessage` implementation\", async () => {\n            expect.assertions(2);\n            const { result } = renderHook(() => useSignMessage(mockUiWalletAccount));\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                const signMessage = result.current;\n                signMessage({ message: new Uint8Array([1, 2, 3]) }).catch(() => {});\n                await jest.runAllTimersAsync();\n                signMessage({ message: new Uint8Array([1, 2, 3]) }).catch(() => {});\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignMessage).toHaveBeenCalledTimes(2);\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignMessage).toHaveBeenCalledWith({\n                    account: mockWalletAccount,\n                    message: new Uint8Array([1, 2, 3]),\n                });\n            }\n        });\n    });\n});\n"
  },
  {
    "path": "packages/react/src/__tests__/useSignTransaction-test.ts",
    "content": "import type { Wallet, WalletAccount, WalletVersion } from '@wallet-standard/base';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED,\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport type { UiWalletAccount } from '@wallet-standard/ui';\nimport {\n    getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n    getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n} from '@wallet-standard/ui-registry';\n\nimport { renderHook } from '../test-renderer';\nimport { useSignTransaction, useSignTransactions } from '../useSignTransaction';\n\njest.mock('@wallet-standard/ui-registry');\n\ndescribe('useSignTransaction', () => {\n    let mockSignTransaction: jest.Mock;\n    let mockUiWalletAccount: {\n        address: 'abc';\n        chains: ['solana:danknet'];\n        features: ['solana:signTransaction'];\n        publicKey: Uint8Array;\n        '~uiWalletHandle': UiWalletAccount['~uiWalletHandle'];\n    };\n    let mockWalletAccount: WalletAccount;\n    beforeEach(() => {\n        mockSignTransaction = jest.fn().mockResolvedValue([{ signature: 'abc' }]);\n        mockUiWalletAccount = {\n            address: 'abc',\n            chains: ['solana:danknet'] as const,\n            features: ['solana:signTransaction'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n            '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n        };\n        mockWalletAccount = {\n            address: 'abc',\n            chains: ['solana:danknet'] as const,\n            features: ['solana:signTransaction'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n        };\n        const mockWallet: Wallet = {\n            accounts: [mockWalletAccount],\n            chains: ['solana:danknet'] as const,\n            features: {\n                ['solana:signTransaction']: {\n                    signTransaction: mockSignTransaction,\n                },\n            },\n            icon: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=',\n            name: 'Mock Wallet',\n            version: '1.0.0' as WalletVersion,\n        };\n        jest.mocked(getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(mockWallet);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            mockWalletAccount,\n        );\n        // Suppresses console output when an `ErrorBoundary` is hit.\n        // See https://stackoverflow.com/a/72632884/802047\n        jest.spyOn(console, 'error').mockImplementation();\n        jest.spyOn(console, 'warn').mockImplementation();\n    });\n    it('fatals when passed a wallet account that does not support the `solana:signTransaction` feature', () => {\n        const { result } = renderHook(() =>\n            useSignTransaction({ ...mockUiWalletAccount, features: ['other:feature'] }, 'solana:danknet'),\n        );\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(\n            new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_FEATURE_UNIMPLEMENTED, {\n                address: 'abc',\n                featureName: 'solana:signTransaction',\n                supportedChains: ['solana:danknet'],\n                supportedFeatures: ['other:feature'],\n            }),\n        );\n    });\n    it('fatals when passed a wallet account that does not support the specified chain', () => {\n        const { result } = renderHook(() =>\n            useSignTransaction({ ...mockUiWalletAccount, chains: ['solana:basednet'] }, 'solana:danknet'),\n        );\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(\n            new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n                address: 'abc',\n                chain: 'solana:danknet',\n                featureName: 'solana:signTransaction',\n                supportedChains: ['solana:basednet'],\n                supportedFeatures: ['solana:signTransaction'],\n            }),\n        );\n        expect(result.current).toMatchObject({\n            context: { featureName: 'solana:signTransaction' },\n        });\n    });\n    it('fatals when the wallet account lookup for the supplied React wallet account fails', () => {\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockImplementation(() => {\n            throw 'o no';\n        });\n        const { result } = renderHook(() => useSignTransaction(mockUiWalletAccount, 'solana:danknet'));\n        expect(result.__type).toBe('error');\n        expect(result.current).toBe('o no');\n    });\n    describe('the function returned', () => {\n        it(\"calls the wallet's `signTransaction` implementation\", async () => {\n            expect.assertions(2);\n            const { result } = renderHook(() => useSignTransaction(mockUiWalletAccount, 'solana:danknet'));\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                const signTransaction = result.current;\n                signTransaction({\n                    options: { minContextSlot: 123n },\n                    transaction: new Uint8Array([1, 2, 3]),\n                }).catch(() => {});\n                await jest.runAllTimersAsync();\n                signTransaction({\n                    options: { minContextSlot: 123n },\n                    transaction: new Uint8Array([1, 2, 3]),\n                }).catch(() => {});\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignTransaction).toHaveBeenCalledTimes(2);\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignTransaction).toHaveBeenCalledWith({\n                    account: mockWalletAccount,\n                    chain: 'solana:danknet',\n                    options: { minContextSlot: 123 },\n                    transaction: new Uint8Array([1, 2, 3]),\n                });\n            }\n        });\n    });\n    describe('useSignTransactions', () => {\n        it('returns empty output without calling the wallet implementation when given no inputs', async () => {\n            expect.assertions(2);\n            const { result } = renderHook(() => useSignTransactions(mockUiWalletAccount, 'solana:danknet'));\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                const signTransactions = result.current;\n                const results = await signTransactions();\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(results).toEqual([]);\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignTransaction).not.toHaveBeenCalled();\n            }\n        });\n        it(\"passes through multiple inputs to the wallet's `signTransaction` implementation\", async () => {\n            expect.assertions(3);\n            mockSignTransaction.mockResolvedValueOnce([{ signature: 'abc' }, { signature: 'def' }]);\n            const { result } = renderHook(() => useSignTransactions(mockUiWalletAccount, 'solana:danknet'));\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (result.__type === 'error' || !result.current) {\n                throw result.current;\n            } else {\n                const signTransactions = result.current;\n                const promise = signTransactions(\n                    {\n                        options: { minContextSlot: 123n },\n                        transaction: new Uint8Array([1, 2, 3]),\n                    },\n                    { transaction: new Uint8Array([4, 5, 6]) },\n                );\n                await jest.runAllTimersAsync();\n                const results = await promise;\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignTransaction).toHaveBeenCalledTimes(1);\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(mockSignTransaction).toHaveBeenCalledWith(\n                    {\n                        account: mockWalletAccount,\n                        chain: 'solana:danknet',\n                        options: { minContextSlot: 123 },\n                        transaction: new Uint8Array([1, 2, 3]),\n                    },\n                    {\n                        account: mockWalletAccount,\n                        chain: 'solana:danknet',\n                        transaction: new Uint8Array([4, 5, 6]),\n                    },\n                );\n                // eslint-disable-next-line jest/no-conditional-expect\n                expect(results).toEqual([{ signature: 'abc' }, { signature: 'def' }]);\n            }\n        });\n        it('fatals when passed a wallet account that does not support the specified chain', () => {\n            const { result } = renderHook(() =>\n                useSignTransactions({ ...mockUiWalletAccount, chains: ['solana:basednet'] }, 'solana:danknet'),\n            );\n            expect(result.__type).toBe('error');\n            expect(result.current).toEqual(\n                new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n                    address: 'abc',\n                    chain: 'solana:danknet',\n                    featureName: 'solana:signTransaction',\n                    supportedChains: ['solana:basednet'],\n                    supportedFeatures: ['solana:signTransaction'],\n                }),\n            );\n            expect(result.current).toMatchObject({\n                context: { featureName: 'solana:signTransaction' },\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/react/src/__tests__/useWalletAccountMessageSigner-test.ts",
    "content": "import { SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport type { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { renderHook } from '../test-renderer';\nimport { useSignMessage } from '../useSignMessage';\nimport { useWalletAccountMessageSigner } from '../useWalletAccountMessageSigner';\n\njest.mock('../useSignMessage');\n\ndescribe('useWalletAccountMessageSigner', () => {\n    let mockSignMessage: jest.Mock;\n    let mockUiWalletAccount: UiWalletAccount;\n    beforeEach(() => {\n        mockSignMessage = jest.fn();\n        mockUiWalletAccount = { address: '11111111111111111111111111111119' } as UiWalletAccount;\n        jest.mocked(useSignMessage).mockReturnValue(mockSignMessage);\n        // Suppresses console output when an `ErrorBoundary` is hit.\n        // See https://stackoverflow.com/a/72632884/802047\n        jest.spyOn(console, 'error').mockImplementation();\n        jest.spyOn(console, 'warn').mockImplementation();\n    });\n    it('fatals when `useSignMessage` fatals', () => {\n        jest.mocked(useSignMessage).mockImplementation(() => {\n            throw new Error('o no');\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(new Error('o no'));\n    });\n    it('returns a `MessageModifyingSigner` with an address', () => {\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        expect(result.current).toHaveProperty('address', mockUiWalletAccount.address);\n    });\n    it('fatals when the signing function returned by `useSignMessage` fatals', async () => {\n        expect.assertions(1);\n        mockSignMessage.mockImplementation(() => {\n            throw new Error('o no');\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(() =>\n                modifyAndSignMessages([{ content: new Uint8Array([1, 2, 3]), signatures: {} }]),\n            ).rejects.toThrow(new Error('o no'));\n        }\n    });\n    it('fatals when passed more than one message to sign', async () => {\n        expect.assertions(1);\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(() =>\n                modifyAndSignMessages([\n                    { content: new Uint8Array([1, 2, 3]), signatures: {} },\n                    { content: new Uint8Array([4, 5, 6]), signatures: {} },\n                ]),\n            ).rejects.toThrow(new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED));\n        }\n    });\n    it('returns the exact same message object when no signature update or message modification takes place', async () => {\n        expect.assertions(1);\n        mockSignMessage.mockImplementation(({ message }: { message: Uint8Array }) => {\n            return Object.freeze({\n                signature: new Uint8Array(64).fill(9),\n                signedMessage: message,\n            });\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            const inputMessage = {\n                content: new Uint8Array([1, 2, 3]),\n                signatures: {\n                    [mockUiWalletAccount.address]: new Uint8Array(64).fill(9) as SignatureBytes,\n                },\n            };\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(\n                (async () => {\n                    const [result] = await modifyAndSignMessages([inputMessage]);\n                    return result;\n                })(),\n            ).resolves.toBe(inputMessage);\n        }\n    });\n    it('returns the a clone of the message object when there is a signature update but no message modification', async () => {\n        expect.assertions(1);\n        mockSignMessage.mockImplementation(({ message }: { message: Uint8Array }) => {\n            return Object.freeze({\n                signature: new Uint8Array(64).fill(8),\n                signedMessage: message,\n            });\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            const inputMessage = {\n                content: new Uint8Array([1, 2, 3]),\n                signatures: {\n                    [mockUiWalletAccount.address]: new Uint8Array(64).fill(9) as SignatureBytes,\n                },\n            };\n            const signPromise = (async () => {\n                const [result] = await modifyAndSignMessages([inputMessage]);\n                return result;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).resolves.not.toBe(inputMessage);\n        }\n    });\n    it('returns the a clone of the message object when there is no signature update but the message is modified', async () => {\n        expect.assertions(1);\n        mockSignMessage.mockImplementation(({ message }: { message: Uint8Array }) => {\n            return Object.freeze({\n                signature: new Uint8Array(64).fill(9),\n                signedMessage: message.map(byte => byte + 1),\n            });\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            const inputMessage = {\n                content: new Uint8Array([1, 2, 3]),\n                signatures: {\n                    [mockUiWalletAccount.address]: new Uint8Array(64).fill(9) as SignatureBytes,\n                },\n            };\n            const signPromise = (async () => {\n                const [result] = await modifyAndSignMessages([inputMessage]);\n                return result;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).resolves.not.toBe(inputMessage);\n        }\n    });\n    it('blanks out the existing signatures when the message is modified', async () => {\n        expect.assertions(1);\n        mockSignMessage.mockImplementation(({ message }: { message: Uint8Array }) => {\n            return Object.freeze({\n                signature: new Uint8Array(64).fill(127),\n                signedMessage: message.map(byte => byte + 1),\n            });\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            const inputMessage = {\n                content: new Uint8Array([1, 2, 3]),\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            const signPromise = (async () => {\n                const [result] = await modifyAndSignMessages([inputMessage]);\n                return result;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).resolves.toEqual({\n                content: inputMessage.content.map(byte => byte + 1),\n                signatures: {\n                    [mockUiWalletAccount.address]: new Uint8Array(64).fill(127) as SignatureBytes,\n                },\n            });\n        }\n    });\n    it('returns an object with the identical message given that the message was not modified', async () => {\n        expect.assertions(1);\n        mockSignMessage.mockImplementation(({ message }: { message: Uint8Array }) => {\n            return Object.freeze({\n                signature: new Uint8Array(64).fill(127),\n                signedMessage: message,\n            });\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            const inputMessage = {\n                content: new Uint8Array([1, 2, 3]),\n                signatures: {},\n            };\n            const signedMessagePromise = (async () => {\n                const [result] = await modifyAndSignMessages([inputMessage]);\n                return result.content;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signedMessagePromise).resolves.toBe(inputMessage.content);\n        }\n    });\n    it('returns an object with the identical signature map given that no new signature was produced', async () => {\n        expect.assertions(1);\n        mockSignMessage.mockImplementation(({ message }: { message: Uint8Array }) => {\n            return Object.freeze({\n                signature: new Uint8Array(64).fill(127),\n                signedMessage: message,\n            });\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            const inputMessage = {\n                content: new Uint8Array([1, 2, 3]),\n                signatures: {\n                    [mockUiWalletAccount.address]: new Uint8Array(64).fill(127) as SignatureBytes,\n                },\n            };\n            const signatureMapPromise = (async () => {\n                const [result] = await modifyAndSignMessages([inputMessage]);\n                return result.signatures;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signatureMapPromise).resolves.toBe(inputMessage.signatures);\n        }\n    });\n    it('returns an object with the additional signature given that the message was not modified', async () => {\n        expect.assertions(1);\n        mockSignMessage.mockImplementation(({ message }: { message: Uint8Array }) => {\n            return Object.freeze({\n                signature: new Uint8Array(64).fill(127),\n                signedMessage: message,\n            });\n        });\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            const inputMessage = {\n                content: new Uint8Array([1, 2, 3]),\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            const signPromise = (async () => {\n                const [result] = await modifyAndSignMessages([inputMessage]);\n                return result;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).resolves.toEqual({\n                content: inputMessage.content,\n                signatures: {\n                    ...inputMessage.signatures,\n                    [mockUiWalletAccount.address]: new Uint8Array(64).fill(127) as SignatureBytes,\n                },\n            });\n        }\n    });\n    it('rejects when aborted', async () => {\n        expect.assertions(1);\n        const { result } = renderHook(() => useWalletAccountMessageSigner(mockUiWalletAccount));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignMessages } = result.current;\n            const inputMessage = {\n                content: new Uint8Array([1, 2, 3]),\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            const abortController = new AbortController();\n            abortController.abort(new Error('o no'));\n            const alreadyAbortedSignal = abortController.signal;\n            const signPromise = (async () => {\n                const [result] = await modifyAndSignMessages([inputMessage], { abortSignal: alreadyAbortedSignal });\n                return result;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).rejects.toThrow(new Error('o no'));\n        }\n    });\n});\n"
  },
  {
    "path": "packages/react/src/__tests__/useWalletAccountTransactionSendingSigner-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport type { VariableSizeEncoder } from '@solana/codecs-core';\nimport { SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { Transaction, TransactionMessageBytes } from '@solana/transactions';\nimport { getTransactionEncoder } from '@solana/transactions';\nimport type { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { renderHook } from '../test-renderer';\nimport { useSignAndSendTransaction } from '../useSignAndSendTransaction';\nimport { useWalletAccountTransactionSendingSigner } from '../useWalletAccountTransactionSendingSigner';\n\njest.mock('@solana/transactions');\njest.mock('../useSignAndSendTransaction');\n\ndescribe('useWalletAccountTransactionSendingSigner', () => {\n    let mockSignAndSendTransaction: jest.Mock;\n    let mockEncodeTransaction: jest.Mock;\n    let mockUiWalletAccount: {\n        address: Address<'11111111111111111111111111111119'>;\n        chains: ['solana:danknet'];\n        features: ['solana:signAndSendTransaction'];\n        publicKey: Uint8Array;\n        '~uiWalletHandle': UiWalletAccount['~uiWalletHandle'];\n    };\n    beforeEach(() => {\n        mockEncodeTransaction = jest.fn();\n        jest.mocked(getTransactionEncoder).mockReturnValue({\n            encode: mockEncodeTransaction,\n        } as unknown as VariableSizeEncoder<Transaction>);\n        mockSignAndSendTransaction = jest.fn().mockResolvedValue({ signature: new Uint8Array([1, 2, 3]) });\n        mockUiWalletAccount = {\n            address: '11111111111111111111111111111119' as Address<'11111111111111111111111111111119'>,\n            chains: ['solana:danknet'] as const,\n            features: ['solana:signAndSendTransaction'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n            '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n        };\n        jest.mocked(useSignAndSendTransaction).mockReturnValue(mockSignAndSendTransaction);\n        // Suppresses console output when an `ErrorBoundary` is hit.\n        // See https://stackoverflow.com/a/72632884/802047\n        jest.spyOn(console, 'error').mockImplementation();\n        jest.spyOn(console, 'warn').mockImplementation();\n    });\n    it('fatals when `useSignAndSendTransaction` fatals', () => {\n        jest.mocked(useSignAndSendTransaction).mockImplementation(() => {\n            throw new Error('o no');\n        });\n        const { result } = renderHook(() =>\n            useWalletAccountTransactionSendingSigner(mockUiWalletAccount, 'solana:danknet'),\n        );\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(new Error('o no'));\n    });\n    it('returns a `TransactionSendingSigner` with an address', () => {\n        const { result } = renderHook(() =>\n            useWalletAccountTransactionSendingSigner(mockUiWalletAccount, 'solana:danknet'),\n        );\n        expect(result.current).toHaveProperty('address', mockUiWalletAccount.address);\n    });\n    it('fatals when the signing function returned by `useSignAndSendTransaction` fatals', async () => {\n        expect.assertions(1);\n        mockSignAndSendTransaction.mockImplementation(() => {\n            throw new Error('o no');\n        });\n        const { result } = renderHook(() =>\n            useWalletAccountTransactionSendingSigner(mockUiWalletAccount, 'solana:danknet'),\n        );\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { signAndSendTransactions } = result.current;\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(() =>\n                signAndSendTransactions([\n                    { messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes, signatures: {} },\n                ]),\n            ).rejects.toThrow(new Error('o no'));\n        }\n    });\n    it('fatals when passed more than one transaction to sign', async () => {\n        expect.assertions(1);\n        const { result } = renderHook(() =>\n            useWalletAccountTransactionSendingSigner(mockUiWalletAccount, 'solana:danknet'),\n        );\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { signAndSendTransactions } = result.current;\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(() =>\n                signAndSendTransactions([\n                    { messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes, signatures: {} },\n                    { messageBytes: new Uint8Array([4, 5, 6]) as unknown as TransactionMessageBytes, signatures: {} },\n                ]),\n            ).rejects.toThrow(new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED));\n        }\n    });\n    it('encodes the input transaction and passes it to the function returned by `signTransactions`', () => {\n        const mockEncodedTransaction = new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes;\n        mockEncodeTransaction.mockReturnValue(mockEncodedTransaction);\n        const { result } = renderHook(() =>\n            useWalletAccountTransactionSendingSigner(mockUiWalletAccount, 'solana:danknet'),\n        );\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { signAndSendTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            signAndSendTransactions([inputTransaction]).catch(() => {});\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mockEncodeTransaction).toHaveBeenCalledWith(inputTransaction);\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mockSignAndSendTransaction).toHaveBeenCalledWith({ transaction: mockEncodedTransaction });\n        }\n    });\n    it('returns the sent transaction signature', async () => {\n        expect.assertions(1);\n        const mockSignatureResult = new Uint8Array(64).fill(127);\n        mockSignAndSendTransaction.mockResolvedValue({ signature: mockSignatureResult });\n        const { result } = renderHook(() =>\n            useWalletAccountTransactionSendingSigner(mockUiWalletAccount, 'solana:danknet'),\n        );\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { signAndSendTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signAndSendTransactions([inputTransaction])).resolves.toEqual([mockSignatureResult]);\n        }\n    });\n    it('calls `signAndSendTransaction` with all options except the `abortSignal`', () => {\n        const mockOptions = { minContextSlot: 123n };\n        const { result } = renderHook(() =>\n            useWalletAccountTransactionSendingSigner(mockUiWalletAccount, 'solana:danknet'),\n        );\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { signAndSendTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            signAndSendTransactions([inputTransaction], {\n                abortSignal: AbortSignal.timeout(1_000_000),\n                ...mockOptions,\n            }).catch(() => {});\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mockSignAndSendTransaction).toHaveBeenCalledWith(mockOptions);\n        }\n    });\n    it('rejects when aborted', async () => {\n        expect.assertions(1);\n        const { result } = renderHook(() =>\n            useWalletAccountTransactionSendingSigner(mockUiWalletAccount, 'solana:danknet'),\n        );\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { signAndSendTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            const abortController = new AbortController();\n            abortController.abort(new Error('o no'));\n            const alreadyAbortedSignal = abortController.signal;\n            const signAndSendPromise = (async () => {\n                const [result] = await signAndSendTransactions([inputTransaction], {\n                    abortSignal: alreadyAbortedSignal,\n                });\n                return result;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signAndSendPromise).rejects.toThrow(new Error('o no'));\n        }\n    });\n});\n"
  },
  {
    "path": "packages/react/src/__tests__/useWalletAccountTransactionSigner-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport type { VariableSizeCodec, VariableSizeDecoder } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED,\n    SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { Blockhash } from '@solana/rpc-types';\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    getCompiledTransactionMessageDecoder,\n} from '@solana/transaction-messages';\nimport {\n    getTransactionLifetimeConstraintFromCompiledTransactionMessage,\n    Transaction,\n    TransactionMessageBytes,\n} from '@solana/transactions';\nimport { getTransactionCodec } from '@solana/transactions';\nimport type { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { renderHook } from '../test-renderer';\nimport { useSignTransaction } from '../useSignTransaction';\nimport { useWalletAccountTransactionSigner } from '../useWalletAccountTransactionSigner';\n\njest.mock('@solana/transaction-messages');\njest.mock('@solana/transactions');\njest.mock('../useSignTransaction');\n\ndescribe('useWalletAccountTransactionSigner', () => {\n    let mockSignTransaction: jest.Mock;\n    let mockDecodeTransaction: jest.Mock;\n    let mockEncodeTransaction: jest.Mock;\n    let mockUiWalletAccount: {\n        address: Address<'11111111111111111111111111111119'>;\n        chains: ['solana:danknet'];\n        features: ['solana:signTransaction'];\n        publicKey: Uint8Array;\n        '~uiWalletHandle': UiWalletAccount['~uiWalletHandle'];\n    };\n    beforeEach(() => {\n        mockDecodeTransaction = jest.fn();\n        mockEncodeTransaction = jest.fn();\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecodeTransaction,\n            encode: mockEncodeTransaction,\n        } as unknown as VariableSizeCodec<Transaction>);\n        mockSignTransaction = jest.fn().mockResolvedValue({\n            signature: new Uint8Array([1, 2, 3]),\n            signedMessage: new Uint8Array([1, 2, 3]),\n        });\n        mockUiWalletAccount = {\n            address: '11111111111111111111111111111119' as Address<'11111111111111111111111111111119'>,\n            chains: ['solana:danknet'] as const,\n            features: ['solana:signTransaction'] as const,\n            publicKey: new Uint8Array([1, 2, 3]),\n            '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n        };\n        jest.mocked(useSignTransaction).mockReturnValue(mockSignTransaction);\n        // Suppresses console output when an `ErrorBoundary` is hit.\n        // See https://stackoverflow.com/a/72632884/802047\n        jest.spyOn(console, 'error').mockImplementation();\n        jest.spyOn(console, 'warn').mockImplementation();\n    });\n    it('fatals when `useSignTransaction` fatals', () => {\n        jest.mocked(useSignTransaction).mockImplementation(() => {\n            throw new Error('o no');\n        });\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        expect(result.__type).toBe('error');\n        expect(result.current).toEqual(new Error('o no'));\n    });\n    it('returns a `TransactionModifyingSigner` with an address', () => {\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        expect(result.current).toHaveProperty('address', mockUiWalletAccount.address);\n    });\n    it('fatals when passed more than one transaction to sign', async () => {\n        expect.assertions(1);\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(() =>\n                modifyAndSignTransactions([\n                    { messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes, signatures: {} },\n                    { messageBytes: new Uint8Array([4, 5, 6]) as unknown as TransactionMessageBytes, signatures: {} },\n                ]),\n            ).rejects.toThrow(new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED));\n        }\n    });\n    it('fatals when the signing function returned by `useSignTransaction` fatals', async () => {\n        expect.assertions(1);\n        mockSignTransaction.mockImplementation(() => {\n            throw new Error('o no');\n        });\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(() =>\n                modifyAndSignTransactions([\n                    { messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes, signatures: {} },\n                ]),\n            ).rejects.toThrow(new Error('o no'));\n        }\n    });\n    it('encodes the input transaction and passes it to the function returned by `signTransactions`', () => {\n        const mockEncodedTransaction = {} as Transaction;\n        mockEncodeTransaction.mockReturnValue(mockEncodedTransaction);\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            modifyAndSignTransactions([inputTransaction]).catch(() => {});\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mockEncodeTransaction).toHaveBeenCalledWith(inputTransaction);\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mockSignTransaction).toHaveBeenCalledWith({ transaction: mockEncodedTransaction });\n        }\n    });\n    it('decodes and returns the signed transaction bytes returned by `signTransactions`', async () => {\n        expect.assertions(2);\n        const mockSignedTransaction = new Uint8Array([1, 2, 3, 4, 5, 6]);\n        const mockDecodedTransaction = { messageBytes: [1, 2, 3] } as unknown as Transaction;\n        mockSignTransaction.mockResolvedValue({ signedTransaction: mockSignedTransaction });\n        mockDecodeTransaction.mockReturnValue(mockDecodedTransaction);\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            const lifetimeConstraint = { blockhash: 'abc', lastValidBlockHeight: 123n };\n            const inputTransaction = {\n                lifetimeConstraint,\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            const signPromise = modifyAndSignTransactions([inputTransaction]);\n            await jest.runAllTimersAsync();\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mockDecodeTransaction).toHaveBeenCalledWith(mockSignedTransaction);\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).resolves.toEqual([{ ...mockDecodedTransaction, lifetimeConstraint }]);\n        }\n    });\n    it('calls `signTransaction` with all options except the `abortSignal`', () => {\n        const mockOptions = { minContextSlot: 123n };\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            modifyAndSignTransactions([inputTransaction], {\n                abortSignal: AbortSignal.timeout(1_000_000),\n                ...mockOptions,\n            }).catch(() => {});\n            // eslint-disable-next-line jest/no-conditional-expect\n            expect(mockSignTransaction).toHaveBeenCalledWith(mockOptions);\n        }\n    });\n    it('rejects when aborted', async () => {\n        expect.assertions(1);\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {\n                    '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n                },\n            };\n            const abortController = new AbortController();\n            abortController.abort(new Error('o no'));\n            const alreadyAbortedSignal = abortController.signal;\n            const signPromise = (async () => {\n                const [result] = await modifyAndSignTransactions([inputTransaction], {\n                    abortSignal: alreadyAbortedSignal,\n                });\n                return result;\n            })();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).rejects.toThrow(new Error('o no'));\n        }\n    });\n    it('returns an unchanged lifetime constraint if the signed transaction has the same one', async () => {\n        expect.assertions(1);\n        const mockSignedTransaction = new Uint8Array([1, 2, 3, 4, 5, 6]);\n        const mockDecodedTransaction = { messageBytes: [4, 5, 6] } as unknown as Transaction;\n        mockSignTransaction.mockResolvedValue({ signedTransaction: mockSignedTransaction });\n        mockDecodeTransaction.mockReturnValue(mockDecodedTransaction);\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            const lifetimeConstraint = { blockhash: 'abc', lastValidBlockHeight: 123n };\n            const inputTransaction = {\n                lifetimeConstraint,\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            };\n            jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n                decode: jest.fn().mockReturnValue({\n                    lifetimeToken: 'abc',\n                }),\n            } as unknown as VariableSizeDecoder<CompiledTransactionMessage & CompiledTransactionMessageWithLifetime>);\n            const signPromise = modifyAndSignTransactions([inputTransaction]);\n            await jest.runAllTimersAsync();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).resolves.toEqual([{ ...mockDecodedTransaction, lifetimeConstraint }]);\n        }\n    });\n    it('returns a new lifetime constraint if the input transaction does not have one', async () => {\n        expect.assertions(1);\n        const mockSignedTransaction = new Uint8Array([1, 2, 3, 4, 5, 6]);\n        const mockDecodedTransaction = { messageBytes: [4, 5, 6] } as unknown as Transaction;\n        mockSignTransaction.mockResolvedValue({ signedTransaction: mockSignedTransaction });\n        mockDecodeTransaction.mockReturnValue(mockDecodedTransaction);\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            };\n            jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n                decode: jest.fn().mockReturnValue({}),\n            } as unknown as VariableSizeDecoder<CompiledTransactionMessage & CompiledTransactionMessageWithLifetime>);\n            const newLifetimeConstraint = { blockhash: 'abc' as Blockhash, lastValidBlockHeight: 123n };\n            jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage).mockResolvedValue(\n                newLifetimeConstraint,\n            );\n            const signPromise = modifyAndSignTransactions([inputTransaction]);\n            await jest.runAllTimersAsync();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).resolves.toEqual([\n                { ...mockDecodedTransaction, lifetimeConstraint: newLifetimeConstraint },\n            ]);\n        }\n    });\n    it('returns a new lifetime constraint if the signed transaction has a different one', async () => {\n        expect.assertions(1);\n        const mockSignedTransaction = new Uint8Array([1, 2, 3, 4, 5, 6]);\n        const mockDecodedTransaction = { messageBytes: [4, 5, 6] } as unknown as Transaction;\n        mockSignTransaction.mockResolvedValue({ signedTransaction: mockSignedTransaction });\n        mockDecodeTransaction.mockReturnValue(mockDecodedTransaction);\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            const inputLifetimeConstraint = { blockhash: 'abc', lastValidBlockHeight: 123n };\n            const inputTransaction = {\n                lifetimeConstraint: inputLifetimeConstraint,\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            };\n            jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n                decode: jest.fn().mockReturnValue({\n                    lifetimeToken: 'def',\n                }),\n            } as unknown as VariableSizeDecoder<CompiledTransactionMessage & CompiledTransactionMessageWithLifetime>);\n            const newLifetimeConstraint = { blockhash: 'def' as Blockhash, lastValidBlockHeight: 456n };\n            jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage).mockResolvedValue(\n                newLifetimeConstraint,\n            );\n            const signPromise = modifyAndSignTransactions([inputTransaction]);\n            await jest.runAllTimersAsync();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).resolves.toEqual([\n                { ...mockDecodedTransaction, lifetimeConstraint: newLifetimeConstraint },\n            ]);\n        }\n    });\n    it('fatals when the signed transaction has a new durable nonce lifetime but the nonce account is only in a lookup table', async () => {\n        expect.assertions(1);\n        const mockSignedTransaction = new Uint8Array([1, 2, 3, 4, 5, 6]);\n        const mockDecodedTransaction = { messageBytes: [4, 5, 6] } as unknown as Transaction;\n        mockSignTransaction.mockResolvedValue({ signedTransaction: mockSignedTransaction });\n        mockDecodeTransaction.mockReturnValue(mockDecodedTransaction);\n        const { result } = renderHook(() => useWalletAccountTransactionSigner(mockUiWalletAccount, 'solana:danknet'));\n        // eslint-disable-next-line jest/no-conditional-in-test\n        if (result.__type === 'error' || !result.current) {\n            throw result.current;\n        } else {\n            const { modifyAndSignTransactions } = result.current;\n            const inputTransaction = {\n                messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            };\n            jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n                decode: jest.fn().mockReturnValue({}),\n            } as unknown as VariableSizeDecoder<CompiledTransactionMessage & CompiledTransactionMessageWithLifetime>);\n            jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage).mockRejectedValue(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n                    nonce: 'abc',\n                }),\n            );\n            const signPromise = modifyAndSignTransactions([inputTransaction]);\n            await jest.runAllTimersAsync();\n            // eslint-disable-next-line jest/no-conditional-expect\n            await expect(signPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n                    nonce: 'abc',\n                }),\n            );\n        }\n    });\n});\n"
  },
  {
    "path": "packages/react/src/__typetests__/selectedWalletAccountContextProvider-typetest.ts",
    "content": "import type { UiWallet, UiWalletAccount } from '@wallet-standard/react';\nimport React from 'react';\n\nimport type { useSelectedWalletAccount } from '../selectedWalletAccountContext';\nimport { SelectedWalletAccountContextProvider } from '../SelectedWalletAccountContextProvider';\n\n// [DESCRIBE] SelectedWalletAccountContextProvider\n{\n    // It accepts correct props\n    {\n        React.createElement(SelectedWalletAccountContextProvider, {\n            children: React.createElement('div', null),\n            filterWallets: (_wallet: UiWallet) => true,\n            stateSync: {\n                deleteSelectedWallet: () => {},\n                getSelectedWallet: () => null,\n                storeSelectedWallet: (_accountKey: string) => {},\n            },\n        });\n    }\n\n    // It requires `filterWallet` to return a boolean\n    {\n        React.createElement(SelectedWalletAccountContextProvider, {\n            children: React.createElement('div', null),\n            // @ts-expect-error filterWallet must return a boolean\n            filterWallets: (_wallet: UiWallet) => 'not a boolean',\n            stateSync: {\n                deleteSelectedWallet: () => {},\n                getSelectedWallet: () => null,\n                storeSelectedWallet: (_accountKey: string) => {},\n            },\n        });\n    }\n}\n\n// [DESCRIBE] useSelectedWalletAccount\n{\n    type CtxValue = ReturnType<typeof useSelectedWalletAccount>;\n\n    // It returns selected wallet account\n    {\n        type SelectedWallet = CtxValue[0];\n        undefined satisfies SelectedWallet;\n        null as unknown as UiWalletAccount satisfies SelectedWallet;\n    }\n\n    // It returns a setter\n    {\n        type SetSelected = CtxValue[1];\n\n        const setSelected = null as unknown as SetSelected;\n        // Positive: setter accepts undefined\n        setSelected(undefined);\n        // Positive: setter accepts an updater function\n        setSelected(prev => prev);\n        // Positive: setter accepts a UiWalletAccount value\n        setSelected({} as UiWalletAccount);\n        // Negative: setter rejects invalid types\n        setSelected(\n            // @ts-expect-error must be of correct type\n            'not a wallet account or undefined',\n        );\n    }\n\n    // It returns filtered wallets\n    {\n        type FilteredWallets = CtxValue[2];\n        const filteredWallets = null as unknown as FilteredWallets;\n        filteredWallets satisfies UiWallet[];\n    }\n}\n"
  },
  {
    "path": "packages/react/src/__typetests__/useSignAndSendTransaction-typetest.ts",
    "content": "/* eslint-disable react-hooks/rules-of-hooks */\n\nimport { address } from '@solana/addresses';\nimport { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { useSignAndSendTransaction, useSignAndSendTransactions } from '../useSignAndSendTransaction';\n\nconst mockWalletAccount = {\n    address: address('123'),\n    chains: ['solana:danknet', 'bitcoin:mainnet'] as const,\n    features: [],\n    publicKey: new Uint8Array([1, 2, 3]),\n    '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n} as const;\n\n// [DESCRIBE] useSignAndSendTransaction.\n{\n    // It accepts any chain in the solana namespace\n    useSignAndSendTransaction(mockWalletAccount, 'solana:danknet');\n    useSignAndSendTransaction(mockWalletAccount, 'solana:basednet');\n\n    // It accepts one of the chains actually supported by the wallet account\n    useSignAndSendTransaction(mockWalletAccount, 'solana:danknet');\n\n    // It rejects a chain in a non-Solana namespace\n    useSignAndSendTransaction(\n        mockWalletAccount,\n        // @ts-expect-error Non-Solana chain\n        'bitcoin:mainnet',\n    );\n}\n\n// [DESCRIBE] useSignAndSendTransactions.\n{\n    // It accepts any chain in the solana namespace\n    useSignAndSendTransactions(mockWalletAccount, 'solana:danknet');\n    useSignAndSendTransactions(mockWalletAccount, 'solana:basednet');\n\n    // It accepts one of the chains actually supported by the wallet account\n    const signAndSendTransactions = useSignAndSendTransactions(mockWalletAccount, 'solana:danknet');\n    signAndSendTransactions({ transaction: new Uint8Array() }, { transaction: new Uint8Array() }).catch(() => {});\n\n    // It rejects a chain in a non-Solana namespace\n    useSignAndSendTransactions(\n        mockWalletAccount,\n        // @ts-expect-error Non-Solana chain\n        'bitcoin:mainnet',\n    );\n}\n"
  },
  {
    "path": "packages/react/src/__typetests__/useSignIn-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\n/* eslint-disable react-hooks/rules-of-hooks */\n\nimport { address } from '@solana/addresses';\nimport { WalletVersion } from '@wallet-standard/base';\nimport { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { useSignIn } from '../useSignIn';\n\nconst mockWalletAccount = {\n    address: address('123'),\n    chains: ['solana:danknet', 'bitcoin:mainnet'] as const,\n    features: [],\n    publicKey: new Uint8Array([1, 2, 3]),\n    '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n} as const;\n\nconst mockWallet = {\n    accounts: [mockWalletAccount],\n    chains: ['solana:danknet', 'bitcoin:mainnet'] as const,\n    features: [],\n    icon: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEAAAAALAAAAAABAAEAAAIBAAA=',\n    name: 'Mock Wallet',\n    version: '1.0.0' as WalletVersion,\n    '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n} as const;\n\n// [DESCRIBE] The function returned from `useSignIn`\n{\n    // [DESCRIBE] When created with a wallet\n    {\n        const signIn = useSignIn(mockWallet);\n\n        // It accepts no config\n        {\n            signIn();\n        }\n\n        // It accepts an address config\n        {\n            signIn({ address: address('abc') });\n        }\n    }\n\n    // [DESCRIBE] When created with a wallet account\n    {\n        const signIn = useSignIn(mockWalletAccount);\n\n        // It accepts no config\n        {\n            signIn();\n        }\n\n        // It does not accept an address config\n        {\n            signIn({\n                // @ts-expect-error Address is already provided by the wallet\n                address: address('abc'),\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "packages/react/src/__typetests__/useSignTransaction-typetest.ts",
    "content": "/* eslint-disable react-hooks/rules-of-hooks */\n\nimport { address } from '@solana/addresses';\nimport { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { useSignTransaction, useSignTransactions } from '../useSignTransaction';\n\nconst mockWalletAccount = {\n    address: address('123'),\n    chains: ['solana:danknet', 'bitcoin:mainnet'] as const,\n    features: [],\n    publicKey: new Uint8Array([1, 2, 3]),\n    '~uiWalletHandle': null as unknown as UiWalletAccount['~uiWalletHandle'],\n} as const;\n\n// [DESCRIBE] useSignTransaction.\n{\n    // It accepts any chain in the solana namespace\n    useSignTransaction(mockWalletAccount, 'solana:danknet');\n    useSignTransaction(mockWalletAccount, 'solana:basednet');\n\n    // It accepts one of the chains actually supported by the wallet account\n    useSignTransaction(mockWalletAccount, 'solana:danknet');\n\n    // It rejects a chain in a non-Solana namespace\n    useSignTransaction(\n        mockWalletAccount,\n        // @ts-expect-error Non-Solana chain\n        'bitcoin:mainnet',\n    );\n}\n\n// [DESCRIBE] useSignTransactions.\n{\n    // It accepts any chain in the solana namespace\n    useSignTransactions(mockWalletAccount, 'solana:danknet');\n    useSignTransactions(mockWalletAccount, 'solana:basednet');\n\n    // It accepts one of the chains actually supported by the wallet account\n    const signTransactions = useSignTransactions(mockWalletAccount, 'solana:danknet');\n    signTransactions({ transaction: new Uint8Array() }, { transaction: new Uint8Array() }).catch(() => {});\n\n    // It rejects a chain in a non-Solana namespace\n    useSignTransactions(\n        mockWalletAccount,\n        // @ts-expect-error Non-Solana chain\n        'bitcoin:mainnet',\n    );\n}\n"
  },
  {
    "path": "packages/react/src/chain.ts",
    "content": "import { IdentifierArray } from '@wallet-standard/base';\n\ntype AssertSolanaChain<T> = T extends `solana:${string}` ? T : never;\n\nexport type OnlySolanaChains<T extends IdentifierArray> = T extends IdentifierArray\n    ? AssertSolanaChain<T[number]>\n    : never;\n"
  },
  {
    "path": "packages/react/src/index.ts",
    "content": "/**\n * This package contains React hooks for building Solana apps.\n *\n * @packageDocumentation\n */\nexport * from './useSignAndSendTransaction';\nexport * from './useSignIn';\nexport * from './useSignMessage';\nexport * from './useSignTransaction';\nexport * from './useWalletAccountMessageSigner';\nexport * from './useWalletAccountTransactionSigner';\nexport * from './useWalletAccountTransactionSendingSigner';\nexport * from './SelectedWalletAccountContextProvider';\nexport * from './selectedWalletAccountContext';\n"
  },
  {
    "path": "packages/react/src/selectedWalletAccountContext.ts",
    "content": "import { UiWallet, UiWalletAccount } from '@wallet-standard/react';\nimport React, { createContext } from 'react';\n\nexport type SelectedWalletAccountState = UiWalletAccount | undefined;\n\nexport type SelectedWalletAccountContextValue = readonly [\n    selectedWalletAccount: SelectedWalletAccountState,\n    setSelectedWalletAccount: React.Dispatch<React.SetStateAction<SelectedWalletAccountState>>,\n    filteredWallets: UiWallet[],\n];\n\nexport const SelectedWalletAccountContext = /*#__PURE__*/ createContext<SelectedWalletAccountContextValue>([\n    undefined,\n    () => {},\n    [],\n]);\n\nexport function useSelectedWalletAccount() {\n    const ctx = React.useContext(SelectedWalletAccountContext);\n    return ctx;\n}\n"
  },
  {
    "path": "packages/react/src/test-renderer.tsx",
    "content": "import React from 'react';\nimport { ErrorBoundary } from 'react-error-boundary';\nimport { act, create, ReactTestRenderer } from 'react-test-renderer';\n\ntype Result<T> =\n    | {\n          __type: 'error';\n          current: Error;\n          reset: () => void;\n      }\n    | {\n          __type: 'result';\n          current?: T;\n      };\n\ntype TestComponentProps<THookReturn> = {\n    executor(): THookReturn;\n    resultRef: Result<THookReturn>;\n};\n\nfunction TestComponentHookRenderer<THookFn extends (...args: never) => unknown>({\n    executor,\n    resultRef,\n}: TestComponentProps<ReturnType<THookFn>>) {\n    resultRef.current = executor();\n    return null;\n}\n\nfunction TestComponent<THookFn extends (...args: never) => unknown>({\n    executor,\n    resultRef,\n}: TestComponentProps<ReturnType<THookFn>>) {\n    return (\n        <ErrorBoundary\n            fallbackRender={({ error, resetErrorBoundary }) => {\n                resultRef.__type = 'error';\n                resultRef.current = error;\n                (resultRef as Extract<typeof resultRef, { __type: 'error' }>).reset = resetErrorBoundary;\n                return null;\n            }}\n            onReset={() => {\n                resultRef.__type = 'result';\n                delete resultRef.current;\n                // eslint-disable-next-line @typescript-eslint/no-explicit-any\n                delete (resultRef as any).reset;\n            }}\n        >\n            <TestComponentHookRenderer executor={executor} resultRef={resultRef} />\n        </ErrorBoundary>\n    );\n}\n\nexport function renderHook<THookReturn>(executor: () => THookReturn): {\n    rerenderHook(nextExecutor: () => THookReturn): void;\n    result: Readonly<Result<THookReturn>>;\n} {\n    const result = { __type: 'result' } as Result<THookReturn>;\n    let testRenderer: ReactTestRenderer;\n    void act(() => {\n        testRenderer = create(<TestComponent executor={executor} resultRef={result} />);\n    });\n    return {\n        rerenderHook(nextExecutor) {\n            void act(() => {\n                testRenderer.update(<TestComponent executor={nextExecutor} resultRef={result} />);\n            });\n        },\n        result,\n    };\n}\n"
  },
  {
    "path": "packages/react/src/useSignAndSendTransaction.ts",
    "content": "import {\n    SolanaSignAndSendTransaction,\n    SolanaSignAndSendTransactionFeature,\n    SolanaSignAndSendTransactionInput,\n    SolanaSignAndSendTransactionOutput,\n} from '@solana/wallet-standard-features';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport { getWalletAccountFeature, type UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\nimport { useCallback } from 'react';\n\nimport { OnlySolanaChains } from './chain';\n\ntype Input = Readonly<\n    Omit<SolanaSignAndSendTransactionInput, 'account' | 'chain' | 'options'> & {\n        options?: Readonly<{\n            minContextSlot?: bigint;\n        }>;\n    }\n>;\ntype Output = SolanaSignAndSendTransactionOutput;\n\n/**\n * Use this to get a function capable of signing a serialized transaction with the private key of a\n * {@link UiWalletAccount} and sending it to the network for processing.\n *\n * @param chain The identifier of the chain the transaction is destined for. Wallets may use this to\n * simulate the transaction for the user.\n *\n * @example\n * ```tsx\n * import { getBase58Decoder } from '@solana/codecs-strings';\n * import { useSignAndSendTransaction } from '@solana/react';\n *\n * function SignAndSendTransactionButton({ account, transactionBytes }) {\n *     const signAndSendTransaction = useSignAndSendTransaction(account, 'solana:devnet');\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const { signature } = await signAndSendTransaction({\n *                         transaction: transactionBytes,\n *                     });\n *                     const base58TransactionSignature = getBase58Decoder().decode(signature);\n *                     window.alert(\n *                         `View transaction: https://explorer.solana.com/tx/${base58TransactionSignature}?cluster=devnet`,\n *                     );\n *                 } catch (e) {\n *                     console.error('Failed to send transaction', e);\n *                 }\n *             }}\n *         >\n *             Sign and Send Transaction\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useSignAndSendTransaction<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: OnlySolanaChains<TWalletAccount['chains']>,\n): (input: Input) => Promise<Output>;\nexport function useSignAndSendTransaction<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): (input: Input) => Promise<Output>;\nexport function useSignAndSendTransaction<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): (input: Input) => Promise<Output> {\n    const signAndSendTransactions = useSignAndSendTransactions(uiWalletAccount, chain);\n    return useCallback(\n        async input => {\n            const [result] = await signAndSendTransactions(input);\n            return result;\n        },\n        [signAndSendTransactions],\n    );\n}\n\n/**\n * Use this to get a function capable of signing one or more serialized transactions with the private\n * key of a {@link UiWalletAccount} and sending them to the network for processing. This supports\n * wallets that allow batching multiple transactions in a single request.\n *\n * @example\n * ```tsx\n * import { useSignAndSendTransactions } from '@solana/react';\n *\n * function SignAndSendTransactionsButton({ account, transactionBytes1, transactionBytes2 }) {\n *     const signAndSendTransactions = useSignAndSendTransactions(account, 'solana:devnet');\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const [first, second] = await signAndSendTransactions(\n *                         { transaction: transactionBytes1 },\n *                         { transaction: transactionBytes2 },\n *                     );\n *                     window.alert(\n *                         `Transaction signatures: ${first.signature.toString()}, ${second.signature.toString()}`,\n *                     );\n *                 } catch (e) {\n *                     console.error('Failed to send transactions', e);\n *                 }\n *             }}\n *         >\n *             Sign and Send Transactions\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useSignAndSendTransactions<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: OnlySolanaChains<TWalletAccount['chains']>,\n): (...inputs: readonly Input[]) => Promise<readonly Output[]>;\nexport function useSignAndSendTransactions<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): (...inputs: readonly Input[]) => Promise<readonly Output[]>;\nexport function useSignAndSendTransactions<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): (...inputs: readonly Input[]) => Promise<readonly Output[]> {\n    if (!uiWalletAccount.chains.includes(chain)) {\n        throw new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n            address: uiWalletAccount.address,\n            chain,\n            featureName: SolanaSignAndSendTransaction,\n            supportedChains: [...uiWalletAccount.chains],\n            supportedFeatures: [...uiWalletAccount.features],\n        });\n    }\n    const signAndSendTransactionFeature = getWalletAccountFeature(\n        uiWalletAccount,\n        SolanaSignAndSendTransaction,\n    ) as SolanaSignAndSendTransactionFeature[typeof SolanaSignAndSendTransaction];\n    const account = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);\n    return useCallback(\n        async (...inputs) => {\n            if (inputs.length === 0) {\n                return [];\n            }\n            const inputsWithChainAndAccount = inputs.map(({ options, ...rest }) => {\n                const minContextSlot = options?.minContextSlot;\n                return {\n                    ...rest,\n                    account,\n                    chain,\n                    ...(minContextSlot != null\n                        ? {\n                              options: {\n                                  minContextSlot: Number(minContextSlot),\n                              },\n                          }\n                        : null),\n                };\n            });\n            const results = await signAndSendTransactionFeature.signAndSendTransaction(...inputsWithChainAndAccount);\n            return results;\n        },\n        [account, chain, signAndSendTransactionFeature],\n    );\n}\n"
  },
  {
    "path": "packages/react/src/useSignIn.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SolanaSignIn,\n    SolanaSignInFeature,\n    SolanaSignInInput,\n    SolanaSignInOutput,\n} from '@solana/wallet-standard-features';\nimport {\n    getWalletAccountFeature,\n    getWalletFeature,\n    UiWallet,\n    UiWalletAccount,\n    UiWalletHandle,\n} from '@wallet-standard/ui';\nimport {\n    getOrCreateUiWalletAccountForStandardWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n    getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n    getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,\n} from '@wallet-standard/ui-registry';\nimport { useCallback } from 'react';\n\ntype Input = SolanaSignInInput;\ntype Output = Omit<SolanaSignInOutput, 'account' | 'signatureType'> &\n    Readonly<{\n        account: UiWalletAccount;\n    }>;\n\n/**\n * Use the ['Sign In With Solana'](https://phantom.app/learn/developers/sign-in-with-solana) feature\n * of a {@link UiWallet} or {@link UiWalletAccount}.\n *\n * @returns A function that you can call to sign in with the particular wallet and address specified\n * by the supplied {@link UiWalletAccount}\n *\n * @example\n * ```tsx\n * import { useSignIn } from '@solana/react';\n *\n * function SignInButton({ wallet }) {\n *     const csrfToken = useCsrfToken();\n *     const signIn = useSignIn(wallet);\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const { account, signedMessage, signature } = await signIn({\n *                         requestId: csrfToken,\n *                     });\n *                     // Authenticate the user, typically on the server, by verifying that\n *                     // `signedMessage` was signed by the person who holds the private key for\n *                     // `account.publicKey`.\n *                     //\n *                     // Authorize the user, also on the server, by decoding `signedMessage` as the\n *                     // text of a Sign In With Solana message, verifying that it was not modified\n *                     // from the values your application expects, and that its content is sufficient\n *                     // to grant them access.\n *                     window.alert(`You are now signed in with the address ${account.address}`);\n *                 } catch (e) {\n *                     console.error('Failed to sign in', e);\n *                 }\n *             }}\n *         >\n *             Sign In\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useSignIn(uiWalletAccount: UiWalletAccount): (input?: Omit<Input, 'address'>) => Promise<Output>;\n/**\n * @returns A function that you can call to sign in with the supplied {@link UiWallet}\n */\nexport function useSignIn(uiWallet: UiWallet): (input?: Input) => Promise<Output>;\nexport function useSignIn(uiWalletHandle: UiWalletHandle): (input?: Input) => Promise<Output> {\n    const signIns = useSignIns(uiWalletHandle);\n    return useCallback(\n        async input => {\n            const [result] = await signIns(input);\n            return result;\n        },\n        [signIns],\n    );\n}\n\nfunction useSignIns(\n    uiWalletHandle: UiWalletHandle,\n): (...inputs: readonly (Input | undefined)[]) => Promise<readonly Output[]> {\n    let signMessageFeature: SolanaSignInFeature[typeof SolanaSignIn];\n    if ('address' in uiWalletHandle && typeof uiWalletHandle.address === 'string') {\n        getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletHandle as UiWalletAccount);\n        signMessageFeature = getWalletAccountFeature(\n            uiWalletHandle as UiWalletAccount,\n            SolanaSignIn,\n        ) as SolanaSignInFeature[typeof SolanaSignIn];\n    } else {\n        signMessageFeature = getWalletFeature(uiWalletHandle, SolanaSignIn) as SolanaSignInFeature[typeof SolanaSignIn];\n    }\n    const wallet = getWalletForHandle_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletHandle);\n    return useCallback(\n        async (...inputs) => {\n            const inputsWithAddressAndChainId = inputs.map(input => ({\n                ...input,\n                // Prioritize the `UiWalletAccount` address if it exists.\n                ...('address' in uiWalletHandle ? { address: uiWalletHandle.address as Address } : null),\n            }));\n            const results = await signMessageFeature.signIn(...inputsWithAddressAndChainId);\n            const resultsWithoutSignatureType = results.map(\n                ({\n                    account,\n                    signatureType: _, // Solana signatures are always of type `ed25519` so drop this property.\n                    ...rest\n                }) => ({\n                    ...rest,\n                    account: getOrCreateUiWalletAccountForStandardWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(\n                        wallet,\n                        account,\n                    ),\n                }),\n            );\n            return resultsWithoutSignatureType;\n        },\n        [signMessageFeature, uiWalletHandle, wallet],\n    );\n}\n"
  },
  {
    "path": "packages/react/src/useSignMessage.ts",
    "content": "import {\n    SolanaSignMessage,\n    SolanaSignMessageFeature,\n    SolanaSignMessageInput,\n    SolanaSignMessageOutput,\n} from '@solana/wallet-standard-features';\nimport { getWalletAccountFeature, UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\nimport { useCallback } from 'react';\n\ntype Input = Omit<SolanaSignMessageInput, 'account'>;\ntype Output = Omit<SolanaSignMessageOutput, 'signatureType'>;\n\n/**\n * Use this to get a function capable of signing a message with the private key of a\n * {@link UiWalletAccount}\n *\n * @example\n * ```tsx\n * import { useSignMessage } from '@solana/react';\n *\n * function SignMessageButton({ account, messageBytes }) {\n *     const signMessage = useSignMessage(account);\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const { signature } = await signMessage({\n *                         message: messageBytes,\n *                     });\n *                     window.alert(`Signature bytes: ${signature.toString()}`);\n *                 } catch (e) {\n *                     console.error('Failed to sign message', e);\n *                 }\n *             }}\n *         >\n *             Sign Message\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useSignMessage<TWalletAccount extends UiWalletAccount>(\n    ...config: Parameters<typeof useSignMessages<TWalletAccount>>\n): (input: Input) => Promise<Output> {\n    const signMessages = useSignMessages(...config);\n    return useCallback(\n        async input => {\n            const [result] = await signMessages(input);\n            return result;\n        },\n        [signMessages],\n    );\n}\n\nfunction useSignMessages<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n): (...inputs: readonly Input[]) => Promise<readonly Output[]> {\n    const signMessageFeature = getWalletAccountFeature(\n        uiWalletAccount,\n        SolanaSignMessage,\n    ) as SolanaSignMessageFeature[typeof SolanaSignMessage];\n    const account = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);\n    return useCallback(\n        async (...inputs) => {\n            const inputsWithAccount = inputs.map(input => ({ ...input, account }));\n            const results = await signMessageFeature.signMessage(...inputsWithAccount);\n            const resultsWithoutSignatureType = results.map(\n                ({\n                    signatureType: _, // Solana signatures are always of type `ed25519` so drop this property.\n                    ...rest\n                }) => rest,\n            );\n            return resultsWithoutSignatureType;\n        },\n        [signMessageFeature, account],\n    );\n}\n"
  },
  {
    "path": "packages/react/src/useSignTransaction.ts",
    "content": "import {\n    SolanaSignTransaction,\n    SolanaSignTransactionFeature,\n    SolanaSignTransactionInput,\n    SolanaSignTransactionOutput,\n} from '@solana/wallet-standard-features';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport { getWalletAccountFeature, UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\nimport { useCallback } from 'react';\n\nimport { OnlySolanaChains } from './chain';\n\ntype Input = Readonly<\n    Omit<SolanaSignTransactionInput, 'account' | 'chain' | 'options'> & {\n        options?: Readonly<{\n            minContextSlot?: bigint;\n        }>;\n    }\n>;\ntype Output = SolanaSignTransactionOutput;\n\n/**\n * Use this to get a function capable of signing a serialized transaction with the private key of a\n * {@link UiWalletAccount}\n *\n * @param chain The identifier of the chain the transaction is destined for. Wallets may use this to\n * simulate the transaction for the user.\n *\n * @example\n * ```tsx\n * import { useSignTransaction } from '@solana/react';\n *\n * function SignTransactionButton({ account, transactionBytes }) {\n *     const signTransaction = useSignTransaction(account, 'solana:devnet');\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const { signedTransaction } = await signTransaction({\n *                         transaction: transactionBytes,\n *                     });\n *                     window.alert(`Signed transaction bytes: ${signedTransaction.toString()}`);\n *                 } catch (e) {\n *                     console.error('Failed to sign transaction', e);\n *                 }\n *             }}\n *         >\n *             Sign Transaction\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useSignTransaction<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: OnlySolanaChains<TWalletAccount['chains']>,\n): (input: Input) => Promise<Output>;\nexport function useSignTransaction<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): (input: Input) => Promise<Output>;\nexport function useSignTransaction<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): (input: Input) => Promise<Output> {\n    const signTransactions = useSignTransactions(uiWalletAccount, chain);\n    return useCallback(\n        async input => {\n            const [result] = await signTransactions(input);\n            return result;\n        },\n        [signTransactions],\n    );\n}\n\n/**\n * Use this to get a function capable of signing one or more serialized transactions with the private\n * key of a {@link UiWalletAccount}. This supports batching multiple transactions in a single wallet\n * prompt when the wallet implementation allows it.\n *\n * @example\n * ```tsx\n * import { useSignTransactions } from '@solana/react';\n *\n * function SignTransactionsButton({ account, transactionBytes1, transactionBytes2 }) {\n *     const signTransactions = useSignTransactions(account, 'solana:devnet');\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const [first, second] = await signTransactions(\n *                         { transaction: transactionBytes1 },\n *                         { transaction: transactionBytes2 },\n *                     );\n *                     window.alert(\n *                         `First transaction bytes: ${first.signedTransaction.toString()}, second transaction bytes: ${second.signedTransaction.toString()}`,\n *                     );\n *                 } catch (e) {\n *                     console.error('Failed to sign transactions', e);\n *                 }\n *             }}\n *         >\n *             Sign Transactions\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useSignTransactions<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: OnlySolanaChains<TWalletAccount['chains']>,\n): (...inputs: readonly Input[]) => Promise<readonly Output[]>;\nexport function useSignTransactions<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): (...inputs: readonly Input[]) => Promise<readonly Output[]>;\nexport function useSignTransactions<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): (...inputs: readonly Input[]) => Promise<readonly Output[]> {\n    if (!uiWalletAccount.chains.includes(chain)) {\n        throw new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n            address: uiWalletAccount.address,\n            chain,\n            featureName: SolanaSignTransaction,\n            supportedChains: [...uiWalletAccount.chains],\n            supportedFeatures: [...uiWalletAccount.features],\n        });\n    }\n    const signTransactionFeature = getWalletAccountFeature(\n        uiWalletAccount,\n        SolanaSignTransaction,\n    ) as SolanaSignTransactionFeature[typeof SolanaSignTransaction];\n    const account = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);\n    return useCallback(\n        async (...inputs) => {\n            if (inputs.length === 0) {\n                return [];\n            }\n            const inputsWithAccountAndChain = inputs.map(({ options, ...rest }) => {\n                const minContextSlot = options?.minContextSlot;\n                return {\n                    ...rest,\n                    account,\n                    chain,\n                    ...(minContextSlot != null\n                        ? {\n                              options: {\n                                  minContextSlot: Number(minContextSlot),\n                              },\n                          }\n                        : null),\n                };\n            });\n            const results = await signTransactionFeature.signTransaction(...inputsWithAccountAndChain);\n            return results;\n        },\n        [signTransactionFeature, account, chain],\n    );\n}\n"
  },
  {
    "path": "packages/react/src/useWalletAccountMessageSigner.ts",
    "content": "import { Address, address } from '@solana/addresses';\nimport { bytesEqual } from '@solana/codecs-core';\nimport { SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getAbortablePromise } from '@solana/promises';\nimport { MessageModifyingSigner, SignableMessage } from '@solana/signers';\nimport type { UiWalletAccount } from '@wallet-standard/ui';\nimport { useMemo } from 'react';\n\nimport { useSignMessage } from './useSignMessage';\n\n/**\n * Use this to get a {@link MessageSigner} capable of signing messages with the private key of a\n * {@link UiWalletAccount}\n *\n * @returns A {@link MessageModifyingSigner}. This is a conservative assumption based on the fact\n * that your application can not control whether or not the wallet will modify the message before\n * signing it. Otherwise this method could more specifically return a {@link MessageSigner} or a\n * {@link MessagePartialSigner}.\n *\n * @example\n * ```tsx\n * import { useWalletAccountMessageSigner } from '@solana/react';\n * import { createSignableMessage } from '@solana/signers';\n *\n * function SignMessageButton({ account, text }) {\n *     const messageSigner = useWalletAccountMessageSigner(account);\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const signableMessage = createSignableMessage(text);\n *                     const [signedMessage] = await messageSigner.modifyAndSignMessages([signableMessage]);\n *                     const messageWasModified = signableMessage.content !== signedMessage.content;\n *                     const signatureBytes = signedMessage.signatures[messageSigner.address];\n *                     window.alert(\n *                         `Signature bytes: ${signatureBytes.toString()}${\n *                             messageWasModified ? ' (message was modified)' : ''\n *                         }`,\n *                     );\n *                 } catch (e) {\n *                     console.error('Failed to sign message', e);\n *                 }\n *             }}\n *         >\n *             Sign Message: {text}\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useWalletAccountMessageSigner<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n): MessageModifyingSigner<TWalletAccount['address']> {\n    const signMessage = useSignMessage(uiWalletAccount);\n    return useMemo(\n        () => ({\n            address: address(uiWalletAccount.address),\n            async modifyAndSignMessages(messages, config) {\n                config?.abortSignal?.throwIfAborted();\n                if (messages.length > 1) {\n                    throw new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);\n                }\n                if (messages.length === 0) {\n                    return messages;\n                }\n                const { content: originalMessage, signatures: originalSignatureMap } = messages[0];\n                const input = {\n                    message: originalMessage,\n                };\n                const { signedMessage, signature } = await getAbortablePromise(signMessage(input), config?.abortSignal);\n                const messageWasModified =\n                    originalMessage.length !== signedMessage.length ||\n                    originalMessage.some((originalByte, ii) => originalByte !== signedMessage[ii]);\n                const originalSignature = originalSignatureMap[uiWalletAccount.address as Address<string>] as\n                    | SignatureBytes\n                    | undefined;\n                const signatureIsNew = originalSignature === undefined || !bytesEqual(originalSignature, signature);\n                if (!signatureIsNew && !messageWasModified) {\n                    // We already had this exact signature, and the message wasn't modified.\n                    // Don't replace the existing message object.\n                    return messages;\n                }\n                const nextSignatureMap = messageWasModified\n                    ? { [uiWalletAccount.address]: signature }\n                    : { ...originalSignatureMap, [uiWalletAccount.address]: signature };\n                const outputMessages = Object.freeze([\n                    Object.freeze({\n                        content: signedMessage,\n                        signatures: Object.freeze(nextSignatureMap),\n                    }) as SignableMessage,\n                ]);\n                return outputMessages;\n            },\n        }),\n        [uiWalletAccount, signMessage],\n    );\n}\n"
  },
  {
    "path": "packages/react/src/useWalletAccountTransactionSendingSigner.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getAbortablePromise } from '@solana/promises';\nimport { TransactionSendingSigner } from '@solana/signers';\nimport { getTransactionEncoder } from '@solana/transactions';\nimport { UiWalletAccount } from '@wallet-standard/ui';\nimport { useMemo, useRef } from 'react';\n\nimport { OnlySolanaChains } from './chain';\nimport { useSignAndSendTransaction } from './useSignAndSendTransaction';\n\n/**\n * Use this to get a {@link TransactionSendingSigner} capable of signing a serialized transaction\n * with the private key of a {@link UiWalletAccount} and sending it to the network for processing.\n *\n * @param chain The identifier of the chain the transaction is destined for. Wallets may use this to\n * simulate the transaction for the user.\n *\n * @example\n * ```tsx\n * import { useWalletAccountTransactionSendingSigner } from '@solana/react';\n * import {\n *     appendTransactionMessageInstruction,\n *     createSolanaRpc,\n *     getBase58Decoder,\n *     pipe,\n *     setTransactionMessageFeePayerSigner,\n *     setTransactionMessageLifetimeUsingBlockhash,\n *     signAndSendTransactionMessageWithSigners,\n * } from '@solana/kit';\n *\n * function RecordMemoButton({ account, rpc, text }) {\n *     const signer = useWalletAccountTransactionSendingSigner(account, 'solana:devnet');\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const { value: latestBlockhash } = await createSolanaRpc('https://api.devnet.solana.com')\n *                         .getLatestBlockhash()\n *                         .send();\n *                     const message = pipe(\n *                         createTransactionMessage({ version: 'legacy' }),\n *                         m => setTransactionMessageFeePayerSigner(signer, m),\n *                         m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n *                         m => appendTransactionMessageInstruction(getAddMemoInstruction({ memo: text }), m),\n *                     );\n *                     const signatureBytes = await signAndSendTransactionMessageWithSigners(message);\n *                     const base58Signature = getBase58Decoder().decode(signature);\n *                     window.alert(`View transaction: https://explorer.solana.com/tx/${base58Signature}?cluster=devnet`);\n *                 } catch (e) {\n *                     console.error('Failed to record memo', e);\n *                 }\n *             }}\n *         >\n *             Record Memo\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useWalletAccountTransactionSendingSigner<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: OnlySolanaChains<TWalletAccount['chains']>,\n): TransactionSendingSigner<TWalletAccount['address']>;\nexport function useWalletAccountTransactionSendingSigner<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): TransactionSendingSigner<TWalletAccount['address']>;\nexport function useWalletAccountTransactionSendingSigner<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): TransactionSendingSigner<TWalletAccount['address']> {\n    const encoderRef = useRef<ReturnType<typeof getTransactionEncoder> | null>(null);\n    const signAndSendTransaction = useSignAndSendTransaction(uiWalletAccount, chain);\n    return useMemo(\n        () => ({\n            address: address(uiWalletAccount.address),\n            async signAndSendTransactions(transactions, config = {}) {\n                const { abortSignal, ...options } = config;\n                abortSignal?.throwIfAborted();\n                const transactionEncoder = (encoderRef.current ||= getTransactionEncoder());\n                if (transactions.length > 1) {\n                    throw new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);\n                }\n                if (transactions.length === 0) {\n                    return [];\n                }\n                const [transaction] = transactions;\n                const wireTransactionBytes = transactionEncoder.encode(transaction);\n                const inputWithOptions = {\n                    ...options,\n                    transaction: wireTransactionBytes as Uint8Array,\n                };\n                const { signature } = await getAbortablePromise(signAndSendTransaction(inputWithOptions), abortSignal);\n                return Object.freeze([signature as SignatureBytes]);\n            },\n        }),\n        [signAndSendTransaction, uiWalletAccount.address],\n    );\n}\n"
  },
  {
    "path": "packages/react/src/useWalletAccountTransactionSigner.ts",
    "content": "import { address } from '@solana/addresses';\nimport { bytesEqual } from '@solana/codecs-core';\nimport { SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED, SolanaError } from '@solana/errors';\nimport { getAbortablePromise } from '@solana/promises';\nimport { TransactionModifyingSigner } from '@solana/signers';\nimport { getCompiledTransactionMessageDecoder } from '@solana/transaction-messages';\nimport {\n    assertIsTransactionWithinSizeLimit,\n    getTransactionCodec,\n    getTransactionLifetimeConstraintFromCompiledTransactionMessage,\n    Transaction,\n    TransactionWithinSizeLimit,\n    TransactionWithLifetime,\n} from '@solana/transactions';\nimport { UiWalletAccount } from '@wallet-standard/ui';\nimport { useMemo, useRef } from 'react';\n\nimport { OnlySolanaChains } from './chain';\nimport { useSignTransaction } from './useSignTransaction';\n\n/**\n * Use this to get a {@link TransactionSigner} capable of signing serialized transactions with the\n * private key of a {@link UiWalletAccount}\n *\n * @returns A {@link TransactionModifyingSigner}. This is a conservative assumption based on the\n * fact that your application can not control whether or not the wallet will modify the transaction\n * before signing it (eg. to add guard instructions, or a priority fee budget). Otherwise this\n * method could more specifically return a {@link TransactionSigner} or a\n * {@link TransactionPartialSigner}.\n *\n * @example\n * ```tsx\n * import { useWalletAccountTransactionSigner } from '@solana/react';\n *\n * function SignTransactionButton({ account, transaction }) {\n *     const transactionSigner = useWalletAccountTransactionSigner(account, 'solana:devnet');\n *     return (\n *         <button\n *             onClick={async () => {\n *                 try {\n *                     const [{ signatures }] = await transactionSigner.modifyAndSignTransactions([transaction]);\n *                     const signatureBytes = signatures[transactionSigner.address];\n *                     window.alert(`Signature bytes: ${signatureBytes.toString()}`);\n *                 } catch (e) {\n *                     console.error('Failed to sign transaction', e);\n *                 }\n *             }}\n *         >\n *             Sign Transaction\n *         </button>\n *     );\n * }\n * ```\n */\nexport function useWalletAccountTransactionSigner<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: OnlySolanaChains<TWalletAccount['chains']>,\n): TransactionModifyingSigner<TWalletAccount['address']>;\nexport function useWalletAccountTransactionSigner<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): TransactionModifyingSigner<TWalletAccount['address']>;\nexport function useWalletAccountTransactionSigner<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: `solana:${string}`,\n): TransactionModifyingSigner<TWalletAccount['address']> {\n    const encoderRef = useRef<ReturnType<typeof getTransactionCodec> | null>(null);\n    const signTransaction = useSignTransaction(uiWalletAccount, chain);\n    return useMemo(\n        () => ({\n            address: address(uiWalletAccount.address),\n            async modifyAndSignTransactions(transactions, config = {}) {\n                const { abortSignal, ...options } = config;\n                abortSignal?.throwIfAborted();\n                const transactionCodec = (encoderRef.current ||= getTransactionCodec());\n                if (transactions.length > 1) {\n                    throw new SolanaError(SOLANA_ERROR__SIGNER__WALLET_MULTISIGN_UNIMPLEMENTED);\n                }\n                if (transactions.length === 0) {\n                    return transactions as readonly (Transaction &\n                        TransactionWithinSizeLimit &\n                        TransactionWithLifetime)[];\n                }\n                const [transaction] = transactions;\n                const wireTransactionBytes = transactionCodec.encode(transaction);\n                const inputWithOptions = {\n                    ...options,\n                    transaction: wireTransactionBytes as Uint8Array,\n                };\n                const { signedTransaction } = await getAbortablePromise(signTransaction(inputWithOptions), abortSignal);\n                const decodedSignedTransaction = transactionCodec.decode(\n                    signedTransaction,\n                ) as (typeof transactions)[number];\n\n                assertIsTransactionWithinSizeLimit(decodedSignedTransaction);\n\n                const existingLifetime =\n                    'lifetimeConstraint' in transaction\n                        ? (transaction as TransactionWithLifetime).lifetimeConstraint\n                        : undefined;\n\n                if (existingLifetime) {\n                    if (bytesEqual(decodedSignedTransaction.messageBytes, transaction.messageBytes)) {\n                        // If the transaction has identical bytes, the lifetime won't have changed\n                        return Object.freeze([\n                            {\n                                ...decodedSignedTransaction,\n                                lifetimeConstraint: existingLifetime,\n                            },\n                        ]);\n                    }\n\n                    // If the transaction has changed, check the lifetime constraint field\n                    const compiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(\n                        decodedSignedTransaction.messageBytes,\n                    );\n                    const currentToken =\n                        'blockhash' in existingLifetime ? existingLifetime.blockhash : existingLifetime.nonce;\n\n                    if (compiledTransactionMessage.lifetimeToken === currentToken) {\n                        return Object.freeze([\n                            {\n                                ...decodedSignedTransaction,\n                                lifetimeConstraint: existingLifetime,\n                            },\n                        ]);\n                    }\n                }\n\n                // If we get here then there is no existing lifetime, or the lifetime has changed. We need to attach a new lifetime\n                const compiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(\n                    decodedSignedTransaction.messageBytes,\n                );\n                const lifetimeConstraint =\n                    await getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage);\n                return Object.freeze([\n                    {\n                        ...decodedSignedTransaction,\n                        lifetimeConstraint,\n                    },\n                ]);\n            },\n        }),\n        [uiWalletAccount.address, signTransaction],\n    );\n}\n"
  },
  {
    "path": "packages/react/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/react/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"jsx\": \"react\",\n        \"lib\": [\"DOM\", \"ES2015\", \"ESNext.Promise\"]\n    },\n    \"display\": \"@solana/react\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"./eslint.config.mjs\", \"src\"]\n}\n"
  },
  {
    "path": "packages/react/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc/CHANGELOG.md",
    "content": "# @solana/rpc\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/errors@6.9.0\n    - @solana/rpc-api@6.9.0\n    - @solana/fast-stable-stringify@6.9.0\n    - @solana/functional@6.9.0\n    - @solana/rpc-spec-types@6.9.0\n    - @solana/rpc-spec@6.9.0\n    - @solana/rpc-transformers@6.9.0\n    - @solana/rpc-transport-http@6.9.0\n    - @solana/rpc-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n    - @solana/fast-stable-stringify@6.8.0\n    - @solana/functional@6.8.0\n    - @solana/rpc-api@6.8.0\n    - @solana/rpc-spec@6.8.0\n    - @solana/rpc-spec-types@6.8.0\n    - @solana/rpc-transformers@6.8.0\n    - @solana/rpc-transport-http@6.8.0\n    - @solana/rpc-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n    - @solana/fast-stable-stringify@6.7.0\n    - @solana/functional@6.7.0\n    - @solana/rpc-api@6.7.0\n    - @solana/rpc-spec@6.7.0\n    - @solana/rpc-spec-types@6.7.0\n    - @solana/rpc-transformers@6.7.0\n    - @solana/rpc-transport-http@6.7.0\n    - @solana/rpc-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/rpc-api@6.6.0\n    - @solana/rpc-spec@6.6.0\n    - @solana/rpc-transformers@6.6.0\n    - @solana/rpc-transport-http@6.6.0\n    - @solana/rpc-types@6.6.0\n    - @solana/fast-stable-stringify@6.6.0\n    - @solana/functional@6.6.0\n    - @solana/rpc-spec-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n    - @solana/fast-stable-stringify@6.5.0\n    - @solana/functional@6.5.0\n    - @solana/rpc-api@6.5.0\n    - @solana/rpc-spec@6.5.0\n    - @solana/rpc-spec-types@6.5.0\n    - @solana/rpc-transformers@6.5.0\n    - @solana/rpc-transport-http@6.5.0\n    - @solana/rpc-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-api@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/rpc-transformers@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/fast-stable-stringify@6.4.0\n    - @solana/functional@6.4.0\n    - @solana/rpc-spec@6.4.0\n    - @solana/rpc-spec-types@6.4.0\n    - @solana/rpc-transport-http@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n    - @solana/fast-stable-stringify@6.3.1\n    - @solana/functional@6.3.1\n    - @solana/rpc-api@6.3.1\n    - @solana/rpc-spec@6.3.1\n    - @solana/rpc-spec-types@6.3.1\n    - @solana/rpc-transformers@6.3.1\n    - @solana/rpc-transport-http@6.3.1\n    - @solana/rpc-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/rpc-api@6.3.0\n    - @solana/rpc-spec@6.3.0\n    - @solana/rpc-transformers@6.3.0\n    - @solana/rpc-transport-http@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/fast-stable-stringify@6.3.0\n    - @solana/functional@6.3.0\n    - @solana/rpc-spec-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/rpc-api@6.2.0\n    - @solana/rpc-spec@6.2.0\n    - @solana/rpc-transformers@6.2.0\n    - @solana/rpc-transport-http@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/fast-stable-stringify@6.2.0\n    - @solana/functional@6.2.0\n    - @solana/rpc-spec-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/rpc-api@6.1.0\n    - @solana/rpc-spec@6.1.0\n    - @solana/rpc-transformers@6.1.0\n    - @solana/rpc-transport-http@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/fast-stable-stringify@6.1.0\n    - @solana/functional@6.1.0\n    - @solana/rpc-spec-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-api@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/fast-stable-stringify@6.0.1\n    - @solana/functional@6.0.1\n    - @solana/rpc-spec@6.0.1\n    - @solana/rpc-spec-types@6.0.1\n    - @solana/rpc-transformers@6.0.1\n    - @solana/rpc-transport-http@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-api@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/fast-stable-stringify@6.0.0\n    - @solana/functional@6.0.0\n    - @solana/rpc-spec@6.0.0\n    - @solana/rpc-spec-types@6.0.0\n    - @solana/rpc-transformers@6.0.0\n    - @solana/rpc-transport-http@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/rpc-api@5.5.1\n    - @solana/rpc-spec@5.5.1\n    - @solana/rpc-transformers@5.5.1\n    - @solana/rpc-transport-http@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/fast-stable-stringify@5.5.1\n    - @solana/functional@5.5.1\n    - @solana/rpc-spec-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/rpc-api@5.5.0\n    - @solana/rpc-spec@5.5.0\n    - @solana/rpc-transformers@5.5.0\n    - @solana/rpc-transport-http@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/fast-stable-stringify@5.5.0\n    - @solana/functional@5.5.0\n    - @solana/rpc-spec-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/fast-stable-stringify@5.4.0\n    - @solana/rpc-transport-http@5.4.0\n    - @solana/rpc-transformers@5.4.0\n    - @solana/rpc-spec-types@5.4.0\n    - @solana/functional@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/rpc-spec@5.4.0\n    - @solana/rpc-api@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n    - @solana/fast-stable-stringify@5.3.0\n    - @solana/functional@5.3.0\n    - @solana/rpc-api@5.3.0\n    - @solana/rpc-spec@5.3.0\n    - @solana/rpc-spec-types@5.3.0\n    - @solana/rpc-transformers@5.3.0\n    - @solana/rpc-transport-http@5.3.0\n    - @solana/rpc-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n    - @solana/rpc-api@5.2.0\n    - @solana/rpc-spec@5.2.0\n    - @solana/rpc-transformers@5.2.0\n    - @solana/rpc-transport-http@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/fast-stable-stringify@5.2.0\n    - @solana/functional@5.2.0\n    - @solana/rpc-spec-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#1028](https://github.com/anza-xyz/kit/pull/1028) [`eb49ed7`](https://github.com/anza-xyz/kit/commit/eb49ed7dd45f2a5a0098b3de5ef482a813f8ad47) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a type `SolanaRpcApiFromClusterUrl`\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`c97df88`](https://github.com/anza-xyz/kit/commit/c97df8886948b281fff7d6b66429a59a9f7bdfa2), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n    - @solana/rpc-api@5.1.0\n    - @solana/rpc-spec@5.1.0\n    - @solana/rpc-transformers@5.1.0\n    - @solana/rpc-transport-http@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/fast-stable-stringify@5.1.0\n    - @solana/functional@5.1.0\n    - @solana/rpc-spec-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/rpc-api@5.0.0\n    - @solana/rpc-transformers@5.0.0\n    - @solana/rpc-spec@5.0.0\n    - @solana/rpc-transport-http@5.0.0\n    - @solana/fast-stable-stringify@5.0.0\n    - @solana/functional@5.0.0\n    - @solana/rpc-spec-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`05970df`](https://github.com/anza-xyz/kit/commit/05970dfc5706d739083d420b669ccac1266c570f), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-transport-http@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/rpc-api@4.0.0\n    - @solana/rpc-spec@4.0.0\n    - @solana/rpc-transformers@4.0.0\n    - @solana/fast-stable-stringify@4.0.0\n    - @solana/functional@4.0.0\n    - @solana/rpc-spec-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`81c83b1`](https://github.com/anza-xyz/kit/commit/81c83b12dd0e145bf7d08182e01824f2f14e5ee5)]:\n    - @solana/errors@3.0.0\n    - @solana/rpc-spec-types@3.0.0\n    - @solana/rpc-api@3.0.0\n    - @solana/rpc-spec@3.0.0\n    - @solana/rpc-transformers@3.0.0\n    - @solana/rpc-transport-http@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/fast-stable-stringify@3.0.0\n    - @solana/functional@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/rpc-spec@2.3.0\n    - @solana/rpc-api@2.3.0\n    - @solana/rpc-transformers@2.3.0\n    - @solana/rpc-transport-http@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/fast-stable-stringify@2.3.0\n    - @solana/functional@2.3.0\n    - @solana/rpc-spec-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.1\n    - @solana/fast-stable-stringify@2.2.1\n    - @solana/functional@2.2.1\n    - @solana/rpc-api@2.2.1\n    - @solana/rpc-spec@2.2.1\n    - @solana/rpc-spec-types@2.2.1\n    - @solana/rpc-transformers@2.2.1\n    - @solana/rpc-transport-http@2.2.1\n    - @solana/rpc-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-transformers@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/rpc-api@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/fast-stable-stringify@2.2.0\n    - @solana/functional@2.2.0\n    - @solana/rpc-spec@2.2.0\n    - @solana/rpc-spec-types@2.2.0\n    - @solana/rpc-transport-http@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2), [`7e7b2ef`](https://github.com/anza-xyz/kit/commit/7e7b2efebfd8de431e4381cc3d3fa117d3228030), [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-api@2.1.1\n    - @solana/rpc-transformers@2.1.1\n    - @solana/fast-stable-stringify@2.1.1\n    - @solana/rpc-transport-http@2.1.1\n    - @solana/rpc-spec-types@2.1.1\n    - @solana/functional@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/rpc-spec@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065) Thanks [@steveluscher](https://github.com/steveluscher)! - Disabled the `MaxListenersExceededWarning` in Node when creating event targets for internal use\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`3c25e7f`](https://github.com/anza-xyz/kit/commit/3c25e7f1a226ec92feaf1b21c702e65032059a42), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/rpc-api@2.1.0\n    - @solana/rpc-transport-http@2.1.0\n    - @solana/rpc-spec@2.1.0\n    - @solana/rpc-transformers@2.1.0\n    - @solana/fast-stable-stringify@2.1.0\n    - @solana/functional@2.1.0\n    - @solana/rpc-spec-types@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2910](https://github.com/solana-labs/solana-web3.js/pull/2910) [`42a70f4`](https://github.com/solana-labs/solana-web3.js/commit/42a70f4c3004e55fe6ce5a8e500f5610765ec66f) Thanks [@Jac0xb](https://github.com/Jac0xb)! - Fixed a bug where the RPC would fail to throw errors in the event that you configured it with an `AbortSignal`\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#2819](https://github.com/solana-labs/solana-web3.js/pull/2819) [`7ee47ae`](https://github.com/solana-labs/solana-web3.js/commit/7ee47ae24ad73b429ee863342f300a6f6c49e3d2) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug where coalesced RPC calls could end up aborted even though there were still interested consumers. This would happen if the consumer count fell to zero, then rose above zero again, in the same runloop.\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Change first argument of `onIntegerOverflow` handler from `methodName: string` to `request: RpcRequest`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- [#3340](https://github.com/solana-labs/solana-web3.js/pull/3340) [`44c8772`](https://github.com/solana-labs/solana-web3.js/commit/44c8772c8711b99e68dce3348e17bfc5b1d2a833) Thanks [@steveluscher](https://github.com/steveluscher)! - Enabled Brotli, gzip, and Deflate compression by default when running in Node.js, where compression headers are not added by the runtime like they are in browsers\n\n- [#2504](https://github.com/solana-labs/solana-web3.js/pull/2504) [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763) Thanks [@steveluscher](https://github.com/steveluscher)! - Replaced `fast-stable-stringify` with our fork\n\n- [#3148](https://github.com/solana-labs/solana-web3.js/pull/3148) [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcTransport` return new `RpcReponse` type instead of parsed JSON data\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`5ed19c6`](https://github.com/solana-labs/solana-web3.js/commit/5ed19c6c3c6e7a1bacde8c23c438ecb85454b126), [`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f), [`91fb1f3`](https://github.com/solana-labs/solana-web3.js/commit/91fb1f39bb174cf1e899a21365153a7b3bbf3571), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`daf9691`](https://github.com/solana-labs/solana-web3.js/commit/daf96918b2e875b60ab733acb0bd3f1b76a46c76), [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e), [`512853e`](https://github.com/solana-labs/solana-web3.js/commit/512853e5d0964075261913f9b2b08137116ce82e), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c), [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7), [`1fde4b1`](https://github.com/solana-labs/solana-web3.js/commit/1fde4b1d75c4af6d965ca26f6a7c649c6a517deb), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`bf07a60`](https://github.com/solana-labs/solana-web3.js/commit/bf07a606768eef7cd37c1dd0e2c0a35fe3b12f24), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`422f928`](https://github.com/solana-labs/solana-web3.js/commit/422f928086db5897522605243ac09148f9301fa1), [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c), [`02cefa7`](https://github.com/solana-labs/solana-web3.js/commit/02cefa7cc98463e602f78a8acc10d85c37f03481), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597), [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/fast-stable-stringify@2.0.0\n    - @solana/errors@2.0.0\n    - @solana/rpc-spec@2.0.0\n    - @solana/rpc-api@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/rpc-transport-http@2.0.0\n    - @solana/rpc-transformers@2.0.0\n    - @solana/rpc-spec-types@2.0.0\n    - @solana/functional@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/rpc-api@2.0.0-rc.4\n    - @solana/rpc-spec@2.0.0-rc.4\n    - @solana/rpc-transformers@2.0.0-rc.4\n    - @solana/rpc-transport-http@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/fast-stable-stringify@2.0.0-rc.4\n    - @solana/functional@2.0.0-rc.4\n    - @solana/rpc-spec-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-spec-types@2.0.0-rc.3\n    - @solana/rpc-spec@2.0.0-rc.3\n    - @solana/rpc-api@2.0.0-rc.3\n    - @solana/rpc-transformers@2.0.0-rc.3\n    - @solana/rpc-transport-http@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/fast-stable-stringify@2.0.0-rc.3\n    - @solana/functional@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Change first argument of `onIntegerOverflow` handler from `methodName: string` to `request: RpcRequest`\n\n- [#3340](https://github.com/solana-labs/solana-web3.js/pull/3340) [`44c8772`](https://github.com/solana-labs/solana-web3.js/commit/44c8772c8711b99e68dce3348e17bfc5b1d2a833) Thanks [@steveluscher](https://github.com/steveluscher)! - Enabled Brotli, gzip, and Deflate compression by default when running in Node.js, where compression headers are not added by the runtime like they are in browsers\n\n- [#3148](https://github.com/solana-labs/solana-web3.js/pull/3148) [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcTransport` return new `RpcReponse` type instead of parsed JSON data\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e), [`512853e`](https://github.com/solana-labs/solana-web3.js/commit/512853e5d0964075261913f9b2b08137116ce82e), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c), [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7), [`1fde4b1`](https://github.com/solana-labs/solana-web3.js/commit/1fde4b1d75c4af6d965ca26f6a7c649c6a517deb), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460), [`bf07a60`](https://github.com/solana-labs/solana-web3.js/commit/bf07a606768eef7cd37c1dd0e2c0a35fe3b12f24), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`422f928`](https://github.com/solana-labs/solana-web3.js/commit/422f928086db5897522605243ac09148f9301fa1), [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c), [`02cefa7`](https://github.com/solana-labs/solana-web3.js/commit/02cefa7cc98463e602f78a8acc10d85c37f03481), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/rpc-spec@2.0.0-rc.2\n    - @solana/rpc-transport-http@2.0.0-rc.2\n    - @solana/rpc-transformers@2.0.0-rc.2\n    - @solana/rpc-spec-types@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/rpc-api@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/fast-stable-stringify@2.0.0-rc.2\n    - @solana/functional@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-api@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/fast-stable-stringify@2.0.0-rc.1\n    - @solana/functional@2.0.0-rc.1\n    - @solana/rpc-spec@2.0.0-rc.1\n    - @solana/rpc-transformers@2.0.0-rc.1\n    - @solana/rpc-transport-http@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2910](https://github.com/solana-labs/solana-web3.js/pull/2910) [`42a70f4`](https://github.com/solana-labs/solana-web3.js/commit/42a70f4c3004e55fe6ce5a8e500f5610765ec66f) Thanks [@Jac0xb](https://github.com/Jac0xb)! - Fixed a bug where the RPC would fail to throw errors in the event that you configured it with an `AbortSignal`\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- Updated dependencies [[`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/rpc-transformers@2.0.0-rc.0\n    - @solana/rpc-spec@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/rpc-transport-http@2.0.0-rc.0\n    - @solana/rpc-api@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n    - @solana/fast-stable-stringify@2.0.0-rc.0\n    - @solana/functional@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2819](https://github.com/solana-labs/solana-web3.js/pull/2819) [`7ee47ae`](https://github.com/solana-labs/solana-web3.js/commit/7ee47ae24ad73b429ee863342f300a6f6c49e3d2) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug where coalesced RPC calls could end up aborted even though there were still interested consumers. This would happen if the consumer count fell to zero, then rose above zero again, in the same runloop.\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`91fb1f3`](https://github.com/solana-labs/solana-web3.js/commit/91fb1f39bb174cf1e899a21365153a7b3bbf3571), [`daf9691`](https://github.com/solana-labs/solana-web3.js/commit/daf96918b2e875b60ab733acb0bd3f1b76a46c76), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597)]:\n    - @solana/rpc-api@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/fast-stable-stringify@2.0.0-preview.4\n    - @solana/rpc-transport-http@2.0.0-preview.4\n    - @solana/rpc-transformers@2.0.0-preview.4\n    - @solana/functional@2.0.0-preview.4\n    - @solana/rpc-spec@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2504](https://github.com/solana-labs/solana-web3.js/pull/2504) [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763) Thanks [@steveluscher](https://github.com/steveluscher)! - Replaced `fast-stable-stringify` with our fork\n\n- Updated dependencies [[`5ed19c6`](https://github.com/solana-labs/solana-web3.js/commit/5ed19c6c3c6e7a1bacde8c23c438ecb85454b126), [`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4)]:\n    - @solana/fast-stable-stringify@2.0.0-preview.3\n    - @solana/errors@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/rpc-api@2.0.0-preview.3\n    - @solana/rpc-transformers@2.0.0-preview.3\n    - @solana/rpc-spec@2.0.0-preview.3\n    - @solana/rpc-transport-http@2.0.0-preview.3\n    - @solana/functional@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n    - @solana/functional@2.0.0-preview.2\n    - @solana/rpc-api@2.0.0-preview.2\n    - @solana/rpc-spec@2.0.0-preview.2\n    - @solana/rpc-transformers@2.0.0-preview.2\n    - @solana/rpc-transport-http@2.0.0-preview.2\n    - @solana/rpc-types@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc\n\n# @solana/rpc\n\nThis package contains utilities for creating objects that you can use to communicate with a Solana JSON RPC server. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nUnless you plan to create a custom RPC interface, you can use the [`createSolanaRpc(clusterUrl)`](#createsolanarpcclusterurl-config) function to obtain a default implementation of the [Solana JSON RPC API](https://solana.com/docs/rpc/http).\n\n## Types\n\n### `RpcTransport{Devnet|Testnet|Mainnet}`\n\nThese types refine the base `RpcTransport` type. Each describes a transport that is specific in some way to a particular Solana cluster.\n\nFor instance, a `RpcTransportDevnet` is understood to communicate with a RPC server related to devnet, and as such might only be accepted for use as the transport of a `RpcDevnet`.\n\nThis is useful in cases where you need to make assertions about what capabilities a RPC offers. For example, RPC methods like `requestAirdrop` are not available on mainnet. You can use the ability to assert on the type of RPC transport at compile time to prevent calling unimplemented methods or presuming the existence of unavailable capabilities.\n\n### `RpcTransportFromClusterUrl<TClusterUrl extends ClusterUrl>`\n\nGiven a `ClusterUrl`, this utility type will resolve to as specific a `RpcTransport` as possible.\n\n```ts\nfunction createCustomTransport<TClusterUrl extends ClusterUrl>(\n    clusterUrl: TClusterUrl,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n    /* ... */\n}\nconst transport = createCustomTransport(testnet('http://api.testnet.solana.com'));\ntransport satisfies RpcTransportTestnet; // OK\n```\n\n### `Rpc{Devnet|Testnet|Mainnet}<TRpcMethods>`\n\nThese types refine the base `Rpc` type. Each describes a RPC that is specific in some way to a particular Solana cluster and a corpus of RPC methods.\n\nThis is useful in cases where you need to make assertions about the suitability of a RPC for a given purpose. For example, you might like to make it a type error to combine certain types with RPCs belonging to certain clusters, at compile time.\n\n```ts\nasync function getSpecialAccountInfo(\n    address: Address<'ReAL1111111111111111111111111111'>,\n    rpc: RpcMainnet<unknown>,\n): Promise<SpecialAccountInfo>;\nasync function getSpecialAccountInfo(\n    address: Address<'TeST1111111111111111111111111111'>,\n    rpc: RpcDevnet<unknown> | RpcTestnet<unknown>,\n): Promise<SpecialAccountInfo>;\nasync function getSpecialAccountInfo(address: Address, rpc: Rpc<unknown>): Promise<SpecialAccountInfo> {\n    /* ... */\n}\nconst rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\nawait getSpecialAccountInfo(address('ReAL1111111111111111111111111111'), rpc); // ERROR\n```\n\n### `RpcFromTransport<TRpcMethods, TRpcTransport extends RpcTransport>`\n\nGiven a `RpcTransport` and a set of RPC methods denoted by `TRpcMethods` this utility type will resolve to a `Rpc` that supports those methods on as specific a cluster as possible.\n\n```ts\nfunction createCustomRpc<TRpcTransport extends RpcTransport>(\n    transport: TRpcTransport,\n): RpcFromTransport<MyCustomRpcMethods, TRpcTransport> {\n    /* ... */\n}\nconst transport = createDefaultRpcTransport({ url: mainnet('http://rpc.company') });\ntransport satisfies RpcTransportMainnet; // OK\nconst rpc = createCustomRpc(transport);\nrpc satisfies RpcMainnet<MyCustomRpcMethods>; // OK\n```\n\n### SolanaRpcApiFromTransport<TTransport extends RpcTransport>\n\nGiven a `RpcTransport` this utility type will resolve to a union of all the methods of the Solana RPC API supported by the transport's cluster.\n\n```ts\nfunction createSolanaRpcFromTransport<TTransport extends RpcTransport>(\n    transport: TTransport,\n): RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport> {\n    /* ... */\n}\nconst transport = createDefaultRpcTransport({ url: mainnet('http://rpc.company') });\ntransport satisfies RpcTransportMainnet; // OK\nconst rpc = createSolanaRpcFromTransport(transport);\nrpc satisfies RpcMainnet<SolanaRpcApiMainnet>; // OK\n```\n\n## Constants\n\n### `DEFAULT_RPC_CONFIG`\n\nWhen you create `Rpc` instances with custom transports but otherwise the default RPC API behaviours, use this.\n\n```ts\nconst myCustomRpc = createRpc({\n    api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n    transport: myCustomTransport,\n});\n```\n\n## Functions\n\n### `createDefaultRpcTransport(config)`\n\nCreates a `RpcTransport` with some default behaviours.\n\nThe default behaviours include:\n\n- An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n- Logic that coalesces multiple calls in the same runloop, for the same methods with the same arguments, into a single network request.\n- [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress responses\n\n#### Arguments\n\nA config object with the following properties:\n\n- `dispatcher_NODE_ONLY`: An optional `Undici.Dispatcher` instance that governs how the networking stack should behave. This option is only relevant in Node applications. Consult the documentation for the various subclasses of `Undici.Dispatcher`, such as `Agent`, `Client`, and `Pool`, at https://undici.nodejs.org/#/docs/api/Client.\n- `headers`: An optional object where the keys are HTTP header names and the values are HTTP header values. This parameter is typed to disallow certain headers from being overwritten.\n- `url`: A `ClusterUrl` at which the RPC server can be contacted.\n\n### `createSolanaRpc(clusterUrl, config)`\n\nCreates a `Rpc` instance that exposes the Solana JSON RPC API given a cluster URL and some optional transport config. See `createDefaultRpcTransport` for the shape of the transport config.\n\n### `createSolanaRpcFromTransport(transport)`\n\nCreates a `Rpc` instance that exposes the Solana JSON RPC API given the supplied `RpcTransport`.\n"
  },
  {
    "path": "packages/rpc/package.json",
    "content": "{\n    \"name\": \"@solana/rpc\",\n    \"version\": \"6.9.0\",\n    \"description\": \"A library for sending JSON RPC requests to Solana RPCs\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/fast-stable-stringify\": \"workspace:*\",\n        \"@solana/functional\": \"workspace:*\",\n        \"@solana/rpc-api\": \"workspace:*\",\n        \"@solana/rpc-spec\": \"workspace:*\",\n        \"@solana/rpc-spec-types\": \"workspace:*\",\n        \"@solana/rpc-transformers\": \"workspace:*\",\n        \"@solana/rpc-transport-http\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/event-target-impl\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc/src/__tests__/rpc-integer-overflow-error-test.ts",
    "content": "import { SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from '../rpc-integer-overflow-error';\n\ndescribe('createSolanaJsonRpcIntegerOverflowError()', () => {\n    it('creates a `SolanaError`', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [2 /* third argument */], 1n);\n        expect(error).toBeInstanceOf(SolanaError);\n    });\n    it('creates a `SolanaError` with the code `SOLANA_ERROR__RPC__INTEGER_OVERFLOW`', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [2 /* third argument */], 1n);\n        expect(error).toHaveProperty('context.__code', SOLANA_ERROR__RPC__INTEGER_OVERFLOW);\n    });\n    it('creates a `SolanaError` with the correct context for a path-less violation', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [2 /* third argument */], 1n);\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n                argumentLabel: '3rd',\n                keyPath: [2],\n                methodName: 'someMethod',\n                optionalPathLabel: '',\n                value: 1n,\n            }),\n        );\n    });\n    it('creates a `SolanaError` with the correct context for a violation with a deep path', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [0 /* first argument */, 'foo', 'bar'], 1n);\n        expect(error).toHaveProperty('context.optionalPathLabel', ' at path `foo.bar`');\n        expect(error).toHaveProperty('context.path', 'foo.bar');\n    });\n    it('omits the error factory function itself from the stack trace', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [0 /* first argument */, 'foo', 'bar'], 1n);\n        expect(error.stack).not.toMatch(/createSolanaJsonRpcIntegerOverflowError/);\n    });\n    it.each(\n        Object.entries({\n            ...(() => {\n                const out: Record<number, string> = {};\n                Array.from({ length: 100 }).forEach((_, ii) => {\n                    const lastDigit = ii % 10;\n                    // eslint-disable-next-line jest/no-conditional-in-test\n                    if (lastDigit === 0) {\n                        out[ii] = `${ii + 1}st`;\n                        // eslint-disable-next-line jest/no-conditional-in-test\n                    } else if (lastDigit === 1) {\n                        out[ii] = `${ii + 1}nd`;\n                        // eslint-disable-next-line jest/no-conditional-in-test\n                    } else if (lastDigit === 2) {\n                        out[ii] = `${ii + 1}rd`;\n                    } else {\n                        out[ii] = `${ii + 1}th`;\n                    }\n                });\n                return out;\n            })(),\n            10: '11th',\n            11: '12th',\n            12: '13th',\n        }),\n    )('computes the correct ordinal when crafting the argument label', (index, expectedLabel) => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [parseInt(index, 10)], 1n);\n        expect(error).toHaveProperty('context.argumentLabel', expectedLabel);\n    });\n});\n"
  },
  {
    "path": "packages/rpc/src/__tests__/rpc-integer-overflow-test.ts",
    "content": "import { SolanaError } from '@solana/errors';\nimport type { RpcTransport } from '@solana/rpc-spec';\n\nimport { createSolanaRpcFromTransport } from '../rpc';\n\ndescribe('RPC integer overflow behavior', () => {\n    let rpc: ReturnType<typeof createSolanaRpcFromTransport>;\n    beforeEach(() => {\n        const transport = jest.fn(\n            () =>\n                new Promise(_ => {\n                    /* never resolve */\n                }),\n        ) as RpcTransport;\n        rpc = createSolanaRpcFromTransport(transport);\n    });\n    it('does not throw when called with a value up to `Number.MAX_SAFE_INTEGER`', () => {\n        expect(() => {\n            rpc.getBlocks(BigInt(Number.MAX_SAFE_INTEGER));\n        }).not.toThrow();\n    });\n    it('does not throw when called with a value up to `-Number.MAX_SAFE_INTEGER`', () => {\n        expect(() => {\n            rpc.getBlocks(BigInt(-Number.MAX_SAFE_INTEGER));\n        }).not.toThrow();\n    });\n    it('throws when called with a value greater than `Number.MAX_SAFE_INTEGER`', () => {\n        expect(() => {\n            rpc.getBlocks(BigInt(Number.MAX_SAFE_INTEGER) + 1n);\n        }).toThrow(SolanaError);\n    });\n    it('throws when called with a value less than `-Number.MAX_SAFE_INTEGER`', () => {\n        expect(() => {\n            rpc.getBlocks(BigInt(-Number.MAX_SAFE_INTEGER) - 1n);\n        }).toThrow(SolanaError);\n    });\n});\n"
  },
  {
    "path": "packages/rpc/src/__tests__/rpc-request-coalescer-test.ts",
    "content": "import type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\nimport { getRpcTransportWithRequestCoalescing } from '../rpc-request-coalescer';\n\ndescribe('RPC request coalescer', () => {\n    let coalescedTransport: RpcTransport;\n    let hashFn: jest.MockedFunction<() => string | undefined>;\n    let mockTransport: jest.MockedFunction<RpcTransport>;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        hashFn = jest.fn();\n        mockTransport = jest.fn().mockResolvedValue(null);\n        coalescedTransport = getRpcTransportWithRequestCoalescing(mockTransport, hashFn);\n    });\n    describe('when requests produce the same hash', () => {\n        beforeEach(() => {\n            hashFn.mockReturnValue('samehash');\n        });\n        it('multiple requests in the same tick produce a single transport request', () => {\n            coalescedTransport({ payload: null }).catch(() => {});\n            coalescedTransport({ payload: null }).catch(() => {});\n            expect(mockTransport).toHaveBeenCalledTimes(1);\n        });\n        it('multiple requests in different ticks each produce their own transport request', () => {\n            expect.assertions(1);\n            coalescedTransport({ payload: null }).catch(() => {});\n            jest.runAllTicks();\n            coalescedTransport({ payload: null }).catch(() => {});\n            expect(mockTransport).toHaveBeenCalledTimes(2);\n        });\n        it('multiple requests in the same tick receive the same response', async () => {\n            expect.assertions(2);\n            const mockResponse = { response: 'ok' };\n            mockTransport.mockResolvedValueOnce(mockResponse);\n            const responsePromiseA = coalescedTransport({ payload: null });\n            const responsePromiseB = coalescedTransport({ payload: null });\n            await Promise.all([\n                expect(responsePromiseA).resolves.toBe(mockResponse),\n                expect(responsePromiseB).resolves.toBe(mockResponse),\n            ]);\n        });\n        it('multiple requests in different ticks receive different responses', async () => {\n            expect.assertions(2);\n            const mockResponseA = { response: 'okA' };\n            const mockResponseB = { response: 'okB' };\n            mockTransport.mockResolvedValueOnce(mockResponseA);\n            mockTransport.mockResolvedValueOnce(mockResponseB);\n            const responsePromiseA = coalescedTransport({ payload: null });\n            jest.runAllTicks();\n            const responsePromiseB = coalescedTransport({ payload: null });\n            await Promise.all([\n                expect(responsePromiseA).resolves.toBe(mockResponseA),\n                expect(responsePromiseB).resolves.toBe(mockResponseB),\n            ]);\n        });\n        it('multiple requests in the same tick receive the same error in the case of failure', async () => {\n            expect.assertions(2);\n            const mockError = { err: 'bad' };\n            mockTransport.mockRejectedValueOnce(mockError);\n            const responsePromiseA = coalescedTransport({ payload: null });\n            const responsePromiseB = coalescedTransport({ payload: null });\n            await Promise.all([\n                expect(responsePromiseA).rejects.toBe(mockError),\n                expect(responsePromiseB).rejects.toBe(mockError),\n            ]);\n        });\n        it('multiple requests in different ticks receive different errors in the case of failure', async () => {\n            expect.assertions(2);\n            const mockErrorA = { err: 'badA' };\n            const mockErrorB = { err: 'badB' };\n            mockTransport.mockRejectedValueOnce(mockErrorA);\n            mockTransport.mockRejectedValueOnce(mockErrorB);\n            const responsePromiseA = coalescedTransport({ payload: null });\n            // eslint-disable-next-line jest/valid-expect\n            const expectationA = expect(responsePromiseA).rejects.toBe(mockErrorA);\n            jest.runAllTicks();\n            const responsePromiseB = coalescedTransport({ payload: null });\n            // eslint-disable-next-line jest/valid-expect\n            const expectationB = expect(responsePromiseB).rejects.toBe(mockErrorB);\n            await Promise.all([expectationA, expectationB]);\n        });\n        it('does not abort the transport when the number of consumers increases, falls to zero, then increases again in the same runloop', () => {\n            expect.assertions(2);\n            const abortControllerA = new AbortController();\n            const abortControllerB = new AbortController();\n            coalescedTransport({ payload: null, signal: abortControllerA.signal }).catch(() => {});\n            coalescedTransport({ payload: null, signal: abortControllerB.signal }).catch(() => {});\n            // Both abort, bringing the consumer count to zero.\n            abortControllerA.abort('o no A');\n            abortControllerB.abort('o no B');\n            // New request comes in at the last moment before the end of the runloop.\n            coalescedTransport({ payload: null }).catch(() => {});\n            jest.runAllTicks();\n            expect(mockTransport).toHaveBeenCalledTimes(1);\n            const transportAbortSignal = mockTransport.mock.lastCall![0].signal!;\n            expect(transportAbortSignal.aborted).toBe(false);\n        });\n        describe('multiple coalesced requests each with an abort signal', () => {\n            let abortControllerA: AbortController;\n            let abortControllerB: AbortController;\n            let responsePromiseA: ReturnType<typeof mockTransport>;\n            let responsePromiseB: ReturnType<typeof mockTransport>;\n            let transportResponsePromise: (value: RpcResponse<unknown>) => void;\n            beforeEach(() => {\n                abortControllerA = new AbortController();\n                abortControllerB = new AbortController();\n                mockTransport.mockImplementation(async ({ signal }) => {\n                    signal?.throwIfAborted();\n                    return await new Promise((resolve, reject) => {\n                        transportResponsePromise = resolve;\n                        signal?.addEventListener('abort', (e: AbortSignalEventMap['abort']) => {\n                            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n                            reject((e.target as AbortSignal).reason);\n                        });\n                    });\n                });\n                responsePromiseA = coalescedTransport({ payload: null, signal: abortControllerA.signal });\n                responsePromiseB = coalescedTransport({ payload: null, signal: abortControllerB.signal });\n            });\n            afterEach(async () => {\n                try {\n                    // Unconditionally await the requests so that the tests don't leak.\n                    await Promise.all([responsePromiseA, responsePromiseB]);\n                } catch {\n                    /* empty */\n                }\n            });\n            it('throws an `AbortError` from the aborted request when no reason is specified', async () => {\n                expect.assertions(3);\n                abortControllerA.abort();\n                await expect(responsePromiseA).rejects.toThrow();\n                await expect(responsePromiseA).rejects.toBeInstanceOf(DOMException);\n                await expect(responsePromiseA).rejects.toHaveProperty('name', 'AbortError');\n            });\n            it(\"rejects from the aborted request with the `AbortSignal's` reason\", async () => {\n                expect.assertions(1);\n                abortControllerA.abort('o no');\n                await expect(responsePromiseA).rejects.toBe('o no');\n            });\n            it('aborts the transport at the end of the runloop when all of the requests abort', () => {\n                expect.assertions(1);\n                responsePromiseA.catch(() => {});\n                responsePromiseB.catch(() => {});\n                abortControllerA.abort('o no A');\n                abortControllerB.abort('o no B');\n                jest.runAllTicks();\n                const transportAbortSignal = mockTransport.mock.lastCall![0].signal!;\n                expect(transportAbortSignal.aborted).toBe(true);\n            });\n            it('does not abort the transport if fewer than every request aborts', () => {\n                expect.assertions(1);\n                abortControllerA.abort('o no A');\n                const transportAbortSignal = mockTransport.mock.lastCall![0].signal!;\n                expect(transportAbortSignal.aborted).toBe(false);\n            });\n            it('delivers responses to all but the aborted requests', async () => {\n                expect.assertions(2);\n                abortControllerA.abort('o no A');\n                const mockResponse = { response: 'ok' };\n                transportResponsePromise(mockResponse);\n                await Promise.all([\n                    expect(responsePromiseA).rejects.toBe('o no A'),\n                    expect(responsePromiseB).resolves.toBe(mockResponse),\n                ]);\n            });\n        });\n    });\n    [\n        {\n            getHashFn() {\n                let counter = 0;\n                return () => `hash-${counter++}`;\n            },\n            hashDescription: 'different hashes',\n        },\n        {\n            getHashFn() {\n                return () => undefined;\n            },\n            hashDescription: 'no hash',\n        },\n    ].forEach(({ hashDescription, getHashFn }) => {\n        describe(`when requests produce ${hashDescription}`, () => {\n            beforeEach(() => {\n                hashFn.mockImplementation(getHashFn());\n            });\n            it('multiple requests in the same tick produce one transport request each', () => {\n                coalescedTransport({ payload: null }).catch(() => {});\n                coalescedTransport({ payload: null }).catch(() => {});\n                expect(mockTransport).toHaveBeenCalledTimes(2);\n            });\n            it('multiple requests in the same tick receive different responses', async () => {\n                expect.assertions(2);\n                const mockResponseA = { response: 'okA' };\n                const mockResponseB = { response: 'okB' };\n                mockTransport.mockResolvedValueOnce(mockResponseA);\n                mockTransport.mockResolvedValueOnce(mockResponseB);\n                const responsePromiseA = coalescedTransport({ payload: null });\n                const responsePromiseB = coalescedTransport({ payload: null });\n                await Promise.all([\n                    expect(responsePromiseA).resolves.toBe(mockResponseA),\n                    expect(responsePromiseB).resolves.toBe(mockResponseB),\n                ]);\n            });\n            it('multiple requests in the same tick receive different errors in the case of failure', async () => {\n                expect.assertions(2);\n                const mockErrorA = { err: 'badA' };\n                const mockErrorB = { err: 'badB' };\n                mockTransport.mockRejectedValueOnce(mockErrorA);\n                mockTransport.mockRejectedValueOnce(mockErrorB);\n                const responsePromiseA = coalescedTransport({ payload: null });\n                const responsePromiseB = coalescedTransport({ payload: null });\n                await Promise.all([\n                    expect(responsePromiseA).rejects.toBe(mockErrorA),\n                    expect(responsePromiseB).rejects.toBe(mockErrorB),\n                ]);\n            });\n        });\n    });\n    // https://github.com/solana-labs/solana-web3.js/pull/2910\n    describe('regression test #2910', () => {\n        beforeEach(() => {\n            // Necessary to prevent the coalescer from bailing out.\n            hashFn.mockReturnValue('samehash');\n        });\n        it('throws an error in the case of failure, if it was not configured with an `AbortSignal`', async () => {\n            expect.assertions(1);\n            const mockError = { err: 'bad' };\n            mockTransport.mockRejectedValueOnce(mockError);\n            await expect(coalescedTransport({ payload: null })).rejects.toBe(mockError);\n        });\n        it('throws an error in the case of failure, if it was configured with an `AbortSignal`', async () => {\n            expect.assertions(1);\n            const mockError = { err: 'bad' };\n            mockTransport.mockRejectedValueOnce(mockError);\n            await expect(coalescedTransport({ payload: null, signal: new AbortController().signal })).rejects.toBe(\n                mockError,\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc/src/__tests__/rpc-request-deduplication-test.ts",
    "content": "import { getSolanaRpcPayloadDeduplicationKey } from '../rpc-request-deduplication';\n\ndescribe('getSolanaRpcPayloadDeduplicationKey', () => {\n    it('produces no key for undefined payloads', () => {\n        expect(getSolanaRpcPayloadDeduplicationKey(undefined)).toBeUndefined();\n    });\n    it('produces no key for null payloads', () => {\n        expect(getSolanaRpcPayloadDeduplicationKey(null)).toBeUndefined();\n    });\n    it('produces no key for array payloads', () => {\n        expect(getSolanaRpcPayloadDeduplicationKey([])).toBeUndefined();\n    });\n    it('produces no key for string payloads', () => {\n        expect(getSolanaRpcPayloadDeduplicationKey('o hai')).toBeUndefined();\n    });\n    it('produces no key for numeric payloads', () => {\n        expect(getSolanaRpcPayloadDeduplicationKey(123)).toBeUndefined();\n    });\n    it('produces no key for bigint payloads', () => {\n        expect(getSolanaRpcPayloadDeduplicationKey(123n)).toBeUndefined();\n    });\n    it('produces no key for object payloads that are not JSON-RPC payloads', () => {\n        expect(getSolanaRpcPayloadDeduplicationKey({})).toBeUndefined();\n    });\n    it('produces a key for a JSON-RPC payload', () => {\n        expect(\n            getSolanaRpcPayloadDeduplicationKey({\n                id: 1,\n                jsonrpc: '2.0',\n                method: 'getFoo',\n                params: 'foo',\n            }),\n        ).toMatchInlineSnapshot(`\"[\"getFoo\",\"foo\"]\"`);\n    });\n    it('produces identical keys for two materially identical JSON-RPC payloads', () => {\n        expect(\n            getSolanaRpcPayloadDeduplicationKey({\n                id: 1,\n                jsonrpc: '2.0',\n                method: 'getFoo',\n                params: { a: 1, b: { c: [2, 3], d: 4 } },\n            }),\n        ).toEqual(\n            /* eslint-disable sort-keys-fix/sort-keys-fix */\n            getSolanaRpcPayloadDeduplicationKey({\n                jsonrpc: '2.0',\n                method: 'getFoo',\n                params: { b: { d: 4, c: [2, 3] }, a: 1 },\n                id: 2,\n            }),\n            /* eslint-enable sort-keys-fix/sort-keys-fix */\n        );\n    });\n});\n"
  },
  {
    "path": "packages/rpc/src/__tests__/rpc-transport-header-config-test.ts",
    "content": "import { createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\n\nimport { createDefaultRpcTransport } from '../rpc-transport';\n\njest.mock('@solana/rpc-transport-http');\n\ndescribe('createDefaultRpcTransport', () => {\n    if (__NODEJS__) {\n        it('adds default compression headers', () => {\n            createDefaultRpcTransport({ url: 'fake://url' });\n            expect(createHttpTransportForSolanaRpc).toHaveBeenCalledWith(\n                expect.objectContaining({\n                    headers: expect.objectContaining({\n                        'accept-encoding': 'br,gzip,deflate',\n                    }),\n                }),\n            );\n        });\n        it('allows the override of the default compression headers', () => {\n            createDefaultRpcTransport({\n                headers: { 'aCcEpT-eNcOdInG': 'zstd' },\n                url: 'fake://url',\n            });\n            expect(createHttpTransportForSolanaRpc).toHaveBeenCalledWith(\n                expect.objectContaining({\n                    headers: expect.objectContaining({\n                        'accept-encoding': 'zstd',\n                    }),\n                }),\n            );\n        });\n    }\n    it('adds configured headers to each request with downcased property names', () => {\n        createDefaultRpcTransport({\n            headers: { aUtHoRiZaTiOn: 'Picard, 4 7 Alpha Tango' },\n            url: 'fake://url',\n        });\n        expect(createHttpTransportForSolanaRpc).toHaveBeenCalledWith(\n            expect.objectContaining({\n                headers: expect.objectContaining({\n                    authorization: 'Picard, 4 7 Alpha Tango',\n                }),\n            }),\n        );\n    });\n    it('adds a `solana-client` header with the current NPM package version by default', () => {\n        createDefaultRpcTransport({ url: 'fake://url' });\n        expect(createHttpTransportForSolanaRpc).toHaveBeenCalledWith(\n            expect.objectContaining({\n                headers: expect.objectContaining({\n                    // Version is defined in `setup-define-version-constant.ts`\n                    'solana-client': `js/0.0.0-test`,\n                }),\n            }),\n        );\n    });\n    it('makes it impossible to override the `solana-client` header', () => {\n        createDefaultRpcTransport({\n            headers: { 'sOlAnA-cLiEnT': 'fakeversion' },\n            url: 'fake://url',\n        });\n        expect(createHttpTransportForSolanaRpc).toHaveBeenCalledWith(\n            expect.objectContaining({\n                headers: expect.objectContaining({\n                    // Version is defined in `setup-define-version-constant.ts`\n                    'solana-client': `js/0.0.0-test`,\n                }),\n            }),\n        );\n        expect(createHttpTransportForSolanaRpc).toHaveBeenCalledWith(\n            expect.objectContaining({\n                headers: expect.not.objectContaining({\n                    'sOlAnA-cLiEnT': 'fakeversion',\n                }),\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/rpc/src/__typetests__/rpc-clusters-typetest.ts",
    "content": "import type { SolanaRpcApi, SolanaRpcApiDevnet, SolanaRpcApiMainnet, SolanaRpcApiTestnet } from '@solana/rpc-api';\nimport type { Rpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl, devnet, DevnetUrl, mainnet, MainnetUrl, testnet, TestnetUrl } from '@solana/rpc-types';\n\nimport { createSolanaRpc, createSolanaRpcFromTransport } from '../rpc';\nimport type {\n    RpcDevnet,\n    RpcMainnet,\n    RpcTestnet,\n    RpcTransportDevnet,\n    RpcTransportMainnet,\n    RpcTransportTestnet,\n    SolanaRpcApiFromClusterUrl,\n} from '../rpc-clusters';\nimport { createDefaultRpcTransport } from '../rpc-transport';\n\n// Define cluster-aware URLs and transports.\n\nconst genericUrl = 'http://localhost:8899';\nconst devnetUrl = devnet('https://api.devnet.solana.com');\nconst testnetUrl = testnet('https://api.testnet.solana.com');\nconst mainnetUrl = mainnet('https://api.mainnet-beta.solana.com');\n\nconst genericTransport = createDefaultRpcTransport({ url: genericUrl });\nconst devnetTransport = createDefaultRpcTransport({ url: devnetUrl });\nconst testnetTransport = createDefaultRpcTransport({ url: testnetUrl });\nconst mainnetTransport = createDefaultRpcTransport({ url: mainnetUrl });\n\n// [DESCRIBE] createDefaultRpcTransport.\n{\n    // No cluster specified should be generic `RpcTransport`.\n    {\n        genericTransport satisfies RpcTransport;\n        //@ts-expect-error Should not be a devnet transport\n        genericTransport satisfies RpcTransportDevnet;\n        //@ts-expect-error Should not be a testnet transport\n        genericTransport satisfies RpcTransportTestnet;\n        //@ts-expect-error Should not be a mainnet transport\n        genericTransport satisfies RpcTransportMainnet;\n    }\n\n    // Devnet cluster should be `RpcTransportDevnet`.\n    {\n        devnetTransport satisfies RpcTransportDevnet;\n        //@ts-expect-error Should not be a testnet transport\n        devnetTransport satisfies RpcTransportTestnet;\n        //@ts-expect-error Should not be a mainnet transport\n        devnetTransport satisfies RpcTransportMainnet;\n    }\n\n    // Testnet cluster should be `RpcTransportTestnet`.\n    {\n        testnetTransport satisfies RpcTransportTestnet;\n        //@ts-expect-error Should not be a devnet transport\n        testnetTransport satisfies RpcTransportDevnet;\n        //@ts-expect-error Should not be a mainnet transport\n        testnetTransport satisfies RpcTransportMainnet;\n    }\n\n    // Mainnet cluster should be `RpcTransportMainnet`.\n    {\n        mainnetTransport satisfies RpcTransportMainnet;\n        //@ts-expect-error Should not be a devnet transport\n        mainnetTransport satisfies RpcTransportDevnet;\n        //@ts-expect-error Should not be a testnet transport\n        mainnetTransport satisfies RpcTransportTestnet;\n    }\n}\n\n// [DESCRIBE] createSolanaRpcFromTransport.\n{\n    const genericRpc = createSolanaRpcFromTransport(genericTransport);\n    const devnetRpc = createSolanaRpcFromTransport(devnetTransport);\n    const testnetRpc = createSolanaRpcFromTransport(testnetTransport);\n    const mainnetRpc = createSolanaRpcFromTransport(mainnetTransport);\n\n    // No cluster specified should be generic `Rpc`.\n    {\n        genericRpc satisfies Rpc<SolanaRpcApi>;\n        //@ts-expect-error Should not be a devnet RPC\n        genericRpc satisfies RpcDevnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a testnet RPC\n        genericRpc satisfies RpcTestnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a mainnet RPC\n        genericRpc satisfies RpcMainnet<SolanaRpcApi>;\n    }\n\n    // Devnet cluster should be `RpcDevnet`.\n    {\n        devnetRpc satisfies Rpc<SolanaRpcApi>;\n        devnetRpc satisfies Rpc<SolanaRpcApiDevnet>;\n        devnetRpc satisfies RpcDevnet<SolanaRpcApi>;\n        devnetRpc satisfies RpcDevnet<SolanaRpcApiDevnet>; // Same types\n        //@ts-expect-error Should not be a testnet RPC\n        devnetRpc satisfies RpcTestnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a mainnet RPC\n        devnetRpc satisfies RpcMainnet<SolanaRpcApi>;\n    }\n\n    // Testnet cluster should be `RpcTestnet`.\n    {\n        testnetRpc satisfies Rpc<SolanaRpcApi>;\n        testnetRpc satisfies Rpc<SolanaRpcApiTestnet>;\n        testnetRpc satisfies RpcTestnet<SolanaRpcApi>;\n        testnetRpc satisfies RpcTestnet<SolanaRpcApiTestnet>; // Same types\n        //@ts-expect-error Should not be a devnet RPC\n        testnetRpc satisfies RpcDevnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a mainnet RPC\n        testnetRpc satisfies RpcMainnet<SolanaRpcApi>;\n    }\n\n    // Mainnet cluster should be `RpcMainnet`.\n    {\n        mainnetRpc satisfies Rpc<SolanaRpcApiMainnet>;\n        mainnetRpc satisfies RpcMainnet<SolanaRpcApiMainnet>;\n        //@ts-expect-error Should not have `requestAirdrop` method\n        mainnetRpc satisfies Rpc<RequestAirdropApi>;\n        //@ts-expect-error Should not be a devnet RPC\n        mainnetRpc satisfies RpcDevnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a testnet RPC\n        mainnetRpc satisfies RpcTestnet<SolanaRpcApi>;\n    }\n}\n\n// [DESCRIBE] createSolanaRpc.\n{\n    const genericRpc = createSolanaRpc(genericUrl);\n    const devnetRpc = createSolanaRpc(devnetUrl);\n    const testnetRpc = createSolanaRpc(testnetUrl);\n    const mainnetRpc = createSolanaRpc(mainnetUrl);\n\n    // No cluster specified should be generic `Rpc`.\n    {\n        genericRpc satisfies Rpc<SolanaRpcApi>;\n        //@ts-expect-error Should not be a devnet RPC\n        genericRpc satisfies RpcDevnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a testnet RPC\n        genericRpc satisfies RpcTestnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a mainnet RPC\n        genericRpc satisfies RpcMainnet<SolanaRpcApi>;\n    }\n\n    // Devnet cluster should be `RpcDevnet`.\n    {\n        devnetRpc satisfies Rpc<SolanaRpcApi>;\n        devnetRpc satisfies Rpc<SolanaRpcApiDevnet>;\n        devnetRpc satisfies RpcDevnet<SolanaRpcApi>;\n        devnetRpc satisfies RpcDevnet<SolanaRpcApiDevnet>; // Same types\n        //@ts-expect-error Should not be a testnet RPC\n        devnetRpc satisfies RpcTestnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a mainnet RPC\n        devnetRpc satisfies RpcMainnet<SolanaRpcApi>;\n    }\n\n    // Testnet cluster should be `RpcTestnet`.\n    {\n        testnetRpc satisfies Rpc<SolanaRpcApi>;\n        testnetRpc satisfies Rpc<SolanaRpcApiTestnet>;\n        testnetRpc satisfies RpcTestnet<SolanaRpcApi>;\n        testnetRpc satisfies RpcTestnet<SolanaRpcApiTestnet>; // Same types\n        //@ts-expect-error Should not be a devnet RPC\n        testnetRpc satisfies RpcDevnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a mainnet RPC\n        testnetRpc satisfies RpcMainnet<SolanaRpcApi>;\n    }\n\n    // Mainnet cluster should be `RpcMainnet`.\n    {\n        mainnetRpc satisfies Rpc<SolanaRpcApiMainnet>;\n        mainnetRpc satisfies RpcMainnet<SolanaRpcApiMainnet>;\n        //@ts-expect-error Should not have `requestAirdrop` method\n        mainnetRpc satisfies Rpc<RequestAirdropApi>;\n        //@ts-expect-error Should not be a devnet RPC\n        mainnetRpc satisfies RpcDevnet<SolanaRpcApi>;\n        //@ts-expect-error Should not be a testnet RPC\n        mainnetRpc satisfies RpcTestnet<SolanaRpcApi>;\n    }\n}\n\n// [DESCRIBE] SolanaRpcApiFromClusterUrl\n{\n    const genericRpcApi = null as unknown as SolanaRpcApiFromClusterUrl<ClusterUrl>;\n    const devnetRpcApi = null as unknown as SolanaRpcApiFromClusterUrl<DevnetUrl>;\n    const testnetRpcApi = null as unknown as SolanaRpcApiFromClusterUrl<TestnetUrl>;\n    const mainnetRpcApi = null as unknown as SolanaRpcApiFromClusterUrl<MainnetUrl>;\n\n    // No cluster specified should be the most restricted `SolanaRpcApi`, ie Mainnet.\n    {\n        genericRpcApi satisfies SolanaRpcApiMainnet;\n        //@ts-expect-error Should not be `SolanaRpcApiDevnet`\n        genericRpcApi satisfies SolanaRpcApiDevnet;\n        //@ts-expect-error Should not be `SolanaRpcApiTestnet`\n        genericRpcApi satisfies SolanaRpcApiTestnet;\n        //@ts-expect-error Should not be `SolanaRpcApi`\n        genericRpcApi satisfies SolanaRpcApi;\n    }\n\n    // Devnet cluster should be `SolanaRpcApiDevnet`.\n    {\n        devnetRpcApi satisfies SolanaRpcApiDevnet;\n        devnetRpcApi satisfies SolanaRpcApi;\n    }\n\n    // Testnet cluster should be `SolanaRpcApiTestnet`.\n    {\n        testnetRpcApi satisfies SolanaRpcApiTestnet;\n        testnetRpcApi satisfies SolanaRpcApi;\n    }\n\n    // Mainnet cluster should be `SolanaRpcApiMainnet`.\n    {\n        mainnetRpcApi satisfies SolanaRpcApiMainnet;\n        //@ts-expect-error Should not be `SolanaRpcApiDevnet`\n        mainnetRpcApi satisfies SolanaRpcApiDevnet;\n        //@ts-expect-error Should not be `SolanaRpcApiTestnet`\n        mainnetRpcApi satisfies SolanaRpcApiTestnet;\n        //@ts-expect-error Should not be `SolanaRpcApi`\n        mainnetRpcApi satisfies SolanaRpcApi;\n    }\n}\n"
  },
  {
    "path": "packages/rpc/src/index.ts",
    "content": "/**\n * This package contains utilities for creating objects that you can use to communicate with a\n * Solana JSON RPC server. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * Unless you plan to create a custom RPC interface, you can use the\n * {@link createSolanaRpc} function to obtain a default implementation of the\n * [Solana JSON RPC API](https://solana.com/docs/rpc/http).\n *\n * @packageDocumentation\n */\nexport * from '@solana/rpc-api';\nexport * from '@solana/rpc-spec';\n\nexport * from './rpc';\nexport * from './rpc-default-config';\nexport * from './rpc-clusters';\nexport * from './rpc-transport';\n"
  },
  {
    "path": "packages/rpc/src/rpc-clusters.ts",
    "content": "import type { SolanaRpcApi, SolanaRpcApiDevnet, SolanaRpcApiMainnet, SolanaRpcApiTestnet } from '@solana/rpc-api';\nimport type { Rpc, RpcTransport } from '@solana/rpc-spec';\nimport { type ClusterUrl, type DevnetUrl, type MainnetUrl, type TestnetUrl } from '@solana/rpc-types';\n\n/**\n * A {@link RpcTransport} that communicates with the devnet cluster.\n *\n * Such transports are understood to communicate with a RPC server that services devnet, and as such\n * might only be accepted for use as the transport of a {@link RpcDevnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * For example, RPC methods like {@link requestAirdrop} are not available on mainnet. You can use\n * the ability to assert on the type of RPC transport at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable capabilities.\n */\nexport type RpcTransportDevnet = RpcTransport & { '~cluster': 'devnet' };\n/**\n * A {@link RpcTransport} that communicates with the testnet cluster.\n *\n * Such transports are understood to communicate with a RPC server that services testnet, and as\n * such  might only be accepted for use as the transport of a {@link RpcTestnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * For example, RPC methods like {@link requestAirdrop} are not available on mainnet. You can use\n * the ability to assert on the type of RPC transport at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable capabilities.\n */\nexport type RpcTransportTestnet = RpcTransport & { '~cluster': 'testnet' };\n/**\n * A {@link RpcTransport} that communicates with the mainnet cluster.\n *\n * Such transports are understood to communicate with a RPC server that services mainnet, and as\n * such might only be accepted for use as the transport of a {@link RpcMainnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * For example, RPC methods like {@link requestAirdrop} are not available on mainnet. You can use\n * the ability to assert on the type of RPC transport at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable capabilities.\n */\nexport type RpcTransportMainnet = RpcTransport & { '~cluster': 'mainnet' };\n/**\n * Given a {@link ClusterUrl}, this utility type will resolve to as specific a {@link RpcTransport}\n * as possible.\n *\n * @example\n * ```ts\n * function createCustomTransport<TClusterUrl extends ClusterUrl>(\n *     clusterUrl: TClusterUrl,\n * ): RpcTransportFromClusterUrl<TClusterUrl> {\n *     /* ... *\\/\n * }\n *\n * const transport = createCustomTransport(testnet('http://api.testnet.solana.com'));\n * transport satisfies RpcTransportTestnet; // OK\n * ```\n */\nexport type RpcTransportFromClusterUrl<TClusterUrl extends ClusterUrl> = TClusterUrl extends DevnetUrl\n    ? RpcTransportDevnet\n    : TClusterUrl extends TestnetUrl\n      ? RpcTransportTestnet\n      : TClusterUrl extends MainnetUrl\n        ? RpcTransportMainnet\n        : RpcTransport;\n/**\n * A {@link Rpc} that supports the RPC methods available on the devnet cluster.\n *\n * This is useful in cases where you need to make assertions about the suitability of a RPC for a\n * given purpose. For example, you might like to make it a type error to combine certain types with\n * RPCs belonging to certain clusters, at compile time.\n *\n * @example\n * ```ts\n * async function getSpecialAccountInfo(\n *     address: Address<'ReAL1111111111111111111111111111'>,\n *     rpc: RpcMainnet<unknown>,\n * ): Promise<SpecialAccountInfo>;\n * async function getSpecialAccountInfo(\n *     address: Address<'TeST1111111111111111111111111111'>,\n *     rpc: RpcDevnet<unknown> | RpcTestnet<unknown>,\n * ): Promise<SpecialAccountInfo>;\n * async function getSpecialAccountInfo(address: Address, rpc: Rpc<unknown>): Promise<SpecialAccountInfo> {\n *     /* ... *\\/\n * }\n * const rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * await getSpecialAccountInfo(address('ReAL1111111111111111111111111111'), rpc); // ERROR\n * ```\n */\nexport type RpcDevnet<TRpcMethods> = Rpc<TRpcMethods> & { '~cluster': 'devnet' };\n/**\n * A {@link Rpc} that supports the RPC methods available on the testnet cluster.\n *\n * This is useful in cases where you need to make assertions about the suitability of a RPC for a\n * given purpose. For example, you might like to make it a type error to combine certain types with\n * RPCs belonging to certain clusters, at compile time.\n *\n * @example\n * ```ts\n * async function getSpecialAccountInfo(\n *     address: Address<'ReAL1111111111111111111111111111'>,\n *     rpc: RpcMainnet<unknown>,\n * ): Promise<SpecialAccountInfo>;\n * async function getSpecialAccountInfo(\n *     address: Address<'TeST1111111111111111111111111111'>,\n *     rpc: RpcDevnet<unknown> | RpcTestnet<unknown>,\n * ): Promise<SpecialAccountInfo>;\n * async function getSpecialAccountInfo(address: Address, rpc: Rpc<unknown>): Promise<SpecialAccountInfo> {\n *     /* ... *\\/\n * }\n * const rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * await getSpecialAccountInfo(address('ReAL1111111111111111111111111111'), rpc); // ERROR\n * ```\n */\nexport type RpcTestnet<TRpcMethods> = Rpc<TRpcMethods> & { '~cluster': 'testnet' };\n/**\n * A {@link Rpc} that supports the RPC methods available on the mainnet cluster.\n *\n * This is useful in cases where you need to make assertions about the suitability of a RPC for a\n * given purpose. For example, you might like to make it a type error to combine certain types with\n * RPCs belonging to certain clusters, at compile time.\n *\n * @example\n * ```ts\n * async function getSpecialAccountInfo(\n *     address: Address<'ReAL1111111111111111111111111111'>,\n *     rpc: RpcMainnet<unknown>,\n * ): Promise<SpecialAccountInfo>;\n * async function getSpecialAccountInfo(\n *     address: Address<'TeST1111111111111111111111111111'>,\n *     rpc: RpcDevnet<unknown> | RpcTestnet<unknown>,\n * ): Promise<SpecialAccountInfo>;\n * async function getSpecialAccountInfo(address: Address, rpc: Rpc<unknown>): Promise<SpecialAccountInfo> {\n *     /* ... *\\/\n * }\n * const rpc = createSolanaRpc(devnet('https://api.devnet.solana.com'));\n * await getSpecialAccountInfo(address('ReAL1111111111111111111111111111'), rpc); // ERROR\n * ```\n */\nexport type RpcMainnet<TRpcMethods> = Rpc<TRpcMethods> & { '~cluster': 'mainnet' };\n/**\n * Given a {@link RpcTransport} and a set of RPC methods denoted by `TRpcMethods`, this utility type\n * will resolve to a {@link Rpc} that supports those methods on as specific a cluster as possible.\n *\n * @example\n * ```ts\n * function createCustomRpc<TRpcTransport extends RpcTransport>(\n *     transport: TRpcTransport,\n * ): RpcFromTransport<MyCustomRpcMethods, TRpcTransport> {\n *     /* ... *\\/\n * }\n * const transport = createDefaultRpcTransport({ url: mainnet('http://rpc.company') });\n * transport satisfies RpcTransportMainnet; // OK\n * const rpc = createCustomRpc(transport);\n * rpc satisfies RpcMainnet<MyCustomRpcMethods>; // OK\n * ```\n */\nexport type RpcFromTransport<TRpcMethods, TRpcTransport extends RpcTransport> = TRpcTransport extends RpcTransportDevnet\n    ? RpcDevnet<TRpcMethods>\n    : TRpcTransport extends RpcTransportTestnet\n      ? RpcTestnet<TRpcMethods>\n      : TRpcTransport extends RpcTransportMainnet\n        ? RpcMainnet<TRpcMethods>\n        : Rpc<TRpcMethods>;\n/**\n * Given a {@link RpcTransport} this utility type will resolve to a union of all the methods of the\n * Solana RPC API supported by the transport's cluster.\n *\n * @example\n * ```ts\n * function createSolanaRpcFromTransport<TTransport extends RpcTransport>(\n *     transport: TTransport,\n * ): RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport> {\n *     /* ... *\\/\n * }\n * const transport = createDefaultRpcTransport({ url: mainnet('http://rpc.company') });\n * transport satisfies RpcTransportMainnet; // OK\n * const rpc = createSolanaRpcFromTransport(transport);\n * rpc satisfies RpcMainnet<SolanaRpcApiMainnet>; // OK\n * ```\n */\nexport type SolanaRpcApiFromTransport<TTransport extends RpcTransport> = TTransport extends RpcTransportDevnet\n    ? SolanaRpcApiDevnet\n    : TTransport extends RpcTransportTestnet\n      ? SolanaRpcApiTestnet\n      : TTransport extends RpcTransportMainnet\n        ? SolanaRpcApiMainnet\n        : SolanaRpcApi;\n\n/**\n * Given a {@link ClusterUrl} this utility type will resolve to a union of all the methods of the\n * Solana RPC API supported by the URL's cluster.\n *\n * @example\n * ```ts\n * function createSolanaRpcFromClusterUrl<TClusterUrl extends ClusterUrl>(\n *     clusterUrl: TClusterUrl,\n * ): Rpc<SolanaRpcApiFromClusterUrl<TClusterUrl>, RpcTransportFromClusterUrl<TClusterUrl>> {\n *     /* ... *\\/\n * }\n * const rpc = createSolanaRpcFromClusterUrl(mainnet('http://rpc.company'));\n * rpc satisfies Rpc<SolanaRpcApiMainnet>; // OK\n * ```\n */\nexport type SolanaRpcApiFromClusterUrl<TClusterUrl extends ClusterUrl> = SolanaRpcApiFromTransport<\n    RpcTransportFromClusterUrl<TClusterUrl>\n>;\n"
  },
  {
    "path": "packages/rpc/src/rpc-default-config.ts",
    "content": "import type { createSolanaRpcApi } from '@solana/rpc-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\n/**\n * When you create {@link Rpc} instances with custom transports but otherwise the default RPC API\n * behaviours, use this.\n *\n * @example\n * ```ts\n * const myCustomRpc = createRpc({\n *     api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n *     transport: myCustomTransport,\n * });\n * ```\n */\nexport const DEFAULT_RPC_CONFIG: Partial<NonNullable<Parameters<typeof createSolanaRpcApi>[0]>> = {\n    defaultCommitment: 'confirmed',\n    onIntegerOverflow(request, keyPath, value) {\n        throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n    },\n};\n"
  },
  {
    "path": "packages/rpc/src/rpc-integer-overflow-error.ts",
    "content": "import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n    methodName: string,\n    keyPath: KeyPath,\n    value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n    let argumentLabel = '';\n    if (typeof keyPath[0] === 'number') {\n        const argPosition = keyPath[0] + 1;\n        const lastDigit = argPosition % 10;\n        const lastTwoDigits = argPosition % 100;\n        if (lastDigit == 1 && lastTwoDigits != 11) {\n            argumentLabel = argPosition + 'st';\n        } else if (lastDigit == 2 && lastTwoDigits != 12) {\n            argumentLabel = argPosition + 'nd';\n        } else if (lastDigit == 3 && lastTwoDigits != 13) {\n            argumentLabel = argPosition + 'rd';\n        } else {\n            argumentLabel = argPosition + 'th';\n        }\n    } else {\n        argumentLabel = `\\`${keyPath[0].toString()}\\``;\n    }\n    const path =\n        keyPath.length > 1\n            ? keyPath\n                  .slice(1)\n                  .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n                  .join('.')\n            : undefined;\n    const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n        argumentLabel,\n        keyPath: keyPath as readonly (number | string | symbol)[],\n        methodName,\n        optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n        value,\n        ...(path !== undefined ? { path } : undefined),\n    });\n    safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n    return error;\n}\n"
  },
  {
    "path": "packages/rpc/src/rpc-request-coalescer.ts",
    "content": "import { AbortController } from '@solana/event-target-impl';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\n\ntype CoalescedRequest = {\n    readonly abortController: AbortController;\n    numConsumers: number;\n    readonly responsePromise: Promise<RpcResponse>;\n};\n\ntype GetDeduplicationKeyFn = (payload: unknown) => string | undefined;\n\n// This used to be a `Symbol()`, but there's a bug in Node <21 where the `undici` library passes\n// the `reason` property of the `AbortSignal` straight to `Error.captureStackTrace()` without first\n// typechecking it. `Error.captureStackTrace()` fatals when given a `Symbol`.\n// See https://github.com/nodejs/undici/pull/2597\nlet EXPLICIT_ABORT_TOKEN: ReturnType<typeof createExplicitAbortToken>;\nfunction createExplicitAbortToken() {\n    // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n    // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n    return __DEV__\n        ? {\n              EXPLICIT_ABORT_TOKEN:\n                  'This object is thrown from the request that underlies a series of coalesced ' +\n                  'requests when the last request in that series aborts',\n          }\n        : {};\n}\n\nexport function getRpcTransportWithRequestCoalescing<TTransport extends RpcTransport>(\n    transport: TTransport,\n    getDeduplicationKey: GetDeduplicationKeyFn,\n): TTransport {\n    let coalescedRequestsByDeduplicationKey: Record<string, CoalescedRequest> | undefined;\n    return async function makeCoalescedHttpRequest<TResponse>(\n        request: Parameters<RpcTransport>[0],\n    ): Promise<RpcResponse<TResponse>> {\n        const { payload, signal } = request;\n        const deduplicationKey = getDeduplicationKey(payload);\n        if (deduplicationKey === undefined) {\n            return await transport(request);\n        }\n        if (!coalescedRequestsByDeduplicationKey) {\n            queueMicrotask(() => {\n                coalescedRequestsByDeduplicationKey = undefined;\n            });\n            coalescedRequestsByDeduplicationKey = {};\n        }\n        if (coalescedRequestsByDeduplicationKey[deduplicationKey] == null) {\n            const abortController = new AbortController();\n            const responsePromise = (async () => {\n                try {\n                    return await transport<TResponse>({\n                        ...request,\n                        signal: abortController.signal,\n                    });\n                } catch (e) {\n                    if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n                        // We triggered this error when the last subscriber aborted. Letting this\n                        // error bubble up from here would cause runtime fatals where there should\n                        // be none.\n                        return;\n                    }\n                    throw e;\n                }\n            })();\n            coalescedRequestsByDeduplicationKey[deduplicationKey] = {\n                abortController,\n                numConsumers: 0,\n                responsePromise,\n            };\n        }\n        const coalescedRequest = coalescedRequestsByDeduplicationKey[deduplicationKey];\n        coalescedRequest.numConsumers++;\n        if (signal) {\n            const responsePromise = coalescedRequest.responsePromise as Promise<RpcResponse<TResponse>>;\n            return await new Promise<RpcResponse<TResponse>>((resolve, reject) => {\n                const handleAbort = (e: AbortSignalEventMap['abort']) => {\n                    signal.removeEventListener('abort', handleAbort);\n                    coalescedRequest.numConsumers -= 1;\n                    queueMicrotask(() => {\n                        if (coalescedRequest.numConsumers === 0) {\n                            const abortController = coalescedRequest.abortController;\n                            abortController.abort((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n                        }\n                    });\n                    // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n                    reject((e.target as AbortSignal).reason);\n                };\n                signal.addEventListener('abort', handleAbort);\n                responsePromise\n                    .then(resolve)\n                    .catch(reject)\n                    .finally(() => {\n                        signal.removeEventListener('abort', handleAbort);\n                    });\n            });\n        } else {\n            return (await coalescedRequest.responsePromise) as RpcResponse<TResponse>;\n        }\n    } as TTransport;\n}\n"
  },
  {
    "path": "packages/rpc/src/rpc-request-deduplication.ts",
    "content": "import fastStableStringify from '@solana/fast-stable-stringify';\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nexport function getSolanaRpcPayloadDeduplicationKey(payload: unknown): string | undefined {\n    return isJsonRpcPayload(payload) ? fastStableStringify([payload.method, payload.params]) : undefined;\n}\n"
  },
  {
    "path": "packages/rpc/src/rpc-transport.ts",
    "content": "import { pipe } from '@solana/functional';\nimport { createHttpTransport, createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { RpcTransportFromClusterUrl } from './rpc-clusters';\nimport { getRpcTransportWithRequestCoalescing } from './rpc-request-coalescer';\nimport { getSolanaRpcPayloadDeduplicationKey } from './rpc-request-deduplication';\n\ntype RpcTransportConfig = Parameters<typeof createHttpTransport>[0];\ninterface DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> extends RpcTransportConfig {\n    url: TClusterUrl;\n}\n\nfunction normalizeHeaders<T extends Record<string, string>>(\n    headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n    const out: Record<string, string> = {};\n    for (const headerName in headers) {\n        // Lowercasing header names makes it easier to override user-supplied headers.\n        out[headerName.toLowerCase()] = headers[headerName];\n    }\n    return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n\n/**\n * Creates a {@link RpcTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - An automatically-set `Solana-Client` request header, containing the version of `@solana/kit`\n * - Logic that coalesces multiple calls in the same runloop, for the same methods with the same\n *   arguments, into a single network request.\n * - [node-only] An automatically-set `Accept-Encoding` request header asking the server to compress\n *   responses\n *\n * @param config\n */\nexport function createDefaultRpcTransport<TClusterUrl extends ClusterUrl>(\n    config: DefaultRpcTransportConfig<TClusterUrl>,\n): RpcTransportFromClusterUrl<TClusterUrl> {\n    return pipe(\n        createHttpTransportForSolanaRpc({\n            ...config,\n            headers: {\n                ...(__NODEJS__ &&\n                    ({\n                        // Keep these headers lowercase so they will be overridden by any user-supplied headers below.\n                        'accept-encoding':\n                            // Natively supported by Node LTS v20.18.0 and above.\n                            'br,gzip,deflate', // Brotli, gzip, and Deflate, in that order.\n                    } as { [overrideHeader: string]: string })),\n                ...(config.headers ? normalizeHeaders(config.headers) : undefined),\n                ...({\n                    // Keep these headers lowercase so they will override any user-supplied headers above.\n                    'solana-client': __VERSION__ ? `js/${__VERSION__}` : 'UNKNOWN',\n                } as { [overrideHeader: string]: string }),\n            },\n        }) as RpcTransportFromClusterUrl<TClusterUrl>,\n        transport => getRpcTransportWithRequestCoalescing(transport, getSolanaRpcPayloadDeduplicationKey),\n    );\n}\n"
  },
  {
    "path": "packages/rpc/src/rpc.ts",
    "content": "import { createSolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, RpcTransport } from '@solana/rpc-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport type { RpcFromTransport, SolanaRpcApiFromTransport } from './rpc-clusters';\nimport { DEFAULT_RPC_CONFIG } from './rpc-default-config';\nimport { createDefaultRpcTransport } from './rpc-transport';\n\ntype DefaultRpcTransportConfig<TClusterUrl extends ClusterUrl> = Parameters<\n    typeof createDefaultRpcTransport<TClusterUrl>\n>[0];\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given a cluster URL and some\n * optional transport config. See {@link createDefaultRpcTransport} for the shape of the transport\n * config.\n */\nexport function createSolanaRpc<TClusterUrl extends ClusterUrl>(\n    clusterUrl: TClusterUrl,\n    config?: Omit<DefaultRpcTransportConfig<TClusterUrl>, 'url'>,\n) {\n    return createSolanaRpcFromTransport(createDefaultRpcTransport({ url: clusterUrl, ...config }));\n}\n\n/**\n * Creates a {@link Rpc} instance that exposes the Solana JSON RPC API given the supplied\n * {@link RpcTransport}.\n */\nexport function createSolanaRpcFromTransport<TTransport extends RpcTransport>(transport: TTransport) {\n    return createRpc({\n        api: createSolanaRpcApi(DEFAULT_RPC_CONFIG),\n        transport,\n    }) as RpcFromTransport<SolanaRpcApiFromTransport<TTransport>, TTransport>;\n}\n"
  },
  {
    "path": "packages/rpc/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-api/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-api/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-api/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-api/CHANGELOG.md",
    "content": "# @solana/rpc-api\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1544](https://github.com/anza-xyz/kit/pull/1544) [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update RPC types for Agave v3.x validator compatibility.\n\n    **`@solana/rpc-parsed-types`**: `JsonParsedVoteAccount` now includes `blockRevenueCollector`, `blockRevenueCommissionBps`, `blsPubkeyCompressed`, `inflationRewardsCollector`, `inflationRewardsCommissionBps`, `pendingDelegatorRewards`, and a `latency` field on each vote entry.\n\n    **`@solana/rpc-api`**: `SimulateTransactionApiResponseBase` now includes `fee`, `loadedAddresses`, `preBalances`, `postBalances`, `preTokenBalances`, and `postTokenBalances`.\n\n    **`@solana/errors`**: `RpcSimulateTransactionResult` updated with the same new fields.\n\n    **Note on `replacementBlockhash`**: Agave v3.x validators now always return `replacementBlockhash` in `simulateTransaction` responses (as `null` when `replaceRecentBlockhash` is not set). Kit's types still model this field as conditionally present based on config. A future breaking change will move it to the base response type as `TransactionBlockhashLifetime | null` to match v3.x behavior. Consumers using v3.x validators may see this field at runtime even when Kit's types don't surface it.\n\n    **Note on Agave v3.x validator behavior**: Validators running Agave v3.x no longer return a dedicated `TRANSACTION_SIGNATURE_VERIFICATION_FAILURE` RPC error for invalid signatures in `simulateTransaction` or `sendTransaction`. Instead, `simulateTransaction` returns a result with `err: \"SignatureFailure\"`, and `sendTransaction` returns a preflight failure with the signature error as the cause. This is a validator-level change and does not affect Kit's API surface.\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/errors@6.9.0\n    - @solana/rpc-parsed-types@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/rpc-spec@6.9.0\n    - @solana/rpc-transformers@6.9.0\n    - @solana/rpc-types@6.9.0\n    - @solana/transaction-messages@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/rpc-parsed-types@6.8.0\n    - @solana/rpc-spec@6.8.0\n    - @solana/rpc-transformers@6.8.0\n    - @solana/rpc-types@6.8.0\n    - @solana/transaction-messages@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/rpc-parsed-types@6.7.0\n    - @solana/rpc-spec@6.7.0\n    - @solana/rpc-transformers@6.7.0\n    - @solana/rpc-types@6.7.0\n    - @solana/transaction-messages@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/transactions@6.6.0\n    - @solana/errors@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/rpc-spec@6.6.0\n    - @solana/rpc-transformers@6.6.0\n    - @solana/rpc-types@6.6.0\n    - @solana/rpc-parsed-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/rpc-parsed-types@6.5.0\n    - @solana/rpc-spec@6.5.0\n    - @solana/rpc-transformers@6.5.0\n    - @solana/rpc-types@6.5.0\n    - @solana/transaction-messages@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c), [`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/transaction-messages@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/rpc-parsed-types@6.4.0\n    - @solana/rpc-transformers@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/rpc-spec@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/rpc-parsed-types@6.3.1\n    - @solana/rpc-spec@6.3.1\n    - @solana/rpc-transformers@6.3.1\n    - @solana/rpc-types@6.3.1\n    - @solana/transaction-messages@6.3.1\n    - @solana/transactions@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/rpc-spec@6.3.0\n    - @solana/rpc-transformers@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/transaction-messages@6.3.0\n    - @solana/transactions@6.3.0\n    - @solana/rpc-parsed-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/rpc-spec@6.2.0\n    - @solana/rpc-transformers@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/transaction-messages@6.2.0\n    - @solana/transactions@6.2.0\n    - @solana/rpc-parsed-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/transaction-messages@6.1.0\n    - @solana/transactions@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-strings@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/rpc-spec@6.1.0\n    - @solana/rpc-transformers@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/rpc-parsed-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies [[`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492), [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462)]:\n    - @solana/transaction-messages@6.0.1\n    - @solana/transactions@6.0.1\n    - @solana/addresses@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/rpc-parsed-types@6.0.1\n    - @solana/rpc-spec@6.0.1\n    - @solana/rpc-transformers@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926), [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a), [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db)]:\n    - @solana/transaction-messages@6.0.0\n    - @solana/transactions@6.0.0\n    - @solana/addresses@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/rpc-parsed-types@6.0.0\n    - @solana/rpc-spec@6.0.0\n    - @solana/rpc-transformers@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/rpc-spec@5.5.1\n    - @solana/rpc-transformers@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/transaction-messages@5.5.1\n    - @solana/transactions@5.5.1\n    - @solana/rpc-parsed-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/rpc-spec@5.5.0\n    - @solana/rpc-transformers@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/transaction-messages@5.5.0\n    - @solana/transactions@5.5.0\n    - @solana/rpc-parsed-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/transaction-messages@5.4.0\n    - @solana/rpc-parsed-types@5.4.0\n    - @solana/rpc-transformers@5.4.0\n    - @solana/codecs-strings@5.4.0\n    - @solana/transactions@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/rpc-spec@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/rpc-parsed-types@5.3.0\n    - @solana/rpc-spec@5.3.0\n    - @solana/rpc-transformers@5.3.0\n    - @solana/rpc-types@5.3.0\n    - @solana/transaction-messages@5.3.0\n    - @solana/transactions@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/transaction-messages@5.2.0\n    - @solana/transactions@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/rpc-spec@5.2.0\n    - @solana/rpc-transformers@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/rpc-parsed-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#978](https://github.com/anza-xyz/kit/pull/978) [`c97df88`](https://github.com/anza-xyz/kit/commit/c97df8886948b281fff7d6b66429a59a9f7bdfa2) Thanks [@nonergodic](https://github.com/nonergodic)! - Expanded the type of several RPC inputs to accept readonly arrays of values\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951), [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/transactions@5.1.0\n    - @solana/transaction-messages@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/rpc-spec@5.1.0\n    - @solana/rpc-transformers@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/rpc-parsed-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/rpc-parsed-types@5.0.0\n    - @solana/rpc-transformers@5.0.0\n    - @solana/transaction-messages@5.0.0\n    - @solana/transactions@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-strings@5.0.0\n    - @solana/keys@5.0.0\n    - @solana/rpc-spec@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df), [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013)]:\n    - @solana/transactions@4.0.0\n    - @solana/errors@4.0.0\n    - @solana/keys@4.0.0\n    - @solana/transaction-messages@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/codecs-strings@4.0.0\n    - @solana/rpc-spec@4.0.0\n    - @solana/rpc-transformers@4.0.0\n    - @solana/rpc-parsed-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6), [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0), [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845), [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf)]:\n    - @solana/transaction-messages@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/transactions@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/codecs-strings@3.0.0\n    - @solana/keys@3.0.0\n    - @solana/rpc-spec@3.0.0\n    - @solana/rpc-transformers@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/rpc-parsed-types@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a), [`53e1336`](https://github.com/anza-xyz/kit/commit/53e1336149878c84048e0fde5c7e7ace6cc1e97f), [`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eb61d94`](https://github.com/anza-xyz/kit/commit/eb61d94786e212fc23778d445a94b86d2b1b024f), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`bbcb913`](https://github.com/anza-xyz/kit/commit/bbcb913839d33abc746f38d6e65e7bfd30cd2ac6), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`e6c0568`](https://github.com/anza-xyz/kit/commit/e6c0568ef34fdc04075af27eb102851123a02be0), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/transaction-messages@2.3.0\n    - @solana/transactions@2.3.0\n    - @solana/errors@2.3.0\n    - @solana/rpc-spec@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-strings@2.3.0\n    - @solana/keys@2.3.0\n    - @solana/rpc-transformers@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/rpc-parsed-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/keys@2.2.1\n    - @solana/rpc-parsed-types@2.2.1\n    - @solana/rpc-spec@2.2.1\n    - @solana/rpc-transformers@2.2.1\n    - @solana/rpc-types@2.2.1\n    - @solana/transaction-messages@2.2.1\n    - @solana/transactions@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/addresses@2.2.0\n    - @solana/keys@2.2.0\n    - @solana/rpc-transformers@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/transaction-messages@2.2.0\n    - @solana/transactions@2.2.0\n    - @solana/rpc-parsed-types@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/rpc-spec@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - RPC methods that take no parameters no longer rely on having a placeholder `NO_CONFIG` argument. Removing it will save you from wondering why it exists.\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#433](https://github.com/anza-xyz/kit/pull/433) [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a) Thanks [@steveluscher](https://github.com/steveluscher)! - Corrected a misspelling of `readonlyIndexes` in the `AddressLookupTable` type. This fixes the return type of the `getTransaction` RPC call.\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`7e7b2ef`](https://github.com/anza-xyz/kit/commit/7e7b2efebfd8de431e4381cc3d3fa117d3228030), [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`776e18d`](https://github.com/anza-xyz/kit/commit/776e18d75c759a839608069c61da3f70b775540b), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-transformers@2.1.1\n    - @solana/transaction-messages@2.1.1\n    - @solana/rpc-parsed-types@2.1.1\n    - @solana/codecs-strings@2.1.1\n    - @solana/transactions@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/rpc-spec@2.1.1\n    - @solana/errors@2.1.1\n    - @solana/keys@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [#85](https://github.com/anza-xyz/kit/pull/85) [`3c25e7f`](https://github.com/anza-xyz/kit/commit/3c25e7f1a226ec92feaf1b21c702e65032059a42) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix accountKeys type in getTransaction JSON parsed\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/keys@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/transaction-messages@2.1.0\n    - @solana/rpc-parsed-types@2.1.0\n    - @solana/transactions@2.1.0\n    - @solana/rpc-spec@2.1.0\n    - @solana/rpc-transformers@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2868](https://github.com/solana-labs/solana-web3.js/pull/2868) [`91fb1f3`](https://github.com/solana-labs/solana-web3.js/commit/91fb1f39bb174cf1e899a21365153a7b3bbf3571) Thanks [@steveluscher](https://github.com/steveluscher)! - The `simulateTransaction` RPC method now accepts an `innerInstructions` param. When `true`, the simulation result will include an array of inner instructions, if any.\n\n- [#2865](https://github.com/solana-labs/solana-web3.js/pull/2865) [`daf9691`](https://github.com/solana-labs/solana-web3.js/commit/daf96918b2e875b60ab733acb0bd3f1b76a46c76) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a TypeScript error where the return value of `simulateTransaction` claimed there was an `accounts` property at the top level when it is in fact `value.accounts`\n\n- [#3145](https://github.com/solana-labs/solana-web3.js/pull/3145) [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type\n\n- [#3213](https://github.com/solana-labs/solana-web3.js/pull/3213) [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcApi: no longer extend RpcApiMethods + remove export\n\n- [#3454](https://github.com/solana-labs/solana-web3.js/pull/3454) [`1fde4b1`](https://github.com/solana-labs/solana-web3.js/commit/1fde4b1d75c4af6d965ca26f6a7c649c6a517deb) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Correct type of replacementBlockhash in simulateTransaction\n\n- [#3456](https://github.com/solana-labs/solana-web3.js/pull/3456) [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove `UnsafeBeyond2Pow53Minus1` type suffixes\n\n- [#3150](https://github.com/solana-labs/solana-web3.js/pull/3150) [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcApi` use new `RpcRequestTransformer` and `RpcResponseTransformer`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3202](https://github.com/solana-labs/solana-web3.js/pull/3202) [`bf07a60`](https://github.com/solana-labs/solana-web3.js/commit/bf07a606768eef7cd37c1dd0e2c0a35fe3b12f24) Thanks [@disco-infinex](https://github.com/disco-infinex)! - PerformanceSample return type field numNonVoteTransaction corrected to numNonVoteTransactions\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `getIntegerOverflowRequestTransformer`, `getBigIntDowncastRequestTransformer` and `getTreeWalkerRequestTransformer` helpers\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#2866](https://github.com/solana-labs/solana-web3.js/pull/2866) [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677) Thanks [@steveluscher](https://github.com/steveluscher)! - The `TransactionInstruction` RPC type now has `stackHeight`\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#3148](https://github.com/solana-labs/solana-web3.js/pull/3148) [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcTransport` return new `RpcReponse` type instead of parsed JSON data\n\n- [#3201](https://github.com/solana-labs/solana-web3.js/pull/3201) [`02cefa7`](https://github.com/solana-labs/solana-web3.js/commit/02cefa7cc98463e602f78a8acc10d85c37f03481) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Update the response type of the `getClusterNodes` RPC method\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e), [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c), [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597), [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/rpc-spec@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/transactions@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/rpc-transformers@2.0.0\n    - @solana/keys@2.0.0\n    - @solana/transaction-messages@2.0.0\n    - @solana/rpc-parsed-types@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n    - @solana/keys@2.0.0-rc.4\n    - @solana/rpc-spec@2.0.0-rc.4\n    - @solana/rpc-transformers@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/transaction-messages@2.0.0-rc.4\n    - @solana/transactions@2.0.0-rc.4\n    - @solana/rpc-parsed-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-spec@2.0.0-rc.3\n    - @solana/rpc-transformers@2.0.0-rc.3\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/keys@2.0.0-rc.3\n    - @solana/rpc-parsed-types@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n    - @solana/transaction-messages@2.0.0-rc.3\n    - @solana/transactions@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3145](https://github.com/solana-labs/solana-web3.js/pull/3145) [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type\n\n- [#3213](https://github.com/solana-labs/solana-web3.js/pull/3213) [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcApi: no longer extend RpcApiMethods + remove export\n\n- [#3454](https://github.com/solana-labs/solana-web3.js/pull/3454) [`1fde4b1`](https://github.com/solana-labs/solana-web3.js/commit/1fde4b1d75c4af6d965ca26f6a7c649c6a517deb) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Correct type of replacementBlockhash in simulateTransaction\n\n- [#3456](https://github.com/solana-labs/solana-web3.js/pull/3456) [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove `UnsafeBeyond2Pow53Minus1` type suffixes\n\n- [#3150](https://github.com/solana-labs/solana-web3.js/pull/3150) [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcApi` use new `RpcRequestTransformer` and `RpcResponseTransformer`\n\n- [#3202](https://github.com/solana-labs/solana-web3.js/pull/3202) [`bf07a60`](https://github.com/solana-labs/solana-web3.js/commit/bf07a606768eef7cd37c1dd0e2c0a35fe3b12f24) Thanks [@disco-infinex](https://github.com/disco-infinex)! - PerformanceSample return type field numNonVoteTransaction corrected to numNonVoteTransactions\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `getIntegerOverflowRequestTransformer`, `getBigIntDowncastRequestTransformer` and `getTreeWalkerRequestTransformer` helpers\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#3148](https://github.com/solana-labs/solana-web3.js/pull/3148) [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcTransport` return new `RpcReponse` type instead of parsed JSON data\n\n- [#3201](https://github.com/solana-labs/solana-web3.js/pull/3201) [`02cefa7`](https://github.com/solana-labs/solana-web3.js/commit/02cefa7cc98463e602f78a8acc10d85c37f03481) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Update the response type of the `getClusterNodes` RPC method\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c), [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/rpc-spec@2.0.0-rc.2\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/rpc-transformers@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/transaction-messages@2.0.0-rc.2\n    - @solana/rpc-parsed-types@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/transactions@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n    - @solana/keys@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies [[`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302)]:\n    - @solana/keys@2.0.0-rc.1\n    - @solana/transactions@2.0.0-rc.1\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/rpc-parsed-types@2.0.0-rc.1\n    - @solana/rpc-spec@2.0.0-rc.1\n    - @solana/rpc-transformers@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n    - @solana/transaction-messages@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/transaction-messages@2.0.0-rc.0\n    - @solana/rpc-transformers@2.0.0-rc.0\n    - @solana/rpc-spec@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/transactions@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n    - @solana/keys@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n    - @solana/rpc-parsed-types@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2868](https://github.com/solana-labs/solana-web3.js/pull/2868) [`91fb1f3`](https://github.com/solana-labs/solana-web3.js/commit/91fb1f39bb174cf1e899a21365153a7b3bbf3571) Thanks [@steveluscher](https://github.com/steveluscher)! - The `simulateTransaction` RPC method now accepts an `innerInstructions` param. When `true`, the simulation result will include an array of inner instructions, if any.\n\n- [#2865](https://github.com/solana-labs/solana-web3.js/pull/2865) [`daf9691`](https://github.com/solana-labs/solana-web3.js/commit/daf96918b2e875b60ab733acb0bd3f1b76a46c76) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a TypeScript error where the return value of `simulateTransaction` claimed there was an `accounts` property at the top level when it is in fact `value.accounts`\n\n- [#2866](https://github.com/solana-labs/solana-web3.js/pull/2866) [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677) Thanks [@steveluscher](https://github.com/steveluscher)! - The `TransactionInstruction` RPC type now has `stackHeight`\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/keys@2.0.0-preview.4\n    - @solana/transaction-messages@2.0.0-preview.4\n    - @solana/rpc-parsed-types@2.0.0-preview.4\n    - @solana/rpc-transformers@2.0.0-preview.4\n    - @solana/transactions@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n    - @solana/rpc-spec@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/transactions@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/transaction-messages@2.0.0-preview.3\n    - @solana/keys@2.0.0-preview.3\n    - @solana/rpc-transformers@2.0.0-preview.3\n    - @solana/rpc-spec@2.0.0-preview.3\n    - @solana/rpc-parsed-types@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/addresses@2.0.0-preview.2\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-strings@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n    - @solana/keys@2.0.0-preview.2\n    - @solana/rpc-parsed-types@2.0.0-preview.2\n    - @solana/rpc-spec@2.0.0-preview.2\n    - @solana/rpc-transformers@2.0.0-preview.2\n    - @solana/rpc-types@2.0.0-preview.2\n    - @solana/transactions@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-api/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-api/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-api?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-api?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-api\n\n# @solana/rpc-api\n\nThis package contains types that describe the [methods](https://solana.com/docs/rpc/http) of the Solana JSON RPC API, and utilities for creating a `RpcApi` implementation with sensible defaults. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nEach RPC method is described in terms of a TypeScript type of the following form:\n\n```ts\ntype ExampleApi = {\n    getSomething(address: Address): Something;\n};\n```\n\nA `RpcApi` that implements `ExampleApi` will ultimately expose its defined methods on any `Rpc` that uses it.\n\n```ts\nconst rpc: Rpc<ExampleApi> = createExampleRpc(/* ... */);\nconst something: Something = await rpc.getSomething(address('95DpK3y3GF7U8s1k4EvZ7xqyeCkhsHeZaE97iZpHUGMN')).send();\n```\n\n## Types\n\n### `SolanaRpcApi{Devnet|Testnet|Mainnet}`\n\nThese types represent the RPC methods available on a specific Solana cluster.\n\nFor instance, the test clusters support the `RequestAirdropApi` while mainnet does not.\n\n## Functions\n\n### `createSolanaRpcApi(config)`\n\nCreates a `RpcApi` implementation of the Solana JSON RPC API with some default behaviours.\n\nThe default behaviours include:\n\n- A transform that converts `bigint` inputs to `number` for compatibility with version 1.0 of the Solana JSON RPC.\n- A transform that calls the config's `onIntegerOverflow` handler whenever a `bigint` input would overflow a JavaScript IEEE 754 number. See [this](https://github.com/solana-labs/solana-web3.js/issues/1116) GitHub issue for more information.\n- A transform that applies a default commitment wherever not specified\n\n#### Arguments\n\nA config object with the following properties:\n\n- `defaultCommitment`: An optional default `Commitment` value. Given an RPC method that takes `commitment` as a parameter, this value will be used when the caller does not supply one.\n- `onIntegerOverflow(request, keyPath, value): void`: An optional function that will be called whenever a `bigint` input exceeds that which can be expressed using JavaScript numbers. This is used in the default `SolanaRpcApi` to throw an exception rather than to allow truncated values to propagate through a program.\n"
  },
  {
    "path": "packages/rpc-api/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-api\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Defines all default Solana RPC methods as types\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-api\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/rpc-parsed-types\": \"workspace:*\",\n        \"@solana/rpc-spec\": \"workspace:*\",\n        \"@solana/rpc-transformers\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/rpc-spec-types\": \"workspace:*\",\n        \"@solana/rpc-transport-http\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-api/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/__setup__.ts",
    "content": "import { createRpc, Rpc } from '@solana/rpc-spec';\nimport { createHttpTransportForSolanaRpc } from '@solana/rpc-transport-http';\n\nimport { createSolanaRpcApi, SolanaRpcApi } from '..';\n\nexport function createLocalhostSolanaRpc(): Rpc<SolanaRpcApi> {\n    return createRpc({\n        api: createSolanaRpcApi(),\n        transport: createHttpTransportForSolanaRpc({ url: 'http://127.0.0.1:8899' }),\n    });\n}\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-account-info-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetAccountInfoApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getAccountInfo', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns account info', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n                const publicKey =\n                    'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        commitment,\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: '2Uw1bpnsXxu3e',\n                        executable: false,\n                        lamports: 5000000n,\n                        owner: '11111111111111111111111111111111',\n                        rentEpoch: 18446744073709551615n,\n                        space: 9n,\n                    },\n                });\n            });\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n            const sendPromise = rpc\n                .getAccountInfo(publicKey, {\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n\n    describe('when called with an account that does not exist', () => {\n        it('returns a null RPC response', async () => {\n            expect.assertions(1);\n            // randomly generated\n            const publicKey =\n                'Bb39jXh8b1rWHymSqM46kKXYwzA35ChNZAMCZ3wSDAMV' as Address<'Bb39jXh8b1rWHymSqM46kKXYwzA35ChNZAMCZ3wSDAMV'>;\n            const accountInfoPromise = rpc.getAccountInfo(publicKey).send();\n            await expect(accountInfoPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: null,\n            });\n        });\n    });\n\n    describe('when called with base58 encoding', () => {\n        it('returns account info with annotated base58 encoding', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const accountInfo = await rpc\n                .getAccountInfo(publicKey, {\n                    encoding: 'base58',\n                })\n                .send();\n\n            expect(accountInfo.value?.data).toStrictEqual(['2Uw1bpnsXxu3e', 'base58']);\n        });\n    });\n\n    describe('when called with base64 encoding', () => {\n        it('returns account info with annotated base64 encoding', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const accountInfo = await rpc\n                .getAccountInfo(publicKey, {\n                    encoding: 'base64',\n                })\n                .send();\n\n            expect(accountInfo.value?.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n        });\n    });\n\n    describe('when called with base64+zstd encoding', () => {\n        it('returns account info with annotated base64+zstd encoding', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const accountInfo = await rpc\n                .getAccountInfo(publicKey, {\n                    encoding: 'base64+zstd',\n                })\n                .send();\n\n            expect(accountInfo.value?.data).toStrictEqual(['KLUv/QBYSQAAdGVzdCBkYXRh', 'base64+zstd']);\n        });\n    });\n\n    describe('when called with jsonParsed encoding', () => {\n        describe('for an account without parse-able JSON data', () => {\n            it('falls back to annotated base64', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n                const publicKey =\n                    'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n                const accountInfo = await rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                expect(accountInfo.value?.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n            });\n        });\n\n        describe('for an account with parse-able JSON data', () => {\n            it('returns parsed JSON data for AddressLookupTable account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/address-lookup-table-account.json\n                const publicKey =\n                    '2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n' as Address<'2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    addresses: [\n                                        'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn',\n                                        'FWscgV4VDSsMxkQg7jZ4HksqjLyadJS5RiCnAVZv2se9',\n                                        '6PoVp5L36hYU5oDWjZiUnhcKqVnkwYXgditMKufxhTuo',\n                                        '9J4yDqU6wBkdhP5bmJhukhsEzBkaAXiBmii52kTdxpQq',\n                                        '25FkCKVY4nMLaqCWhWoDt3idfNRBHkyQttTd4VCibYoU',\n                                        'CSYi7PVzvEA2iiDWhR8eN6EBjZpKyzPX1aMbayrk9YTD',\n                                        'CSYi7PVzvEA2iiDWhR8eN6EBjZpKyzPX1aMbayrk9YTD',\n                                        '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                                        '6ndVLNpgFDZZS1Ph7A9oZKD15Z6FurMMeVrsYiP6NUw8',\n                                        '9zqNWNXHPLkW6LcNbBboF6tFvAHoT97UFczUusGLdGhE',\n                                        '3nkuz3xksLcsok3NexdDLWZqUMehrPQj23a8fkPnZ4ng',\n                                        'EL9gfMj99EvcV5x3NxHbRQsJKbavFcFvvNxbpJg6CvqM',\n                                        'EWmQeCKE6MsByDGdL7sktuL5eCfTUBKSLQe12tG3mFfn',\n                                        '4oEA4jBmBbZmrzAxnConZP93LQuwh9bV5T1y7NLFwtMk',\n                                        'EHjk9n6jCrDLVGhC2vjvdzaFP2gPonK7Up1tVg9Zc11y',\n                                        'GsPu9qRgkF9RDFnQjXh3TngvAdQPYUnTSaeG1K4uNjj3',\n                                        '9J4yDqU6wBkdhP5bmJhukhsEzBkaAXiBmii52kTdxpQq',\n                                        'FoNprxYzYmwnYzhM964CxEHchhj17YREieJtSAXg9FMU',\n                                        'FAH4Nd2GhQmLWxHcVN63rnc4EomJw2EEpA5ukGuzZyKc',\n                                        'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                        'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',\n                                        'FAH4Nd2GhQmLWxHcVN63rnc4EomJw2EEpA5ukGuzZyKc',\n                                        'CZw6RPBy9BecE4hVBG4cK4E64gJN7gT9D1EZKCGRqkHV',\n                                        '2Q1PhUaRw3GeaCxv2ud8iaxWAZjpisdU5bvUTtVacgJU',\n                                        'Sysvar1nstructions1111111111111111111111111',\n                                        'auth9SigNpDKz4sJJ1DfCTuZrZNSAgh9sFD3rboVmgg',\n                                        '11111111111111111111111111111111',\n                                        'SysvarRent111111111111111111111111111111111',\n                                        'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                                        '7YVgrijuM9eSNgeyEpZBw7cZ3ncXhUbHkst9NjAVQQd4',\n                                        '4ncLWXmfoFGyGuCXKLFxguCAYE4ioUp4RKKoUHtJPNGN',\n                                        'FZYB8CfgDexiDv9Vm3vHBuEBNxy97yetVTU6nq1nPyxQ',\n                                        'CJBCQppi8NjNxqzyoHJG2h97RinfKePP1ZUMMWcxp339',\n                                        '9WPz1JB6xWb5Cn3uvL9T2hR2sKPfVB5GANoVM7pf1zvG',\n                                        '5gb1Vq2ZVtx25w8TDnpGTzPk8nZXgZ1TLWvSt6hnBiXn',\n                                        'mm8fDa7jiufFGD6h4foq9vdmTRxDeDSTKB9CZynwQQs',\n                                        '4cdDuEivqaGiF2Yu6LjdgTukmfgsHoxfhjTua59xXexP',\n                                        'AdH2Utn6Fus15ZhtenW4hZBQnvtLgM1YCW2MfVp7pYS5',\n                                        'FoNprxYzYmwnYzhM964CxEHchhj17YREieJtSAXg9FMU',\n                                    ],\n                                    authority: '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                                    deactivationSlot: '204699277',\n                                    lastExtendedSlot: '204699234',\n                                    lastExtendedSlotStartIndex: 20,\n                                },\n                                type: 'lookupTable',\n                            },\n                            program: 'address-lookup-table',\n                            space: 1304n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: 'AddressLookupTab1e1111111111111111111111111',\n                        rentEpoch: 0n,\n                        space: 1304n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for BpfLoaderUpgradeable account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/bpf-upgradeable-loader-program-account.json\n                const publicKey =\n                    'AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk' as Address<'AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk'>;\n\n                const accountInfo = await rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                expect(accountInfo).toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    programData: '3vnUTQbDuCgfVn7yQcigUwMQNGkLBZ7GfKWb3gYbAY23',\n                                },\n                                type: 'program',\n                            },\n                            program: 'bpf-upgradeable-loader',\n                            space: 36n,\n                        },\n                        executable: true,\n                        lamports: 10290815n,\n                        owner: 'BPFLoaderUpgradeab1e11111111111111111111111',\n                        rentEpoch: 0n,\n                        space: 36n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for Config validator account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/config-validator-account.json\n                const publicKey =\n                    'FtLZBmDW4Y6WNTYYZv9AcC2nQupDMDzX5Q5mp5MLpmdY' as Address<'FtLZBmDW4Y6WNTYYZv9AcC2nQupDMDzX5Q5mp5MLpmdY'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    configData: {\n                                        name: 'HoldTheNode',\n                                        website: 'https://holdthenode.com',\n                                    },\n                                    keys: [\n                                        {\n                                            pubkey: 'Va1idator1nfo111111111111111111111111111111',\n                                            signer: false,\n                                        },\n                                        {\n                                            pubkey: '5hvJ19nRgtzAkosb5bcx9bqeN2QA1Qwxq4M349Q2L6s2',\n                                            signer: true,\n                                        },\n                                    ],\n                                },\n                                type: 'validatorInfo',\n                            },\n                            program: 'config',\n                            space: 643n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: 'Config1111111111111111111111111111111111111',\n                        rentEpoch: 0n,\n                        space: 643n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for Config stake account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/config-stake-account.json\n                const publicKey =\n                    'StakeConfig11111111111111111111111111111111' as Address<'StakeConfig11111111111111111111111111111111'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    slashPenalty: 12,\n                                    warmupCooldownRate: 0.25,\n                                },\n                                type: 'stakeConfig',\n                            },\n                            program: 'config',\n                            space: 10n,\n                        },\n                        executable: false,\n                        lamports: 960480n,\n                        owner: 'Config1111111111111111111111111111111111111',\n                        rentEpoch: 0n,\n                        space: 10n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for Nonce account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/nonce-account.json\n                const publicKey =\n                    'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU' as Address<'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    authority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                    blockhash: 'TcVy2wVcs7WqWVopv8LAJBHQfqVYZrm8UDqjDvBFQt8',\n                                    feeCalculator: {\n                                        lamportsPerSignature: expect.stringMatching(/\\d+/),\n                                    },\n                                },\n                                type: 'initialized',\n                            },\n                            program: 'nonce',\n                            space: 80n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: '11111111111111111111111111111111',\n                        rentEpoch: 0n,\n                        space: 80n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for SPL Token mint account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-account.json\n                const publicKey =\n                    'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address<'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    decimals: 6,\n                                    freezeAuthority: null,\n                                    isInitialized: true,\n                                    mintAuthority: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                                    supply: '1690580887590527729',\n                                },\n                                type: 'mint',\n                            },\n                            program: 'spl-token',\n                            space: 82n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        rentEpoch: 0n,\n                        space: 82n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for SPL Token token account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-account.json\n                const publicKey =\n                    'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca' as Address<'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    isNative: false,\n                                    mint: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                                    owner: '6UsGbaMgchgj4wiwKKuE1v5URHdcDfEiMSM25QpesKir',\n                                    state: 'initialized',\n                                    tokenAmount: {\n                                        amount: '9999999779500000',\n                                        decimals: 6,\n                                        uiAmount: 9999999779.5,\n                                        uiAmountString: '9999999779.5',\n                                    },\n                                },\n                                type: 'account',\n                            },\n                            program: 'spl-token',\n                            space: 165n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        rentEpoch: 0n,\n                        space: 165n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for SPL token multisig account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-account.json\n                const publicKey =\n                    '4Uh9vK5nnxfskc73asy7AeRYDfZocrv1th9DEjtdCn88' as Address<'4Uh9vK5nnxfskc73asy7AeRYDfZocrv1th9DEjtdCn88'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    isInitialized: true,\n                                    numRequiredSigners: 2,\n                                    numValidSigners: 2,\n                                    signers: [\n                                        'Fkc4FN7PPhyGsAcHPW3dBBJ4BvtYkDr2rBFBgFpvy3nB',\n                                        '5scSndUhfZJ8j8wZz5UNHhvuPBhvN1RboTdkKSvFHLtW',\n                                    ],\n                                },\n                                type: 'multisig',\n                            },\n                            program: 'spl-token',\n                            space: 355n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        rentEpoch: 0n,\n                        space: 355n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for SPL Token 22 mint account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-22-mint-account.json\n                const publicKey =\n                    'CKfatsPMUf8SkiURsDXs7eK6GWb4Jsd6UDbs7twMCWxo' as Address<'CKfatsPMUf8SkiURsDXs7eK6GWb4Jsd6UDbs7twMCWxo'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    decimals: 5,\n                                    extensions: [\n                                        {\n                                            extension: 'transferFeeConfig',\n                                            state: {\n                                                newerTransferFee: {\n                                                    epoch: 457n,\n                                                    maximumFee: 3906250000000000000n,\n                                                    transferFeeBasisPoints: 690,\n                                                },\n                                                olderTransferFee: {\n                                                    epoch: 455n,\n                                                    maximumFee: 3906250000000000000n,\n                                                    transferFeeBasisPoints: 0,\n                                                },\n                                                transferFeeConfigAuthority:\n                                                    '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                withdrawWithheldAuthority:\n                                                    '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                withheldAmount: 0n,\n                                            },\n                                        },\n                                    ],\n                                    freezeAuthority: '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                    isInitialized: true,\n                                    mintAuthority: '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                    supply: '99998926239436',\n                                },\n                                type: 'mint',\n                            },\n                            program: 'spl-token-2022',\n                            space: 278n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                        rentEpoch: 0n,\n                        space: 278n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for Stake account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/stake-account.json\n                const publicKey =\n                    'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN' as Address<'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    meta: {\n                                        authorized: {\n                                            staker: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                            withdrawer: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                        },\n                                        lockup: {\n                                            custodian: '11111111111111111111111111111111',\n                                            epoch: 0n,\n                                            unixTimestamp: 0n,\n                                        },\n                                        rentExemptReserve: '2282880',\n                                    },\n                                    stake: {\n                                        creditsObserved: 169965713n,\n                                        delegation: {\n                                            activationEpoch: '386',\n                                            deactivationEpoch: '471',\n                                            stake: '8007935',\n                                            voter: 'CertusDeBmqN8ZawdkxK5kFGMwBXdudvWHYwtNgNhvLu',\n                                            warmupCooldownRate: 0.25,\n                                        },\n                                    },\n                                },\n                                type: 'delegated',\n                            },\n                            program: 'stake',\n                            space: 200n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: 'Stake11111111111111111111111111111111111111',\n                        rentEpoch: 0n,\n                        space: 200n,\n                    },\n                });\n            });\n\n            it('returns parsed JSON data for Sysvar rent account', async () => {\n                expect.assertions(1);\n                // Sysvar accounts don't need a fixture\n                const publicKey =\n                    'SysvarRent111111111111111111111111111111111' as Address<'SysvarRent111111111111111111111111111111111'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: expect.objectContaining({\n                        data: {\n                            parsed: {\n                                info: expect.objectContaining({\n                                    burnPercent: 50,\n                                    exemptionThreshold: 1,\n                                    lamportsPerByteYear: '6960',\n                                }),\n                                type: 'rent',\n                            },\n                            program: 'sysvar',\n                            space: 17n,\n                        },\n                        executable: false,\n                        owner: 'Sysvar1111111111111111111111111111111111111',\n                    }),\n                });\n            });\n\n            it('returns parsed JSON data for Vote account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/vote-account.json\n                const publicKey =\n                    '4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp' as Address<'4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp'>;\n\n                const accountInfoPromise = rpc\n                    .getAccountInfo(publicKey, {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                await expect(accountInfoPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: expect.objectContaining({\n                        data: {\n                            parsed: {\n                                info: expect.objectContaining({\n                                    authorizedVoters: [\n                                        {\n                                            authorizedVoter: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                            epoch: 656n,\n                                        },\n                                    ],\n                                    authorizedWithdrawer: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                    blockRevenueCollector: expect.any(String),\n                                    blockRevenueCommissionBps: expect.any(BigInt),\n                                    blsPubkeyCompressed: null,\n                                    commission: 50,\n                                    epochCredits: expect.arrayContaining([\n                                        {\n                                            credits: '117764802',\n                                            epoch: 593n,\n                                            previousCredits: '117762806',\n                                        },\n                                        {\n                                            credits: '118161978',\n                                            epoch: 594n,\n                                            previousCredits: '117764802',\n                                        },\n                                        {\n                                            credits: '118593951',\n                                            epoch: 595n,\n                                            previousCredits: '118161978',\n                                        },\n                                        {\n                                            credits: '119025928',\n                                            epoch: 596n,\n                                            previousCredits: '118593951',\n                                        },\n                                        {\n                                            credits: '119456860',\n                                            epoch: 597n,\n                                            previousCredits: '119025928',\n                                        },\n                                        {\n                                            credits: '119770741',\n                                            epoch: 598n,\n                                            previousCredits: '119456860',\n                                        },\n                                        {\n                                            credits: '119773739',\n                                            epoch: 599n,\n                                            previousCredits: '119770741',\n                                        },\n                                        {\n                                            credits: '119777233',\n                                            epoch: 600n,\n                                            previousCredits: '119773739',\n                                        },\n                                        {\n                                            credits: '119780053',\n                                            epoch: 601n,\n                                            previousCredits: '119777233',\n                                        },\n                                        {\n                                            credits: '119783284',\n                                            epoch: 602n,\n                                            previousCredits: '119780053',\n                                        },\n                                        {\n                                            credits: '119786399',\n                                            epoch: 603n,\n                                            previousCredits: '119783284',\n                                        },\n                                        {\n                                            credits: '119788422',\n                                            epoch: 604n,\n                                            previousCredits: '119786399',\n                                        },\n                                        {\n                                            credits: '119791169',\n                                            epoch: 605n,\n                                            previousCredits: '119788422',\n                                        },\n                                        {\n                                            credits: '119793299',\n                                            epoch: 606n,\n                                            previousCredits: '119791169',\n                                        },\n                                        {\n                                            credits: '119796454',\n                                            epoch: 607n,\n                                            previousCredits: '119793299',\n                                        },\n                                        {\n                                            credits: '119799687',\n                                            epoch: 608n,\n                                            previousCredits: '119796454',\n                                        },\n                                        {\n                                            credits: '119802861',\n                                            epoch: 609n,\n                                            previousCredits: '119799687',\n                                        },\n                                        {\n                                            credits: '119804679',\n                                            epoch: 610n,\n                                            previousCredits: '119802861',\n                                        },\n                                        {\n                                            credits: '119807952',\n                                            epoch: 611n,\n                                            previousCredits: '119804679',\n                                        },\n                                        {\n                                            credits: '119810634',\n                                            epoch: 612n,\n                                            previousCredits: '119807952',\n                                        },\n                                        {\n                                            credits: '119813372',\n                                            epoch: 613n,\n                                            previousCredits: '119810634',\n                                        },\n                                        {\n                                            credits: '119816503',\n                                            epoch: 614n,\n                                            previousCredits: '119813372',\n                                        },\n                                        {\n                                            credits: '119819850',\n                                            epoch: 615n,\n                                            previousCredits: '119816503',\n                                        },\n                                        {\n                                            credits: '119823406',\n                                            epoch: 616n,\n                                            previousCredits: '119819850',\n                                        },\n                                        {\n                                            credits: '119825752',\n                                            epoch: 617n,\n                                            previousCredits: '119823406',\n                                        },\n                                        {\n                                            credits: '119828458',\n                                            epoch: 618n,\n                                            previousCredits: '119825752',\n                                        },\n                                        {\n                                            credits: '119830399',\n                                            epoch: 619n,\n                                            previousCredits: '119828458',\n                                        },\n                                        {\n                                            credits: '119833206',\n                                            epoch: 620n,\n                                            previousCredits: '119830399',\n                                        },\n                                        {\n                                            credits: '119836333',\n                                            epoch: 621n,\n                                            previousCredits: '119833206',\n                                        },\n                                        {\n                                            credits: '119839690',\n                                            epoch: 622n,\n                                            previousCredits: '119836333',\n                                        },\n                                        {\n                                            credits: '119842672',\n                                            epoch: 623n,\n                                            previousCredits: '119839690',\n                                        },\n                                        {\n                                            credits: '119845737',\n                                            epoch: 624n,\n                                            previousCredits: '119842672',\n                                        },\n                                        {\n                                            credits: '119848231',\n                                            epoch: 625n,\n                                            previousCredits: '119845737',\n                                        },\n                                        {\n                                            credits: '119851184',\n                                            epoch: 626n,\n                                            previousCredits: '119848231',\n                                        },\n                                        {\n                                            credits: '119854617',\n                                            epoch: 627n,\n                                            previousCredits: '119851184',\n                                        },\n                                        {\n                                            credits: '119856852',\n                                            epoch: 628n,\n                                            previousCredits: '119854617',\n                                        },\n                                        {\n                                            credits: '119860362',\n                                            epoch: 629n,\n                                            previousCredits: '119856852',\n                                        },\n                                        {\n                                            credits: '119863578',\n                                            epoch: 630n,\n                                            previousCredits: '119860362',\n                                        },\n                                        {\n                                            credits: '119867336',\n                                            epoch: 631n,\n                                            previousCredits: '119863578',\n                                        },\n                                        {\n                                            credits: '119871382',\n                                            epoch: 632n,\n                                            previousCredits: '119867336',\n                                        },\n                                        {\n                                            credits: '119874725',\n                                            epoch: 633n,\n                                            previousCredits: '119871382',\n                                        },\n                                        {\n                                            credits: '119878010',\n                                            epoch: 634n,\n                                            previousCredits: '119874725',\n                                        },\n                                        {\n                                            credits: '119881019',\n                                            epoch: 635n,\n                                            previousCredits: '119878010',\n                                        },\n                                        {\n                                            credits: '119884533',\n                                            epoch: 636n,\n                                            previousCredits: '119881019',\n                                        },\n                                        {\n                                            credits: '119887482',\n                                            epoch: 637n,\n                                            previousCredits: '119884533',\n                                        },\n                                        {\n                                            credits: '119890917',\n                                            epoch: 638n,\n                                            previousCredits: '119887482',\n                                        },\n                                        {\n                                            credits: '119891583',\n                                            epoch: 639n,\n                                            previousCredits: '119890917',\n                                        },\n                                        {\n                                            credits: '119894976',\n                                            epoch: 640n,\n                                            previousCredits: '119891583',\n                                        },\n                                        {\n                                            credits: '119897217',\n                                            epoch: 641n,\n                                            previousCredits: '119894976',\n                                        },\n                                        {\n                                            credits: '119899074',\n                                            epoch: 642n,\n                                            previousCredits: '119897217',\n                                        },\n                                        {\n                                            credits: '119902893',\n                                            epoch: 643n,\n                                            previousCredits: '119899074',\n                                        },\n                                        {\n                                            credits: '119905968',\n                                            epoch: 644n,\n                                            previousCredits: '119902893',\n                                        },\n                                        {\n                                            credits: '119909166',\n                                            epoch: 645n,\n                                            previousCredits: '119905968',\n                                        },\n                                        {\n                                            credits: '119912335',\n                                            epoch: 646n,\n                                            previousCredits: '119909166',\n                                        },\n                                        {\n                                            credits: '119916478',\n                                            epoch: 647n,\n                                            previousCredits: '119912335',\n                                        },\n                                        {\n                                            credits: '119919918',\n                                            epoch: 648n,\n                                            previousCredits: '119916478',\n                                        },\n                                        {\n                                            credits: '120283578',\n                                            epoch: 649n,\n                                            previousCredits: '119919918',\n                                        },\n                                        {\n                                            credits: '120325223',\n                                            epoch: 650n,\n                                            previousCredits: '120283578',\n                                        },\n                                        {\n                                            credits: '120329512',\n                                            epoch: 651n,\n                                            previousCredits: '120325223',\n                                        },\n                                        {\n                                            credits: '120333844',\n                                            epoch: 652n,\n                                            previousCredits: '120329512',\n                                        },\n                                        {\n                                            credits: '120337635',\n                                            epoch: 653n,\n                                            previousCredits: '120333844',\n                                        },\n                                        {\n                                            credits: '120341034',\n                                            epoch: 654n,\n                                            previousCredits: '120337635',\n                                        },\n                                        {\n                                            credits: '120345192',\n                                            epoch: 655n,\n                                            previousCredits: '120341034',\n                                        },\n                                        {\n                                            credits: '120347138',\n                                            epoch: 656n,\n                                            previousCredits: '120345192',\n                                        },\n                                    ]),\n                                    inflationRewardsCollector: expect.any(String),\n                                    inflationRewardsCommissionBps: expect.any(BigInt),\n                                    lastTimestamp: {\n                                        slot: 283619438n,\n                                        timestamp: 1709828565n,\n                                    },\n                                    nodePubkey: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                    pendingDelegatorRewards: expect.any(String),\n                                    priorVoters: [],\n                                    rootSlot: 283619407n,\n                                    votes: expect.any(Array),\n                                }),\n                                type: 'vote',\n                            },\n                            program: 'vote',\n                            space: 3762n,\n                        },\n                        executable: false,\n                        lamports: 10290815n,\n                        owner: 'Vote111111111111111111111111111111111111111',\n                        rentEpoch: 0n,\n                        space: 3762n,\n                    }),\n                });\n            });\n        });\n    });\n\n    describe('when called with no encoding', () => {\n        it('returns base58 data without an annotation', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const accountInfo = await rpc.getAccountInfo(publicKey, {}).send();\n\n            expect(accountInfo.value?.data).toBe('2Uw1bpnsXxu3e');\n        });\n    });\n\n    describe('when called with a dataSlice', () => {\n        it('returns the correct slice of the data', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const accountInfo = await rpc\n                .getAccountInfo(publicKey, {\n                    dataSlice: {\n                        length: 5,\n                        offset: 0,\n                    },\n                    encoding: 'base64',\n                })\n                .send();\n\n            expect(accountInfo.value?.data).toStrictEqual(['dGVzdCA=', 'base64']);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-balance-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetBalanceApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getBalance', () => {\n    let rpc: Rpc<GetBalanceApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns a balance of zero for a new address', async () => {\n                expect.assertions(1);\n                // This key is random, don't re-use in any tests that affect balance\n                const publicKey =\n                    '4BfxgLzn6pEuVB2ynBMqckHFdYD8VNcrheDFFCB6U5TH' as Address<'4BfxgLzn6pEuVB2ynBMqckHFdYD8VNcrheDFFCB6U5TH'>;\n                const balancePromise = rpc.getBalance(publicKey).send();\n                await expect(balancePromise).resolves.toHaveProperty('value', BigInt(0));\n            });\n        });\n    });\n\n    describe('given an account with a non-zero balance', () => {\n        // See scripts/fixtures/4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc.json\n        const publicKey =\n            '4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc' as Address<'4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc'>;\n        it('returns the correct balance', async () => {\n            expect.assertions(1);\n            const balancePromise = rpc.getBalance(publicKey).send();\n            await expect(balancePromise).resolves.toHaveProperty('value', BigInt(5_000_000));\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            // This key is random, don't re-use in any tests that affect balance\n            const publicKey =\n                '4BfxgLzn6pEuVB2ynBMqckHFdYD8VNcrheDFFCB6U5TH' as Address<'4BfxgLzn6pEuVB2ynBMqckHFdYD8VNcrheDFFCB6U5TH'>;\n            const sendPromise = rpc\n                .getBalance(publicKey, {\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-block-commitment-test.ts",
    "content": "describe('getBlockCommitment', () => {\n    // TODO: We need a good way to feed `getBlockCommitment` a recent block.\n    // This would actually return a value for commitment.\n    // This is tricky to do without `getSlot`, and we'll need some kind\n    // of manipulation capability over test-validator to pull it off without\n    // another RPC call.\n    it.todo('returns the block commitment for a recent block');\n\n    // TODO: We also need a reliable way to feed `getBlockCommitment` an old block.\n    it.todo('returns the block commitment for an older block, which has null commitment');\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-block-height.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetBlockHeightApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getBlockHeight', () => {\n    let rpc: Rpc<GetBlockHeightApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the result as a bigint', async () => {\n                expect.assertions(1);\n                const result = await rpc.getBlockHeight({ commitment }).send();\n                expect(result).toEqual(expect.any(BigInt));\n            });\n        });\n    });\n    describe('when called with a `minContextSlot` of 0', () => {\n        it('returns the result as a bigint', async () => {\n            expect.assertions(1);\n            const result = await rpc.getBlockHeight({ minContextSlot: 0n }).send();\n            expect(result).toEqual(expect.any(BigInt));\n        });\n    });\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const sendPromise = rpc\n                .getBlockHeight({\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-block-production-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetBlockProductionApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getBlockProduction', () => {\n    let rpc: Rpc<GetBlockProductionApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns block production data', async () => {\n                expect.assertions(1);\n                const blockProductionPromise = rpc.getBlockProduction({ commitment }).send();\n                await expect(blockProductionPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        // FIXME: https://stackoverflow.com/questions/77204507/how-can-you-match-on-wildcard-object-keys-using-jest-matchers\n                        byIdentity: expect.any(Object),\n                        range: {\n                            firstSlot: expect.any(BigInt),\n                            lastSlot: expect.any(BigInt),\n                        },\n                    },\n                });\n            });\n\n            it('has the latest context slot as the last slot', async () => {\n                expect.assertions(1);\n                const blockProduction = await rpc.getBlockProduction({ commitment }).send();\n                expect(blockProduction.value.range.lastSlot).toBe(blockProduction.context.slot);\n            });\n        });\n    });\n\n    describe('when called with a single identity', () => {\n        // Currently this call always returns just one identity in tests, so no way to meaningfully test this\n        it.todo('returns data for just that identity');\n\n        it('returns an empty byIdentity if the identity is not a block producer', async () => {\n            expect.assertions(1);\n            // Randomly generated address, assumed not to be a block producer\n            const identity =\n                '9NmqDDZa7mH1DBM4zeq9cm7VcRn2un1i2TwuMvjBoVhU' as Address<'9NmqDDZa7mH1DBM4zeq9cm7VcRn2un1i2TwuMvjBoVhU'>;\n            const blockProductionPromise = rpc.getBlockProduction({ identity }).send();\n            await expect(blockProductionPromise).resolves.toMatchObject({\n                value: {\n                    byIdentity: {},\n                },\n            });\n        });\n    });\n\n    describe('when called with a `lastSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const blockProductionPromise = rpc\n                .getBlockProduction({\n                    range: {\n                        firstSlot: 0n,\n                        lastSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                    },\n                })\n                .send();\n            await Promise.all([\n                expect(blockProductionPromise).rejects.toThrow(SolanaError),\n                expect(blockProductionPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n                ),\n                expect(blockProductionPromise).rejects.toHaveProperty(\n                    'context.__serverMessage',\n                    expect.stringMatching(/lastSlot, 9223372036854776000, is too large; max \\d+/),\n                ),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-block-test.ts",
    "content": "describe('when `transactionDetails` is set to `full`', () => {\n    describe('returns transactions with the correct shape', () => {\n        it.todo('when called with json encoding and maxSupportedTransactionVersion is set');\n        it.todo('when called with jsonParsed encoding and maxSupportedTransactionVersion is set');\n        it.todo('when called with base58 encoding and maxSupportedTransactionVersion is set');\n        it.todo('when called with base64 encoding and maxSupportedTransactionVersion is set');\n        it.todo('when called with json encoding and maxSupportedTransactionVersion is not set');\n        it.todo('when called with jsonParsed encoding and maxSupportedTransactionVersion is not set');\n        it.todo('when called with base58 encoding and maxSupportedTransactionVersion is not set');\n        it.todo('when called with base64 encoding and maxSupportedTransactionVersion is not set');\n        it.todo('when called without additional config');\n    });\n});\n\ndescribe('when `transactionDetails` is set to `accounts`', () => {\n    describe('returns transactions with only signatures and an annotated list of accounts', () => {\n        it.todo('when maxSupportedTransactionVersion is set');\n        it.todo('when maxSupportedTransactionVersion is not set');\n        it.todo('when called without additional config');\n    });\n});\n\ndescribe('when `transactionDetails` is set to `signatures`', () => {\n    describe('returns transactions with only signatures', () => {\n        it.todo('when maxSupportedTransactionVersion is set');\n        it.todo('when maxSupportedTransactionVersion is not set');\n        it.todo('when called without additional config');\n    });\n});\n\ndescribe('when `transactionDetails` is set to `none`', () => {\n    describe('when called with rewards set to false', () => {\n        it.todo('returns an empty array for transactions and an empty array for rewards');\n    });\n\n    describe('when called with rewards set to true', () => {\n        it.todo('returns no transactions and an array of rewards for rewards');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-block-time-test.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { GetBlockTimeApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getBlockTime', () => {\n    let rpc: Rpc<GetBlockTimeApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    describe('when called with a currently available block', () => {\n        // TODO: either use getFirstAvailableBlock when implemented, or we'll need a way to control the ledger\n        it.todo('returns a block time');\n    });\n\n    describe('when called with a block that has been cleaned up', () => {\n        // TODO: will need a way to control the ledger and get a past block that has been cleaned up\n        // Expected error:\n        /*\n    \"error\": {\n      \"code\": -32001,\n      \"message\": \"Block 150 cleaned up, does not exist on node. First available block: 141077\"\n    }\n    */\n        it.todo('returns an error');\n    });\n\n    describe('when called with a block higher than the highest block available', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const blockNumber = 2n ** 63n - 1n; // u64:MAX; safe bet it'll be too high.\n            const blockTimePromise = rpc.getBlockTime(blockNumber).send();\n            await expect(blockTimePromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE, {\n                    __serverMessage: 'Block not available for slot 9223372036854776000',\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-blocks-with-limit-test.ts",
    "content": "import type { Commitment } from '@solana/rpc-types';\n\ndescribe('getBlocksWithLimit', () => {\n    (['confirmed', 'finalized'] as Exclude<Commitment, 'processed'>[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            describe('when called with a valid `startSlot` and a valid `limit`', () => {\n                // On the test validator, finalized blocks tend to be available ~35 slots\n                // after the current confirmed slot.\n                // So we'll have to wait for a few blocks to be confirmed before we can test this.\n                it.todo('returns 5 blocks for a limit of 5');\n            });\n\n            describe('when called with a valid `startSlot` and a `limit` of 0', () => {\n                it.todo('returns an empty array');\n            });\n\n            describe('when called with a `limit` resulting in a slot higher than the highest slot available', () => {\n                // TODO: We need to be able to deterministically set the highest slot\n                // so we can test against it, but without making an RPC call like\n                // `getSlot` which would defeat the purpose of this test.\n                it.todo('returns up to the highest slot available');\n            });\n\n            describe('when called with a `startSlot` higher than the highest slot available', () => {\n                it.todo('returns an empty array');\n            });\n\n            describe('when called with a `limit` higher than 500,000', () => {\n                it.todo('throws an error');\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-cluster-nodes-test.ts",
    "content": "import { open } from 'node:fs/promises';\n\nimport type { Rpc } from '@solana/rpc-spec';\nimport path from 'path';\n\nimport { GetClusterNodesApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst logFilePath = path.resolve(__dirname, '../../../../test-ledger/validator.log');\n\n// TPU does not seem to be reliably matchable from the log file\nconst featureSetPattern = /feat:([\\d]+)/;\nconst gossipPattern = /local gossip address: [\\d.]+:([\\d]+)/;\nconst pubkeyPattern = /identity pubkey: ([\\w]{32,})/;\nconst rpcPattern = /rpc bound to [\\d.]+:([\\d]+)/;\nconst shredVersionPattern = /shred_version: ([\\d]+)/;\nconst versionPattern = /agave-validator ([\\d.]+)/;\n\nasync function getNodeInfoFromLogFile() {\n    const file = await open(logFilePath);\n    try {\n        let featureSet: number | undefined;\n        let gossip: string | undefined;\n        let pubkey: string | undefined;\n        let rpc: string | undefined;\n        let shredVersion: number | undefined;\n        let version: string | undefined;\n        for await (const line of file.readLines({ encoding: 'utf-8' })) {\n            const featureSetMatch = line.match(featureSetPattern);\n            if (featureSetMatch) {\n                featureSet = parseInt(featureSetMatch[1]);\n            }\n            const gossipMatch = line.match(gossipPattern);\n            if (gossipMatch) {\n                gossip = '127.0.0.1:' + gossipMatch[1];\n            }\n            const pubkeyMatch = line.match(pubkeyPattern);\n            if (pubkeyMatch) {\n                pubkey = pubkeyMatch[1];\n            }\n            const rpcMatch = line.match(rpcPattern);\n            if (rpcMatch) {\n                rpc = '127.0.0.1:' + rpcMatch[1];\n            }\n            const shredVersionMatch = line.match(shredVersionPattern);\n            if (shredVersionMatch) {\n                shredVersion = parseInt(shredVersionMatch[1]);\n            }\n            const versionMatch = line.match(versionPattern);\n            if (versionMatch) {\n                version = versionMatch[1];\n            }\n            if (featureSet && gossip && pubkey && rpc && shredVersion && version) {\n                return [featureSet, gossip, pubkey, rpc, shredVersion, version] as const;\n            }\n        }\n        throw new Error(`Node info not found in logfile \\`${logFilePath}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getClusterNodes', () => {\n    let mockRpc: Rpc<GetClusterNodesApi>;\n    beforeEach(() => {\n        mockRpc = createLocalhostSolanaRpc();\n    });\n\n    describe('when run against the test validator', () => {\n        it('returns RPC and validator info', async () => {\n            expect.assertions(1);\n            const [featureSet, gossip, pubkey, rpc, shredVersion, version] = await getNodeInfoFromLogFile();\n            const res = await mockRpc.getClusterNodes().send();\n            expect(res[0]).toStrictEqual({\n                featureSet,\n                gossip,\n                pubkey,\n                pubsub: expect.stringMatching(/127.0.0.1(:\\d+)?/),\n                rpc,\n                serveRepair: expect.stringMatching(/127.0.0.1(:\\d+)?/),\n                shredVersion,\n                tpu: expect.stringMatching(/127.0.0.1(:\\d+)?/),\n                tpuForwards: expect.stringMatching(/127.0.0.1(:\\d+)?/),\n                tpuForwardsQuic: expect.stringMatching(/127.0.0.1(:\\d+)?/),\n                tpuQuic: expect.stringMatching(/127.0.0.1(:\\d+)?/),\n                tpuVote: expect.stringMatching(/127.0.0.1(:\\d+)?/),\n                tvu: expect.stringMatching(/127.0.0.1(:\\d+)?/),\n                version,\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-epoch-info-test.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetEpochInfoApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getEpochInfo', () => {\n    let rpc: Rpc<GetEpochInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns epoch info', async () => {\n                expect.assertions(1);\n                const epochInfoPromise = rpc.getEpochInfo().send();\n                await expect(epochInfoPromise).resolves.toStrictEqual({\n                    absoluteSlot: expect.any(BigInt),\n                    blockHeight: expect.any(BigInt),\n                    epoch: expect.any(BigInt),\n                    slotIndex: expect.any(BigInt),\n                    slotsInEpoch: expect.any(BigInt),\n                    transactionCount: expect.any(BigInt),\n                });\n            });\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const epochInfoPromise = rpc\n                .getEpochInfo({\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(epochInfoPromise).rejects.toThrow(SolanaError),\n                expect(epochInfoPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(epochInfoPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-epoch-schedule-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\n\nimport { GetEpochScheduleApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getEpochSchedule', () => {\n    let rpc: Rpc<GetEpochScheduleApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    it('returns the epoch schedule', async () => {\n        expect.assertions(1);\n        const epochSchedulePromise = rpc.getEpochSchedule().send();\n        await expect(epochSchedulePromise).resolves.toStrictEqual({\n            firstNormalEpoch: expect.any(BigInt),\n            firstNormalSlot: expect.any(BigInt),\n            leaderScheduleSlotOffset: expect.any(BigInt),\n            slotsPerEpoch: expect.any(BigInt),\n            warmup: expect.any(Boolean),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-fee-for-message-test.ts",
    "content": "import { fixEncoderSize } from '@solana/codecs-core';\nimport { getBase58Encoder, getBase64Decoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SolanaError,\n} from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Blockhash, Commitment } from '@solana/rpc-types';\nimport type { TransactionMessageBytesBase64 } from '@solana/transactions';\n\nimport { GetFeeForMessageApi, GetLatestBlockhashApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n// See scripts/fixtures/send-transaction-fee-payer.json\nconst MOCK_PUBLIC_KEY_BYTES = // DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i\n    // prettier-ignore\n    new Uint8Array([\n        0xb8, 0xac, 0x70, 0x4f, 0xaf, 0xc7, 0xa5, 0xfc, 0x8c, 0x5d, 0x1f, 0x0a, 0xc8, 0xcf, 0xaa, 0xe0,\n        0x42, 0xfa, 0x3b, 0xb8, 0x25, 0xf0, 0xec, 0xfc, 0xe2, 0x27, 0x4d, 0x7d, 0xad, 0xad, 0x51, 0x2d,\n    ]);\n\nfunction getMockTransactionMessage(blockhash: Blockhash) {\n    const memoString = 'Hello from the Kit tests!';\n    const blockhashBytes = fixEncoderSize(getBase58Encoder(), 32).encode(blockhash);\n    // prettier-ignore\n    const message = new Uint8Array([\n        /** VERSION HEADER */\n        0x80, // 0 + version mask\n\n        /** MESSAGE HEADER */\n        0x01, // numSignerAccounts\n        0x00, // numReadonlySignerAccount\n        0x01, // numReadonlyNonSignerAccounts\n\n        /** STATIC ADDRESSES */\n        0x02, // Number of static accounts\n            ...MOCK_PUBLIC_KEY_BYTES,\n            0x05, 0x4a, 0x53, 0x5a, 0x99, 0x29, 0x21, 0x06, 0x4d, 0x24, 0xe8, 0x71, 0x60, 0xda, 0x38, 0x7c, 0x7c, 0x35, 0xb5, 0xdd, 0xbc, 0x92, 0xbb, 0x81, 0xe4, 0x1f, 0xa8, 0x40, 0x41, 0x05, 0x44, 0x8d, // MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\n\n        /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n        ...blockhashBytes,\n\n        /* INSTRUCTIONS */\n        0x01, // Number of instructions\n\n            // First instruction\n            0x01, // Program address index\n            0x00, // Number of address indices\n            memoString.length, // Length of instruction data\n                ...new TextEncoder().encode(memoString),\n\n        /** ADDRESS TABLE LOOKUPS */\n        0x00, // Number of address table lookups\n    ]);\n    return getBase64Decoder().decode(message) as TransactionMessageBytesBase64;\n}\n\ndescribe('getFeeForMessage', () => {\n    let rpc: Rpc<GetFeeForMessageApi & GetLatestBlockhashApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            if (commitment === 'finalized') {\n                it.todo(\n                    'returns the result as a bigint (test broken; see https://discord.com/channels/428295358100013066/560496939779620864/1132048104728825926)',\n                );\n                return;\n            }\n            describe('when called with a recent blockhash', () => {\n                it('returns the result as a bigint', async () => {\n                    expect.assertions(1);\n                    const latestBlockhash = await rpc.getLatestBlockhash({ commitment }).send();\n                    const message = getMockTransactionMessage(latestBlockhash.value.blockhash);\n                    const result = await rpc.getFeeForMessage(message, { commitment }).send();\n                    expect(result).toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        value: expect.any(BigInt),\n                    });\n                });\n            });\n\n            describe('when called with an old blockhash', () => {\n                // TODO: There's no way to deterministically get an old blockhash\n                it.todo('returns null');\n            });\n\n            describe('when called with a blockhash that does not exist', () => {\n                it('returns null', async () => {\n                    expect.assertions(1);\n                    const message = getMockTransactionMessage(\n                        // Randomly generated\n                        'BnWCFuxmi6uH3ceVx4R8qcbWBMPVVYVVFWtAiiTA1PAu' as Blockhash,\n                    );\n                    const result = await rpc.getFeeForMessage(message, { commitment }).send();\n                    expect(result).toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        value: null,\n                    });\n                });\n            });\n        });\n    });\n\n    describe('when called with an invalid message', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const sendPromise = rpc.getFeeForMessage('someInvalidMessage' as TransactionMessageBytesBase64).send();\n            await expect(sendPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'invalid base64 encoding: InvalidPadding',\n                }),\n            );\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const latestBlockhash = await rpc.getLatestBlockhash().send();\n            const message = getMockTransactionMessage(latestBlockhash.value.blockhash);\n            const sendPromise = rpc\n                .getFeeForMessage(message, {\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-first-available-block-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\n\nimport { GetFirstAvailableBlockApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getFirstAvailableBlock', () => {\n    let rpc: Rpc<GetFirstAvailableBlockApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    describe('when called with no parameters', () => {\n        it('returns a bigint', async () => {\n            expect.assertions(1);\n            const result = await rpc.getFirstAvailableBlock().send();\n            expect(result).toEqual(expect.any(BigInt));\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-genesis-hash-test.ts",
    "content": "import { open } from 'node:fs/promises';\n\nimport type { Rpc } from '@solana/rpc-spec';\nimport path from 'path';\n\nimport { GetGenesisHashApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst logFilePath = path.resolve(__dirname, '../../../../test-ledger/validator.log');\nconst genesisHashPattern = /genesis hash: ([\\d\\w]{32,})/;\n\nasync function getGenesisHashFromLogFile() {\n    const file = await open(logFilePath);\n    try {\n        for await (const line of file.readLines({ encoding: 'utf-8' })) {\n            const match = line.match(genesisHashPattern);\n            if (match) {\n                return match[1];\n            }\n        }\n        throw new Error(`Genesis hash not found in logfile \\`${logFilePath}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getGenesisHash', () => {\n    let rpc: Rpc<GetGenesisHashApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    describe('when sent to a local validator', () => {\n        it('returns the genesis hash', async () => {\n            expect.assertions(1);\n            const expectedGenesisHash = await getGenesisHashFromLogFile();\n            const genesisHashPromise = rpc.getGenesisHash().send();\n            await expect(genesisHashPromise).resolves.toBe(expectedGenesisHash);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-health-test.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY, SolanaError } from '@solana/errors';\nimport { createRpc, type Rpc } from '@solana/rpc-spec';\n\nimport { createSolanaRpcApi, GetHealthApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getHealth', () => {\n    describe('when the node is healthy', () => {\n        let rpc: Rpc<GetHealthApi>;\n        beforeEach(() => {\n            rpc = createLocalhostSolanaRpc();\n        });\n        it('returns \"ok\"', async () => {\n            expect.assertions(1);\n            const healthPromise = rpc.getHealth().send();\n            await expect(healthPromise).resolves.toBe('ok');\n        });\n    });\n\n    describe('when the node is unhealthy', () => {\n        let rpc: Rpc<GetHealthApi>;\n        const errorMessage = 'Node is unhealthy';\n        const errorCode = SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY;\n        const errorObject = {\n            code: errorCode,\n            data: { numSlotsBehind: 123 },\n            message: errorMessage,\n        };\n        beforeEach(() => {\n            rpc = createRpc({\n                api: createSolanaRpcApi(),\n                transport: jest.fn().mockResolvedValue({ error: errorObject }),\n            });\n        });\n        it('returns an error message', async () => {\n            expect.assertions(1);\n            const healthPromise = rpc.getHealth().send();\n            await expect(healthPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY, {\n                    numSlotsBehind: 123,\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-highest-snapshot-slot-test.ts",
    "content": "// TODO: Again, until we can manipulate the local validator more,\n// this test can't be implemented properly.\ndescribe('getHighestSnapshotSlot', () => {\n    describe('when there is at least one valid snapshot', () => {\n        it.todo('returns the highest snapshot slot information that the node has snapshots for');\n    });\n\n    describe('when there are no snapshots yet', () => {\n        // TODO:\n        //  Error code -32008\n        //  Message: \"No snapshot\"\n        it.todo('throws an error');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-identity-test.ts",
    "content": "import { open } from 'node:fs/promises';\n\nimport type { Address } from '@solana/addresses';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport type { Rpc } from '@solana/rpc-spec';\nimport path from 'path';\n\nimport { GetIdentityApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst validatorKeypairPath = path.resolve(__dirname, '../../../../test-ledger/validator-keypair.json');\n\nasync function getValidatorAddress() {\n    const file = await open(validatorKeypairPath);\n    try {\n        let secretKey: Uint8Array | undefined;\n        for await (const line of file.readLines({ encoding: 'binary' })) {\n            secretKey = new Uint8Array(JSON.parse(line));\n            break; // Only need the first line\n        }\n        if (secretKey) {\n            const publicKey = secretKey.slice(32, 64);\n            const expectedAddress = getBase58Decoder().decode(publicKey);\n            return expectedAddress as Address;\n        }\n        throw new Error(`Failed to read keypair file \\`${validatorKeypairPath}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getIdentity', () => {\n    let rpc: Rpc<GetIdentityApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    it('returns the identity of the currently running local validator', async () => {\n        expect.assertions(1);\n        const expectedAddress = await getValidatorAddress();\n        const identityPromise = rpc.getIdentity().send();\n        await expect(identityPromise).resolves.toStrictEqual({\n            identity: expectedAddress,\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-inflation-governor-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetInflationGovernorApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getInflationGovernor', () => {\n    let rpc: Rpc<GetInflationGovernorApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    // TODO: I honestly have no clue how to test this\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the inflation governor result with expected formatting', async () => {\n                expect.assertions(1);\n                const result = await rpc.getInflationGovernor({ commitment }).send();\n                expect(result).toStrictEqual({\n                    foundation: expect.any(Number),\n                    foundationTerm: expect.any(Number),\n                    initial: expect.any(Number),\n                    taper: expect.any(Number),\n                    terminal: expect.any(Number),\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-inflation-rate-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\n\nimport { GetInflationRateApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getInflationRate', () => {\n    let rpc: Rpc<GetInflationRateApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    // TODO: I honestly have no clue how to test this\n    describe(`when called`, () => {\n        it('returns the inflation rate result with expected formatting', async () => {\n            expect.assertions(1);\n            const result = await rpc.getInflationRate().send();\n            expect(result).toStrictEqual({\n                epoch: expect.any(BigInt),\n                foundation: expect.any(Number),\n                total: expect.any(Number),\n                validator: expect.any(Number),\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-inflation-reward-test.ts",
    "content": "import {\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SolanaError,\n} from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetInflationRewardApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getInflationReward', () => {\n    let rpc: Rpc<GetInflationRewardApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    [{ minContextSlot: 0n }, null].forEach(minContextConfig => {\n        describe(`when called with ${\n            minContextConfig ? `a \\`minContextSlot\\` of ${minContextConfig.minContextSlot}` : 'no `minContextSlot`'\n        }`, () => {\n            (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n                describe(`when called with \\`${commitment}\\` commitment`, () => {\n                    // TODO(#1240) Figure out a way to write tests for these.\n                    // * Need to be able to fast-forward the validator to have at least one epoch.\n                    // * Need to prepare a fixture address that is owed an inflation/staking reward.\n                    it.todo('returns null for an address expected to have no inflation rewards');\n                    it.todo('returns the inflation reward details for an address expected to have an inflation reward');\n                });\n            });\n        });\n    });\n    describe('when called with an `epoch` higher than the highest epoch available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const sendPromise = rpc\n                .getInflationReward([], {\n                    epoch: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_BLOCK_NOT_AVAILABLE,\n                ),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__serverMessage',\n                    expect.stringMatching(/Block not available for slot \\d+/),\n                ),\n            ]);\n        });\n    });\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const sendPromise = rpc\n                .getInflationReward([], {\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-largest-accounts-test.ts",
    "content": "import { open } from 'node:fs/promises';\n\nimport type { Address } from '@solana/addresses';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\nimport path from 'path';\n\nimport { GetLargestAccountsApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\nconst faucetKeypairPath = path.resolve(__dirname, '../../../../test-ledger/faucet-keypair.json');\nconst validatorKeypairPath = path.resolve(__dirname, '../../../../test-ledger/validator-keypair.json');\nconst voteAccountKeypairPath = path.resolve(__dirname, '../../../../test-ledger/vote-account-keypair.json');\n\nasync function getNodeAddress(path: string) {\n    const file = await open(path);\n    try {\n        let secretKey: Uint8Array | undefined;\n        for await (const line of file.readLines({ encoding: 'binary' })) {\n            secretKey = new Uint8Array(JSON.parse(line));\n            break; // Only need the first line\n        }\n        if (secretKey) {\n            const publicKey = secretKey.slice(32, 64);\n            const expectedAddress = getBase58Decoder().decode(publicKey);\n            return expectedAddress as Address;\n        }\n        throw new Error(`Failed to read keypair file \\`${path}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getLargestAccounts', () => {\n    let rpc: Rpc<GetLargestAccountsApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            describe('when called without filter', () => {\n                it('returns a list of the largest accounts', async () => {\n                    expect.assertions(1);\n                    const faucetAddress = await getNodeAddress(faucetKeypairPath);\n                    const validatorAddress = await getNodeAddress(validatorKeypairPath);\n                    const voteAccountAddress = await getNodeAddress(voteAccountKeypairPath);\n                    const largestAccountsPromise = rpc.getLargestAccounts({ commitment }).send();\n                    await expect(largestAccountsPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                address: voteAccountAddress,\n                                lamports: expect.any(BigInt), // Changes\n                            },\n                            {\n                                address: faucetAddress,\n                                lamports: expect.any(BigInt), // Changes\n                            },\n                            {\n                                address: validatorAddress,\n                                lamports: expect.any(BigInt), // Changes\n                            },\n                        ]),\n                    });\n                });\n            });\n\n            describe('when called with the `circulating` filter', () => {\n                // TODO: This will always the same as above until we can mock\n                // non-circulating accounts with the test validator.\n                it('returns a list of the largest circulating accounts', async () => {\n                    expect.assertions(1);\n                    const faucetAddress = await getNodeAddress(faucetKeypairPath);\n                    const validatorAddress = await getNodeAddress(validatorKeypairPath);\n                    const voteAccountAddress = await getNodeAddress(voteAccountKeypairPath);\n                    const largestAccountsPromise = rpc.getLargestAccounts({ commitment, filter: 'circulating' }).send();\n                    await expect(largestAccountsPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                address: voteAccountAddress,\n                                lamports: expect.any(BigInt), // Changes\n                            },\n                            {\n                                address: faucetAddress,\n                                lamports: expect.any(BigInt), // Changes\n                            },\n                            {\n                                address: validatorAddress,\n                                lamports: expect.any(BigInt), // Changes\n                            },\n                        ]),\n                    });\n                });\n            });\n\n            describe('when called with the `nonCirculating` filter', () => {\n                // TODO: This will always be an empty array until we can mock it\n                // with the test validator.\n                it.todo('returns a list of the largest non-circulating accounts');\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-latest-blockhash-test.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetLatestBlockhashApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getLatestBlockhash', () => {\n    let rpc: Rpc<GetLatestBlockhashApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the blockhash and block height', async () => {\n                expect.assertions(1);\n                const blockhashPromise = rpc.getLatestBlockhash({ commitment }).send();\n                await expect(blockhashPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        blockhash: expect.any(String),\n                        lastValidBlockHeight: expect.any(BigInt),\n                    },\n                });\n            });\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const sendPromise = rpc\n                .getLatestBlockhash({\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-leader-schedule-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\nimport assert from 'assert';\nimport { open } from 'fs/promises';\nimport path from 'path';\n\nimport { GetLeaderScheduleApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst validatorKeypairPath = path.resolve(__dirname, '../../../../test-ledger/validator-keypair.json');\n\nasync function getValidatorAddress() {\n    const file = await open(validatorKeypairPath);\n    try {\n        let secretKey: Uint8Array | undefined;\n        for await (const line of file.readLines({ encoding: 'binary' })) {\n            secretKey = new Uint8Array(JSON.parse(line));\n            break; // Only need the first line\n        }\n        if (secretKey) {\n            const publicKey = secretKey.slice(32, 64);\n            const expectedAddress = getBase58Decoder().decode(publicKey);\n            return expectedAddress as Address;\n        }\n        throw new Error(`Failed to read keypair file \\`${validatorKeypairPath}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getLeaderSchedule', () => {\n    let rpc: Rpc<GetLeaderScheduleApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            describe('when called with no identity and no slot', () => {\n                it('returns the leader schedule for all cluster nodes in the current epoch', async () => {\n                    expect.assertions(3);\n                    const res = await rpc.getLeaderSchedule(null, { commitment }).send();\n                    // Does not need null check (default slot)\n                    expect(res).toStrictEqual(expect.any(Object));\n                    for (const key of Object.keys(res)) {\n                        expect(typeof key).toBe('string');\n                        // Needs typecasting to be used as accessor\n                        const base58Key: Address = key as Address;\n                        expect(res[base58Key]).toStrictEqual(expect.any(Array));\n                    }\n                });\n            });\n\n            describe('when called with no identity and a valid slot', () => {\n                it('returns the leader schedule for all cluster nodes in the epoch corresponding to the provided slot', async () => {\n                    expect.assertions(3);\n                    const res = await rpc.getLeaderSchedule(0n, { commitment }).send();\n                    // Needs null check (slot provided and may correspond to epoch that does not exist)\n                    expect(res).toStrictEqual(expect.any(Object));\n                    assert(res);\n                    for (const key of Object.keys(res)) {\n                        expect(typeof key).toBe('string');\n                        // Needs typecasting to be used as accessor\n                        const base58Key: Address = key as Address;\n                        expect(res[base58Key]).toStrictEqual(expect.any(Array));\n                    }\n                });\n            });\n\n            describe('when called with an account that is a validator identity and no slot', () => {\n                it('returns the leader schedule for only the specified node in the current epoch', async () => {\n                    expect.assertions(1);\n                    const identity = await getValidatorAddress();\n                    const res = await rpc\n                        .getLeaderSchedule(null, {\n                            commitment,\n                            identity,\n                        })\n                        .send();\n                    // Does not need null check (default slot)\n                    expect(res).toStrictEqual({\n                        [identity]: expect.any(Array),\n                    });\n                });\n            });\n\n            describe('when called with an account that is a validator identity and a valid slot', () => {\n                it('returns the leader schedule for only the specified node in the epoch corresponding to the provided slot', async () => {\n                    expect.assertions(1);\n                    const identity = await getValidatorAddress();\n                    const res = await rpc\n                        .getLeaderSchedule(0n, {\n                            commitment,\n                            identity,\n                        })\n                        .send();\n                    // Needs null check (slot provided and may correspond to epoch that does not exist)\n                    assert(res);\n                    expect(res).toStrictEqual({\n                        [identity]: expect.any(Array),\n                    });\n                });\n            });\n        });\n\n        describe('given an account that exists but is not a validator identity', () => {\n            it('returns an empty object', async () => {\n                expect.assertions(1);\n                const res = await rpc\n                    .getLeaderSchedule(null, {\n                        commitment,\n                        // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n                        identity: 'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address,\n                    })\n                    .send();\n                expect(res).toStrictEqual({});\n            });\n        });\n\n        describe('given an account that does not exist', () => {\n            it('returns an empty object', async () => {\n                expect.assertions(1);\n                const res = await rpc\n                    .getLeaderSchedule(null, {\n                        commitment,\n                        // Randomly generated\n                        identity: 'BnWCFuxmi6uH3ceVx4R8qcbWBMPVVYVVFWtAiiTA1PAu' as Address,\n                    })\n                    .send();\n                expect(res).toStrictEqual({});\n            });\n        });\n\n        describe('given an invalid slot', () => {\n            it('returns an empty object', async () => {\n                expect.assertions(1);\n                const leaderSchedulePromise = rpc\n                    .getLeaderSchedule(\n                        2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                        { commitment },\n                    )\n                    .send();\n                await expect(leaderSchedulePromise).resolves.toBeNull();\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-max-retransmit-slot-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\n\nimport { GetMaxRetransmitSlotApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getMaxRetransmitSlot', () => {\n    let rpc: Rpc<GetMaxRetransmitSlotApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    describe('when called with no parameters', () => {\n        it('returns a bigint', async () => {\n            expect.assertions(1);\n            const result = await rpc.getMaxRetransmitSlot().send();\n            expect(result).toEqual(expect.any(BigInt));\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-max-shred-insert-slot-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\n\nimport { GetMaxShredInsertSlotApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getMaxShredInsertSlot', () => {\n    let rpc: Rpc<GetMaxShredInsertSlotApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    describe('when called with no parameters', () => {\n        it('returns a bigint', async () => {\n            expect.assertions(1);\n            const result = await rpc.getMaxShredInsertSlot().send();\n            expect(result).toEqual(expect.any(BigInt));\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-minimum-balance-for-rent-exemption-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetMinimumBalanceForRentExemptionApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getMinimumBalanceForRentExemption', () => {\n    let rpc: Rpc<GetMinimumBalanceForRentExemptionApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns an expected rent amount', async () => {\n                expect.assertions(1);\n                const result = await rpc.getMinimumBalanceForRentExemption(BigInt(0), { commitment }).send();\n                expect(result).toEqual(BigInt(890880));\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-multiple-accounts-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetMultipleAccountsApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getMultipleAccounts', () => {\n    let rpc: Rpc<GetMultipleAccountsApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns account info for multiple accounts', async () => {\n                expect.assertions(1);\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts(\n                        [\n                            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n                            'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>,\n                            // See scripts/fixtures/4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc.json\n                            '4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc' as Address<'4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc'>,\n                        ],\n                        {\n                            commitment,\n                        },\n                    )\n                    .send();\n\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: ['dGVzdCBkYXRh', 'base64'],\n                            executable: false,\n                            lamports: 5000000n,\n                            owner: '11111111111111111111111111111111',\n                            rentEpoch: 18446744073709551615n,\n                            space: 9n,\n                        },\n                        {\n                            data: ['', 'base64'],\n                            executable: false,\n                            lamports: 5000000n,\n                            owner: '11111111111111111111111111111111',\n                            rentEpoch: 18446744073709551615n,\n                            space: 0n,\n                        },\n                    ],\n                });\n            });\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n            const sendPromise = rpc\n                .getMultipleAccounts([publicKey], {\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n\n    describe('when called with an empty array of accounts', () => {\n        it('returns an empty array RPC response', async () => {\n            expect.assertions(1);\n\n            const multipleAccountsPromise = rpc.getMultipleAccounts([]).send();\n            await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [],\n            });\n        });\n    });\n\n    describe('when called with accounts including one that does not exist', () => {\n        it('returns a list with null for the one that does not exist', async () => {\n            expect.assertions(1);\n\n            const multipleAccountsPromise = rpc\n                .getMultipleAccounts([\n                    // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n                    'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>,\n                    // Randomly generated\n                    '8HgNKsvrrQh6DoAtugeFdxYw38zGR1yi2FtYWqVvH9uG' as Address<'8HgNKsvrrQh6DoAtugeFdxYw38zGR1yi2FtYWqVvH9uG'>,\n                ])\n                .send();\n\n            await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        data: ['dGVzdCBkYXRh', 'base64'],\n                        executable: false,\n                        lamports: 5000000n,\n                        owner: '11111111111111111111111111111111',\n                        rentEpoch: 18446744073709551615n,\n                        space: 9n,\n                    },\n                    null,\n                ],\n            });\n        });\n    });\n\n    describe('when called with accounts where none exist', () => {\n        it('returns a list with null values', async () => {\n            expect.assertions(1);\n\n            const multipleAccountsPromise = rpc\n                .getMultipleAccounts([\n                    // Randomly generated\n                    '8HgNKsvrrQh6DoAtugeFdxYw38zGR1yi2FtYWqVvH9uG' as Address<'8HgNKsvrrQh6DoAtugeFdxYw38zGR1yi2FtYWqVvH9uG'>,\n                    // Randomly generated\n                    '6JkwLherbVYPVF5sXGHm7qd9Lpd6gzinU4P792FkgdfS' as Address<'6JkwLherbVYPVF5sXGHm7qd9Lpd6gzinU4P792FkgdfS'>,\n                ])\n                .send();\n\n            await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [null, null],\n            });\n        });\n    });\n\n    describe('when called with base58 encoding', () => {\n        it('returns account info with annotated base58 encoding', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const multipleAccounts = await rpc\n                .getMultipleAccounts([publicKey], {\n                    encoding: 'base58',\n                })\n                .send();\n\n            expect(multipleAccounts.value[0]?.data).toStrictEqual(['2Uw1bpnsXxu3e', 'base58']);\n        });\n    });\n\n    describe('when called with base64 encoding', () => {\n        it('returns account info with annotated base64 encoding', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const multipleAccounts = await rpc\n                .getMultipleAccounts([publicKey], {\n                    encoding: 'base64',\n                })\n                .send();\n\n            expect(multipleAccounts.value[0]?.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n        });\n    });\n\n    describe('when called with base64+zstd encoding', () => {\n        it('returns account info with annotated base64+zstd encoding', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const multipleAccounts = await rpc\n                .getMultipleAccounts([publicKey], {\n                    encoding: 'base64+zstd',\n                })\n                .send();\n\n            expect(multipleAccounts.value[0]?.data).toStrictEqual(['KLUv/QBYSQAAdGVzdCBkYXRh', 'base64+zstd']);\n        });\n    });\n\n    describe('when called with jsonParsed encoding', () => {\n        describe('for an account without parse-able JSON data', () => {\n            it('falls back to annotated base64', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n                const publicKey =\n                    'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n                const multipleAccounts = await rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                expect(multipleAccounts.value[0]?.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n            });\n        });\n\n        describe('for an account with parse-able JSON data', () => {\n            it('returns parsed JSON data for AddressLookupTable account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/address-lookup-table-account.json\n                const publicKey =\n                    '2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n' as Address<'2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        addresses: [\n                                            'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn',\n                                            'FWscgV4VDSsMxkQg7jZ4HksqjLyadJS5RiCnAVZv2se9',\n                                            '6PoVp5L36hYU5oDWjZiUnhcKqVnkwYXgditMKufxhTuo',\n                                            '9J4yDqU6wBkdhP5bmJhukhsEzBkaAXiBmii52kTdxpQq',\n                                            '25FkCKVY4nMLaqCWhWoDt3idfNRBHkyQttTd4VCibYoU',\n                                            'CSYi7PVzvEA2iiDWhR8eN6EBjZpKyzPX1aMbayrk9YTD',\n                                            'CSYi7PVzvEA2iiDWhR8eN6EBjZpKyzPX1aMbayrk9YTD',\n                                            '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                                            '6ndVLNpgFDZZS1Ph7A9oZKD15Z6FurMMeVrsYiP6NUw8',\n                                            '9zqNWNXHPLkW6LcNbBboF6tFvAHoT97UFczUusGLdGhE',\n                                            '3nkuz3xksLcsok3NexdDLWZqUMehrPQj23a8fkPnZ4ng',\n                                            'EL9gfMj99EvcV5x3NxHbRQsJKbavFcFvvNxbpJg6CvqM',\n                                            'EWmQeCKE6MsByDGdL7sktuL5eCfTUBKSLQe12tG3mFfn',\n                                            '4oEA4jBmBbZmrzAxnConZP93LQuwh9bV5T1y7NLFwtMk',\n                                            'EHjk9n6jCrDLVGhC2vjvdzaFP2gPonK7Up1tVg9Zc11y',\n                                            'GsPu9qRgkF9RDFnQjXh3TngvAdQPYUnTSaeG1K4uNjj3',\n                                            '9J4yDqU6wBkdhP5bmJhukhsEzBkaAXiBmii52kTdxpQq',\n                                            'FoNprxYzYmwnYzhM964CxEHchhj17YREieJtSAXg9FMU',\n                                            'FAH4Nd2GhQmLWxHcVN63rnc4EomJw2EEpA5ukGuzZyKc',\n                                            'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                            'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',\n                                            'FAH4Nd2GhQmLWxHcVN63rnc4EomJw2EEpA5ukGuzZyKc',\n                                            'CZw6RPBy9BecE4hVBG4cK4E64gJN7gT9D1EZKCGRqkHV',\n                                            '2Q1PhUaRw3GeaCxv2ud8iaxWAZjpisdU5bvUTtVacgJU',\n                                            'Sysvar1nstructions1111111111111111111111111',\n                                            'auth9SigNpDKz4sJJ1DfCTuZrZNSAgh9sFD3rboVmgg',\n                                            '11111111111111111111111111111111',\n                                            'SysvarRent111111111111111111111111111111111',\n                                            'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                                            '7YVgrijuM9eSNgeyEpZBw7cZ3ncXhUbHkst9NjAVQQd4',\n                                            '4ncLWXmfoFGyGuCXKLFxguCAYE4ioUp4RKKoUHtJPNGN',\n                                            'FZYB8CfgDexiDv9Vm3vHBuEBNxy97yetVTU6nq1nPyxQ',\n                                            'CJBCQppi8NjNxqzyoHJG2h97RinfKePP1ZUMMWcxp339',\n                                            '9WPz1JB6xWb5Cn3uvL9T2hR2sKPfVB5GANoVM7pf1zvG',\n                                            '5gb1Vq2ZVtx25w8TDnpGTzPk8nZXgZ1TLWvSt6hnBiXn',\n                                            'mm8fDa7jiufFGD6h4foq9vdmTRxDeDSTKB9CZynwQQs',\n                                            '4cdDuEivqaGiF2Yu6LjdgTukmfgsHoxfhjTua59xXexP',\n                                            'AdH2Utn6Fus15ZhtenW4hZBQnvtLgM1YCW2MfVp7pYS5',\n                                            'FoNprxYzYmwnYzhM964CxEHchhj17YREieJtSAXg9FMU',\n                                        ],\n                                        authority: '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                                        deactivationSlot: '204699277',\n                                        lastExtendedSlot: '204699234',\n                                        lastExtendedSlotStartIndex: 20,\n                                    },\n                                    type: 'lookupTable',\n                                },\n                                program: 'address-lookup-table',\n                                space: 1304n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'AddressLookupTab1e1111111111111111111111111',\n                            rentEpoch: 0n,\n                            space: 1304n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for BpfLoaderUpgradeable account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/bpf-upgradeable-loader-program-account.json\n                const publicKey =\n                    'AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk' as Address<'AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        programData: '3vnUTQbDuCgfVn7yQcigUwMQNGkLBZ7GfKWb3gYbAY23',\n                                    },\n                                    type: 'program',\n                                },\n                                program: 'bpf-upgradeable-loader',\n                                space: 36n,\n                            },\n                            executable: true,\n                            lamports: 10290815n,\n                            owner: 'BPFLoaderUpgradeab1e11111111111111111111111',\n                            rentEpoch: 0n,\n                            space: 36n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for Config validator account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/config-validator-account.json\n                const publicKey =\n                    'FtLZBmDW4Y6WNTYYZv9AcC2nQupDMDzX5Q5mp5MLpmdY' as Address<'FtLZBmDW4Y6WNTYYZv9AcC2nQupDMDzX5Q5mp5MLpmdY'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        configData: {\n                                            name: 'HoldTheNode',\n                                            website: 'https://holdthenode.com',\n                                        },\n                                        keys: [\n                                            {\n                                                pubkey: 'Va1idator1nfo111111111111111111111111111111',\n                                                signer: false,\n                                            },\n                                            {\n                                                pubkey: '5hvJ19nRgtzAkosb5bcx9bqeN2QA1Qwxq4M349Q2L6s2',\n                                                signer: true,\n                                            },\n                                        ],\n                                    },\n                                    type: 'validatorInfo',\n                                },\n                                program: 'config',\n                                space: 643n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'Config1111111111111111111111111111111111111',\n                            rentEpoch: 0n,\n                            space: 643n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for Config stake account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/config-stake-account.json\n                const publicKey =\n                    'StakeConfig11111111111111111111111111111111' as Address<'StakeConfig11111111111111111111111111111111'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        slashPenalty: 12,\n                                        warmupCooldownRate: 0.25,\n                                    },\n                                    type: 'stakeConfig',\n                                },\n                                program: 'config',\n                                space: 10n,\n                            },\n                            executable: false,\n                            lamports: 960480n,\n                            owner: 'Config1111111111111111111111111111111111111',\n                            rentEpoch: 0n,\n                            space: 10n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for Nonce account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/nonce-account.json\n                const publicKey =\n                    'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU' as Address<'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        authority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                        blockhash: 'TcVy2wVcs7WqWVopv8LAJBHQfqVYZrm8UDqjDvBFQt8',\n                                        feeCalculator: {\n                                            lamportsPerSignature: '5000',\n                                        },\n                                    },\n                                    type: 'initialized',\n                                },\n                                program: 'nonce',\n                                space: 80n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: '11111111111111111111111111111111',\n                            rentEpoch: 0n,\n                            space: 80n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for SPL Token mint account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-account.json\n                const publicKey =\n                    'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address<'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        decimals: 6,\n                                        freezeAuthority: null,\n                                        isInitialized: true,\n                                        mintAuthority: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                                        supply: '1690580887590527729',\n                                    },\n                                    type: 'mint',\n                                },\n                                program: 'spl-token',\n                                space: 82n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 82n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for SPL Token token account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-account.json\n                const publicKey =\n                    'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca' as Address<'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        isNative: false,\n                                        mint: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                                        owner: '6UsGbaMgchgj4wiwKKuE1v5URHdcDfEiMSM25QpesKir',\n                                        state: 'initialized',\n                                        tokenAmount: {\n                                            amount: '9999999779500000',\n                                            decimals: 6,\n                                            uiAmount: 9999999779.5,\n                                            uiAmountString: '9999999779.5',\n                                        },\n                                    },\n                                    type: 'account',\n                                },\n                                program: 'spl-token',\n                                space: 165n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for SPL token multisig account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-account.json\n                const publicKey =\n                    '4Uh9vK5nnxfskc73asy7AeRYDfZocrv1th9DEjtdCn88' as Address<'4Uh9vK5nnxfskc73asy7AeRYDfZocrv1th9DEjtdCn88'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        isInitialized: true,\n                                        numRequiredSigners: 2,\n                                        numValidSigners: 2,\n                                        signers: [\n                                            'Fkc4FN7PPhyGsAcHPW3dBBJ4BvtYkDr2rBFBgFpvy3nB',\n                                            '5scSndUhfZJ8j8wZz5UNHhvuPBhvN1RboTdkKSvFHLtW',\n                                        ],\n                                    },\n                                    type: 'multisig',\n                                },\n                                program: 'spl-token',\n                                space: 355n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 355n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for SPL Token 22 mint account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-22-mint-account.json\n                const publicKey =\n                    'CKfatsPMUf8SkiURsDXs7eK6GWb4Jsd6UDbs7twMCWxo' as Address<'CKfatsPMUf8SkiURsDXs7eK6GWb4Jsd6UDbs7twMCWxo'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        decimals: 5,\n                                        extensions: [\n                                            {\n                                                extension: 'transferFeeConfig',\n                                                state: {\n                                                    newerTransferFee: {\n                                                        epoch: 457n,\n                                                        maximumFee: 3906250000000000000n,\n                                                        transferFeeBasisPoints: 690,\n                                                    },\n                                                    olderTransferFee: {\n                                                        epoch: 455n,\n                                                        maximumFee: 3906250000000000000n,\n                                                        transferFeeBasisPoints: 0,\n                                                    },\n                                                    transferFeeConfigAuthority:\n                                                        '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                    withdrawWithheldAuthority:\n                                                        '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                    withheldAmount: 0n,\n                                                },\n                                            },\n                                        ],\n                                        freezeAuthority: '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                        isInitialized: true,\n                                        mintAuthority: '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                        supply: '99998926239436',\n                                    },\n                                    type: 'mint',\n                                },\n                                program: 'spl-token-2022',\n                                space: 278n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                            rentEpoch: 0n,\n                            space: 278n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for Stake account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/stake-account.json\n                const publicKey =\n                    'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN' as Address<'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        meta: {\n                                            authorized: {\n                                                staker: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                                withdrawer: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                            },\n                                            lockup: {\n                                                custodian: '11111111111111111111111111111111',\n                                                epoch: 0n,\n                                                unixTimestamp: 0n,\n                                            },\n                                            rentExemptReserve: '2282880',\n                                        },\n                                        stake: {\n                                            creditsObserved: 169965713n,\n                                            delegation: {\n                                                activationEpoch: '386',\n                                                deactivationEpoch: '471',\n                                                stake: '8007935',\n                                                voter: 'CertusDeBmqN8ZawdkxK5kFGMwBXdudvWHYwtNgNhvLu',\n                                                warmupCooldownRate: 0.25,\n                                            },\n                                        },\n                                    },\n                                    type: 'delegated',\n                                },\n                                program: 'stake',\n                                space: 200n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'Stake11111111111111111111111111111111111111',\n                            rentEpoch: 0n,\n                            space: 200n,\n                        },\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for Sysvar rent account', async () => {\n                expect.assertions(1);\n                // Sysvar accounts don't need a fixture\n                const publicKey =\n                    'SysvarRent111111111111111111111111111111111' as Address<'SysvarRent111111111111111111111111111111111'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        expect.objectContaining({\n                            data: {\n                                parsed: {\n                                    info: expect.objectContaining({\n                                        burnPercent: 50,\n                                        exemptionThreshold: 1,\n                                        lamportsPerByteYear: '6960',\n                                    }),\n                                    type: 'rent',\n                                },\n                                program: 'sysvar',\n                                space: 17n,\n                            },\n                            executable: false,\n                            owner: 'Sysvar1111111111111111111111111111111111111',\n                        }),\n                    ],\n                });\n            });\n\n            it('returns parsed JSON data for Vote account', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/vote-account.json\n                const publicKey =\n                    '4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp' as Address<'4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp'>;\n\n                const multipleAccountsPromise = rpc\n                    .getMultipleAccounts([publicKey], {\n                        encoding: 'jsonParsed',\n                    })\n                    .send();\n\n                // Length 1\n                await expect(multipleAccountsPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        expect.objectContaining({\n                            data: {\n                                parsed: {\n                                    info: expect.objectContaining({\n                                        authorizedVoters: [\n                                            {\n                                                authorizedVoter: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                                epoch: 656n,\n                                            },\n                                        ],\n                                        authorizedWithdrawer: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                        blockRevenueCollector: expect.any(String),\n                                        blockRevenueCommissionBps: expect.any(BigInt),\n                                        blsPubkeyCompressed: null,\n                                        commission: 50,\n                                        epochCredits: expect.arrayContaining([\n                                            {\n                                                credits: '117764802',\n                                                epoch: 593n,\n                                                previousCredits: '117762806',\n                                            },\n                                            {\n                                                credits: '118161978',\n                                                epoch: 594n,\n                                                previousCredits: '117764802',\n                                            },\n                                            {\n                                                credits: '118593951',\n                                                epoch: 595n,\n                                                previousCredits: '118161978',\n                                            },\n                                            {\n                                                credits: '119025928',\n                                                epoch: 596n,\n                                                previousCredits: '118593951',\n                                            },\n                                            {\n                                                credits: '119456860',\n                                                epoch: 597n,\n                                                previousCredits: '119025928',\n                                            },\n                                            {\n                                                credits: '119770741',\n                                                epoch: 598n,\n                                                previousCredits: '119456860',\n                                            },\n                                            {\n                                                credits: '119773739',\n                                                epoch: 599n,\n                                                previousCredits: '119770741',\n                                            },\n                                            {\n                                                credits: '119777233',\n                                                epoch: 600n,\n                                                previousCredits: '119773739',\n                                            },\n                                            {\n                                                credits: '119780053',\n                                                epoch: 601n,\n                                                previousCredits: '119777233',\n                                            },\n                                            {\n                                                credits: '119783284',\n                                                epoch: 602n,\n                                                previousCredits: '119780053',\n                                            },\n                                            {\n                                                credits: '119786399',\n                                                epoch: 603n,\n                                                previousCredits: '119783284',\n                                            },\n                                            {\n                                                credits: '119788422',\n                                                epoch: 604n,\n                                                previousCredits: '119786399',\n                                            },\n                                            {\n                                                credits: '119791169',\n                                                epoch: 605n,\n                                                previousCredits: '119788422',\n                                            },\n                                            {\n                                                credits: '119793299',\n                                                epoch: 606n,\n                                                previousCredits: '119791169',\n                                            },\n                                            {\n                                                credits: '119796454',\n                                                epoch: 607n,\n                                                previousCredits: '119793299',\n                                            },\n                                            {\n                                                credits: '119799687',\n                                                epoch: 608n,\n                                                previousCredits: '119796454',\n                                            },\n                                            {\n                                                credits: '119802861',\n                                                epoch: 609n,\n                                                previousCredits: '119799687',\n                                            },\n                                            {\n                                                credits: '119804679',\n                                                epoch: 610n,\n                                                previousCredits: '119802861',\n                                            },\n                                            {\n                                                credits: '119807952',\n                                                epoch: 611n,\n                                                previousCredits: '119804679',\n                                            },\n                                            {\n                                                credits: '119810634',\n                                                epoch: 612n,\n                                                previousCredits: '119807952',\n                                            },\n                                            {\n                                                credits: '119813372',\n                                                epoch: 613n,\n                                                previousCredits: '119810634',\n                                            },\n                                            {\n                                                credits: '119816503',\n                                                epoch: 614n,\n                                                previousCredits: '119813372',\n                                            },\n                                            {\n                                                credits: '119819850',\n                                                epoch: 615n,\n                                                previousCredits: '119816503',\n                                            },\n                                            {\n                                                credits: '119823406',\n                                                epoch: 616n,\n                                                previousCredits: '119819850',\n                                            },\n                                            {\n                                                credits: '119825752',\n                                                epoch: 617n,\n                                                previousCredits: '119823406',\n                                            },\n                                            {\n                                                credits: '119828458',\n                                                epoch: 618n,\n                                                previousCredits: '119825752',\n                                            },\n                                            {\n                                                credits: '119830399',\n                                                epoch: 619n,\n                                                previousCredits: '119828458',\n                                            },\n                                            {\n                                                credits: '119833206',\n                                                epoch: 620n,\n                                                previousCredits: '119830399',\n                                            },\n                                            {\n                                                credits: '119836333',\n                                                epoch: 621n,\n                                                previousCredits: '119833206',\n                                            },\n                                            {\n                                                credits: '119839690',\n                                                epoch: 622n,\n                                                previousCredits: '119836333',\n                                            },\n                                            {\n                                                credits: '119842672',\n                                                epoch: 623n,\n                                                previousCredits: '119839690',\n                                            },\n                                            {\n                                                credits: '119845737',\n                                                epoch: 624n,\n                                                previousCredits: '119842672',\n                                            },\n                                            {\n                                                credits: '119848231',\n                                                epoch: 625n,\n                                                previousCredits: '119845737',\n                                            },\n                                            {\n                                                credits: '119851184',\n                                                epoch: 626n,\n                                                previousCredits: '119848231',\n                                            },\n                                            {\n                                                credits: '119854617',\n                                                epoch: 627n,\n                                                previousCredits: '119851184',\n                                            },\n                                            {\n                                                credits: '119856852',\n                                                epoch: 628n,\n                                                previousCredits: '119854617',\n                                            },\n                                            {\n                                                credits: '119860362',\n                                                epoch: 629n,\n                                                previousCredits: '119856852',\n                                            },\n                                            {\n                                                credits: '119863578',\n                                                epoch: 630n,\n                                                previousCredits: '119860362',\n                                            },\n                                            {\n                                                credits: '119867336',\n                                                epoch: 631n,\n                                                previousCredits: '119863578',\n                                            },\n                                            {\n                                                credits: '119871382',\n                                                epoch: 632n,\n                                                previousCredits: '119867336',\n                                            },\n                                            {\n                                                credits: '119874725',\n                                                epoch: 633n,\n                                                previousCredits: '119871382',\n                                            },\n                                            {\n                                                credits: '119878010',\n                                                epoch: 634n,\n                                                previousCredits: '119874725',\n                                            },\n                                            {\n                                                credits: '119881019',\n                                                epoch: 635n,\n                                                previousCredits: '119878010',\n                                            },\n                                            {\n                                                credits: '119884533',\n                                                epoch: 636n,\n                                                previousCredits: '119881019',\n                                            },\n                                            {\n                                                credits: '119887482',\n                                                epoch: 637n,\n                                                previousCredits: '119884533',\n                                            },\n                                            {\n                                                credits: '119890917',\n                                                epoch: 638n,\n                                                previousCredits: '119887482',\n                                            },\n                                            {\n                                                credits: '119891583',\n                                                epoch: 639n,\n                                                previousCredits: '119890917',\n                                            },\n                                            {\n                                                credits: '119894976',\n                                                epoch: 640n,\n                                                previousCredits: '119891583',\n                                            },\n                                            {\n                                                credits: '119897217',\n                                                epoch: 641n,\n                                                previousCredits: '119894976',\n                                            },\n                                            {\n                                                credits: '119899074',\n                                                epoch: 642n,\n                                                previousCredits: '119897217',\n                                            },\n                                            {\n                                                credits: '119902893',\n                                                epoch: 643n,\n                                                previousCredits: '119899074',\n                                            },\n                                            {\n                                                credits: '119905968',\n                                                epoch: 644n,\n                                                previousCredits: '119902893',\n                                            },\n                                            {\n                                                credits: '119909166',\n                                                epoch: 645n,\n                                                previousCredits: '119905968',\n                                            },\n                                            {\n                                                credits: '119912335',\n                                                epoch: 646n,\n                                                previousCredits: '119909166',\n                                            },\n                                            {\n                                                credits: '119916478',\n                                                epoch: 647n,\n                                                previousCredits: '119912335',\n                                            },\n                                            {\n                                                credits: '119919918',\n                                                epoch: 648n,\n                                                previousCredits: '119916478',\n                                            },\n                                            {\n                                                credits: '120283578',\n                                                epoch: 649n,\n                                                previousCredits: '119919918',\n                                            },\n                                            {\n                                                credits: '120325223',\n                                                epoch: 650n,\n                                                previousCredits: '120283578',\n                                            },\n                                            {\n                                                credits: '120329512',\n                                                epoch: 651n,\n                                                previousCredits: '120325223',\n                                            },\n                                            {\n                                                credits: '120333844',\n                                                epoch: 652n,\n                                                previousCredits: '120329512',\n                                            },\n                                            {\n                                                credits: '120337635',\n                                                epoch: 653n,\n                                                previousCredits: '120333844',\n                                            },\n                                            {\n                                                credits: '120341034',\n                                                epoch: 654n,\n                                                previousCredits: '120337635',\n                                            },\n                                            {\n                                                credits: '120345192',\n                                                epoch: 655n,\n                                                previousCredits: '120341034',\n                                            },\n                                            {\n                                                credits: '120347138',\n                                                epoch: 656n,\n                                                previousCredits: '120345192',\n                                            },\n                                        ]),\n                                        inflationRewardsCollector: expect.any(String),\n                                        inflationRewardsCommissionBps: expect.any(BigInt),\n                                        lastTimestamp: {\n                                            slot: 283619438n,\n                                            timestamp: 1709828565n,\n                                        },\n                                        nodePubkey: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                        pendingDelegatorRewards: expect.any(String),\n                                        priorVoters: [],\n                                        rootSlot: 283619407n,\n                                        votes: expect.any(Array),\n                                    }),\n                                    type: 'vote',\n                                },\n                                program: 'vote',\n                                space: 3762n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'Vote111111111111111111111111111111111111111',\n                            rentEpoch: 0n,\n                            space: 3762n,\n                        }),\n                    ],\n                });\n            });\n        });\n    });\n\n    describe('when called with no encoding', () => {\n        it('returns annotated base64 data', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const multipleAccounts = await rpc.getMultipleAccounts([publicKey], {}).send();\n\n            expect(multipleAccounts.value[0]?.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n        });\n    });\n\n    describe('when called with a dataSlice', () => {\n        it('returns the correct slice of the data', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            // data is 'test data'\n            const publicKey =\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\n            const multipleAccounts = await rpc\n                .getMultipleAccounts([publicKey], {\n                    dataSlice: {\n                        length: 5,\n                        offset: 0,\n                    },\n                    encoding: 'base64',\n                })\n                .send();\n\n            expect(multipleAccounts.value[0]?.data).toStrictEqual(['dGVzdCA=', 'base64']);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-program-accounts-test.ts",
    "content": "import { open } from 'node:fs/promises';\n\nimport type { Address } from '@solana/addresses';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Base58EncodedBytes, Commitment } from '@solana/rpc-types';\nimport path from 'path';\n\nimport { GetProgramAccountsApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\nconst validatorKeypairPath = path.resolve(__dirname, '../../../../test-ledger/validator-keypair.json');\nconst voteAccountKeypairPath = path.resolve(__dirname, '../../../../test-ledger/vote-account-keypair.json');\n\nasync function getNodeAddress(path: string) {\n    const file = await open(path);\n    try {\n        let secretKey: Uint8Array | undefined;\n        for await (const line of file.readLines({ encoding: 'binary' })) {\n            secretKey = new Uint8Array(JSON.parse(line));\n            break; // Only need the first line\n        }\n        if (secretKey) {\n            const publicKey = secretKey.slice(32, 64);\n            const expectedAddress = getBase58Decoder().decode(publicKey);\n            return expectedAddress as Address;\n        }\n        throw new Error(`Failed to read keypair file \\`${path}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getProgramAccounts', () => {\n    let rpc: Rpc<GetProgramAccountsApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns account info', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/gpa1.json\n                const program =\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                const accountInfosPromise = rpc\n                    .getProgramAccounts(program, {\n                        commitment,\n                    })\n                    .send();\n\n                await expect(accountInfosPromise).resolves.toStrictEqual(\n                    // We can't guarantee ordering is preserved across test runs\n                    expect.arrayContaining([\n                        {\n                            account: {\n                                data: '2Uw1bpnsXxu3e',\n                                executable: false,\n                                lamports: 5000000n,\n                                owner: 'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                                rentEpoch: 18446744073709551615n,\n                                space: 9n,\n                            },\n                            pubkey: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                        },\n                    ]),\n                );\n            });\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const program =\n                'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n            const sendPromise = rpc\n                .getProgramAccounts(program, {\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n\n    describe('when called with a program with no accounts', () => {\n        it('returns an empty list', async () => {\n            expect.assertions(1);\n            // randomly generated\n            const program =\n                'FZp6uJxwZbyZUCSF3Hyv494Su7w2MJEtNdYuc4RQHa2Z' as Address<'FZp6uJxwZbyZUCSF3Hyv494Su7w2MJEtNdYuc4RQHa2Z'>;\n            const accountInfoPromise = rpc.getProgramAccounts(program).send();\n            await expect(accountInfoPromise).resolves.toStrictEqual([]);\n        });\n    });\n\n    describe('when called with a program with multiple accounts', () => {\n        it('returns account info for all accounts', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa2-1.json, scripts/fixtures/gpa2-2.json,\n            const program =\n                'AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6' as Address<'AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6'>;\n\n            const accountInfosPromise = rpc.getProgramAccounts(program).send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual(\n                // We can't guarantee ordering is preserved across test runs\n                expect.arrayContaining([\n                    {\n                        account: {\n                            data: '2Uw1bpnsXxu3e',\n                            executable: false,\n                            lamports: 5000000n,\n                            owner: 'AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6',\n                            rentEpoch: 18446744073709551615n,\n                            space: 9n,\n                        },\n                        pubkey: 'C5q1p5UiCVrt6vcLJDGcS4AZ98fahKyb9XkDRdqATK17',\n                    },\n                    {\n                        account: {\n                            data: '2Uw1bpnsXxu3e',\n                            executable: false,\n                            lamports: 5000000n,\n                            owner: 'AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6',\n                            rentEpoch: 18446744073709551615n,\n                            space: 9n,\n                        },\n                        pubkey: 'Hhsoev7Apk5dMbktzLUrsTHuMq9e9GSYBaLcnN2PfdKS',\n                    },\n                ]),\n            );\n        });\n    });\n\n    describe('when called with base58 encoding', () => {\n        describe('when called with withContext: false', () => {\n            it('returns top-level account info with annotated base58 encoding', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/gpa1.json\n                // data is 'test data'\n                const program =\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                const accountInfo = await rpc\n                    .getProgramAccounts(program, {\n                        encoding: 'base58',\n                        withContext: false,\n                    })\n                    .send();\n\n                expect(accountInfo[0].account.data).toStrictEqual(['2Uw1bpnsXxu3e', 'base58']);\n            });\n        });\n\n        describe('when called with withContext: true', () => {\n            it('returns RPC Response with account info with annotated base58 encoding', async () => {\n                expect.assertions(2);\n                // See scripts/fixtures/gpa1.json\n                // data is 'test data'\n                const program =\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                const accountInfo = await rpc\n                    .getProgramAccounts(program, {\n                        encoding: 'base58',\n                        withContext: true,\n                    })\n                    .send();\n\n                expect(accountInfo.context.slot).toEqual(expect.any(BigInt));\n                expect(accountInfo.value[0].account.data).toStrictEqual(['2Uw1bpnsXxu3e', 'base58']);\n            });\n        });\n    });\n\n    describe('when called with base64 encoding', () => {\n        describe('when called with withContext: false', () => {\n            it('returns top-level account info with annotated base64 encoding', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/gpa1.json\n                // data is 'test data'\n                const program =\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                const accountInfo = await rpc\n                    .getProgramAccounts(program, {\n                        encoding: 'base64',\n                        withContext: false,\n                    })\n                    .send();\n\n                expect(accountInfo[0].account.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n            });\n        });\n\n        describe('when called with withContext: true', () => {\n            it('returns RPC Response with account info with annotated base64 encoding', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/gpa1.json\n                // data is 'test data'\n                const program =\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                const accountInfo = await rpc\n                    .getProgramAccounts(program, {\n                        encoding: 'base64',\n                        withContext: true,\n                    })\n                    .send();\n\n                expect(accountInfo.value[0].account.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n            });\n        });\n    });\n\n    describe('when called with base64+zstd encoding', () => {\n        describe('when called with withContext: false', () => {\n            it('returns top-level account info with annotated base64+zstd encoding', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/gpa1.json\n                // data is 'test data'\n                const program =\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                const accountInfo = await rpc\n                    .getProgramAccounts(program, {\n                        encoding: 'base64+zstd',\n                        withContext: false,\n                    })\n                    .send();\n\n                expect(accountInfo[0].account.data).toStrictEqual(['KLUv/QBYSQAAdGVzdCBkYXRh', 'base64+zstd']);\n            });\n        });\n\n        describe('when called with withContext: true', () => {\n            it('returns RPC Response with account info with annotated base64+zstd encoding', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/gpa1.json\n                // data is 'test data'\n                const program =\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                const accountInfo = await rpc\n                    .getProgramAccounts(program, {\n                        encoding: 'base64+zstd',\n                        withContext: true,\n                    })\n                    .send();\n\n                expect(accountInfo.value[0].account.data).toStrictEqual(['KLUv/QBYSQAAdGVzdCBkYXRh', 'base64+zstd']);\n            });\n        });\n    });\n\n    describe('when called with jsonParsed encoding', () => {\n        describe('for an account without parse-able JSON data', () => {\n            describe('when called with withContext: false', () => {\n                it('returns top-level account info with annotated base64 encoding', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/gpa1.json\n                    // data is 'test data'\n                    const program =\n                        'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                    const accountInfo = await rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    expect(accountInfo[0].account.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n                });\n            });\n\n            describe('when called with withContext: true', () => {\n                it('returns RPC Response with account info with annotated base64 encoding', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/gpa1.json\n                    // data is 'test data'\n                    const program =\n                        'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n                    const accountInfo = await rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    expect(accountInfo.value[0].account.data).toStrictEqual(['dGVzdCBkYXRh', 'base64']);\n                });\n            });\n        });\n\n        describe('for an account with parse-able JSON data', () => {\n            // Note: make sure these tests are resilient against adding more accounts under the same program\n            describe('when called with withContext false', () => {\n                it('returns parsed JSON data for AddressLookupTable account', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/address-lookup-table-account.json\n                    const program =\n                        'AddressLookupTab1e1111111111111111111111111' as Address<'AddressLookupTab1e1111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                addresses: [\n                                                    'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn',\n                                                    'FWscgV4VDSsMxkQg7jZ4HksqjLyadJS5RiCnAVZv2se9',\n                                                    '6PoVp5L36hYU5oDWjZiUnhcKqVnkwYXgditMKufxhTuo',\n                                                    '9J4yDqU6wBkdhP5bmJhukhsEzBkaAXiBmii52kTdxpQq',\n                                                    '25FkCKVY4nMLaqCWhWoDt3idfNRBHkyQttTd4VCibYoU',\n                                                    'CSYi7PVzvEA2iiDWhR8eN6EBjZpKyzPX1aMbayrk9YTD',\n                                                    'CSYi7PVzvEA2iiDWhR8eN6EBjZpKyzPX1aMbayrk9YTD',\n                                                    '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                                                    '6ndVLNpgFDZZS1Ph7A9oZKD15Z6FurMMeVrsYiP6NUw8',\n                                                    '9zqNWNXHPLkW6LcNbBboF6tFvAHoT97UFczUusGLdGhE',\n                                                    '3nkuz3xksLcsok3NexdDLWZqUMehrPQj23a8fkPnZ4ng',\n                                                    'EL9gfMj99EvcV5x3NxHbRQsJKbavFcFvvNxbpJg6CvqM',\n                                                    'EWmQeCKE6MsByDGdL7sktuL5eCfTUBKSLQe12tG3mFfn',\n                                                    '4oEA4jBmBbZmrzAxnConZP93LQuwh9bV5T1y7NLFwtMk',\n                                                    'EHjk9n6jCrDLVGhC2vjvdzaFP2gPonK7Up1tVg9Zc11y',\n                                                    'GsPu9qRgkF9RDFnQjXh3TngvAdQPYUnTSaeG1K4uNjj3',\n                                                    '9J4yDqU6wBkdhP5bmJhukhsEzBkaAXiBmii52kTdxpQq',\n                                                    'FoNprxYzYmwnYzhM964CxEHchhj17YREieJtSAXg9FMU',\n                                                    'FAH4Nd2GhQmLWxHcVN63rnc4EomJw2EEpA5ukGuzZyKc',\n                                                    'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                                    'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',\n                                                    'FAH4Nd2GhQmLWxHcVN63rnc4EomJw2EEpA5ukGuzZyKc',\n                                                    'CZw6RPBy9BecE4hVBG4cK4E64gJN7gT9D1EZKCGRqkHV',\n                                                    '2Q1PhUaRw3GeaCxv2ud8iaxWAZjpisdU5bvUTtVacgJU',\n                                                    'Sysvar1nstructions1111111111111111111111111',\n                                                    'auth9SigNpDKz4sJJ1DfCTuZrZNSAgh9sFD3rboVmgg',\n                                                    '11111111111111111111111111111111',\n                                                    'SysvarRent111111111111111111111111111111111',\n                                                    'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                                                    '7YVgrijuM9eSNgeyEpZBw7cZ3ncXhUbHkst9NjAVQQd4',\n                                                    '4ncLWXmfoFGyGuCXKLFxguCAYE4ioUp4RKKoUHtJPNGN',\n                                                    'FZYB8CfgDexiDv9Vm3vHBuEBNxy97yetVTU6nq1nPyxQ',\n                                                    'CJBCQppi8NjNxqzyoHJG2h97RinfKePP1ZUMMWcxp339',\n                                                    '9WPz1JB6xWb5Cn3uvL9T2hR2sKPfVB5GANoVM7pf1zvG',\n                                                    '5gb1Vq2ZVtx25w8TDnpGTzPk8nZXgZ1TLWvSt6hnBiXn',\n                                                    'mm8fDa7jiufFGD6h4foq9vdmTRxDeDSTKB9CZynwQQs',\n                                                    '4cdDuEivqaGiF2Yu6LjdgTukmfgsHoxfhjTua59xXexP',\n                                                    'AdH2Utn6Fus15ZhtenW4hZBQnvtLgM1YCW2MfVp7pYS5',\n                                                    'FoNprxYzYmwnYzhM964CxEHchhj17YREieJtSAXg9FMU',\n                                                ],\n                                                authority: '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                                                deactivationSlot: '204699277',\n                                                lastExtendedSlot: '204699234',\n                                                lastExtendedSlotStartIndex: 20,\n                                            },\n                                            type: 'lookupTable',\n                                        },\n                                        program: 'address-lookup-table',\n                                        space: 1304n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'AddressLookupTab1e1111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 1304n,\n                                },\n                                pubkey: '2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n',\n                            },\n                        ]),\n                    );\n                });\n\n                it('returns parsed JSON data for BpfLoaderUpgradeable account', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/bpf-upgradeable-loader-program-account.json\n                    const program =\n                        'BPFLoaderUpgradeab1e11111111111111111111111' as Address<'BPFLoaderUpgradeab1e11111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                // Token 2022 data account\n                                                programData: 'DoU57AYuPFu2QU514RktNPG22QhApEjnKxnBcu4BHDTY',\n                                            },\n                                            type: 'program',\n                                        },\n                                        program: 'bpf-upgradeable-loader',\n                                        space: 36n,\n                                    },\n                                    executable: true,\n                                    lamports: expect.any(BigInt),\n                                    owner: 'BPFLoaderUpgradeab1e11111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 36n,\n                                },\n                                pubkey: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                programData: '3vnUTQbDuCgfVn7yQcigUwMQNGkLBZ7GfKWb3gYbAY23',\n                                            },\n                                            type: 'program',\n                                        },\n                                        program: 'bpf-upgradeable-loader',\n                                        space: 36n,\n                                    },\n                                    executable: true,\n                                    lamports: expect.any(BigInt),\n                                    owner: 'BPFLoaderUpgradeab1e11111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 36n,\n                                },\n                                pubkey: 'AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object), // Huge\n                                            type: 'programData',\n                                        },\n                                        program: 'bpf-upgradeable-loader',\n                                        space: expect.any(BigInt),\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt),\n                                    owner: 'BPFLoaderUpgradeab1e11111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: expect.any(BigInt),\n                                },\n                                // Token 2022 data account\n                                pubkey: 'DoU57AYuPFu2QU514RktNPG22QhApEjnKxnBcu4BHDTY',\n                            },\n                        ]),\n                    );\n                });\n\n                it('returns parsed JSON data for Config stake and validator accounts', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/config-stake-account.json\n                    // See scripts/fixtures/config-validator-account.json\n                    const publicKey =\n                        'Config1111111111111111111111111111111111111' as Address<'Config1111111111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(publicKey, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                slashPenalty: 12,\n                                                warmupCooldownRate: 0.25,\n                                            },\n                                            type: 'stakeConfig',\n                                        },\n                                        program: 'config',\n                                        space: 10n,\n                                    },\n                                    executable: false,\n                                    lamports: 960480n,\n                                    owner: 'Config1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 10n,\n                                },\n                                pubkey: 'StakeConfig11111111111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                configData: {\n                                                    name: 'HoldTheNode',\n                                                    website: 'https://holdthenode.com',\n                                                },\n                                                keys: [\n                                                    {\n                                                        pubkey: 'Va1idator1nfo111111111111111111111111111111',\n                                                        signer: false,\n                                                    },\n                                                    {\n                                                        pubkey: '5hvJ19nRgtzAkosb5bcx9bqeN2QA1Qwxq4M349Q2L6s2',\n                                                        signer: true,\n                                                    },\n                                                ],\n                                            },\n                                            type: 'validatorInfo',\n                                        },\n                                        program: 'config',\n                                        space: 643n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'Config1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 643n,\n                                },\n                                pubkey: 'FtLZBmDW4Y6WNTYYZv9AcC2nQupDMDzX5Q5mp5MLpmdY',\n                            },\n                        ]),\n                    );\n                });\n\n                it('returns parsed JSON data for Nonce account', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/nonce-account.json\n                    const program = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    // Too large to try to match all accounts owned by system program\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                authority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                blockhash: 'TcVy2wVcs7WqWVopv8LAJBHQfqVYZrm8UDqjDvBFQt8',\n                                                feeCalculator: {\n                                                    lamportsPerSignature: '5000',\n                                                },\n                                            },\n                                            type: 'initialized',\n                                        },\n                                        program: 'nonce',\n                                        space: 80n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: '11111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 80n,\n                                },\n                                pubkey: 'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU',\n                            },\n                        ]),\n                    );\n                });\n\n                it('returns parsed JSON data for accounts owned by SPL Token', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/spl-token-account.json\n                    // See scripts/fixtures/spl-token-token-account.json\n                    // See scripts/fixtures/spl-token-multisig-account.json\n                    const program =\n                        'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 9,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: null,\n                                                supply: '0',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 1000000000n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: 1n,\n                                    space: 82n,\n                                },\n                                pubkey: 'So11111111111111111111111111111111111111112',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 9,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                supply: '0',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 82n,\n                                },\n                                pubkey: '2nBoNW5B9SdpJYEg9neii7ecCJFwh6UrbXS6HFxkK7Gf',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 9,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                supply: '1000000000000',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 82n,\n                                },\n                                pubkey: '4SspA9vWmizwcvngHTapwQtpnRrPf8V483giCSaCmy6M',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                isInitialized: true,\n                                                numRequiredSigners: 2,\n                                                numValidSigners: 2,\n                                                signers: [\n                                                    'Fkc4FN7PPhyGsAcHPW3dBBJ4BvtYkDr2rBFBgFpvy3nB',\n                                                    '5scSndUhfZJ8j8wZz5UNHhvuPBhvN1RboTdkKSvFHLtW',\n                                                ],\n                                            },\n                                            type: 'multisig',\n                                        },\n                                        program: 'spl-token',\n                                        space: 355n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 355n,\n                                },\n                                pubkey: '4Uh9vK5nnxfskc73asy7AeRYDfZocrv1th9DEjtdCn88',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                delegate: 'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL',\n                                                delegatedAmount: {\n                                                    amount: '100000000000',\n                                                    decimals: 9,\n                                                    uiAmount: 100,\n                                                    uiAmountString: '100',\n                                                },\n                                                isNative: false,\n                                                mint: '4SspA9vWmizwcvngHTapwQtpnRrPf8V483giCSaCmy6M',\n                                                owner: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                state: 'initialized',\n                                                tokenAmount: {\n                                                    amount: '1000000000000',\n                                                    decimals: 9,\n                                                    uiAmount: 1000,\n                                                    uiAmountString: '1000',\n                                                },\n                                            },\n                                            type: 'account',\n                                        },\n                                        program: 'spl-token',\n                                        space: 165n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 165n,\n                                },\n                                pubkey: '6uGCrvzPAta1nc6wP9oHvM6sRDu1kXTMuJSJvro4R4xS',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                isNative: false,\n                                                mint: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                                                owner: '6UsGbaMgchgj4wiwKKuE1v5URHdcDfEiMSM25QpesKir',\n                                                state: 'initialized',\n                                                tokenAmount: {\n                                                    amount: '9999999779500000',\n                                                    decimals: 6,\n                                                    uiAmount: 9999999779.5,\n                                                    uiAmountString: '9999999779.5',\n                                                },\n                                            },\n                                            type: 'account',\n                                        },\n                                        program: 'spl-token',\n                                        space: 165n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 165n,\n                                },\n                                pubkey: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 6,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                                                supply: '1690580887590527729',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 82n,\n                                },\n                                pubkey: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                isNative: false,\n                                                mint: '2nBoNW5B9SdpJYEg9neii7ecCJFwh6UrbXS6HFxkK7Gf',\n                                                owner: 'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL',\n                                                state: 'initialized',\n                                                tokenAmount: {\n                                                    amount: '0',\n                                                    decimals: 9,\n                                                    uiAmount: 0,\n                                                    uiAmountString: '0',\n                                                },\n                                            },\n                                            type: 'account',\n                                        },\n                                        program: 'spl-token',\n                                        space: 165n,\n                                    },\n                                    executable: false,\n                                    lamports: 2039280n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 165n,\n                                },\n                                pubkey: 'GoJdqNkvpf26BAX8cYsV3bb52kbBYt7vT5rqpPGGgK5F',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 9,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                supply: '0',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 1461600n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 82n,\n                                },\n                                pubkey: 'HWHfrWotTpaNArteqeYDziV1ZX9Lm7WV684NeUCwPPzj',\n                            },\n                        ]),\n                    );\n                });\n\n                it('returns parsed JSON data for SPL Token 22 mint account', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/spl-token-22-mint-account.json\n                    const program =\n                        'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb' as Address<'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 5,\n                                                extensions: [\n                                                    {\n                                                        extension: 'transferFeeConfig',\n                                                        state: {\n                                                            newerTransferFee: {\n                                                                epoch: 457n,\n                                                                maximumFee: 3906250000000000000n,\n                                                                transferFeeBasisPoints: 690,\n                                                            },\n                                                            olderTransferFee: {\n                                                                epoch: 455n,\n                                                                maximumFee: 3906250000000000000n,\n                                                                transferFeeBasisPoints: 0,\n                                                            },\n                                                            transferFeeConfigAuthority:\n                                                                '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                            withdrawWithheldAuthority:\n                                                                '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                            withheldAmount: 0n,\n                                                        },\n                                                    },\n                                                ],\n                                                freezeAuthority: '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                isInitialized: true,\n                                                mintAuthority: '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                supply: '99998926239436',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token-2022',\n                                        space: 278n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 278n,\n                                },\n                                pubkey: 'CKfatsPMUf8SkiURsDXs7eK6GWb4Jsd6UDbs7twMCWxo',\n                            },\n                        ]),\n                    );\n                });\n\n                it('returns parsed JSON data for Stake account', async () => {\n                    expect.assertions(1);\n                    const voteAccountAddress = await getNodeAddress(voteAccountKeypairPath);\n                    // TODO: Test validator does not write this keypair to JSON\n                    // See solana-labs/solana/pull/33014\n                    const stakeAddress = expect.any(String);\n                    // See scripts/fixtures/stake-account.json\n                    const program =\n                        'Stake11111111111111111111111111111111111111' as Address<'Stake11111111111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            // Local validator\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                meta: {\n                                                    authorized: {\n                                                        staker: stakeAddress,\n                                                        withdrawer: stakeAddress,\n                                                    },\n                                                    lockup: {\n                                                        custodian: '11111111111111111111111111111111',\n                                                        epoch: 0n,\n                                                        unixTimestamp: 0n,\n                                                    },\n                                                    rentExemptReserve: '2282880',\n                                                },\n                                                stake: {\n                                                    creditsObserved: expect.any(BigInt), // Changes\n                                                    delegation: {\n                                                        activationEpoch: expect.any(String), // Changes\n                                                        deactivationEpoch: expect.any(String), // Changes\n                                                        stake: expect.any(String), // Changes\n                                                        voter: voteAccountAddress,\n                                                        warmupCooldownRate: 0.25,\n                                                    },\n                                                },\n                                            },\n                                            type: 'delegated',\n                                        },\n                                        program: 'stake',\n                                        space: 200n,\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt), // Changes\n                                    owner: 'Stake11111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 200n,\n                                },\n                                pubkey: stakeAddress,\n                            },\n                            // Fixture\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                meta: {\n                                                    authorized: {\n                                                        staker: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                                        withdrawer: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                                    },\n                                                    lockup: {\n                                                        custodian: '11111111111111111111111111111111',\n                                                        epoch: 0n,\n                                                        unixTimestamp: 0n,\n                                                    },\n                                                    rentExemptReserve: '2282880',\n                                                },\n                                                stake: {\n                                                    creditsObserved: expect.any(BigInt), // Changes\n                                                    delegation: {\n                                                        activationEpoch: expect.any(String), // Changes\n                                                        deactivationEpoch: expect.any(String), // Changes\n                                                        stake: expect.any(String), // Changes\n                                                        voter: 'CertusDeBmqN8ZawdkxK5kFGMwBXdudvWHYwtNgNhvLu',\n                                                        warmupCooldownRate: 0.25,\n                                                    },\n                                                },\n                                            },\n                                            type: 'delegated',\n                                        },\n                                        program: 'stake',\n                                        space: 200n,\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt), // Changes\n                                    owner: 'Stake11111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 200n,\n                                },\n                                pubkey: 'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN',\n                            },\n                        ]),\n                    );\n                });\n\n                it('returns parsed JSON data for Sysvar rent account', async () => {\n                    expect.assertions(1);\n                    // Sysvar accounts don't need a fixture\n                    // They're owned by Sysvar1111111111111111111111111111111111111\n                    const program =\n                        'Sysvar1111111111111111111111111111111111111' as Address<'Sysvar1111111111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'clock',\n                                        },\n                                        program: 'sysvar',\n                                        space: 40n,\n                                    },\n                                    executable: false,\n                                    lamports: 1169280n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 40n,\n                                },\n                                pubkey: 'SysvarC1ock11111111111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'epochSchedule',\n                                        },\n                                        program: 'sysvar',\n                                        space: 33n,\n                                    },\n                                    executable: false,\n                                    lamports: 1120560n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 33n,\n                                },\n                                pubkey: 'SysvarEpochSchedu1e111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'recentBlockhashes',\n                                        },\n                                        program: 'sysvar',\n                                        space: 6008n,\n                                    },\n                                    executable: false,\n                                    lamports: 42706560n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 6008n,\n                                },\n                                pubkey: 'SysvarRecentB1ockHashes11111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'rent',\n                                        },\n                                        program: 'sysvar',\n                                        space: 17n,\n                                    },\n                                    executable: false,\n                                    lamports: 1009200n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 17n,\n                                },\n                                pubkey: 'SysvarRent111111111111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'slotHistory',\n                                        },\n                                        program: 'sysvar',\n                                        space: 131097n,\n                                    },\n                                    executable: false,\n                                    lamports: 913326000n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 131097n,\n                                },\n                                pubkey: 'SysvarS1otHistory11111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'stakeHistory',\n                                        },\n                                        program: 'sysvar',\n                                        space: 16392n,\n                                    },\n                                    executable: false,\n                                    lamports: 114979200n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 16392n,\n                                },\n                                pubkey: 'SysvarStakeHistory1111111111111111111111111',\n                            },\n                        ]),\n                    );\n                });\n\n                it('returns parsed JSON data for Vote account', async () => {\n                    expect.assertions(1);\n                    const validatorAddress = await getNodeAddress(validatorKeypairPath);\n                    const voteAccountAddress = await getNodeAddress(voteAccountKeypairPath);\n                    // See scripts/fixtures/vote-account.json\n                    const program =\n                        'Vote111111111111111111111111111111111111111' as Address<'Vote111111111111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: false,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual(\n                        // We can't guarantee ordering is preserved across test runs\n                        expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            // FIXME: We don't do a strict match here because `rootSlot` can sometimes be `null`\n                                            //        Install a matcher that can match 'BigInt OR null'. None of the builtins can.\n                                            info: expect.objectContaining({\n                                                authorizedVoters: expect.arrayContaining([\n                                                    {\n                                                        authorizedVoter: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                                        epoch: expect.any(BigInt), // Changes\n                                                    },\n                                                ]),\n                                                authorizedWithdrawer: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                                commission: 50,\n                                                epochCredits: expect.any(Array), // Huge, changes\n                                                lastTimestamp: {\n                                                    slot: expect.any(BigInt),\n                                                    timestamp: expect.any(BigInt),\n                                                },\n                                                nodePubkey: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                                priorVoters: expect.any(Array), // Huge, changes\n                                                // Note: `rootSlot` can be null in early test validator startup. Omitting\n                                                votes: expect.any(Array), // Huge, changes\n                                            }),\n                                            type: 'vote',\n                                        },\n                                        program: 'vote',\n                                        space: 3762n,\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt), // Changes\n                                    owner: 'Vote111111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 3762n,\n                                },\n                                pubkey: '4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp',\n                            },\n                            // Local Validator\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            // FIXME: We don't do a strict match here because `rootSlot` can sometimes be `null`\n                                            //        Install a matcher that can match 'BigInt OR null'. None of the builtins can.\n                                            info: expect.objectContaining({\n                                                authorizedVoters: expect.arrayContaining([\n                                                    {\n                                                        authorizedVoter: voteAccountAddress,\n                                                        epoch: expect.any(BigInt), // Changes\n                                                    },\n                                                ]),\n                                                authorizedWithdrawer: voteAccountAddress,\n                                                commission: 0,\n                                                epochCredits: expect.any(Array), // Huge, changes\n                                                lastTimestamp: {\n                                                    slot: expect.any(BigInt),\n                                                    timestamp: expect.any(BigInt),\n                                                },\n                                                nodePubkey: validatorAddress,\n                                                priorVoters: expect.any(Array), // Huge, changes\n                                                // Note: `rootSlot` can be null in early test validator startup. Omitting\n                                                votes: expect.any(Array), // Huge, changes\n                                            }),\n                                            type: 'vote',\n                                        },\n                                        program: 'vote',\n                                        space: 3762n,\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt), // Changes\n                                    owner: 'Vote111111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 3762n,\n                                },\n                                pubkey: voteAccountAddress,\n                            },\n                        ]),\n                    );\n                });\n            });\n\n            describe('when called with withContext true', () => {\n                it('returns RPC response with parsed JSON data for AddressLookupTable account', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/address-lookup-table-account.json\n                    const program =\n                        'AddressLookupTab1e1111111111111111111111111' as Address<'AddressLookupTab1e1111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                addresses: [\n                                                    'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn',\n                                                    'FWscgV4VDSsMxkQg7jZ4HksqjLyadJS5RiCnAVZv2se9',\n                                                    '6PoVp5L36hYU5oDWjZiUnhcKqVnkwYXgditMKufxhTuo',\n                                                    '9J4yDqU6wBkdhP5bmJhukhsEzBkaAXiBmii52kTdxpQq',\n                                                    '25FkCKVY4nMLaqCWhWoDt3idfNRBHkyQttTd4VCibYoU',\n                                                    'CSYi7PVzvEA2iiDWhR8eN6EBjZpKyzPX1aMbayrk9YTD',\n                                                    'CSYi7PVzvEA2iiDWhR8eN6EBjZpKyzPX1aMbayrk9YTD',\n                                                    '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                                                    '6ndVLNpgFDZZS1Ph7A9oZKD15Z6FurMMeVrsYiP6NUw8',\n                                                    '9zqNWNXHPLkW6LcNbBboF6tFvAHoT97UFczUusGLdGhE',\n                                                    '3nkuz3xksLcsok3NexdDLWZqUMehrPQj23a8fkPnZ4ng',\n                                                    'EL9gfMj99EvcV5x3NxHbRQsJKbavFcFvvNxbpJg6CvqM',\n                                                    'EWmQeCKE6MsByDGdL7sktuL5eCfTUBKSLQe12tG3mFfn',\n                                                    '4oEA4jBmBbZmrzAxnConZP93LQuwh9bV5T1y7NLFwtMk',\n                                                    'EHjk9n6jCrDLVGhC2vjvdzaFP2gPonK7Up1tVg9Zc11y',\n                                                    'GsPu9qRgkF9RDFnQjXh3TngvAdQPYUnTSaeG1K4uNjj3',\n                                                    '9J4yDqU6wBkdhP5bmJhukhsEzBkaAXiBmii52kTdxpQq',\n                                                    'FoNprxYzYmwnYzhM964CxEHchhj17YREieJtSAXg9FMU',\n                                                    'FAH4Nd2GhQmLWxHcVN63rnc4EomJw2EEpA5ukGuzZyKc',\n                                                    'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                                    'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',\n                                                    'FAH4Nd2GhQmLWxHcVN63rnc4EomJw2EEpA5ukGuzZyKc',\n                                                    'CZw6RPBy9BecE4hVBG4cK4E64gJN7gT9D1EZKCGRqkHV',\n                                                    '2Q1PhUaRw3GeaCxv2ud8iaxWAZjpisdU5bvUTtVacgJU',\n                                                    'Sysvar1nstructions1111111111111111111111111',\n                                                    'auth9SigNpDKz4sJJ1DfCTuZrZNSAgh9sFD3rboVmgg',\n                                                    '11111111111111111111111111111111',\n                                                    'SysvarRent111111111111111111111111111111111',\n                                                    'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                                                    '7YVgrijuM9eSNgeyEpZBw7cZ3ncXhUbHkst9NjAVQQd4',\n                                                    '4ncLWXmfoFGyGuCXKLFxguCAYE4ioUp4RKKoUHtJPNGN',\n                                                    'FZYB8CfgDexiDv9Vm3vHBuEBNxy97yetVTU6nq1nPyxQ',\n                                                    'CJBCQppi8NjNxqzyoHJG2h97RinfKePP1ZUMMWcxp339',\n                                                    '9WPz1JB6xWb5Cn3uvL9T2hR2sKPfVB5GANoVM7pf1zvG',\n                                                    '5gb1Vq2ZVtx25w8TDnpGTzPk8nZXgZ1TLWvSt6hnBiXn',\n                                                    'mm8fDa7jiufFGD6h4foq9vdmTRxDeDSTKB9CZynwQQs',\n                                                    '4cdDuEivqaGiF2Yu6LjdgTukmfgsHoxfhjTua59xXexP',\n                                                    'AdH2Utn6Fus15ZhtenW4hZBQnvtLgM1YCW2MfVp7pYS5',\n                                                    'FoNprxYzYmwnYzhM964CxEHchhj17YREieJtSAXg9FMU',\n                                                ],\n                                                authority: '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                                                deactivationSlot: '204699277',\n                                                lastExtendedSlot: '204699234',\n                                                lastExtendedSlotStartIndex: 20,\n                                            },\n                                            type: 'lookupTable',\n                                        },\n                                        program: 'address-lookup-table',\n                                        space: 1304n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'AddressLookupTab1e1111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 1304n,\n                                },\n                                pubkey: '2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n',\n                            },\n                        ]),\n                    });\n                });\n\n                it('returns RPC response with parsed JSON data for BpfLoaderUpgradeable account', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/bpf-upgradeable-loader-program-account.json\n                    const program =\n                        'BPFLoaderUpgradeab1e11111111111111111111111' as Address<'BPFLoaderUpgradeab1e11111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                // Token 2022 data account\n                                                programData: 'DoU57AYuPFu2QU514RktNPG22QhApEjnKxnBcu4BHDTY',\n                                            },\n                                            type: 'program',\n                                        },\n                                        program: 'bpf-upgradeable-loader',\n                                        space: 36n,\n                                    },\n                                    executable: true,\n                                    lamports: 1141440n,\n                                    owner: 'BPFLoaderUpgradeab1e11111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 36n,\n                                },\n                                pubkey: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                programData: '3vnUTQbDuCgfVn7yQcigUwMQNGkLBZ7GfKWb3gYbAY23',\n                                            },\n                                            type: 'program',\n                                        },\n                                        program: 'bpf-upgradeable-loader',\n                                        space: 36n,\n                                    },\n                                    executable: true,\n                                    lamports: 10290815n,\n                                    owner: 'BPFLoaderUpgradeab1e11111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 36n,\n                                },\n                                pubkey: 'AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object), // Huge\n                                            type: 'programData',\n                                        },\n                                        program: 'bpf-upgradeable-loader',\n                                        space: expect.any(BigInt),\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt),\n                                    owner: 'BPFLoaderUpgradeab1e11111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: expect.any(BigInt),\n                                },\n                                // Token 2022 data account\n                                pubkey: 'DoU57AYuPFu2QU514RktNPG22QhApEjnKxnBcu4BHDTY',\n                            },\n                        ]),\n                    });\n                });\n\n                it('returns RPC response with parsed JSON data for Config stake and validator accounts', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/config-stake-account.json\n                    // See scripts/fixtures/config-validator-account.json\n                    const publicKey =\n                        'Config1111111111111111111111111111111111111' as Address<'Config1111111111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(publicKey, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                slashPenalty: 12,\n                                                warmupCooldownRate: 0.25,\n                                            },\n                                            type: 'stakeConfig',\n                                        },\n                                        program: 'config',\n                                        space: 10n,\n                                    },\n                                    executable: false,\n                                    lamports: 960480n,\n                                    owner: 'Config1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 10n,\n                                },\n                                pubkey: 'StakeConfig11111111111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                configData: {\n                                                    name: 'HoldTheNode',\n                                                    website: 'https://holdthenode.com',\n                                                },\n                                                keys: [\n                                                    {\n                                                        pubkey: 'Va1idator1nfo111111111111111111111111111111',\n                                                        signer: false,\n                                                    },\n                                                    {\n                                                        pubkey: '5hvJ19nRgtzAkosb5bcx9bqeN2QA1Qwxq4M349Q2L6s2',\n                                                        signer: true,\n                                                    },\n                                                ],\n                                            },\n                                            type: 'validatorInfo',\n                                        },\n                                        program: 'config',\n                                        space: 643n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'Config1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 643n,\n                                },\n                                pubkey: 'FtLZBmDW4Y6WNTYYZv9AcC2nQupDMDzX5Q5mp5MLpmdY',\n                            },\n                        ]),\n                    });\n                });\n\n                it('returns RPC response with parsed JSON data for Nonce account', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/nonce-account.json\n                    const program = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    // Too large to try to match all accounts owned by system program\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                authority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                blockhash: 'TcVy2wVcs7WqWVopv8LAJBHQfqVYZrm8UDqjDvBFQt8',\n                                                feeCalculator: {\n                                                    lamportsPerSignature: '5000',\n                                                },\n                                            },\n                                            type: 'initialized',\n                                        },\n                                        program: 'nonce',\n                                        space: 80n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: '11111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 80n,\n                                },\n                                pubkey: 'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU',\n                            },\n                        ]),\n                    });\n                });\n\n                it('returns RPC response with parsed JSON data for accounts owned by SPL Token', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/spl-token-account.json\n                    // See scripts/fixtures/spl-token-account-account.json\n                    // See scripts/fixtures/spl-token-multisig-account.json\n                    const program =\n                        'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 9,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: null,\n                                                supply: '0',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 1000000000n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: 1n,\n                                    space: 82n,\n                                },\n                                pubkey: 'So11111111111111111111111111111111111111112',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 9,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                supply: '0',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 82n,\n                                },\n                                pubkey: '2nBoNW5B9SdpJYEg9neii7ecCJFwh6UrbXS6HFxkK7Gf',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 9,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                supply: '1000000000000',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 82n,\n                                },\n                                pubkey: '4SspA9vWmizwcvngHTapwQtpnRrPf8V483giCSaCmy6M',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                isInitialized: true,\n                                                numRequiredSigners: 2,\n                                                numValidSigners: 2,\n                                                signers: [\n                                                    'Fkc4FN7PPhyGsAcHPW3dBBJ4BvtYkDr2rBFBgFpvy3nB',\n                                                    '5scSndUhfZJ8j8wZz5UNHhvuPBhvN1RboTdkKSvFHLtW',\n                                                ],\n                                            },\n                                            type: 'multisig',\n                                        },\n                                        program: 'spl-token',\n                                        space: 355n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 355n,\n                                },\n                                pubkey: '4Uh9vK5nnxfskc73asy7AeRYDfZocrv1th9DEjtdCn88',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                delegate: 'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL',\n                                                delegatedAmount: {\n                                                    amount: '100000000000',\n                                                    decimals: 9,\n                                                    uiAmount: 100,\n                                                    uiAmountString: '100',\n                                                },\n                                                isNative: false,\n                                                mint: '4SspA9vWmizwcvngHTapwQtpnRrPf8V483giCSaCmy6M',\n                                                owner: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                state: 'initialized',\n                                                tokenAmount: {\n                                                    amount: '1000000000000',\n                                                    decimals: 9,\n                                                    uiAmount: 1000,\n                                                    uiAmountString: '1000',\n                                                },\n                                            },\n                                            type: 'account',\n                                        },\n                                        program: 'spl-token',\n                                        space: 165n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 165n,\n                                },\n                                pubkey: '6uGCrvzPAta1nc6wP9oHvM6sRDu1kXTMuJSJvro4R4xS',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                isNative: false,\n                                                mint: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                                                owner: '6UsGbaMgchgj4wiwKKuE1v5URHdcDfEiMSM25QpesKir',\n                                                state: 'initialized',\n                                                tokenAmount: {\n                                                    amount: '9999999779500000',\n                                                    decimals: 6,\n                                                    uiAmount: 9999999779.5,\n                                                    uiAmountString: '9999999779.5',\n                                                },\n                                            },\n                                            type: 'account',\n                                        },\n                                        program: 'spl-token',\n                                        space: 165n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 165n,\n                                },\n                                pubkey: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 6,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                                                supply: '1690580887590527729',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 82n,\n                                },\n                                pubkey: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                isNative: false,\n                                                mint: '2nBoNW5B9SdpJYEg9neii7ecCJFwh6UrbXS6HFxkK7Gf',\n                                                owner: 'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL',\n                                                state: 'initialized',\n                                                tokenAmount: {\n                                                    amount: '0',\n                                                    decimals: 9,\n                                                    uiAmount: 0,\n                                                    uiAmountString: '0',\n                                                },\n                                            },\n                                            type: 'account',\n                                        },\n                                        program: 'spl-token',\n                                        space: 165n,\n                                    },\n                                    executable: false,\n                                    lamports: 2039280n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 165n,\n                                },\n                                pubkey: 'GoJdqNkvpf26BAX8cYsV3bb52kbBYt7vT5rqpPGGgK5F',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 9,\n                                                freezeAuthority: null,\n                                                isInitialized: true,\n                                                mintAuthority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                                supply: '0',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token',\n                                        space: 82n,\n                                    },\n                                    executable: false,\n                                    lamports: 1461600n,\n                                    owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 82n,\n                                },\n                                pubkey: 'HWHfrWotTpaNArteqeYDziV1ZX9Lm7WV684NeUCwPPzj',\n                            },\n                        ]),\n                    });\n                });\n\n                it('returns RPC response with parsed JSON data for SPL Token 22 mint account', async () => {\n                    expect.assertions(1);\n                    // See scripts/fixtures/spl-token-22-mint-account.json\n                    const program =\n                        'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb' as Address<'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                decimals: 5,\n                                                extensions: [\n                                                    {\n                                                        extension: 'transferFeeConfig',\n                                                        state: {\n                                                            newerTransferFee: {\n                                                                epoch: 457n,\n                                                                maximumFee: 3906250000000000000n,\n                                                                transferFeeBasisPoints: 690,\n                                                            },\n                                                            olderTransferFee: {\n                                                                epoch: 455n,\n                                                                maximumFee: 3906250000000000000n,\n                                                                transferFeeBasisPoints: 0,\n                                                            },\n                                                            transferFeeConfigAuthority:\n                                                                '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                            withdrawWithheldAuthority:\n                                                                '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                            withheldAmount: 0n,\n                                                        },\n                                                    },\n                                                ],\n                                                freezeAuthority: '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                isInitialized: true,\n                                                mintAuthority: '7MyTjmRygJoCuDBUtAuSugiYZFULD2SWaoUTmtjtRDzD',\n                                                supply: '99998926239436',\n                                            },\n                                            type: 'mint',\n                                        },\n                                        program: 'spl-token-2022',\n                                        space: 278n,\n                                    },\n                                    executable: false,\n                                    lamports: 10290815n,\n                                    owner: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 278n,\n                                },\n                                pubkey: 'CKfatsPMUf8SkiURsDXs7eK6GWb4Jsd6UDbs7twMCWxo',\n                            },\n                        ]),\n                    });\n                });\n\n                it('returns RPC response with parsed JSON data for Stake account', async () => {\n                    expect.assertions(1);\n                    const voteAccountAddress = await getNodeAddress(voteAccountKeypairPath);\n                    // TODO: Test validator does not write this keypair to JSON\n                    // See solana-labs/solana/pull/33014\n                    const stakeAddress = expect.any(String);\n                    // See scripts/fixtures/stake-account.json\n                    const program =\n                        'Stake11111111111111111111111111111111111111' as Address<'Stake11111111111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            // Local Validator\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                meta: {\n                                                    authorized: {\n                                                        staker: stakeAddress,\n                                                        withdrawer: stakeAddress,\n                                                    },\n                                                    lockup: {\n                                                        custodian: '11111111111111111111111111111111',\n                                                        epoch: 0n,\n                                                        unixTimestamp: 0n,\n                                                    },\n                                                    rentExemptReserve: '2282880',\n                                                },\n                                                stake: {\n                                                    creditsObserved: expect.any(BigInt), // Changes\n                                                    delegation: {\n                                                        activationEpoch: expect.any(String), // Changes\n                                                        deactivationEpoch: expect.any(String), // Changes\n                                                        stake: expect.any(String), // Changes\n                                                        voter: voteAccountAddress,\n                                                        warmupCooldownRate: 0.25,\n                                                    },\n                                                },\n                                            },\n                                            type: 'delegated',\n                                        },\n                                        program: 'stake',\n                                        space: 200n,\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt), // Changes\n                                    owner: 'Stake11111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 200n,\n                                },\n                                pubkey: stakeAddress,\n                            },\n                            // Fixture\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: {\n                                                meta: {\n                                                    authorized: {\n                                                        staker: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                                        withdrawer: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                                    },\n                                                    lockup: {\n                                                        custodian: '11111111111111111111111111111111',\n                                                        epoch: 0n,\n                                                        unixTimestamp: 0n,\n                                                    },\n                                                    rentExemptReserve: '2282880',\n                                                },\n                                                stake: {\n                                                    creditsObserved: expect.any(BigInt), // Changes\n                                                    delegation: {\n                                                        activationEpoch: expect.any(String), // Changes\n                                                        deactivationEpoch: expect.any(String), // Changes\n                                                        stake: expect.any(String), // Changes\n                                                        voter: 'CertusDeBmqN8ZawdkxK5kFGMwBXdudvWHYwtNgNhvLu',\n                                                        warmupCooldownRate: 0.25,\n                                                    },\n                                                },\n                                            },\n                                            type: 'delegated',\n                                        },\n                                        program: 'stake',\n                                        space: 200n,\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt), // Changes\n                                    owner: 'Stake11111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 200n,\n                                },\n                                pubkey: 'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN',\n                            },\n                        ]),\n                    });\n                });\n\n                it('returns RPC response with parsed JSON data for Sysvar rent account', async () => {\n                    expect.assertions(1);\n                    // Sysvar accounts don't need a fixture\n                    // They're owned by Sysvar1111111111111111111111111111111111111\n                    const program =\n                        'Sysvar1111111111111111111111111111111111111' as Address<'Sysvar1111111111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'clock',\n                                        },\n                                        program: 'sysvar',\n                                        space: 40n,\n                                    },\n                                    executable: false,\n                                    lamports: 1169280n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 40n,\n                                },\n                                pubkey: 'SysvarC1ock11111111111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'epochSchedule',\n                                        },\n                                        program: 'sysvar',\n                                        space: 33n,\n                                    },\n                                    executable: false,\n                                    lamports: 1120560n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 33n,\n                                },\n                                pubkey: 'SysvarEpochSchedu1e111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'lastRestartSlot',\n                                        },\n                                        program: 'sysvar',\n                                        space: 8n,\n                                    },\n                                    executable: false,\n                                    lamports: 946560n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 8n,\n                                },\n                                pubkey: 'SysvarLastRestartS1ot1111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'recentBlockhashes',\n                                        },\n                                        program: 'sysvar',\n                                        space: 6008n,\n                                    },\n                                    executable: false,\n                                    lamports: 42706560n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 6008n,\n                                },\n                                pubkey: 'SysvarRecentB1ockHashes11111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'rent',\n                                        },\n                                        program: 'sysvar',\n                                        space: 17n,\n                                    },\n                                    executable: false,\n                                    lamports: 1009200n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 17n,\n                                },\n                                pubkey: 'SysvarRent111111111111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'slotHistory',\n                                        },\n                                        program: 'sysvar',\n                                        space: 131097n,\n                                    },\n                                    executable: false,\n                                    lamports: 913326000n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 131097n,\n                                },\n                                pubkey: 'SysvarS1otHistory11111111111111111111111111',\n                            },\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            info: expect.any(Object),\n                                            type: 'stakeHistory',\n                                        },\n                                        program: 'sysvar',\n                                        space: 16392n,\n                                    },\n                                    executable: false,\n                                    lamports: 114979200n,\n                                    owner: 'Sysvar1111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 16392n,\n                                },\n                                pubkey: 'SysvarStakeHistory1111111111111111111111111',\n                            },\n                        ]),\n                    });\n                });\n\n                it('returns RPC response with parsed JSON data for Vote account', async () => {\n                    expect.assertions(1);\n                    const validatorAddress = await getNodeAddress(validatorKeypairPath);\n                    const voteAccountAddress = await getNodeAddress(voteAccountKeypairPath);\n                    // See scripts/fixtures/vote-account.json\n                    const program =\n                        'Vote111111111111111111111111111111111111111' as Address<'Vote111111111111111111111111111111111111111'>;\n\n                    const accountInfosPromise = rpc\n                        .getProgramAccounts(program, {\n                            encoding: 'jsonParsed',\n                            withContext: true,\n                        })\n                        .send();\n\n                    await expect(accountInfosPromise).resolves.toStrictEqual({\n                        context: CONTEXT_MATCHER,\n                        // We can't guarantee ordering is preserved across test runs\n                        value: expect.arrayContaining([\n                            // Fixture\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            // FIXME: We don't do a strict match here because `rootSlot` can sometimes be `null`\n                                            //        Install a matcher that can match 'BigInt OR null'. None of the builtins can.\n                                            info: expect.objectContaining({\n                                                authorizedVoters: expect.arrayContaining([\n                                                    {\n                                                        authorizedVoter: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                                        epoch: expect.any(BigInt), // Changes\n                                                    },\n                                                ]),\n                                                authorizedWithdrawer: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                                commission: 50,\n                                                epochCredits: expect.any(Array), // Huge, changes\n                                                lastTimestamp: {\n                                                    slot: expect.any(BigInt),\n                                                    timestamp: expect.any(BigInt),\n                                                },\n                                                nodePubkey: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                                priorVoters: expect.any(Array), // Huge, changes\n                                                // Note: `rootSlot` can be null in early test validator startup. Omitting\n                                                votes: expect.any(Array), // Huge, changes\n                                            }),\n                                            type: 'vote',\n                                        },\n                                        program: 'vote',\n                                        space: 3762n,\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt), // Changes\n                                    owner: 'Vote111111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 3762n,\n                                },\n                                pubkey: '4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp',\n                            },\n                            // Local Validator\n                            {\n                                account: {\n                                    data: {\n                                        parsed: {\n                                            // FIXME: We don't do a strict match here because `rootSlot` can sometimes be `null`\n                                            //        Install a matcher that can match 'BigInt OR null'. None of the builtins can.\n                                            info: expect.objectContaining({\n                                                authorizedVoters: expect.arrayContaining([\n                                                    {\n                                                        authorizedVoter: voteAccountAddress,\n                                                        epoch: expect.any(BigInt), // Changes\n                                                    },\n                                                ]),\n                                                authorizedWithdrawer: voteAccountAddress,\n                                                commission: 0,\n                                                epochCredits: expect.any(Array), // Huge, changes\n                                                lastTimestamp: {\n                                                    slot: expect.any(BigInt),\n                                                    timestamp: expect.any(BigInt),\n                                                },\n                                                nodePubkey: validatorAddress,\n                                                priorVoters: expect.any(Array), // Huge, changes\n                                                // Note: `rootSlot` can be null in early test validator startup. Omitting\n                                                votes: expect.any(Array), // Huge, changes\n                                            }),\n                                            type: 'vote',\n                                        },\n                                        program: 'vote',\n                                        space: 3762n,\n                                    },\n                                    executable: false,\n                                    lamports: expect.any(BigInt), // Changes\n                                    owner: 'Vote111111111111111111111111111111111111111',\n                                    rentEpoch: expect.any(BigInt),\n                                    space: 3762n,\n                                },\n                                pubkey: voteAccountAddress,\n                            },\n                        ]),\n                    });\n                });\n            });\n        });\n    });\n\n    describe('when called with no encoding', () => {\n        it('returns base58 data without an annotation', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa1.json\n            // data is 'test data'\n            const program =\n                'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n            const accountInfo = await rpc.getProgramAccounts(program).send();\n            expect(accountInfo[0].account.data).toBe('2Uw1bpnsXxu3e');\n        });\n    });\n\n    describe('when called with a dataSlice', () => {\n        it('returns the correct slice of the data', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa1.json\n            // data is 'test data'\n            const program =\n                'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' as Address<'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj'>;\n\n            const accountInfo = await rpc\n                .getProgramAccounts(program, {\n                    dataSlice: {\n                        length: 5,\n                        offset: 0,\n                    },\n                    encoding: 'base64',\n                })\n                .send();\n\n            expect(accountInfo[0].account.data).toStrictEqual(['dGVzdCA=', 'base64']);\n        });\n    });\n\n    describe('when called with a data size filter', () => {\n        it('returns the matching accounts', async () => {\n            expect.assertions(3);\n            const program =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const programAccounts = await rpc\n                .getProgramAccounts(program, {\n                    encoding: 'jsonParsed',\n                    filters: [\n                        {\n                            dataSize: 165n, // Token account size\n                        },\n                    ],\n                })\n                .send();\n\n            programAccounts.forEach(item => {\n                expect(item).toMatchObject({\n                    account: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    isNative: expect.any(Boolean),\n                                    mint: expect.any(String),\n                                    owner: expect.any(String),\n                                    state: expect.any(String),\n                                    tokenAmount: {\n                                        amount: expect.any(String),\n                                        decimals: expect.any(Number),\n                                        uiAmount: expect.any(Number),\n                                        uiAmountString: expect.any(String),\n                                    },\n                                },\n                                type: 'account',\n                            },\n                            program: 'spl-token',\n                            space: 165n, // Token account space\n                        },\n                        executable: false,\n                        lamports: expect.any(BigInt),\n                        owner: expect.any(String),\n                        rentEpoch: expect.any(BigInt),\n                        space: 165n, // Token account space\n                    },\n                    pubkey: expect.any(String),\n                });\n            });\n        });\n    });\n\n    describe('when called with a memcmpy filter', () => {\n        it('returns the matching accounts', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/spl-token-mint-account.json\n            const mint =\n                'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address<'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'>;\n            const program =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const programAccounts = await rpc\n                .getProgramAccounts(program, {\n                    encoding: 'jsonParsed',\n                    filters: [\n                        {\n                            memcmp: {\n                                bytes: mint as unknown as Base58EncodedBytes,\n                                encoding: 'base58',\n                                offset: 0n,\n                            },\n                        },\n                    ],\n                })\n                .send();\n\n            programAccounts.forEach(item => {\n                expect(item).toMatchObject({\n                    account: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    isNative: expect.any(Boolean),\n                                    mint, // Matches mint address provided in filter.\n                                    owner: expect.any(String),\n                                    state: expect.any(String),\n                                    tokenAmount: {\n                                        amount: expect.any(String),\n                                        decimals: expect.any(Number),\n                                        uiAmount: expect.any(Number),\n                                        uiAmountString: expect.any(String),\n                                    },\n                                },\n                                type: 'account',\n                            },\n                            program: 'spl-token',\n                            space: 165n, // Token account space\n                        },\n                        executable: false,\n                        lamports: expect.any(BigInt),\n                        owner: expect.any(String),\n                        rentEpoch: expect.any(BigInt),\n                        space: 165n, // Token account space\n                    },\n                    pubkey: expect.any(String),\n                });\n            });\n        });\n    });\n\n    describe('when called with both a data size and a memcmpy filter', () => {\n        it('returns the matching accounts', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/spl-token-mint-account.json\n            const mint =\n                'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address<'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'>;\n            const program =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const programAccounts = await rpc\n                .getProgramAccounts(program, {\n                    encoding: 'jsonParsed',\n                    filters: [\n                        {\n                            dataSize: 165n, // Token account size\n                        },\n                        {\n                            memcmp: {\n                                bytes: mint as unknown as Base58EncodedBytes,\n                                encoding: 'base58',\n                                offset: 0n,\n                            },\n                        },\n                    ],\n                })\n                .send();\n\n            programAccounts.forEach(item => {\n                expect(item).toMatchObject({\n                    account: {\n                        data: {\n                            parsed: {\n                                info: {\n                                    isNative: expect.any(Boolean),\n                                    mint, // Matches mint address provided in filter.\n                                    owner: expect.any(String),\n                                    state: expect.any(String),\n                                    tokenAmount: {\n                                        amount: expect.any(String),\n                                        decimals: expect.any(Number),\n                                        uiAmount: expect.any(Number),\n                                        uiAmountString: expect.any(String),\n                                    },\n                                },\n                                type: 'account',\n                            },\n                            program: 'spl-token',\n                            space: 165n, // Token account space\n                        },\n                        executable: false,\n                        lamports: expect.any(BigInt),\n                        owner: expect.any(String),\n                        rentEpoch: expect.any(BigInt),\n                        space: 165n, // Token account space\n                    },\n                    pubkey: expect.any(String),\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-recent-performance-samples-test.ts",
    "content": "describe('getRecentPerformanceSamples', () => {\n    // TODO: need a way to create performance samples without waiting 60s\n    describe('when called without a limit', () => {\n        it.todo('returns the latest performance samples');\n    });\n\n    describe('when called with a limit', () => {\n        it.todo('only returns the requested number of performance samples');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-recent-prioritization-fees-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { GetRecentPrioritizationFeesApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getRecentPrioritizationFees', () => {\n    let rpc: Rpc<GetRecentPrioritizationFeesApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    describe('when called with no addresses provided', () => {\n        it('returns a list of prioritization fees', async () => {\n            expect.assertions(1);\n            const res = await rpc.getRecentPrioritizationFees().send();\n            expect(Array.isArray(res)).toBe(true);\n            // TODO: We have no way to reliably ensure at least one slot\n            // has passed at the time of this test, so we can't reliably\n            // expect an array that isn't empty.\n            //\n            // expect(res[0]).toMatchObject({\n            //     prioritizationFee: expect.any(BigInt),\n            //     slot: expect.any(BigInt),\n            // });\n        });\n    });\n\n    describe('when called with one address provided', () => {\n        // TODO: This test does not check whether the response is related to\n        // prioritization fees associated with locking the provided account\n        it('returns a list of prioritization fees', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            const addresses = ['GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address];\n            const res = await rpc.getRecentPrioritizationFees(addresses).send();\n            expect(Array.isArray(res)).toBe(true);\n            // TODO: We have no way to reliably ensure at least one slot\n            // has passed at the time of this test, so we can't reliably\n            // expect an array that isn't empty.\n            //\n            // expect(res[0]).toMatchObject({\n            //     prioritizationFee: expect.any(BigInt),\n            //     slot: expect.any(BigInt),\n            // });\n        });\n    });\n\n    describe('when called with multiple addresses provided', () => {\n        // TODO: This test does not check whether the response is related to\n        // prioritization fees associated with locking the provided accounts\n        it('returns a list of prioritization fees', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc.json\n            // See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n            const addresses = [\n                '4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc' as Address,\n                'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address,\n            ];\n            const res = await rpc.getRecentPrioritizationFees(addresses).send();\n            expect(Array.isArray(res)).toBe(true);\n            // TODO: We have no way to reliably ensure at least one slot\n            // has passed at the time of this test, so we can't reliably\n            // expect an array that isn't empty.\n            //\n            // expect(res[0]).toMatchObject({\n            //     prioritizationFee: expect.any(BigInt),\n            //     slot: expect.any(BigInt),\n            // });\n        });\n    });\n\n    describe('when called with the address of an account that does not exist', () => {\n        // TODO: This test does not check whether the response is related to\n        // prioritization fees associated with locking the provided account\n        it('returns a list of prioritization fees', async () => {\n            expect.assertions(1);\n            // Randomly generated\n            const addresses = ['BnWCFuxmi6uH3ceVx4R8qcbWBMPVVYVVFWtAiiTA1PAu' as Address];\n            const res = await rpc.getRecentPrioritizationFees(addresses).send();\n            expect(Array.isArray(res)).toBe(true);\n            // TODO: We have no way to reliably ensure at least one slot\n            // has passed at the time of this test, so we can't reliably\n            // expect an array that isn't empty.\n            //\n            // expect(res[0]).toMatchObject({\n            //     prioritizationFee: expect.any(BigInt),\n            //     slot: expect.any(BigInt),\n            // });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-signature-statuses-test.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, SolanaError } from '@solana/errors';\nimport type { Signature } from '@solana/keys';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { GetSignatureStatusesApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getSignatureStatuses', () => {\n    let rpc: Rpc<GetSignatureStatusesApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    describe('when called with a valid transaction signature', () => {\n        [true, false].forEach(searchTransactionHistory => {\n            describe(`with \\`searchTransactionHistory\\`: ${searchTransactionHistory} and one signature provided`, () => {\n                // TODO: Cannot test this until we have a way to mock\n                // some transactions without RPC methods\n                it.todo('returns a signature status with the correct shape');\n            });\n\n            describe(`with \\`searchTransactionHistory\\`: ${searchTransactionHistory} and multiple signatures provided`, () => {\n                // TODO: Cannot test this until we have a way to mock\n                // some transactions without RPC methods\n                it.todo('returns a signature status with the correct shape');\n            });\n        });\n    });\n\n    describe('when called with no transaction signature provided', () => {\n        it('returns an empty list', async () => {\n            expect.assertions(1);\n            const signatureStatusPromise = rpc.getSignatureStatuses([]).send();\n            await expect(signatureStatusPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [],\n            });\n        });\n    });\n\n    describe('when called with an invalid transaction signature', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const signatureStatusPromise = rpc.getSignatureStatuses(['invalid_signature' as Signature]).send();\n            await expect(signatureStatusPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid param: Invalid',\n                }),\n            );\n        });\n    });\n\n    describe('when called with a transaction signature that does not exist', () => {\n        it('returns null for that signature', async () => {\n            expect.assertions(1);\n            const signatureStatusPromise = rpc\n                .getSignatureStatuses([\n                    // Randomly generated\n                    '4Vx3PAb665jCLRpbpgKshZuwKP6TUgoSDDAbKEsyvkKhwrNDT6CE5d7MT1vEPkgEo1cmr7zsM8h724wRnjyCAoR3' as Signature,\n                ])\n                .send();\n            await expect(signatureStatusPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [null],\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-signatures-for-address-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { GetSignaturesForAddressApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getSignaturesForAddress', () => {\n    let rpc: Rpc<GetSignaturesForAddressApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (\n        ['confirmed', 'finalized'] as ['confirmed', 'finalized'] as NonNullable<\n            Parameters<typeof rpc.getSignaturesForAddress>[1]\n        >['commitment'][]\n    ).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns no transactions for a new address', async () => {\n                expect.assertions(1);\n                // This key is random, don't re-use in any tests that perform transactions\n                const publicKey =\n                    '3F6rba4VRgdGeYzgCNWQaEJUerUEQVVuwKrETigvHhJP' as Address<'3F6rba4VRgdGeYzgCNWQaEJUerUEQVVuwKrETigvHhJP'>;\n                const transactionsPromise = rpc.getSignaturesForAddress(publicKey, { commitment }).send();\n                await expect(transactionsPromise).resolves.toEqual([]);\n            });\n        });\n    });\n\n    describe('given an account with transactions', () => {\n        // TODO Need to be able to send transactions\n        it.todo('returns the transactions for that account');\n        it.todo('returns only the first transactions when called with a `limit`');\n        it.todo('returns transactions from `since` if defined');\n        it.todo('returns transactions only to `until` if defined');\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            // This key is random, don't re-use in any tests that perform transactions\n            const publicKey = '3F6rba4VRgdGeYzgCNWQaEJUerUEQVVuwKrETigvHhJP' as Address;\n            const sendPromise = rpc\n                .getSignaturesForAddress(publicKey, {\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-slot-leader-test.ts",
    "content": "import { open } from 'node:fs/promises';\n\nimport type { Address } from '@solana/addresses';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\nimport path from 'path';\n\nimport { GetSlotLeaderApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst validatorKeypairPath = path.resolve(__dirname, '../../../../test-ledger/validator-keypair.json');\n\nasync function getValidatorAddress() {\n    const file = await open(validatorKeypairPath);\n    try {\n        let secretKey: Uint8Array | undefined;\n        for await (const line of file.readLines({ encoding: 'binary' })) {\n            secretKey = new Uint8Array(JSON.parse(line));\n            break; // Only need the first line\n        }\n        if (secretKey) {\n            const publicKey = secretKey.slice(32, 64);\n            const expectedAddress = getBase58Decoder().decode(publicKey);\n            return expectedAddress as Address;\n        }\n        throw new Error(`Failed to read keypair file \\`${validatorKeypairPath}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getSlotLeader', () => {\n    let rpc: Rpc<GetSlotLeaderApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            describe('when called with no `minContextSlot`', () => {\n                // This will always be the local validator\n                it(\"returns the leader's address\", async () => {\n                    expect.assertions(1);\n                    const slotLeaderPromise = rpc.getSlotLeader({ commitment }).send();\n                    await expect(slotLeaderPromise).resolves.toEqual(await getValidatorAddress());\n                });\n            });\n\n            describe('when called with a valid `minContextSlot`', () => {\n                // This will always be the local validator\n                it(\"returns the leader's address\", async () => {\n                    expect.assertions(1);\n                    const slotLeaderPromise = rpc.getSlotLeader({ commitment, minContextSlot: 0n }).send();\n                    await expect(slotLeaderPromise).resolves.toEqual(await getValidatorAddress());\n                });\n            });\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const sendPromise = rpc\n                .getSlotLeader({\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-slot-leaders-test.ts",
    "content": "import { open } from 'node:fs/promises';\n\nimport type { Address } from '@solana/addresses';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport path from 'path';\n\nimport { GetSlotLeadersApi, MinimumLedgerSlotApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst validatorKeypairPath = path.resolve(__dirname, '../../../../test-ledger/validator-keypair.json');\n\nasync function getValidatorAddress() {\n    const file = await open(validatorKeypairPath);\n    try {\n        let secretKey: Uint8Array | undefined;\n        for await (const line of file.readLines({ encoding: 'binary' })) {\n            secretKey = new Uint8Array(JSON.parse(line));\n            break; // Only need the first line\n        }\n        if (secretKey) {\n            const publicKey = secretKey.slice(32, 64);\n            const expectedAddress = getBase58Decoder().decode(publicKey);\n            return expectedAddress as Address;\n        }\n        throw new Error(`Failed to read keypair file \\`${validatorKeypairPath}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getSlotLeaders', () => {\n    let rpc: Rpc<GetSlotLeadersApi & MinimumLedgerSlotApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    describe('when called with a valid slot', () => {\n        // This will always be the local validator\n        it('returns the node public keys', async () => {\n            expect.assertions(2);\n            const minimumLedgerSlot = await rpc.minimumLedgerSlot().send();\n\n            const result = await rpc.getSlotLeaders(minimumLedgerSlot, 3).send();\n            expect(Array.isArray(result)).toBe(true);\n            expect(result[0]).toEqual(await getValidatorAddress());\n        });\n    });\n\n    describe('when called with a `startSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const sendPromise = rpc\n                .getSlotLeaders(\n                    2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                    3,\n                )\n                .send();\n            await expect(sendPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid slot range: leader schedule for epoch 21350398233460 is unavailable',\n                }),\n            );\n        });\n    });\n\n    describe('when called with a `limit` greater than 5000', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const minimumLedgerSlot = await rpc.minimumLedgerSlot().send();\n\n            const sendPromise = rpc.getSlotLeaders(minimumLedgerSlot, 5001).send();\n            await expect(sendPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid limit; max 5000',\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-slot-test.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetSlotApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getSlot', () => {\n    let rpc: Rpc<GetSlotApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the result as a bigint', async () => {\n                expect.assertions(1);\n                const result = await rpc.getSlot({ commitment }).send();\n                expect(result).toEqual(expect.any(BigInt));\n            });\n        });\n    });\n    describe('when called with a `minContextSlot` of 0', () => {\n        it('returns the result as a bigint', async () => {\n            expect.assertions(1);\n            const result = await rpc.getSlot({ minContextSlot: 0n }).send();\n            expect(result).toEqual(expect.any(BigInt));\n        });\n    });\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const sendPromise = rpc\n                .getSlot({\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-stake-minimum-delegation-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetStakeMinimumDelegationApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getStakeMinimumDelegation', () => {\n    let rpc: Rpc<GetStakeMinimumDelegationApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the result as a bigint wrapped in an RpcResponseData', async () => {\n                expect.assertions(1);\n                const result = await rpc.getStakeMinimumDelegation({ commitment }).send();\n                expect(result.value).toEqual(expect.any(BigInt));\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-supply-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetSupplyApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getSupply', () => {\n    let rpc: Rpc<GetSupplyApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the supply', async () => {\n                expect.assertions(1);\n                const supply = await rpc.getSupply({ commitment }).send();\n\n                expect(supply).toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        circulating: expect.any(BigInt),\n                        nonCirculating: expect.any(BigInt),\n                        nonCirculatingAccounts: expect.arrayContaining([expect.any(String)]),\n                        total: expect.any(BigInt),\n                    },\n                });\n\n                // TODO: we don't reliably have non-circulating accounts in test validator yet\n                // expect(supply.value.nonCirculatingAccounts.length).toBeGreaterThan(0);\n            });\n        });\n    });\n\n    describe('when called with `excludeNonCirculatingAccountsList: true`', () => {\n        it.todo('returns an empty `nonCirculatingAccounts` array');\n    });\n\n    describe('when called with `excludeNonCirculatingAccountsList: false`', () => {\n        it.todo('returns a non-empty `nonCirculatingAccounts` array');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-token-account-balance-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetTokenAccountBalanceApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getTokenAccountBalance', () => {\n    let rpc: Rpc<GetTokenAccountBalanceApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns token account balance', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-token-account.json\n                const publicKey =\n                    'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca' as Address<'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca'>;\n                const tokenAccountBalancePromise = rpc.getTokenAccountBalance(publicKey, { commitment }).send();\n                await expect(tokenAccountBalancePromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        amount: '9999999779500000',\n                        decimals: 6,\n                        uiAmount: 9999999779.5,\n                        uiAmountString: '9999999779.5',\n                    },\n                });\n            });\n        });\n    });\n\n    describe('when called with an account that is not a token account', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const sendPromise = rpc\n                .getTokenAccountBalance(\n                    // Randomly generated\n                    'BnWCFuxmi6uH3ceVx4R8qcbWBMPVVYVVFWtAiiTA1PAu' as Address,\n                )\n                .send();\n            await expect(sendPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid params: missing field `commitment`.',\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-token-accounts-by-delegate-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SolanaError,\n} from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetTokenAccountsByDelegateApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getTokenAccountsByDelegate', () => {\n    let rpc: Rpc<GetTokenAccountsByDelegateApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns RPC response with account info', async () => {\n                expect.assertions(1);\n                // Delegate for fixtures/spl-token-token-account-delegated.json\n                const delegate =\n                    'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n                // token program for above delegated token account\n                const tokenProgram =\n                    'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n                const accountInfosPromise = rpc\n                    .getTokenAccountsByDelegate(\n                        delegate,\n                        { programId: tokenProgram },\n                        {\n                            commitment,\n                            encoding: 'base64',\n                        },\n                    )\n                    .send();\n\n                await expect(accountInfosPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            account: {\n                                data: [\n                                    'MzQJGAUaL2fumioXGww9PVOXgMEaYSUPr/X0cUZdeAYsDL6z1hknAtbDjgZSI7IFX/T4ppGnUviTNyfH5/mUSwAQpdToAAAAAQAAAN++YxbNiIWM+zxxHYuV2FyrImZH2l93yTIUPo7gDw6JAQAAAAAAAAAAAAAAAADodkgXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n                                    'base64',\n                                ],\n                                executable: false,\n                                lamports: 10290815n,\n                                owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                rentEpoch: 0n,\n                                space: 165n,\n                            },\n                            pubkey: '6uGCrvzPAta1nc6wP9oHvM6sRDu1kXTMuJSJvro4R4xS',\n                        },\n                    ],\n                });\n            });\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws a slot not reached error', async () => {\n            expect.assertions(3);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // token program for above delegated token account\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfoPromise = rpc\n                .getTokenAccountsByDelegate(\n                    delegate,\n                    { programId: tokenProgram },\n                    {\n                        minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                    },\n                )\n                .send();\n            await Promise.all([\n                expect(accountInfoPromise).rejects.toThrow(SolanaError),\n                expect(accountInfoPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(accountInfoPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n\n    describe('when called with a delegate with no accounts', () => {\n        it('returns an empty list', async () => {\n            expect.assertions(1);\n            // randomly generated\n            const delegate =\n                'AUbvs341pr8rvpUaDBjpxhH9sg62eVsaMTV6vHoz4iJF' as Address<'AUbvs341pr8rvpUaDBjpxhH9sg62eVsaMTV6vHoz4iJF'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByDelegate(delegate, { programId: tokenProgram }).send();\n            await expect(accountInfoPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [],\n            });\n        });\n    });\n\n    describe('when called with a mint that does not exist', () => {\n        it('throws an error for mint not existing', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // randomly generated\n            const mint =\n                'bYaTaiLtMmTfqZaVbo2rwQrdj1iA2DdjMrSACLCSZj4' as Address<'bYaTaiLtMmTfqZaVbo2rwQrdj1iA2DdjMrSACLCSZj4'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByDelegate(delegate, { mint }).send();\n            await expect(accountInfoPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid param: could not find mint',\n                }),\n            );\n        });\n    });\n\n    describe('when called with a mint that has a delegated token account', () => {\n        it('returns RPC response with account info', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // Mint at fixtures/spl-token-mint-account-with-delegated.json (mint for above delegated account)\n            const mint =\n                '4SspA9vWmizwcvngHTapwQtpnRrPf8V483giCSaCmy6M' as Address<'4SspA9vWmizwcvngHTapwQtpnRrPf8V483giCSaCmy6M'>;\n\n            const accountInfosPromise = rpc\n                .getTokenAccountsByDelegate(\n                    delegate,\n                    { mint },\n                    {\n                        encoding: 'base64',\n                    },\n                )\n                .send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        account: {\n                            data: [\n                                'MzQJGAUaL2fumioXGww9PVOXgMEaYSUPr/X0cUZdeAYsDL6z1hknAtbDjgZSI7IFX/T4ppGnUviTNyfH5/mUSwAQpdToAAAAAQAAAN++YxbNiIWM+zxxHYuV2FyrImZH2l93yTIUPo7gDw6JAQAAAAAAAAAAAAAAAADodkgXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n                                'base64',\n                            ],\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                        pubkey: '6uGCrvzPAta1nc6wP9oHvM6sRDu1kXTMuJSJvro4R4xS',\n                    },\n                ],\n            });\n        });\n    });\n\n    describe('when called with a mint that has no delegated token accounts', () => {\n        it('returns an empty list', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // Mint at fixtures/spl-token-mint-no-token-accounts.json (not the same mint as above delegated account)\n            const mint =\n                'HWHfrWotTpaNArteqeYDziV1ZX9Lm7WV684NeUCwPPzj' as Address<'HWHfrWotTpaNArteqeYDziV1ZX9Lm7WV684NeUCwPPzj'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByDelegate(delegate, { mint }).send();\n\n            await expect(accountInfoPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [],\n            });\n        });\n    });\n\n    describe('when called with a program that is not a Token program', () => {\n        it('throws an error for unrecognized program', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // randomly generated\n            const programId =\n                'HFnhCvdV9yyShcFNQvdR5LazsKXpnJNxwoRKjE9V1LrF' as Address<'HFnhCvdV9yyShcFNQvdR5LazsKXpnJNxwoRKjE9V1LrF'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByDelegate(delegate, { programId }).send();\n            await expect(accountInfoPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid param: unrecognized Token program id',\n                }),\n            );\n        });\n    });\n\n    describe('when called with a program that has no delegated token accounts', () => {\n        it('returns an empty list', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // Token22 program (not the same as above delegated account fixture)\n            const programId =\n                'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb' as Address<'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByDelegate(delegate, { programId }).send();\n\n            await expect(accountInfoPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [],\n            });\n        });\n    });\n\n    describe('when called with base58 encoding', () => {\n        // Currently we can't test this because every token account is >128 bytes\n        // The solana source only allows base58 encoding up to 128 bytes: https://github.com/anza-xyz/agave/blob/d11072e4e00cb3a8009f62b3bddcec79069f970a/account-decoder/src/lib.rs#L39-L43\n        it.todo('returns RPC Response with account info with annotated base58 encoding');\n    });\n\n    describe('when called with base64 encoding', () => {\n        it('returns RPC Response with account info with annotated base64 encoding', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfosPromise = rpc\n                .getTokenAccountsByDelegate(\n                    delegate,\n                    { programId: tokenProgram },\n                    {\n                        encoding: 'base64',\n                    },\n                )\n                .send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        account: {\n                            data: [\n                                'MzQJGAUaL2fumioXGww9PVOXgMEaYSUPr/X0cUZdeAYsDL6z1hknAtbDjgZSI7IFX/T4ppGnUviTNyfH5/mUSwAQpdToAAAAAQAAAN++YxbNiIWM+zxxHYuV2FyrImZH2l93yTIUPo7gDw6JAQAAAAAAAAAAAAAAAADodkgXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n                                'base64',\n                            ],\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                        pubkey: '6uGCrvzPAta1nc6wP9oHvM6sRDu1kXTMuJSJvro4R4xS',\n                    },\n                ],\n            });\n        });\n    });\n\n    describe('when called with base64+zstd encoding', () => {\n        it('returns RPC Response with account info with annotated base64+zstd encoding', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfosPromise = rpc\n                .getTokenAccountsByDelegate(\n                    delegate,\n                    { programId: tokenProgram },\n                    {\n                        encoding: 'base64+zstd',\n                    },\n                )\n                .send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        account: {\n                            data: [\n                                'KLUv/QBY5QMANAczNAkYBRovZ+6aKhcbDD09U5eAwRphJQ+v9fRxRl14BiwMvrPWGScC1sOOBlIjsgVf9PimkadS+JM3J8fn+ZRLABCl1OgAAAABAAAA375jFs2IhYz7PHEdi5XYXKsiZkfaX3fJMhQ+juAPDokBAOh2SBcAAgDBoy4Hzg==',\n                                'base64+zstd',\n                            ],\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                        pubkey: '6uGCrvzPAta1nc6wP9oHvM6sRDu1kXTMuJSJvro4R4xS',\n                    },\n                ],\n            });\n        });\n    });\n\n    describe('when called with jsonParsed encoding', () => {\n        it('returns RPC response with parsed JSON data for SPL Token token account', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfosPromise = rpc\n                .getTokenAccountsByDelegate(\n                    delegate,\n                    { programId: tokenProgram },\n                    {\n                        encoding: 'jsonParsed',\n                    },\n                )\n                .send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        account: {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        delegate: 'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL',\n                                        delegatedAmount: {\n                                            amount: '100000000000',\n                                            decimals: 9,\n                                            uiAmount: 100,\n                                            uiAmountString: '100',\n                                        },\n                                        isNative: false,\n                                        mint: '4SspA9vWmizwcvngHTapwQtpnRrPf8V483giCSaCmy6M',\n                                        owner: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                                        state: 'initialized',\n                                        tokenAmount: {\n                                            amount: '1000000000000',\n                                            decimals: 9,\n                                            uiAmount: 1000,\n                                            uiAmountString: '1000',\n                                        },\n                                    },\n                                    type: 'account',\n                                },\n                                program: 'spl-token',\n                                space: 165n,\n                            },\n                            executable: false,\n                            lamports: 10290815n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                        pubkey: '6uGCrvzPAta1nc6wP9oHvM6sRDu1kXTMuJSJvro4R4xS',\n                    },\n                ],\n            });\n        });\n    });\n\n    describe('when called with no encoding', () => {\n        // Currently we can't test this because every token account is >128 bytes\n        // The solana source only allows base58 encoding up to 128 bytes: https://github.com/anza-xyz/agave/blob/d11072e4e00cb3a8009f62b3bddcec79069f970a/account-decoder/src/lib.rs#L39-L43\n        it.todo('returns base58 data without an annotation');\n    });\n\n    describe('when called with a dataSlice', () => {\n        it('returns the slice of the data', async () => {\n            expect.assertions(1);\n            // Delegate for fixtures/spl-token-token-account-delegated.json\n            const delegate =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfo = await rpc\n                .getTokenAccountsByDelegate(\n                    delegate,\n                    { programId: tokenProgram },\n                    {\n                        dataSlice: { length: 10, offset: 0 },\n                        encoding: 'base64',\n                    },\n                )\n                .send();\n\n            expect(accountInfo.value[0].account.data[0].length).toBeLessThan(20);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-token-accounts-by-owner-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SolanaError,\n} from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetTokenAccountsByOwnerApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getTokenAccountsByOwner', () => {\n    let rpc: Rpc<GetTokenAccountsByOwnerApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns RPC response with account info', async () => {\n                expect.assertions(1);\n                // Owner for fixtures/spl-token-token-account-owner.json\n                const owner =\n                    'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n                // token program for above token account\n                const tokenProgram =\n                    'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n                const accountInfosPromise = rpc\n                    .getTokenAccountsByOwner(\n                        owner,\n                        { programId: tokenProgram },\n                        {\n                            commitment,\n                            encoding: 'base64',\n                        },\n                    )\n                    .send();\n\n                await expect(accountInfosPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            account: {\n                                data: [\n                                    'Gm8Iy/4ID/afCSL46M6y025/coiwRHJeND8W2XNpBsTfvmMWzYiFjPs8cR2LldhcqyJmR9pfd8kyFD6O4A8OiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n                                    'base64',\n                                ],\n                                executable: false,\n                                lamports: 2039280n,\n                                owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                rentEpoch: 0n,\n                                space: 165n,\n                            },\n                            pubkey: 'GoJdqNkvpf26BAX8cYsV3bb52kbBYt7vT5rqpPGGgK5F',\n                        },\n                    ],\n                });\n            });\n        });\n    });\n\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws a slot not reached error', async () => {\n            expect.assertions(3);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // token program for above token account\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfoPromise = rpc\n                .getTokenAccountsByOwner(\n                    owner,\n                    { programId: tokenProgram },\n                    {\n                        minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                    },\n                )\n                .send();\n            await Promise.all([\n                expect(accountInfoPromise).rejects.toThrow(SolanaError),\n                expect(accountInfoPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(accountInfoPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n\n    describe('when called with an owner with no accounts', () => {\n        it('returns an empty list', async () => {\n            expect.assertions(1);\n            // randomly generated\n            const owner =\n                'GS2BpYHDF7p3NortvgvUFsFyqZGe7HjBPNkBiABccfN8' as Address<'GS2BpYHDF7p3NortvgvUFsFyqZGe7HjBPNkBiABccfN8'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByOwner(owner, { programId: tokenProgram }).send();\n            await expect(accountInfoPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [],\n            });\n        });\n    });\n\n    describe('when called with a mint that does not exist', () => {\n        it('throws an error for mint not existing', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // randomly generated\n            const mint =\n                'bYaTaiLtMmTfqZaVbo2rwQrdj1iA2DdjMrSACLCSZj4' as Address<'bYaTaiLtMmTfqZaVbo2rwQrdj1iA2DdjMrSACLCSZj4'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByOwner(owner, { mint }).send();\n            await expect(accountInfoPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid param: could not find mint',\n                }),\n            );\n        });\n    });\n\n    describe('when called with a mint that has a token account', () => {\n        it('returns RPC response with account info', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // Mint at fixtures/spl-token-mint-account-with-owner.json (mint for above account)\n            const mint =\n                '2nBoNW5B9SdpJYEg9neii7ecCJFwh6UrbXS6HFxkK7Gf' as Address<'2nBoNW5B9SdpJYEg9neii7ecCJFwh6UrbXS6HFxkK7Gf'>;\n\n            const accountInfosPromise = rpc\n                .getTokenAccountsByOwner(\n                    owner,\n                    { mint },\n                    {\n                        encoding: 'base64',\n                    },\n                )\n                .send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        account: {\n                            data: [\n                                'Gm8Iy/4ID/afCSL46M6y025/coiwRHJeND8W2XNpBsTfvmMWzYiFjPs8cR2LldhcqyJmR9pfd8kyFD6O4A8OiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n                                'base64',\n                            ],\n                            executable: false,\n                            lamports: 2039280n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                        pubkey: 'GoJdqNkvpf26BAX8cYsV3bb52kbBYt7vT5rqpPGGgK5F',\n                    },\n                ],\n            });\n        });\n    });\n\n    describe('when called with a mint that has no token accounts', () => {\n        it('returns an empty list', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // Mint at fixtures/spl-token-mint-no-token-accounts.json (not the same mint as above account)\n            const mint =\n                'HWHfrWotTpaNArteqeYDziV1ZX9Lm7WV684NeUCwPPzj' as Address<'HWHfrWotTpaNArteqeYDziV1ZX9Lm7WV684NeUCwPPzj'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByOwner(owner, { mint }).send();\n\n            await expect(accountInfoPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [],\n            });\n        });\n    });\n\n    describe('when called with a program that is not a Token program', () => {\n        it('throws an error for unrecognized program', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // randomly generated\n            const programId =\n                'AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk' as Address<'AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByOwner(owner, { programId }).send();\n            await expect(accountInfoPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid param: unrecognized Token program id',\n                }),\n            );\n        });\n    });\n\n    describe('when called with a program that has no token accounts', () => {\n        it('returns an empty list', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            // Token22 program (not the same as above account fixture)\n            const programId =\n                'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb' as Address<'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb'>;\n\n            const accountInfoPromise = rpc.getTokenAccountsByOwner(owner, { programId }).send();\n\n            await expect(accountInfoPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [],\n            });\n        });\n    });\n\n    describe('when called with base58 encoding', () => {\n        // Currently we can't test this because every token account is >128 bytes\n        // The solana source only allows base58 encoding up to 128 bytes: https://github.com/anza-xyz/agave/blob/d11072e4e00cb3a8009f62b3bddcec79069f970a/account-decoder/src/lib.rs#L39-L43\n        it.todo('returns RPC Response with account info with annotated base58 encoding');\n    });\n\n    describe('when called with base64 encoding', () => {\n        it('returns RPC Response with account info with annotated base64 encoding', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfosPromise = rpc\n                .getTokenAccountsByOwner(\n                    owner,\n                    { programId: tokenProgram },\n                    {\n                        encoding: 'base64',\n                    },\n                )\n                .send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        account: {\n                            data: [\n                                'Gm8Iy/4ID/afCSL46M6y025/coiwRHJeND8W2XNpBsTfvmMWzYiFjPs8cR2LldhcqyJmR9pfd8kyFD6O4A8OiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n                                'base64',\n                            ],\n                            executable: false,\n                            lamports: 2039280n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                        pubkey: 'GoJdqNkvpf26BAX8cYsV3bb52kbBYt7vT5rqpPGGgK5F',\n                    },\n                ],\n            });\n        });\n    });\n\n    describe('when called with base64+zstd encoding', () => {\n        it('returns RPC Response with account info with annotated base64+zstd encoding', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfosPromise = rpc\n                .getTokenAccountsByOwner(\n                    owner,\n                    { programId: tokenProgram },\n                    {\n                        encoding: 'base64+zstd',\n                    },\n                )\n                .send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        account: {\n                            data: [\n                                'KLUv/QBYbQIANAQabwjL/ggP9p8JIvjozrLTbn9yiLBEcl40PxbZc2kGxN++YxbNiIWM+zxxHYuV2FyrImZH2l93yTIUPo7gDw6JAAEAAgAEJwaY4Aw=',\n                                'base64+zstd',\n                            ],\n                            executable: false,\n                            lamports: 2039280n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                        pubkey: 'GoJdqNkvpf26BAX8cYsV3bb52kbBYt7vT5rqpPGGgK5F',\n                    },\n                ],\n            });\n        });\n    });\n\n    describe('when called with jsonParsed encoding', () => {\n        it('returns RPC response with parsed JSON data for SPL Token token account', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfosPromise = rpc\n                .getTokenAccountsByOwner(\n                    owner,\n                    { programId: tokenProgram },\n                    {\n                        encoding: 'jsonParsed',\n                    },\n                )\n                .send();\n\n            await expect(accountInfosPromise).resolves.toStrictEqual({\n                context: CONTEXT_MATCHER,\n                value: [\n                    {\n                        account: {\n                            data: {\n                                parsed: {\n                                    info: {\n                                        isNative: false,\n                                        mint: '2nBoNW5B9SdpJYEg9neii7ecCJFwh6UrbXS6HFxkK7Gf',\n                                        owner: 'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL',\n                                        state: 'initialized',\n                                        tokenAmount: {\n                                            amount: '0',\n                                            decimals: 9,\n                                            uiAmount: 0,\n                                            uiAmountString: '0',\n                                        },\n                                    },\n                                    type: 'account',\n                                },\n                                program: 'spl-token',\n                                space: 165n,\n                            },\n                            executable: false,\n                            lamports: 2039280n,\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            rentEpoch: 0n,\n                            space: 165n,\n                        },\n                        pubkey: 'GoJdqNkvpf26BAX8cYsV3bb52kbBYt7vT5rqpPGGgK5F',\n                    },\n                ],\n            });\n        });\n    });\n\n    describe('when called with no encoding', () => {\n        // Currently we can't test this because every token account is >128 bytes\n        // The solana source only allows base58 encoding up to 128 bytes: https://github.com/anza-xyz/agave/blob/d11072e4e00cb3a8009f62b3bddcec79069f970a/account-decoder/src/lib.rs#L39-L43\n        it.todo('returns base58 data without an annotation');\n    });\n\n    describe('when called with a dataSlice', () => {\n        it('returns the slice of the data', async () => {\n            expect.assertions(1);\n            // Owner for fixtures/spl-token-token-account-owner.json\n            const owner =\n                'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL' as Address<'G4QJANEpvEN8vLaaMZoWwZtqHfWxuWpd5RrVVYXPCgeL'>;\n\n            const tokenProgram =\n                'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n            const accountInfo = await rpc\n                .getTokenAccountsByOwner(\n                    owner,\n                    { programId: tokenProgram },\n                    {\n                        dataSlice: { length: 10, offset: 0 },\n                        encoding: 'base64',\n                    },\n                )\n                .send();\n\n            expect(accountInfo.value[0].account.data[0].length).toBeLessThan(20);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-token-largest-accounts-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetTokenLargestAccountsApi, GetTokenSupplyApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getTokenLargestAccounts', () => {\n    let rpc: Rpc<GetTokenLargestAccountsApi & GetTokenSupplyApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            // TODO: will need a way to create token mint + accounts in tests\n            it('returns the 20 largest token accounts', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-mint-account.json\n                const pubkey =\n                    'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address<'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'>;\n                const tokenAccountBalancePromise = rpc.getTokenLargestAccounts(pubkey, { commitment }).send();\n                await expect(tokenAccountBalancePromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: [\n                        {\n                            address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n                            amount: '9999999779500000',\n                            decimals: 6,\n                            // This can be Number or null, but we're using a fixture so it should be Number\n                            uiAmount: 9999999779.5,\n                            uiAmountString: '9999999779.5',\n                        },\n                    ],\n                });\n            });\n        });\n    });\n\n    describe('when called with an account that is not a token mint', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const sendPromise = rpc\n                .getTokenSupply(\n                    // Randomly generated\n                    'BnWCFuxmi6uH3ceVx4R8qcbWBMPVVYVVFWtAiiTA1PAu' as Address,\n                )\n                .send();\n            await expect(sendPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid params: missing field `commitment`.',\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-token-supply-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetTokenSupplyApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\ndescribe('getTokenSupply', () => {\n    let rpc: Rpc<GetTokenSupplyApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns total token supply', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/spl-token-mint-account.json\n                const pubkey =\n                    'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address<'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'>;\n                const tokenAccountBalancePromise = rpc.getTokenSupply(pubkey, { commitment }).send();\n                await expect(tokenAccountBalancePromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: {\n                        amount: '1690580887590527729',\n                        decimals: 6,\n                        // This can be Number or null, but we're using a fixture so it should be Number\n                        uiAmount: 1690580887590.5278,\n                        uiAmountString: '1690580887590.527729',\n                    },\n                });\n            });\n        });\n    });\n\n    describe('when called with an account that is not a token mint', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const sendPromise = rpc\n                .getTokenSupply(\n                    // Randomly generated\n                    'BnWCFuxmi6uH3ceVx4R8qcbWBMPVVYVVFWtAiiTA1PAu' as Address,\n                )\n                .send();\n            await expect(sendPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                    __serverMessage: 'Invalid params: missing field `commitment`.',\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-transaction-count-test.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED, SolanaError } from '@solana/errors';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetTransactionCountApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getTransactionCount', () => {\n    let rpc: Rpc<GetTransactionCountApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the result as a bigint', async () => {\n                expect.assertions(1);\n                const result = await rpc.getTransactionCount({ commitment }).send();\n                expect(result).toEqual(expect.any(BigInt));\n            });\n        });\n    });\n    describe('when called with a `minContextSlot` of 0', () => {\n        it('returns the result as a bigint', async () => {\n            expect.assertions(1);\n            const result = await rpc.getTransactionCount({ minContextSlot: 0n }).send();\n            expect(result).toEqual(expect.any(BigInt));\n        });\n    });\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const sendPromise = rpc\n                .getTransactionCount({\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                })\n                .send();\n            await Promise.all([\n                expect(sendPromise).rejects.toThrow(SolanaError),\n                expect(sendPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(sendPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-transaction-test.ts",
    "content": "// import { createHttpTransport, createJsonRpc, type Rpc } from '@solana/rpc-types';\n\n// import { createSolanaRpcApi, GetTransactionApi } from '../index';\n\ndescribe('getTransaction', () => {\n    // let rpc: Rpc<GetTransactionApi>;\n    beforeEach(() => {\n        // rpc = createJsonRpc<GetTransactionApi>({\n        //   api: createSolanaRpcApi(),\n        //   transport: createHttpTransport({ url: 'http://127.0.0.1:8899' }),\n        // });\n    });\n\n    describe('returns a transaction with the correct shape', () => {\n        it.todo('when called with json encoding and maxSupportedTransactionVersion is set');\n        it.todo('when called with jsonParsed encoding and maxSupportedTransactionVersion is set');\n        it.todo('when called with base58 encoding and maxSupportedTransactionVersion is set');\n        it.todo('when called with base64 encoding and maxSupportedTransactionVersion is set');\n        it.todo('when called with json encoding and maxSupportedTransactionVersion is not set');\n        it.todo('when called with jsonParsed encoding and maxSupportedTransactionVersion is not set');\n        it.todo('when called with base58 encoding and maxSupportedTransactionVersion is not set');\n        it.todo('when called with base64 encoding and maxSupportedTransactionVersion is not set');\n        it.todo('when called without config');\n    });\n\n    ['json', 'jsonParsed', 'base64', 'base58'].forEach(_encoding => {\n        describe('when requesting a v0 transaction without a defined maxSupportedTransactionVersion', () => {\n            it.todo('throws an error'); // -32015 JSON_RPC_SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-version-test.ts",
    "content": "import { open } from 'node:fs/promises';\n\nimport type { Rpc } from '@solana/rpc-spec';\nimport path from 'path';\n\nimport { GetVersionApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst logFilePath = path.resolve(__dirname, '../../../../test-ledger/validator.log');\nconst featureSetPattern = /feat:([\\d]+)/;\nconst versionPattern = /agave-validator ([\\d.]+)/;\n\nasync function getVersionFromLogFile() {\n    const file = await open(logFilePath);\n    try {\n        let version: string | undefined;\n        let featureSet: number | undefined;\n        for await (const line of file.readLines({ encoding: 'utf-8' })) {\n            const featureSetMatch = line.match(featureSetPattern);\n            if (featureSetMatch) {\n                featureSet = parseInt(featureSetMatch[1]);\n            }\n            const versionMatch = line.match(versionPattern);\n            if (versionMatch) {\n                version = versionMatch[1];\n            }\n            if (version && featureSet) {\n                return [featureSet, version];\n            }\n        }\n        throw new Error(`Version info not found in logfile \\`${logFilePath}\\``);\n    } finally {\n        await file.close();\n    }\n}\n\ndescribe('getVersion', () => {\n    let rpc: Rpc<GetVersionApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    describe('when called on a valid node', () => {\n        it('returns the version', async () => {\n            expect.assertions(1);\n            const [expectedFeatureSet, expectedVersion] = await getVersionFromLogFile();\n            const versionPromise = rpc.getVersion().send();\n            await expect(versionPromise).resolves.toMatchObject({\n                'feature-set': expectedFeatureSet,\n                'solana-core': expectedVersion,\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/get-vote-accounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { GetVoteAccountsApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('getVoteAccounts', () => {\n    let rpc: Rpc<GetVoteAccountsApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns current and delinquent vote accounts', async () => {\n                expect.assertions(1);\n                const voteAccountsPromise = rpc.getVoteAccounts().send();\n                await expect(voteAccountsPromise).resolves.toStrictEqual({\n                    // FIXME: The legacy vote account tests add vote accounts to the local validator\n                    //        (which is shared with this test) in such a way that makes a\n                    //        `toStrictEqual()` assertion impossible here.\n                    current: expect.arrayContaining([\n                        {\n                            // Fixture\n                            activatedStake: expect.any(BigInt), // Changes\n                            commission: 50,\n                            epochCredits: expect.any(Array), // Changes\n                            epochVoteAccount: true,\n                            lastVote: expect.any(BigInt), // Changes\n                            nodePubkey: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                            rootSlot: expect.any(BigInt), // Changes\n                            votePubkey: '4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp',\n                        },\n                    ]),\n                    delinquent: expect.any(Array), // Changes\n                });\n            });\n\n            // TODO: don't have a way to create vote accounts yet\n            it.todo('returns vote accounts with the correct shape');\n        });\n    });\n\n    describe('when called with a `votePubkey` of a single vote account', () => {\n        it.todo('returns only that vote account');\n    });\n\n    describe('when called with a `votePubkey` of a vote account that does not exist', () => {\n        it('returns empty `current` and `delinquent` fields', async () => {\n            expect.assertions(1);\n            // randomly generated address, don't re-use in anything that creates a vote account\n            const address =\n                '2eTCZxWZkU5h3Mo162gLRTECzuJhPgC1McB9rCcoqNm2' as Address<'2eTCZxWZkU5h3Mo162gLRTECzuJhPgC1McB9rCcoqNm2'>;\n            const voteAccountsPromise = rpc.getVoteAccounts({ votePubkey: address }).send();\n            await expect(voteAccountsPromise).resolves.toStrictEqual({\n                current: [],\n                delinquent: [],\n            });\n        });\n    });\n\n    describe('when called with `keepUnstakedDelinquents` set to false', () => {\n        it.todo('filters out delinquent vote accounts with `activeStake` of 0');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/is-blockhash-valid-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\nimport type { Blockhash, Commitment } from '@solana/rpc-types';\n\nimport { IsBlockhashValidApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('isBlockhashValid', () => {\n    let rpc: Rpc<IsBlockhashValidApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the result as a bool wrapped in an RpcResponseData', async () => {\n                expect.assertions(1);\n                const blockhash = '9PCVWkKP3bq1sT5eLFurUysMvVs4PxJsTfza5QSBB4d1' as Blockhash;\n                const result = await rpc.isBlockhashValid(blockhash, { commitment }).send();\n                expect(result.value).toEqual(expect.any(Boolean));\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/minimum-ledger-slot-test.ts",
    "content": "import type { Rpc } from '@solana/rpc-spec';\n\nimport { MinimumLedgerSlotApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('minimumLedgerSlot', () => {\n    let rpc: Rpc<MinimumLedgerSlotApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    describe('when called with no parameters', () => {\n        it('returns a bigint', async () => {\n            expect.assertions(1);\n            const result = await rpc.minimumLedgerSlot().send();\n            expect(result).toEqual(expect.any(BigInt));\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/request-airdrop-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment, Lamports } from '@solana/rpc-types';\n\nimport { RequestAirdropApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('requestAirdrop', () => {\n    let rpc: Rpc<RequestAirdropApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it('returns the signature of the airdrop', async () => {\n                expect.assertions(1);\n                const randomBytes = new Uint8Array(32);\n                crypto.getRandomValues(randomBytes);\n                const publicKeyAddress = getBase58Decoder().decode(randomBytes);\n                const resultPromise = rpc\n                    .requestAirdrop(publicKeyAddress as Address, 5000000n as Lamports, {\n                        commitment,\n                    })\n                    .send();\n                await expect(resultPromise).resolves.toEqual(expect.any(String));\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/send-transaction-test.ts",
    "content": "import { Buffer } from 'node:buffer';\n\nimport { fixEncoderSize } from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n    SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE,\n    SolanaError,\n} from '@solana/errors';\nimport { createPrivateKeyFromBytes } from '@solana/keys';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Commitment } from '@solana/rpc-types';\nimport type { Base64EncodedWireTransaction } from '@solana/transactions';\n\nimport { GetLatestBlockhashApi, GetMinimumBalanceForRentExemptionApi, SendTransactionApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nfunction getMockTransactionMessage({\n    blockhash,\n    feePayerAddressBytes,\n    memoString,\n    version = 0x80, // 0 + version mask\n}: {\n    blockhash: string;\n    feePayerAddressBytes: Uint8Array;\n    memoString: string;\n    version?: number;\n}) {\n    const blockhashBytes = fixEncoderSize(getBase58Encoder(), 32).encode(blockhash);\n    // prettier-ignore\n    return new Uint8Array([\n        /** VERSION HEADER */\n        version,\n\n        /** MESSAGE HEADER */\n        0x01, // numSignerAccounts\n        0x00, // numReadonlySignerAccount\n        0x01, // numReadonlyNonSignerAccounts\n\n        /** STATIC ADDRESSES */\n        0x02, // Number of static accounts\n            ...feePayerAddressBytes,\n            0x05, 0x4a, 0x53, 0x5a, 0x99, 0x29, 0x21, 0x06, 0x4d, 0x24, 0xe8, 0x71, 0x60, 0xda, 0x38, 0x7c, 0x7c, 0x35, 0xb5, 0xdd, 0xbc, 0x92, 0xbb, 0x81, 0xe4, 0x1f, 0xa8, 0x40, 0x41, 0x05, 0x44, 0x8d, // MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\n\n        /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n        ...blockhashBytes,\n\n        /* INSTRUCTIONS */\n        0x01, // Number of instructions\n\n            // First instruction\n            0x01, // Program address index\n            0x00, // Number of address indices\n            memoString.length, // Length of instruction data\n                ...new TextEncoder().encode(memoString),\n\n        /** ADDRESS TABLE LOOKUPS */\n        0x00, // Number of address table lookups\n    ]);\n}\nconst MOCK_PRIVATE_KEY_BYTES = new Uint8Array([\n    16, 192, 67, 187, 170, 210, 152, 95, 180, 204, 123, 21, 81, 45, 171, 85, 188, 91, 164, 34, 8, 0, 244, 56, 209, 190,\n    255, 201, 212, 94, 45, 186,\n]);\n// See scripts/fixtures/send-transaction-fee-payer.json\nconst MOCK_PUBLIC_KEY_BYTES = // DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i\n    // prettier-ignore\n    new Uint8Array([\n        0xb8, 0xac, 0x70, 0x4f, 0xaf, 0xc7, 0xa5, 0xfc, 0x8c, 0x5d, 0x1f, 0x0a, 0xc8, 0xcf, 0xaa, 0xe0,\n        0x42, 0xfa, 0x3b, 0xb8, 0x25, 0xf0, 0xec, 0xfc, 0xe2, 0x27, 0x4d, 0x7d, 0xad, 0xad, 0x51, 0x2d,\n    ]);\n\nconst MOCK_INSUFFICIENT_BALANCE_PRIVATE_KEY_BYTES = new Uint8Array([\n    153, 77, 119, 0, 167, 108, 113, 105, 100, 122, 229, 212, 244, 214, 192, 210, 79, 109, 245, 95, 24, 121, 235, 17, 55,\n    166, 132, 117, 31, 134, 31, 171,\n]);\n// See scripts/fixtures/send-transaction-fee-payer-insuffcient-funds.json\nconst MOCK_INSUFFICIENT_BALANCE_PUBLIC_KEY_BYTES = // 6Zs91PMyhqyMgNVuT8EnM6f3YjVAVabvVWLjpFSC288q\n    // prettier-ignore\n    new Uint8Array([\n        0x52, 0xb5, 0xb6, 0x37, 0xf1, 0x28, 0x73, 0x8d, 0x25, 0x61, 0x59, 0xba, 0xca, 0x2b, 0x99, 0x20,\n        0x1c, 0xa8, 0xa6, 0xb3, 0xa1, 0x95, 0xfc, 0x07, 0x9d, 0xa2, 0xf1, 0xb7, 0x33, 0xc0, 0xa5, 0x3a,\n    ]);\n\nasync function getSecretKey(privateKeyBytes: Uint8Array) {\n    return await createPrivateKeyFromBytes(privateKeyBytes, /* extractable */ false);\n}\n\ndescribe('sendTransaction', () => {\n    let rpc: Rpc<GetLatestBlockhashApi & GetMinimumBalanceForRentExemptionApi & SendTransactionApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` preflight commitment`, () => {\n            if (commitment === 'finalized') {\n                it.todo(\n                    'returns the transaction signature (test broken; see https://discord.com/channels/428295358100013066/560496939779620864/1132048104728825926)',\n                );\n                return;\n            }\n            it('returns the transaction signature', async () => {\n                expect.assertions(1);\n                const [secretKey, { value: latestBlockhash }] = await Promise.all([\n                    getSecretKey(MOCK_PRIVATE_KEY_BYTES),\n                    rpc.getLatestBlockhash({ commitment }).send(),\n                ]);\n                const message = getMockTransactionMessage({\n                    blockhash: latestBlockhash.blockhash,\n                    feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n                    memoString: `Hello from the Kit tests! [${performance.now()}]`,\n                });\n                const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n                const resultPromise = rpc\n                    .sendTransaction(\n                        Buffer.from(\n                            new Uint8Array([\n                                0x01, // Length of signatures\n                                ...signature,\n                                ...message,\n                            ]),\n                        ).toString('base64') as Base64EncodedWireTransaction,\n                        { encoding: 'base64', preflightCommitment: commitment },\n                    )\n                    .send();\n                await expect(resultPromise).resolves.toEqual(getBase58Decoder().decode(signature));\n            });\n        });\n    });\n    it('fatals when called with a transaction having an invalid signature', async () => {\n        expect.assertions(1);\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: 'processed' }).send();\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(Array(64).fill(0));\n        const resultPromise = rpc\n            .sendTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { encoding: 'base64', preflightCommitment: 'processed' },\n            )\n            .send();\n        await expect(resultPromise).rejects.toHaveProperty(\n            'context.__code',\n            SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE,\n        );\n    });\n    it('fatals when called with a transaction having an unsupported version', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(MOCK_PRIVATE_KEY_BYTES),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n            version: 0xfe, // Version 126\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .sendTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { encoding: 'base64', preflightCommitment: 'processed' },\n            )\n            .send();\n        await expect(resultPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                __serverMessage:\n                    'failed to deserialize solana_transaction::versioned::VersionedTransaction: ' +\n                    'invalid value: integer `126`, expected a valid transaction message version',\n            }),\n        );\n    });\n    it('fatals when called with a malformed transaction message', async () => {\n        expect.assertions(1);\n        const secretKey = await getSecretKey(MOCK_PRIVATE_KEY_BYTES);\n        const message = new Uint8Array([4, 5, 6]);\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .sendTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { encoding: 'base64', preflightCommitment: 'processed' },\n            )\n            .send();\n        await expect(resultPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                __serverMessage:\n                    'failed to deserialize solana_transaction::versioned::VersionedTransaction: ' +\n                    'io error: failed to fill whole buffer',\n            }),\n        );\n    });\n    it(\"fatals when the fee payer's account does not exist\", async () => {\n        expect.assertions(1);\n        const [[secretKey, publicKeyBytes], { value: latestBlockhash }] = await Promise.all([\n            (async () => {\n                const keyPair = await crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']);\n                return [keyPair.privateKey, new Uint8Array(await crypto.subtle.exportKey('raw', keyPair.publicKey))];\n            })(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: publicKeyBytes,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .sendTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { encoding: 'base64', preflightCommitment: 'processed' },\n            )\n            .send();\n        await expect(resultPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE, {\n                accounts: null,\n                cause: new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__ACCOUNT_NOT_FOUND),\n                fee: null,\n                innerInstructions: null,\n                loadedAccountsDataSize: 0,\n                loadedAddresses: null,\n                logs: [],\n                postBalances: null,\n                postTokenBalances: null,\n                preBalances: null,\n                preTokenBalances: null,\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: 0n,\n            }),\n        );\n    });\n    it('fatals when the fee payer has insufficient funds to pay rent', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(MOCK_INSUFFICIENT_BALANCE_PRIVATE_KEY_BYTES),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_INSUFFICIENT_BALANCE_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .sendTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x1, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { encoding: 'base64', preflightCommitment: 'processed' },\n            )\n            .send();\n        await expect(resultPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE, {\n                accounts: null,\n                cause: new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE),\n                fee: null,\n                innerInstructions: null,\n                loadedAccountsDataSize: 0,\n                loadedAddresses: null,\n                logs: [],\n                postBalances: null,\n                postTokenBalances: null,\n                preBalances: null,\n                preTokenBalances: null,\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: 0n,\n            }),\n        );\n    });\n    it('fatals when the blockhash does not exist', async () => {\n        expect.assertions(1);\n        const secretKey = await getSecretKey(MOCK_PRIVATE_KEY_BYTES);\n        const message = getMockTransactionMessage({\n            blockhash: getBase58Decoder().decode(new Uint8Array(Array(32).fill(0))),\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .sendTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { encoding: 'base64', preflightCommitment: 'processed' },\n            )\n            .send();\n        await expect(resultPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE, {\n                accounts: null,\n                cause: new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND),\n                fee: null,\n                innerInstructions: null,\n                loadedAccountsDataSize: 0,\n                loadedAddresses: null,\n                logs: [],\n                postBalances: null,\n                postTokenBalances: null,\n                preBalances: null,\n                preTokenBalances: null,\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: 0n,\n            }),\n        );\n    });\n    describe('when called with a `minContextSlot` higher than the highest slot available', () => {\n        it('throws an error', async () => {\n            expect.assertions(3);\n            const [secretKey, { value: latestBlockhash }] = await Promise.all([\n                getSecretKey(MOCK_PRIVATE_KEY_BYTES),\n                rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n            ]);\n            const message = getMockTransactionMessage({\n                blockhash: latestBlockhash.blockhash,\n                feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n                memoString: `Hello from the Kit tests! [${performance.now()}]`,\n            });\n            const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n            const resultPromise = rpc\n                .sendTransaction(\n                    Buffer.from(\n                        new Uint8Array([\n                            0x01, // Length of signatures\n                            ...signature,\n                            ...message,\n                        ]),\n                    ).toString('base64') as Base64EncodedWireTransaction,\n                    {\n                        encoding: 'base64',\n                        minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                        preflightCommitment: 'processed',\n                    },\n                )\n                .send();\n            await Promise.all([\n                expect(resultPromise).rejects.toThrow(SolanaError),\n                expect(resultPromise).rejects.toHaveProperty(\n                    'context.__code',\n                    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n                ),\n                expect(resultPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__tests__/simulate-transaction-test.ts",
    "content": "import { Buffer } from 'node:buffer';\n\nimport type { Address } from '@solana/addresses';\nimport { fixEncoderSize, ReadonlyUint8Array } from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__JSON_RPC__INVALID_PARAMS,\n    SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n    SolanaError,\n} from '@solana/errors';\nimport { createPrivateKeyFromBytes } from '@solana/keys';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Base58EncodedBytes, Commitment } from '@solana/rpc-types';\nimport type { Base64EncodedWireTransaction } from '@solana/transactions';\n\nimport { GetLatestBlockhashApi, SimulateTransactionApi } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst CONTEXT_MATCHER = expect.objectContaining({\n    slot: expect.any(BigInt),\n});\n\nfunction getMockTransactionMessage({\n    blockhash,\n    feePayerAddressBytes,\n    memoString,\n    version = 0x80, // 0 + version mask\n}: {\n    blockhash: string;\n    feePayerAddressBytes: Uint8Array;\n    memoString: string;\n    version?: number;\n}) {\n    const blockhashBytes = fixEncoderSize(getBase58Encoder(), 32).encode(blockhash);\n    // prettier-ignore\n    return new Uint8Array([\n        /** VERSION HEADER */\n        version,\n\n        /** MESSAGE HEADER */\n        0x01, // numSignerAccounts\n        0x00, // numReadonlySignerAccount\n        0x01, // numReadonlyNonSignerAccounts\n\n        /** STATIC ADDRESSES */\n        0x02, // Number of static accounts\n        ...feePayerAddressBytes,\n        0x05, 0x4a, 0x53, 0x5a, 0x99, 0x29, 0x21, 0x06, 0x4d, 0x24, 0xe8, 0x71, 0x60, 0xda, 0x38, 0x7c, 0x7c, 0x35, 0xb5, 0xdd, 0xbc, 0x92, 0xbb, 0x81, 0xe4, 0x1f, 0xa8, 0x40, 0x41, 0x05, 0x44, 0x8d, // MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\n\n        /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n        ...blockhashBytes,\n\n        /* INSTRUCTIONS */\n        0x01, // Number of instructions\n\n        // First instruction\n        0x01, // Program address index\n        0x00, // Number of address indices\n        memoString.length, // Length of instruction data\n        ...new TextEncoder().encode(memoString),\n\n        /** ADDRESS TABLE LOOKUPS */\n        0x00, // Number of address table lookups\n    ]);\n}\n\nfunction getMockTransactionMessageWithAdditionalAccount({\n    blockhash,\n    feePayerAddressBytes,\n    accountAddressBytes,\n    memoString,\n    version = 0x80, // 0 + version mask\n}: {\n    accountAddressBytes: ReadonlyUint8Array;\n    blockhash: string;\n    feePayerAddressBytes: ReadonlyUint8Array;\n    memoString: string;\n    version?: number;\n}) {\n    const blockhashBytes = fixEncoderSize(getBase58Encoder(), 32).encode(blockhash);\n    // prettier-ignore\n    return new Uint8Array([\n        /** VERSION HEADER */\n        version,\n\n        /** MESSAGE HEADER */\n        0x01, // numSignerAccounts\n        0x00, // numReadonlySignerAccount\n        0x01, // numReadonlyNonSignerAccounts\n\n        /** STATIC ADDRESSES */\n        0x03, // Number of static accounts\n        ...feePayerAddressBytes,\n        0x05, 0x4a, 0x53, 0x5a, 0x99, 0x29, 0x21, 0x06, 0x4d, 0x24, 0xe8, 0x71, 0x60, 0xda, 0x38, 0x7c, 0x7c, 0x35, 0xb5, 0xdd, 0xbc, 0x92, 0xbb, 0x81, 0xe4, 0x1f, 0xa8, 0x40, 0x41, 0x05, 0x44, 0x8d, // MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\n        ...accountAddressBytes,\n\n        /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n        ...blockhashBytes,\n\n        /* INSTRUCTIONS */\n        0x01, // Number of instructions\n\n        // First instruction\n        0x01, // Program address index\n        0x00, // Number of address indices\n        memoString.length, // Length of instruction data\n        ...new TextEncoder().encode(memoString),\n\n        /** ADDRESS TABLE LOOKUPS */\n        0x00, // Number of address table lookups\n    ]);\n}\n\nconst MOCK_PRIVATE_KEY_BYTES = new Uint8Array([\n    16, 192, 67, 187, 170, 210, 152, 95, 180, 204, 123, 21, 81, 45, 171, 85, 188, 91, 164, 34, 8, 0, 244, 56, 209, 190,\n    255, 201, 212, 94, 45, 186,\n]);\n// See scripts/fixtures/send-transaction-fee-payer.json\nconst MOCK_PUBLIC_KEY_BYTES = // DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i\n    // prettier-ignore\n    new Uint8Array([\n        0xb8, 0xac, 0x70, 0x4f, 0xaf, 0xc7, 0xa5, 0xfc, 0x8c, 0x5d, 0x1f, 0x0a, 0xc8, 0xcf, 0xaa, 0xe0,\n        0x42, 0xfa, 0x3b, 0xb8, 0x25, 0xf0, 0xec, 0xfc, 0xe2, 0x27, 0x4d, 0x7d, 0xad, 0xad, 0x51, 0x2d,\n    ]);\n\nasync function getSecretKey() {\n    return await createPrivateKeyFromBytes(MOCK_PRIVATE_KEY_BYTES, /* extractable */ false);\n}\n\ndescribe('simulateTransaction', () => {\n    let rpc: Rpc<GetLatestBlockhashApi & SimulateTransactionApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` preflight commitment`, () => {\n            if (commitment === 'finalized') {\n                it.todo(\n                    'returns the transaction information (test broken; see https://discord.com/channels/428295358100013066/560496939779620864/1132048104728825926)',\n                );\n                return;\n            }\n            it('returns the transaction information', async () => {\n                expect.assertions(1);\n                const [secretKey, { value: latestBlockhash }] = await Promise.all([\n                    getSecretKey(),\n                    rpc.getLatestBlockhash({ commitment }).send(),\n                ]);\n                const message = getMockTransactionMessage({\n                    blockhash: latestBlockhash.blockhash,\n                    feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n                    memoString: `Hello from the Kit tests! [${performance.now()}]`,\n                });\n                const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n                const resultPromise = rpc\n                    .simulateTransaction(\n                        Buffer.from(\n                            new Uint8Array([\n                                0x01, // Length of signatures\n                                ...signature,\n                                ...message,\n                            ]),\n                        ).toString('base64') as Base64EncodedWireTransaction,\n                        { commitment, encoding: 'base64' },\n                    )\n                    .send();\n\n                await expect(resultPromise).resolves.toStrictEqual({\n                    context: CONTEXT_MATCHER,\n                    value: expect.objectContaining({\n                        accounts: null,\n                        err: null,\n                        fee: expect.any(BigInt),\n                        innerInstructions: null,\n                        loadedAddresses: {\n                            readonly: expect.any(Array),\n                            writable: expect.any(Array),\n                        },\n                        logs: expect.any(Array),\n                        postBalances: expect.any(Array),\n                        postTokenBalances: expect.any(Array),\n                        preBalances: expect.any(Array),\n                        preTokenBalances: expect.any(Array),\n                        replacementBlockhash: null,\n                        returnData: null,\n                        unitsConsumed: expect.any(BigInt),\n                    }),\n                });\n            });\n        });\n    });\n\n    it('throws when called with a `minContextSlot` higher than the highest slot available', async () => {\n        expect.assertions(3);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    commitment: 'processed',\n                    encoding: 'base64',\n                    minContextSlot: 2n ** 63n - 1n, // u64:MAX; safe bet it'll be too high.\n                },\n            )\n            .send();\n        await Promise.all([\n            expect(resultPromise).rejects.toThrow(SolanaError),\n            expect(resultPromise).rejects.toHaveProperty(\n                'context.__code',\n                SOLANA_ERROR__JSON_RPC__SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED,\n            ),\n            expect(resultPromise).rejects.toHaveProperty('context.contextSlot', expect.any(BigInt)),\n        ]);\n    });\n\n    it('returns a SignatureFailure error when called with an invalid signature if `sigVerify` is true', async () => {\n        expect.assertions(1);\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: 'processed' }).send();\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(Array(64).fill(0));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    commitment: 'processed',\n                    encoding: 'base64',\n                    sigVerify: true,\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                err: 'SignatureFailure',\n            }),\n        });\n    });\n\n    it('does not throw when called with an invalid signature when `sigVerify` is false', async () => {\n        expect.assertions(1);\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: 'processed' }).send();\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(Array(64).fill(0));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    commitment: 'processed',\n                    encoding: 'base64',\n                    sigVerify: false,\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: null,\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('returns a BlockhashNotFound error when the blockhash does not exist when `replaceRecentBlockhash` is false', async () => {\n        expect.assertions(1);\n        const secretKey = await getSecretKey();\n        const message = getMockTransactionMessage({\n            blockhash: getBase58Decoder().decode(new Uint8Array(Array(32).fill(0))),\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    commitment: 'processed',\n                    encoding: 'base64',\n                    replaceRecentBlockhash: false,\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: null,\n                err: 'BlockhashNotFound',\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('replaces the invalid blockhash when `replaceRecentBlockhash` is true', async () => {\n        expect.assertions(1);\n        const secretKey = await getSecretKey();\n        const message = getMockTransactionMessage({\n            blockhash: getBase58Decoder().decode(new Uint8Array(Array(32).fill(0))),\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    commitment: 'processed',\n                    encoding: 'base64',\n                    replaceRecentBlockhash: true,\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: null,\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: {\n                    blockhash: expect.any(String),\n                    lastValidBlockHeight: expect.any(BigInt),\n                },\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('throws when called with a transaction having an unsupported version', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n            version: 0xfe, // Version 126\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { commitment: 'processed', encoding: 'base64' },\n            )\n            .send();\n        await expect(resultPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                __serverMessage:\n                    'failed to deserialize solana_transaction::versioned::VersionedTransaction: ' +\n                    'invalid value: integer `126`, expected a valid transaction message version',\n            }),\n        );\n    });\n\n    it('throws when called with a malformed transaction message', async () => {\n        expect.assertions(1);\n        const secretKey = await getSecretKey();\n        const message = new Uint8Array([4, 5, 6]);\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { commitment: 'processed', encoding: 'base64' },\n            )\n            .send();\n        await expect(resultPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__JSON_RPC__INVALID_PARAMS, {\n                __serverMessage:\n                    'failed to deserialize solana_transaction::versioned::VersionedTransaction: ' +\n                    'io error: failed to fill whole buffer',\n            }),\n        );\n    });\n\n    it('returns an AccountNotFound error when the fee payer is an unknown account', async () => {\n        expect.assertions(1);\n        const [[secretKey, publicKeyBytes], { value: latestBlockhash }] = await Promise.all([\n            (async () => {\n                const keyPair = await crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']);\n                return [keyPair.privateKey, new Uint8Array(await crypto.subtle.exportKey('raw', keyPair.publicKey))];\n            })(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: publicKeyBytes,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                { commitment: 'processed', encoding: 'base64' },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: null,\n                err: 'AccountNotFound',\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('returns account data for a transaction account with base64 encoding', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    accounts: {\n                        addresses: ['DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i' as Address],\n                        encoding: 'base64',\n                    },\n                    commitment: 'processed',\n                    encoding: 'base64',\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: [\n                    expect.objectContaining({\n                        data: ['', 'base64'],\n                    }),\n                ],\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('returns account data for a transaction account with base64+zstd encoding', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    accounts: {\n                        addresses: ['DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i' as Address],\n                        encoding: 'base64+zstd',\n                    },\n                    commitment: 'processed',\n                    encoding: 'base64',\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: [\n                    expect.objectContaining({\n                        data: [expect.any(String), 'base64+zstd'],\n                    }),\n                ],\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('returns account data for a transaction account with jsonParsed encoding', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessageWithAdditionalAccount({\n            accountAddressBytes: getBase58Encoder().encode('4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp'), // see scripts/fixtures/vote-account.json\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    accounts: {\n                        addresses: ['4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp' as Address],\n                        encoding: 'jsonParsed',\n                    },\n                    commitment: 'processed',\n                    encoding: 'base64',\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: [\n                    expect.objectContaining({\n                        data: expect.objectContaining({\n                            parsed: expect.objectContaining({\n                                info: expect.objectContaining({\n                                    authorizedVoters: expect.any(Array),\n                                    authorizedWithdrawer: expect.any(String),\n                                    commission: expect.any(Number),\n                                    epochCredits: expect.any(Array),\n                                    lastTimestamp: expect.any(Object),\n                                    nodePubkey: expect.any(String),\n                                    priorVoters: expect.any(Array),\n                                    rootSlot: expect.any(BigInt),\n                                    votes: expect.any(Array),\n                                }),\n                                type: 'vote',\n                            }),\n                            program: 'vote',\n                        }),\n                    }),\n                ],\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('returns account data for a transaction account with jsonParsed encoding (fallback to base64)', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    accounts: {\n                        addresses: ['DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i' as Address],\n                        encoding: 'jsonParsed',\n                    },\n                    commitment: 'processed',\n                    encoding: 'base64',\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: [\n                    expect.objectContaining({\n                        // falls back to base64\n                        data: ['', 'base64'],\n                    }),\n                ],\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('returns account data for a transaction account with base64 encoding when encoding is not specified', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    accounts: {\n                        addresses: ['DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i' as Address],\n                    },\n                    commitment: 'processed',\n                    encoding: 'base64',\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: [\n                    expect.objectContaining({\n                        data: ['', 'base64'],\n                    }),\n                ],\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('returns null array entries for accounts that are not part of the transaction', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const resultPromise = rpc\n            .simulateTransaction(\n                Buffer.from(\n                    new Uint8Array([\n                        0x01, // Length of signatures\n                        ...signature,\n                        ...message,\n                    ]),\n                ).toString('base64') as Base64EncodedWireTransaction,\n                {\n                    accounts: {\n                        addresses: [\n                            // Randomly generated\n                            'CsJGwBvZrmMheK7cgMXh7ZHmKLL5w76X7pmofUG3cUWB' as Address,\n                            'DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i' as Address,\n                        ],\n                        encoding: 'base64',\n                    },\n                    commitment: 'processed',\n                    encoding: 'base64',\n                },\n            )\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: [\n                    null,\n                    expect.objectContaining({\n                        data: ['', 'base64'],\n                    }),\n                ],\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n\n    it('returns transaction information for a base58 encoded transaction', async () => {\n        expect.assertions(1);\n        const [secretKey, { value: latestBlockhash }] = await Promise.all([\n            getSecretKey(),\n            rpc.getLatestBlockhash({ commitment: 'processed' }).send(),\n        ]);\n        const message = getMockTransactionMessage({\n            blockhash: latestBlockhash.blockhash,\n            feePayerAddressBytes: MOCK_PUBLIC_KEY_BYTES,\n            memoString: `Hello from the Kit tests! [${performance.now()}]`,\n        });\n        const signature = new Uint8Array(await crypto.subtle.sign('Ed25519', secretKey, message));\n        const base58WireTransaction = getBase58Decoder().decode(\n            Buffer.from(\n                new Uint8Array([\n                    0x01, // Length of signatures\n                    ...signature,\n                    ...message,\n                ]),\n            ),\n        );\n        const resultPromise = rpc\n            .simulateTransaction(base58WireTransaction as Base58EncodedBytes, {\n                commitment: 'processed',\n            })\n            .send();\n\n        await expect(resultPromise).resolves.toStrictEqual({\n            context: CONTEXT_MATCHER,\n            value: expect.objectContaining({\n                accounts: null,\n                err: null,\n                innerInstructions: null,\n                logs: expect.any(Array),\n                replacementBlockhash: null,\n                returnData: null,\n                unitsConsumed: expect.any(BigInt),\n            }),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__typetests__/get-block-production-typetest.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport type { GetBlockProductionApi } from '../getBlockProduction';\n\nconst rpc = null as unknown as Rpc<GetBlockProductionApi>;\nconst identity = 'Joe11111111111111111111111111111' as Address<'Joe11111111111111111111111111111'>;\n\nvoid (async () => {\n    // [DESCRIBE] getBlockProduction with no identity.\n    {\n        // Returns leader slot / blocks produced record, by validator.\n        const result = await rpc.getBlockProduction().send();\n        result.value.byIdentity satisfies Record<Address, [leaderSlots: bigint, blocksProduced: bigint]>;\n    }\n\n    // [DESCRIBE] getBlockProduction with an identity.\n    {\n        // Returns leader slot / blocks produced record, for exactly the validator specified.\n        const result = await rpc.getBlockProduction({ identity }).send();\n        result.value.byIdentity satisfies Record<typeof identity, [leaderSlots: bigint, blocksProduced: bigint]>;\n    }\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__typetests__/get-block-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Rpc } from '@solana/rpc-spec';\nimport type {\n    Base58EncodedBytes,\n    Base58EncodedDataResponse,\n    Base64EncodedDataResponse,\n    Blockhash,\n    Lamports,\n    Reward,\n    TokenBalance,\n    TransactionError,\n    TransactionStatus,\n} from '@solana/rpc-types';\nimport { TransactionVersion } from '@solana/transaction-messages';\n\nimport { GetBlockApi } from '../getBlock';\n\nfunction assertNotAProperty<T extends object, TPropName extends string>(\n    _: { [Prop in keyof T]: Prop extends TPropName ? never : T[Prop] },\n    _propName: TPropName,\n): void {}\n\nconst rpc = null as unknown as Rpc<GetBlockApi>;\n\nfunction assertBase(\n    response: {\n        blockHeight: bigint;\n        blockTime: bigint;\n        blockhash: string;\n        parentSlot: bigint;\n        previousBlockhash: string;\n    } & { [key: string]: unknown },\n) {\n    response.blockhash satisfies string;\n    response.blockHeight satisfies bigint;\n    response.blockTime satisfies bigint;\n    response.parentSlot satisfies bigint;\n    response.previousBlockhash satisfies string;\n}\n\nvoid (async () => {\n    // First overload\n    // Rewards set to `false`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                rewards: false,\n                transactionDetails: 'none',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            assertNotAProperty(response, 'rewards');\n        }\n    }\n\n    // First overload with configs\n    // Rewards set to `false`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'processed',\n                encoding: 'base64',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n                transactionDetails: 'none',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            assertNotAProperty(response, 'rewards');\n        }\n    }\n\n    // Second overload\n    // Rewards defaults to `true`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                transactionDetails: 'none',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Second overload with configs\n    // Rewards defaults to `true`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'base58',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'none',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Second overload\n    // Rewards set to `true`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                rewards: true,\n                transactionDetails: 'none',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Second overload with configs\n    // Rewards set to `true`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'base58',\n                maxSupportedTransactionVersion: 0,\n                rewards: true,\n                transactionDetails: 'none',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Third overload\n    // Rewards set to `false`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                rewards: false,\n                transactionDetails: 'signatures',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            assertNotAProperty(response, 'rewards');\n            response.signatures satisfies readonly Base58EncodedBytes[];\n        }\n    }\n\n    // Third overload with configs\n    // Rewards set to `false`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'json',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n                transactionDetails: 'signatures',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            assertNotAProperty(response, 'rewards');\n            response.signatures satisfies readonly Base58EncodedBytes[];\n        }\n    }\n\n    // Fourth overload\n    // Rewards defaults to `true`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                transactionDetails: 'signatures',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            response.signatures satisfies readonly Base58EncodedBytes[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Fourth overload with configs\n    // Rewards defaults to `true`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'signatures',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            response.signatures satisfies readonly Base58EncodedBytes[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Fourth overload\n    // Rewards set to `true`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                rewards: true,\n                transactionDetails: 'signatures',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            response.signatures satisfies readonly Base58EncodedBytes[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Fourth overload with configs\n    // Rewards set to `true`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n                maxSupportedTransactionVersion: 0,\n                rewards: true,\n                transactionDetails: 'signatures',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'transactions');\n            response.signatures satisfies readonly Base58EncodedBytes[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    type ExpectedMetaForAccountsBase = {\n        err: TransactionError | null;\n        fee: Lamports;\n        postBalances: readonly Lamports[];\n        postTokenBalances?: readonly TokenBalance[];\n        preBalances: readonly Lamports[];\n        preTokenBalances?: readonly TokenBalance[];\n        status: TransactionStatus;\n    };\n\n    type ExpectedTransactionForAccountsBaseLegacy = {\n        meta: ExpectedMetaForAccountsBase | null;\n        transaction: {\n            accountKeys: readonly Readonly<{\n                pubkey: string;\n                signer: boolean;\n                source: 'transaction';\n                writable: boolean;\n            }>[];\n            signatures: readonly Base58EncodedBytes[];\n        };\n    };\n\n    type ExpectedTransactionForAccountsBaseVersioned = {\n        meta: ExpectedMetaForAccountsBase | null;\n        transaction: {\n            accountKeys: readonly Readonly<{\n                pubkey: string;\n                signer: boolean;\n                source: 'lookupTable' | 'transaction';\n                writable: boolean;\n            }>[];\n            signatures: readonly Base58EncodedBytes[];\n        };\n        version: TransactionVersion;\n    };\n\n    // Fifth overload\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseVersioned[];\n        }\n    }\n\n    // Fifth overload with configs\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'base64',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseVersioned[];\n        }\n    }\n\n    // Sixth overload\n    // Rewards set to `false`\n    // Max supported transaction version defaults to `legacy`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                rewards: false,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies Array<\n                ExpectedTransactionForAccountsBaseLegacy & {\n                    version: 'legacy';\n                }\n            >;\n        }\n    }\n\n    // Sixth overload with configs\n    // Rewards set to `false`\n    // Max supported transaction version defaults to `legacy`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'base64',\n                rewards: false,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies Array<\n                ExpectedTransactionForAccountsBaseLegacy & {\n                    version: 'legacy';\n                }\n            >;\n        }\n    }\n\n    // Seventh overload\n    // Rewards defaults to `true`\n    // Max supported transaction version set to 0\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseVersioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Seventh overload with configs\n    // Rewards defaults to `true`\n    // Max supported transaction version set to 0\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'base64',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseVersioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Seventh overload\n    // Rewards set to `true`\n    // Max supported transaction version set to 0\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                maxSupportedTransactionVersion: 0,\n                rewards: true,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseVersioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Seventh overload with configs\n    // Rewards set to `true`\n    // Max supported transaction version set to 0\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                commitment: 'confirmed',\n                encoding: 'base64',\n                maxSupportedTransactionVersion: 0,\n                rewards: true,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseVersioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Eighth overload\n    // Rewards defaults to `true`\n    // Max supported transaction version defaults to `legacy`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForAccountsBaseVersioned & {\n                version: 'legacy';\n            })[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Eighth overload\n    // Rewards set to `true`\n    // Max supported transaction version defaults to `legacy`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                rewards: true,\n                transactionDetails: 'accounts',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForAccountsBaseLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForAccountsBaseVersioned & {\n                version: 'legacy';\n            })[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    type ExpectedMetaForFullBase58 = {\n        computeUnitsConsumed?: bigint;\n        err: TransactionError | null;\n        fee: Lamports;\n        innerInstructions: readonly Readonly<{\n            index: number;\n            instructions: readonly Readonly<{\n                accounts: readonly number[];\n                data: Base58EncodedBytes;\n                programIdIndex: number;\n                stackHeight?: number;\n            }>[];\n        }>[];\n        logMessages: readonly string[] | null;\n        postBalances: readonly Lamports[];\n        postTokenBalances?: readonly TokenBalance[];\n        preBalances: readonly Lamports[];\n        preTokenBalances?: readonly TokenBalance[];\n        returnData?: Readonly<{\n            data: Base64EncodedDataResponse;\n            programId: Address;\n        }>;\n        rewards: readonly Reward[] | null;\n        status: TransactionStatus;\n    };\n\n    type ExpectedTransactionForFullBase58Legacy = {\n        meta: ExpectedMetaForFullBase58 | null;\n        transaction: Base58EncodedDataResponse;\n    };\n\n    type ExpectedTransactionForFullBase58Versioned = {\n        meta:\n            | (ExpectedMetaForFullBase58 &\n                  Readonly<{\n                      loadedAddresses: {\n                          readonly: readonly Address[];\n                          writable: readonly Address[];\n                      };\n                  }>)\n            | null;\n        transaction: Base58EncodedDataResponse;\n        version: TransactionVersion;\n    };\n\n    // Ninth overload\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    // Encoding set to `base58`\n    // Transaction details default to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base58',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullBase58Versioned[];\n        }\n    }\n\n    // Ninth overload\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    // Encoding set to `base58`\n    // Transaction details set to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base58',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n                transactionDetails: 'full',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullBase58Versioned[];\n        }\n    }\n\n    // Tenth overload\n    // Rewards set to `false`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `base58`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base58',\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullBase58Legacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullBase58Legacy & {\n                version: 'legacy';\n            })[];\n        }\n    }\n\n    // Tenth overload\n    // Rewards set to `false`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `base58`\n    // Transaction details set to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base58',\n                rewards: false,\n                transactionDetails: 'full',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullBase58Legacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullBase58Legacy & {\n                version: 'legacy';\n            })[];\n        }\n    }\n\n    // Eleventh overload\n    // Rewards defaults to `true`\n    // Max supported transaction version set to 0\n    // Encoding set to `base58`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base58',\n                maxSupportedTransactionVersion: 0,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullBase58Versioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Eleventh overload\n    // Rewards set to `true`\n    // Max supported transaction version set to 0\n    // Encoding set to `base58`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base58',\n                maxSupportedTransactionVersion: 0,\n                rewards: true,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullBase58Versioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Twelfth overload\n    // Rewards defaults to `true`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `base58`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base58',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullBase58Legacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullBase58Legacy & {\n                version: 'legacy';\n            })[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Twelfth overload\n    // Rewards set to `true`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `base58`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base58',\n                rewards: true,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullBase58Legacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullBase58Legacy & {\n                version: 'legacy';\n            })[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    type ExpectedMetaForFullBase64 = {\n        computeUnitsConsumed?: bigint;\n        err: TransactionError | null;\n        fee: Lamports;\n        innerInstructions: readonly Readonly<{\n            index: number;\n            instructions: readonly Readonly<{\n                accounts: readonly number[];\n                data: Base58EncodedBytes;\n                programIdIndex: number;\n                stackHeight?: number;\n            }>[];\n        }>[];\n        logMessages: readonly string[] | null;\n        postBalances: readonly Lamports[];\n        postTokenBalances?: readonly TokenBalance[];\n        preBalances: readonly Lamports[];\n        preTokenBalances?: readonly TokenBalance[];\n        returnData?: Readonly<{\n            data: Base64EncodedDataResponse;\n            programId: Address;\n        }>;\n        rewards: readonly Reward[] | null;\n        status: TransactionStatus;\n    };\n\n    type ExpectedTransactionForFullBase64Legacy = {\n        meta: ExpectedMetaForFullBase64 | null;\n        transaction: Base64EncodedDataResponse;\n    };\n\n    type ExpectedTransactionForFullBase64Versioned = {\n        meta:\n            | (ExpectedMetaForFullBase64 &\n                  Readonly<{\n                      loadedAddresses: {\n                          readonly: readonly Address[];\n                          writable: readonly Address[];\n                      };\n                  }>)\n            | null;\n        transaction: Base64EncodedDataResponse;\n        version: TransactionVersion;\n    };\n\n    // Thirteenth overload\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    // Encoding set to `base64`\n    // Transaction details default to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base64',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullBase64Versioned[];\n        }\n    }\n\n    // Thirteenth overload\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    // Encoding set to `base64`\n    // Transaction details set to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base64',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n                transactionDetails: 'full',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullBase64Versioned[];\n        }\n    }\n\n    // Fourteenth overload\n    // Rewards set to `false`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `base64`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base64',\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullBase64Legacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullBase64Legacy & {\n                version: 'legacy';\n            })[];\n        }\n    }\n\n    // Fourteenth overload\n    // Rewards set to `false`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `base64`\n    // Transaction details set to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base64',\n                rewards: false,\n                transactionDetails: 'full',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullBase64Legacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullBase64Legacy & {\n                version: 'legacy';\n            })[];\n        }\n    }\n\n    // Fifteenth overload\n    // Rewards defaults to `true`\n    // Max supported transaction version set to 0\n    // Encoding set to `base64`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base64',\n                maxSupportedTransactionVersion: 0,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullBase64Versioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Sixteenth overload\n    // Rewards defaults to `true`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `base64`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'base64',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullBase64Legacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullBase64Legacy & {\n                version: 'legacy';\n            })[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    type ExpectedParsedTransactionInstruction = Readonly<{\n        parsed: {\n            info?: object;\n            type: string;\n        };\n        program: string;\n        programId: Address;\n    }>;\n\n    type ExpectedPartiallyDecodedTransactionInstruction = Readonly<{\n        accounts: readonly Address[];\n        data: Base58EncodedBytes;\n        programId: Address;\n    }>;\n\n    type ExpectedTransactionInstructionForFullJsonParsed =\n        | ExpectedParsedTransactionInstruction\n        | ExpectedPartiallyDecodedTransactionInstruction;\n\n    type ExpectedMetaForFullJsonParsedBase = {\n        computeUnitsConsumed?: bigint;\n        err: TransactionError | null;\n        fee: Lamports;\n        innerInstructions: readonly Readonly<{\n            index: number;\n            instructions: readonly ExpectedTransactionInstructionForFullJsonParsed[];\n        }>[];\n        logMessages: readonly string[] | null;\n        postBalances: readonly Lamports[];\n        postTokenBalances?: readonly TokenBalance[];\n        preBalances: readonly Lamports[];\n        preTokenBalances?: readonly TokenBalance[];\n        returnData?: Readonly<{\n            data: Base64EncodedDataResponse;\n            programId: Address;\n        }>;\n        rewards: readonly Reward[] | null;\n        status: TransactionStatus;\n    };\n\n    type ExpectedMetaForFullJsonParsedLoadedAddresses = Readonly<{\n        loadedAddresses: {\n            readonly: readonly Address[];\n            writable: readonly Address[];\n        };\n    }>;\n\n    type ExpectedTransactionForFullJsonParsedBase = {\n        message: {\n            header: {\n                numReadonlySignedAccounts: number;\n                numReadonlyUnsignedAccounts: number;\n                numRequiredSignatures: number;\n            };\n            instructions: readonly ExpectedTransactionInstructionForFullJsonParsed[];\n            recentBlockhash: Blockhash;\n        };\n        signatures: readonly Base58EncodedBytes[];\n    };\n\n    type ExpectedTransactionForFullJsonParsedLegacy = {\n        meta: ExpectedMetaForFullJsonParsedBase | null;\n        transaction: ExpectedTransactionForFullJsonParsedBase & {\n            message: Readonly<{\n                accountKeys: readonly Readonly<{\n                    pubkey: string;\n                    signer: boolean;\n                    source: 'transaction';\n                    writable: boolean;\n                }>[];\n            }>;\n        };\n    };\n\n    type ExpectedTransactionForFullJsonParsedVersioned = {\n        meta: (ExpectedMetaForFullJsonParsedBase & ExpectedMetaForFullJsonParsedLoadedAddresses) | null;\n        transaction: ExpectedTransactionForFullJsonParsedBase & {\n            message: Readonly<{\n                accountKeys: readonly Readonly<{\n                    pubkey: string;\n                    signer: boolean;\n                    source: 'lookupTable' | 'transaction';\n                    writable: boolean;\n                }>[];\n            }>;\n        };\n        version: TransactionVersion;\n    };\n\n    // Seventeenth overload\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    // Encoding set to `jsonParsed`\n    // Transaction details default to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'jsonParsed',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonParsedVersioned[];\n        }\n    }\n\n    // Eighteenth overload\n    // Rewards set to `false`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `jsonParsed`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'jsonParsed',\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonParsedLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullJsonParsedLegacy & {\n                version: 'legacy';\n            })[];\n        }\n    }\n\n    // Nineteenth overload\n    // Rewards defaults to `true`\n    // Max supported transaction version set to 0\n    // Encoding set to `jsonParsed`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'jsonParsed',\n                maxSupportedTransactionVersion: 0,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            void response.transactions[0].transaction;\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonParsedVersioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Twentieth overload\n    // Rewards defaults to `true`\n    // Max supported transaction defaults to `legacy`\n    // Encoding set to `jsonParsed`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'jsonParsed',\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonParsedLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullJsonParsedLegacy & {\n                version: 'legacy';\n            })[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    type ExpectedTransactionInstructionForFullJson = {\n        accounts: readonly number[];\n        data: Base58EncodedBytes;\n        programIdIndex: number;\n    };\n\n    type ExpectedMetaForFullJsonBase = {\n        computeUnitsConsumed?: bigint;\n        err: TransactionError | null;\n        fee: Lamports;\n        innerInstructions: readonly Readonly<{\n            index: number;\n            instructions: readonly ExpectedTransactionInstructionForFullJson[];\n        }>[];\n        logMessages: readonly string[] | null;\n        postBalances: readonly Lamports[];\n        postTokenBalances?: readonly TokenBalance[];\n        preBalances: readonly Lamports[];\n        preTokenBalances?: readonly TokenBalance[];\n        returnData?: Readonly<{\n            data: Base64EncodedDataResponse;\n            programId: Address;\n        }>;\n        rewards: readonly Reward[] | null;\n        status: TransactionStatus;\n    };\n\n    type ExpectedMetaForFullJsonLoadedAddresses = Readonly<{\n        loadedAddresses: {\n            readonly: readonly Address[];\n            writable: readonly Address[];\n        };\n    }>;\n\n    type ExpectedTransactionForFullJsonBase = {\n        message: {\n            accountKeys: readonly Address[];\n            header: {\n                numReadonlySignedAccounts: number;\n                numReadonlyUnsignedAccounts: number;\n                numRequiredSignatures: number;\n            };\n            instructions: readonly ExpectedTransactionInstructionForFullJson[];\n            recentBlockhash: Blockhash;\n        };\n        signatures: readonly Base58EncodedBytes[];\n    };\n\n    type ExpectedTransactionForFullJsonLegacy = {\n        meta: ExpectedMetaForFullJsonBase | null;\n        transaction: ExpectedTransactionForFullJsonBase;\n    };\n\n    type ExpectedTransactionForFullJsonVersioned = {\n        meta: (ExpectedMetaForFullJsonBase & ExpectedMetaForFullJsonLoadedAddresses) | null;\n        transaction: ExpectedTransactionForFullJsonBase;\n        version: TransactionVersion;\n    };\n\n    // Twenty-first overload\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    // Encoding defaults to `json`\n    // Transaction details default to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonVersioned[];\n        }\n    }\n\n    // Twenty-first overload\n    // Rewards set to `false`\n    // Max supported transaction version set to 0\n    // Encoding set to `json`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                encoding: 'json',\n                maxSupportedTransactionVersion: 0,\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonVersioned[];\n        }\n    }\n\n    // Twenty-second overload\n    // Rewards set to `false`\n    // Max supported transaction defaults to `legacy`\n    // Encoding defaults to `json`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                rewards: false,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            assertNotAProperty(response, 'rewards');\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullJsonLegacy & {\n                version: 'legacy';\n            })[];\n        }\n    }\n\n    // Twenty-third overload\n    // Rewards defaults to `true`\n    // Max supported transaction version set to 0\n    // Encoding defaults to `json`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc\n            .getBlock(0n, {\n                // No extra configs\n                maxSupportedTransactionVersion: 0,\n            })\n            .send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonVersioned[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Twenty-fourth overload\n    // Rewards defaults to `true`\n    // Max supported transaction defaults to `legacy`\n    // Encoding defaults to `json`\n    // Transaction details defaults to `full`\n    {\n        const response = await rpc.getBlock(0n).send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullJsonLegacy & {\n                version: 'legacy';\n            })[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n\n    // Twenty-fourth overload with configs\n    {\n        const response = await rpc.getBlock(0n, { commitment: 'confirmed' }).send();\n        if (response) {\n            assertBase(response);\n            response.transactions satisfies readonly ExpectedTransactionForFullJsonLegacy[];\n            // @ts-expect-error `version` should be undefined\n            response.transactions satisfies readonly (ExpectedTransactionForFullJsonLegacy & {\n                version: 'legacy';\n            })[];\n            response.rewards satisfies readonly Reward[];\n        }\n    }\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__typetests__/get-leader-schedule-typetest.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Slot } from '@solana/rpc-types';\n\nimport type { GetLeaderScheduleApi } from '../getLeaderSchedule';\n\nconst rpc = null as unknown as Rpc<GetLeaderScheduleApi>;\nconst slot = 0n as Slot;\nconst identity = 'Joe11111111111111111111111111111' as Address<'Joe11111111111111111111111111111'>;\n\nvoid (async () => {\n    {\n        const result = await rpc.getLeaderSchedule().send();\n        // Won't be null\n        result satisfies Record<Address, Slot[]>;\n    }\n\n    {\n        const result = await rpc.getLeaderSchedule(null).send();\n        // Won't be null\n        result satisfies Record<Address, Slot[]>;\n    }\n\n    {\n        const result = await rpc.getLeaderSchedule(slot).send();\n        // Can be null if the slot corresponds to an epoch that does not exist\n        result satisfies Record<Address, Slot[]> | null;\n    }\n\n    {\n        const result = await rpc.getLeaderSchedule(slot, { identity }).send();\n        // Can be null if the slot corresponds to an epoch that does not exist\n        result satisfies Readonly<{ [key: Address]: Slot[] | undefined }> | null;\n    }\n\n    {\n        const result = await rpc.getLeaderSchedule(null, { identity }).send();\n        // Won't be null\n        result satisfies Readonly<{ [key: Address]: Slot[] | undefined }>;\n    }\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__typetests__/get-supply-typetest.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport type { GetSupplyApi } from '../getSupply';\n\nconst rpc = null as unknown as Rpc<GetSupplyApi>;\n\nvoid (async () => {\n    {\n        const result = await rpc.getSupply({ excludeNonCirculatingAccountsList: true }).send();\n        result satisfies Readonly<{\n            value: Readonly<{\n                nonCirculatingAccounts: never[];\n            }>;\n        }>;\n    }\n\n    {\n        const result = await rpc.getSupply().send();\n        result satisfies Readonly<{\n            value: Readonly<{\n                nonCirculatingAccounts: Address[];\n            }>;\n        }>;\n        // @ts-expect-error should not be `never`\n        result satisfies Readonly<{\n            value: Readonly<{\n                nonCirculatingAccounts: never[];\n            }>;\n        }>;\n    }\n\n    {\n        const result = await rpc.getSupply({ excludeNonCirculatingAccountsList: false }).send();\n        result satisfies Readonly<{\n            value: Readonly<{\n                nonCirculatingAccounts: Address[];\n            }>;\n        }>;\n        // @ts-expect-error should not be `never`\n        result satisfies Readonly<{\n            value: Readonly<{\n                nonCirculatingAccounts: never[];\n            }>;\n        }>;\n    }\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__typetests__/get-token-accounts-by-delegate-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Rpc } from '@solana/rpc-spec';\n\nimport { GetTokenAccountsByDelegateApi } from '..';\n\nconst rpc = {} as unknown as Rpc<GetTokenAccountsByDelegateApi>;\n\nvoid (async () => {\n    const tokenAccountsByDelegate = await rpc\n        .getTokenAccountsByDelegate(\n            'delegate' as Address,\n            { programId: 'program' as Address },\n            { encoding: 'jsonParsed' },\n        )\n        .send();\n\n    const firstAccount = tokenAccountsByDelegate.value[0];\n    firstAccount.pubkey satisfies Address;\n    firstAccount.account.data.program satisfies Address;\n    firstAccount.account.data.parsed.type satisfies 'account';\n    firstAccount.account.data.parsed.info.mint satisfies Address;\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__typetests__/get-token-accounts-by-owner-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Rpc } from '@solana/rpc-spec';\n\nimport { GetTokenAccountsByOwnerApi } from '..';\n\nconst rpc = {} as unknown as Rpc<GetTokenAccountsByOwnerApi>;\n\nvoid (async () => {\n    const tokenAccountsByOwner = await rpc\n        .getTokenAccountsByOwner('owner' as Address, { programId: 'program' as Address }, { encoding: 'jsonParsed' })\n        .send();\n\n    const firstAccount = tokenAccountsByOwner.value[0];\n    firstAccount.pubkey satisfies Address;\n    firstAccount.account.data.program satisfies Address;\n    firstAccount.account.data.parsed.type satisfies 'account';\n    firstAccount.account.data.parsed.info.mint satisfies Address;\n});\n"
  },
  {
    "path": "packages/rpc-api/src/__typetests__/rpc-api-typetest.ts",
    "content": "import { SolanaRpcApi, SolanaRpcApiDevnet, SolanaRpcApiMainnet, SolanaRpcApiTestnet } from '..';\n\n'getAccountInfo' satisfies keyof SolanaRpcApi;\n// @ts-expect-error RPC API does not have this method\n'someMadeUpMethod' satisfies keyof SolanaRpcApi;\n\n// if we extend the RPC API with additional methods, we can access them on keyof\ntype TestRpcApi = SolanaRpcApi & {\n    someMadeUpMethod: () => void;\n};\n'someMadeUpMethod' satisfies keyof TestRpcApi;\n\n// request airdrop is available on test networks, but not mainnet\n'requestAirdrop' satisfies keyof SolanaRpcApiDevnet;\n'requestAirdrop' satisfies keyof SolanaRpcApiTestnet;\n'requestAirdrop' satisfies keyof SolanaRpcApi;\n// @ts-expect-error requestAirdrop is not available on mainnet\n'requestAirdrop' satisfies keyof SolanaRpcApiMainnet;\n"
  },
  {
    "path": "packages/rpc-api/src/__typetests__/simulate-transaction-typetest.ts",
    "content": "import type { PendingRpcRequest, Rpc } from '@solana/rpc-spec';\nimport {\n    TransactionForFullMetaInnerInstructionsParsed,\n    TransactionForFullMetaInnerInstructionsUnparsed,\n} from '@solana/rpc-types';\nimport { Base64EncodedWireTransaction, TransactionBlockhashLifetime } from '@solana/transactions';\n\nimport type { SimulateTransactionApi } from '../simulateTransaction';\n\nconst rpc = null as unknown as Rpc<SimulateTransactionApi>;\nconst base64Transaction = 'SomeTx11111111111111111111111111111' as Base64EncodedWireTransaction;\n\n// [DESCRIBE] The interaction between `sigVerify` and `replaceRecentBlockhash`.\n{\n    // It raises a type error if both are true\n    {\n        rpc.simulateTransaction(\n            base64Transaction,\n            // @ts-expect-error Can't both be true.\n            {\n                encoding: 'base64',\n                replaceRecentBlockhash: true,\n                sigVerify: true,\n            },\n        );\n    }\n    // It allows `replaceRecentBlockhash` to be true so long as `sigVerify` is not\n    {\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            replaceRecentBlockhash: true,\n            sigVerify: false,\n        });\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            replaceRecentBlockhash: true,\n            // `sigVerify` omitted\n        });\n    }\n    // It allows `sigVerify` to be true so long as `replaceRecentBlockhash` is not\n    {\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            replaceRecentBlockhash: false,\n            sigVerify: true,\n        });\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            // `replaceRecentBlockhash` omitted\n            sigVerify: true,\n        });\n    }\n}\n\n// [DESCRIBE] `innerInstructions`.\n{\n    // It materializes inner instructions in the response when `true`\n    {\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            innerInstructions: true,\n        }) satisfies PendingRpcRequest<{\n            value: TransactionForFullMetaInnerInstructionsParsed | TransactionForFullMetaInnerInstructionsUnparsed;\n        }>;\n    }\n    // It does not materialize inner instructions in the response when `false` or omitted\n    {\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            innerInstructions: false,\n            // @ts-expect-error `innerInstructions` should not be a property on the response\n        }) satisfies PendingRpcRequest<{ value: { innerInstructions: unknown } }>;\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            // @ts-expect-error `innerInstructions` should not be a property on the response\n        }) satisfies PendingRpcRequest<{ value: { innerInstructions: unknown } }>;\n    }\n}\n\n// [DESCRIBE] `replaceRecentBlockhash`.\n{\n    // It materializes a replacement blockhash in the response when `true`\n    {\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            replaceRecentBlockhash: true,\n        }) satisfies PendingRpcRequest<{ value: { replacementBlockhash: TransactionBlockhashLifetime } }>;\n    }\n    // It does not materialize a replacement blockhash in the response when `false` or omitted\n    {\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            replaceRecentBlockhash: false,\n            // @ts-expect-error `replacementBlockhash` should not be a property on the response\n        }) satisfies PendingRpcRequest<{ value: { replacementBlockhash: unknown } }>;\n        rpc.simulateTransaction(base64Transaction, {\n            encoding: 'base64',\n            // @ts-expect-error `replacementBlockhash` should not be a property on the response\n        }) satisfies PendingRpcRequest<{ value: { replacementBlockhash: unknown } }>;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-api/src/getAccountInfo.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithJsonData,\n    Commitment,\n    DataSlice,\n    Slot,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype GetAccountInfoApiResponse<T> = (AccountInfoBase & T) | null;\n\ntype GetAccountInfoApiCommonConfig = Readonly<{\n    /**\n     * Fetch the details of the account as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Determines how the account data should be encoded in the response.\n     *\n     * - `'base58'` returns a tuple whose first element is the data as a base58-encoded string. If\n     *   the account contains more than 129 bytes of data, an error will be raised.\n     * - `'base64'` returns a tuple whose first element is the data as a base64-encoded string.\n     * - `'base64+zstd'` returns a tuple whose first element is the\n     *   [ZStandard](https://facebook.github.io/zstd/)-compressed data as a base64-encoded string.\n     * - `'jsonParsed'` will cause the server to attempt to process the data using a parser specific\n     *   to the account's owning program. If successful, the parsed data will be returned in the\n     *   response as JSON. Otherwise, the raw account data will be returned in the response as a\n     *   tuple whose first element is a base64-encoded string.\n     */\n    encoding: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n}>;\n\ntype GetAccountInfoApiSliceableCommonConfig = Readonly<{\n    /**\n     * Define which slice of the account's data you want the RPC to return.\n     *\n     * Use this to save network bandwidth and encoding time when you do not need the entire buffer.\n     *\n     * Data slicing is only available for `\"base58\"`, `\"base64\"`, and `\"base64+zstd\"` encodings.\n     */\n    dataSlice?: DataSlice;\n}>;\n\nexport type GetAccountInfoApi = {\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, it will be returned in the response as a tuple whose first element\n     * is a base64-encoded string.\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config: GetAccountInfoApiCommonConfig &\n            GetAccountInfoApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ): SolanaRpcResponse<GetAccountInfoApiResponse<AccountInfoWithBase64EncodedData>>;\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config: GetAccountInfoApiCommonConfig &\n            GetAccountInfoApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n            }>,\n    ): SolanaRpcResponse<GetAccountInfoApiResponse<AccountInfoWithBase64EncodedZStdCompressedData>>;\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, the server will attempt to process it using a parser specific to the\n     * account's owning program. If successful, the parsed data will be returned in the response as\n     * JSON. Otherwise, the raw account data will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config: GetAccountInfoApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ): SolanaRpcResponse<GetAccountInfoApiResponse<AccountInfoWithJsonData>>;\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, it will be returned in the response as a tuple whose first element\n     * is a base58-encoded string. If the account contains more than 129 bytes of data, this method\n     * will raise an error.\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config: GetAccountInfoApiCommonConfig &\n            GetAccountInfoApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ): SolanaRpcResponse<GetAccountInfoApiResponse<AccountInfoWithBase58EncodedData>>;\n    /**\n     * Fetches information associated with the account at the given address.\n     *\n     * If the account has data, it will be returned in the response as a base58-encoded string. If\n     * the account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * {@label base58-legacy}\n     * @see https://solana.com/docs/rpc/http/getaccountinfo\n     */\n    getAccountInfo(\n        address: Address,\n        config?: Omit<GetAccountInfoApiCommonConfig, 'encoding'>,\n    ): SolanaRpcResponse<GetAccountInfoApiResponse<AccountInfoWithBase58Bytes>>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getBalance.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, Lamports, Slot, SolanaRpcResponse } from '@solana/rpc-types';\n\ntype GetBalanceApiResponse = SolanaRpcResponse<Lamports>;\n\nexport type GetBalanceApi = {\n    /**\n     * Fetches the Lamport balance of the account at the given address.\n     * @see https://solana.com/docs/rpc/http/getbalance\n     */\n    getBalance(\n        address: Address,\n        config?: Readonly<{\n            /**\n             * Fetch the balance of the account as of the highest slot that has reached this level\n             * of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): GetBalanceApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getBlock.ts",
    "content": "import type {\n    Base58EncodedBytes,\n    Blockhash,\n    Commitment,\n    Reward,\n    Slot,\n    TransactionForAccounts,\n    TransactionForFullBase58,\n    TransactionForFullBase64,\n    TransactionForFullJson,\n    TransactionForFullJsonParsed,\n    UnixTimestamp,\n} from '@solana/rpc-types';\nimport type { TransactionVersion } from '@solana/transaction-messages';\n\n// API response types\n\ntype GetBlockApiResponseBase = Readonly<{\n    /** The number of blocks beneath this block */\n    blockHeight: bigint;\n    /** Estimated production time, as Unix timestamp */\n    blockTime: UnixTimestamp;\n    /** the blockhash of this block */\n    blockhash: Blockhash;\n    /** The slot index of this block's parent */\n    parentSlot: Slot;\n    /** The blockhash of this block's parent */\n    previousBlockhash: Blockhash;\n}>;\n\ntype GetBlockApiResponseWithRewards = Readonly<{\n    /** Block-level rewards */\n    rewards: readonly Reward[];\n}>;\n\ntype GetBlockApiResponseWithSignatures = Readonly<{\n    /** List of signatures applied to transactions in this block */\n    signatures: readonly Base58EncodedBytes[];\n}>;\n\ntype GetBlockApiResponseWithTransactions<TTransaction> = Readonly<{\n    transactions: readonly TTransaction[];\n}>;\n\n// API parameter types\n\ntype GetBlockCommonConfig = Readonly<{\n    /**\n     * Fetch blocks from slots that have reached at least this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Omit<Commitment, 'processed'>;\n    /**\n     * Determines how the transaction property should be encoded in the response.\n     *\n     * - `'base58'` produces a tuple whose first element is the wire transaction as a base58-encoded\n     *   string.\n     * - `'base64'` produces a tuple whose first element is the wire transaction as a base64-encoded\n     *   string.\n     * - `'json'` produces an object with `message` and `signatures` properties. The `instructions`\n     *   property of the message is an array of instructions, each an object containing the indices\n     *   of the instruction's accounts, the instruction data, the index of the program address, and\n     *   optionally the stack height if it is an inner instruction.\n     * - `'jsonParsed'` produces an object with `message` and `signatures` properties. This property\n     *   will cause the server to attempt to process each instruction using a parser specific to its\n     *   program. If successful, the parsed instruction will be returned in the response as JSON.\n     *   Otherwise, each instruction will be returned according to the rules of `'json'` encoding.\n     *\n     * @defaultValue \"json\"\n     */\n    encoding?: GetBlockEncoding;\n    /**\n     * The newest transaction version that the caller wants to receive in the response. This\n     * argument has no effect unless the {@link GetBlockCommonConfig.transactionDetails | transactionDetails}\n     * argument is set to `'accounts'` or `'full'`.\n     *\n     * When not supplied, only legacy (unversioned) transactions will be returned, and no `version`\n     * property will be returned in the response.\n     *\n     * If a block contains any transaction at a version higher than this, the server will throw\n     * {@link SolanaErrorCode.SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION | SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION}.\n     */\n    maxSupportedTransactionVersion?: GetBlockMaxSupportedTransactionVersion;\n    /**\n     * Set this to `false` to omit block rewards from the response. These typically only\n     * materialize on the first block of an epoch.\n     * @defaultValue true\n     */\n    rewards?: boolean;\n    /**\n     * The level of transaction detail to include in the response.\n     *\n     * - `'accounts'` includes signatures, an annotated list of accounts, and some transaction\n     *   metadata.\n     * - `'full'` includes the entire transaction message and its signatures.\n     * - `'none'` excludes transaction details completely.\n     * - `'signatures'` includes transaction signatures only.\n     *\n     * @defaultValue \"full\"\n     */\n    transactionDetails?: GetBlockTransactionDetailsMode;\n}>;\n\ntype GetBlockEncoding = 'base58' | 'base64' | 'json' | 'jsonParsed';\ntype GetBlockTransactionDetailsMode = 'accounts' | 'full' | 'none' | 'signatures';\n\ntype GetBlockMaxSupportedTransactionVersion = Exclude<TransactionVersion, 'legacy'>;\n\nexport type GetBlockApi = {\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-none--rewards-none}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=none, rewards=false, encoding + maxSupportedTransactionVersion irrelevant\n        config: GetBlockCommonConfig &\n            Readonly<{\n                rewards: false;\n                transactionDetails: 'none';\n            }>,\n    ): GetBlockApiResponseBase | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-none--rewards-included}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=none, rewards=missing/true, encoding + maxSupportedTransactionVersion irrelevant\n        config: GetBlockCommonConfig &\n            Readonly<{\n                rewards?: true;\n                transactionDetails: 'none';\n            }>,\n    ): (GetBlockApiResponseBase & GetBlockApiResponseWithRewards) | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-signatures--rewards-none}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=signatures, rewards=false, encoding + maxSupportedTransactionVersion irrelevant\n        config: GetBlockCommonConfig &\n            Readonly<{\n                rewards: false;\n                transactionDetails: 'signatures';\n            }>,\n    ): (GetBlockApiResponseBase & GetBlockApiResponseWithSignatures) | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-signatures--rewards-included}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=signatures, rewards=missing/true, encoding + maxSupportedTransactionVersion irrelevant\n        config: GetBlockCommonConfig &\n            Readonly<{\n                rewards?: true;\n                transactionDetails: 'signatures';\n            }>,\n    ): (GetBlockApiResponseBase & GetBlockApiResponseWithRewards & GetBlockApiResponseWithSignatures) | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-accounts--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=accounts, rewards=false, maxSupportedTransactionVersion=0, encoding irrelevant\n        config: GetBlockCommonConfig &\n            Readonly<{\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                rewards: false;\n                transactionDetails: 'accounts';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithTransactions<TransactionForAccounts<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-accounts--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=accounts, rewards=false, maxSupportedTransactionVersion=missing, encoding irrelevant\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                rewards: false;\n                transactionDetails: 'accounts';\n            }>,\n    ): (GetBlockApiResponseBase & GetBlockApiResponseWithTransactions<TransactionForAccounts<void>>) | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-accounts--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=accounts, rewards=missing/true, maxSupportedTransactionVersion=0, encoding irrelevant\n        config: GetBlockCommonConfig &\n            Readonly<{\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                rewards?: true;\n                transactionDetails: 'accounts';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForAccounts<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-accounts--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=accounts, rewards=missing/true, maxSupportedTransactionVersion=missing, encoding irrelevant\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                rewards?: true;\n                transactionDetails: 'accounts';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForAccounts<void>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-base58--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=base58, rewards=false, maxSupportedTransactionVersion=0\n        config: GetBlockCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                rewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithTransactions<TransactionForFullBase58<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-base58--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=base58, rewards=false, maxSupportedTransactionVersion=missing\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                encoding: 'base58';\n                rewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): (GetBlockApiResponseBase & GetBlockApiResponseWithTransactions<TransactionForFullBase58<void>>) | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-base58--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=base58, rewards=missing/true, maxSupportedTransactionVersion=0\n        config: GetBlockCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                rewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForFullBase58<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-base58--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=base58, rewards=missing/true, maxSupportedTransactionVersion=missing\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                encoding: 'base58';\n                rewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForFullBase58<void>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-base64--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=base64, rewards=false, maxSupportedTransactionVersion=0\n        config: GetBlockCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                rewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithTransactions<TransactionForFullBase64<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-base64--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=base64, rewards=false, maxSupportedTransactionVersion=missing\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                encoding: 'base64';\n                rewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): (GetBlockApiResponseBase & GetBlockApiResponseWithTransactions<TransactionForFullBase64<void>>) | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-base64--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=base64, rewards=missing/true, maxSupportedTransactionVersion=0\n        config: GetBlockCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                rewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForFullBase64<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-base64--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=base64, rewards=missing/true, maxSupportedTransactionVersion=missing\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                encoding: 'base64';\n                rewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForFullBase64<void>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-parsed--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=jsonParsed, rewards=false, maxSupportedTransactionVersion=0\n        config: GetBlockCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                rewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithTransactions<TransactionForFullJsonParsed<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-parsed--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=jsonParsed, rewards=false, maxSupportedTransactionVersion=missing\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                encoding: 'jsonParsed';\n                rewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): (GetBlockApiResponseBase & GetBlockApiResponseWithTransactions<TransactionForFullJsonParsed<void>>) | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-parsed--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=jsonParsed, rewards=missing/true, maxSupportedTransactionVersion=0\n        config: GetBlockCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForFullJsonParsed<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-parsed--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=jsonParsed, rewards=missing/true, maxSupportedTransactionVersion=missing\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                encoding: 'jsonParsed';\n                rewards?: boolean;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForFullJsonParsed<void>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-json--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=json (default), rewards=false, maxSupportedTransactionVersion=0\n        config: GetBlockCommonConfig &\n            Readonly<{\n                encoding?: 'json';\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                rewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithTransactions<TransactionForFullJson<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-json--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=json (default), rewards=false, maxSupportedTransactionVersion=missing\n        config: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                encoding?: 'json';\n                rewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): (GetBlockApiResponseBase & GetBlockApiResponseWithTransactions<TransactionForFullJson<void>>) | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-json--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=json (default), rewards=missing/true, maxSupportedTransactionVersion=0\n        config: GetBlockCommonConfig &\n            Readonly<{\n                encoding?: 'json';\n                maxSupportedTransactionVersion: GetBlockMaxSupportedTransactionVersion;\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForFullJson<GetBlockMaxSupportedTransactionVersion>>)\n        | null;\n    /**\n     * Returns identity and transaction information about a confirmed block in the ledger\n     *\n     * {@label transactions-json--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/http/getblock\n     */\n    getBlock(\n        slot: Slot,\n        // transactionDetails=full (default), encoding=json (default), rewards=missing/true, maxSupportedTransactionVersion=missing\n        config?: Omit<GetBlockCommonConfig, 'maxSupportedTransactionVersion'> &\n            Readonly<{\n                encoding?: 'json';\n                transactionDetails?: 'full';\n            }>,\n    ):\n        | (GetBlockApiResponseBase &\n              GetBlockApiResponseWithRewards &\n              GetBlockApiResponseWithTransactions<TransactionForFullJson<void>>)\n        | null;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getBlockCommitment.ts",
    "content": "import type { Lamports, Slot } from '@solana/rpc-types';\n\ntype GetBlockCommitmentApiResponse = Readonly<{\n    /**\n     * An array that represents the amount of cluster stake, denominated in {@link Lamports}, that\n     * has voted on the block at each depth from `0` to `MAX_LOCKOUT_HISTORY`.\n     */\n    commitment: readonly Lamports[] | null;\n    /** The total active stake, in {@link Lamports}, of the current epoch. */\n    totalStake: Lamports;\n}>;\n\nexport type GetBlockCommitmentApi = {\n    /**\n     * Returns the amount of cluster stake in {@link Lamports} that has voted on a particular block,\n     * as well as the stake attributed to each vote account.\n     * @see https://solana.com/docs/rpc/http/getblockcommitment\n     */\n    getBlockCommitment(slot: Slot): GetBlockCommitmentApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getBlockHeight.ts",
    "content": "import type { Commitment, Slot } from '@solana/rpc-types';\n\ntype GetBlockHeightApiResponse = bigint;\n\nexport type GetBlockHeightApi = {\n    /**\n     * Returns the current block height of the node\n     * @see https://solana.com/docs/rpc/http/getblockheight\n     */\n    getBlockHeight(\n        config?: Readonly<{\n            /**\n             * Fetch the block height as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): GetBlockHeightApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getBlockProduction.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, Slot, SolanaRpcResponse } from '@solana/rpc-types';\n\ntype NumberOfLeaderSlots = bigint;\ntype NumberOfBlocksProduced = bigint;\n\ntype SlotRange = Readonly<{\n    /** First slot to return block production information for */\n    firstSlot: Slot;\n    /**\n     * Last slot to return block production information for.\n     * @defaultValue If not provided, defaults to the highest slot.\n     */\n    lastSlot?: Slot;\n}>;\n\ntype GetBlockProductionApiConfigBase = Readonly<{\n    /**\n     * Fetch the block production information as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Slot range to return block production for (inclusive).\n     * @defaultValue If not provided, fetches block production for the current epoch.\n     */\n    range?: SlotRange;\n}>;\n\ntype BlockProductionRecord = [\n    /** The number of leader slots the validator had, in the slot range given */\n    numLeaderSlots: NumberOfLeaderSlots,\n    /** The number of blocks that the validator produced, in the slot range given */\n    numBlocksProduced: NumberOfBlocksProduced,\n];\n\ntype BlockProductionWithSingleIdentity<TIdentity extends string> = Readonly<{\n    [TAddress in TIdentity]?: BlockProductionRecord;\n}>;\n\ntype BlockProductionWithAllIdentities = Record<Address, BlockProductionRecord>;\n\ntype GetBlockProductionApiResponse<T> = Readonly<{\n    /** Block production results, indexed by validator address. */\n    byIdentity: T;\n    /** The range of slots (inclusive) for which block production information was fetched */\n    range: SlotRange;\n}>;\n\nexport type GetBlockProductionApi = {\n    /**\n     * Returns a validator's leader slot count and the number of blocks it produced, in the given\n     * slot range\n     *\n     * {@label specific-validator}\n     * @see https://solana.com/docs/rpc/http/getblockproduction\n     */\n    getBlockProduction<TIdentity extends Address>(\n        config: GetBlockProductionApiConfigBase &\n            Readonly<{\n                /**\n                 * When supplied, the response will only include results for the validator with this\n                 * address\n                 */\n                identity: TIdentity;\n            }>,\n    ): SolanaRpcResponse<GetBlockProductionApiResponse<BlockProductionWithSingleIdentity<TIdentity>>>;\n    /**\n     * Returns each validator's leader slot count and the number of blocks they produced, in the\n     * given slot range\n     *\n     * {@label all-validators}\n     * @see https://solana.com/docs/rpc/http/getblockproduction\n     */\n    getBlockProduction(\n        config?: GetBlockProductionApiConfigBase,\n    ): SolanaRpcResponse<GetBlockProductionApiResponse<BlockProductionWithAllIdentities>>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getBlockTime.ts",
    "content": "import type { Slot, UnixTimestamp } from '@solana/rpc-types';\n\ntype GetBlockTimeApiResponse = UnixTimestamp;\n\nexport type GetBlockTimeApi = {\n    /**\n     * Returns the estimated production time of a block.\n     *\n     * Each validator reports their UTC time to the ledger on a regular interval by intermittently\n     * adding a timestamp to a vote for a particular block. A requested block's time is calculated\n     * from the stake-weighted mean of the vote timestamps in a set of recent blocks recorded on the\n     * ledger.\n     *\n     * @returns Estimated production time, as Unix timestamp (seconds since the Unix epoch)\n     * @see https://solana.com/docs/rpc/http/getblocktime\n     */\n    getBlockTime(\n        /** Block number, identified by slot */\n        blockNumber: Slot,\n    ): GetBlockTimeApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getBlocks.ts",
    "content": "import type { Commitment, Slot } from '@solana/rpc-types';\n\ntype GetBlocksApiResponse = Slot[];\n\nexport type GetBlocksApi = {\n    /**\n     * Returns a list of confirmed blocks between two slots (inclusive).\n     *\n     * @see https://solana.com/docs/rpc/http/getblocks\n     */\n    getBlocks(\n        /** The first slot for which to return a confirmed block */\n        startSlotInclusive: Slot,\n        /**\n         * The last slot for which to return a confirmed block.\n         *\n         * Must be no more than 500,000 blocks higher than the start slot.\n         *\n         * @defaultValue If not provided, defaults to the latest confirmed slot.\n         */\n        endSlotInclusive?: Slot,\n        config?: Readonly<{\n            /**\n             * Include only blocks at slots that have reached at least this level of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Exclude<Commitment, 'processed'>;\n        }>,\n    ): GetBlocksApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getBlocksWithLimit.ts",
    "content": "import type { Commitment, Slot } from '@solana/rpc-types';\n\ntype GetBlocksWithLimitApiResponse = Slot[];\n\nexport type GetBlocksWithLimitApi = {\n    /**\n     * Returns a list of confirmed blocks starting at the given slot (inclusive). Returns up to the\n     * number of blocks specified by the limit.\n     *\n     * @see https://solana.com/docs/rpc/http/getblockswithlimit\n     */\n    getBlocksWithLimit(\n        /** The first slot for which to return a confirmed block */\n        startSlotInclusive: Slot,\n        /**\n         * The maximum number of blocks to return (between 0 and 500,000).\n         *\n         * Specifying 0 will result in an empty array being returned.\n         */\n        limit: number,\n        config?: Readonly<{\n            /**\n             * Include only blocks at slots that have reached at least this level of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Exclude<Commitment, 'processed'>;\n        }>,\n    ): GetBlocksWithLimitApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getClusterNodes.ts",
    "content": "import { Address } from '@solana/addresses';\n\ntype ClusterNode = Readonly<{\n    /**\n     * The unique identifier of the node's feature set.\n     *\n     * This value is computed by sorting all feature addresses' byte arrays lexicographically,\n     * hashing them, then taking the first 4 bytes of the result. This keeps the feature set value\n     * stable across versions until a new feature is introduced.\n     */\n    featureSet: number | null;\n    /** Gossip network address for the node (host:port) */\n    gossip: string | null;\n    /** Node public key, as base-58 encoded string */\n    pubkey: Address;\n    /** WebSocket PubSub network address for the node (host:port) */\n    pubsub: string | null;\n    /** JSON RPC network address for the node, or `null` if the JSON RPC service is not enabled */\n    rpc: string | null;\n    /** Server repair UDP network address for the node (host:port) */\n    serveRepair: string | null;\n    /** The shred version the node has been configured to use */\n    shredVersion: number | null;\n    /** TPU network address for the node (host:port) */\n    tpu: string | null;\n    /** Tpu UDP forwards network address for the node (host:port) */\n    tpuForwards: string | null;\n    /** Tpu QUIC forwards network address for the node (host:port) */\n    tpuForwardsQuic: string | null;\n    /** Tpu QUIC network address for the node (host:port) */\n    tpuQuic: string | null;\n    /** Tpu UDP vote network address for the node (host:port) */\n    tpuVote: string | null;\n    /** Tvu UDP network address for the node (host:port) */\n    tvu: string | null;\n    /** The software version of the node, or `null` if the version information is not available */\n    version: string | null;\n}>;\n\ntype GetClusterNodesApiResponse = readonly ClusterNode[];\n\nexport type GetClusterNodesApi = {\n    /**\n     * Returns information about all the nodes participating in the cluster.\n     *\n     * @see https://solana.com/docs/rpc/http/getclusternodes\n     */\n    getClusterNodes(): GetClusterNodesApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getEpochInfo.ts",
    "content": "import type { Commitment, Slot } from '@solana/rpc-types';\n\ntype GetEpochInfoApiResponse = Readonly<{\n    /** The current slot */\n    absoluteSlot: Slot;\n    /** The current block height */\n    blockHeight: bigint;\n    /** The current epoch */\n    epoch: bigint;\n    /** The current slot relative to the start of the current epoch */\n    slotIndex: bigint;\n    /** The number of slots in this epoch */\n    slotsInEpoch: bigint;\n    /** Total number of transactions processed without error since genesis */\n    transactionCount: bigint | null;\n}>;\n\nexport type GetEpochInfoApi = {\n    /**\n     * Returns information about the current epoch.\n     *\n     * @see https://solana.com/docs/rpc/http/getepochinfo\n     */\n    getEpochInfo(\n        config?: Readonly<{\n            /**\n             * Fetch epoch information as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): GetEpochInfoApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getEpochSchedule.ts",
    "content": "type GetEpochScheduleApiResponse = Readonly<{\n    /**\n     * First normal-length epoch after the warmup period,\n     * log2(slotsPerEpoch) - log2(MINIMUM_SLOTS_PER_EPOCH)\n     */\n    firstNormalEpoch: bigint;\n    /**\n     * The first slot after the warmup period, MINIMUM_SLOTS_PER_EPOCH * (2^(firstNormalEpoch) - 1)\n     */\n    firstNormalSlot: bigint;\n    /**\n     * The number of slots before beginning of an epoch to calculate a leader schedule for that\n     * epoch\n     */\n    leaderScheduleSlotOffset: bigint;\n    /** The maximum number of slots in each epoch */\n    slotsPerEpoch: bigint;\n    /** Whether epochs start short and grow */\n    warmup: boolean;\n}>;\n\nexport type GetEpochScheduleApi = {\n    /**\n     * Returns the epoch schedule information from this cluster's genesis config\n     *\n     * @see https://solana.com/docs/rpc/http/getepochschedule\n     */\n    getEpochSchedule(): GetEpochScheduleApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getFeeForMessage.ts",
    "content": "import type { Commitment, Lamports, Slot, SolanaRpcResponse } from '@solana/rpc-types';\nimport type { TransactionMessageBytesBase64 } from '@solana/transactions';\n\ntype GetFeeForMessageApiResponse = Lamports | null;\n\nexport type GetFeeForMessageApi = {\n    /**\n     * Returns the fee the network will charge for a particular message\n     *\n     * @returns The fee that the network will charge to process the message, in {@link Lamports}, as\n     * computed at the specified blockhash.\n     * @see https://solana.com/docs/rpc/http/getfeeformessage\n     */\n    getFeeForMessage(\n        /** A transaction message encoded as a base64 string */\n        message: TransactionMessageBytesBase64,\n        config?: Readonly<{\n            /**\n             * Fetch the fee information as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): SolanaRpcResponse<GetFeeForMessageApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getFirstAvailableBlock.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype GetFirstAvailableBlockApiResponse = Slot;\n\nexport type GetFirstAvailableBlockApi = {\n    /**\n     * Returns the slot of the lowest confirmed block available on the node.\n     *\n     * Different nodes may offer more or less historical block data, depending on their\n     * configuration. An appropriately configured node should be able to access all blocks, from\n     * genesis onward. When it is not, this method will tell you the slot of the lowest block\n     * available.\n     *\n     * @see https://solana.com/docs/rpc/http/getfirstavailableblock\n     */\n    getFirstAvailableBlock(): GetFirstAvailableBlockApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getGenesisHash.ts",
    "content": "import type { Base58EncodedBytes } from '@solana/rpc-types';\n\ntype GetGenesisHashApiResponse = Base58EncodedBytes;\n\nexport type GetGenesisHashApi = {\n    /**\n     * Returns the genesis hash.\n     *\n     * @returns A SHA-256 hash of the network's genesis config.\n     * @see https://solana.com/docs/rpc/http/getgenesishash\n     */\n    getGenesisHash(): GetGenesisHashApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getHealth.ts",
    "content": "type GetHealthApiResponse = 'ok';\n\nexport type GetHealthApi = {\n    /**\n     * Returns the health status of the node.\n     *\n     * A healthy node is one that is within _n_ slots of the latest cluster-confirmed slot, where\n     * _n_ is a node-configurable parameter with a\n     * [default of 128](https://github.com/anza-xyz/agave/blob/a080c4bb157f48b268b74cf5dd2f3de39db7dc5d/rpc-client-types/src/request.rs#L157).\n     *\n     * @returns The string \"ok\" if the node is healthy.\n     * @throws {SOLANA_ERROR__JSON_RPC__SERVER_ERROR_NODE_UNHEALTHY} if the node is unhealthy. The\n     * specifics of the error response are unstable and may change in the future.\n     * @see https://solana.com/docs/rpc/http/gethealth\n     */\n    getHealth(): GetHealthApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getHighestSnapshotSlot.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype GetHighestSnapshotSlotApiResponse = Readonly<{\n    /** The highest full snapshot slot */\n    full: Slot;\n    /**\n     * The highest incremental snapshot slot based on the slot indicated by\n     * {@link GetHighestSnapshotSlotApiResponse.full | full}\n     */\n    incremental: Slot | null;\n}>;\n\nexport type GetHighestSnapshotSlotApi = {\n    /**\n     * Returns the highest slot information that the node has snapshots for.\n     *\n     * This will find the highest full snapshot slot, and the highest incremental snapshot slot\n     * based on the full snapshot slot, if there is one.\n     *\n     * @see https://solana.com/docs/rpc/http/gethighestsnapshotslot\n     */\n    getHighestSnapshotSlot(): GetHighestSnapshotSlotApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getIdentity.ts",
    "content": "import type { Address } from '@solana/addresses';\n\ntype GetIdentityApiResponse = Readonly<{\n    identity: Address;\n}>;\n\nexport type GetIdentityApi = {\n    /**\n     * Returns the identity pubkey for the current node.\n     *\n     * @see https://solana.com/docs/rpc/http/getidentity\n     */\n    getIdentity(): GetIdentityApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getInflationGovernor.ts",
    "content": "import type { Commitment, F64UnsafeSeeDocumentation } from '@solana/rpc-types';\n\ntype GetInflationGovernorApiResponse = Readonly<{\n    /** Percentage of total inflation allocated to the foundation */\n    foundation: F64UnsafeSeeDocumentation;\n    /** Duration of foundation pool inflation in years */\n    foundationTerm: F64UnsafeSeeDocumentation;\n    /** The initial inflation percentage from time 0 */\n    initial: F64UnsafeSeeDocumentation;\n    /**\n     * Rate per year at which inflation is lowered. (Rate reduction is derived using the target slot\n     * time in genesis config)\n     */\n    taper: F64UnsafeSeeDocumentation;\n    /** Terminal inflation percentage */\n    terminal: F64UnsafeSeeDocumentation;\n}>;\n\nexport type GetInflationGovernorApi = {\n    /**\n     * Returns the current inflation governor.\n     *\n     * @see https://solana.com/docs/rpc/http/getinflationgovernor\n     */\n    getInflationGovernor(\n        config?: Readonly<{\n            /**\n             * Return the inflation governor as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n        }>,\n    ): GetInflationGovernorApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getInflationRate.ts",
    "content": "import type { F64UnsafeSeeDocumentation } from '@solana/rpc-types';\n\ntype GetInflationRateApiResponse = Readonly<{\n    /** Epoch for which these values are valid */\n    epoch: bigint;\n    /** Inflation allocated to the foundation */\n    foundation: F64UnsafeSeeDocumentation;\n    /** Total inflation */\n    total: F64UnsafeSeeDocumentation;\n    /** Inflation allocated to validators */\n    validator: F64UnsafeSeeDocumentation;\n}>;\n\nexport type GetInflationRateApi = {\n    /**\n     * Returns the specific inflation values for the current epoch.\n     *\n     * @see https://solana.com/docs/rpc/http/getinflationrate\n     */\n    getInflationRate(): GetInflationRateApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getInflationReward.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, Lamports, Slot } from '@solana/rpc-types';\n\ntype GetInflationRewardApiConfig = Readonly<{\n    /**\n     * Fetch the inflation reward details as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * An epoch for which the reward occurs.\n     *\n     * @defaultValue If omitted, the previous epoch will be used.\n     */\n    epoch?: bigint;\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n}>;\n\ntype InflationReward = Readonly<{\n    /** Reward amount in {@link Lamports} */\n    amount: Lamports;\n    /** Vote account commission when the reward was credited */\n    commission: number;\n    /** The slot in which the rewards are delivered */\n    effectiveSlot: Slot;\n    /** Epoch for which reward occurred */\n    epoch: bigint;\n    /** Post balance of the account in {@link Lamports} */\n    postBalance: Lamports;\n}>;\n\ntype GetInflationRewardApiResponse = readonly (InflationReward | null)[];\n\nexport type GetInflationRewardApi = {\n    /**\n     * Returns the inflation / staking reward for a list of addresses for an epoch.\n     *\n     * @see https://solana.com/docs/rpc/http/getinflationreward\n     */\n    getInflationReward(\n        addresses: readonly Address[],\n        config?: GetInflationRewardApiConfig,\n    ): GetInflationRewardApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getLargestAccounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, Lamports, SolanaRpcResponse } from '@solana/rpc-types';\n\ntype GetLargestAccountsResponseItem = Readonly<{\n    /** Base-58 encoded address of the account */\n    address: Address;\n    /** Number of {@link Lamports} in the account */\n    lamports: Lamports;\n}>;\n\ntype GetLargestAccountsApiResponse = readonly GetLargestAccountsResponseItem[];\n\nexport type GetLargestAccountsApi = {\n    /**\n     * Returns the 20 largest accounts, by {@link Lamports | Lamport} balance.\n     *\n     * Results may be cached up to two hours.\n     *\n     * @see https://solana.com/docs/rpc/http/getlargestaccounts\n     */\n    getLargestAccounts(\n        config?: Readonly<{\n            /**\n             * Fetch the largest accounts as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Filter results by account type.\n             *\n             * @defaultValue When not specified, all accounts will be considered regardless of their\n             * type.\n             */\n            filter?: 'circulating' | 'nonCirculating';\n        }>,\n    ): SolanaRpcResponse<GetLargestAccountsApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getLatestBlockhash.ts",
    "content": "import type { Blockhash, Commitment, Slot, SolanaRpcResponse } from '@solana/rpc-types';\n\ntype GetLatestBlockhashApiResponse = Readonly<{\n    /** A SHA-256 hash as base-58 encoded string */\n    blockhash: Blockhash;\n    /**\n     * Last block height at which the blockhash will be considered a valid lifetime specifier with\n     * which to land a transaction.\n     *\n     * @see {@link setTransactionMessageLifetimeUsingBlockhash}\n     */\n    lastValidBlockHeight: bigint;\n}>;\n\nexport type GetLatestBlockhashApi = {\n    /**\n     * Returns the blockhash of the latest block.\n     *\n     * @see https://solana.com/docs/rpc/http/getlatestblockhash\n     */\n    getLatestBlockhash(\n        config?: Readonly<{\n            /**\n             * Fetch the latest blockhash as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): SolanaRpcResponse<GetLatestBlockhashApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getLeaderSchedule.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, Slot } from '@solana/rpc-types';\n\ntype GetLeaderScheduleApiConfigBase = Readonly<{\n    /**\n     * Fetch the leader schedule as of the highest slot that has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n}>;\n\n// A dictionary of validator identities as base-58 encoded strings, and their corresponding leader\n// slot indices as values relative to the first slot in the requested epoch.\n//\n// @example\n// ```json\n// {\n//   \"4Qkev8aNZcqFNSRhQzwyLMFSsi94jHqE8WNVTJzTP99F\": [\n//     0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n//     21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\n//     39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,\n//     57, 58, 59, 60, 61, 62, 63\n//   ]\n// }\n// ```\ntype GetLeaderScheduleApiResponseWithAllIdentities = Record<Address, Slot[]>;\n\ntype GetLeaderScheduleApiResponseWithSingleIdentity<TIdentity extends string> = Readonly<{\n    [TAddress in TIdentity]?: Slot[];\n}>;\n\nexport type GetLeaderScheduleApi = {\n    /**\n     * Fetch the leader schedule of a particular validator.\n     *\n     * @param slot A slot that will be used to select the epoch for which to return the leader\n     * schedule.\n     *\n     * @returns A dictionary having a single key representing the specified validator identity, and\n     * its corresponding leader slot indices as values relative to the first slot in the requested\n     * epoch, or `null` if there is no epoch that corresponds to the given slot.\n     * @see https://solana.com/docs/rpc/http/getleaderschedule\n     */\n    getLeaderSchedule<TIdentity extends Address>(\n        slot: Slot,\n        config: GetLeaderScheduleApiConfigBase &\n            Readonly<{\n                /** Only return results for this validator identity (base58 encoded address) */\n                identity: Address;\n            }>,\n    ): GetLeaderScheduleApiResponseWithSingleIdentity<TIdentity> | null;\n    /**\n     * Fetch the leader schedule for all validators.\n     *\n     * @param slot A slot that will be used to select the epoch for which to return the leader\n     * schedule.\n     *\n     * @returns A dictionary of validator identities as base-58 encoded strings, and their\n     * corresponding leader slot indices as values relative to the first slot in the requested\n     * epoch, or `null` if there is no epoch that corresponds to the given slot.\n     * @see https://solana.com/docs/rpc/http/getleaderschedule\n     */\n    getLeaderSchedule(\n        slot: Slot,\n        config?: GetLeaderScheduleApiConfigBase,\n    ): GetLeaderScheduleApiResponseWithAllIdentities | null;\n    /**\n     * Fetch the leader schedule of a particular validator.\n     *\n     * @param slot When `null`, orders the leader schedule for the current epoch.\n     *\n     * @returns A dictionary having a single key representing the specified validator identity, and\n     * its corresponding leader slot indices as values relative to the first slot in the current\n     * epoch.\n     * @see https://solana.com/docs/rpc/http/getleaderschedule\n     */\n    getLeaderSchedule<TIdentity extends Address>(\n        slot: null,\n        config: GetLeaderScheduleApiConfigBase &\n            Readonly<{\n                /** Only return results for this validator identity (base58 encoded address) */\n                identity: Address;\n            }>,\n    ): GetLeaderScheduleApiResponseWithSingleIdentity<TIdentity>;\n    /**\n     * Fetch the leader schedule of all validators.\n     *\n     * @param slot When `null`, orders the leader schedule for the current epoch.\n     *\n     * @returns A dictionary of validator identities as base-58 encoded strings, and their\n     * corresponding leader slot indices as values relative to the first slot in the current\n     * epoch.\n     * @see https://solana.com/docs/rpc/http/getleaderschedule\n     */\n    getLeaderSchedule(\n        slot?: null,\n        config?: GetLeaderScheduleApiConfigBase,\n    ): GetLeaderScheduleApiResponseWithAllIdentities;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getMaxRetransmitSlot.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype GetMaxRetransmitSlotApiResponse = Slot;\n\nexport type GetMaxRetransmitSlotApi = {\n    /**\n     * Get the max slot seen from retransmit stage.\n     *\n     * @see https://solana.com/docs/rpc/http/getmaxretransmitslot\n     */\n    getMaxRetransmitSlot(): GetMaxRetransmitSlotApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getMaxShredInsertSlot.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype GetMaxShredInsertSlotApiResponse = Slot;\n\nexport type GetMaxShredInsertSlotApi = {\n    /**\n     * Get the max slot seen from after shred insert.\n     *\n     * @see https://solana.com/docs/rpc/http/getmaxshredinsertslot\n     */\n    getMaxShredInsertSlot(): GetMaxShredInsertSlotApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getMinimumBalanceForRentExemption.ts",
    "content": "import type { Commitment, Lamports } from '@solana/rpc-types';\n\ntype GetMinimumBalanceForRentExemptionApiResponse = Lamports;\n\nexport type GetMinimumBalanceForRentExemptionApi = {\n    /**\n     * Returns the minimum balance required to exempt an account from rent collection.\n     *\n     * @returns The minimum {@link Lamports | Lamport} balance required to grant an account of the\n     * specified size an exemption from rent collection.\n     * @see https://solana.com/docs/rpc/http/getminimumbalanceforrentexemption\n     */\n    getMinimumBalanceForRentExemption(\n        /**\n         * The number of bytes of account data for which an exemption from rent collection is being\n         * sought.\n         */\n        size: bigint,\n        config?: Readonly<{\n            /**\n             * Return the minimum balance as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n        }>,\n    ): GetMinimumBalanceForRentExemptionApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getMultipleAccounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithJsonData,\n    Commitment,\n    DataSlice,\n    Slot,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype GetMultipleAccountsApiResponseBase = AccountInfoBase | null;\n\ntype GetMultipleAccountsApiCommonConfig = Readonly<{\n    /**\n     * Fetch the details of the accounts as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Determines how the accounts' data should be encoded in the response.\n     *\n     * - `'base58'` returns a tuple whose first element is the data as a base58-encoded string. If\n     *   the account contains more than 129 bytes of data, an error will be raised.\n     * - `'base64'` returns a tuple whose first element is the data as a base64-encoded string.\n     * - `'base64+zstd'` returns a tuple whose first element is the\n     *   [ZStandard](https://facebook.github.io/zstd/)-compressed data as a base64-encoded string.\n     * - `'jsonParsed'` will cause the server to attempt to process the data using a parser specific\n     *   to each account's owning program. If successful, the parsed data will be returned in the\n     *   response as JSON. Otherwise, the raw account data will be returned in the response as a\n     *   tuple whose first element is a base64-encoded string.\n     */\n    encoding?: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n}>;\n\ntype GetMultipleAccountsApiSliceableCommonConfig = Readonly<{\n    /**\n     * Define which slice of the accounts' data you want the RPC to return.\n     *\n     * Use this to save network bandwidth and encoding time when you do not need the entire buffer.\n     *\n     * Data slicing is only available for `\"base58\"`, `\"base64\"`, and `\"base64+zstd\"` encodings.\n     */\n    dataSlice?: DataSlice;\n}>;\n\nexport type GetMultipleAccountsApi = {\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, it will be returned in the response as a tuple whose first element\n     * is a base64-encoded string.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: readonly Address[],\n        config: GetMultipleAccountsApiCommonConfig &\n            GetMultipleAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ): SolanaRpcResponse<(GetMultipleAccountsApiResponseBase & (AccountInfoWithBase64EncodedData | null))[]>;\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: readonly Address[],\n        config: GetMultipleAccountsApiCommonConfig &\n            GetMultipleAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n            }>,\n    ): SolanaRpcResponse<\n        (GetMultipleAccountsApiResponseBase & (AccountInfoWithBase64EncodedZStdCompressedData | null))[]\n    >;\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, the server will attempt to process it using a parser specific to\n     * each account's owning program. If successful, the parsed data will be returned in the\n     * response as JSON. Otherwise, the raw account data will be returned in the response as a tuple\n     * whose first element is a base64-encoded string.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: readonly Address[],\n        config: GetMultipleAccountsApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ): SolanaRpcResponse<(GetMultipleAccountsApiResponseBase & (AccountInfoWithJsonData | null))[]>;\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, it will be returned in the response as a tuple whose first element\n     * is a base58-encoded string. If any account contains more than 129 bytes of data, this method\n     * will raise an error.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: readonly Address[],\n        config: GetMultipleAccountsApiCommonConfig &\n            GetMultipleAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ): SolanaRpcResponse<(GetMultipleAccountsApiResponseBase & (AccountInfoWithBase58EncodedData | null))[]>;\n    /**\n     * Fetches information associated with the accounts at the given addresses.\n     *\n     * If the accounts have data, it will be returned in the response as a base58-encoded string. If\n     * any account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * @param addresses A maximum of 100 addresses for which to fetch account data\n     *\n     * {@label base58-legacy}\n     * @see https://solana.com/docs/rpc/http/getmultipleaccounts\n     */\n    getMultipleAccounts(\n        addresses: readonly Address[],\n        config?: GetMultipleAccountsApiCommonConfig,\n    ): SolanaRpcResponse<(GetMultipleAccountsApiResponseBase & (AccountInfoWithBase64EncodedData | null))[]>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getProgramAccounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithJsonData,\n    AccountInfoWithPubkey,\n    Commitment,\n    DataSlice,\n    GetProgramAccountsDatasizeFilter,\n    GetProgramAccountsMemcmpFilter,\n    Slot,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype GetProgramAccountsApiCommonConfig = Readonly<{\n    /**\n     * Fetch the details of the accounts as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Determines how the accounts' data should be encoded in the response.\n     *\n     * - `'base58'` returns a tuple whose first element is the data as a base58-encoded string. If\n     *   the account contains more than 129 bytes of data, an error will be raised.\n     * - `'base64'` returns a tuple whose first element is the data as a base64-encoded string.\n     * - `'base64+zstd'` returns a tuple whose first element is the\n     *   [ZStandard](https://facebook.github.io/zstd/)-compressed data as a base64-encoded string.\n     * - `'jsonParsed'` will cause the server to attempt to process the data using a parser specific\n     *   to the owning program. If successful, the parsed data will be returned in the response as\n     *   JSON. Otherwise, the raw account data will be returned in the response as a tuple whose\n     *   first element is a base64-encoded string.\n     */\n    encoding?: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    /**\n     * Limits results to those that match all of these filters.\n     *\n     * This is useful when your aim is to find program accounts whose purpose is uniquely determined\n     * by having a data buffer of a known size, or whose data contains a known series of bytes (eg.\n     * a discriminator).\n     *\n     * You can specify up to 4 filters.\n     *\n     * @defaultValue When omitted, no filters are applied.\n     */\n    filters?: readonly (GetProgramAccountsDatasizeFilter | GetProgramAccountsMemcmpFilter)[];\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n    /**\n     * Wraps the result in an {@link RpcResponse} when `true`\n     *\n     * @defaultValue false\n     */\n    withContext?: boolean;\n}>;\n\ntype GetProgramAccountsApiSliceableCommonConfig = Readonly<{\n    /**\n     * Define which slice of the accounts' data you want the RPC to return.\n     *\n     * Use this to save network bandwidth and encoding time when you do not need the entire buffer.\n     *\n     * Data slicing is only available for `\"base58\"`, `\"base64\"`, and `\"base64+zstd\"` encodings.\n     */\n    dataSlice?: DataSlice;\n}>;\n\nexport type GetProgramAccountsApi = {\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, it will be returned in the response as a tuple whose first element\n     * is a base64-encoded string.\n     *\n     * {@label base64-withcontext}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            GetProgramAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n                withContext: true;\n            }>,\n    ): SolanaRpcResponse<AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase64EncodedData>[]>;\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, it will be returned in the response as a tuple whose first element\n     * is a base64-encoded string.\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            GetProgramAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n                withContext?: boolean;\n            }>,\n    ): AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase64EncodedData>[];\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * {@label base64-zstd-compressed-withcontext}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            GetProgramAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n                withContext: true;\n            }>,\n    ): SolanaRpcResponse<AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData>[]>;\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            GetProgramAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n                withContext?: boolean;\n            }>,\n    ): AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData>[];\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, the server will attempt to process it using a parser specific to\n     * the owning program. If successful, the parsed data will be returned in the response as JSON.\n     * Otherwise, the raw account data will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * {@label parsed-withcontext}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n                withContext: true;\n            }>,\n    ): SolanaRpcResponse<AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithJsonData>[]>;\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, the server will attempt to process it using a parser specific to\n     * the owning program. If successful, the parsed data will be returned in the response as JSON.\n     * Otherwise, the raw account data will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n                withContext?: boolean;\n            }>,\n    ): AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithJsonData>[];\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, it will be returned in the response as a tuple whose first element\n     * is a base58-encoded string. If any account contains more than 129 bytes of data, this method\n     * will raise an error.\n     *\n     * {@label base58-withcontext}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            GetProgramAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n                withContext: true;\n            }>,\n    ): SolanaRpcResponse<AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase58EncodedData>[]>;\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, it will be returned in the response as a tuple whose first element\n     * is a base58-encoded string. If any account contains more than 129 bytes of data, this method\n     * will raise an error.\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            GetProgramAccountsApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n                withContext?: boolean;\n            }>,\n    ): AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase58EncodedData>[];\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, it will be returned in the response as a base58-encoded string. If\n     * any account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * {@label base58-legacy-withcontext}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config: GetProgramAccountsApiCommonConfig &\n            GetProgramAccountsApiSliceableCommonConfig &\n            Readonly<{\n                withContext: true;\n            }>,\n    ): SolanaRpcResponse<AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase58Bytes>[]>;\n    /**\n     * Fetches information associated with all accounts owned by the program at the given address.\n     *\n     * If the accounts have data, it will be returned in the response as a base58-encoded string. If\n     * any account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * {@label base58-legacy-withcontext}\n     * @see https://solana.com/docs/rpc/http/getprogramaccounts\n     */\n    getProgramAccounts(\n        program: Address,\n        config?: GetProgramAccountsApiCommonConfig &\n            GetProgramAccountsApiSliceableCommonConfig &\n            Readonly<{\n                withContext?: boolean;\n            }>,\n    ): AccountInfoWithPubkey<AccountInfoBase & AccountInfoWithBase58Bytes>[];\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getRecentPerformanceSamples.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype PerformanceSample = Readonly<{\n    /** Number of non-vote transactions in sample */\n    numNonVoteTransactions: bigint;\n    /** Number of slots in sample */\n    numSlots: bigint;\n    /** Number of transactions in sample */\n    numTransactions: bigint;\n    /** Number of seconds in a sample window */\n    samplePeriodSecs: number;\n    /** Slot in which sample was taken at */\n    slot: Slot;\n}>;\n\ntype GetRecentPerformanceSamplesApiResponse = readonly PerformanceSample[];\n\nexport type GetRecentPerformanceSamplesApi = {\n    /**\n     * Returns a list of recent performance samples, in reverse slot order.\n     *\n     * Performance samples are taken every 60 seconds and include the number of transactions and\n     * slots that occur in a given time window.\n     *\n     * @param limit Number of samples to return. Maximum of 720.\n     * @see https://solana.com/docs/rpc/http/getrecentperformancesamples\n     */\n    getRecentPerformanceSamples(limit?: number): GetRecentPerformanceSamplesApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getRecentPrioritizationFees.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { MicroLamports, Slot } from '@solana/rpc-types';\n\ntype RecentPrioritizationFee = Readonly<{\n    /**\n     * The smallest per-compute-unit fee paid by at least one successfully landed transaction,\n     * specified in increments of {@link MicroLamports} (0.000001 {@link Lamports}).\n     */\n    prioritizationFee: MicroLamports;\n    /** Slot in which the fee was observed */\n    slot: Slot;\n}>;\n\ntype GetRecentPrioritizationFeesApiResponse = readonly RecentPrioritizationFee[];\n\nexport type GetRecentPrioritizationFeesApi = {\n    /**\n     * Returns a list of the smallest prioritization fees paid in recent blocks.\n     *\n     * Currently, a node's prioritization-fee cache stores data from up to 150 blocks.\n     *\n     * @param addresses A maximum of 128 addresses. When supplied, the response will reflect the\n     * prioritization fee paid for transactions which take a write-lock on all of them.\n     *\n     * @see https://solana.com/docs/rpc/http/getrecentprioritizationfees\n     */\n    getRecentPrioritizationFees(addresses?: readonly Address[]): GetRecentPrioritizationFeesApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getSignatureStatuses.ts",
    "content": "import type { Signature } from '@solana/keys';\nimport type { Commitment, Slot, SolanaRpcResponse, TransactionError } from '@solana/rpc-types';\n\n/** @deprecated */\ntype TransactionStatusOk = Readonly<{\n    Ok: null;\n}>;\n\n/** @deprecated */\ntype TransactionStatusErr = Readonly<{\n    Err: TransactionError;\n}>;\n\ntype SignatureStatusResult = Readonly<{\n    /**\n     * The transaction's cluster confirmation status; either `processed`, `confirmed`, or\n     * `finalized`.\n     */\n    confirmationStatus: Commitment | null;\n    /**\n     * Number of blocks since signature confirmation or `null` if rooted as well as finalized by a\n     * supermajority of the cluster.\n     */\n    confirmations: bigint | null;\n    /** If the transaction failed, this property will contain the error */\n    err: TransactionError | null;\n    /** The slot the transaction was processed */\n    slot: Slot;\n    /** @deprecated */\n    status: TransactionStatusErr | TransactionStatusOk;\n}>;\n\ntype GetSignatureStatusesApiResponse = readonly (SignatureStatusResult | null)[];\n\nexport type GetSignatureStatusesApi = {\n    /**\n     * Returns the statuses of a list of signatures.\n     *\n     * Each signature uniquely identifies a transaction by virtue of being the first or only\n     * signature in its list of signatures.\n     *\n     * @see https://solana.com/docs/rpc/http/getsignaturestatuses\n     */\n    getSignatureStatuses(\n        /**\n         * An array of transaction signatures to confirm, as base-58 encoded strings (up to a\n         * maximum of 256)\n         */\n        signatures: readonly Signature[],\n        config?: Readonly<{\n            /**\n             * Determines whether the search for a transaction with a given signature will consider\n             * any more than what is available in the recent status cache that retains statuses for\n             * the active slots plus `MAX_RECENT_BLOCKHASHES` rooted slots. When `true` the search\n             * will proceed into local block storage then, if available, archival storage.\n             *\n             * @defaultValue `false`\n             */\n            searchTransactionHistory?: boolean;\n        }>,\n    ): SolanaRpcResponse<GetSignatureStatusesApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getSignaturesForAddress.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { Commitment, Slot, TransactionError, UnixTimestamp } from '@solana/rpc-types';\n\ntype GetSignaturesForAddressTransaction = Readonly<{\n    /** estimated production time of when transaction was processed. null if not available. */\n    blockTime: UnixTimestamp | null;\n    /** The transaction's cluster confirmation status */\n    confirmationStatus: Commitment | null;\n    /** Error if transaction failed, null if transaction succeeded. */\n    err: TransactionError | null;\n    /** Memo associated with the transaction, null if no memo is present */\n    memo: string | null;\n    /** transaction signature as base-58 encoded string */\n    signature: Signature;\n    /** The slot that contains the block with the transaction */\n    slot: Slot;\n}>;\n\ntype GetSignaturesForAddressApiResponse = readonly GetSignaturesForAddressTransaction[];\n\ntype AllowedCommitmentForGetSignaturesForAddress = Exclude<Commitment, 'processed'>;\n\ntype GetSignaturesForAddressConfig = Readonly<{\n    /**\n     * Start the search from before, but excluding, this signature.\n     *\n     * @defaultValue When omitted, the search starts from the top of the latest confirmed block.\n     */\n    before?: Signature;\n    /**\n     * Fetch the signatures as of the highest slot that has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: AllowedCommitmentForGetSignaturesForAddress;\n    /**\n     * Maximum transaction signatures to return (between 1 and 1,000).\n     *\n     * @defaultValue 1000\n     */\n    limit?: number;\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n    /**\n     * Search, back in time, until this transaction signature.\n     *\n     * @defaultValue When omitted, search will proceed until the limit (if supplied) or until 1,000\n     * signatures have been found.\n     */\n    until?: Signature;\n}>;\n\nexport type GetSignaturesForAddressApi = {\n    /**\n     * Returns signatures for confirmed transactions that load the given address.\n     *\n     * {@label before-signature}\n     * @returns Signatures in reverse chronological order starting from before, but excluding, the\n     * signature supplied.\n     * @see https://solana.com/docs/rpc/http/getsignaturesforaddress\n     */\n    getSignaturesForAddress(\n        address: Address,\n        config?: GetSignaturesForAddressConfig &\n            Readonly<{\n                before: Signature;\n            }>,\n    ): GetSignaturesForAddressApiResponse;\n    /**\n     * Returns signatures for confirmed transactions that load the given address.\n     *\n     * {@label all}\n     * @returns Signatures in reverse chronological order starting from the most recent confirmed\n     * block.\n     * @see https://solana.com/docs/rpc/http/getsignaturesforaddress\n     */\n    getSignaturesForAddress(\n        address: Address,\n        config?: GetSignaturesForAddressConfig,\n    ): GetSignaturesForAddressApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getSlot.ts",
    "content": "import type { Commitment, Slot } from '@solana/rpc-types';\n\ntype GetSlotApiResponse = Slot;\n\nexport type GetSlotApi = {\n    /**\n     * Returns the slot that has reached the given or default commitment level.\n     *\n     * @see https://solana.com/docs/rpc/http/getslot\n     */\n    getSlot(\n        config?: Readonly<{\n            /**\n             * Fetch the highest slot that has reached this level of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): GetSlotApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getSlotLeader.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, Slot } from '@solana/rpc-types';\n\ntype GetSlotLeaderApiResponse = Address;\n\nexport type GetSlotLeaderApi = {\n    /**\n     * Returns the current slot leader.\n     *\n     * @returns The address of the validator that has been granted the opportunity to create the\n     * block for the current slot.\n     * @see https://solana.com/docs/rpc/http/getslotleader\n     */\n    getSlotLeader(\n        config?: Readonly<{\n            /**\n             * Fetch the leader as of the highest slot that has reached this level of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): GetSlotLeaderApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getSlotLeaders.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Slot } from '@solana/rpc-types';\n\n/** array of Node identity public keys as base-58 encoded strings */\ntype GetSlotLeadersApiResponse = Address[];\n\nexport type GetSlotLeadersApi = {\n    /**\n     * Returns the slot leaders for a given slot range.\n     *\n     * @returns The addresses of the validators that have been granted the opportunity to create the\n     * blocks for each slot in the range provided\n     * @see https://solana.com/docs/rpc/http/getslotleaders\n     */\n    getSlotLeaders(\n        /** Start slot, as u64 integer */\n        startSlotInclusive: Slot,\n        /** Limit (between 1 and 5000) */\n        limit: number,\n    ): GetSlotLeadersApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getStakeMinimumDelegation.ts",
    "content": "import type { Commitment, Lamports, SolanaRpcResponse } from '@solana/rpc-types';\n\ntype GetStakeMinimumDelegationApiResponse = Lamports;\n\nexport type GetStakeMinimumDelegationApi = {\n    /**\n     * Returns the minimum amount of stake that can be delegated to a validator, in\n     * {@link Lamports}.\n     *\n     * @see https://solana.com/docs/rpc/http/getstakeminimumdelegation\n     */\n    getStakeMinimumDelegation(\n        config?: Readonly<{\n            /**\n             * Fetch the minimum delegation as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n        }>,\n    ): SolanaRpcResponse<GetStakeMinimumDelegationApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getSupply.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, Lamports, SolanaRpcResponse } from '@solana/rpc-types';\n\ntype GetSupplyConfig = Readonly<{\n    /**\n     * Fetch the supply as of the highest slot that has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    excludeNonCirculatingAccountsList?: boolean;\n}>;\n\ntype GetSupplyApiResponseBase = Readonly<{\n    /** Circulating supply in {@link Lamports} */\n    circulating: Lamports;\n    /** Non-circulating supply in {@link Lamports} */\n    nonCirculating: Lamports;\n    /** Total supply in {@link Lamports} */\n    total: Lamports;\n}>;\n\ntype GetSupplyApiResponseWithNonCirculatingAccounts = GetSupplyApiResponseBase &\n    Readonly<{\n        /** Addresses of non-circulating accounts */\n        nonCirculatingAccounts: Address[];\n    }>;\n\ntype GetSupplyApiResponseWithoutNonCirculatingAccounts = GetSupplyApiResponseBase &\n    Readonly<{\n        /**\n         * An empty array, since the `excludeNonCirculatingAccountsList` argument was not set to\n         * `true`.\n         */\n        nonCirculatingAccounts: never[];\n    }>;\n\nexport type GetSupplyApi = {\n    /**\n     * Returns information about the current supply, excluding the list of non-circulating accounts.\n     *\n     * {@label exclude-non-circulating-accounts}\n     * @see https://solana.com/docs/rpc/http/getsupply\n     */\n    getSupply(\n        config: GetSupplyConfig &\n            Readonly<{\n                excludeNonCirculatingAccountsList: true;\n            }>,\n    ): SolanaRpcResponse<GetSupplyApiResponseWithoutNonCirculatingAccounts>;\n    /**\n     * Returns information about the current supply.\n     *\n     * {@label default}\n     * @see https://solana.com/docs/rpc/http/getsupply\n     */\n    getSupply(\n        config?: GetSupplyConfig &\n            Readonly<{\n                excludeNonCirculatingAccountsList?: false;\n            }>,\n    ): SolanaRpcResponse<GetSupplyApiResponseWithNonCirculatingAccounts>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getTokenAccountBalance.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, SolanaRpcResponse, TokenAmount } from '@solana/rpc-types';\n\ntype GetTokenAccountBalanceApiResponse = TokenAmount;\n\nexport type GetTokenAccountBalanceApi = {\n    /**\n     * Returns the balance of an SPL Token account.\n     *\n     * @see https://solana.com/docs/rpc/http/gettokenaccountbalance\n     */\n    getTokenAccountBalance(\n        address: Address,\n        config?: Readonly<{\n            /**\n             * Fetch the balance as of the highest slot that has reached this level of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n        }>,\n    ): SolanaRpcResponse<GetTokenAccountBalanceApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getTokenAccountsByDelegate.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { JsonParsedTokenAccount } from '@solana/rpc-parsed-types';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithPubkey,\n    Commitment,\n    DataSlice,\n    Slot,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype TokenAccountInfoWithJsonData = Readonly<{\n    data: Readonly<{\n        parsed: {\n            info: JsonParsedTokenAccount;\n            type: 'account';\n        };\n        /** Name of the program that owns this account. */\n        program: Address;\n        space: bigint;\n    }>;\n}>;\n\ntype GetTokenAccountsByDelegateResponse<T> = readonly AccountInfoWithPubkey<AccountInfoBase & T>[];\n\ntype MintFilter = Readonly<{\n    /** This filter matches when the token account's mint is equal to the address supplied. */\n    mint: Address;\n}>;\n\ntype ProgramIdFilter = Readonly<{\n    /**\n     * This filter matches when the token account's token program address is equal to the address\n     * supplied.\n     */\n    programId: Address;\n}>;\n\ntype AccountsFilter = MintFilter | ProgramIdFilter;\n\ntype GetTokenAccountsByDelegateApiCommonConfig = Readonly<{\n    /**\n     * Fetch the details of the accounts as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Determines how the accounts' data should be encoded in the response.\n     *\n     * - `'base58'` returns a tuple whose first element is the data as a base58-encoded string. If\n     *   the account contains more than 129 bytes of data, an error will be raised.\n     * - `'base64'` returns a tuple whose first element is the data as a base64-encoded string.\n     * - `'base64+zstd'` returns a tuple whose first element is the\n     *   [ZStandard](https://facebook.github.io/zstd/)-compressed data as a base64-encoded string.\n     * - `'jsonParsed'` will cause the server to attempt to process the data using a parser specific\n     *   to each account's owning program. If successful, the parsed data will be returned in the\n     *   response as JSON. Otherwise, the raw account data will be returned in the response as a\n     *   tuple whose first element is a base64-encoded string.\n     */\n    encoding?: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n}>;\n\ntype GetTokenAccountsByDelegateApiSliceableCommonConfig = Readonly<{\n    /**\n     * Define which slice of the accounts' data you want the RPC to return.\n     *\n     * Use this to save network bandwidth and encoding time when you do not need the entire buffer.\n     *\n     * Data slicing is only available for `\"base58\"`, `\"base64\"`, and `\"base64+zstd\"` encodings.\n     */\n    dataSlice?: DataSlice;\n}>;\n\nexport type GetTokenAccountsByDelegateApi = {\n    /**\n     * Returns all SPL Token accounts for which transfer authority over some quantity of tokens has\n     * been delegated to the supplied address.\n     *\n     * The accounts' data will be returned in the response as a tuple whose first element is a\n     * base64-encoded string.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbydelegate\n     */\n    getTokenAccountsByDelegate(\n        delegate: Address,\n        filter: AccountsFilter,\n        config: GetTokenAccountsByDelegateApiCommonConfig &\n            GetTokenAccountsByDelegateApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ): SolanaRpcResponse<GetTokenAccountsByDelegateResponse<AccountInfoWithBase64EncodedData>>;\n    /**\n     * Returns all SPL Token accounts for which transfer authority over some quantity of tokens has\n     * been delegated to the supplied address.\n     *\n     * The accounts' data will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbydelegate\n     */\n    getTokenAccountsByDelegate(\n        delegate: Address,\n        filter: AccountsFilter,\n        config: GetTokenAccountsByDelegateApiCommonConfig &\n            GetTokenAccountsByDelegateApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n            }>,\n    ): SolanaRpcResponse<GetTokenAccountsByDelegateResponse<AccountInfoWithBase64EncodedZStdCompressedData>>;\n    /**\n     * Returns all SPL Token accounts for which transfer authority over some quantity of tokens has\n     * been delegated to the supplied address.\n     *\n     * The server will attempt to process the accounts' data using a parser specific to each\n     * account's owning token program.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbydelegate\n     */\n    getTokenAccountsByDelegate(\n        delegate: Address,\n        filter: AccountsFilter,\n        config: GetTokenAccountsByDelegateApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ): SolanaRpcResponse<GetTokenAccountsByDelegateResponse<TokenAccountInfoWithJsonData>>;\n    /**\n     * Returns all SPL Token accounts for which transfer authority over some quantity of tokens has\n     * been delegated to the supplied address.\n     *\n     * The accounts' data will be returned in the response as a tuple whose first element is a\n     * base58-encoded string. If any account contains more than 129 bytes of data, this method will\n     * raise an error.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbydelegate\n     */\n    getTokenAccountsByDelegate(\n        delegate: Address,\n        filter: AccountsFilter,\n        config: GetTokenAccountsByDelegateApiCommonConfig &\n            GetTokenAccountsByDelegateApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ): SolanaRpcResponse<GetTokenAccountsByDelegateResponse<AccountInfoWithBase58EncodedData>>;\n    /**\n     * Returns all SPL Token accounts for which transfer authority over some quantity of tokens has\n     * been delegated to the supplied address.\n     *\n     * The accounts' data will be returned in the response as a base58-encoded string. If any\n     * account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label base58-legacy}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbydelegate\n     */\n    getTokenAccountsByDelegate(\n        delegate: Address,\n        filter: AccountsFilter,\n        config?: GetTokenAccountsByDelegateApiCommonConfig & GetTokenAccountsByDelegateApiSliceableCommonConfig,\n    ): SolanaRpcResponse<GetTokenAccountsByDelegateResponse<AccountInfoWithBase58Bytes>>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getTokenAccountsByOwner.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { JsonParsedTokenAccount } from '@solana/rpc-parsed-types';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithPubkey,\n    Commitment,\n    DataSlice,\n    Slot,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype TokenAccountInfoWithJsonData = Readonly<{\n    data: Readonly<{\n        parsed: {\n            info: JsonParsedTokenAccount;\n            type: 'account';\n        };\n        /** Name of the program that owns this account. */\n        program: Address;\n        space: bigint;\n    }>;\n}>;\n\ntype GetTokenAccountsByOwnerResponse<T> = readonly AccountInfoWithPubkey<AccountInfoBase & T>[];\n\ntype MintFilter = Readonly<{\n    /** This filter matches when the token account's mint is equal to the address supplied. */\n    mint: Address;\n}>;\n\ntype ProgramIdFilter = Readonly<{\n    /**\n     * This filter matches when the token account's token program address is equal to the address\n     * supplied.\n     */\n    programId: Address;\n}>;\n\ntype AccountsFilter = MintFilter | ProgramIdFilter;\n\ntype GetTokenAccountsByOwnerApiCommonConfig = Readonly<{\n    /**\n     * Fetch the details of the accounts as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Determines how the accounts' data should be encoded in the response.\n     *\n     * - `'base58'` returns a tuple whose first element is the data as a base58-encoded string. If\n     *   the account contains more than 129 bytes of data, an error will be raised.\n     * - `'base64'` returns a tuple whose first element is the data as a base64-encoded string.\n     * - `'base64+zstd'` returns a tuple whose first element is the\n     *   [ZStandard](https://facebook.github.io/zstd/)-compressed data as a base64-encoded string.\n     * - `'jsonParsed'` will cause the server to attempt to process the data using a parser specific\n     *   to each account's owning program. If successful, the parsed data will be returned in the\n     *   response as JSON. Otherwise, the raw account data will be returned in the response as a\n     *   tuple whose first element is a base64-encoded string.\n     */\n    encoding?: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n}>;\n\ntype GetTokenAccountsByOwnerApiSliceableCommonConfig = Readonly<{\n    /**\n     * Define which slice of the accounts' data you want the RPC to return.\n     *\n     * Use this to save network bandwidth and encoding time when you do not need the entire buffer.\n     *\n     * Data slicing is only available for `\"base58\"`, `\"base64\"`, and `\"base64+zstd\"` encodings.\n     */\n    dataSlice?: DataSlice;\n}>;\nexport type GetTokenAccountsByOwnerApi = {\n    /**\n     * Returns all SPL Token accounts owned by the supplied address.\n     *\n     * The accounts' data will be returned in the response as a tuple whose first element is a\n     * base64-encoded string.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbyowner\n     */\n    getTokenAccountsByOwner(\n        owner: Address,\n        filter: AccountsFilter,\n        config: GetTokenAccountsByOwnerApiCommonConfig &\n            GetTokenAccountsByOwnerApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ): SolanaRpcResponse<GetTokenAccountsByOwnerResponse<AccountInfoWithBase64EncodedData>>;\n    /**\n     * Returns all SPL Token accounts owned by the supplied address.\n     *\n     * The accounts' data will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbyowner\n     */\n    getTokenAccountsByOwner(\n        owner: Address,\n        filter: AccountsFilter,\n        config: GetTokenAccountsByOwnerApiCommonConfig &\n            GetTokenAccountsByOwnerApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n            }>,\n    ): SolanaRpcResponse<GetTokenAccountsByOwnerResponse<AccountInfoWithBase64EncodedZStdCompressedData>>;\n    /**\n     * Returns all SPL Token accounts owned by the supplied address.\n     *\n     * The server will attempt to process the accounts' data using a parser specific to each\n     * account's owning token program.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbyowner\n     */\n    getTokenAccountsByOwner(\n        owner: Address,\n        filter: AccountsFilter,\n        config: GetTokenAccountsByOwnerApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ): SolanaRpcResponse<GetTokenAccountsByOwnerResponse<TokenAccountInfoWithJsonData>>;\n    /**\n     * Returns all SPL Token accounts owned by the supplied address.\n     *\n     * The accounts' data will be returned in the response as a tuple whose first element is a\n     * base58-encoded string. If any account contains more than 129 bytes of data, this method will\n     * raise an error.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbyowner\n     */\n    getTokenAccountsByOwner(\n        owner: Address,\n        filter: AccountsFilter,\n        config: GetTokenAccountsByOwnerApiCommonConfig &\n            GetTokenAccountsByOwnerApiSliceableCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ): SolanaRpcResponse<GetTokenAccountsByOwnerResponse<AccountInfoWithBase58EncodedData>>;\n    /**\n     * Returns all SPL Token accounts owned by the supplied address.\n     *\n     * The accounts' data will be returned in the response as a base58-encoded string. If any\n     * account contains more than 129 bytes of data, this method will raise an error.\n     *\n     * @param filter Limits the results to either token accounts associated with a particular mint,\n     * or token accounts owned by a certain token program.\n     *\n     * {@label base58-legacy}\n     * @see https://solana.com/docs/rpc/http/gettokenaccountsbyowner\n     */\n    getTokenAccountsByOwner(\n        owner: Address,\n        filter: AccountsFilter,\n        config?: GetTokenAccountsByOwnerApiCommonConfig & GetTokenAccountsByOwnerApiSliceableCommonConfig,\n    ): SolanaRpcResponse<GetTokenAccountsByOwnerResponse<AccountInfoWithBase58Bytes>>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getTokenLargestAccounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, SolanaRpcResponse, TokenAmount } from '@solana/rpc-types';\n\ntype TokenLargestAccount = Readonly<{ address: Address }> & TokenAmount;\n\ntype GetTokenLargestAccountsApiResponse = readonly TokenLargestAccount[];\n\nexport type GetTokenLargestAccountsApi = {\n    /**\n     * Returns the 20 largest token accounts whose mint is equal to the address supplied.\n     *\n     * @see https://solana.com/docs/rpc/http/gettokenlargestaccounts\n     */\n    getTokenLargestAccounts(\n        tokenMint: Address,\n        config?: Readonly<{\n            /**\n             * Fetch the largest accounts as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n        }>,\n    ): SolanaRpcResponse<GetTokenLargestAccountsApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getTokenSupply.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, SolanaRpcResponse, TokenAmount } from '@solana/rpc-types';\n\ntype GetTokenSupplyApiResponse = TokenAmount;\n\nexport type GetTokenSupplyApi = {\n    /**\n     * Returns the total supply of the token mint supplied.\n     *\n     * @see https://solana.com/docs/rpc/http/gettokensupply\n     */\n    getTokenSupply(\n        tokenMint: Address,\n        config?: Readonly<{\n            /**\n             * Fetch the supply as of the highest slot that has reached this level of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n        }>,\n    ): SolanaRpcResponse<GetTokenSupplyApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getTransaction.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type {\n    Base58EncodedBytes,\n    Base58EncodedDataResponse,\n    Base64EncodedDataResponse,\n    Blockhash,\n    Commitment,\n    Lamports,\n    Reward,\n    Slot,\n    TokenBalance,\n    TransactionError,\n    TransactionStatus,\n    UnixTimestamp,\n} from '@solana/rpc-types';\nimport type { TransactionVersion } from '@solana/transaction-messages';\n\ntype ReturnData = {\n    /** A tuple whose first element is the bytes of the return data as a base64-encoded string. */\n    data: Base64EncodedDataResponse;\n    /** The address of the program that generated the return data */\n    programId: Address;\n};\n\ntype TransactionMetaBase = Readonly<{\n    /** Number of compute units consumed by the transaction */\n    computeUnitsConsumed?: bigint;\n    /** Error if transaction failed, `null` if transaction succeeded. */\n    err: TransactionError | null;\n    /** The fee this transaction was charged, in {@link Lamports} */\n    fee: Lamports;\n    /**\n     * String log messages or `null` if log message recording was not enabled during this\n     * transaction\n     */\n    logMessages: readonly string[] | null;\n    /** Account balances after the transaction was processed */\n    postBalances: readonly Lamports[];\n    /**\n     * List of token balances from after the transaction was processed or omitted if token balance\n     * recording was not yet enabled during this transaction\n     */\n    postTokenBalances?: readonly TokenBalance[];\n    /** Account balances from before the transaction was processed */\n    preBalances: readonly Lamports[];\n    /**\n     * List of token balances from before the transaction was processed or omitted if token balance\n     * recording was not yet enabled during this transaction\n     */\n    preTokenBalances?: readonly TokenBalance[];\n    /** The most-recent return data generated by an instruction in the transaction */\n    returnData?: ReturnData;\n    /**\n     * Transaction-level rewards; currently only `\"Rent\"`, but other types may be added in the\n     * future\n     */\n    rewards: readonly Reward[] | null;\n    /** @deprecated */\n    status: TransactionStatus;\n}>;\n\ntype AddressTableLookup = Readonly<{\n    /** The address of the address lookup table account. */\n    accountKey: Address;\n    /** Indexes of accounts in a lookup table to load as read-only. */\n    readonlyIndexes: readonly number[];\n    /** Indexes of accounts in a lookup table to load as writable. */\n    writableIndexes: readonly number[];\n}>;\n\ntype TransactionBase = Readonly<{\n    message: {\n        /**\n         * For transactions whose lifetime is specified by a recent blockhash, this is that\n         * blockhash, and for transactions whose lifetime is specified by a durable nonce, this is\n         * the nonce value.\n         */\n        recentBlockhash: Blockhash;\n    };\n    /**\n     * An ordered list of signatures belonging to the accounts required to sign this transaction.\n     *\n     * Each signature is an Ed25519 signature of the transaction message using the private key\n     * associated with the account required to sign the transaction.\n     */\n    signatures: readonly Base58EncodedBytes[];\n}>;\n\ntype InstructionWithStackHeight = Readonly<{\n    /**\n     * A number indicating the height at which this instruction was called with respect to the\n     * bottom of the call stack denoted by `1` or `null`.\n     *\n     * For instance, an instruction explicitly declared in the transaction message will have a `1`\n     * or `null` height, the first instruction that it calls using a cross-program invocation (CPI)\n     * will have a height of 2, an instruction called by that instruction using a CPI will have a\n     * depth of 3, and so on.\n     */\n    stackHeight: number; // FIXME(https://github.com/anza-xyz/agave/issues/5732) Should be `1` instead of `null` at base of stack\n}>;\n\ntype InstructionWithData = Readonly<{\n    /** The input to the invoked program */\n    data: Base58EncodedBytes;\n}>;\n\ntype TransactionInstruction = InstructionWithData &\n    Partial<InstructionWithStackHeight> &\n    Readonly<{\n        /**\n         * An ordered list of indices that indicate which accounts in the transaction message's\n         * accounts list are loaded by this instruction.\n         */\n        accounts: readonly number[];\n        /**\n         * The index of the address in the transaction message's accounts list associated with the\n         * program to invoke.\n         */\n        programIdIndex: number;\n    }>;\n\ntype TransactionJson = Readonly<{\n    message: {\n        /** An ordered list of addresses belonging to the accounts loaded by this transaction */\n        accountKeys: readonly Address[];\n        header: {\n            /**\n             * The number of read-only accounts in the static accounts list that must sign this\n             * transaction.\n             *\n             * Subtracting this number from `numRequiredSignatures` yields the index of the first\n             * read-only signer account in the static accounts list.\n             */\n            numReadonlySignedAccounts: number;\n            /**\n             * The number of accounts in the static accounts list that are neither writable nor\n             * signers.\n             *\n             * Adding this number to `numRequiredSignatures` yields the index of the first read-only\n             * non-signer account in the static accounts list.\n             */\n            numReadonlyUnsignedAccounts: number;\n            /**\n             * The number of accounts in the static accounts list that must sign this transaction.\n             *\n             * Subtracting `numReadonlySignedAccounts` from this number yields the number of\n             * writable signer accounts in the static accounts list. Writable signer accounts always\n             * begin at index zero in the static accounts list.\n             *\n             * This number itself is the index of the first non-signer account in the static\n             * accounts list.\n             */\n            numRequiredSignatures: number;\n        };\n        instructions: readonly TransactionInstruction[];\n    };\n}> &\n    TransactionBase;\n\ntype PartiallyDecodedTransactionInstruction = InstructionWithData &\n    Partial<InstructionWithStackHeight> &\n    Readonly<{\n        /** An ordered list of addresses belonging to the accounts loaded by this instruction */\n        accounts: readonly Address[];\n        /** The address of the program to invoke */\n        programId: Address;\n    }>;\n\ntype ParsedTransactionInstruction = Partial<InstructionWithStackHeight> &\n    Readonly<{\n        /** The output of the program's instruction parser */\n        parsed: {\n            /** The instruction, as interpreted the program's instruction parser. */\n            info?: object;\n            /**\n             * A label that indicates the type of the instruction, as determined by the program's\n             * instruction parser.\n             */\n            type: string;\n        };\n        /** The name of the program. */\n        program: string;\n        /** The address of the program */\n        programId: Address;\n    }>;\n\ntype ParsedAccount = Readonly<{\n    /** The address of the account */\n    pubkey: Address;\n    /** Whether this account is required to sign the transaction that it's a part of */\n    signer: boolean;\n    /**\n     * Indicates whether the account was statically declared in the transaction message or loaded\n     * from an address lookup table.\n     */\n    source: 'lookupTable' | 'transaction';\n    /** Whether this account must be loaded with a write-lock */\n    writable: boolean;\n}>;\n\ntype TransactionJsonParsed = Readonly<{\n    message: {\n        /**\n         * An ordered list of parsed accounts belonging to the accounts loaded by this transaction\n         */\n        accountKeys: readonly ParsedAccount[];\n        instructions: readonly (ParsedTransactionInstruction | PartiallyDecodedTransactionInstruction)[];\n    };\n}> &\n    TransactionBase;\n\ntype GetTransactionCommonConfig<TMaxSupportedTransactionVersion> = Readonly<{\n    /**\n     * Fetch the transaction details as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Determines how the transaction should be encoded in the response.\n     *\n     * - `'base58'` returns a tuple whose first element is the bytes of the wire transaction as a\n     *   base58-encoded string.\n     * - `'base64'` returns a tuple whose first element is the bytes of the wire transaction as a\n     *   base64-encoded string.\n     * - `'json'` returns structured {@link TransactionJson}\n     * - `'jsonParsed'` returns structured {@link TransactionJson} which the server will attempt to\n     *   further process using account parsers and parsers specific to the transaction instructions'\n     *   owning program. Whenever an instruction parser is successful, instruction will consist of\n     *   parsed data as JSON. Otherwise, the instruction will materialize as a list of accounts, a\n     *   program address, and base64-encoded instruction data.\n     */\n    encoding: 'base58' | 'base64' | 'json' | 'jsonParsed';\n    /**\n     * The newest transaction version that the caller wants to receive in the response.\n     *\n     * When not supplied, only legacy (unversioned) transactions will be returned, and no `version`\n     * property will be returned in the response.\n     *\n     * If a transaction with the supplied signature is found with a version higher than this, the\n     * server will throw\n     * {@link SolanaErrorCode.SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION | SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION}.\n     */\n    maxSupportedTransactionVersion?: TMaxSupportedTransactionVersion;\n}>;\n\ntype GetTransactionApiResponseBase = Readonly<{\n    /**\n     * The estimated production time at which the transaction was processed. `null` if not\n     * available.\n     */\n    blockTime: UnixTimestamp | null;\n    /** The slot during which this transaction was processed */\n    slot: Slot;\n}>;\n\ntype TransactionMetaLoadedAddresses = Readonly<{\n    /** Addresses loaded from lookup tables */\n    loadedAddresses: {\n        /** Ordered list of base-58 encoded addresses for read-only accounts */\n        readonly: readonly Address[];\n        /** Ordered list of base-58 encoded addresses for writable accounts */\n        writable: readonly Address[];\n    };\n}>;\n\ntype InnerInstructions<TInstructionType> = Readonly<{\n    /** The index of the instruction in the transaction */\n    index: number;\n    /** The instructions */\n    instructions: readonly TInstructionType[];\n}>;\n\ntype TransactionMetaInnerInstructionsNotParsed = Readonly<{\n    /** A list of instructions called by programs via cross-program invocation (CPI) */\n    innerInstructions?: readonly InnerInstructions<TransactionInstruction>[] | null;\n}>;\n\ntype TransactionMetaInnerInstructionsParsed = Readonly<{\n    /** A list of instructions called by programs via cross-program invocation (CPI) */\n    innerInstructions?:\n        | readonly InnerInstructions<ParsedTransactionInstruction | PartiallyDecodedTransactionInstruction>[]\n        | null;\n}>;\n\ntype TransactionAddressTableLookups = Readonly<{\n    message: Readonly<{\n        /** A list of address tables and the accounts that this transaction loads from them */\n        addressTableLookups: readonly AddressTableLookup[];\n    }>;\n}>;\n\nexport type GetTransactionApi = {\n    /**\n     * Returns details of the confirmed transaction identified by the given signature.\n     *\n     * @param signature A 64 byte Ed25519 signature, encoded as a base-58 string, that uniquely\n     * identifies a transaction by virtue of being the first or only signature in its list of\n     * signatures.\n     *\n     * Materializes the transaction as structured {@link TransactionJson} which the server will\n     * attempt to further process using account parsers and parsers specific to the transaction\n     * instructions' owning program. Whenever an instruction parser is successful, instruction will\n     * consist of parsed data as JSON. Otherwise, the instruction will materialize as a list of\n     * accounts, a program address, and base64-encoded instruction data.\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/http/gettransaction\n     */\n    getTransaction<TMaxSupportedTransactionVersion extends TransactionVersion | void = void>(\n        signature: Signature,\n        config: GetTransactionCommonConfig<TMaxSupportedTransactionVersion> &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ):\n        | (GetTransactionApiResponseBase &\n              (TMaxSupportedTransactionVersion extends void\n                  ? Record<string, never>\n                  : { version: TransactionVersion }) & {\n                  meta: (TransactionMetaBase & TransactionMetaInnerInstructionsParsed) | null;\n                  transaction: TransactionJsonParsed &\n                      (TMaxSupportedTransactionVersion extends void\n                          ? Record<string, never>\n                          : TransactionAddressTableLookups);\n              })\n        | null;\n    /**\n     * Returns details of the confirmed transaction identified by the given signature.\n     *\n     * @param signature A 64 byte Ed25519 signature, encoded as a base-58 string, that uniquely\n     * identifies a transaction by virtue of being the first or only signature in its list of\n     * signatures.\n     *\n     * Materializes the transaction as a tuple whose first element is the bytes of the wire\n     * transaction as a base64-encoded string.\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/http/gettransaction\n     */\n    getTransaction<TMaxSupportedTransactionVersion extends TransactionVersion | void = void>(\n        signature: Signature,\n        config: GetTransactionCommonConfig<TMaxSupportedTransactionVersion> &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ):\n        | (GetTransactionApiResponseBase &\n              (TMaxSupportedTransactionVersion extends void\n                  ? Record<string, never>\n                  : { version: TransactionVersion }) & {\n                  meta:\n                      | (TransactionMetaBase &\n                            TransactionMetaInnerInstructionsNotParsed &\n                            (TMaxSupportedTransactionVersion extends void\n                                ? Record<string, never>\n                                : TransactionMetaLoadedAddresses))\n                      | null;\n                  transaction: Base64EncodedDataResponse;\n              })\n        | null;\n    /**\n     * Returns details of the confirmed transaction identified by the given signature.\n     *\n     * @param signature A 64 byte Ed25519 signature, encoded as a base-58 string, that uniquely\n     * identifies a transaction by virtue of being the first or only signature in its list of\n     * signatures.\n     *\n     * Materializes the transaction as a tuple whose first element is the bytes of the wire\n     * transaction as a base58-encoded string.\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/http/gettransaction\n     */\n    getTransaction<TMaxSupportedTransactionVersion extends TransactionVersion | void = void>(\n        signature: Signature,\n        config: GetTransactionCommonConfig<TMaxSupportedTransactionVersion> &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ):\n        | (GetTransactionApiResponseBase &\n              (TMaxSupportedTransactionVersion extends void\n                  ? Record<string, never>\n                  : { version: TransactionVersion }) & {\n                  meta:\n                      | (TransactionMetaBase &\n                            TransactionMetaInnerInstructionsNotParsed &\n                            (TMaxSupportedTransactionVersion extends void\n                                ? Record<string, never>\n                                : TransactionMetaLoadedAddresses))\n                      | null;\n                  transaction: Base58EncodedDataResponse;\n              })\n        | null;\n    /**\n     * Returns details of the confirmed transaction identified by the given signature.\n     *\n     * @param signature A 64 byte Ed25519 signature, encoded as a base-58 string, that uniquely\n     * identifies a transaction by virtue of being the first or only signature in its list of\n     * signatures.\n     *\n     * Materializes the transaction as structured {@link TransactionJson}.\n     *\n     * {@label json}\n     * @see https://solana.com/docs/rpc/http/gettransaction\n     */\n    getTransaction<TMaxSupportedTransactionVersion extends TransactionVersion | void = void>(\n        signature: Signature,\n        config?: GetTransactionCommonConfig<TMaxSupportedTransactionVersion> &\n            Readonly<{\n                encoding?: 'json';\n            }>,\n    ):\n        | (GetTransactionApiResponseBase &\n              (TMaxSupportedTransactionVersion extends void\n                  ? Record<string, never>\n                  : { version: TransactionVersion }) & {\n                  meta:\n                      | (TransactionMetaBase &\n                            TransactionMetaInnerInstructionsNotParsed &\n                            (TMaxSupportedTransactionVersion extends void\n                                ? Record<string, never>\n                                : TransactionMetaLoadedAddresses))\n                      | null;\n                  transaction: TransactionJson &\n                      (TMaxSupportedTransactionVersion extends void\n                          ? Record<string, never>\n                          : TransactionAddressTableLookups);\n              })\n        | null;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getTransactionCount.ts",
    "content": "import type { Commitment, Slot } from '@solana/rpc-types';\n\ntype GetTransactionCountApiResponse = bigint;\n\nexport type GetTransactionCountApi = {\n    /**\n     * Returns the current number of transactions to have achieved a given level of commitment.\n     *\n     * @see https://solana.com/docs/rpc/http/gettransactioncount\n     */\n    getTransactionCount(\n        config?: Readonly<{\n            /**\n             * Fetch the transaction count as of the highest slot that has reached this level of\n             * commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): GetTransactionCountApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getVersion.ts",
    "content": "type GetVersionApiResponse = Readonly<{\n    /**\n     * The unique identifier of the node's feature set.\n     *\n     * This value is computed by sorting all feature addresses' byte arrays lexicographically,\n     * hashing them, then taking the first 4 bytes of the result. This keeps the feature set value\n     * stable across versions until a new feature is introduced.\n     */\n    'feature-set': number; // `u32`\n    /** Software version of the node */\n    'solana-core': string;\n}>;\n\nexport type GetVersionApi = {\n    /**\n     * Returns the current Solana version running on the node.\n     *\n     * @see https://solana.com/docs/rpc/http/getversion\n     */\n    getVersion(): GetVersionApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/getVoteAccounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment, Epoch, Slot } from '@solana/rpc-types';\n\ntype Credits = bigint;\ntype PreviousCredits = bigint;\n\ntype EpochCredit = [Epoch, Credits, PreviousCredits];\n\ntype VoteAccount<TVotePubkey extends Address> = Readonly<{\n    /**\n     * The amount of stake, in {@link Lamports}, delegated to this vote account and active in this\n     * epoch.\n     */\n    activatedStake: bigint;\n    /** The percentage of rewards payout owed to the vote account */\n    commission: number;\n    /** Latest history of earned credits for up to five epochs */\n    epochCredits: readonly EpochCredit[];\n    /** Whether the vote account is staked for this epoch */\n    epochVoteAccount: boolean;\n    /** Most recent slot voted on by this vote account */\n    lastVote: bigint;\n    /** Validator identity */\n    nodePubkey: Address;\n    /** Current root slot for this vote account */\n    rootSlot: Slot;\n    /** Vote account address */\n    votePubkey: TVotePubkey;\n}>;\n\ntype GetVoteAccountsApiResponse<TVotePubkey extends Address> = Readonly<{\n    /** Vote accounts belonging to validators which are keeping pace with the tip of the chain */\n    current: readonly VoteAccount<TVotePubkey>[];\n    /** Vote accounts belonging to validators which have fallen behind the tip of the chain */\n    delinquent: readonly VoteAccount<TVotePubkey>[];\n}>;\n\ntype GetVoteAccountsConfig<TVoteAddress extends Address> = Readonly<{\n    /**\n     * Fetch the details of the vote accounts as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Specify the number of slots behind the tip that a validator must fall to be considered\n     * delinquent.\n     *\n     * For the sake of consistency between ecosystem products, _it is recommended that this argument\n     * be **omitted**._\n     *\n     * @defaultValue `128n`\n     */\n    delinquentSlotDistance?: bigint;\n    /**\n     * Return delinquent validators (ie. validators who are behind the tip of the chain by the\n     * number of slots specified by `delinquentSlotDistance`), even if they are unstaked\n     *\n     * @defaultValue `false`\n     */\n    keepUnstakedDelinquents?: boolean;\n    /** Only return results for the validator with this vote account address */\n    votePubkey?: TVoteAddress;\n}>;\n\nexport type GetVoteAccountsApi = {\n    /**\n     * Returns the account info and associated stake for all the voting accounts in the current\n     * bank.\n     *\n     * @see https://solana.com/docs/rpc/http/getvoteaccounts\n     */\n    getVoteAccounts<TVoteAccount extends Address>(\n        config?: GetVoteAccountsConfig<TVoteAccount>,\n    ): GetVoteAccountsApiResponse<TVoteAccount>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/index.ts",
    "content": "/**\n * This package contains types that describe the [methods](https://solana.com/docs/rpc/http) of the\n * Solana JSON RPC API, and utilities for creating a {@link RpcApi} implementation with sensible\n * defaults. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @example\n * Each RPC method is described in terms of a TypeScript type of the following form:\n *\n * ```ts\n * type ExampleApi = {\n *     getSomething(address: Address): Something;\n * };\n * ```\n *\n * A {@link RpcApi} that implements `ExampleApi` will ultimately expose its defined methods on any\n * {@link Rpc} that uses it.\n *\n * ```ts\n * const rpc: Rpc<ExampleApi> = createExampleRpc(/* ... *\\/);\n * const something: Something = await rpc.getSomething(address('95DpK3y3GF7U8s1k4EvZ7xqyeCkhsHeZaE97iZpHUGMN')).send();\n * ```\n *\n * @packageDocumentation\n */\nimport { createJsonRpcApi, RpcApi } from '@solana/rpc-spec';\nimport {\n    AllowedNumericKeypaths,\n    getDefaultRequestTransformerForSolanaRpc,\n    getDefaultResponseTransformerForSolanaRpc,\n    innerInstructionsConfigs,\n    jsonParsedAccountsConfigs,\n    jsonParsedTokenAccountsConfigs,\n    KEYPATH_WILDCARD,\n    messageConfig,\n    RequestTransformerConfig,\n} from '@solana/rpc-transformers';\n\nimport { GetAccountInfoApi } from './getAccountInfo';\nimport { GetBalanceApi } from './getBalance';\nimport { GetBlockApi } from './getBlock';\nimport { GetBlockCommitmentApi } from './getBlockCommitment';\nimport { GetBlockHeightApi } from './getBlockHeight';\nimport { GetBlockProductionApi } from './getBlockProduction';\nimport { GetBlocksApi } from './getBlocks';\nimport { GetBlocksWithLimitApi } from './getBlocksWithLimit';\nimport { GetBlockTimeApi } from './getBlockTime';\nimport { GetClusterNodesApi } from './getClusterNodes';\nimport { GetEpochInfoApi } from './getEpochInfo';\nimport { GetEpochScheduleApi } from './getEpochSchedule';\nimport { GetFeeForMessageApi } from './getFeeForMessage';\nimport { GetFirstAvailableBlockApi } from './getFirstAvailableBlock';\nimport { GetGenesisHashApi } from './getGenesisHash';\nimport { GetHealthApi } from './getHealth';\nimport { GetHighestSnapshotSlotApi } from './getHighestSnapshotSlot';\nimport { GetIdentityApi } from './getIdentity';\nimport { GetInflationGovernorApi } from './getInflationGovernor';\nimport { GetInflationRateApi } from './getInflationRate';\nimport { GetInflationRewardApi } from './getInflationReward';\nimport { GetLargestAccountsApi } from './getLargestAccounts';\nimport { GetLatestBlockhashApi } from './getLatestBlockhash';\nimport { GetLeaderScheduleApi } from './getLeaderSchedule';\nimport { GetMaxRetransmitSlotApi } from './getMaxRetransmitSlot';\nimport { GetMaxShredInsertSlotApi } from './getMaxShredInsertSlot';\nimport { GetMinimumBalanceForRentExemptionApi } from './getMinimumBalanceForRentExemption';\nimport { GetMultipleAccountsApi } from './getMultipleAccounts';\nimport { GetProgramAccountsApi } from './getProgramAccounts';\nimport { GetRecentPerformanceSamplesApi } from './getRecentPerformanceSamples';\nimport { GetRecentPrioritizationFeesApi } from './getRecentPrioritizationFees';\nimport { GetSignaturesForAddressApi } from './getSignaturesForAddress';\nimport { GetSignatureStatusesApi } from './getSignatureStatuses';\nimport { GetSlotApi } from './getSlot';\nimport { GetSlotLeaderApi } from './getSlotLeader';\nimport { GetSlotLeadersApi } from './getSlotLeaders';\nimport { GetStakeMinimumDelegationApi } from './getStakeMinimumDelegation';\nimport { GetSupplyApi } from './getSupply';\nimport { GetTokenAccountBalanceApi } from './getTokenAccountBalance';\nimport { GetTokenAccountsByDelegateApi } from './getTokenAccountsByDelegate';\nimport { GetTokenAccountsByOwnerApi } from './getTokenAccountsByOwner';\nimport { GetTokenLargestAccountsApi } from './getTokenLargestAccounts';\nimport { GetTokenSupplyApi } from './getTokenSupply';\nimport { GetTransactionApi } from './getTransaction';\nimport { GetTransactionCountApi } from './getTransactionCount';\nimport { GetVersionApi } from './getVersion';\nimport { GetVoteAccountsApi } from './getVoteAccounts';\nimport { IsBlockhashValidApi } from './isBlockhashValid';\nimport { MinimumLedgerSlotApi } from './minimumLedgerSlot';\nimport { RequestAirdropApi } from './requestAirdrop';\nimport { SendTransactionApi } from './sendTransaction';\nimport { SimulateTransactionApi } from './simulateTransaction';\n\ntype SolanaRpcApiForAllClusters = GetAccountInfoApi &\n    GetBalanceApi &\n    GetBlockApi &\n    GetBlockCommitmentApi &\n    GetBlockHeightApi &\n    GetBlockProductionApi &\n    GetBlocksApi &\n    GetBlocksWithLimitApi &\n    GetBlockTimeApi &\n    GetClusterNodesApi &\n    GetEpochInfoApi &\n    GetEpochScheduleApi &\n    GetFeeForMessageApi &\n    GetFirstAvailableBlockApi &\n    GetGenesisHashApi &\n    GetHealthApi &\n    GetHighestSnapshotSlotApi &\n    GetIdentityApi &\n    GetInflationGovernorApi &\n    GetInflationRateApi &\n    GetInflationRewardApi &\n    GetLargestAccountsApi &\n    GetLatestBlockhashApi &\n    GetLeaderScheduleApi &\n    GetMaxRetransmitSlotApi &\n    GetMaxShredInsertSlotApi &\n    GetMinimumBalanceForRentExemptionApi &\n    GetMultipleAccountsApi &\n    GetProgramAccountsApi &\n    GetRecentPerformanceSamplesApi &\n    GetRecentPrioritizationFeesApi &\n    GetSignaturesForAddressApi &\n    GetSignatureStatusesApi &\n    GetSlotApi &\n    GetSlotLeaderApi &\n    GetSlotLeadersApi &\n    GetStakeMinimumDelegationApi &\n    GetSupplyApi &\n    GetTokenAccountBalanceApi &\n    GetTokenAccountsByDelegateApi &\n    GetTokenAccountsByOwnerApi &\n    GetTokenLargestAccountsApi &\n    GetTokenSupplyApi &\n    GetTransactionApi &\n    GetTransactionCountApi &\n    GetVersionApi &\n    GetVoteAccountsApi &\n    IsBlockhashValidApi &\n    MinimumLedgerSlotApi &\n    SendTransactionApi &\n    SimulateTransactionApi;\ntype SolanaRpcApiForTestClusters = RequestAirdropApi & SolanaRpcApiForAllClusters;\n/**\n * Represents the RPC methods available on test clusters.\n *\n * For instance, the test clusters support the {@link RequestAirdropApi} while mainnet does not.\n */\nexport type SolanaRpcApi = SolanaRpcApiForTestClusters;\n/**\n * Represents the RPC methods available on the devnet cluster.\n *\n * For instance, the devnet cluster supports the {@link RequestAirdropApi} while mainnet does not.\n */\nexport type SolanaRpcApiDevnet = SolanaRpcApiForTestClusters;\n/**\n * Represents the RPC methods available on the testnet cluster.\n *\n * For instance, the testnet cluster supports the {@link RequestAirdropApi} while mainnet does not.\n */\nexport type SolanaRpcApiTestnet = SolanaRpcApiForTestClusters;\n/**\n * Represents the RPC methods available on the mainnet cluster.\n *\n * For instance, the mainnet cluster does not support the {@link RequestAirdropApi} whereas test\n * clusters do.\n */\nexport type SolanaRpcApiMainnet = SolanaRpcApiForAllClusters;\n\nexport type {\n    GetAccountInfoApi,\n    GetBalanceApi,\n    GetBlockApi,\n    GetBlockCommitmentApi,\n    GetBlockHeightApi,\n    GetBlockProductionApi,\n    GetBlocksApi,\n    GetBlocksWithLimitApi,\n    GetBlockTimeApi,\n    GetClusterNodesApi,\n    GetEpochInfoApi,\n    GetEpochScheduleApi,\n    GetFeeForMessageApi,\n    GetFirstAvailableBlockApi,\n    GetGenesisHashApi,\n    GetHealthApi,\n    GetHighestSnapshotSlotApi,\n    GetIdentityApi,\n    GetInflationGovernorApi,\n    GetInflationRateApi,\n    GetInflationRewardApi,\n    GetLargestAccountsApi,\n    GetLatestBlockhashApi,\n    GetLeaderScheduleApi,\n    GetMaxRetransmitSlotApi,\n    GetMaxShredInsertSlotApi,\n    GetMinimumBalanceForRentExemptionApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetRecentPerformanceSamplesApi,\n    GetRecentPrioritizationFeesApi,\n    GetSignaturesForAddressApi,\n    GetSignatureStatusesApi,\n    GetSlotApi,\n    GetSlotLeaderApi,\n    GetSlotLeadersApi,\n    GetStakeMinimumDelegationApi,\n    GetSupplyApi,\n    GetTokenAccountBalanceApi,\n    GetTokenAccountsByDelegateApi,\n    GetTokenAccountsByOwnerApi,\n    GetTokenLargestAccountsApi,\n    GetTokenSupplyApi,\n    GetTransactionApi,\n    GetTransactionCountApi,\n    GetVersionApi,\n    GetVoteAccountsApi,\n    IsBlockhashValidApi,\n    MinimumLedgerSlotApi,\n    RequestAirdropApi,\n    SendTransactionApi,\n    SimulateTransactionApi,\n};\n\ntype Config = RequestTransformerConfig;\n\n/**\n * Creates a {@link RpcApi} implementation of the Solana JSON RPC API with some default behaviours.\n *\n * The default behaviours include:\n * - A transform that converts `bigint` inputs to `number` for compatibility with version 1.0 of the\n *   Solana JSON RPC.\n * - A transform that calls the config's {@link Config.onIntegerOverflow | onIntegerOverflow}\n *   handler whenever a `bigint` input would overflow a JavaScript IEEE 754 number. See\n *   [this](https://github.com/solana-labs/solana-web3.js/issues/1116) GitHub issue for more\n *   information.\n * - A transform that applies a default commitment wherever not specified\n */\nexport function createSolanaRpcApi<\n    // eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents\n    TRpcMethods extends SolanaRpcApi | SolanaRpcApiDevnet | SolanaRpcApiMainnet | SolanaRpcApiTestnet = SolanaRpcApi,\n>(config?: Config): RpcApi<TRpcMethods> {\n    return createJsonRpcApi<TRpcMethods>({\n        requestTransformer: getDefaultRequestTransformerForSolanaRpc(config),\n        responseTransformer: getDefaultResponseTransformerForSolanaRpc({\n            allowedNumericKeyPaths: getAllowedNumericKeypaths(),\n        }),\n    });\n}\n\nlet memoizedKeypaths: AllowedNumericKeypaths<RpcApi<SolanaRpcApi>>;\n\n/**\n * These are keypaths at the end of which you will find a numeric value that should *not* be upcast\n * to a `bigint`. These are values that are legitimately defined as `u8` or `usize` on the backend.\n */\nfunction getAllowedNumericKeypaths(): AllowedNumericKeypaths<RpcApi<SolanaRpcApi>> {\n    if (!memoizedKeypaths) {\n        memoizedKeypaths = {\n            getAccountInfo: jsonParsedAccountsConfigs.map(c => ['value', ...c]),\n            getBlock: [\n                ['transactions', KEYPATH_WILDCARD, 'meta', 'preTokenBalances', KEYPATH_WILDCARD, 'accountIndex'],\n                [\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'preTokenBalances',\n                    KEYPATH_WILDCARD,\n                    'uiTokenAmount',\n                    'decimals',\n                ],\n                ['transactions', KEYPATH_WILDCARD, 'meta', 'postTokenBalances', KEYPATH_WILDCARD, 'accountIndex'],\n                [\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'postTokenBalances',\n                    KEYPATH_WILDCARD,\n                    'uiTokenAmount',\n                    'decimals',\n                ],\n                ['transactions', KEYPATH_WILDCARD, 'meta', 'rewards', KEYPATH_WILDCARD, 'commission'],\n                ...innerInstructionsConfigs.map(c => [\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'innerInstructions',\n                    KEYPATH_WILDCARD,\n                    ...c,\n                ]),\n                ...messageConfig.map(c => ['transactions', KEYPATH_WILDCARD, 'transaction', 'message', ...c] as const),\n                ['rewards', KEYPATH_WILDCARD, 'commission'],\n            ],\n            getClusterNodes: [\n                [KEYPATH_WILDCARD, 'featureSet'],\n                [KEYPATH_WILDCARD, 'shredVersion'],\n            ],\n            getInflationGovernor: [['initial'], ['foundation'], ['foundationTerm'], ['taper'], ['terminal']],\n            getInflationRate: [['foundation'], ['total'], ['validator']],\n            getInflationReward: [[KEYPATH_WILDCARD, 'commission']],\n            getMultipleAccounts: jsonParsedAccountsConfigs.map(c => ['value', KEYPATH_WILDCARD, ...c]),\n            getProgramAccounts: jsonParsedAccountsConfigs.flatMap(c => [\n                ['value', KEYPATH_WILDCARD, 'account', ...c],\n                [KEYPATH_WILDCARD, 'account', ...c],\n            ]),\n            getRecentPerformanceSamples: [[KEYPATH_WILDCARD, 'samplePeriodSecs']],\n            getTokenAccountBalance: [\n                ['value', 'decimals'],\n                ['value', 'uiAmount'],\n            ],\n            getTokenAccountsByDelegate: jsonParsedTokenAccountsConfigs.map(c => [\n                'value',\n                KEYPATH_WILDCARD,\n                'account',\n                ...c,\n            ]),\n            getTokenAccountsByOwner: jsonParsedTokenAccountsConfigs.map(c => [\n                'value',\n                KEYPATH_WILDCARD,\n                'account',\n                ...c,\n            ]),\n            getTokenLargestAccounts: [\n                ['value', KEYPATH_WILDCARD, 'decimals'],\n                ['value', KEYPATH_WILDCARD, 'uiAmount'],\n            ],\n            getTokenSupply: [\n                ['value', 'decimals'],\n                ['value', 'uiAmount'],\n            ],\n            getTransaction: [\n                ['meta', 'preTokenBalances', KEYPATH_WILDCARD, 'accountIndex'],\n                ['meta', 'preTokenBalances', KEYPATH_WILDCARD, 'uiTokenAmount', 'decimals'],\n                ['meta', 'postTokenBalances', KEYPATH_WILDCARD, 'accountIndex'],\n                ['meta', 'postTokenBalances', KEYPATH_WILDCARD, 'uiTokenAmount', 'decimals'],\n                ['meta', 'rewards', KEYPATH_WILDCARD, 'commission'],\n                ...innerInstructionsConfigs.map(c => ['meta', 'innerInstructions', KEYPATH_WILDCARD, ...c]),\n                ...messageConfig.map(c => ['transaction', 'message', ...c] as const),\n            ],\n            getVersion: [['feature-set']],\n            getVoteAccounts: [\n                ['current', KEYPATH_WILDCARD, 'commission'],\n                ['delinquent', KEYPATH_WILDCARD, 'commission'],\n            ],\n            simulateTransaction: [\n                ['value', 'loadedAccountsDataSize'],\n                ...jsonParsedAccountsConfigs.map(c => ['value', 'accounts', KEYPATH_WILDCARD, ...c]),\n                ...innerInstructionsConfigs.map(c => ['value', 'innerInstructions', KEYPATH_WILDCARD, ...c]),\n            ],\n        };\n    }\n    return memoizedKeypaths;\n}\n"
  },
  {
    "path": "packages/rpc-api/src/isBlockhashValid.ts",
    "content": "import type { Blockhash, Commitment, Slot, SolanaRpcResponse } from '@solana/rpc-types';\n\ntype IsBlockhashValidApiResponse = boolean;\n\nexport type IsBlockhashValidApi = {\n    /**\n     * Returns whether a blockhash is still valid or not.\n     *\n     * The last 300 blockhashes produced are considered valid. This equates to an age of ~2 minutes.\n     *\n     * @param blockhash A SHA-256 hash as base-58 encoded string\n     *\n     * @see https://solana.com/docs/rpc/http/isblockhashvalid\n     */\n    isBlockhashValid(\n        blockhash: Blockhash,\n        config?: Readonly<{\n            /**\n             * Evaluate whether the blockhash is valid as of the highest slot that has reached this\n             * level of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        }>,\n    ): SolanaRpcResponse<IsBlockhashValidApiResponse>;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/minimumLedgerSlot.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype MinimumLedgerSlotApiResponse = Slot;\n\nexport type MinimumLedgerSlotApi = {\n    /**\n     * Returns the lowest slot about which the node has information.\n     *\n     * Different nodes may offer more or less historical slot data, depending on their\n     * configuration. An appropriately configured node should be able to access all slots, from\n     * genesis onward. When it is not, this method will tell you the lowest slot available.\n     *\n     * @see https://solana.com/docs/rpc/http/minimumledgerslot\n     */\n    minimumLedgerSlot(): MinimumLedgerSlotApiResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/requestAirdrop.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { Commitment, Lamports } from '@solana/rpc-types';\n\ntype RequestAirdropConfig = Readonly<{\n    /**\n     * Evaluate the request as of the highest slot that has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n}>;\n\ntype RequestAirdropResponse = Signature;\n\nexport type RequestAirdropApi = {\n    /**\n     * Requests an airdrop of {@link Lamports} to the specified address.\n     *\n     * This method is offered by test clusters as a way to obtain SOL tokens to pay transaction\n     * fees.\n     *\n     * @returns The signature of the airdrop transaction, as a base-58 encoded string.\n     * @see https://solana.com/docs/rpc/http/requestairdrop\n     */\n    requestAirdrop(\n        recipientAccount: Address,\n        lamports: Lamports,\n        config?: RequestAirdropConfig,\n    ): RequestAirdropResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/sendTransaction.ts",
    "content": "import type { Signature } from '@solana/keys';\nimport type { Commitment, Slot } from '@solana/rpc-types';\nimport type { Base64EncodedWireTransaction } from '@solana/transactions';\n\ntype SendTransactionConfig = Readonly<{\n    /**\n     * Maximum number of times for the RPC node to retry sending the transaction to the leader.\n     *\n     * @defaultValue When omitted, the RPC node will retry the transaction until it is finalized or\n     * until its lifetime specifier (ie. its recent blockhash or nonce) expires.\n     */\n    maxRetries?: bigint;\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n    /**\n     * Simulate the transaction as of the highest slot that has reached this level of commitment.\n     *\n     * Has no effect when `skipPreflight` is set to `true`.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    preflightCommitment?: Commitment;\n    /** @defaultValue `false` */\n    skipPreflight?: boolean;\n}>;\n\ntype SendTransactionResponse = Signature;\n\nexport type SendTransactionApi = {\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    sendTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config?: SendTransactionConfig & { encoding?: 'base58' },\n    ): SendTransactionResponse;\n    /**\n     * Submits a signed transaction to the cluster for processing.\n     *\n     * This method does not alter the transaction in any way; it relays the transaction created by\n     * clients to the node as-is.\n     *\n     * If the node's RPC service receives the transaction, this method immediately succeeds, without\n     * waiting for any confirmations. A successful response from this method does not guarantee the\n     * transaction will be processed or confirmed by the cluster.\n     *\n     * While the RPC service will reasonably retry to submit it, the transaction could fail to be\n     * committed if the transaction's lifetime specifier (ie. its recent blockhash or nonce) expires\n     * before it lands.\n     *\n     * Use {@link GetSignatureStatusesApi.getSignatureStatuses} to ensure that a transaction has\n     * been processed and confirmed.\n     *\n     * Before submitting, the following preflight checks are performed:\n     *\n     *     1. The transaction signatures are verified\n     *     2. The transaction is simulated against the bank slot specified by the preflight\n     *        commitment. On failure, an error will be returned. It is recommended to specify the\n     *        same commitment and preflight commitment to avoid confusing behavior. You can disable\n     *        preflight checks if desired.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * @returns The signature of the transaction, as a base-58 encoded string. This is the first\n     * signature in the transaction, which is used to uniquely identify it. You do not have to wait\n     * for this method to return to obtain the signature; you can extract it from the transaction\n     * before sending it.\n     *\n     * @see https://solana.com/docs/rpc/http/sendtransaction\n     */\n    sendTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config?: SendTransactionConfig & { encoding: 'base64' },\n    ): SendTransactionResponse;\n};\n"
  },
  {
    "path": "packages/rpc-api/src/simulateTransaction.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithJsonData,\n    Base58EncodedBytes,\n    Base64EncodedDataResponse,\n    Commitment,\n    Lamports,\n    Slot,\n    SolanaRpcResponse,\n    TokenBalance,\n    TransactionError,\n    TransactionForFullMetaInnerInstructionsParsed,\n    TransactionForFullMetaInnerInstructionsUnparsed,\n} from '@solana/rpc-types';\nimport type { Base64EncodedWireTransaction, TransactionBlockhashLifetime } from '@solana/transactions';\n\ntype SimulateTransactionConfigBase = Readonly<{\n    /**\n     * Simulate the transaction as of the highest slot that has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * If `true` the response will include inner instructions. These inner instructions will be\n     * `jsonParsed` where possible, otherwise `json`.\n     * @defaultValue false\n     */\n    innerInstructions?: boolean;\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n}>;\n\n// Both are optional booleans, but conflict - so cannot both be true\ntype SigVerifyAndReplaceRecentBlockhashConfig<TReplaceBlockhash extends boolean | undefined = false | undefined> =\n    TReplaceBlockhash extends true\n        ? Readonly<{\n              /** if `true` the transaction recent blockhash will be replaced with the most recent blockhash. (conflicts with `sigVerify`) */\n              replaceRecentBlockhash: true;\n              /** if `true` the transaction signatures will be verified (conflicts with `replaceRecentBlockhash`) */\n              sigVerify?: false;\n          }>\n        :\n              | Readonly<{\n                    /** if `true` the transaction recent blockhash will be replaced with the most recent blockhash. (conflicts with `sigVerify`) */\n                    replaceRecentBlockhash?: boolean;\n                    /** if `true` the transaction signatures will be verified (conflicts with `replaceRecentBlockhash`) */\n                    sigVerify?: false;\n                }>\n              | Readonly<{\n                    /** if `true` the transaction recent blockhash will be replaced with the most recent blockhash. (conflicts with `sigVerify`) */\n                    replaceRecentBlockhash?: false;\n                    /** if `true` the transaction signatures will be verified (conflicts with `replaceRecentBlockhash`) */\n                    sigVerify: true;\n                }>;\n\ntype AccountsConfigWithBase64EncodingZstdCompression = Readonly<{\n    accounts: {\n        /** An `array` of accounts to return */\n        addresses: readonly Address[];\n        /** Encoding for returned Account data */\n        encoding: 'base64+zstd';\n    };\n}>;\n\ntype AccountsConfigWithJsonParsedEncoding = Readonly<{\n    accounts: {\n        /** An `array` of accounts to return */\n        addresses: readonly Address[];\n        /** Encoding for returned Account data */\n        encoding: 'jsonParsed';\n    };\n}>;\n\ntype AccountsConfigWithBase64Encoding = Readonly<{\n    accounts: {\n        /** An `array` of accounts to return */\n        addresses: readonly Address[];\n        // Optional because this is the default encoding\n        /** Encoding for returned Account data */\n        encoding?: 'base64';\n    };\n}>;\n\ntype WithInnerInstructionsConfig = Readonly<{\n    innerInstructions: true;\n}>;\n\ntype SimulateTransactionApiResponseBase = Readonly<{\n    /** If the transaction failed, this property will contain the error */\n    err: TransactionError | null;\n    /** The fee the transaction would have paid */\n    fee: Lamports | null;\n    /** The number of bytes of all accounts loaded by this transaction */\n    loadedAccountsDataSize?: number;\n    /** Addresses loaded from address lookup tables */\n    loadedAddresses: Readonly<{\n        readonly: readonly Address[];\n        writable: readonly Address[];\n    }> | null;\n    /**\n     * Array of log messages the transaction instructions output during execution, `null` if\n     * simulation failed before the transaction was able to execute (for example due to an invalid\n     * blockhash or signature verification failure)\n     */\n    logs: string[] | null;\n    /** Lamport balances for each account after the transaction would have been processed */\n    postBalances: readonly Lamports[] | null;\n    /** Token balances for each token account after the transaction would have been processed */\n    postTokenBalances: readonly TokenBalance[] | null;\n    /** Lamport balances for each account before the transaction was processed */\n    preBalances: readonly Lamports[] | null;\n    /** Token balances for each token account before the transaction was processed */\n    preTokenBalances: readonly TokenBalance[] | null;\n    /** The most-recent return data generated by an instruction in the transaction */\n    returnData: Readonly<{\n        /** The return data itself, as base-64 encoded binary data */\n        data: Base64EncodedDataResponse;\n        /** The program that generated the return data */\n        programId: Address;\n    }> | null;\n    /** The number of compute budget units consumed during the processing of this transaction */\n    unitsConsumed?: bigint;\n}>;\n\ntype SimulateTransactionApiResponseWithAccounts<T extends AccountInfoBase> = Readonly<{\n    /** Array of accounts with the same length as the `accounts.addresses` array in the request */\n    accounts: (T | null)[];\n}>;\n\ntype SimulateTransactionApiResponseWithInnerInstructions = Readonly<\n    TransactionForFullMetaInnerInstructionsParsed | TransactionForFullMetaInnerInstructionsUnparsed\n>;\n\ntype SimulateTransactionApiResponseWithReplacementBlockhash = Readonly<{\n    /**\n     * The blockhash that was used to simulate the transaction when `replaceRecentBlockhash` is\n     * `true`.\n     *\n     * Note: Agave v3.x validators always return this field (as `null` when not requested), but\n     * Kit's types currently only surface it when `replaceRecentBlockhash` is `true`. A future\n     * breaking change will move this to the base response type to match v3.x behavior.\n     */\n    replacementBlockhash: TransactionBlockhashLifetime;\n}>;\n\nexport type SimulateTransactionApi = {\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithBase64Encoding &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedData> &\n            SimulateTransactionApiResponseWithInnerInstructions &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithBase64Encoding &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedData> &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithBase64EncodingZstdCompression &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<\n                AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData\n            > &\n            SimulateTransactionApiResponseWithInnerInstructions &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithBase64EncodingZstdCompression &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<\n                AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData\n            > &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithJsonParsedEncoding &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithJsonData> &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config?: SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig,\n    ): SolanaRpcResponse<\n        Readonly<{ readonly accounts: null }> &\n            SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithInnerInstructions &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config?: SigVerifyAndReplaceRecentBlockhashConfig<true> & SimulateTransactionConfigBase,\n    ): SolanaRpcResponse<\n        Readonly<{ readonly accounts: null }> &\n            SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state,\n     * obtain the list of inner instructions run, if any, and replace the transaction's blockhash\n     * with the most recent one.\n     *\n     * If the listed accounts have data, it will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * The replacement blockhash and the blockheight until which it is valid will be returned in the\n     * response.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-base64--with-inner-instructions--with-replacement-blockhash}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithBase64Encoding &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedData> &\n            SimulateTransactionApiResponseWithInnerInstructions &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state, and\n     * replace the transaction's blockhash with the most recent one.\n     *\n     * If the listed accounts have data, it will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * The replacement blockhash and the blockheight until which it is valid will be returned in the\n     * response.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-base64--no-inner-instructions--with-replacement-blockhash}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithBase64Encoding &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedData> &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state,\n     * obtain the list of inner instructions run, if any, and replace the transaction's blockhash\n     * with the most recent one.\n     *\n     * If the listed accounts have data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * The replacement blockhash and the blockheight until which it is valid will be returned in the\n     * response.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-base64-zstd-compressed--with-inner-instructions--with-replacement-blockhash}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithBase64EncodingZstdCompression &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<\n                AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData\n            > &\n            SimulateTransactionApiResponseWithInnerInstructions &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state, and\n     * replace the transaction's blockhash with the most recent one.\n     *\n     * If the listed accounts have data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * The replacement blockhash and the blockheight until which it is valid will be returned in the\n     * response.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-base64-zstd-compressed--no-inner-instructions--with-replacement-blockhash}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithBase64EncodingZstdCompression &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<\n                AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData\n            > &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state,\n     * obtain the list of inner instructions run, if any, and replace the transaction's blockhash\n     * with the most recent one.\n     *\n     * If the listed accounts have data, the server will attempt to process it using a parser\n     * specific to each account's owning program. If successful, the parsed data will be returned in\n     * the response as JSON. Otherwise, the raw account data will be returned in the response as a\n     * tuple whose first element is a base64-encoded string.\n     *\n     * The replacement blockhash and the blockheight until which it is valid will be returned in the\n     * response.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-parsed--with-inner-instructions--with-replacement-blockhash}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithJsonParsedEncoding &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithJsonData> &\n            SimulateTransactionApiResponseWithInnerInstructions &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state, and\n     * replace the transaction's blockhash with the most recent one.\n     *\n     * If the listed accounts have data, the server will attempt to process it using a parser\n     * specific to each account's owning program. If successful, the parsed data will be returned in\n     * the response as JSON. Otherwise, the raw account data will be returned in the response as a\n     * tuple whose first element is a base64-encoded string.\n     *\n     * The replacement blockhash and the blockheight until which it is valid will be returned in the\n     * response.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-parsed--no-inner-instructions--with-replacement-blockhash}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithJsonParsedEncoding &\n            SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithJsonData> &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /**\n     * Simulate sending a transaction, obtain the list of inner instructions run, if any, and\n     * replace the transaction's blockhash with the most recent one.\n     *\n     * The replacement blockhash and the blockheight until which it is valid will be returned in the\n     * response.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label no-accounts--with-inner-instructions--with-replacement-blockhash}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: SigVerifyAndReplaceRecentBlockhashConfig<true> &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        Readonly<{ readonly accounts: null }> &\n            SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithInnerInstructions &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /**\n     * Simulate sending a transaction, and replace the transaction's blockhash with the most recent\n     * one.\n     *\n     * The replacement blockhash and the blockheight until which it is valid will be returned in the\n     * response.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label no-accounts--no-inner-instructions--with-replacement-blockhash}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: SigVerifyAndReplaceRecentBlockhashConfig<true> & SimulateTransactionConfigBase & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        Readonly<{ readonly accounts: null }> &\n            SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithReplacementBlockhash\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithBase64Encoding &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedData> &\n            SimulateTransactionApiResponseWithInnerInstructions\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithBase64Encoding &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedData>\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithBase64EncodingZstdCompression &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<\n                AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData\n            > &\n            SimulateTransactionApiResponseWithInnerInstructions\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithBase64EncodingZstdCompression &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData>\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithJsonParsedEncoding &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithJsonData> &\n            SimulateTransactionApiResponseWithInnerInstructions\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config: AccountsConfigWithJsonParsedEncoding &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase,\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithJsonData>\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config?: SigVerifyAndReplaceRecentBlockhashConfig & SimulateTransactionConfigBase & WithInnerInstructionsConfig,\n    ): SolanaRpcResponse<\n        Readonly<{ readonly accounts: null }> &\n            SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithInnerInstructions\n    >;\n\n    /** @deprecated Set `encoding` to `'base64'` when calling this method */\n    simulateTransaction(\n        base58EncodedWireTransaction: Base58EncodedBytes,\n        config?: SigVerifyAndReplaceRecentBlockhashConfig & SimulateTransactionConfigBase,\n    ): SolanaRpcResponse<Readonly<{ readonly accounts: null }> & SimulateTransactionApiResponseBase>;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state, and\n     * obtain the list of inner instructions run, if any.\n     *\n     * If the listed accounts have data, it will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-base64--with-inner-instructions}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithBase64Encoding &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedData> &\n            SimulateTransactionApiResponseWithInnerInstructions\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state.\n     *\n     * If the listed accounts have data, it will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-base64--no-inner-instructions}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithBase64Encoding &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedData>\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state, and\n     * obtain the list of inner instructions run, if any.\n     *\n     * If the listed accounts have data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-base64-zstd-compressed--with-inner-instructions}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithBase64EncodingZstdCompression &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<\n                AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData\n            > &\n            SimulateTransactionApiResponseWithInnerInstructions\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state.\n     *\n     * If the listed accounts have data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-base64-zstd-compressed--no-inner-instructions}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithBase64EncodingZstdCompression &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData>\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state, and\n     * obtain the list of inner instructions run, if any.\n     *\n     * If the listed accounts have data, the server will attempt to process it using a parser\n     * specific to each account's owning program. If successful, the parsed data will be returned in\n     * the response as JSON. Otherwise, the raw account data will be returned in the response as a\n     * tuple whose first element is a base64-encoded string.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-parsed--with-inner-instructions}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithJsonParsedEncoding &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithJsonData> &\n            SimulateTransactionApiResponseWithInnerInstructions\n    >;\n\n    /**\n     * Simulate sending a transaction, fetch a list of accounts in their post-simulation state.\n     *\n     * If the listed accounts have data, the server will attempt to process it using a parser\n     * specific to each account's owning program. If successful, the parsed data will be returned in\n     * the response as JSON. Otherwise, the raw account data will be returned in the response as a\n     * tuple whose first element is a base64-encoded string.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label accounts-parsed--no-inner-instructions}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: AccountsConfigWithJsonParsedEncoding &\n            SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithAccounts<AccountInfoBase & AccountInfoWithJsonData>\n    >;\n\n    /**\n     * Simulate sending a transaction, and obtain the list of inner instructions run, if any.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label no-accounts--with-inner-instructions}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: SigVerifyAndReplaceRecentBlockhashConfig &\n            SimulateTransactionConfigBase &\n            WithInnerInstructionsConfig & { encoding: 'base64' },\n    ): SolanaRpcResponse<\n        Readonly<{ readonly accounts: null }> &\n            SimulateTransactionApiResponseBase &\n            SimulateTransactionApiResponseWithInnerInstructions\n    >;\n\n    /**\n     * Simulate sending a transaction.\n     *\n     * @param base64EncodedWireTransaction A fully signed transaction in wire format, as a base-64\n     * encoded string. Use {@link getBase64EncodedWireTransaction} to obtain this.\n     *\n     * {@label no-accounts--no-inner-instructions}\n     * @see https://solana.com/docs/rpc/http/simulatetransaction\n     */\n    simulateTransaction(\n        base64EncodedWireTransaction: Base64EncodedWireTransaction,\n        config: SigVerifyAndReplaceRecentBlockhashConfig & SimulateTransactionConfigBase & { encoding: 'base64' },\n    ): SolanaRpcResponse<Readonly<{ readonly accounts: null }> & SimulateTransactionApiResponseBase>;\n};\n"
  },
  {
    "path": "packages/rpc-api/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-api/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/rpc-api\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-api/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-graphql/.gitignore",
    "content": "dist/\n"
  },
  {
    "path": "packages/rpc-graphql/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-graphql/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-graphql/CHANGELOG.md",
    "content": "# @solana/rpc-graphql\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/codecs-strings@6.9.0\n    - @solana/fast-stable-stringify@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b)]:\n    - @solana/codecs-strings@6.8.0\n    - @solana/fast-stable-stringify@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.7.0\n    - @solana/fast-stable-stringify@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.6.0\n    - @solana/fast-stable-stringify@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.5.0\n    - @solana/fast-stable-stringify@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-strings@6.4.0\n    - @solana/fast-stable-stringify@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.3.1\n    - @solana/fast-stable-stringify@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.3.0\n    - @solana/fast-stable-stringify@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.2.0\n    - @solana/fast-stable-stringify@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.1.0\n    - @solana/fast-stable-stringify@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.0.1\n    - @solana/fast-stable-stringify@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@6.0.0\n    - @solana/fast-stable-stringify@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@5.5.1\n    - @solana/fast-stable-stringify@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@5.5.0\n    - @solana/fast-stable-stringify@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09)]:\n    - @solana/fast-stable-stringify@5.4.0\n    - @solana/codecs-strings@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@5.3.0\n    - @solana/fast-stable-stringify@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/codecs-strings@5.2.0\n    - @solana/fast-stable-stringify@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97)]:\n    - @solana/codecs-strings@5.1.0\n    - @solana/fast-stable-stringify@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@5.0.0\n    - @solana/fast-stable-stringify@5.0.0\n\n## 4.0.0\n\n### Major Changes\n\n- [#550](https://github.com/anza-xyz/kit/pull/550) [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a) Thanks [@steveluscher](https://github.com/steveluscher)! - Removed `rentEpoch` from the `AccountInfoBase` type. This property is no longer relevant post SIMD-215. Developers whose applications rely on this property being numeric should either eliminate it or hardcode it to `18_446_744_073_709_551_615n`.\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@4.0.0\n    - @solana/fast-stable-stringify@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@3.0.0\n    - @solana/fast-stable-stringify@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@2.3.0\n    - @solana/fast-stable-stringify@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@2.2.1\n    - @solana/fast-stable-stringify@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@2.2.0\n    - @solana/fast-stable-stringify@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#433](https://github.com/anza-xyz/kit/pull/433) [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a) Thanks [@steveluscher](https://github.com/steveluscher)! - Corrected a misspelling of `readonlyIndexes` in the `AddressLookupTable` type. This fixes the return type of the `getTransaction` RPC call.\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/fast-stable-stringify@2.1.1\n    - @solana/codecs-strings@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [#153](https://github.com/anza-xyz/kit/pull/153) [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a) Thanks [@steveluscher](https://github.com/steveluscher)! - The values of the `rewardType` property have been corrected. They previously were specified as having a lowercase initial character.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d)]:\n    - @solana/codecs-strings@2.1.0\n    - @solana/fast-stable-stringify@2.1.0\n\n## 2.0.0\n\n### Minor Changes\n\n- [#3098](https://github.com/solana-labs/solana-web3.js/pull/3098) [`2f541b6`](https://github.com/solana-labs/solana-web3.js/commit/2f541b6c7e87002cf26e911d31df4779d4da674c) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Update program accounts filters for `programAccounts` query\n\n### Patch Changes\n\n- [#3213](https://github.com/solana-labs/solana-web3.js/pull/3213) [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcApi: no longer extend RpcApiMethods + remove export\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`5ed19c6`](https://github.com/solana-labs/solana-web3.js/commit/5ed19c6c3c6e7a1bacde8c23c438ecb85454b126), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/fast-stable-stringify@2.0.0\n    - @solana/codecs-strings@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@2.0.0-rc.4\n    - @solana/fast-stable-stringify@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/fast-stable-stringify@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Minor Changes\n\n- [#3098](https://github.com/solana-labs/solana-web3.js/pull/3098) [`2f541b6`](https://github.com/solana-labs/solana-web3.js/commit/2f541b6c7e87002cf26e911d31df4779d4da674c) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Update program accounts filters for `programAccounts` query\n\n### Patch Changes\n\n- [#3213](https://github.com/solana-labs/solana-web3.js/pull/3213) [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcApi: no longer extend RpcApiMethods + remove export\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/fast-stable-stringify@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/fast-stable-stringify@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/codecs-strings@2.0.0-rc.0\n    - @solana/fast-stable-stringify@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/fast-stable-stringify@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`5ed19c6`](https://github.com/solana-labs/solana-web3.js/commit/5ed19c6c3c6e7a1bacde8c23c438ecb85454b126), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83)]:\n    - @solana/fast-stable-stringify@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/codecs-strings@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-graphql/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-graphql/README.md",
    "content": "# @solana/rpc-graphql\n\nThis package defines a GraphQL client resolver built on top of the\n[Solana JSON-RPC](https://docs.solana.com/api/http).\n\nA client resolver in this context is simply a client-side RPC interface\ndesigned to give application developers the ability to use GraphQL to interact\nwith data on the Solana blockchain.\n\nThe resolver presents developers with a new schema for working with Solana data\n(see [Schema](#schema)), as well as new features only possible with GraphQL.\nAdditionally, the resolver is designed to make highly-optimized use of the\nSolana JSON RPC, balancing RPC requests, batch loading, and caching\n(see [RPC Optimizations](#rpc-optimizations)).\n\nGraphQL is a query language for your API, and a server-side runtime for\nexecuting queries using a type system you define for your data.\n\n<img src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/GraphQL_Logo.svg/1024px-GraphQL_Logo.svg.png?20161105194737\" alt=\"graphql-icon\" width=\"24\" align=\"center\"/> [**GraphQL**](https://graphql.org/learn/)\n\n# Quick Start\n\nThe RPC-GraphQL client requires an RPC client, as defined by the package\n`@solana/rpc-spec`. Such a client is available in `@solana/kit:2.0` or\ncan be created manually with a custom implementation.\n\n```ts\nRpc<TRpcMethods>;\n```\n\nThe RPC-GraphQL requires an RPC client with the following API methods available\nfor use in order to properly execute all queries.\n\n```ts\nRpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>;\n```\n\nTo initialize the RPC-GraphQL client, simple use `createSolanaRpcGraphQL`.\n\n```ts\nimport { createSolanaRpc } from '@solana/rpc';\n\n// Create the RPC client\nconst rpc = createSolanaRpc('https://api.devnet.solana.com');\n\n// Create the RPC-GraphQL client\nconst rpcGraphQL = createSolanaRpcGraphQL(rpc);\n```\n\nThe `RpcGraphQL` type supports one method `query` which accepts a string\nquery source and an optional `variableValues` parameter - which is an object\ncontaining any variables to pipe into the query string.\n\nYou can define queries with hard-coded parameters.\n\n```ts\nconst source = `\n    query myQuery {\n        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n            lamports\n        }\n    }\n`;\n\nconst result = await rpcGraphQL.query(source);\n```\n\n```\ndata: {\n    account: {\n        lamports: 10290815n,\n    },\n}\n```\n\nYou can also pass the variable values.\n\n```ts\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            lamports\n        }\n    }\n`;\n\nconst variableValues = {\n    address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    account: {\n        lamports: 10290815n,\n    },\n}\n```\n\nQueries with variable values can also be re-used!\n\n```ts\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            lamports\n        }\n    }\n`;\n\nconst lamportsAccountA = await rpcGraphQL.query(source, {\n    address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n});\n\nconst lamportsAccountB = await rpcGraphQL.query(source, {\n    address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n});\n```\n\n# Schema\n\nSolana data can be categorized into three main types:\n\n- Accounts\n- Transactions\n- Blocks\n\nThese types encompass everything that can be queried from the Solana ledger.\n\n## Accounts\n\nThe `Account` interface contains common fields across all accounts.\n\n```graphql\ninterface Account {\n    address: Address\n    data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n    executable: Boolean\n    lamports: BigInt\n    ownerProgram: Account\n    space: BigInt\n}\n```\n\nAny account can be queried by these fields without specifying the specific\naccount type.\n\n```ts\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            executable\n            lamports\n        }\n    }\n`;\n\nconst variableValues = {\n    address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    account: {\n        executable: false,\n        lamports: 10290815n,\n    },\n}\n```\n\n### Querying Account Data\n\nQuerying accounts by their encoded data (`base58`, `base64`, `base64+zstd`) is\nstill fully supported.\n\n```ts\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            data(encoding: BASE_64)\n        }\n    }\n`;\n\nconst variableValues = {\n    address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    account: {\n        data: 'dGVzdCBkYXRh',\n    },\n}\n```\n\n### Querying Specific Account Types\n\nA set of specific parsed account types are supported in GraphQL.\n\n- `GenericAccount`: A generic base account type\n- `NonceAccount`: A nonce account\n- `LookupTableAccount`: An address lookup table account\n- `MintAccount`: An SPL mint\n- `TokenAccount`: An SPL token account\n- `StakeAccount`: A stake account\n- `VoteAccount`: A vote account\n\nYou can choose how to handle querying of specific account types. For example,\nyou might _only_ want specifically any account that matches `MintAccount`.\n\n```ts\nconst maybeMintAddresses = [\n    'J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ',\n    'JAbWqZ7S2c6jomQr8ofAYBo257bE1QJtHwbX1yWc2osZ',\n    '2AQ4CSNu6zNUZsUq4aLNUSjyrLv4qFFXQuKs5RTHbg2Y',\n    'EVW3CoyogapBfQxBFFEKGMM1bn3JyoFiqkAJdw3FHX1b',\n];\n\nconst mintAccounts = [];\n\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            ... on MintAccount {\n                data {\n                    decimals\n                    isInitialized\n                    mintAuthority\n                    supply\n                }\n            }\n        }\n    }\n`;\n\nfor (const address of maybeMintAddresses) {\n    const result = await rpcGraphQL.query(source, { address });\n    if (result != null) {\n        const {\n            data: {\n                account: { data: mintInfo },\n            },\n        } = result;\n        mintAccounts.push(mintInfo);\n    }\n}\n```\n\nMaybe you want to handle both mints _and_ token accounts.\n\n```ts\nconst mintOrTokenAccountAddresses = [\n    'J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ',\n    'JAbWqZ7S2c6jomQr8ofAYBo257bE1QJtHwbX1yWc2osZ',\n    '2AQ4CSNu6zNUZsUq4aLNUSjyrLv4qFFXQuKs5RTHbg2Y',\n    'EVW3CoyogapBfQxBFFEKGMM1bn3JyoFiqkAJdw3FHX1b',\n];\n\nconst mintAccounts = [];\nconst tokenAccounts = [];\n\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            ... on MintAccount {\n                __typename\n                decimals\n                isInitialized\n                supply\n            }\n            ... on TokenAccount {\n                __typename\n                isNative\n                mint\n                state\n            }\n        }\n    }\n`;\n\nfor (const address of mintOrTokenAccountAddresses) {\n    const result = await rpcGraphQL.query(source, { address });\n    if (result != null) {\n        const {\n            data: { account: accountParsedData },\n        } = result;\n        if (accountParsedData.__typename === 'MintAccount') {\n            mintAccounts.push(accountParsedInfo);\n        } else {\n            tokenAccounts.push(accountParsedInfo);\n        }\n    }\n}\n```\n\n### Querying Program Accounts\n\nAnother account-based query that can be performed with RPC-GraphQL is the\n`programAccounts` query. The response will be a list of `Account` types as\ndefined above.\n\n```ts\nconst source = `\n    query myQuery($programAddress: String!) {\n        programAccounts(programAddress: $address) {\n            executable\n            lamports\n        }\n    }\n`;\n\nconst variableValues = {\n    programAddress: 'AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    programAccounts: [\n        {\n            executable: false,\n            lamports: 10290815n,\n        },\n        {\n            executable: false,\n            lamports: 10290815n,\n        },\n        /* .. */\n    ]\n}\n```\n\nAccount data encoding in `base58`, `base64`, and `base64+zstd` is also\nsupported with this query, as well as `dataSlice` and `filter`.\n\n```ts\nconst source = `\n    query myQuery($programAddress: String!) {\n        programAccounts(programAddress: $programAddress) {\n            data(encoding: BASE_64, dataSlice: { length: 5, offset: 0 })\n        }\n    }\n`;\n\nconst variableValues = {\n    programAddress: 'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    programAccounts: [\n        {\n            data: 'dGVzdCA=',\n        },\n        /* .. */\n    ],\n}\n```\n\nAlthough specific parsed account types are directly tied to the program which\nowns them, it's still possible to handle various specific account types within\nthe same program accounts response.\n\n```ts\nconst source = `\n    query myQuery($programAddress: String!) {\n        programAccounts(programAddress: $address) {\n            ... on MintAccount {\n                __typename\n                decimals\n                isInitialized\n                mintAuthority\n                supply\n            }\n            ... on TokenAccount {\n                __typename\n                isNative\n                mint\n                owner\n                state\n            }\n        }\n    }\n`;\n\nconst variableValues = {\n    programAddress: 'AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n\nconst { mints, tokenAccounts } = result.data.programAccounts.reduce(\n    (acc: { mints: any[]; tokenAccounts: any[] }, account) => {\n        if (account.__typename === 'MintAccount') {\n            acc.mints.push(accountParsedInfo);\n        } else {\n            acc.tokenAccounts.push(accountParsedInfo);\n        }\n        return acc;\n    },\n    { mints: [], tokenAccounts: [] },\n);\n```\n\n### Nested Account Queries\n\nNotice the `owner` field of the `Account` interface is also an `Account`\ninterface. This powers nested queries against the `owner` field of an account.\n\n```ts\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            address\n            owner {\n                address\n                executable\n                lamports\n            }\n        }\n    }\n`;\n\nconst variableValues = {\n    address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    account: {\n        address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n        owner: {\n            address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n            executable: true,\n            lamports: 10290815n,\n        },\n    },\n}\n```\n\nAs you can see, simply defining a nested query with RPC-GraphQL will augment\nthe multiple RPC calls and parsing code required to gather the necessary\ninformation!\n\nYou can nest queries as far as you want!\n\n```ts\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            address\n            owner {\n                address\n                owner {\n                    address\n                    owner {\n                        address\n                    }\n                }\n            }\n        }\n    }\n`;\n\nconst variableValues = {\n    address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    account: {\n        address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n        owner: {\n            address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n            owner: {\n                address: 'BPFLoader2111111111111111111111111111111111',\n                owner: {\n                    address: 'NativeLoader1111111111111111111111111111111',\n                },\n            },\n        },\n    },\n}\n```\n\nNested queries can also be applied to specific account types.\n\n```ts\nconst source = `\n    query myQuery($address: String!) {\n        account(address: $address) {\n            ... on MintAccount {\n                address\n                data {\n                    mintAuthority {\n                        address\n                        lamports\n                    }\n                }\n            }\n        }\n    }\n`;\n\nconst variableValues = {\n    address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    account: {\n        address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n        data: {\n            mintAuthority: {\n                address: 'DpfJkNonoVB3sor9H9ceajhex4XHVPrDAGAq2ahdG4JZ',\n                lamports: 10290815n,\n            }\n        },\n    },\n}\n```\n\nNested account queries are also supported on `programAccounts` queries.\n\n## Transactions\n\nThe `Transaction` type contains common fields across all transactions.\n\n```graphql\ntype Transaction {\n    blockTime: BigInt\n    data(encoding: TransactionEncoding!): String\n    message: TransactionMessage\n    meta: TransactionMeta\n    signatures: [Signature]\n    slot: Slot\n    version: String\n}\n```\n\nNote that unlike accounts, the `Transaction` type is not an interface, so the\nbase response type of a transaction query remains constant. However, the list\nof instructions contained in a parsed transaction are returned as the\n`TransactionInstruction` interface, which can be queried by specific type.\nSee [Querying Specific Transaction Instruction Types](#querying-specific-transaction-instruction-types).\n\n```graphql\ninterface TransactionInstruction {\n    programId: Address\n}\n```\n\nA transaction can be queried by the `transaction` query.\n\n```ts\nconst source = `\n    query myQuery($signature: String!) {\n        transaction(signature: $signature) {\n            blockTime\n            meta {\n                computeUnitsConsumed\n                logMessages\n            }\n            slot\n        }\n    }\n`;\n\nconst variableValues = {\n    signature: '63zkpxATgAwXRGFQZPDESTw2m4uZQ99sX338ibgKtTcgG6v34E3MSS3zckCwJHrimS71cvei6h1Bn1K1De53BNWC',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    transaction: {\n        blockTime: 230860412n,\n        meta: {\n            computeUnitsConsumed: 120000n,\n            logMessages: [\n                \"Program 8tfDNiaEyrV6Q1U4DEXrEigs9DoDtkugzFbybENEbCDz invoke [1]\",\n                \"Program 8tfDNiaEyrV6Q1U4DEXrEigs9DoDtkugzFbybENEbCDz consumed 2164 of 452155 compute units\",\n                \"Program 8tfDNiaEyrV6Q1U4DEXrEigs9DoDtkugzFbybENEbCDz success\",\n                \"Program ComputeBudget111111111111111111111111111111 invoke [1]\",\n                \"Program ComputeBudget111111111111111111111111111111 success\"\n            ]\n        },\n        slot: 230860693n,\n    },\n}\n```\n\n### Querying Transaction Data\n\nQuerying encoded transaction data (`base58`, `base64`) is fully supported.\n\n```ts\nconst source = `\n    query myQuery($signature: String!, $commitment: Commitment) {\n        transaction(signature: $signature, commitment: $commitment) {\n            data(encoding: BASE_64)\n        }\n    }\n`;\n\nconst variableValues = {\n    signature: '63zkpxATgAwXRGFQZPDESTw2m4uZQ99sX338ibgKtTcgG6v34E3MSS3zckCwJHrimS71cvei6h1Bn1K1De53BNWC',\n    commitment: 'confirmed',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\n{\n  \"data\": {\n    \"transaction\": {\n      \"data\": \"AbgFjqLTBtoAaHXexSN1OYXf+UNox6qe3JcyCmEwE57iUHxCkHp8zKTJVznd6nLtUFNMYJWHCtMb+yPjk7QIxAQBAAEDeXJtpS2Z1gsH6tc7L28L9gg8yFx3qU401pHXj4vK/skUvD7y/LnapfCdSx3FfTguy49UDQVvGgOK0ix/P42YuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5uE0ATTHEABQrIB1+aoEdYJxvQthXPLHFxSH2y+ACK4BAgIAAQwCAAAAAMqaOwAAAAA=\"\n    }\n  }\n}\n```\n\n### Querying Specific Transaction Instruction Types\n\nAs mentioned above, parsed transactions return a list of instructions that\nimplement the `TransactionInstruction` interface. These instructions can be\nqueried by specific instruction types.\n\nInstructions for the following programs are supported.\n\n- Address Lookup Table\n- BPF Loader\n- BPF Upgradeable Loader\n- Stake\n- SPL Associated Token\n- SPL Memo\n- SPL Token\n- System\n- Vote\n\nAdditionally, the `GenericInstruction` type is the base parsed instruction type.\n\n```graphql\ntype GenericInstruction implements TransactionInstruction {\n    accounts: [Address]\n    data: Base64EncodedBytes\n    programId: Address\n}\n```\n\nSpecific transaction instruction types can be queried within a `Transaction`\nresponse like so.\n\n```ts\nconst source = `\n    query myQuery($signature: String!, $commitment: Commitment) {\n        transaction(signature: $signature, commitment: $commitment) {\n            message {\n                instructions {\n                    ... on CreateAccountInstruction {\n                        lamports\n                        programId\n                        space\n                    }\n                }\n            }\n        }\n    }\n`;\n\nconst variableValues = {\n    signature: '63zkpxATgAwXRGFQZPDESTw2m4uZQ99sX338ibgKtTcgG6v34E3MSS3zckCwJHrimS71cvei6h1Bn1K1De53BNWC',\n    commitment: 'confirmed',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    transaction: {\n        message: {\n            instructions: [\n                {\n                    lamports: 890880n,\n                    programId: '11111111111111111111111111111111',\n                    space: 0n,\n                },\n                /* .. */\n            ]\n        },\n    },\n}\n```\n\n### Nested Transaction Queries\n\nSince transactions have a relatively large number of data points, they are\nparticularly useful for nested queries!\n\nSimilar to nested querying accounts, it's possible to nest queries inside your\ntransaction queries to look up other objects, such as accounts, as they appear\nin the transaction response.\n\n```ts\nconst source = `\n    query myQuery($signature: String!, $commitment: Commitment) {\n        transaction(signature: $signature, commitment: $commitment) {\n            message {\n                instructions {\n                    ... on SplTokenTransferInstruction {\n                        amount\n                        authority {\n                            # Account\n                            address\n                            lamports\n                        }\n                        destination {\n                            # Account\n                            ... on TokenAccount {\n                                address\n                                mint {\n                                    ... on MintAccount {\n                                        # Account\n                                        address\n                                        decimals\n                                    }\n                                }\n                                owner {\n                                    # Account\n                                    address\n                                    lamports\n                                }\n                            }\n                        }\n                        source {\n                            # Account\n                            ... on TokenAccount {\n                                address\n                                mint {\n                                    ... on MintAccount {\n                                        # Account\n                                        address\n                                        decimals\n                                    }\n                                }\n                                owner {\n                                    # Account\n                                    address\n                                    lamports\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n`;\n\nconst variableValues = {\n    signature: '63zkpxATgAwXRGFQZPDESTw2m4uZQ99sX338ibgKtTcgG6v34E3MSS3zckCwJHrimS71cvei6h1Bn1K1De53BNWC',\n    commitment: 'confirmed',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    transaction: {\n        message: {\n            instructions: [\n                {\n                    amount: '50',\n                    authority: {\n                        address: 'AHPPMhzDQix9sKULBqeaQ5BUZgrKdz8tg6DzPxsofB12',\n                        lamports: 890880n,\n                    },\n                    destination: {\n                        address: '2W8mUY75zxqwAcpirn75r3Cc7TStMirFyHwKqo13fmB1',\n                        mint: {\n                            address: '8poKMotB2cEYVv5sbjrdyssASZj1vwYCe7GJFeXo2QP7',\n                            decimals: 6,\n                        },\n                        owner: {\n                            address: '7tRxJ2znbTFpwW9XaMMiDsXDudoPEUXRcpDpm8qjWgAZ',\n                            lamports: 890880n,\n                        }\n                    },\n                    source: {\n                        address: 'BqFCPqXUm4cq6jaZZx1TDTvUR1wdEuNNwAHBEVR6mJhM',\n                        mint: {\n                            address: '8poKMotB2cEYVv5sbjrdyssASZj1vwYCe7GJFeXo2QP7',\n                            decimals: 6,\n                        },\n                        owner: {\n                            address: '3dPmVLMD7PC5faZNyJUH9WFrUxAsbjydJfoozwmR1wDG',\n                            lamports: e890880n,\n                        }\n                    }\n                },\n                /* .. */\n            ]\n        }\n    }\n}\n```\n\n## Blocks\n\nThe `Block` type contains common fields across all blocks.\n\n```graphql\ntype Block {\n    blockhash: String\n    blockHeight: BigInt\n    blockTime: BigInt\n    parentSlot: Slot\n    previousBlockhash: String\n    rewards: [Reward]\n    signatures: [Signature]\n    transactions: [Transaction]\n}\n```\n\nJust like the `programAccounts` query will return a list of `Account` types, on\nwhich you can perform many operations, the `block` query will return a list of\n`Transaction` types, however blocks also contain their own high-level data\nfields, such as `blockhash` and `blockTime`.\n\n```ts\nconst source = `\n    query myQuery($slot: BigInt!, $commitment: Commitment) {\n        block(slot: $slot, commitment: $commitment) {\n            blockHeight\n            blockhash\n            parentSlot\n            rewards {\n                commission\n                lamports\n                rewardType\n            }\n            transactions {\n                message {\n                    instructions {\n                        ... on CreateAccountInstruction {\n                            lamports\n                            programId\n                            space\n                        }\n                    }\n                }\n            }\n        }\n    }\n`;\n\nconst variableValues = {\n    slot: 43596n,\n    commitment: 'confirmed',\n};\n\nconst result = await rpcGraphQL.query(source, variableValues);\n```\n\n```\ndata: {\n    block: {\n        blockHeight: 196758578n,\n        blockhash: 'BqFCPqXUm4cq6jaZZx1TDTvUR1wdEuNNwAHBEVR6mJhM',\n        parentSlot: 230862408n,\n        rewards: [\n            {\n                commission: 0.05,\n                lamports: 58578n,\n                rewardType: 'Staking',\n            },\n            {\n                commission: 0.05,\n                lamports: 58578n,\n                rewardType: 'Staking',\n            }\n        ],\n        transactions: [\n            {\n                message: {\n                    instructions: [\n                        {\n                            lamports: 890880n,\n                            programId: '11111111111111111111111111111111',\n                            space: 0n,\n                        },\n                        /* .. */\n                    ]\n                },\n            }\n        ],\n    },\n}\n```\n\n# RPC Optimizations\n\nRPC-GraphQL ships highly-optimized use of the Solana JSON RPC out of the box,\nso developers can focus on building dynamic web applications without worrying\nabout abusing their RPC endpoint.\n\nThe resolver leverages query inspection before making any requests to the RPC,\nin order to determine the most resource-conservative way to vend to your\napplication the requested response.\n\nThis results in four main benefits:\n\n- Caching\n- Request coalescing\n- Minimized network payloads\n- Batch loading\n\n## Caching\n\nCaching is a fairly standard part of any good GraphQL library, and\n`@solana/rpc-graphql` makes no exception.\n\nIf a query contains fetches for the same resource, the resolver can simply\nfetch this information from the cache, ensuring no duplicate RPC requests\nare ever made.\n\nFor example, if we were to query for a `MintAccount` and the `mintAuthority`\nalso happened to be the mint itself, the following query would ensure we only\nfetch this account once.\n\n```graphql\nquery {\n    account(address: \"J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ\") {\n        lamports\n        data(encoding: BASE_64)\n        ... on MintAccount {\n            mintAuthority {\n                lamports\n                data(encoding: BASE_64)\n            }\n        }\n    }\n}\n```\n\n## Request Coalescing\n\nSometimes more than one request can be coalesced into the same request, again\nsaving on network round-trips.\n\nIn the example below, we're making two queries for the same account, but\ndifferent fields.\n\n```graphql\nquery {\n    account(address: \"J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ\") {\n        lamports\n        space\n    }\n    account(address: \"J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ\") {\n        ... on NonceAccount {\n            authority {\n                address\n            }\n            blockhash\n            feeCalculator {\n                lamportsPerSignature\n            }\n        }\n    }\n}\n```\n\nRather than requesting this account twice, the resolver will combine these\ntwo queries into the same RPC request, and then split the response out to the\ncorresponding query results.\n\n## Minimized Network Payloads\n\nWhen it comes to retrieving data from an RPC endpoint, fetching more\ninformation than you need can be a significant waste of network resources, and\neven impact application performance.\n\nThe RPC-GraphQL resolver takes steps to minimize this network overhead based on\nthe contents of the query provided.\n\nFor example, in the following `account` query, we're going to request multiple\nresponses for `base64` encoded data on the same account.\n\n```graphql\nquery {\n    account(address: \"J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ\") {\n        firstEightBytes: data(encoding: BASE_64, dataSlice: { length: 8, offset: 0 })\n        nextEightBytes: data(encoding: BASE_64, dataSlice: { length: 8, offset: 8 })\n        anotherEightBytes: data(encoding: BASE_64, dataSlice: { length: 8, offset: 16 })\n    }\n}\n```\n\nTo gather this information, a developer may elect for one of two solutions:\n\n1. Call the RPC three times with each data slice. This will result in `3n`\n   requests where `n` is the number of times your application may invoke this\n   query.\n2. Call the RPC once for the data, convert from `base64` to raw bytes, slice\n   the raw bytes, then encode each subset back to `base64`. This requires a lot\n   of overhead on application development.\n\nRPC-GraphQL will perform solution two for you automatically, choosing to save\non network calls and bytes over the wire in favor of slicing the returned data\nlocally.\n\nIn fact, the resolver will minimize bytes over the wire by only requesting the\nspecific slice of the data that encompasses all requested data slices. In the\nabove example, we've requested three ranges of data:\n\n- `0` - `8`\n- `8` - `16`\n- `16` - `24`\n\nIf this account has a massive amount of data, fetching more than the query asks\nfor would be wasteful. The resolver will only fetch `0` - `24` and slice the\nresponse to serve the requested query.\n\n## Batch Loading\n\nIn some cases, the Solana JSON RPC offers batch loading for certain data types.\nOne such example is the RPC methods `getAccountInfo` and `getMultipleAccounts`.\n\nAs one might predict, whenever multiple accounts are requested with parameters\nthat can be coalesced, one single call to `getMultipleAccounts` can be made.\n\nIn the example above from [Request Coalescing](#request-coalescing), let's\nsimply change the query to request two different accounts.\n\n```graphql\nquery {\n    account(address: \"J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ\") {\n        lamports\n        space\n    }\n    account(address: \"EVW3CoyogapBfQxBFFEKGMM1bn3JyoFiqkAJdw3FHX1b\") {\n        ... on NonceAccount {\n            authority {\n                address\n            }\n            blockhash\n            feeCalculator {\n                lamportsPerSignature\n            }\n        }\n    }\n}\n```\n\nNow the resolver would recognize the distinction between the two accounts, but\nit would still see the ability to coalesce request parameters. As a result,\nRPC-GraphQL would make one call to `getMultipleAccounts` as follows.\n\n```ts\nrpc.getMultipleAccounts([\n    'J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ',\n    'EVW3CoyogapBfQxBFFEKGMM1bn3JyoFiqkAJdw3FHX1b',\n]);\n```\n\nThis batch loading can work in conjunction with the other forms of\noptimization as well, such as minimized network payloads.\n\n```graphql\nquery {\n    account(address: \"J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ\") {\n        data(encoding: BASE_64, dataSlice: { length: 32, offset: 0 })\n    }\n    account(address: \"EVW3CoyogapBfQxBFFEKGMM1bn3JyoFiqkAJdw3FHX1b\") {\n        authorityData: data(encoding: BASE_64, dataSlice: { length: 32, offset: 0 })\n        u64Data: data(encoding: BASE_64, dataSlice: { length: 8, offset: 32 })\n    }\n}\n```\n\n```ts\nrpc.getMultipleAccounts(\n    ['J7iup799j5BVjKXACZycYef7WQ4x1wfzhUsc5v357yWQ', 'EVW3CoyogapBfQxBFFEKGMM1bn3JyoFiqkAJdw3FHX1b'],\n    {\n        encoding: 'base64',\n        dataSlice: { length: 40, offset: 0 },\n    },\n);\n```\n\nIn this case the resolver would ensure the proper data slices are dealt out\nfrom the single `getMultipleAccounts` response.\n"
  },
  {
    "path": "packages/rpc-graphql/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-graphql\",\n    \"version\": \"6.9.0\",\n    \"description\": \"A library for resolving GraphQl query calls to the Solana JSON RPC API\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-graphql\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@graphql-tools/schema\": \"^10.0.33\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/fast-stable-stringify\": \"workspace:*\",\n        \"dataloader\": \"^2.2.3\",\n        \"graphql\": \"^16.14.0\"\n    },\n    \"devDependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/rpc\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-graphql/src/__tests__/__setup__.ts",
    "content": "/* eslint-disable sort-keys-fix/sort-keys-fix */\n\nimport { createDefaultRpcTransport, createRpc, createSolanaRpcApi, Rpc, SolanaRpcApi } from '@solana/rpc';\n\nexport function createLocalhostSolanaRpc(): Rpc<SolanaRpcApi> {\n    return createRpc({\n        api: createSolanaRpcApi(),\n        transport: createDefaultRpcTransport({ url: 'http://127.0.0.1:8899' }),\n    });\n}\n\nexport const mockTransactionBase58 = {\n    blockTime: 1699617771,\n    meta: {\n        computeUnitsConsumed: 2100,\n        err: null,\n        fee: 5000,\n        innerInstructions: [],\n        loadedAddresses: {\n            readonly: [],\n            writable: [],\n        },\n        logMessages: [\n            'Program Vote111111111111111111111111111111111111111 invoke [1]',\n            'Program Vote111111111111111111111111111111111111111 success',\n        ],\n        postBalances: [1007369134736714, 100000000000, 1],\n        postTokenBalances: [],\n        preBalances: [1007369134741714, 100000000000, 1],\n        preTokenBalances: [],\n        rewards: [],\n        status: {\n            Ok: null,\n        },\n    },\n    slot: 257316391,\n    transaction: [\n        '6xNkTPi3A4y1wBWWx5ju992mhhQed8f7PvKdVC5TExCBVPsFKQREWEKEw7FH1sTtcTRBzfsbaKMwkToPGAh9Vux71etguU9F1zbPWcu4jm9R89JvfBHqgy6HNJxuP1bwGLjEVkCAU5mJXj2AwwY6rn6wbBGJk4vo8G6gpVUtXbctbF1ovKt2BitBzPdfwGF6oXkFCddPtj1YjQinNqhdCv56Wd2NeB6xhTKqDUhEfiyoqdvmEPAYsSqtfiiGRocWQCbu18r3jzT7bVRHPPVM7dXKJeV7sEvoxkmMPMrk7EcYBjeFGaJCaLnjizzb2T7sdaHQQQD5EwRPHLrUoKC5dZ6bkRLopbtzaWE9jAyCWJFUYCvNAkgDJbxHub3dgRdar6uDiKvBz5ZP3SW2KgbcfjeLpx6eq4NByyUuWfyNxEGgVnUiVLB',\n        'base58',\n    ],\n};\n\nexport const mockTransactionBase64 = {\n    blockTime: 1699617771,\n    meta: {\n        computeUnitsConsumed: 2100,\n        err: null,\n        fee: 5000,\n        innerInstructions: [],\n        loadedAddresses: {\n            readonly: [],\n            writable: [],\n        },\n        logMessages: [\n            'Program Vote111111111111111111111111111111111111111 invoke [1]',\n            'Program Vote111111111111111111111111111111111111111 success',\n        ],\n        postBalances: [1007369134736714, 100000000000, 1],\n        postTokenBalances: [],\n        preBalances: [1007369134741714, 100000000000, 1],\n        preTokenBalances: [],\n        rewards: [],\n        status: {\n            Ok: null,\n        },\n    },\n    slot: 257316391,\n    transaction: [\n        'AepkROU+YmVQzntENpmquZ1qpkha7UFbM7otQT4fBnBGj9jnh0Ajpi5udBvmgy0Xl+oHCVoVBmyb6Sefe62OPAABAAEDCXTeVPd6+prT1HSQn2zglbliOjWaXQjMgHuKkt1eH5YKiAaVN9osvzAWT9Si70lMmML05TxzF4KLoavohN5bhAdhSB01dHS7fE12JOvTvbPYNV5z0RBD/A2jU4AAAAAAagAuoluUJsP7XqnRIG7xK7Enle/1dyqE6zCdyAUQJ08BAgIBAHQMAAAAB1ZWDwAAAAAfAR8BHgEdARwBGwEaARkBGAEXARYBFQEUARMBEgERARABDwEOAQ0BDAELAQoBCQEIAQcBBgEFAQQBAwECAQHSQS4WTFXgfy7GPfwboTLrsk3OHMs3lPgWrEMfMaT3sQHrG05lAAAAAA==',\n        'base64',\n    ],\n};\n\nexport const mockTransactionGeneric = {\n    blockTime: 1699618507,\n    meta: {\n        computeUnitsConsumed: 53355,\n        err: null,\n        fee: 5000,\n        innerInstructions: [],\n        logMessages: [\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4263 of 480000 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4461 of 475737 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4504 of 471276 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4600 of 466772 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4213 of 462172 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4390 of 457959 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4392 of 453569 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4703 of 449177 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4509 of 444474 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4240 of 439965 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4471 of 435725 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s invoke [1]',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s consumed 4459 of 431254 compute units',\n            'Program gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s success',\n            'Program ComputeBudget111111111111111111111111111111 invoke [1]',\n            'Program ComputeBudget111111111111111111111111111111 success',\n        ],\n        postBalances: [\n            113383490000, 23942400, 23942400, 23942400, 23942400, 23942400, 23942400, 23942400, 23942400, 23942400,\n            23942400, 23942400, 23942400, 1, 1169280, 1141440,\n        ],\n        postTokenBalances: [],\n        preBalances: [\n            113383495000, 23942400, 23942400, 23942400, 23942400, 23942400, 23942400, 23942400, 23942400, 23942400,\n            23942400, 23942400, 23942400, 1, 1169280, 1141440,\n        ],\n        preTokenBalances: [],\n        rewards: [],\n        status: {\n            Ok: null,\n        },\n    },\n    slot: 257318391,\n    transaction: {\n        message: {\n            accountKeys: [\n                {\n                    pubkey: 'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '3LuSbvThg5STSvcqTFNG74pifPs9cz2kT6msLA7trkiz',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '3uwrCNiVJrUU4AfUyoAABHLMGgdtzR6Fnk9LFrAudcUd',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '4JnBkEHGCS86CkrLSkZiLWYFfVtsvUhXGd7BYF1pQk2T',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '5SSkXsEKQepHHAewytPVwdej4epN1nxgLVM84L4KXgy7',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '6FnzHuB86M4FVp4UPzgYHb9xi9SxhFcpd1YFnmKKSzhh',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'BfrLgSZLBNpWvytEcurngBFdkbEP5YMyjTgs8gb9DLMM',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'CbemEDzti5Vdh5JdT6Vj7cGEDfSLvvVyNRPveMGrt45z',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'DLs1QkLjp92HGRU899J6eNjBn7VK3cLGg8NhMpqfJMjU',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'DMyZyzfNR1uhqYcFGrNftirkveCbyNVLnCB8HgShYz4V',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'Eag4Uc8nrEfwyXykuoBwCaigW1oQu9DkuiAwr6qkw9QK',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'EfCD8rMxH7rUNo8A5AXmqvdXfgTCL5V8hAtSDW49KePb',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'HYEgRDsZVSzPzZor1RaeUicaKBQcGGxgf1MCn9KUtaqA',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'ComputeBudget111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'SysvarC1ock11111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n            ],\n            instructions: [\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        'DMyZyzfNR1uhqYcFGrNftirkveCbyNVLnCB8HgShYz4V',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwo7gRuVPWDv2unmQd4jq8zWK3wQZG54k2b',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        'CbemEDzti5Vdh5JdT6Vj7cGEDfSLvvVyNRPveMGrt45z',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwujWTHqRu8S9Jpua28JRHAfiNoVwoQUqwV',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        '6FnzHuB86M4FVp4UPzgYHb9xi9SxhFcpd1YFnmKKSzhh',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwrzrkWH6hYPqjdWj5udRaTyxZzQpJ1CLpP',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        '3uwrCNiVJrUU4AfUyoAABHLMGgdtzR6Fnk9LFrAudcUd',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwbtf9bEjkQBS9YADJiEpsmFLPiPiXUB1fd',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        'HYEgRDsZVSzPzZor1RaeUicaKBQcGGxgf1MCn9KUtaqA',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwbgw281VXtZiGZpkiRGPJjpLpufuRA2znK',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        '5SSkXsEKQepHHAewytPVwdej4epN1nxgLVM84L4KXgy7',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwbjdVM7NzaewBokEtqBPiz7sEUJG4uaXhq',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        '3LuSbvThg5STSvcqTFNG74pifPs9cz2kT6msLA7trkiz',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcweejgvAyYMaMZv5DHLeAKv4iDYvwXWst7R',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        'BfrLgSZLBNpWvytEcurngBFdkbEP5YMyjTgs8gb9DLMM',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwfCdRcjR1XiBBejZ8wWhawB14y76Fy3waX',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        'DLs1QkLjp92HGRU899J6eNjBn7VK3cLGg8NhMpqfJMjU',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwrS6dBfd33GmL7Uq6xuc6thGmeWXzyoSF1',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        'Eag4Uc8nrEfwyXykuoBwCaigW1oQu9DkuiAwr6qkw9QK',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwmFG26LaHMh1WU2xgzDpnFPNrmzhJ1jGUP',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        '4JnBkEHGCS86CkrLSkZiLWYFfVtsvUhXGd7BYF1pQk2T',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwxvsFAVu1Kh7RwbWACySGJGX5B6yPjkxHD',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'HUZu4xMSHbxTWbkXR6jkGdjvDPJLjrpSNXSoUFBRgjWs',\n                        'EfCD8rMxH7rUNo8A5AXmqvdXfgTCL5V8hAtSDW49KePb',\n                        'SysvarC1ock11111111111111111111111111111111',\n                    ],\n                    data: '6mJFQCt94hG4CKNYKgVcwt66hLszPZu81oa7B7FhnA8YmRE415Kdxj',\n                    programId: 'gSbePebfvPy7tRqimPoVecS2UsBvYv46ynrzWocc92s',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [],\n                    data: 'E6YYnj',\n                    programId: 'ComputeBudget111111111111111111111111111111',\n                    stackHeight: null,\n                },\n            ],\n            recentBlockhash: 'ETbinvUP8hqHssm4wHePZnEYupJncfuqn8YdY9uKkYow',\n        },\n        signatures: ['DC4yP5xEUhHuzSDq8fk2TznnMxy4DJm4M5qSzmnuPngLtnn8jH8qu4MEjmie2piiksEGwe98CawKUHuR7VQJ1Nt'],\n    },\n    version: 'legacy',\n};\n\nexport const mockTransactionAddressLookup = {\n    blockTime: 1699614307,\n    meta: {\n        computeUnitsConsumed: 1200,\n        err: null,\n        fee: 6600,\n        innerInstructions: [\n            {\n                index: 2,\n                instructions: [\n                    {\n                        parsed: {\n                            info: {\n                                destination: 'Dm8oknt7wHtvkVZKgQHtDFqgdHjL89cAoXyiPavK6DcU',\n                                lamports: 445440,\n                                source: '2fZT6MLRvvanGDWwP6ydAt1jkftDhSW7Du5Lo4uY314N',\n                            },\n                            type: 'transfer',\n                        },\n                        program: 'system',\n                        programId: '11111111111111111111111111111111',\n                        stackHeight: 2,\n                    },\n                ],\n            },\n        ],\n        logMessages: [\n            'Program ComputeBudget111111111111111111111111111111 invoke [1]',\n            'Program ComputeBudget111111111111111111111111111111 success',\n            'Program ComputeBudget111111111111111111111111111111 invoke [1]',\n            'Program ComputeBudget111111111111111111111111111111 success',\n            'Program AddressLookupTab1e1111111111111111111111111 invoke [1]',\n            'Program 11111111111111111111111111111111 invoke [2]',\n            'Program 11111111111111111111111111111111 success',\n            'Program AddressLookupTab1e1111111111111111111111111 success',\n        ],\n        postBalances: [998247520, 1726080, 1, 1, 1],\n        postTokenBalances: [],\n        preBalances: [998699560, 1280640, 1, 1, 1],\n        preTokenBalances: [],\n        rewards: [],\n        status: {\n            Ok: null,\n        },\n    },\n    slot: 257306980,\n    transaction: {\n        message: {\n            accountKeys: [\n                {\n                    pubkey: '2fZT6MLRvvanGDWwP6ydAt1jkftDhSW7Du5Lo4uY314N',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'Dm8oknt7wHtvkVZKgQHtDFqgdHjL89cAoXyiPavK6DcU',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'ComputeBudget111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'AddressLookupTab1e1111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: '11111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n            ],\n            addressTableLookups: [],\n            instructions: [\n                {\n                    accounts: [],\n                    data: '3QBcnUb9zKM9',\n                    programId: 'ComputeBudget111111111111111111111111111111',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [],\n                    data: 'Fj2Eoy',\n                    programId: 'ComputeBudget111111111111111111111111111111',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            lookupTableAccount: 'Dm8oknt7wHtvkVZKgQHtDFqgdHjL89cAoXyiPavK6DcU',\n                            lookupTableAuthority: '2fZT6MLRvvanGDWwP6ydAt1jkftDhSW7Du5Lo4uY314N',\n                            newAddresses: [\n                                '2fZT6MLRvvanGDWwP6ydAt1jkftDhSW7Du5Lo4uY314N',\n                                '11111111111111111111111111111111',\n                            ],\n                            payerAccount: '2fZT6MLRvvanGDWwP6ydAt1jkftDhSW7Du5Lo4uY314N',\n                            systemProgram: '11111111111111111111111111111111',\n                        },\n                        type: 'extendLookupTable',\n                    },\n                    program: 'address-lookup-table',\n                    programId: 'AddressLookupTab1e1111111111111111111111111',\n                    stackHeight: null,\n                },\n            ],\n            recentBlockhash: '2s1nPVeBAsh3cMuhyJxeZr3thiZiea8851pDYH3Py7mi',\n        },\n        signatures: ['2oitdwWTduGvnYJUzFg3e8vgeB3LnxXGxrWKGiYFyM5HRHQvtDmZKA7yf8emHZpw8NkqjwnFskBeYTy1W8Zv5eMR'],\n    },\n    version: 0,\n};\n\nexport const mockTransactionSystem = {\n    blockTime: 1699618622,\n    meta: {\n        computeUnitsConsumed: 284289,\n        err: null,\n        fee: 10000,\n        innerInstructions: [\n            {\n                index: 2,\n                instructions: [\n                    {\n                        parsed: {\n                            info: {\n                                extensionTypes: ['immutableOwner'],\n                                mint: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                            },\n                            type: 'getAccountDataSize',\n                        },\n                        program: 'spl-token',\n                        programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        stackHeight: 2,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                lamports: 2039280,\n                                newAccount: 'DNDx4t174ASMR7yNA5HQZppaU4WaAEQa3x1HphLHBDDU',\n                                owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                source: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                                space: 165,\n                            },\n                            type: 'createAccount',\n                        },\n                        program: 'system',\n                        programId: '11111111111111111111111111111111',\n                        stackHeight: 2,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                account: 'DNDx4t174ASMR7yNA5HQZppaU4WaAEQa3x1HphLHBDDU',\n                            },\n                            type: 'initializeImmutableOwner',\n                        },\n                        program: 'spl-token',\n                        programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        stackHeight: 2,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                account: 'DNDx4t174ASMR7yNA5HQZppaU4WaAEQa3x1HphLHBDDU',\n                                mint: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                                owner: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            },\n                            type: 'initializeAccount3',\n                        },\n                        program: 'spl-token',\n                        programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        stackHeight: 2,\n                    },\n                ],\n            },\n            {\n                index: 4,\n                instructions: [\n                    {\n                        parsed: {\n                            info: {\n                                amount: '1990000',\n                                authority: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                                destination: '7ZV4v2Q1krNiwmYvc7K4TzJ8jpK9HSW4wrH6W9ngSLH7',\n                                source: 'BeFuHRNFWT5q8qS5jF35awgFR88vtE33UWxDGxQrrJCZ',\n                            },\n                            type: 'transfer',\n                        },\n                        program: 'spl-token',\n                        programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        stackHeight: 2,\n                    },\n                    {\n                        accounts: [\n                            'CmakeM5y4gikp7GyTZRps2RwvC1qZ4HQNX1AwsRgwqrQ',\n                            'H6ojAjBeHu821EvH1sHggoxFq98wMBa9Ka99LMHgVie8',\n                            'Eo6HqnrR5mWoBuoksxQtzjL5A4txBEH8KCiTRykZPQn4',\n                            'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                            'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                            'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                            'CxST73mXAHuH5n18jZ3xFgthDot9XLJGWXfi2z6MBuqT',\n                            'GP1xRUzahZem3X2uh7pYZNTeryrQF1tDXRKH76FX1i1V',\n                            '5GCz3rtxi1LoWiozqXRMNvPWhybQgEdPwLrMKXH7Gm4E',\n                            'A5JSBNA1N824Y7ZtQ98oBUVNB6wjThTvbUCTQyHfK5NC',\n                            '3kDKLKbdEaVV2XnhdyshthzRYcknrLLk1Fizft7LcXAG',\n                            'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                            'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            '11111111111111111111111111111111',\n                            'SysvarS1otHashes111111111111111111111111111',\n                        ],\n                        data: '9ZxXEgRKtxM',\n                        programId: 'CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR',\n                        stackHeight: 2,\n                    },\n                    {\n                        accounts: [\n                            '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                            'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                            'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            'H6ojAjBeHu821EvH1sHggoxFq98wMBa9Ka99LMHgVie8',\n                            '11111111111111111111111111111111',\n                        ],\n                        data: '3LnyAmGDjLoXr8a2pYMDkNpLpnxQUUk5wW8Cnm6kva9LBqTwQxrmEfsSCjkD6cUtu1SygE2aRqPmFDx9bA3BESL1EVy6KVc7GPuGUruUcn254bRgJwwYDFL423L9mrRXeh9wLVk8H9s6MhX6qmMjM9Fu6Lw9No1oBXgvGPk1nxWXCAymTVKysqiu7Ys1ckhSKtTyMjY4sGtMsCWjt992DjfUBLoDgUHaw4m9M4zzVAUsMUgC6Svr1mzJAJ1Vu3FNMifMcdGPW3qmx7VS16oYEs1nmB28ey8X25XDfLmkrB',\n                        programId: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                        stackHeight: 3,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                destination: '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                                lamports: 15616720,\n                                source: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            },\n                            type: 'transfer',\n                        },\n                        program: 'system',\n                        programId: '11111111111111111111111111111111',\n                        stackHeight: 4,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                account: '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                                space: 679,\n                            },\n                            type: 'allocate',\n                        },\n                        program: 'system',\n                        programId: '11111111111111111111111111111111',\n                        stackHeight: 4,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                account: '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                                owner: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                            },\n                            type: 'assign',\n                        },\n                        program: 'system',\n                        programId: '11111111111111111111111111111111',\n                        stackHeight: 4,\n                    },\n                    {\n                        accounts: [\n                            'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                            'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                            'H6ojAjBeHu821EvH1sHggoxFq98wMBa9Ka99LMHgVie8',\n                            'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                            'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            '11111111111111111111111111111111',\n                        ],\n                        data: 'xQfWWpLr8ajWF',\n                        programId: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                        stackHeight: 3,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                destination: 'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                                lamports: 2853600,\n                                source: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            },\n                            type: 'transfer',\n                        },\n                        program: 'system',\n                        programId: '11111111111111111111111111111111',\n                        stackHeight: 4,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                account: 'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                                space: 282,\n                            },\n                            type: 'allocate',\n                        },\n                        program: 'system',\n                        programId: '11111111111111111111111111111111',\n                        stackHeight: 4,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                account: 'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                                owner: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                            },\n                            type: 'assign',\n                        },\n                        program: 'system',\n                        programId: '11111111111111111111111111111111',\n                        stackHeight: 4,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                authorityType: 'mintTokens',\n                                mint: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                                multisigAuthority: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                                newAuthority: 'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                                signers: ['AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r'],\n                            },\n                            type: 'setAuthority',\n                        },\n                        program: 'spl-token',\n                        programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        stackHeight: 4,\n                    },\n                    {\n                        parsed: {\n                            info: {\n                                authorityType: 'freezeAccount',\n                                mint: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                                multisigAuthority: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                                newAuthority: 'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                                signers: ['AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r'],\n                            },\n                            type: 'setAuthority',\n                        },\n                        program: 'spl-token',\n                        programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        stackHeight: 4,\n                    },\n                    {\n                        accounts: [\n                            '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                            'H6ojAjBeHu821EvH1sHggoxFq98wMBa9Ka99LMHgVie8',\n                        ],\n                        data: '3DhU62yedutwviTVGMfUJGHobmkNWvigVK7ZTMWwoUStEZuf8jH1',\n                        programId: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                        stackHeight: 3,\n                    },\n                    {\n                        accounts: [\n                            '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                            'H6ojAjBeHu821EvH1sHggoxFq98wMBa9Ka99LMHgVie8',\n                            'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            '3kDKLKbdEaVV2XnhdyshthzRYcknrLLk1Fizft7LcXAG',\n                            'GP1xRUzahZem3X2uh7pYZNTeryrQF1tDXRKH76FX1i1V',\n                            '5GCz3rtxi1LoWiozqXRMNvPWhybQgEdPwLrMKXH7Gm4E',\n                            'A5JSBNA1N824Y7ZtQ98oBUVNB6wjThTvbUCTQyHfK5NC',\n                            'CxST73mXAHuH5n18jZ3xFgthDot9XLJGWXfi2z6MBuqT',\n                        ],\n                        data: 'Z',\n                        programId: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                        stackHeight: 3,\n                    },\n                ],\n            },\n        ],\n        logMessages: [\n            'Program 11111111111111111111111111111111 invoke [1]',\n            'Program 11111111111111111111111111111111 success',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]',\n            'Program log: Instruction: InitializeMint',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2967 of 999850 compute units',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\n            'Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]',\n            'Program log: Create',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]',\n            'Program log: Instruction: GetAccountDataSize',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1622 of 991520 compute units',\n            'Program return: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA pQAAAAAAAAA=',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\n            'Program 11111111111111111111111111111111 invoke [2]',\n            'Program 11111111111111111111111111111111 success',\n            'Program log: Initialize the associated token account',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]',\n            'Program log: Instruction: InitializeImmutableOwner',\n            'Program log: Please upgrade to SPL Token 2022 for immutable owner support',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 1405 of 984880 compute units',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]',\n            'Program log: Instruction: InitializeAccount3',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4241 of 981000 compute units',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\n            'Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 20407 of 996883 compute units',\n            'Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL success',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [1]',\n            'Program log: Instruction: MintTo',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4536 of 976476 compute units',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\n            'Program Drop9NhG6Mm6oQmPnzr8FQP6rWaPiwFkin59SeAKApLc invoke [1]',\n            'Program log: Instruction: MintNft',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]',\n            'Program log: Instruction: Transfer',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4645 of 946736 compute units',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\n            'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR invoke [2]',\n            'Program log: Instruction: Mint',\n            'Program log: (Deprecated as of 1.0.0) Use MintV2 instead',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s invoke [3]',\n            'Program log: IX: Create Metadata Accounts v3',\n            'Program 11111111111111111111111111111111 invoke [4]',\n            'Program 11111111111111111111111111111111 success',\n            'Program log: Allocate space for the account',\n            'Program 11111111111111111111111111111111 invoke [4]',\n            'Program 11111111111111111111111111111111 success',\n            'Program log: Assign the account to the owning program',\n            'Program 11111111111111111111111111111111 invoke [4]',\n            'Program 11111111111111111111111111111111 success',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s consumed 42280 of 892008 compute units',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s success',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s invoke [3]',\n            'Program log: V3 Create Master Edition',\n            'Program log: Transfer 2853600 lamports to the new account',\n            'Program 11111111111111111111111111111111 invoke [4]',\n            'Program 11111111111111111111111111111111 success',\n            'Program log: Allocate space for the account',\n            'Program 11111111111111111111111111111111 invoke [4]',\n            'Program 11111111111111111111111111111111 success',\n            'Program log: Assign the account to the owning program',\n            'Program 11111111111111111111111111111111 invoke [4]',\n            'Program 11111111111111111111111111111111 success',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [4]',\n            'Program log: Instruction: SetAuthority',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3090 of 801966 compute units',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [4]',\n            'Program log: Instruction: SetAuthority',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 3250 of 795631 compute units',\n            'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s consumed 53370 of 844890 compute units',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s success',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s invoke [3]',\n            'Program log: IX: Update Metadata Accounts v2',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s consumed 18940 of 789213 compute units',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s success',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s invoke [3]',\n            'Program log: IX: Set and Verify Collection',\n            'Program log: Clean write collection metadata',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s consumed 43054 of 765463 compute units',\n            'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s success',\n            'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR consumed 205947 of 925016 compute units',\n            'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR success',\n            'Program Drop9NhG6Mm6oQmPnzr8FQP6rWaPiwFkin59SeAKApLc consumed 256229 of 971940 compute units',\n            'Program Drop9NhG6Mm6oQmPnzr8FQP6rWaPiwFkin59SeAKApLc success',\n        ],\n        postBalances: [\n            720480960, 1461600, 5616720, 2039280, 15616720, 2039280, 18144720, 2039280, 2853600, 10203360, 0, 1,\n            4108677884, 1224960, 2345520, 2853600, 731913600, 1141440, 1134480, 1141440, 1461600, 1141440, 1169280,\n            1009200, 143487360, 934087680,\n        ],\n        postTokenBalances: [\n            {\n                accountIndex: 3,\n                mint: 'HvCDUjehP8xNJfCGQxmTWQoEueYApaCL9sJTTBFeS3f4',\n                owner: '3kDKLKbdEaVV2XnhdyshthzRYcknrLLk1Fizft7LcXAG',\n                programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                uiTokenAmount: {\n                    amount: '1216420792',\n                    decimals: 6,\n                    uiAmount: 1216.420792,\n                    uiAmountString: '1216.420792',\n                },\n            },\n            {\n                accountIndex: 5,\n                mint: 'HvCDUjehP8xNJfCGQxmTWQoEueYApaCL9sJTTBFeS3f4',\n                owner: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                uiTokenAmount: {\n                    amount: '1068410181062',\n                    decimals: 6,\n                    uiAmount: 1068410.181062,\n                    uiAmountString: '1068410.181062',\n                },\n            },\n            {\n                accountIndex: 7,\n                mint: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                owner: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                uiTokenAmount: {\n                    amount: '1',\n                    decimals: 0,\n                    uiAmount: 1.0,\n                    uiAmountString: '1',\n                },\n            },\n        ],\n        preBalances: [\n            742462160, 0, 5616720, 2039280, 0, 2039280, 18144720, 0, 0, 10203360, 0, 1, 4108677884, 1224960, 2345520,\n            2853600, 731913600, 1141440, 1134480, 1141440, 1461600, 1141440, 1169280, 1009200, 143487360, 934087680,\n        ],\n        preTokenBalances: [\n            {\n                accountIndex: 3,\n                mint: 'HvCDUjehP8xNJfCGQxmTWQoEueYApaCL9sJTTBFeS3f4',\n                owner: '3kDKLKbdEaVV2XnhdyshthzRYcknrLLk1Fizft7LcXAG',\n                programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                uiTokenAmount: {\n                    amount: '1214430792',\n                    decimals: 6,\n                    uiAmount: 1214.430792,\n                    uiAmountString: '1214.430792',\n                },\n            },\n            {\n                accountIndex: 5,\n                mint: 'HvCDUjehP8xNJfCGQxmTWQoEueYApaCL9sJTTBFeS3f4',\n                owner: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                uiTokenAmount: {\n                    amount: '1068412171062',\n                    decimals: 6,\n                    uiAmount: 1068412.171062,\n                    uiAmountString: '1068412.171062',\n                },\n            },\n        ],\n        rewards: [],\n        status: {\n            Ok: null,\n        },\n    },\n    slot: 257318704,\n    transaction: {\n        message: {\n            accountKeys: [\n                {\n                    pubkey: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '5GCz3rtxi1LoWiozqXRMNvPWhybQgEdPwLrMKXH7Gm4E',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '7ZV4v2Q1krNiwmYvc7K4TzJ8jpK9HSW4wrH6W9ngSLH7',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'BeFuHRNFWT5q8qS5jF35awgFR88vtE33UWxDGxQrrJCZ',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'CmakeM5y4gikp7GyTZRps2RwvC1qZ4HQNX1AwsRgwqrQ',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'DNDx4t174ASMR7yNA5HQZppaU4WaAEQa3x1HphLHBDDU',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'Eo6HqnrR5mWoBuoksxQtzjL5A4txBEH8KCiTRykZPQn4',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'H6ojAjBeHu821EvH1sHggoxFq98wMBa9Ka99LMHgVie8',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '11111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: '3kDKLKbdEaVV2XnhdyshthzRYcknrLLk1Fizft7LcXAG',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: '3pNTNq5PaUhDLke4m4SKGctvxMedEv4rbQrPQu9zUMPG',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: '9Cp66QGfrmw1jGgrKEuEqpLzWJtX6yYx7fz63haJWcoq',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'A5JSBNA1N824Y7ZtQ98oBUVNB6wjThTvbUCTQyHfK5NC',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'CxST73mXAHuH5n18jZ3xFgthDot9XLJGWXfi2z6MBuqT',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'Drop9NhG6Mm6oQmPnzr8FQP6rWaPiwFkin59SeAKApLc',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'GP1xRUzahZem3X2uh7pYZNTeryrQF1tDXRKH76FX1i1V',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'SysvarC1ock11111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'SysvarRent111111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'SysvarS1otHashes111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n            ],\n            instructions: [\n                {\n                    parsed: {\n                        info: {\n                            lamports: 1461600,\n                            newAccount: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                            owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            source: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            space: 82,\n                        },\n                        type: 'createAccount',\n                    },\n                    program: 'system',\n                    programId: '11111111111111111111111111111111',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            decimals: 0,\n                            freezeAuthority: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            mint: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                            mintAuthority: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            rentSysvar: 'SysvarRent111111111111111111111111111111111',\n                        },\n                        type: 'initializeMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: 'DNDx4t174ASMR7yNA5HQZppaU4WaAEQa3x1HphLHBDDU',\n                            mint: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                            source: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                            systemProgram: '11111111111111111111111111111111',\n                            tokenProgram: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            wallet: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                        },\n                        type: 'create',\n                    },\n                    program: 'spl-associated-token-account',\n                    programId: 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: 'DNDx4t174ASMR7yNA5HQZppaU4WaAEQa3x1HphLHBDDU',\n                            amount: '1',\n                            mint: 'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                            mintAuthority: 'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                        },\n                        type: 'mintTo',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                    stackHeight: null,\n                },\n                {\n                    accounts: [\n                        'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                        '9Cp66QGfrmw1jGgrKEuEqpLzWJtX6yYx7fz63haJWcoq',\n                        'Eo6HqnrR5mWoBuoksxQtzjL5A4txBEH8KCiTRykZPQn4',\n                        'CmakeM5y4gikp7GyTZRps2RwvC1qZ4HQNX1AwsRgwqrQ',\n                        'H6ojAjBeHu821EvH1sHggoxFq98wMBa9Ka99LMHgVie8',\n                        'FX5iUBr2XdvULwa2trYRbPMHpnfxz28DrkEsVWSuPJMV',\n                        'AH7F2EPHXWhfF5yc7xnv1zPbwz3YqD6CtAqbCyE9dy7r',\n                        '8cTmTFTvMrELxXn1wKJeU45WiGf7suAmMJA8WrKe3TuW',\n                        'EAsdRhCDjRj7G4U5GjNG7b5mpMvpBfiDNiMTMM9JpQqn',\n                        'CxST73mXAHuH5n18jZ3xFgthDot9XLJGWXfi2z6MBuqT',\n                        '3kDKLKbdEaVV2XnhdyshthzRYcknrLLk1Fizft7LcXAG',\n                        'GP1xRUzahZem3X2uh7pYZNTeryrQF1tDXRKH76FX1i1V',\n                        '5GCz3rtxi1LoWiozqXRMNvPWhybQgEdPwLrMKXH7Gm4E',\n                        'A5JSBNA1N824Y7ZtQ98oBUVNB6wjThTvbUCTQyHfK5NC',\n                        'CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR',\n                        'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',\n                        'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        'SysvarC1ock11111111111111111111111111111111',\n                        '11111111111111111111111111111111',\n                        'SysvarS1otHashes111111111111111111111111111',\n                        '3pNTNq5PaUhDLke4m4SKGctvxMedEv4rbQrPQu9zUMPG',\n                        'BeFuHRNFWT5q8qS5jF35awgFR88vtE33UWxDGxQrrJCZ',\n                        '7ZV4v2Q1krNiwmYvc7K4TzJ8jpK9HSW4wrH6W9ngSLH7',\n                    ],\n                    data: 'T5oA9o97wiSHHPKwc58huJ',\n                    programId: 'Drop9NhG6Mm6oQmPnzr8FQP6rWaPiwFkin59SeAKApLc',\n                    stackHeight: null,\n                },\n            ],\n            recentBlockhash: 'bFotro8geZ9HJbE3SUJ77yQuCaECpRidocDapgM2BNW',\n        },\n        signatures: [\n            '3mjQHJqKBrWe2LnUYsx3a7Vr68qQHCW1ru2m2ycuiFfcihcpXdQ7KqKrjqKyQkmN5jjcvMeBvJDsSTiaXzoSWXSF',\n            '2Tfh6G4R9cxdtFDbCvnNR9QKjJX8o19ux4WwYiZsx9xRcAKKmZg88BqgQRJf2mrZBj1PuTPVCspWTDqqaNZAdsPJ',\n        ],\n    },\n    version: 'legacy',\n};\n\n// Lots of good token instructions in this one\nexport const mockTransactionToken = mockTransactionSystem;\n\nexport const mockTransactionStake = {\n    blockTime: 1699617128,\n    meta: {\n        computeUnitsConsumed: 20907,\n        err: null,\n        fee: 15000,\n        innerInstructions: [],\n        logMessages: [\n            'Program 11111111111111111111111111111111 invoke [1]',\n            'Program 11111111111111111111111111111111 success',\n            'Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr invoke [1]',\n            'Program log: Signed by BfdPksUrBeWBQp8ati1uoFqavi59dbmVJ7BEB3e6NeAg',\n            'Program log: Memo (len 11): \"fb_07ce1448\"',\n            'Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr consumed 19107 of 999850 compute units',\n            'Program MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr success',\n            'Program 11111111111111111111111111111111 invoke [1]',\n            'Program 11111111111111111111111111111111 success',\n            'Program Stake11111111111111111111111111111111111111 invoke [1]',\n            'Program Stake11111111111111111111111111111111111111 success',\n            'Program Stake11111111111111111111111111111111111111 invoke [1]',\n            'Program Stake11111111111111111111111111111111111111 success',\n        ],\n        postBalances: [\n            969985000, 30000000, 6258473240, 100000000, 42706560, 1009200, 51241152368, 1169280, 114979200, 960480, 1,\n            521498880, 1,\n        ],\n        postTokenBalances: [],\n        preBalances: [\n            1000000000, 0, 6258473240, 100000000, 42706560, 1009200, 51241152368, 1169280, 114979200, 960480, 1,\n            521498880, 1,\n        ],\n        preTokenBalances: [],\n        rewards: [],\n        status: {\n            Ok: null,\n        },\n    },\n    slot: 257314644,\n    transaction: {\n        message: {\n            accountKeys: [\n                {\n                    pubkey: 'BfdPksUrBeWBQp8ati1uoFqavi59dbmVJ7BEB3e6NeAg',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'DdNzYKnkq7PqCRX4kncvwVYNZE7dZ9xdCz6yMekqjWH4',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'gHMcHv21qqgui64sPRC2RTTehck1yc2EPxP1xJNfejZ',\n                    signer: true,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: '8XQj6xNHGrjfcL7K1a2KZMHjG2M9d6HCTxTL2wVjFjBa',\n                    signer: false,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'SysvarRecentB1ockHashes11111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'SysvarRent111111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'FwR3PbjS5iyqzLiLugrBqKSa5EKZ4vK9SKs7eQXtT59f',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'SysvarC1ock11111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'SysvarStakeHistory1111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'StakeConfig11111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: '11111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'Stake11111111111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n            ],\n            instructions: [\n                {\n                    parsed: {\n                        info: {\n                            nonceAccount: '8XQj6xNHGrjfcL7K1a2KZMHjG2M9d6HCTxTL2wVjFjBa',\n                            nonceAuthority: 'gHMcHv21qqgui64sPRC2RTTehck1yc2EPxP1xJNfejZ',\n                            recentBlockhashesSysvar: 'SysvarRecentB1ockHashes11111111111111111111',\n                        },\n                        type: 'advanceNonce',\n                    },\n                    program: 'system',\n                    programId: '11111111111111111111111111111111',\n                    stackHeight: null,\n                },\n                {\n                    parsed: 'fb_07ce1448',\n                    program: 'spl-memo',\n                    programId: 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            lamports: 30000000,\n                            newAccount: 'DdNzYKnkq7PqCRX4kncvwVYNZE7dZ9xdCz6yMekqjWH4',\n                            owner: 'Stake11111111111111111111111111111111111111',\n                            source: 'BfdPksUrBeWBQp8ati1uoFqavi59dbmVJ7BEB3e6NeAg',\n                            space: 200,\n                        },\n                        type: 'createAccount',\n                    },\n                    program: 'system',\n                    programId: '11111111111111111111111111111111',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authorized: {\n                                staker: 'BfdPksUrBeWBQp8ati1uoFqavi59dbmVJ7BEB3e6NeAg',\n                                withdrawer: 'BfdPksUrBeWBQp8ati1uoFqavi59dbmVJ7BEB3e6NeAg',\n                            },\n                            lockup: {\n                                custodian: '11111111111111111111111111111111',\n                                epoch: 0,\n                                unixTimestamp: 0,\n                            },\n                            rentSysvar: 'SysvarRent111111111111111111111111111111111',\n                            stakeAccount: 'DdNzYKnkq7PqCRX4kncvwVYNZE7dZ9xdCz6yMekqjWH4',\n                        },\n                        type: 'initialize',\n                    },\n                    program: 'stake',\n                    programId: 'Stake11111111111111111111111111111111111111',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            clockSysvar: 'SysvarC1ock11111111111111111111111111111111',\n                            stakeAccount: 'DdNzYKnkq7PqCRX4kncvwVYNZE7dZ9xdCz6yMekqjWH4',\n                            stakeAuthority: 'BfdPksUrBeWBQp8ati1uoFqavi59dbmVJ7BEB3e6NeAg',\n                            stakeConfigAccount: 'StakeConfig11111111111111111111111111111111',\n                            stakeHistorySysvar: 'SysvarStakeHistory1111111111111111111111111',\n                            voteAccount: 'FwR3PbjS5iyqzLiLugrBqKSa5EKZ4vK9SKs7eQXtT59f',\n                        },\n                        type: 'delegate',\n                    },\n                    program: 'stake',\n                    programId: 'Stake11111111111111111111111111111111111111',\n                    stackHeight: null,\n                },\n            ],\n            recentBlockhash: 'CjfMoKRUSyDvhanrBauxrwTgjoPWUy5yvTsGbttseANT',\n        },\n        signatures: [\n            '3zAhEb6t4UX8cJfrTujTGwdXW6KzMJZ5zQzZEBvJsmznQCPmb1DCyfGMzDvHt8nvATMjBhNCQhenxxdv3kvKcxNE',\n            '3zAhEb6t4UX8cJfrTujTGwdXW6KzMJZ5zQzZEBvJsmznbCTczzN4keMoEWEZXRNZvH4Kj2neWetV47sZShPSXfn4',\n            '3sHi1r5cKLYgojXRBssDNG9vd5cGraUMwehUDiBVm2SLMUcY5NwCaXG9u3PYZ6VY1R4kNfCKHU2m1RLnDPnAURFT',\n        ],\n    },\n};\n\n// There's a memo instruction in this one\nexport const mockTransactionMemo = mockTransactionStake;\n\nexport const mockTransactionToken2022AllExtensions = {\n    blockTime: 1713246023,\n    meta: {\n        computeUnitsConsumed: 41367,\n        err: null,\n        fee: 10000,\n        innerInstructions: [],\n        logMessages: ['REDACTED'],\n        postBalances: [99996921345480, 7078320, 1, 1, 1009200, 1141440],\n        postTokenBalances: [],\n        preBalances: [99996928433800, 0, 1, 1, 1009200, 1141440],\n        preTokenBalances: [],\n        rewards: [],\n        status: { Ok: null },\n    },\n    slot: 6717,\n    transaction: {\n        message: {\n            accountKeys: [\n                {\n                    pubkey: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: '11111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'ComputeBudget111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'SysvarRent111111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n                {\n                    pubkey: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n            ],\n            instructions: [\n                // Initializing Mint Extensions.\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            newAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'initializeMintCloseAuthority',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            delegate: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'initializePermanentDelegate',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            rate: 5,\n                            rateAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'initializeInterestBearingConfig',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: { mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ' },\n                        type: 'initializeNonTransferableMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            accountState: 'initialized',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'initializeDefaultAccountState',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            maximumFee: 11,\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            transferFeeBasisPoints: 10,\n                            transferFeeConfigAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            withdrawWithheldAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'initializeTransferFeeConfig',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            auditorElgamalPubkey: null,\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            autoApproveNewAccounts: true,\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'initializeConfidentialTransferMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                // TODO: `--enable-freeze`. Not supported by `jsonParsed` yet.\n                {\n                    accounts: ['FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ'],\n                    data: 'FQsaEAbK2543un21hNdSBkRnUxPtWEMrLCqSTL1pH7ks8vxEus7Wudc96rrUGi6vSfBuzo9BGZFLdAwNy2BhwjjHcF',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            programId: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'initializeTransferHook',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            metadataAddress: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'initializeMetadataPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            groupAddress: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'initializeGroupPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            memberAddress: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'initializeGroupMemberPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                // Updating Mint Extension pointers.\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            programId: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'updateTransferHook',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            programId: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'updateTransferHook',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            metadataAddress: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'updateMetadataPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            metadataAddress: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'updateMetadataPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            groupAddress: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'updateGroupPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            groupAddress: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'updateGroupPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            memberAddress: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'updateGroupMemberPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            memberAddress: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'updateGroupMemberPointer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            accountState: 'frozen',\n                            freezeAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'updateDefaultAccountState',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            accountState: 'frozen',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigFreezeAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'updateDefaultAccountState',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                // Initializing Account Extensions.\n                {\n                    parsed: {\n                        info: { account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d' },\n                        type: 'initializeImmutableOwner',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                // TODO (more) ...\n                // Toggling Account Extensions.\n                {\n                    parsed: {\n                        info: {\n                            account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            owner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'enableRequiredMemoTransfers',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            owner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'enableCpiGuard',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            multisigOwner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'enableCpiGuard',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            owner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'disableCpiGuard',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            multisigOwner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'disableCpiGuard',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            decryptableZeroBalance: 'o1O7rQmIqYJpoIuTj7d7dv+XvY5jvyFN9xs9oVO3sYH4/RBK',\n                            maximumPendingBalanceCreditCounter: 65536,\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigOwner: 'Sysvar1nstructions1111111111111111111111111',\n                            signers: ['2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB'],\n                        },\n                        type: 'configureConfidentialTransferAccount',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            sourceAccounts: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'harvestWithheldTokensToMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            feeRecipient: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            sourceAccounts: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                            withdrawWithheldAuthority: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                        },\n                        type: 'withdrawWithheldTokensFromAccounts',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            feeRecipient: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            sourceAccounts: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                            multisigWithdrawWithheldAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'withdrawWithheldTokensFromAccounts',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            feeRecipient: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            withdrawWithheldAuthority: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                        },\n                        type: 'withdrawWithheldTokensFromMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            feeRecipient: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigWithdrawWithheldAuthority: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'withdrawWithheldTokensFromMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            feeAmount: {\n                                amount: '5000',\n                                decimals: 9,\n                                uiAmount: 0.000005,\n                                uiAmountString: '0.000005',\n                            },\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            tokenAmount: {\n                                amount: '1000000000000000',\n                                decimals: 9,\n                                uiAmount: 1000000,\n                                uiAmountString: '1000000',\n                            },\n                        },\n                        type: 'transferCheckedWithFee',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            feeAmount: {\n                                amount: '5',\n                                decimals: 2,\n                                uiAmount: 0.05,\n                                uiAmountString: '0.05',\n                            },\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            tokenAmount: {\n                                amount: '55',\n                                decimals: 2,\n                                uiAmount: 0.55,\n                                uiAmountString: '0.55',\n                            },\n                        },\n                        type: 'transferCheckedWithFee',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'enableRequiredMemoTransfers',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'enableRequiredMemoTransfers',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'disableRequiredMemoTransfers',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'disableRequiredMemoTransfers',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            rate: 20,\n                            rateAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'initializeInterestBearingConfig',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            newRate: 20,\n                            rateAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'updateInterestBearingConfigRate',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigRateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            newRate: 20,\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'updateInterestBearingConfigRate',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            confidentialTransferAuditorAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'approveConfidentialTransferAccount',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            proofInstructionOffset: 1,\n                        },\n                        type: 'emptyConfidentialTransferAccount',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            instructionsSysvar: 'Sysvar1nstructions1111111111111111111111111',\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            proofInstructionOffset: 1,\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'emptyConfidentialTransferAccount',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '8wYAr4UKaHh35zFFbZW6iGgaBPJo1z9mvLwsdd3Mcpjo',\n                            expectedPendingBalanceCreditCounter: 1,\n                            newDecryptableAvailableBalance: '57fZKMs9YqFhu6fENwKTe7mGZh+wJbIvYkQ3LI/FDnOdc2w7',\n                            owner: 'B1diwnBSzuzbyzkKvd7nWfe4Et4hBbmBzvNY6HXB6mRV',\n                        },\n                        type: 'applyPendingConfidentialTransferBalance',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '8wYAr4UKaHh35zFFbZW6iGgaBPJo1z9mvLwsdd3Mcpjo',\n                            expectedPendingBalanceCreditCounter: 1,\n                            newDecryptableAvailableBalance: '57fZKMs9YqFhu6fENwKTe7mGZh+wJbIvYkQ3LI/FDnOdc2w7',\n                            multisigOwner: 'B1diwnBSzuzbyzkKvd7nWfe4Et4hBbmBzvNY6HXB6mRV',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'applyPendingConfidentialTransferBalance',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'enableConfidentialTransferConfidentialCredits',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'enableConfidentialTransferConfidentialCredits',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'disableConfidentialTransferConfidentialCredits',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'disableConfidentialTransferConfidentialCredits',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'enableConfidentialTransferNonConfidentialCredits',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'enableConfidentialTransferNonConfidentialCredits',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'disableNonConfidentialTransferConfidentialCredits',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'disableNonConfidentialTransferConfidentialCredits',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            amount: 1,\n                            decimals: 10,\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'depositConfidentialTransfer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            amount: 1,\n                            decimals: 10,\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'depositConfidentialTransfer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n\n                {\n                    parsed: {\n                        info: {\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            amount: 1,\n                            decimals: 10,\n                            newDecryptableAvailableBalance: '57fZKMs9YqFhu6fENwKTe7mGZh+wJbIvYkQ3LI/FDnOdc2w7',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            proofInstructionOffset: 1,\n                        },\n                        type: 'withdrawConfidentialTransfer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            amount: 1,\n                            decimals: 10,\n                            newDecryptableAvailableBalance: '57fZKMs9YqFhu6fENwKTe7mGZh+wJbIvYkQ3LI/FDnOdc2w7',\n                            proofInstructionOffset: 1,\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'withdrawConfidentialTransfer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            newSourceDecryptableAvailableBalance: '57fZKMs9YqFhu6fENwKTe7mGZh+wJbIvYkQ3LI/FDnOdc2w7',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            proofInstructionOffset: 1,\n                        },\n                        type: 'confidentialTransfer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            newSourceDecryptableAvailableBalance: '57fZKMs9YqFhu6fENwKTe7mGZh+wJbIvYkQ3LI/FDnOdc2w7',\n                            proofInstructionOffset: 1,\n                            multisigOwner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'confidentialTransfer',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            source: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            destination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ciphertextCommitmentEqualityContext: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            batchedGroupedCiphertext2HandlesValidityContext:\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            batchedRangeProofContext: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            owner: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            newSourceDecryptableAvailableBalance: '57fZKMs9YqFhu6fENwKTe7mGZh+wJbIvYkQ3LI/FDnOdc2w7',\n                            noOpOnUninitializedSplitContextState: true,\n                            closeSplitContextStateOnExecution: true,\n                            lamportDestination: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            contextStateOwner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'confidentialTransferWithSplitProofs',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            confidentialTransferMintAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            newConfidentialTransferMintAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            auditorElgamalPubkey: null,\n                            authority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            autoApproveNewAccounts: true,\n                        },\n                        type: 'updateConfidentialTransferMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            feeRecipient: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            proofInstructionOffset: 1,\n                            withdrawWithheldAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'withdrawWithheldConfidentialTransferTokensFromMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            feeRecipient: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            proofInstructionOffset: 1,\n                            multisigWithdrawWithheldAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'withdrawWithheldConfidentialTransferTokensFromMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            feeRecipient: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            proofInstructionOffset: 1,\n                            withdrawWithheldAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            sourceAccounts: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'withdrawWithheldConfidentialTransferTokensFromAccounts',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            feeRecipient: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            instructionsSysvar: 'SysvarRent111111111111111111111111111111111',\n                            proofInstructionOffset: 1,\n                            multisigWithdrawWithheldAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                            sourceAccounts: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'withdrawWithheldConfidentialTransferTokensFromAccounts',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            sourceAccounts: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'harvestWithheldConfidentialTransferTokensToMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            owner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'enableConfidentialTransferFeeHarvestToMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigOwner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'enableConfidentialTransferFeeHarvestToMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            owner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'disableConfidentialTransferFeeHarvestToMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            multisigOwner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                        },\n                        type: 'disableConfidentialTransferFeeHarvestToMint',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            authority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            withdrawWithheldAuthorityElgamalPubkey: null,\n                            harvestToMintEnabled: true,\n                            withheldAmount: '57fZKMs9YqFhu6fENwKTe7mGZh+wJbIvYkQ3LI/FDnOdc2w7',\n                            mint: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'initializeConfidentialTransferFeeConfig',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            group: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            maxSize: 22,\n                            mintAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            updateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            mint: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'initializeTokenGroup',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            group: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            maxSize: 22,\n                            updateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'updateTokenGroupMaxSize',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            group: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            updateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            newAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'updateTokenGroupAuthority',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            member: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            memberMint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            memberMintAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            group: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            groupUpdateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                        },\n                        type: 'initializeTokenGroupMember',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            metadata: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            updateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            mint: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            mintAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            name: 'Test',\n                            symbol: 'tst',\n                            uri: 'http://test.test',\n                        },\n                        type: 'initializeTokenMetadata',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            metadata: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            updateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            field: 'newField',\n                            value: 'newValue',\n                        },\n                        type: 'updateTokenMetadataField',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            metadata: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            updateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            key: 'key',\n                            idempotent: true,\n                        },\n                        type: 'removeTokenMetadataKey',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            metadata: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            updateAuthority: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            newAuthority: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                        },\n                        type: 'updateTokenMetadataAuthority',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            metadata: 'FsHcsGiY43QmZc6yTgwYC1DA5U3ZgycXxn3bd2oBjrEZ',\n                            start: 0,\n                            end: 100,\n                        },\n                        type: 'emitTokenMetadata',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            extensionTypes: ['transferFeeAmount', 'memoTransfer'],\n                            owner: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            payer: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            systemProgram: '11111111111111111111111111111111',\n                        },\n                        type: 'reallocate',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n                {\n                    parsed: {\n                        info: {\n                            account: '6muXBR8kTs1UEbATDkFzEf61HPeEHrCvdBNciVoxic8d',\n                            extensionTypes: ['transferFeeAmount', 'memoTransfer'],\n                            payer: '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            systemProgram: '11111111111111111111111111111111',\n                            signers: [\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                                '2Pwe6Yahh5cbzvCwRMtTYFeboSwYiWeHhYJzZZBsU6eB',\n                            ],\n                            multisigOwner: 'Sysvar1nstructions1111111111111111111111111',\n                        },\n                        type: 'reallocate',\n                    },\n                    program: 'spl-token',\n                    programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                    stackHeight: null,\n                },\n            ],\n            recentBlockhash: '6vRS7MoToVccMqfQecdVC6UbmARaT5mha91zhreqnce9',\n        },\n        signatures: [\n            '3Td5GvkFeAN43v2w1dP4RbuACWKWXgQE5DBHSyr6iGCGfjR4BUhmGoFiUsM3PauyaLMRTZN6RMjkbmdwawJy8UY5',\n            'KeEuFvtCTWjsC1kX2GChA5PZnjhfvXnQgigcSnbFoSsnE1cvEyNd8NVTgyJHqrusWhesR29z4EKwuF5xVFPyhEK',\n        ],\n    },\n};\n\nexport const mockTransactionVote = {\n    blockTime: 1699617237,\n    meta: {\n        computeUnitsConsumed: 2100,\n        err: null,\n        fee: 10000,\n        innerInstructions: [],\n        logMessages: [\n            'Program Vote111111111111111111111111111111111111111 invoke [1]',\n            'Program Vote111111111111111111111111111111111111111 success',\n        ],\n        postBalances: [500400400000, 1000000000000000, 1],\n        postTokenBalances: [],\n        preBalances: [500400410000, 1000000000000000, 1],\n        preTokenBalances: [],\n        rewards: [],\n        status: {\n            Ok: null,\n        },\n    },\n    slot: 20210,\n    transaction: {\n        message: {\n            accountKeys: [\n                {\n                    pubkey: '2gZDNztVterZb7aSMifCRd4V15YY8a9QcBBQ3ARTDe95',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'GGLDv8wTrSNuEq1pBhUfDFYEKFXDsvFU7YHkMj7a1EyK',\n                    signer: true,\n                    source: 'transaction',\n                    writable: true,\n                },\n                {\n                    pubkey: 'Vote111111111111111111111111111111111111111',\n                    signer: false,\n                    source: 'transaction',\n                    writable: false,\n                },\n            ],\n            instructions: [\n                {\n                    parsed: {\n                        info: {\n                            voteAccount: 'GGLDv8wTrSNuEq1pBhUfDFYEKFXDsvFU7YHkMj7a1EyK',\n                            voteAuthority: 'GGLDv8wTrSNuEq1pBhUfDFYEKFXDsvFU7YHkMj7a1EyK',\n                            voteStateUpdate: {\n                                hash: '72apBZbPCAZGwxhfmGNr23r2UmEScmj1VpKkyKpLRFJU',\n                                lockouts: [\n                                    {\n                                        confirmation_count: 31,\n                                        slot: 20179,\n                                    },\n                                    {\n                                        confirmation_count: 30,\n                                        slot: 20180,\n                                    },\n                                    {\n                                        confirmation_count: 29,\n                                        slot: 20181,\n                                    },\n                                    {\n                                        confirmation_count: 28,\n                                        slot: 20182,\n                                    },\n                                    {\n                                        confirmation_count: 27,\n                                        slot: 20183,\n                                    },\n                                    {\n                                        confirmation_count: 26,\n                                        slot: 20184,\n                                    },\n                                    {\n                                        confirmation_count: 25,\n                                        slot: 20185,\n                                    },\n                                    {\n                                        confirmation_count: 24,\n                                        slot: 20186,\n                                    },\n                                    {\n                                        confirmation_count: 23,\n                                        slot: 20187,\n                                    },\n                                    {\n                                        confirmation_count: 22,\n                                        slot: 20188,\n                                    },\n                                    {\n                                        confirmation_count: 21,\n                                        slot: 20189,\n                                    },\n                                    {\n                                        confirmation_count: 20,\n                                        slot: 20190,\n                                    },\n                                    {\n                                        confirmation_count: 19,\n                                        slot: 20191,\n                                    },\n                                    {\n                                        confirmation_count: 18,\n                                        slot: 20192,\n                                    },\n                                    {\n                                        confirmation_count: 17,\n                                        slot: 20193,\n                                    },\n                                    {\n                                        confirmation_count: 16,\n                                        slot: 20194,\n                                    },\n                                    {\n                                        confirmation_count: 15,\n                                        slot: 20195,\n                                    },\n                                    {\n                                        confirmation_count: 14,\n                                        slot: 20196,\n                                    },\n                                    {\n                                        confirmation_count: 13,\n                                        slot: 20197,\n                                    },\n                                    {\n                                        confirmation_count: 12,\n                                        slot: 20198,\n                                    },\n                                    {\n                                        confirmation_count: 11,\n                                        slot: 20199,\n                                    },\n                                    {\n                                        confirmation_count: 10,\n                                        slot: 20200,\n                                    },\n                                    {\n                                        confirmation_count: 9,\n                                        slot: 20201,\n                                    },\n                                    {\n                                        confirmation_count: 8,\n                                        slot: 20202,\n                                    },\n                                    {\n                                        confirmation_count: 7,\n                                        slot: 20203,\n                                    },\n                                    {\n                                        confirmation_count: 6,\n                                        slot: 20204,\n                                    },\n                                    {\n                                        confirmation_count: 5,\n                                        slot: 20205,\n                                    },\n                                    {\n                                        confirmation_count: 4,\n                                        slot: 20206,\n                                    },\n                                    {\n                                        confirmation_count: 3,\n                                        slot: 20207,\n                                    },\n                                    {\n                                        confirmation_count: 2,\n                                        slot: 20208,\n                                    },\n                                    {\n                                        confirmation_count: 1,\n                                        slot: 20209,\n                                    },\n                                ],\n                                root: 20178,\n                                timestamp: 1699617238,\n                            },\n                        },\n                        type: 'compactupdatevotestate',\n                    },\n                    program: 'vote',\n                    programId: 'Vote111111111111111111111111111111111111111',\n                    stackHeight: null,\n                },\n            ],\n            recentBlockhash: 'EBSvSuA2grMDdbBB61KSxmW8V7dauiXLJouyXGLiiEYz',\n        },\n        signatures: [\n            '41TfwbZi3WV5NJ7BY42r9sSkCUNfA7ab3j744DXR2wxZG9FyfctAoMYVYpQDj4je3xo89W7cvqGMzAq1nxd8R4xx',\n            '2FaeinN3wGnytjrEZkP1KULaF24jrTHbD52TYowyErEfuhvavwRcLensJyiRicqEPKEaiBCzxn1BpR5Yi8BCYrhK',\n        ],\n    },\n};\n\nconst mockRewards = [\n    {\n        commission: 0.1,\n        lamports: 50000,\n        postBalance: 1000000000000000,\n        pubkey: 'DdNzYKnkq7PqCRX4kncvwVYNZE7dZ9xdCz6yMekqjWH4',\n        rewardType: 'Staking',\n    },\n    {\n        commission: 0.1,\n        lamports: 50000,\n        postBalance: 1000000000000000,\n        pubkey: 'DdNzYKnkq7PqCRX4kncvwVYNZE7dZ9xdCz6yMekqjWH4',\n        rewardType: 'Staking',\n    },\n    {\n        commission: 0.1,\n        lamports: 50000,\n        postBalance: 1000000000000000,\n        pubkey: 'DdNzYKnkq7PqCRX4kncvwVYNZE7dZ9xdCz6yMekqjWH4',\n        rewardType: 'Staking',\n    },\n];\n\nexport const mockBlockFullBase58 = {\n    blockHeight: 257317189,\n    blockTime: 1699618066,\n    blockhash: 'bFotro8geZ9HJbE3SUJ77yQuCaECpRidocDapgM2BNW',\n    parentSlot: 257317188,\n    previousBlockhash: '3Z3gk6nNq8qRq6JnV8o9Xh7s7P8Q4qY4v9dZ5XnJzGtM',\n    rewards: mockRewards,\n    transactions: [mockTransactionBase58, mockTransactionBase58],\n};\n\nexport const mockBlockFullBase64 = {\n    blockHeight: 257317189,\n    blockTime: 1699618066,\n    blockhash: 'bFotro8geZ9HJbE3SUJ77yQuCaECpRidocDapgM2BNW',\n    parentSlot: 257317188,\n    previousBlockhash: '3Z3gk6nNq8qRq6JnV8o9Xh7s7P8Q4qY4v9dZ5XnJzGtM',\n    rewards: mockRewards,\n    transactions: [mockTransactionBase64, mockTransactionBase64],\n};\n\nexport const mockBlockFull = {\n    blockHeight: 257317189,\n    blockTime: 1699618066,\n    blockhash: 'bFotro8geZ9HJbE3SUJ77yQuCaECpRidocDapgM2BNW',\n    parentSlot: 257317188,\n    previousBlockhash: '3Z3gk6nNq8qRq6JnV8o9Xh7s7P8Q4qY4v9dZ5XnJzGtM',\n    rewards: mockRewards,\n    transactions: [\n        mockTransactionAddressLookup,\n        mockTransactionGeneric,\n        mockTransactionStake,\n        mockTransactionSystem,\n        mockTransactionToken,\n        mockTransactionVote,\n    ],\n};\n\nexport const mockBlockSignatures = {\n    blockHeight: 257317189,\n    blockTime: 1699618066,\n    blockhash: 'bFotro8geZ9HJbE3SUJ77yQuCaECpRidocDapgM2BNW',\n    parentSlot: 257317188,\n    previousBlockhash: '3Z3gk6nNq8qRq6JnV8o9Xh7s7P8Q4qY4v9dZ5XnJzGtM',\n    rewards: mockRewards,\n    signatures: [\n        '3mjQHJqKBrWe2LnUYsx3a7Vr68qQHCW1ru2m2ycuiFfcihcpXdQ7KqKrjqKyQkmN5jjcvMeBvJDsSTiaXzoSWXSF',\n        '2Tfh6G4R9cxdtFDbCvnNR9QKjJX8o19ux4WwYiZsx9xRcAKKmZg88BqgQRJf2mrZBj1PuTPVCspWTDqqaNZAdsPJ',\n    ],\n};\n"
  },
  {
    "path": "packages/rpc-graphql/src/__tests__/account-test.ts",
    "content": "import {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ntype GraphQLCompliantRpc = Rpc<\n    GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi\n>;\n\ndescribe('account', () => {\n    let rpc: GraphQLCompliantRpc;\n    let rpcGraphQL: RpcGraphQL;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n\n    describe('basic queries', () => {\n        // See scripts/fixtures/spl-token-token-account.json\n        const variableValues = {\n            address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n        };\n        it(\"can query an account's lamports balance\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        lamports\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        lamports: 10290815n,\n                    },\n                },\n            });\n        });\n        it(\"can query an account's executable value\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $commitment: Commitment) {\n                    account(address: $address, commitment: $commitment) {\n                        executable\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        executable: false,\n                    },\n                },\n            });\n        });\n        it(\"can query an account's address\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $commitment: Commitment) {\n                    account(address: $address, commitment: $commitment) {\n                        address\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n                    },\n                },\n            });\n        });\n        it('can query multiple fields', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $commitment: Commitment) {\n                    account(address: $address, commitment: $commitment) {\n                        executable\n                        lamports\n                        space\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        executable: false,\n                        lamports: 10290815n,\n                        space: 165n,\n                    },\n                },\n            });\n        });\n    });\n    describe('nested basic queries', () => {\n        // See scripts/fixtures/spl-token-token-account.json\n        const variableValues = {\n            address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n            commitment: 'CONFIRMED',\n        };\n        it(\"can perform a nested query for the account's ownerProgram\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $commitment: Commitment) {\n                    account(address: $address, commitment: $commitment) {\n                        ownerProgram {\n                            address\n                            executable\n                            lamports\n                            space\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        ownerProgram: {\n                            address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            executable: true,\n                            lamports: expect.any(BigInt),\n                            space: 133352n,\n                        },\n                    },\n                },\n            });\n        });\n    });\n    describe('double nested basic queries', () => {\n        // See scripts/fixtures/spl-token-token-account.json\n        const variableValues = {\n            address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n            commitment: 'CONFIRMED',\n        };\n        it(\"can perform a double nested query for each account's ownerProgram\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $commitment: Commitment) {\n                    account(address: $address, commitment: $commitment) {\n                        ownerProgram {\n                            address\n                            ownerProgram {\n                                address\n                                executable\n                                lamports\n                                space\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        ownerProgram: {\n                            address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            ownerProgram: {\n                                address: 'BPFLoader2111111111111111111111111111111111',\n                                executable: true,\n                                lamports: expect.any(BigInt),\n                                space: 25n,\n                            },\n                        },\n                    },\n                },\n            });\n        });\n    });\n    describe('triple nested basic queries', () => {\n        // See scripts/fixtures/spl-token-token-account.json\n        const variableValues = {\n            address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n            commitment: 'CONFIRMED',\n        };\n        it(\"can perform a triple nested query for each account's ownerProgram\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        ownerProgram {\n                            address\n                            ownerProgram {\n                                address\n                                ownerProgram {\n                                    address\n                                }\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        ownerProgram: {\n                            address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            ownerProgram: {\n                                address: 'BPFLoader2111111111111111111111111111111111',\n                                ownerProgram: {\n                                    address: 'NativeLoader1111111111111111111111111111111',\n                                },\n                            },\n                        },\n                    },\n                },\n            });\n        });\n    });\n    describe('account data queries', () => {\n        // See scripts/fixtures/gpa1.json\n        const address = 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk';\n        it('can get account data as base58', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        data(encoding: BASE_58)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { address });\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address,\n                        data: '2Uw1bpnsXxu3e',\n                    },\n                },\n            });\n        });\n        it('can get account data as base58 with data slice', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa1.json\n            const variableValues = {\n                address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                encoding: 'BASE_58',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $encoding: AccountEncoding!) {\n                    account(address: $address) {\n                        address\n                        data(encoding: $encoding, dataSlice: { offset: 0, length: 5 })\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                        data: 'E8f4pET', // As tested on local RPC\n                    },\n                },\n            });\n        });\n        it('can get account data as base64', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        data(encoding: BASE_64)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { address });\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address,\n                        data: 'dGVzdCBkYXRh',\n                    },\n                },\n            });\n        });\n        it('can get account data as base64 with data slice', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa1.json\n            const variableValues = {\n                address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                encoding: 'BASE_64',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $encoding: AccountEncoding!) {\n                    account(address: $address) {\n                        address\n                        data(encoding: $encoding, dataSlice: { offset: 0, length: 5 })\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                        data: 'dGVzdCA=',\n                    },\n                },\n            });\n        });\n        it('can get account data as base64 with two data slices', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa1.json\n            const variableValues = {\n                address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                encoding: 'BASE_64',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $encoding: AccountEncoding!) {\n                    account(address: $address) {\n                        address\n                        dataA: data(encoding: $encoding, dataSlice: { offset: 2, length: 5 })\n                        dataB: data(encoding: $encoding, dataSlice: { offset: 4, length: 5 })\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                        dataA: 'c3QgZGE=', // As tested on local RPC\n                        dataB: 'IGRhdGE=', // As tested on local RPC\n                    },\n                },\n            });\n        });\n        it('can get account data as base64+zstd', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        data(encoding: BASE_64_ZSTD)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { address });\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address,\n                        data: 'KLUv/QBYSQAAdGVzdCBkYXRh',\n                    },\n                },\n            });\n        });\n        it('can get account data as base64+zstd with data slice', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa1.json\n            const variableValues = {\n                address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                encoding: 'BASE_64_ZSTD',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $encoding: AccountEncoding!) {\n                    account(address: $address) {\n                        address\n                        data(encoding: $encoding, dataSlice: { offset: 0, length: 15 })\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                        data: 'KLUv/QBYSQAAdGVzdCBkYXRh', // As tested on local RPC\n                    },\n                },\n            });\n        });\n        it('can get account data as base64+zstd with multiple data slices', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa1.json\n            const variableValues = {\n                address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                encoding: 'BASE_64_ZSTD',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!, $encoding: AccountEncoding!) {\n                    account(address: $address) {\n                        address\n                        dataA: data(encoding: $encoding, dataSlice: { offset: 0, length: 5 })\n                        dataB: data(encoding: $encoding, dataSlice: { offset: 0, length: 15 })\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                        dataA: 'KLUv/QBYKQAAdGVzdCA=', // As tested on local RPC\n                        dataB: 'KLUv/QBYSQAAdGVzdCBkYXRh', // As tested on local RPC\n                    },\n                },\n            });\n        });\n        it('can get account data with multiple encodings', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        dataBase58: data(encoding: BASE_58)\n                        dataBase64: data(encoding: BASE_64)\n                        dataBase64Zstd: data(encoding: BASE_64_ZSTD)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { address });\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address,\n                        dataBase58: '2Uw1bpnsXxu3e',\n                        dataBase64: 'dGVzdCBkYXRh',\n                        dataBase64Zstd: 'KLUv/QBYSQAAdGVzdCBkYXRh',\n                    },\n                },\n            });\n        });\n        it('can get account data with multiple encodings and data slices', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/gpa1.json\n            const variableValues = {\n                address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        dataBase58: data(encoding: BASE_58, dataSlice: { offset: 0, length: 5 })\n                        dataBase64: data(encoding: BASE_64, dataSlice: { offset: 0, length: 5 })\n                        dataBase64Zstd: data(encoding: BASE_64_ZSTD, dataSlice: { offset: 0, length: 5 })\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk',\n                        dataBase58: 'E8f4pET', // As tested on local RPC\n                        dataBase64: 'dGVzdCA=', // As tested on local RPC\n                        dataBase64Zstd: 'KLUv/QBYKQAAdGVzdCA=', // As tested on local RPC\n                    },\n                },\n            });\n        });\n        it('can get account data as jsonParsed', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        ... on MintAccount {\n                            supply\n                        }\n                    }\n                }\n            `;\n            const resultParsed = await rpcGraphQL.query(source, {\n                // See scripts/fixtures/spl-token-mint-account.json\n                address: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n            });\n            expect(resultParsed).toMatchObject({\n                data: {\n                    account: {\n                        supply: expect.any(BigInt),\n                    },\n                },\n            });\n        });\n    });\n    describe('specific account type queries', () => {\n        it('can get a nonce account', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/nonce-account.json\n            const variableValues = {\n                address: 'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        space\n                        ... on NonceAccount {\n                            authority {\n                                address\n                            }\n                            blockhash\n                            feeCalculator {\n                                lamportsPerSignature\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU',\n                        authority: {\n                            address: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe',\n                        },\n                        blockhash: expect.any(String),\n                        feeCalculator: {\n                            lamportsPerSignature: expect.any(BigInt),\n                        },\n                        lamports: expect.any(BigInt),\n                        ownerProgram: {\n                            address: '11111111111111111111111111111111',\n                        },\n                        space: 80n,\n                    },\n                },\n            });\n        });\n        it('can get an address lookup table account', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/address-lookup-table-account.json\n            const variableValues = {\n                address: '2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        space\n                        ... on LookupTableAccount {\n                            addresses\n                            authority {\n                                address\n                            }\n                            deactivationSlot\n                            lastExtendedSlot\n                            lastExtendedSlotStartIndex\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: '2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n',\n                        addresses: expect.any(Array),\n                        authority: {\n                            address: '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B',\n                        },\n                        deactivationSlot: expect.any(BigInt),\n                        lamports: expect.any(BigInt),\n                        lastExtendedSlot: expect.any(BigInt),\n                        lastExtendedSlotStartIndex: expect.any(Number),\n                        ownerProgram: {\n                            address: 'AddressLookupTab1e1111111111111111111111111',\n                        },\n                        space: 1304n,\n                    },\n                },\n            });\n        });\n        it('can get a mint account', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/spl-token-mint-account.json\n            const variableValues = {\n                address: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        space\n                        ... on MintAccount {\n                            decimals\n                            isInitialized\n                            mintAuthority {\n                                address\n                                lamports\n                            }\n                            supply\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        decimals: 6,\n                        isInitialized: true,\n                        lamports: expect.any(BigInt),\n                        mintAuthority: {\n                            address: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            lamports: expect.any(BigInt),\n                        },\n                        ownerProgram: {\n                            address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        },\n                        space: 82n,\n                        supply: expect.any(BigInt),\n                    },\n                },\n            });\n        });\n        it('can get a token account', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/spl-token-token-account.json\n            const variableValues = {\n                address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        space\n                        ... on TokenAccount {\n                            isNative\n                            mint {\n                                address\n                            }\n                            owner {\n                                address\n                            }\n                            state\n                            tokenAmount {\n                                amount\n                                decimals\n                                uiAmount\n                                uiAmountString\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca',\n                        isNative: expect.any(Boolean),\n                        lamports: expect.any(BigInt),\n                        mint: {\n                            address: expect.any(String),\n                        },\n                        owner: {\n                            address: '6UsGbaMgchgj4wiwKKuE1v5URHdcDfEiMSM25QpesKir',\n                        },\n                        ownerProgram: {\n                            address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        },\n                        space: 165n,\n                        state: expect.any(String),\n                        tokenAmount: {\n                            amount: expect.any(BigInt),\n                            decimals: expect.any(Number),\n                            uiAmountString: expect.any(String),\n                        },\n                    },\n                },\n            });\n        });\n        it('can get a stake account', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/stake-account.json\n            const variableValues = {\n                address: 'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        space\n                        ... on StakeAccount {\n                            meta {\n                                authorized {\n                                    staker {\n                                        address\n                                    }\n                                    withdrawer {\n                                        address\n                                    }\n                                }\n                                lockup {\n                                    custodian {\n                                        address\n                                    }\n                                    epoch\n                                    unixTimestamp\n                                }\n                                rentExemptReserve\n                            }\n                            stake {\n                                creditsObserved\n                                delegation {\n                                    activationEpoch\n                                    deactivationEpoch\n                                    stake\n                                    voter {\n                                        address\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: 'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN',\n                        lamports: expect.any(BigInt),\n                        meta: {\n                            authorized: {\n                                staker: {\n                                    address: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                },\n                                withdrawer: {\n                                    address: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V',\n                                },\n                            },\n                            lockup: {\n                                custodian: {\n                                    address: '11111111111111111111111111111111',\n                                },\n                                epoch: expect.any(BigInt),\n                                unixTimestamp: expect.any(BigInt),\n                            },\n                            rentExemptReserve: expect.any(BigInt),\n                        },\n                        ownerProgram: {\n                            address: 'Stake11111111111111111111111111111111111111',\n                        },\n                        space: 200n,\n                        stake: {\n                            creditsObserved: expect.any(BigInt),\n                            delegation: {\n                                activationEpoch: expect.any(BigInt),\n                                deactivationEpoch: expect.any(BigInt),\n                                stake: expect.any(BigInt),\n                                voter: {\n                                    address: 'CertusDeBmqN8ZawdkxK5kFGMwBXdudvWHYwtNgNhvLu',\n                                },\n                            },\n                        },\n                    },\n                },\n            });\n        });\n        it('can get a vote account', async () => {\n            expect.assertions(1);\n            // See scripts/fixtures/vote-account.json\n            const variableValues = {\n                address: '4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        space\n                        ... on VoteAccount {\n                            authorizedVoters {\n                                authorizedVoter {\n                                    address\n                                }\n                                epoch\n                            }\n                            authorizedWithdrawer {\n                                address\n                            }\n                            commission\n                            epochCredits {\n                                credits\n                                epoch\n                                previousCredits\n                            }\n                            lastTimestamp {\n                                slot\n                                timestamp\n                            }\n                            node {\n                                address\n                            }\n                            priorVoters\n                            rootSlot\n                            votes {\n                                confirmationCount\n                                slot\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    account: {\n                        address: '4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp',\n                        authorizedVoters: expect.arrayContaining([\n                            {\n                                authorizedVoter: {\n                                    address: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                                },\n                                epoch: expect.any(BigInt),\n                            },\n                        ]),\n                        authorizedWithdrawer: {\n                            address: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                        },\n                        commission: expect.any(Number),\n                        epochCredits: expect.arrayContaining([\n                            {\n                                credits: expect.any(BigInt),\n                                epoch: expect.any(BigInt),\n                                previousCredits: expect.any(BigInt),\n                            },\n                        ]),\n                        lamports: expect.any(BigInt),\n                        lastTimestamp: {\n                            slot: expect.any(BigInt),\n                            timestamp: expect.any(BigInt),\n                        },\n                        node: {\n                            address: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr',\n                        },\n                        ownerProgram: {\n                            address: 'Vote111111111111111111111111111111111111111',\n                        },\n                        priorVoters: expect.any(Array),\n                        rootSlot: expect.any(BigInt),\n                        space: 3762n,\n                        votes: expect.arrayContaining([\n                            {\n                                confirmationCount: expect.any(Number),\n                                slot: expect.any(BigInt),\n                            },\n                        ]),\n                    },\n                },\n            });\n        });\n        describe('sysvars', () => {\n            it('can get the clock sysvar', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    address: 'SysvarC1ock11111111111111111111111111111111',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            address\n                            lamports\n                            ownerProgram {\n                                address\n                            }\n                            space\n                            ... on SysvarClockAccount {\n                                epoch\n                                epochStartTimestamp\n                                leaderScheduleEpoch\n                                slot\n                                unixTimestamp\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            address: 'SysvarC1ock11111111111111111111111111111111',\n                            epoch: expect.any(BigInt),\n                            epochStartTimestamp: expect.any(BigInt),\n                            lamports: expect.any(BigInt),\n                            leaderScheduleEpoch: expect.any(BigInt),\n                            ownerProgram: {\n                                address: 'Sysvar1111111111111111111111111111111111111',\n                            },\n                            slot: expect.any(BigInt),\n                            space: expect.any(BigInt),\n                            unixTimestamp: expect.any(BigInt),\n                        },\n                    },\n                });\n            });\n            // TODO: Does not exist on-chain yet.\n            it.todo('can get the epoch rewards sysvar');\n            it('can get the epoch schedule sysvar', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    address: 'SysvarEpochSchedu1e111111111111111111111111',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            address\n                            lamports\n                            ownerProgram {\n                                address\n                            }\n                            space\n                            ... on SysvarEpochScheduleAccount {\n                                firstNormalEpoch\n                                firstNormalSlot\n                                leaderScheduleSlotOffset\n                                slotsPerEpoch\n                                warmup\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            address: 'SysvarEpochSchedu1e111111111111111111111111',\n                            firstNormalEpoch: expect.any(BigInt),\n                            firstNormalSlot: expect.any(BigInt),\n                            lamports: expect.any(BigInt),\n                            leaderScheduleSlotOffset: expect.any(BigInt),\n                            ownerProgram: {\n                                address: 'Sysvar1111111111111111111111111111111111111',\n                            },\n                            slotsPerEpoch: expect.any(BigInt),\n                            space: expect.any(BigInt),\n                            warmup: expect.any(Boolean),\n                        },\n                    },\n                });\n            });\n            it('can get the last restart slot sysvar', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    address: 'SysvarLastRestartS1ot1111111111111111111111',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            address\n                            lamports\n                            ownerProgram {\n                                address\n                            }\n                            space\n                            ... on SysvarLastRestartSlotAccount {\n                                lastRestartSlot\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            address: 'SysvarLastRestartS1ot1111111111111111111111',\n                            lamports: expect.any(BigInt),\n                            lastRestartSlot: expect.any(BigInt),\n                            ownerProgram: {\n                                address: 'Sysvar1111111111111111111111111111111111111',\n                            },\n                            space: expect.any(BigInt),\n                        },\n                    },\n                });\n            });\n            it('can get the recent blockhashes sysvar', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    address: 'SysvarRecentB1ockHashes11111111111111111111',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            address\n                            lamports\n                            ownerProgram {\n                                address\n                            }\n                            space\n                            ... on SysvarRecentBlockhashesAccount {\n                                entries {\n                                    blockhash\n                                    feeCalculator {\n                                        lamportsPerSignature\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111',\n                            entries: expect.arrayContaining([\n                                {\n                                    blockhash: expect.any(String),\n                                    feeCalculator: {\n                                        lamportsPerSignature: expect.any(BigInt),\n                                    },\n                                },\n                            ]),\n                            lamports: expect.any(BigInt),\n                            ownerProgram: {\n                                address: 'Sysvar1111111111111111111111111111111111111',\n                            },\n                            space: expect.any(BigInt),\n                        },\n                    },\n                });\n            });\n            it('can get the rent sysvar', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    address: 'SysvarRent111111111111111111111111111111111',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            address\n                            lamports\n                            ownerProgram {\n                                address\n                            }\n                            space\n                            ... on SysvarRentAccount {\n                                burnPercent\n                                exemptionThreshold\n                                lamportsPerByteYear\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            address: 'SysvarRent111111111111111111111111111111111',\n                            burnPercent: expect.any(Number),\n                            exemptionThreshold: expect.any(Number),\n                            lamports: expect.any(BigInt),\n                            lamportsPerByteYear: expect.any(BigInt),\n                            ownerProgram: {\n                                address: 'Sysvar1111111111111111111111111111111111111',\n                            },\n                            space: expect.any(BigInt),\n                        },\n                    },\n                });\n            });\n            it('can get the slot hashes sysvar', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    address: 'SysvarS1otHashes111111111111111111111111111',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            address\n                            lamports\n                            ownerProgram {\n                                address\n                            }\n                            space\n                            ... on SysvarSlotHashesAccount {\n                                entries {\n                                    hash\n                                    slot\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            address: 'SysvarS1otHashes111111111111111111111111111',\n                            entries: expect.arrayContaining([\n                                {\n                                    hash: expect.any(String),\n                                    slot: expect.any(BigInt),\n                                },\n                            ]),\n                            lamports: expect.any(BigInt),\n                            ownerProgram: {\n                                address: 'Sysvar1111111111111111111111111111111111111',\n                            },\n                            space: expect.any(BigInt),\n                        },\n                    },\n                });\n            });\n            it('can get the slot history sysvar', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    address: 'SysvarS1otHistory11111111111111111111111111',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            address\n                            lamports\n                            ownerProgram {\n                                address\n                            }\n                            space\n                            ... on SysvarSlotHistoryAccount {\n                                bits\n                                nextSlot\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            address: 'SysvarS1otHistory11111111111111111111111111',\n                            bits: expect.any(String),\n                            lamports: expect.any(BigInt),\n                            nextSlot: expect.any(BigInt),\n                            ownerProgram: {\n                                address: 'Sysvar1111111111111111111111111111111111111',\n                            },\n                            space: expect.any(BigInt),\n                        },\n                    },\n                });\n            });\n            it('can get the stake history sysvar', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    address: 'SysvarStakeHistory1111111111111111111111111',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            address\n                            lamports\n                            ownerProgram {\n                                address\n                            }\n                            space\n                            ... on SysvarStakeHistoryAccount {\n                                entries {\n                                    effective\n                                    activating\n                                    deactivating\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            address: 'SysvarStakeHistory1111111111111111111111111',\n                            entries: expect.any(Array), // Not always populated on test validator\n                            lamports: expect.any(BigInt),\n                            ownerProgram: {\n                                address: 'Sysvar1111111111111111111111111111111111111',\n                            },\n                            space: expect.any(BigInt),\n                        },\n                    },\n                });\n            });\n        });\n        describe('token-2022 extensions', () => {\n            // See scripts/fixtures/spl-token-22-mint-mega-token.json\n            const megaMintAddress = '5gSwsLGzyCwgwPJSnxjsQCaFeE19ZFaibHMLky9TDFim';\n            // See scripts/fixtures/spl-token-22-mint-with-token-group-account.json\n            const tokenGroupMintAddress = '6sN6TS566ttRqmQzSTKxuHBtb8rPNZoqZeiERggev7zW';\n            // See scripts/fixtures/spl-token-22-mint-with-token-group-member-account.json\n            const tokenGroupMemberAddress = 'A2ka2DEVUy1Jm8iuPbXETSKFZQ2wDTq5HW8SrJqMiCi3';\n            // See scripts/fixtures/spl-token-22-account-mega-token-member.json\n            const megaAccountAddress = 'aUg6iJ3p43hTJsxHrQ1KfqMQYStoFvqcSJRcc51cYzK';\n            it('mint-close-authority', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionMintCloseAuthority {\n                                        closeAuthority {\n                                            address\n                                        }\n                                        extension\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    closeAuthority: {\n                                        address: expect.any(String),\n                                    },\n                                    extension: 'mintCloseAuthority',\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('permanent-delegate', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionPermanentDelegate {\n                                        delegate {\n                                            address\n                                        }\n                                        extension\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    delegate: {\n                                        address: expect.any(String),\n                                    },\n                                    extension: 'permanentDelegate',\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('interest-bearing-config', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionInterestBearingConfig {\n                                        currentRate\n                                        extension\n                                        initializationTimestamp\n                                        lastUpdateTimestamp\n                                        preUpdateAverageRate\n                                        rateAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    currentRate: expect.any(Number),\n                                    extension: 'interestBearingConfig',\n                                    initializationTimestamp: expect.any(BigInt),\n                                    lastUpdateTimestamp: expect.any(BigInt),\n                                    preUpdateAverageRate: expect.any(Number),\n                                    rateAuthority: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('non-transferable', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionNonTransferable {\n                                        extension\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'nonTransferable',\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('default-account-state', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionDefaultAccountState {\n                                        accountState\n                                        extension\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    accountState: expect.any(String),\n                                    extension: 'defaultAccountState',\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('transfer-fee-config', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionTransferFeeConfig {\n                                        extension\n                                        newerTransferFee {\n                                            epoch\n                                            maximumFee\n                                            transferFeeBasisPoints\n                                        }\n                                        olderTransferFee {\n                                            epoch\n                                            maximumFee\n                                            transferFeeBasisPoints\n                                        }\n                                        transferFeeConfigAuthority {\n                                            address\n                                        }\n                                        withdrawWithheldAuthority {\n                                            address\n                                        }\n                                        withheldAmount\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'transferFeeConfig',\n                                    newerTransferFee: {\n                                        epoch: expect.any(BigInt),\n                                        maximumFee: expect.any(BigInt),\n                                        transferFeeBasisPoints: expect.any(Number),\n                                    },\n                                    olderTransferFee: {\n                                        epoch: expect.any(BigInt),\n                                        maximumFee: expect.any(BigInt),\n                                        transferFeeBasisPoints: expect.any(Number),\n                                    },\n                                    transferFeeConfigAuthority: {\n                                        address: expect.any(String),\n                                    },\n                                    withdrawWithheldAuthority: {\n                                        address: expect.any(String),\n                                    },\n                                    withheldAmount: expect.any(BigInt),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('confidential-transfer-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionConfidentialTransferMint {\n                                        auditorElgamalPubkey\n                                        authority {\n                                            address\n                                        }\n                                        autoApproveNewAccounts\n                                        extension\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    auditorElgamalPubkey: null,\n                                    authority: {\n                                        address: expect.any(String),\n                                    },\n                                    autoApproveNewAccounts: expect.any(Boolean),\n                                    extension: 'confidentialTransferMint',\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('confidential-transfer-fee-config', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionConfidentialTransferFeeConfig {\n                                        authority {\n                                            address\n                                        }\n                                        extension\n                                        harvestToMintEnabled\n                                        withdrawWithheldAuthorityElgamalPubkey\n                                        withheldAmount\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    authority: {\n                                        address: expect.any(String),\n                                    },\n                                    extension: 'confidentialTransferFeeConfig',\n                                    harvestToMintEnabled: expect.any(Boolean),\n                                    withdrawWithheldAuthorityElgamalPubkey: expect.any(String),\n                                    withheldAmount: expect.any(String),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('transfer-hook', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionTransferHook {\n                                        authority {\n                                            address\n                                        }\n                                        extension\n                                        hookProgramId {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    authority: {\n                                        address: expect.any(String),\n                                    },\n                                    extension: 'transferHook',\n                                    hookProgramId: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('metadata-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionMetadataPointer {\n                                        authority {\n                                            address\n                                        }\n                                        extension\n                                        metadataAddress {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    authority: {\n                                        address: expect.any(String),\n                                    },\n                                    extension: 'metadataPointer',\n                                    metadataAddress: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('group-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionGroupPointer {\n                                        authority {\n                                            address\n                                        }\n                                        extension\n                                        groupAddress {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    authority: {\n                                        address: expect.any(String),\n                                    },\n                                    extension: 'groupPointer',\n                                    groupAddress: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('group-member-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionGroupMemberPointer {\n                                        authority {\n                                            address\n                                        }\n                                        extension\n                                        memberAddress {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    authority: {\n                                        address: expect.any(String),\n                                    },\n                                    extension: 'groupMemberPointer',\n                                    memberAddress: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('token-metadata', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionTokenMetadata {\n                                        additionalMetadata {\n                                            key\n                                            value\n                                        }\n                                        extension\n                                        mint {\n                                            address\n                                        }\n                                        name\n                                        symbol\n                                        updateAuthority {\n                                            address\n                                        }\n                                        uri\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: megaMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    additionalMetadata: expect.arrayContaining([\n                                        {\n                                            key: expect.any(String),\n                                            value: expect.any(String),\n                                        },\n                                    ]),\n                                    extension: 'tokenMetadata',\n                                    mint: {\n                                        address: expect.any(String),\n                                    },\n                                    name: expect.any(String),\n                                    symbol: expect.any(String),\n                                    updateAuthority: {\n                                        address: expect.any(String),\n                                    },\n                                    uri: expect.any(String),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('token-group', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionTokenGroup {\n                                        extension\n                                        maxSize\n                                        mint {\n                                            address\n                                        }\n                                        size\n                                        updateAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: tokenGroupMintAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'tokenGroup',\n                                    maxSize: expect.any(BigInt),\n                                    mint: {\n                                        address: expect.any(String),\n                                    },\n                                    size: expect.any(BigInt),\n                                    updateAuthority: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('token-group-member', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on MintAccount {\n                                extensions {\n                                    ... on SplTokenExtensionTokenGroupMember {\n                                        extension\n                                        group {\n                                            address\n                                        }\n                                        memberNumber\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { address: tokenGroupMemberAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'tokenGroupMember',\n                                    group: {\n                                        address: expect.any(String),\n                                    },\n                                    memberNumber: expect.any(BigInt),\n                                    mint: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n\n            it('confidential-transfer-account', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on TokenAccount {\n                                extensions {\n                                    ... on SplTokenExtensionConfidentialTransferAccount {\n                                        actualPendingBalanceCreditCounter\n                                        allowConfidentialCredits\n                                        allowNonConfidentialCredits\n                                        approved\n                                        availableBalance\n                                        decryptableAvailableBalance\n                                        elgamalPubkey\n                                        expectedPendingBalanceCreditCounter\n                                        maximumPendingBalanceCreditCounter\n                                        pendingBalanceCreditCounter\n                                        pendingBalanceHi\n                                        pendingBalanceLo\n                                        extension\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { address: megaAccountAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    actualPendingBalanceCreditCounter: null,\n                                    allowConfidentialCredits: expect.any(Boolean),\n                                    allowNonConfidentialCredits: expect.any(Boolean),\n                                    approved: expect.any(Boolean),\n                                    availableBalance: expect.any(String),\n                                    decryptableAvailableBalance: expect.any(String),\n                                    elgamalPubkey: expect.any(String),\n                                    expectedPendingBalanceCreditCounter: null,\n                                    extension: 'confidentialTransferAccount',\n                                    maximumPendingBalanceCreditCounter: null,\n                                    pendingBalanceCreditCounter: null,\n                                    pendingBalanceHi: expect.any(String),\n                                    pendingBalanceLo: expect.any(String),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n\n            it('transfer-fee-amount', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on TokenAccount {\n                                extensions {\n                                    ... on SplTokenExtensionTransferFeeAmount {\n                                        extension\n                                        withheldAmount\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { address: megaAccountAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'transferFeeAmount',\n                                    withheldAmount: expect.any(BigInt),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n\n            it('transfer-hook-account', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on TokenAccount {\n                                extensions {\n                                    ... on SplTokenExtensionTransferHookAccount {\n                                        extension\n                                        transferring\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { address: megaAccountAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'transferHookAccount',\n                                    transferring: expect.any(Boolean),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n\n            it('confidential-transfer-fee-amount', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on TokenAccount {\n                                extensions {\n                                    ... on SplTokenExtensionConfidentialTransferFeeAmount {\n                                        extension\n                                        withheldAmount\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { address: megaAccountAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'confidentialTransferFeeAmount',\n                                    withheldAmount: expect.any(String),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n\n            it('non-transferable-account', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on TokenAccount {\n                                extensions {\n                                    ... on SplTokenExtensionNonTransferableAccount {\n                                        extension\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { address: megaAccountAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'nonTransferableAccount',\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n\n            it('immutable-owner', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on TokenAccount {\n                                extensions {\n                                    ... on SplTokenExtensionImmutableOwner {\n                                        extension\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { address: megaAccountAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'immutableOwner',\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n\n            it('memo-transfer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on TokenAccount {\n                                extensions {\n                                    ... on SplTokenExtensionMemoTransfer {\n                                        extension\n                                        requireIncomingTransferMemos\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { address: megaAccountAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'memoTransfer',\n                                    requireIncomingTransferMemos: expect.any(Boolean),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n\n            it('cpi-guard', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account(address: $address) {\n                            ... on TokenAccount {\n                                extensions {\n                                    ... on SplTokenExtensionCpiGuard {\n                                        extension\n                                        lockCpi\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { address: megaAccountAddress });\n                expect(result).toMatchObject({\n                    data: {\n                        account: {\n                            extensions: expect.arrayContaining([\n                                {\n                                    extension: 'cpiGuard',\n                                    lockCpi: expect.any(Boolean),\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/__tests__/block-tests.ts",
    "content": "import {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\nimport type { Slot } from '@solana/rpc-types';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../index';\nimport { mockBlockFull, mockBlockFullBase58, mockBlockFullBase64, mockBlockSignatures } from './__setup__';\n\ntype GraphQLCompliantRpc = Rpc<\n    GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi\n>;\n\ndescribe('block', () => {\n    let mockRpcTransport: jest.Mock;\n    let rpc: GraphQLCompliantRpc;\n    let rpcGraphQL: RpcGraphQL;\n\n    // Random slot for testing.\n    // Not actually used. Just needed for proper query parsing.\n    const slot = 511226n as Slot;\n\n    beforeEach(() => {\n        mockRpcTransport = jest.fn();\n        rpc = new Proxy<GraphQLCompliantRpc>({} as GraphQLCompliantRpc, {\n            get(target, p) {\n                if (!target[p as keyof GraphQLCompliantRpc]) {\n                    const pendingRpcRequest = { send: mockRpcTransport };\n                    // @ts-expect-error - Mocking RPC methods\n                    target[p as keyof GraphQLCompliantRpc] = jest\n                        .fn()\n                        .mockReturnValue(pendingRpcRequest) as GraphQLCompliantRpc[keyof GraphQLCompliantRpc];\n                }\n                return target[p as keyof GraphQLCompliantRpc];\n            },\n        });\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    describe('basic queries', () => {\n        it(\"can query a block's block time\", async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValue(mockBlockFull);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        blockTime\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { slot });\n            expect(result).toMatchObject({\n                data: {\n                    block: {\n                        blockTime: expect.any(BigInt),\n                    },\n                },\n            });\n        });\n        it('can query multiple fields on a block', async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValue(mockBlockFull);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        blockhash\n                        parentSlot\n                        rewards {\n                            pubkey\n                            lamports\n                            postBalance\n                            rewardType\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { slot });\n            expect(result).toMatchObject({\n                data: {\n                    block: {\n                        blockhash: expect.any(String),\n                        parentSlot: expect.any(BigInt),\n                        rewards: expect.arrayContaining([\n                            {\n                                lamports: expect.any(BigInt),\n                                postBalance: expect.any(BigInt),\n                                pubkey: expect.any(String),\n                                rewardType: expect.any(String),\n                            },\n                        ]),\n                    },\n                },\n            });\n        });\n        it(\"can query a block's transaction signatures\", async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockBlockSignatures); // TODO: Mocks\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        signatures\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { slot });\n            expect(result).toMatchObject({\n                data: {\n                    block: {\n                        signatures: expect.any(Array),\n                    },\n                },\n            });\n        });\n        it(\"can query a block's transaction data as `base58`\", async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockBlockFullBase58); // TODO: Mocks\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        transactions {\n                            data(encoding: BASE_58)\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { slot });\n            expect(result).toMatchObject({\n                data: {\n                    block: {\n                        transactions: expect.arrayContaining([\n                            {\n                                data: expect.any(String),\n                            },\n                        ]),\n                    },\n                },\n            });\n        });\n        it(\"can query a block's transaction data as `base64`\", async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockBlockFullBase64); // TODO: Mocks\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        transactions {\n                            data(encoding: BASE_64)\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { slot });\n            expect(result).toMatchObject({\n                data: {\n                    block: {\n                        transactions: expect.arrayContaining([\n                            {\n                                data: expect.any(String),\n                            },\n                        ]),\n                    },\n                },\n            });\n        });\n        it(\"can query a block's parsed transaction message\", async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        transactions {\n                            message {\n                                accountKeys {\n                                    pubkey\n                                    signer\n                                    writable\n                                }\n                                recentBlockhash\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { slot });\n            expect(result).toMatchObject({\n                data: {\n                    block: {\n                        transactions: expect.arrayContaining([\n                            {\n                                message: {\n                                    accountKeys: expect.any(Array),\n                                    recentBlockhash: expect.any(String),\n                                },\n                            },\n                        ]),\n                    },\n                },\n            });\n        });\n    });\n    describe('specific instruction types', () => {\n        describe('instructions', () => {\n            it('can query a block with a transaction containing a `GenericInstruction` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                message {\n                                    instructions {\n                                        ... on GenericInstruction {\n                                            accounts\n                                            data\n                                            programId\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    message: {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                accounts: expect.any(Array),\n                                                data: expect.any(String),\n                                                programId: expect.any(String),\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('can query a block with a transaction containing a `ExtendLookupTable` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                message {\n                                    instructions {\n                                        programId\n                                        ... on ExtendLookupTableInstruction {\n                                            lookupTableAccount {\n                                                address\n                                            }\n                                            lookupTableAuthority {\n                                                address\n                                            }\n                                            newAddresses\n                                            payerAccount {\n                                                address\n                                            }\n                                            systemProgram {\n                                                address\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    message: {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                lookupTableAccount: {\n                                                    address: expect.any(String),\n                                                },\n                                                lookupTableAuthority: {\n                                                    address: expect.any(String),\n                                                },\n                                                newAddresses: expect.any(Array),\n                                                payerAccount: {\n                                                    address: expect.any(String),\n                                                },\n                                                programId: 'AddressLookupTab1e1111111111111111111111111',\n                                                systemProgram: {\n                                                    address: expect.any(String),\n                                                },\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('can query a block with a transaction containing a `CreateAccount` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                message {\n                                    instructions {\n                                        programId\n                                        ... on CreateAccountInstruction {\n                                            lamports\n                                            newAccount {\n                                                address\n                                            }\n                                            owner {\n                                                address\n                                            }\n                                            source {\n                                                address\n                                            }\n                                            space\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    message: {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                lamports: expect.any(BigInt),\n                                                newAccount: {\n                                                    address: expect.any(String),\n                                                },\n                                                owner: {\n                                                    address: expect.any(String),\n                                                },\n                                                programId: '11111111111111111111111111111111',\n                                                source: {\n                                                    address: expect.any(String),\n                                                },\n                                                space: expect.any(BigInt),\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('can query a block with a transaction containing a `SplMemoInstruction` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                message {\n                                    instructions {\n                                        programId\n                                        ... on SplMemoInstruction {\n                                            memo\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    message: {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                memo: 'fb_07ce1448',\n                                                programId: 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr',\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('can query a block with a transaction containing a `SplTokenInitializeMintInstruction` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                message {\n                                    instructions {\n                                        programId\n                                        ... on SplTokenInitializeMintInstruction {\n                                            decimals\n                                            freezeAuthority {\n                                                address\n                                            }\n                                            mint {\n                                                address\n                                            }\n                                            mintAuthority {\n                                                address\n                                            }\n                                            rentSysvar {\n                                                address\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    message: {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                decimals: expect.any(BigInt),\n                                                freezeAuthority: {\n                                                    address: expect.any(String),\n                                                },\n                                                mint: {\n                                                    address: expect.any(String),\n                                                },\n                                                mintAuthority: {\n                                                    address: expect.any(String),\n                                                },\n                                                programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                                rentSysvar: { address: expect.any(String) },\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n        });\n        describe('inner instructions', () => {\n            it('can query a block with a transaction containing a `Allocate` inner instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                meta {\n                                    innerInstructions {\n                                        instructions {\n                                            programId\n                                            ... on AllocateInstruction {\n                                                account {\n                                                    address\n                                                }\n                                                space\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    meta: {\n                                        innerInstructions: expect.arrayContaining([\n                                            {\n                                                instructions: expect.arrayContaining([\n                                                    {\n                                                        account: {\n                                                            address: expect.any(String),\n                                                        },\n                                                        programId: '11111111111111111111111111111111',\n                                                        space: expect.any(BigInt),\n                                                    },\n                                                ]),\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('can query a block with a transaction containing a `Assign` inner instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                meta {\n                                    innerInstructions {\n                                        instructions {\n                                            programId\n                                            ... on AssignInstruction {\n                                                account {\n                                                    address\n                                                }\n                                                owner {\n                                                    address\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    meta: {\n                                        innerInstructions: expect.arrayContaining([\n                                            {\n                                                instructions: expect.arrayContaining([\n                                                    {\n                                                        account: {\n                                                            address: expect.any(String),\n                                                        },\n                                                        owner: {\n                                                            address: expect.any(String),\n                                                        },\n                                                        programId: '11111111111111111111111111111111',\n                                                    },\n                                                ]),\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('can query a block with a transaction containing a `Transfer` inner instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                meta {\n                                    innerInstructions {\n                                        instructions {\n                                            programId\n                                            ... on TransferInstruction {\n                                                destination {\n                                                    address\n                                                }\n                                                lamports\n                                                source {\n                                                    address\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    meta: {\n                                        innerInstructions: expect.arrayContaining([\n                                            {\n                                                instructions: expect.arrayContaining([\n                                                    {\n                                                        destination: {\n                                                            address: expect.any(String),\n                                                        },\n                                                        lamports: expect.any(BigInt),\n                                                        programId: '11111111111111111111111111111111',\n                                                        source: {\n                                                            address: expect.any(String),\n                                                        },\n                                                    },\n                                                ]),\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n            it('can query a block with a transaction containing a `SplTokenTransfer` inner instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                meta {\n                                    innerInstructions {\n                                        instructions {\n                                            programId\n                                            ... on SplTokenTransferInstruction {\n                                                amount\n                                                destination {\n                                                    address\n                                                }\n                                                source {\n                                                    address\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { slot });\n                expect(result).toMatchObject({\n                    data: {\n                        block: {\n                            transactions: expect.arrayContaining([\n                                {\n                                    meta: {\n                                        innerInstructions: expect.arrayContaining([\n                                            {\n                                                instructions: expect.arrayContaining([\n                                                    {\n                                                        amount: expect.any(BigInt),\n                                                        destination: {\n                                                            address: expect.any(String),\n                                                        },\n                                                        programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                                        source: {\n                                                            address: expect.any(String),\n                                                        },\n                                                    },\n                                                ]),\n                                            },\n                                        ]),\n                                    },\n                                },\n                            ]),\n                        },\n                    },\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/__tests__/program-accounts-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../index';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ntype GraphQLCompliantRpc = Rpc<\n    GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi\n>;\n\ndescribe('programAccounts', () => {\n    let rpc: GraphQLCompliantRpc;\n    let rpcGraphQL: RpcGraphQL;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n\n    describe('basic queries', () => {\n        // See scripts/fixtures/gpa2-1.json, scripts/fixtures/gpa2-2.json,\n        const variableValues = {\n            commitment: 'CONFIRMED',\n            programAddress: 'AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6',\n        };\n        it(\"can query program accounts' lamports balances\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!, $commitment: Commitment) {\n                    programAccounts(programAddress: $programAddress, commitment: $commitment) {\n                        lamports\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([{ lamports: expect.any(BigInt) }]),\n                },\n            });\n        });\n        it(\"can query program accounts' executable value\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!, $commitment: Commitment) {\n                    programAccounts(programAddress: $programAddress, commitment: $commitment) {\n                        executable\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([{ executable: expect.any(Boolean) }]),\n                },\n            });\n        });\n        it('can query multiple fields', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!, $commitment: Commitment) {\n                    programAccounts(programAddress: $programAddress, commitment: $commitment) {\n                        executable\n                        lamports\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        {\n                            executable: expect.any(Boolean),\n                            lamports: expect.any(BigInt),\n                        },\n                    ]),\n                },\n            });\n        });\n    });\n    describe('account data queries', () => {\n        // See scripts/fixtures/gpa2-1.json, scripts/fixtures/gpa2-2.json,\n        const programAddress = 'AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6';\n        it(\"can get program accounts' data as base58\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        address\n                        executable\n                        data(encoding: BASE_58)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { programAddress });\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        {\n                            address: 'C5q1p5UiCVrt6vcLJDGcS4AZ98fahKyb9XkDRdqATK17',\n                            data: '2Uw1bpnsXxu3e',\n                            executable: false,\n                        },\n                        {\n                            address: 'Hhsoev7Apk5dMbktzLUrsTHuMq9e9GSYBaLcnN2PfdKS',\n                            data: '2Uw1bpnsXxu3e',\n                            executable: false,\n                        },\n                    ]),\n                },\n            });\n        });\n        it(\"can get program accounts' data as base64\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        address\n                        executable\n                        data(encoding: BASE_64)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { programAddress });\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        {\n                            address: 'C5q1p5UiCVrt6vcLJDGcS4AZ98fahKyb9XkDRdqATK17',\n                            data: 'dGVzdCBkYXRh',\n                            executable: false,\n                        },\n                        {\n                            address: 'Hhsoev7Apk5dMbktzLUrsTHuMq9e9GSYBaLcnN2PfdKS',\n                            data: 'dGVzdCBkYXRh',\n                            executable: false,\n                        },\n                    ]),\n                },\n            });\n        });\n        it(\"can get program accounts' data as base64+zstd\", async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        address\n                        executable\n                        data(encoding: BASE_64_ZSTD)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { programAddress });\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        {\n                            address: 'C5q1p5UiCVrt6vcLJDGcS4AZ98fahKyb9XkDRdqATK17',\n                            data: 'KLUv/QBYSQAAdGVzdCBkYXRh',\n                            executable: false,\n                        },\n                        {\n                            address: 'Hhsoev7Apk5dMbktzLUrsTHuMq9e9GSYBaLcnN2PfdKS',\n                            data: 'KLUv/QBYSQAAdGVzdCBkYXRh',\n                            executable: false,\n                        },\n                    ]),\n                },\n            });\n        });\n    });\n    describe('specific account type queries', () => {\n        it('address lookup table program', async () => {\n            expect.assertions(1);\n            const variableValues = {\n                programAddress: 'AddressLookupTab1e1111111111111111111111111',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        ... on LookupTableAccount {\n                            addresses\n                            authority {\n                                address\n                            }\n                            deactivationSlot\n                            lastExtendedSlot\n                            lastExtendedSlotStartIndex\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        {\n                            address: expect.any(String),\n                            addresses: expect.arrayContaining([expect.any(String)]),\n                            authority: {\n                                address: expect.any(String),\n                            },\n                            deactivationSlot: expect.any(BigInt),\n                            lamports: expect.any(BigInt),\n                            lastExtendedSlot: expect.any(BigInt),\n                            lastExtendedSlotStartIndex: expect.any(Number),\n                            ownerProgram: {\n                                address: 'AddressLookupTab1e1111111111111111111111111',\n                            },\n                        },\n                    ]),\n                },\n            });\n        });\n        it('spl token program', async () => {\n            expect.assertions(1);\n            const variableValues = {\n                programAddress: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        ... on MintAccount {\n                            decimals\n                            isInitialized\n                            mintAuthority {\n                                address\n                            }\n                            supply\n                        }\n                        ... on TokenAccount {\n                            isNative\n                            mint {\n                                address\n                            }\n                            owner {\n                                address\n                            }\n                            state\n                            tokenAmount {\n                                amount\n                                decimals\n                                uiAmount\n                                uiAmountString\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        // Mint account\n                        {\n                            address: expect.any(String),\n                            decimals: expect.any(Number),\n                            isInitialized: expect.any(Boolean),\n                            lamports: expect.any(BigInt),\n                            mintAuthority: {\n                                address: expect.any(String),\n                            },\n                            ownerProgram: {\n                                address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            },\n                            supply: expect.any(BigInt),\n                        },\n                        // Token account\n                        {\n                            address: expect.any(String),\n                            isNative: expect.any(Boolean),\n                            lamports: expect.any(BigInt),\n                            mint: {\n                                address: expect.any(String),\n                            },\n                            owner: {\n                                address: expect.any(String),\n                            },\n                            ownerProgram: {\n                                address: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                            },\n                            state: expect.any(String),\n                            tokenAmount: expect.objectContaining({\n                                amount: expect.any(BigInt),\n                                decimals: expect.any(Number),\n                                uiAmountString: expect.any(String),\n                            }),\n                        },\n                    ]),\n                },\n            });\n        });\n        it('system program', async () => {\n            expect.assertions(1);\n            const variableValues = {\n                programAddress: '11111111111111111111111111111111',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        ... on NonceAccount {\n                            authority {\n                                address\n                            }\n                            blockhash\n                            feeCalculator {\n                                lamportsPerSignature\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        {\n                            address: expect.any(String),\n                            authority: {\n                                address: expect.any(String),\n                            },\n                            blockhash: expect.any(String),\n                            feeCalculator: {\n                                lamportsPerSignature: expect.any(BigInt),\n                            },\n                            lamports: expect.any(BigInt),\n                            ownerProgram: {\n                                address: '11111111111111111111111111111111',\n                            },\n                        },\n                    ]),\n                },\n            });\n        });\n        it('stake program', async () => {\n            expect.assertions(1);\n            const variableValues = {\n                programAddress: 'Stake11111111111111111111111111111111111111',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        ... on StakeAccount {\n                            meta {\n                                authorized {\n                                    staker {\n                                        address\n                                    }\n                                    withdrawer {\n                                        address\n                                    }\n                                }\n                                lockup {\n                                    custodian {\n                                        address\n                                    }\n                                    epoch\n                                    unixTimestamp\n                                }\n                                rentExemptReserve\n                            }\n                            stake {\n                                creditsObserved\n                                delegation {\n                                    activationEpoch\n                                    deactivationEpoch\n                                    stake\n                                    voter {\n                                        address\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        {\n                            address: expect.any(String),\n                            lamports: expect.any(BigInt),\n                            meta: {\n                                authorized: {\n                                    staker: {\n                                        address: expect.any(String),\n                                    },\n                                    withdrawer: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                                lockup: {\n                                    custodian: {\n                                        address: expect.any(String),\n                                    },\n                                    epoch: expect.any(BigInt),\n                                    unixTimestamp: expect.any(BigInt),\n                                },\n                                rentExemptReserve: expect.any(BigInt),\n                            },\n                            ownerProgram: {\n                                address: 'Stake11111111111111111111111111111111111111',\n                            },\n                            stake: {\n                                creditsObserved: expect.any(BigInt),\n                                delegation: {\n                                    activationEpoch: expect.any(BigInt),\n                                    deactivationEpoch: expect.any(BigInt),\n                                    stake: expect.any(BigInt),\n                                    voter: {\n                                        address: expect.any(String),\n                                    },\n                                },\n                            },\n                        },\n                    ]),\n                },\n            });\n        });\n        it('vote program', async () => {\n            expect.assertions(1);\n            const variableValues = {\n                programAddress: 'Vote111111111111111111111111111111111111111',\n            };\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        address\n                        lamports\n                        ownerProgram {\n                            address\n                        }\n                        ... on VoteAccount {\n                            authorizedVoters {\n                                authorizedVoter {\n                                    address\n                                }\n                                epoch\n                            }\n                            authorizedWithdrawer {\n                                address\n                            }\n                            commission\n                            epochCredits {\n                                credits\n                                epoch\n                                previousCredits\n                            }\n                            lastTimestamp {\n                                slot\n                                timestamp\n                            }\n                            node {\n                                address\n                            }\n                            priorVoters\n                            rootSlot\n                            votes {\n                                confirmationCount\n                                slot\n                            }\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, variableValues);\n            expect(result).toMatchObject({\n                data: {\n                    programAccounts: expect.arrayContaining([\n                        {\n                            address: expect.any(String),\n                            authorizedVoters: expect.arrayContaining([\n                                {\n                                    authorizedVoter: {\n                                        address: expect.any(String),\n                                    },\n                                    epoch: expect.any(BigInt),\n                                },\n                            ]),\n                            authorizedWithdrawer: {\n                                address: expect.any(String),\n                            },\n                            commission: expect.any(Number),\n                            epochCredits: expect.arrayContaining([\n                                {\n                                    credits: expect.any(BigInt),\n                                    epoch: expect.any(BigInt),\n                                    previousCredits: expect.any(BigInt),\n                                },\n                            ]),\n                            lamports: expect.any(BigInt),\n                            lastTimestamp: {\n                                slot: expect.any(BigInt),\n                                timestamp: expect.any(BigInt),\n                            },\n                            node: {\n                                address: expect.any(String),\n                            },\n                            ownerProgram: {\n                                address: 'Vote111111111111111111111111111111111111111',\n                            },\n                            priorVoters: expect.any(Array),\n                            rootSlot: expect.any(BigInt),\n                            votes: expect.arrayContaining([\n                                {\n                                    confirmationCount: expect.any(Number),\n                                    slot: expect.any(BigInt),\n                                },\n                            ]),\n                        },\n                    ]),\n                },\n            });\n        });\n    });\n    describe('when called with a dataSlice', () => {\n        describe('when using base58 encoding', () => {\n            it('returns the correct slice of the data', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/gpa1.json\n                const variableValues = {\n                    commitment: 'CONFIRMED',\n                    dataSlice: {\n                        length: 5,\n                        offset: 0,\n                    },\n                    encoding: 'BASE_58',\n                    programAddress: 'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery(\n                        $programAddress: Address!\n                        $commitment: Commitment\n                        $dataSlice: DataSlice\n                        $encoding: AccountEncoding!\n                    ) {\n                        programAccounts(programAddress: $programAddress, commitment: $commitment) {\n                            data(encoding: $encoding, dataSlice: $dataSlice)\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        programAccounts: expect.arrayContaining([\n                            {\n                                data: 'E8f4pET', // As tested on local RPC\n                            },\n                        ]),\n                    },\n                });\n            });\n        });\n        describe('when using base64 encoding', () => {\n            it('returns the correct slice of the data', async () => {\n                expect.assertions(1);\n                // See scripts/fixtures/gpa1.json\n                const variableValues = {\n                    commitment: 'CONFIRMED',\n                    dataSlice: {\n                        length: 5,\n                        offset: 0,\n                    },\n                    encoding: 'BASE_64',\n                    programAddress: 'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                };\n                const source = /* GraphQL */ `\n                    query testQuery(\n                        $programAddress: Address!\n                        $commitment: Commitment\n                        $dataSlice: DataSlice\n                        $encoding: AccountEncoding!\n                    ) {\n                        programAccounts(programAddress: $programAddress, commitment: $commitment) {\n                            data(dataSlice: $dataSlice, encoding: $encoding)\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                expect(result).toMatchObject({\n                    data: {\n                        programAccounts: expect.arrayContaining([\n                            {\n                                data: 'dGVzdCA=', // As tested on local RPC\n                            },\n                        ]),\n                    },\n                });\n            });\n        });\n    });\n    describe('when called with a data size filter', () => {\n        const programAddress =\n            'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n        describe('when using memcmp filter', () => {\n            it('returns the matching accounts', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    dataSizeFilters: [\n                        {\n                            dataSize: 165n, // Token account size\n                        },\n                    ],\n                    programAddress,\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($programAddress: Address!, $dataSizeFilters: [ProgramAccountsDataSizeFilter!]!) {\n                        programAccounts(\n                            programAddress: $programAddress\n                            commitment: null\n                            dataSizeFilters: $dataSizeFilters\n                        ) {\n                            ... on TokenAccount {\n                                mint {\n                                    address\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                console.log(result);\n                expect(result).toMatchObject({\n                    data: {\n                        programAccounts: expect.arrayContaining([\n                            {\n                                mint: {\n                                    address: expect.any(String),\n                                },\n                            },\n                        ]),\n                    },\n                });\n            });\n        });\n    });\n    describe('when called with a memcmp filter', () => {\n        // See scripts/fixtures/spl-token-mint-account.json\n        const mintAddress =\n            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address<'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'>;\n        const programAddress =\n            'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n        describe('when using memcmp filter', () => {\n            it('returns the matching accounts', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    memcmpFilters: [\n                        {\n                            bytes: mintAddress, // Mint address in data.\n                            encoding: 'BASE_58', // Base58-encoded address.\n                            offset: 0, // Offset 0 for mint address.\n                        },\n                    ],\n                    programAddress,\n                };\n                const source = /* GraphQL */ `\n                    query testQuery($programAddress: Address!, $memcmpFilters: [ProgramAccountsMemcmpFilter!]!) {\n                        programAccounts(\n                            programAddress: $programAddress\n                            commitment: null\n                            dataSizeFilters: null\n                            memcmpFilters: $memcmpFilters\n                        ) {\n                            ... on TokenAccount {\n                                mint {\n                                    address\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                console.log(result);\n                expect(result).toMatchObject({\n                    data: {\n                        programAccounts: expect.arrayContaining([\n                            {\n                                mint: {\n                                    address: mintAddress,\n                                },\n                            },\n                        ]),\n                    },\n                });\n            });\n        });\n    });\n\n    describe('when called with both a data size and a memcmpy filter', () => {\n        // See scripts/fixtures/spl-token-mint-account.json\n        const mintAddress =\n            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address<'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr'>;\n        const programAddress =\n            'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address<'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'>;\n\n        describe('when using memcmp filter', () => {\n            it('returns the matching accounts', async () => {\n                expect.assertions(1);\n                const variableValues = {\n                    dataSizeFilters: [\n                        {\n                            dataSize: 165n, // Token account size\n                        },\n                    ],\n                    memcmpFilters: [\n                        {\n                            bytes: mintAddress, // Mint address in data.\n                            encoding: 'BASE_58', // Base58-encoded address.\n                            offset: 0, // Offset 0 for mint address.\n                        },\n                    ],\n                    programAddress,\n                };\n                const source = /* GraphQL */ `\n                    query testQuery(\n                        $programAddress: Address!\n                        $dataSizeFilters: [ProgramAccountsDataSizeFilter!]!\n                        $memcmpFilters: [ProgramAccountsMemcmpFilter!]!\n                    ) {\n                        programAccounts(\n                            programAddress: $programAddress\n                            commitment: null\n                            dataSizeFilters: $dataSizeFilters\n                            memcmpFilters: $memcmpFilters\n                        ) {\n                            ... on TokenAccount {\n                                mint {\n                                    address\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, variableValues);\n                console.log(result);\n                expect(result).toMatchObject({\n                    data: {\n                        programAccounts: expect.arrayContaining([\n                            {\n                                mint: {\n                                    address: mintAddress,\n                                },\n                            },\n                        ]),\n                    },\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/__tests__/transaction-tests.ts",
    "content": "import { Signature } from '@solana/keys';\nimport {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../index';\nimport {\n    mockTransactionAddressLookup,\n    mockTransactionBase58,\n    mockTransactionBase64,\n    mockTransactionGeneric,\n    mockTransactionMemo,\n    mockTransactionSystem,\n    mockTransactionToken,\n    mockTransactionToken2022AllExtensions,\n    mockTransactionVote,\n} from './__setup__';\n\ntype GraphQLCompliantRpc = Rpc<\n    GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi\n>;\n\ndescribe('transaction', () => {\n    let mockRpc: GraphQLCompliantRpc;\n    let mockRpcTransport: jest.Mock;\n    let rpcGraphQL: RpcGraphQL;\n\n    // Random signature for testing.\n    // Not actually used. Just needed for proper query parsing.\n    const signature =\n        '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk' as Signature;\n\n    beforeEach(() => {\n        mockRpcTransport = jest.fn();\n        mockRpc = new Proxy<GraphQLCompliantRpc>({} as GraphQLCompliantRpc, {\n            get(target, p) {\n                if (!target[p as keyof GraphQLCompliantRpc]) {\n                    const pendingRpcRequest = { send: mockRpcTransport };\n                    // @ts-expect-error - Mocking RPC methods\n                    target[p as keyof GraphQLCompliantRpc] = jest\n                        .fn()\n                        .mockReturnValue(pendingRpcRequest) as GraphQLCompliantRpc[keyof GraphQLCompliantRpc];\n                }\n                return target[p as keyof GraphQLCompliantRpc];\n            },\n        });\n        rpcGraphQL = createSolanaRpcGraphQL(mockRpc);\n    });\n\n    describe('basic queries', () => {\n        it('can query a transaction', async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockTransactionVote);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        blockTime\n                        slot\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { signature });\n            expect(result).toMatchObject({\n                data: {\n                    transaction: {\n                        blockTime: expect.any(BigInt),\n                        slot: expect.any(BigInt),\n                    },\n                },\n            });\n        });\n        it(\"can query a transaction's computeUnitsConsumed from it's meta\", async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockTransactionVote);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        meta {\n                            computeUnitsConsumed\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { signature });\n            expect(result).toMatchObject({\n                data: {\n                    transaction: {\n                        meta: {\n                            computeUnitsConsumed: expect.any(BigInt),\n                        },\n                    },\n                },\n            });\n        });\n        it(\"can query several fields from a transaction's meta\", async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockTransactionVote);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        meta {\n                            computeUnitsConsumed\n                            fee\n                            logMessages\n                        }\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { signature });\n            expect(result).toMatchObject({\n                data: {\n                    transaction: {\n                        meta: {\n                            computeUnitsConsumed: expect.any(BigInt),\n                            fee: expect.any(BigInt),\n                            logMessages: expect.any(Array),\n                        },\n                    },\n                },\n            });\n        });\n    });\n    describe('transaction data queries', () => {\n        it('can get a transaction as base58', async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockTransactionBase58);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        data(encoding: BASE_58)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { signature });\n            expect(result).toMatchObject({\n                data: {\n                    transaction: {\n                        data: expect.any(String),\n                    },\n                },\n            });\n        });\n        it('can get a transaction as base64', async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockTransactionBase64);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        data(encoding: BASE_64)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { signature });\n            expect(result).toMatchObject({\n                data: {\n                    transaction: {\n                        data: expect.any(String),\n                    },\n                },\n            });\n        });\n        it('can get a transaction as multiple encodings', async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockTransactionBase58);\n            mockRpcTransport.mockResolvedValueOnce(mockTransactionBase64);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        dataBase58: data(encoding: BASE_58)\n                        dataBase64: data(encoding: BASE_64)\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { signature });\n            expect(result).toMatchObject({\n                data: {\n                    transaction: {\n                        dataBase58: expect.any(String),\n                        dataBase64: expect.any(String),\n                    },\n                },\n            });\n        });\n        it('defaults to jsonParsed', async () => {\n            expect.assertions(1);\n            mockRpcTransport.mockResolvedValueOnce(mockTransactionVote);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        message {\n                            accountKeys {\n                                pubkey\n                                signer\n                                writable\n                            }\n                            recentBlockhash\n                        }\n                        signatures\n                    }\n                }\n            `;\n            const result = await rpcGraphQL.query(source, { signature });\n            expect(result).toMatchObject({\n                data: {\n                    transaction: {\n                        message: {\n                            accountKeys: expect.arrayContaining([\n                                {\n                                    pubkey: expect.any(String),\n                                    signer: expect.any(Boolean),\n                                    writable: expect.any(Boolean),\n                                },\n                            ]),\n                            recentBlockhash: expect.any(String),\n                        },\n                        signatures: expect.any(Array),\n                    },\n                },\n            });\n        });\n    });\n    describe('specific transaction instruction queries', () => {\n        describe('instructions', () => {\n            it('can get a generic instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionGeneric);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    ... on GenericInstruction {\n                                        accounts\n                                        data\n                                        programId\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        accounts: expect.any(Array),\n                                        data: expect.any(String),\n                                        programId: expect.any(String),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('can get a `ExtendLookupTable` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionAddressLookup);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on ExtendLookupTableInstruction {\n                                        lookupTableAccount {\n                                            address\n                                        }\n                                        lookupTableAuthority {\n                                            address\n                                        }\n                                        newAddresses\n                                        payerAccount {\n                                            address\n                                        }\n                                        systemProgram {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        lookupTableAccount: {\n                                            address: expect.any(String),\n                                        },\n                                        lookupTableAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        newAddresses: expect.any(Array),\n                                        payerAccount: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'AddressLookupTab1e1111111111111111111111111',\n                                        systemProgram: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('can get a `CreateAccount` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionSystem);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on CreateAccountInstruction {\n                                        lamports\n                                        newAccount {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        source {\n                                            address\n                                        }\n                                        space\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        lamports: expect.any(BigInt),\n                                        newAccount: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: '11111111111111111111111111111111',\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                        space: expect.any(BigInt),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('can get a `SplMemoInstruction` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionMemo);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplMemoInstruction {\n                                        memo\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        memo: 'fb_07ce1448',\n                                        programId: 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('can get a `SplTokenInitializeMintInstruction` instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionToken);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeMintInstruction {\n                                        decimals\n                                        freezeAuthority {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        mintAuthority {\n                                            address\n                                        }\n                                        rentSysvar {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        decimals: expect.any(BigInt),\n                                        freezeAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        mintAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                        rentSysvar: { address: expect.any(String) },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n        });\n        describe('inner instructions', () => {\n            it('can get an `Allocate` inner instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionSystem);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            meta {\n                                innerInstructions {\n                                    instructions {\n                                        programId\n                                        ... on AllocateInstruction {\n                                            account {\n                                                address\n                                            }\n                                            space\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            meta: {\n                                innerInstructions: expect.arrayContaining([\n                                    {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                account: {\n                                                    address: expect.any(String),\n                                                },\n                                                programId: '11111111111111111111111111111111',\n                                                space: expect.any(BigInt),\n                                            },\n                                        ]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('can get an `Assign` inner instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionSystem);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            meta {\n                                innerInstructions {\n                                    instructions {\n                                        programId\n                                        ... on AssignInstruction {\n                                            account {\n                                                address\n                                            }\n                                            owner {\n                                                address\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            meta: {\n                                innerInstructions: expect.arrayContaining([\n                                    {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                account: {\n                                                    address: expect.any(String),\n                                                },\n                                                owner: {\n                                                    address: expect.any(String),\n                                                },\n                                                programId: '11111111111111111111111111111111',\n                                            },\n                                        ]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('can get a `Transfer` inner instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionSystem);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            meta {\n                                innerInstructions {\n                                    instructions {\n                                        programId\n                                        ... on TransferInstruction {\n                                            destination {\n                                                address\n                                            }\n                                            lamports\n                                            source {\n                                                address\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            meta: {\n                                innerInstructions: expect.arrayContaining([\n                                    {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                destination: {\n                                                    address: expect.any(String),\n                                                },\n                                                lamports: expect.any(BigInt),\n                                                programId: '11111111111111111111111111111111',\n                                                source: {\n                                                    address: expect.any(String),\n                                                },\n                                            },\n                                        ]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('can get a `SplTokenTransfer` inner instruction', async () => {\n                expect.assertions(1);\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionToken);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            meta {\n                                innerInstructions {\n                                    instructions {\n                                        programId\n                                        ... on SplTokenTransferInstruction {\n                                            amount\n                                            destination {\n                                                address\n                                            }\n                                            source {\n                                                address\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            meta: {\n                                innerInstructions: expect.arrayContaining([\n                                    {\n                                        instructions: expect.arrayContaining([\n                                            {\n                                                amount: expect.any(BigInt),\n                                                destination: {\n                                                    address: expect.any(String),\n                                                },\n                                                programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                                source: {\n                                                    address: expect.any(String),\n                                                },\n                                            },\n                                        ]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n        });\n        describe('token-2022 extensions', () => {\n            beforeEach(() => {\n                mockRpcTransport.mockResolvedValueOnce(mockTransactionToken2022AllExtensions);\n            });\n            it('initialize-mint-close-authority', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeMintCloseAuthorityInstruction {\n                                        mint {\n                                            address\n                                        }\n                                        newAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        newAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('initialize-permanent-delegate', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializePermanentDelegateInstruction {\n                                        delegate {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        delegate: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('initialize-group-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeGroupPointerInstruction {\n                                        authority {\n                                            address\n                                        }\n                                        groupAddress {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        groupAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('update-group-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenUpdateGroupPointerInstruction {\n                                        authority {\n                                            address\n                                        }\n                                        groupAddress {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigAuthority {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        groupAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        authority: null,\n                                        groupAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('initialize-group-member-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeGroupMemberPointerInstruction {\n                                        authority {\n                                            address\n                                        }\n                                        memberAddress {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        memberAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('update-group-member-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenUpdateGroupMemberPointerInstruction {\n                                        authority {\n                                            address\n                                        }\n                                        memberAddress {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigAuthority {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        memberAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        authority: null,\n                                        memberAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('initialize-metadata-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeMetadataPointerInstruction {\n                                        authority {\n                                            address\n                                        }\n                                        metadataAddress {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        metadataAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('update-metadata-pointer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenUpdateMetadataPointerInstruction {\n                                        authority {\n                                            address\n                                        }\n                                        metadataAddress {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigAuthority {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        metadataAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        authority: null,\n                                        metadataAddress: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('initialize-transferFee-config', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeTransferFeeConfig {\n                                        mint {\n                                            address\n                                        }\n                                        transferFeeBasisPoints\n                                        maximumFee\n                                        transferFeeConfigAuthority {\n                                            address\n                                        }\n                                        withdrawWithheldAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        maximumFee: expect.any(BigInt),\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        transferFeeBasisPoints: expect.any(BigInt),\n                                        transferFeeConfigAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        withdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('initialize-transfer-hook', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeTransferHookInstruction {\n                                        authority {\n                                            address\n                                        }\n                                        hookProgramId {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        hookProgramId: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('update-transfer-hook', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenUpdateTransferHookInstruction {\n                                        authority {\n                                            address\n                                        }\n                                        hookProgramId {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigAuthority {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        hookProgramId: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        authority: null,\n                                        hookProgramId: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('initialize-default-account-state', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeDefaultAccountStateInstruction {\n                                        accountState\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        accountState: expect.any(String),\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('update-default-account-state', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenUpdateDefaultAccountStateInstruction {\n                                        accountState\n                                        freezeAuthority {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigFreezeAuthority {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        accountState: expect.any(String),\n                                        freezeAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigFreezeAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        accountState: expect.any(String),\n                                        freezeAuthority: null,\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigFreezeAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('enable-cpi-guard', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenEnableCpiGuardInstruction {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n            it('disable-cpi-guard', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenDisableCpiGuardInstruction {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('harvest-withheld-tokens-to-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenHarvestWithheldTokensToMint {\n                                        mint {\n                                            address\n                                        }\n                                        sourceAccounts\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        sourceAccounts: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('withdraw-withheld-tokens-from-accounts', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenWithdrawWithheldTokensFromAccounts {\n                                        feeRecipient {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigWithdrawWithheldAuthority {\n                                            address\n                                        }\n                                        signers\n                                        sourceAccounts\n                                        withdrawWithheldAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        feeRecipient: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigWithdrawWithheldAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                        sourceAccounts: expect.arrayContaining([expect.any(String)]),\n                                        withdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        feeRecipient: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigWithdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        sourceAccounts: expect.arrayContaining([expect.any(String)]),\n                                        withdrawWithheldAuthority: null,\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('withdraw-withheld-tokens-from-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenWithdrawWithheldTokensFromMint {\n                                        mint {\n                                            address\n                                        }\n                                        feeRecipient {\n                                            address\n                                        }\n                                        withdrawWithheldAuthority {\n                                            address\n                                        }\n                                        multisigWithdrawWithheldAuthority {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        feeRecipient: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigWithdrawWithheldAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                        withdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        feeRecipient: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigWithdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        withdrawWithheldAuthority: null,\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('transfer-checked-with-fee', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenTransferCheckedWithFee {\n                                        mint {\n                                            address\n                                        }\n                                        authority {\n                                            address\n                                        }\n                                        source {\n                                            address\n                                        }\n                                        destination {\n                                            address\n                                        }\n                                        feeAmount {\n                                            amount\n                                            decimals\n                                            uiAmount\n                                            uiAmountString\n                                        }\n                                        tokenAmount {\n                                            amount\n                                            decimals\n                                            uiAmount\n                                            uiAmountString\n                                        }\n                                        multisigAuthority {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        feeAmount: {\n                                            amount: expect.any(BigInt),\n                                            decimals: expect.any(Number),\n                                            uiAmount: null, // can't convert decimal to BigInt\n                                            uiAmountString: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                        tokenAmount: {\n                                            amount: expect.any(BigInt),\n                                            decimals: expect.any(Number),\n                                            uiAmount: expect.any(BigInt),\n                                            uiAmountString: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        authority: null,\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        feeAmount: {\n                                            amount: expect.any(BigInt),\n                                            decimals: expect.any(Number),\n                                            uiAmount: null, // can't convert decimal to BigInt\n                                            uiAmountString: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                        tokenAmount: {\n                                            amount: expect.any(BigInt),\n                                            decimals: expect.any(Number),\n                                            uiAmount: null, // Can't convert decimal to BigInt\n                                            uiAmountString: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('enable-required-memo-transfers', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenEnableRequiredMemoTransfers {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('disable-required-memo-transfers', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenDisableRequiredMemoTransfers {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('initialize-confidential-transfer-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeConfidentialTransferMint {\n                                        mint {\n                                            address\n                                        }\n                                        authority {\n                                            address\n                                        }\n                                        auditorElgamalPubkey\n                                        autoApproveNewAccounts\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        auditorElgamalPubkey: null,\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        autoApproveNewAccounts: expect.any(Boolean),\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('initialize-interest-bearing-config', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeInterestBearingConfig {\n                                        mint {\n                                            address\n                                        }\n                                        rate\n                                        rateAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        rate: expect.any(BigInt),\n                                        rateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('update-interest-bearing-config', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenUpdateInterestBearingConfigRate {\n                                        mint {\n                                            address\n                                        }\n                                        multisigRateAuthority {\n                                            address\n                                        }\n                                        newRate\n                                        rateAuthority {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigRateAuthority: null,\n                                        newRate: expect.any(BigInt),\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        rateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        signers: null,\n                                    },\n                                    {\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigRateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        newRate: expect.any(BigInt),\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        rateAuthority: null,\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('approve-confidential-transfer-account', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenApproveConfidentialTransferAccount {\n                                        account {\n                                            address\n                                        }\n                                        confidentialTransferAuditorAuthority {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        confidentialTransferAuditorAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('empty-confidential-transfer-account', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenEmptyConfidentialTransferAccount {\n                                        account {\n                                            address\n                                        }\n                                        instructionsSysvar {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        proofInstructionOffset\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('configure-confidential-transfer-account', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenConfigureConfidentialTransferAccount {\n                                        account {\n                                            address\n                                        }\n                                        decryptableZeroBalance\n                                        maximumPendingBalanceCreditCounter\n                                        mint {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        decryptableZeroBalance: expect.any(String),\n                                        maximumPendingBalanceCreditCounter: expect.any(BigInt),\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('apply-pending-confidential-transfer-balance', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenApplyPendingConfidentialTransferBalance {\n                                        account {\n                                            address\n                                        }\n                                        expectedPendingBalanceCreditCounter\n                                        multisigOwner {\n                                            address\n                                        }\n                                        newDecryptableAvailableBalance\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        expectedPendingBalanceCreditCounter: expect.any(BigInt),\n                                        multisigOwner: null,\n                                        newDecryptableAvailableBalance: expect.any(String),\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        expectedPendingBalanceCreditCounter: expect.any(BigInt),\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        newDecryptableAvailableBalance: expect.any(String),\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('enable-confidential-transfer-confidential-credits', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenEnableConfidentialTransferConfidentialCredits {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('disable-confidential-transfer-confidential-credits', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenDisableConfidentialTransferConfidentialCredits {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('enable-confidential-transfer-non-confidential-credits', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenEnableConfidentialTransferNonConfidentialCredits {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('disable-confidential-transfer-non-confidential-credits', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenDisableConfidentialTransferNonConfidentialCredits {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('deposit-confidential-transfer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenDepositConfidentialTransfer {\n                                        amount\n                                        decimals\n                                        destination {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                        source {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        amount: expect.any(BigInt),\n                                        decimals: expect.any(BigInt),\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        amount: expect.any(BigInt),\n                                        decimals: expect.any(BigInt),\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('withdraw-confidential-transfer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenWithdrawConfidentialTransfer {\n                                        amount\n                                        decimals\n                                        destination {\n                                            address\n                                        }\n                                        instructionsSysvar {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        newDecryptableAvailableBalance\n                                        owner {\n                                            address\n                                        }\n                                        proofInstructionOffset\n                                        signers\n                                        source {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        amount: expect.any(BigInt),\n                                        decimals: expect.any(BigInt),\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        newDecryptableAvailableBalance: expect.any(String),\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: null,\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        amount: expect.any(BigInt),\n                                        decimals: expect.any(BigInt),\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        newDecryptableAvailableBalance: expect.any(String),\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('confidential-transfer', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenConfidentialTransfer {\n                                        destination {\n                                            address\n                                        }\n                                        instructionsSysvar {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        newSourceDecryptableAvailableBalance\n                                        owner {\n                                            address\n                                        }\n                                        proofInstructionOffset\n                                        signers\n                                        source {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        newSourceDecryptableAvailableBalance: expect.any(String),\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: null,\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        newSourceDecryptableAvailableBalance: expect.any(String),\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('confidential-transfer-with-split-proofs', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenConfidentialTransferWithSplitProofs {\n                                        batchedGroupedCiphertext2HandlesValidityContext {\n                                            address\n                                        }\n                                        batchedRangeProofContext {\n                                            address\n                                        }\n                                        ciphertextCommitmentEqualityContext {\n                                            address\n                                        }\n                                        closeSplitContextStateOnExecution\n                                        contextStateOwner {\n                                            address\n                                        }\n                                        destination {\n                                            address\n                                        }\n                                        lamportDestination {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        newSourceDecryptableAvailableBalance\n                                        noOpOnUninitializedSplitContextState\n                                        owner {\n                                            address\n                                        }\n                                        source {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        batchedGroupedCiphertext2HandlesValidityContext: {\n                                            address: expect.any(String),\n                                        },\n                                        batchedRangeProofContext: {\n                                            address: expect.any(String),\n                                        },\n                                        ciphertextCommitmentEqualityContext: {\n                                            address: expect.any(String),\n                                        },\n                                        closeSplitContextStateOnExecution: expect.any(Boolean),\n                                        contextStateOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        destination: {\n                                            address: expect.any(String),\n                                        },\n                                        lamportDestination: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        newSourceDecryptableAvailableBalance: expect.any(String),\n                                        noOpOnUninitializedSplitContextState: expect.any(Boolean),\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        source: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('update-confidential-transfer-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenUpdateConfidentialTransferMint {\n                                        auditorElgamalPubkey\n                                        authority {\n                                            address\n                                        }\n                                        autoApproveNewAccounts\n                                        confidentialTransferMintAuthority {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        newConfidentialTransferMintAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        auditorElgamalPubkey: null,\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        autoApproveNewAccounts: expect.any(Boolean),\n                                        confidentialTransferMintAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        newConfidentialTransferMintAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('withdraw-withheld-confidential-transfer-tokens-from-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenWithdrawWithheldConfidentialTransferTokensFromMint {\n                                        feeRecipient {\n                                            address\n                                        }\n                                        instructionsSysvar {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigWithdrawWithheldAuthority {\n                                            address\n                                        }\n                                        proofInstructionOffset\n                                        signers\n                                        withdrawWithheldAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        feeRecipient: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigWithdrawWithheldAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: null,\n                                        withdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        feeRecipient: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigWithdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        withdrawWithheldAuthority: null,\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('withdraw-withheld-confidential-transfer-tokens-from-accounts', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenWithdrawWithheldConfidentialTransferTokensFromAccounts {\n                                        feeRecipient {\n                                            address\n                                        }\n                                        instructionsSysvar {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        multisigWithdrawWithheldAuthority {\n                                            address\n                                        }\n                                        proofInstructionOffset\n                                        signers\n                                        sourceAccounts\n                                        withdrawWithheldAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        feeRecipient: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigWithdrawWithheldAuthority: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: null,\n                                        sourceAccounts: expect.arrayContaining([expect.any(String)]),\n                                        withdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        feeRecipient: {\n                                            address: expect.any(String),\n                                        },\n                                        instructionsSysvar: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigWithdrawWithheldAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        proofInstructionOffset: expect.any(BigInt),\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        sourceAccounts: expect.arrayContaining([expect.any(String)]),\n                                        withdrawWithheldAuthority: null,\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('harvest-withheld-confidential-transfer-tokens-to-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenHarvestWithheldConfidentialTransferTokensToMint {\n                                        mint {\n                                            address\n                                        }\n                                        sourceAccounts\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        sourceAccounts: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('enable-confidential-transfer-fee-harvest-to-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenEnableConfidentialTransferFeeHarvestToMint {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('disable-confidential-transfer-fee-harvest-to-mint', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenDisableConfidentialTransferFeeHarvestToMint {\n                                        account {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        owner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('initialize-confidential-transfer-fee-config', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenInitializeConfidentialTransferFeeConfig {\n                                        authority {\n                                            address\n                                        }\n                                        harvestToMintEnabled\n                                        mint {\n                                            address\n                                        }\n                                        withdrawWithheldAuthorityElgamalPubkey\n                                        withheldAmount\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        authority: {\n                                            address: expect.any(String),\n                                        },\n                                        harvestToMintEnabled: expect.any(Boolean),\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        withdrawWithheldAuthorityElgamalPubkey: null,\n                                        withheldAmount: expect.any(String),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('initialize-token-group', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenGroupInitializeGroup {\n                                        group {\n                                            address\n                                        }\n                                        maxSize\n                                        mint {\n                                            address\n                                        }\n                                        mintAuthority {\n                                            address\n                                        }\n                                        updateAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        group: {\n                                            address: expect.any(String),\n                                        },\n                                        maxSize: expect.any(BigInt),\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        mintAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        updateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('update-group-max-size', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenGroupUpdateGroupMaxSize {\n                                        group {\n                                            address\n                                        }\n                                        maxSize\n                                        updateAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        group: {\n                                            address: expect.any(String),\n                                        },\n                                        maxSize: expect.any(BigInt),\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        updateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('update-group-authority', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenGroupUpdateGroupAuthority {\n                                        group {\n                                            address\n                                        }\n                                        newAuthority {\n                                            address\n                                        }\n                                        updateAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        group: {\n                                            address: expect.any(String),\n                                        },\n                                        newAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        updateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('initialize-token-group-member', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenGroupInitializeMember {\n                                        group {\n                                            address\n                                        }\n                                        groupUpdateAuthority {\n                                            address\n                                        }\n                                        member {\n                                            address\n                                        }\n                                        memberMint {\n                                            address\n                                        }\n                                        memberMintAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        group: {\n                                            address: expect.any(String),\n                                        },\n                                        groupUpdateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        member: {\n                                            address: expect.any(String),\n                                        },\n                                        memberMint: {\n                                            address: expect.any(String),\n                                        },\n                                        memberMintAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('initialize-token-metadata', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenMetadataInitialize {\n                                        metadata {\n                                            address\n                                        }\n                                        mint {\n                                            address\n                                        }\n                                        mintAuthority {\n                                            address\n                                        }\n                                        name\n                                        symbol\n                                        updateAuthority {\n                                            address\n                                        }\n                                        uri\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        metadata: {\n                                            address: expect.any(String),\n                                        },\n                                        mint: {\n                                            address: expect.any(String),\n                                        },\n                                        mintAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        name: expect.any(String),\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        symbol: expect.any(String),\n                                        updateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        uri: expect.any(String),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('update-token-metadata-field', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenMetadataUpdateField {\n                                        field\n                                        metadata {\n                                            address\n                                        }\n                                        updateAuthority {\n                                            address\n                                        }\n                                        value\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        field: expect.any(String),\n                                        metadata: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        updateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        value: expect.any(String),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('remove-token-metadata-key', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenMetadataRemoveKey {\n                                        idempotent\n                                        key\n                                        metadata {\n                                            address\n                                        }\n                                        updateAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        idempotent: expect.any(Boolean),\n                                        key: expect.any(String),\n                                        metadata: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        updateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('update-token-metadata-authority', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenMetadataUpdateAuthority {\n                                        metadata {\n                                            address\n                                        }\n                                        newAuthority {\n                                            address\n                                        }\n                                        updateAuthority {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        metadata: {\n                                            address: expect.any(String),\n                                        },\n                                        newAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        updateAuthority: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('emit-token-metadata', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenMetadataEmit {\n                                        end\n                                        metadata {\n                                            address\n                                        }\n                                        start\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        end: expect.any(BigInt),\n                                        metadata: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        start: expect.any(BigInt),\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n\n            it('reallocate', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    programId\n                                    ... on SplTokenReallocate {\n                                        account {\n                                            address\n                                        }\n                                        extensionTypes\n                                        owner {\n                                            address\n                                        }\n                                        payer {\n                                            address\n                                        }\n                                        systemProgram {\n                                            address\n                                        }\n                                        multisigOwner {\n                                            address\n                                        }\n                                        signers\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                const result = await rpcGraphQL.query(source, { signature });\n                expect(result).toMatchObject({\n                    data: {\n                        transaction: {\n                            message: {\n                                instructions: expect.arrayContaining([\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        extensionTypes: expect.arrayContaining([expect.any(String)]),\n                                        multisigOwner: null,\n                                        owner: {\n                                            address: expect.any(String),\n                                        },\n                                        payer: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: null,\n                                        systemProgram: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                    {\n                                        account: {\n                                            address: expect.any(String),\n                                        },\n                                        extensionTypes: expect.arrayContaining([expect.any(String)]),\n                                        multisigOwner: {\n                                            address: expect.any(String),\n                                        },\n                                        owner: null,\n                                        payer: {\n                                            address: expect.any(String),\n                                        },\n                                        programId: 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',\n                                        signers: expect.arrayContaining([expect.any(String)]),\n                                        systemProgram: {\n                                            address: expect.any(String),\n                                        },\n                                    },\n                                ]),\n                            },\n                        },\n                    },\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/context.ts",
    "content": "import type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport {\n    createAccountLoader,\n    createBlockLoader,\n    createProgramAccountsLoader,\n    createTransactionLoader,\n    RpcGraphQLLoaders,\n} from './loaders';\n\ntype Config = {\n    /**\n     * Maximum number of acceptable bytes to waste before splitting two\n     * `dataSlice` requests into two requests.\n     */\n    maxDataSliceByteRange: number;\n    /**\n     * Maximum number of accounts to fetch in a single batch.\n     * See https://docs.solana.com/api/http#getmultipleaccounts.\n     */\n    maxMultipleAccountsBatchSize: number;\n};\n\nexport interface RpcGraphQLContext {\n    loaders: RpcGraphQLLoaders;\n}\n\nexport function createSolanaGraphQLContext(\n    rpc: Rpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>,\n    config: Config,\n): RpcGraphQLContext {\n    return {\n        loaders: {\n            account: createAccountLoader(rpc, config),\n            block: createBlockLoader(rpc),\n            programAccounts: createProgramAccountsLoader(rpc, config),\n            transaction: createTransactionLoader(rpc),\n        },\n    };\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/index.ts",
    "content": "import { makeExecutableSchema } from '@graphql-tools/schema';\nimport { graphql } from 'graphql';\n\nimport { createSolanaGraphQLContext } from './context';\nimport { createSolanaGraphQLTypeDefs } from './schema/type-defs';\nimport { createSolanaGraphQLTypeResolvers } from './schema/type-resolvers';\n\nexport interface RpcGraphQL {\n    query(\n        source: Parameters<typeof graphql>[0]['source'],\n        variableValues?: Parameters<typeof graphql>[0]['variableValues'],\n    ): ReturnType<typeof graphql>;\n}\n\n/**\n * Create a GraphQL RPC client resolver.\n *\n * @param rpc       Solana RPC client.\n * @param schema    GraphQL schema.\n * @param config    Optional GraphQL resolver configurations.\n * @returns         GraphQL RPC client resolver.\n */\nexport function createRpcGraphQL(\n    rpc: Parameters<typeof createSolanaGraphQLContext>[0],\n    schema: ReturnType<typeof makeExecutableSchema>,\n    config?: Partial<Parameters<typeof createSolanaGraphQLContext>[1]>,\n): RpcGraphQL {\n    const rpcGraphQLConfig = {\n        maxDataSliceByteRange: config?.maxDataSliceByteRange ?? 200,\n        maxMultipleAccountsBatchSize: config?.maxMultipleAccountsBatchSize ?? 100,\n    };\n    return {\n        async query(source, variableValues?) {\n            const contextValue = createSolanaGraphQLContext(rpc, rpcGraphQLConfig);\n            return await graphql({\n                contextValue,\n                schema,\n                source,\n                variableValues,\n            });\n        },\n    };\n}\n\n/**\n * Create a Solana GraphQL RPC client resolver.\n *\n * Configures the client resolver to use the default Solana GraphQL schema.\n *\n * @param rpc       Solana RPC client.\n * @param config    Optional GraphQL resolver configurations.\n * @returns         Solana GraphQL RPC client resolver.\n */\nexport function createSolanaRpcGraphQL(\n    rpc: Parameters<typeof createSolanaGraphQLContext>[0],\n    config?: Partial<Parameters<typeof createSolanaGraphQLContext>[1]>,\n): RpcGraphQL {\n    const schema = makeExecutableSchema({\n        resolvers: createSolanaGraphQLTypeResolvers(),\n        typeDefs: createSolanaGraphQLTypeDefs(),\n    });\n    return createRpcGraphQL(rpc, schema, config);\n}\n\nexport { createSolanaGraphQLTypeDefs, createSolanaGraphQLTypeResolvers };\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/__tests__/account-loader-test.ts",
    "content": "import type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../../index';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('account loader', () => {\n    let rpc: {\n        getAccountInfo: jest.MockedFunction<Rpc<GetAccountInfoApi>['getAccountInfo']>;\n        getBlock: jest.MockedFunction<Rpc<GetBlockApi>['getBlock']>;\n        getMultipleAccounts: jest.MockedFunction<Rpc<GetMultipleAccountsApi>['getMultipleAccounts']>;\n        getProgramAccounts: jest.MockedFunction<Rpc<GetProgramAccountsApi>['getProgramAccounts']>;\n        getTransaction: jest.MockedFunction<Rpc<GetTransactionApi>['getTransaction']>;\n    };\n    let rpcGraphQL: RpcGraphQL;\n    // Random address for testing.\n    // Not actually used. Just needed for proper query parsing.\n    const address = 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr';\n    beforeEach(() => {\n        jest.useFakeTimers();\n        rpc = {\n            getAccountInfo: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getBlock: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getMultipleAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getProgramAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getTransaction: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n        };\n        rpcGraphQL = createSolanaRpcGraphQL(\n            rpc as unknown as Rpc<\n                GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi\n            >,\n        );\n    });\n    describe('cached responses', () => {\n        it('coalesces multiple requests for the same account into one', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account1: account(address: $address) {\n                        lamports\n                    }\n                    account2: account(address: $address) {\n                        lamports\n                    }\n                    account3: account(address: $address) {\n                        lamports\n                    }\n                }\n            `;\n            rpcGraphQL.query(source, { address }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n        });\n        it('cache resets on new tick', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($address: Address!) {\n                    account(address: $address) {\n                        lamports\n                    }\n                }\n            `;\n            // Call the query twice\n            rpcGraphQL.query(source, { address }).catch(() => {});\n            rpcGraphQL.query(source, { address }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(2);\n        });\n    });\n    describe('batch loading', () => {\n        describe('request partitioning', () => {\n            it('coalesces multiple requests for the same account but different fields into one request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account1: account(address: $address) {\n                            lamports\n                        }\n                        account2: account(address: $address) {\n                            space\n                        }\n                        account3: account(address: $address) {\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { address: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                });\n            });\n            it('coalesces multiple requests for the same account but one with specified `confirmed` commitment into one request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account1: account(address: $address) {\n                            lamports\n                        }\n                        account2: account(address: $address, commitment: CONFIRMED) {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { address: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64', // GraphQL client prefers `base64`\n                });\n            });\n            it('will not coalesce multiple requests for the same account but with different commitments into one request', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        account1: account(address: $address) {\n                            lamports\n                        }\n                        account2: account(address: $address, commitment: CONFIRMED) {\n                            lamports\n                        }\n                        account3: account(address: $address, commitment: FINALIZED) {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { address: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(2);\n                expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64', // GraphQL client prefers `base64`\n                });\n                expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'finalized',\n                    encoding: 'base64', // GraphQL client prefers `base64`\n                });\n            });\n            it('coalesces multiple requests for multiple accounts into one `getMultipleAccounts` request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account1: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            lamports\n                        }\n                        account2: account(address: \"E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr\") {\n                            lamports\n                        }\n                        account3: account(address: \"8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M\") {\n                            lamports\n                        }\n                        account4: account(address: \"BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx\") {\n                            lamports\n                        }\n                        account5: account(address: \"68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC\") {\n                            lamports\n                        }\n                        account6: account(address: \"FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa\") {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getMultipleAccounts).toHaveBeenLastCalledWith(\n                    [\n                        'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        'E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr',\n                        '8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M',\n                        'BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx',\n                        '68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC',\n                        'FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa',\n                    ],\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n            });\n            it('coalesces multiple requests for multiple accounts into one `getMultipleAccounts` request, coalescing `confirmed` commitments', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account1: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            lamports\n                        }\n                        account1Confirmed: account(\n                            address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account2: account(address: \"E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr\") {\n                            lamports\n                        }\n                        account2Confirmed: account(\n                            address: \"E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account3: account(address: \"8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M\") {\n                            lamports\n                        }\n                        account3Confirmed: account(\n                            address: \"8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account4: account(address: \"BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx\") {\n                            lamports\n                        }\n                        account4Confirmed: account(\n                            address: \"BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account5: account(address: \"68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC\") {\n                            lamports\n                        }\n                        account5Confirmed: account(\n                            address: \"68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account6: account(address: \"FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa\") {\n                            lamports\n                        }\n                        account6Confirmed: account(\n                            address: \"FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getMultipleAccounts).toHaveBeenLastCalledWith(\n                    [\n                        'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        'E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr',\n                        '8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M',\n                        'BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx',\n                        '68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC',\n                        'FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa',\n                    ],\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n            });\n            it('will not coalesce multiple requests for multiple accounts into one `getMultipleAccounts` request when different commitments are requested', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account1: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            lamports\n                        }\n                        account1Confirmed: account(\n                            address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account1Finalized: account(\n                            address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\"\n                            commitment: FINALIZED\n                        ) {\n                            lamports\n                        }\n                        account2: account(address: \"E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr\") {\n                            lamports\n                        }\n                        account2Confirmed: account(\n                            address: \"E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account2Finalized: account(\n                            address: \"E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr\"\n                            commitment: FINALIZED\n                        ) {\n                            lamports\n                        }\n                        account3: account(address: \"8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M\") {\n                            lamports\n                        }\n                        account3Confirmed: account(\n                            address: \"8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account3Finalized: account(\n                            address: \"8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M\"\n                            commitment: FINALIZED\n                        ) {\n                            lamports\n                        }\n                        account4: account(address: \"BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx\") {\n                            lamports\n                        }\n                        account4Confirmed: account(\n                            address: \"BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account4Finalized: account(\n                            address: \"BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx\"\n                            commitment: FINALIZED\n                        ) {\n                            lamports\n                        }\n                        account5: account(address: \"68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC\") {\n                            lamports\n                        }\n                        account5Confirmed: account(\n                            address: \"68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account5Finalized: account(\n                            address: \"68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC\"\n                            commitment: FINALIZED\n                        ) {\n                            lamports\n                        }\n                        account6: account(address: \"FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa\") {\n                            lamports\n                        }\n                        account6Confirmed: account(\n                            address: \"FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa\"\n                            commitment: CONFIRMED\n                        ) {\n                            lamports\n                        }\n                        account6Finalized: account(\n                            address: \"FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa\"\n                            commitment: FINALIZED\n                        ) {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(2);\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                    [\n                        'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        'E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr',\n                        '8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M',\n                        'BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx',\n                        '68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC',\n                        'FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa',\n                    ],\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                    [\n                        'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        'E3gxDM5HFkRALNTiWkdi9CNnXpCyTRuHz1fijP9EZbqr',\n                        '8mU8aurnEhNooLD7gRbY3jhtjWHsYpBEcFL1Dut3wu8M',\n                        'BXiu8QD4YiJ9QhMhijgDrdZh6buNe1Axtz5JG71fuDBx',\n                        '68xCDFqAHkce2tRMCTg8NMYDP9UHyMzSGsJQcHwto7aC',\n                        'FAMce8gx9Kt6CiE1AE7at6P15myQyQFqQr9fXoZbfJSa',\n                    ],\n                    {\n                        commitment: 'finalized',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n            });\n            it('coalesces multi-layered multiple requests into `getMultipleAccounts` requests', async () => {\n                expect.assertions(7);\n\n                // Set up mocks\n                type MockDataOwner = { data: [string, string]; owner: string };\n                const getAccountInfoMockResponseValue = ({ data, owner }: MockDataOwner) =>\n                    ({\n                        data,\n                        owner,\n                    }) as unknown as ReturnType<GetAccountInfoApi['getAccountInfo']>;\n                const getMultipleAccountsMockResponse = (accounts: MockDataOwner[]) =>\n                    ({\n                        context: {\n                            slot: 0n,\n                        },\n                        value: accounts.map(({ data, owner }) => getAccountInfoMockResponseValue({ data, owner })),\n                    }) as unknown as ReturnType<GetMultipleAccountsApi['getMultipleAccounts']>;\n\n                // First we should see `getMultipleAccounts` used for the first two layers\n                rpc.getMultipleAccounts\n                    .mockImplementationOnce(() => ({\n                        reactiveStore: jest.fn().mockImplementation(() => {\n                            throw new Error('not implemented');\n                        }),\n                        send: () =>\n                            Promise.resolve(\n                                getMultipleAccountsMockResponse([\n                                    {\n                                        data: ['AA', 'base64'],\n                                        owner: '11111111111111111111111111111111',\n                                    },\n                                    {\n                                        data: ['AA', 'base64'],\n                                        owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                    },\n                                    {\n                                        data: ['AA', 'base64'],\n                                        owner: 'Stake11111111111111111111111111111111111111',\n                                    },\n                                    {\n                                        data: ['AA', 'base64'],\n                                        owner: 'Vote111111111111111111111111111111111111111',\n                                    },\n                                ]),\n                            ),\n                    }))\n                    .mockImplementationOnce(() => ({\n                        reactiveStore: jest.fn().mockImplementation(() => {\n                            throw new Error('not implemented');\n                        }),\n                        send: () =>\n                            Promise.resolve(\n                                getMultipleAccountsMockResponse([\n                                    {\n                                        data: ['AA', 'base64'],\n                                        owner: 'NativeLoader1111111111111111111111111111111',\n                                    },\n                                    {\n                                        data: ['AA', 'base64'],\n                                        owner: 'BPFLoader2111111111111111111111111111111111',\n                                    },\n                                    {\n                                        data: ['AA', 'base64'],\n                                        owner: 'NativeLoader1111111111111111111111111111111',\n                                    },\n                                ]),\n                            ),\n                    }));\n\n                // Then we should see `getAccountInfo` used for the single\n                // account in the last layer\n                rpc.getAccountInfo.mockReturnValue({\n                    reactiveStore: jest.fn().mockImplementation(() => {\n                        throw new Error('not implemented');\n                    }),\n                    send: jest.fn().mockResolvedValueOnce({\n                        context: {\n                            slot: 0,\n                        },\n                        value: getAccountInfoMockResponseValue({\n                            data: ['AA', 'base64'],\n                            owner: 'NativeLoader1111111111111111111111111111111',\n                        }),\n                    }),\n                });\n\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        # Nonce account (see scripts/fixtures/nonce-account.json)\n                        account1: account(address: \"AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU\") {\n                            lamports\n                            ownerProgram {\n                                lamports\n                            }\n                        }\n                        # Mint account (see scripts/fixtures/spl-token-mint-account.json)\n                        account2: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            lamports\n                            ownerProgram {\n                                lamports\n                                ownerProgram {\n                                    lamports\n                                }\n                            }\n                        }\n                        # Stake account (see scripts/fixtures/stake-account.json)\n                        account3: account(address: \"CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN\") {\n                            lamports\n                        }\n                        # Vote account (see scripts/fixtures/vote-account.json)\n                        account4: account(address: \"4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp\") {\n                            lamports\n                            ownerProgram {\n                                space\n                            }\n                        }\n                    }\n                `;\n\n                rpcGraphQL.query(source).catch(() => {});\n\n                // Evaluate layer 1\n                await jest.advanceTimersToNextTimerAsync();\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getMultipleAccounts).toHaveBeenLastCalledWith(\n                    [\n                        'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU',\n                        'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN',\n                        '4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp',\n                    ],\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n                rpc.getMultipleAccounts.mockClear();\n\n                // Evaluate layer 2\n                await jest.advanceTimersToNextTimerAsync();\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getMultipleAccounts).toHaveBeenLastCalledWith(\n                    [\n                        '11111111111111111111111111111111',\n                        'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                        'Vote111111111111111111111111111111111111111',\n                    ],\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n                rpc.getMultipleAccounts.mockClear();\n\n                // Evaluate layer 3\n                await jest.advanceTimersToNextTimerAsync();\n                jest.runAllTimers();\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(0);\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('BPFLoader2111111111111111111111111111111111', {\n                    commitment: 'confirmed',\n                    encoding: 'base64', // GraphQL client prefers `base64`\n                });\n            });\n            it('breaks multiple account requests into multiple `getMultipleAccounts` requests if the batch limit is exceeded', async () => {\n                expect.assertions(3);\n\n                rpcGraphQL = createSolanaRpcGraphQL(\n                    rpc as unknown as Rpc<\n                        GetAccountInfoApi &\n                            GetBlockApi &\n                            GetMultipleAccountsApi &\n                            GetProgramAccountsApi &\n                            GetTransactionApi\n                    >,\n                    { maxMultipleAccountsBatchSize: 3 },\n                );\n\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        # Nonce account (see scripts/fixtures/nonce-account.json)\n                        account1: account(address: \"AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU\") {\n                            lamports\n                        }\n                        # Mint account (see scripts/fixtures/spl-token-mint-account.json)\n                        account2: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            lamports\n                        }\n                        # Stake account (see scripts/fixtures/stake-account.json)\n                        account3: account(address: \"CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN\") {\n                            lamports\n                        }\n                        # Vote account (see scripts/fixtures/vote-account.json)\n                        account4: account(address: \"4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp\") {\n                            lamports\n                        }\n                    }\n                `;\n\n                rpcGraphQL.query(source).catch(() => {});\n\n                await jest.runAllTimersAsync();\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(2);\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                    [\n                        'AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU',\n                        'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        'CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN',\n                    ],\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n                expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(['4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp'], {\n                    commitment: 'confirmed',\n                    encoding: 'base64', // GraphQL client prefers `base64`\n                });\n            });\n        });\n        describe('encoding requests', () => {\n            it('does not use `jsonParsed` if no parsed type is queried', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                });\n            });\n            it('uses only `base58` if one data field is requested with `base58` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            data(encoding: BASE_58)\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base58',\n                });\n            });\n            it('uses only `base64` if one data field is requested with `base64` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            data(encoding: BASE_64)\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                });\n            });\n            it('uses only `base64+zstd` if one data field is requested with `base64+zstd` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            data(encoding: BASE_64_ZSTD)\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64+zstd',\n                });\n            });\n            it('only uses `jsonParsed` if a parsed type is queried, but data is not', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                });\n            });\n            it('does not call the loader twice for other base fields and `base58` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            data(encoding: BASE_58)\n                            lamports\n                            space\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base58',\n                });\n            });\n            it('does not call the loader twice for other base fields and `base64` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            data(encoding: BASE_64)\n                            lamports\n                            space\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                });\n            });\n            it('does not call the loader twice for other base fields and `base64+zstd` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            data(encoding: BASE_64_ZSTD)\n                            lamports\n                            space\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64+zstd',\n                });\n            });\n            it('does not call the loader twice for other base fields and inline fragment', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            lamports\n                            space\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                });\n            });\n            it('will not make multiple calls for more than one inline fragment', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            ... on MintAccount {\n                                supply\n                            }\n                            ... on TokenAccount {\n                                lamports\n                            }\n                            ... on NonceAccount {\n                                blockhash\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                });\n            });\n            it('uses `jsonParsed` and the requested data encoding if a parsed type is queried alongside encoded data', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            data(encoding: BASE_64)\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(2);\n                expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                });\n                expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                });\n            });\n            it('uses only the number of requests for the number of different encodings requested', async () => {\n                expect.assertions(4);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                            dataBase58_1: data(encoding: BASE_58)\n                            dataBase58_2: data(encoding: BASE_58)\n                            dataBase58_3: data(encoding: BASE_58)\n                            dataBase64_1: data(encoding: BASE_64)\n                            dataBase64_2: data(encoding: BASE_64)\n                            dataBase64_3: data(encoding: BASE_64)\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(3);\n                expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base58',\n                });\n                expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                });\n                expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                });\n            });\n        });\n        describe('data slice requests', () => {\n            describe('single account queries', () => {\n                it('does not call the loader twice for data slice and other fields', async () => {\n                    expect.assertions(2);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                                lamports\n                                space\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                    expect(rpc.getAccountInfo).toHaveBeenLastCalledWith(\n                        'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 10, offset: 0 },\n                            encoding: 'base64',\n                        },\n                    );\n                });\n                it('coalesces a data with no data slice and data with data slice within byte limit to the same request', async () => {\n                    expect.assertions(2);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataWithNoSlice: data(encoding: BASE_64)\n                                dataWithSlice: data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                    expect(rpc.getAccountInfo).toHaveBeenLastCalledWith(\n                        'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                        {\n                            commitment: 'confirmed',\n                            encoding: 'base64', // No `dataSlice` arg since one field asked for the whole data\n                        },\n                    );\n                });\n                it('coalesces non-sliced and sliced data requests across encodings', async () => {\n                    expect.assertions(3);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataBase58WithNoSlice: data(encoding: BASE_58)\n                                dataBase58WithSlice: data(encoding: BASE_58, dataSlice: { length: 10, offset: 0 })\n                                dataBase64WithNoSlice: data(encoding: BASE_64)\n                                dataBase64WithSlice: data(encoding: BASE_64, dataSlice: { length: 20, offset: 4 })\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getAccountInfo).toHaveBeenCalledTimes(2);\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        encoding: 'base58', // No `dataSlice` arg since one field asked for the whole data\n                    });\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // No `dataSlice` arg since one field asked for the whole data\n                    });\n                });\n                it('always uses separate requests for `base64+zstd` no matter the data slice', async () => {\n                    expect.assertions(4);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataBase64ZstdWithNoSlice: data(encoding: BASE_64_ZSTD)\n                                dataBase64ZstdWithSlice1: data(\n                                    encoding: BASE_64_ZSTD\n                                    dataSlice: { length: 16, offset: 4 }\n                                )\n                                dataBase64ZstdWithSlice2: data(\n                                    encoding: BASE_64_ZSTD\n                                    dataSlice: { length: 40, offset: 12 }\n                                )\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getAccountInfo).toHaveBeenCalledTimes(3);\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        encoding: 'base64+zstd',\n                    });\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 16, offset: 4 },\n                        encoding: 'base64+zstd',\n                    });\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 40, offset: 12 },\n                        encoding: 'base64+zstd',\n                    });\n                });\n                it('coalesces multiple data slice requests within byte limit to the same request', async () => {\n                    expect.assertions(2);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                                dataSlice2: data(encoding: BASE_64, dataSlice: { length: 16, offset: 2 })\n                                dataSlice3: data(encoding: BASE_64, dataSlice: { length: 20, offset: 6 })\n                                dataSlice4: data(encoding: BASE_64, dataSlice: { length: 10, offset: 10 })\n                                dataSlice5: data(encoding: BASE_64, dataSlice: { length: 10, offset: 30 })\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 40, offset: 0 }, // Coalesced into one slice\n                        encoding: 'base64',\n                    });\n                });\n                it('splits multiple data slice requests beyond byte limit into two requests', async () => {\n                    expect.assertions(3);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { length: 4, offset: 0 })\n                                dataSlice2: data(encoding: BASE_64, dataSlice: { length: 4, offset: 2000 })\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getAccountInfo).toHaveBeenCalledTimes(2);\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 4, offset: 0 },\n                        encoding: 'base64',\n                    });\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 4, offset: 2000 },\n                        encoding: 'base64',\n                    });\n                });\n                it('honors the byte limit across encodings', async () => {\n                    expect.assertions(5);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataBase58WithinByteLimit: data(encoding: BASE_58, dataSlice: { length: 4, offset: 0 })\n                                dataBase58BeyondByteLimit: data(\n                                    encoding: BASE_58\n                                    dataSlice: { length: 4, offset: 2000 }\n                                )\n                                dataBase64WithinByteLimit: data(encoding: BASE_64, dataSlice: { length: 4, offset: 0 })\n                                dataBase64BeyondByteLimit: data(\n                                    encoding: BASE_64\n                                    dataSlice: { length: 4, offset: 2000 }\n                                )\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getAccountInfo).toHaveBeenCalledTimes(4);\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 4, offset: 0 },\n                        encoding: 'base58',\n                    });\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 4, offset: 2000 },\n                        encoding: 'base58',\n                    });\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 4, offset: 0 },\n                        encoding: 'base64',\n                    });\n                    expect(rpc.getAccountInfo).toHaveBeenCalledWith('Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr', {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 4, offset: 2000 },\n                        encoding: 'base64',\n                    });\n                });\n            });\n            describe('multiple account queries', () => {\n                it('does not call the loader twice for data slice and other fields', async () => {\n                    expect.assertions(2);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            accountA: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                                lamports\n                                space\n                            }\n                            accountB: account(address: \"2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb\") {\n                                data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                                lamports\n                                space\n                            }\n                            accountC: account(address: \"4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u\") {\n                                data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                                lamports\n                                space\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(1);\n                    expect(rpc.getMultipleAccounts).toHaveBeenLastCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 10, offset: 0 },\n                            encoding: 'base64',\n                        },\n                    );\n                });\n                it('coalesces a data with no data slice and data with data slice within byte limit to the same request', async () => {\n                    expect.assertions(2);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            accountA: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataWithNoSlice: data(encoding: BASE_64)\n                                dataWithSlice: data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                            }\n                            accountB: account(address: \"2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb\") {\n                                dataWithNoSlice: data(encoding: BASE_64)\n                                dataWithSlice: data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                            }\n                            accountC: account(address: \"4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u\") {\n                                dataWithNoSlice: data(encoding: BASE_64)\n                                dataWithSlice: data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(1);\n                    expect(rpc.getMultipleAccounts).toHaveBeenLastCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            encoding: 'base64', // No `dataSlice` arg since one field asked for the whole data\n                        },\n                    );\n                });\n                it('coalesces non-sliced and sliced data requests across encodings', async () => {\n                    expect.assertions(3);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            accountA: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataBase58WithNoSlice: data(encoding: BASE_58)\n                                dataBase58WithSlice: data(encoding: BASE_58, dataSlice: { length: 10, offset: 0 })\n                                dataBase64WithNoSlice: data(encoding: BASE_64)\n                                dataBase64WithSlice: data(encoding: BASE_64, dataSlice: { length: 12, offset: 4 })\n                            }\n                            accountB: account(address: \"2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb\") {\n                                dataBase58WithNoSlice: data(encoding: BASE_58)\n                                dataBase58WithSlice: data(encoding: BASE_58, dataSlice: { length: 14, offset: 4 })\n                                dataBase64WithNoSlice: data(encoding: BASE_64)\n                                dataBase64WithSlice: data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                            }\n                            accountC: account(address: \"4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u\") {\n                                dataBase58WithNoSlice: data(encoding: BASE_58)\n                                dataBase58WithSlice: data(encoding: BASE_58, dataSlice: { length: 10, offset: 50 })\n                                dataBase64WithNoSlice: data(encoding: BASE_64)\n                                dataBase64WithSlice: data(encoding: BASE_64, dataSlice: { length: 100, offset: 0 })\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(2);\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            encoding: 'base58', // No `dataSlice` arg since one field asked for the whole data\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            encoding: 'base64', // No `dataSlice` arg since one field asked for the whole data\n                        },\n                    );\n                });\n                it('coalesces multiple data slice requests within byte limit to the same request', async () => {\n                    expect.assertions(2);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            accountA: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 10 })\n                                dataSlice2: data(encoding: BASE_64, dataSlice: { offset: 2, length: 16 })\n                                dataSlice3: data(encoding: BASE_64, dataSlice: { offset: 6, length: 20 })\n                                dataSlice4: data(encoding: BASE_64, dataSlice: { offset: 10, length: 10 })\n                                dataSlice5: data(encoding: BASE_64, dataSlice: { offset: 30, length: 10 })\n                            }\n                            accountB: account(address: \"2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 10 })\n                                dataSlice2: data(encoding: BASE_64, dataSlice: { offset: 2, length: 16 })\n                                dataSlice3: data(encoding: BASE_64, dataSlice: { offset: 6, length: 20 })\n                                dataSlice4: data(encoding: BASE_64, dataSlice: { offset: 10, length: 10 })\n                                dataSlice5: data(encoding: BASE_64, dataSlice: { offset: 30, length: 10 })\n                            }\n                            accountC: account(address: \"4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 10 })\n                                dataSlice2: data(encoding: BASE_64, dataSlice: { offset: 2, length: 16 })\n                                dataSlice3: data(encoding: BASE_64, dataSlice: { offset: 6, length: 20 })\n                                dataSlice4: data(encoding: BASE_64, dataSlice: { offset: 10, length: 10 })\n                                dataSlice5: data(encoding: BASE_64, dataSlice: { offset: 30, length: 10 })\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(1);\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 40, offset: 0 }, // Coalesced into one slice\n                            encoding: 'base64',\n                        },\n                    );\n                });\n                it('splits multiple data slice requests beyond the default byte limit into two requests', async () => {\n                    expect.assertions(3);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            accountA: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataSlice2: data(encoding: BASE_64, dataSlice: { offset: 2000, length: 4 })\n                            }\n                            accountB: account(address: \"2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataSlice2: data(encoding: BASE_64, dataSlice: { offset: 2000, length: 4 })\n                            }\n                            accountC: account(address: \"4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataSlice2: data(encoding: BASE_64, dataSlice: { offset: 2000, length: 4 })\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(2);\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 0 },\n                            encoding: 'base64',\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 2000 },\n                            encoding: 'base64',\n                        },\n                    );\n                });\n                it('splits multiple data slice requests beyond a provided byte limit into two requests', async () => {\n                    expect.assertions(3);\n                    const maxDataSliceByteRange = 100;\n                    rpcGraphQL = createSolanaRpcGraphQL(\n                        rpc as unknown as Rpc<\n                            GetAccountInfoApi &\n                                GetBlockApi &\n                                GetMultipleAccountsApi &\n                                GetProgramAccountsApi &\n                                GetTransactionApi\n                        >,\n                        {\n                            maxDataSliceByteRange,\n                        },\n                    );\n                    const source = /* GraphQL */ `\n                        query testQuery($maxDataSliceByteRange: Int!) {\n                            accountA: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataSlice2: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                            }\n                            accountB: account(address: \"2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataSlice2: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                            }\n                            accountC: account(address: \"4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u\") {\n                                dataSlice1: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataSlice2: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source, { maxDataSliceByteRange }).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(2);\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 0 },\n                            encoding: 'base64',\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: maxDataSliceByteRange },\n                            encoding: 'base64',\n                        },\n                    );\n                });\n                it('honors the default byte limit across encodings', async () => {\n                    expect.assertions(5);\n                    const source = /* GraphQL */ `\n                        query testQuery {\n                            accountA: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataBase58WithinByteLimit: data(encoding: BASE_58, dataSlice: { offset: 0, length: 4 })\n                                dataBase58BeyondByteLimit: data(\n                                    encoding: BASE_58\n                                    dataSlice: { offset: 2000, length: 4 }\n                                )\n                                dataBase64WithinByteLimit: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataBase64BeyondByteLimit: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: 2000, length: 4 }\n                                )\n                            }\n                            accountB: account(address: \"2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb\") {\n                                dataBase58WithinByteLimit: data(encoding: BASE_58, dataSlice: { offset: 0, length: 4 })\n                                dataBase58BeyondByteLimit: data(\n                                    encoding: BASE_58\n                                    dataSlice: { offset: 2000, length: 4 }\n                                )\n                                dataBase64WithinByteLimit: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataBase64BeyondByteLimit: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: 2000, length: 4 }\n                                )\n                            }\n                            accountC: account(address: \"4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u\") {\n                                dataBase58WithinByteLimit: data(encoding: BASE_58, dataSlice: { offset: 0, length: 4 })\n                                dataBase58BeyondByteLimit: data(\n                                    encoding: BASE_58\n                                    dataSlice: { offset: 2000, length: 4 }\n                                )\n                                dataBase64WithinByteLimit: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataBase64BeyondByteLimit: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: 2000, length: 4 }\n                                )\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(4);\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 0 },\n                            encoding: 'base58',\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 2000 },\n                            encoding: 'base58',\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 0 },\n                            encoding: 'base64',\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 2000 },\n                            encoding: 'base64',\n                        },\n                    );\n                });\n                it('honors a provided byte limit across encodings', async () => {\n                    expect.assertions(5);\n                    const maxDataSliceByteRange = 100;\n                    rpcGraphQL = createSolanaRpcGraphQL(\n                        rpc as unknown as Rpc<\n                            GetAccountInfoApi &\n                                GetBlockApi &\n                                GetMultipleAccountsApi &\n                                GetProgramAccountsApi &\n                                GetTransactionApi\n                        >,\n                        {\n                            maxDataSliceByteRange,\n                        },\n                    );\n                    const source = /* GraphQL */ `\n                        query testQuery($maxDataSliceByteRange: Int!) {\n                            accountA: account(address: \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\") {\n                                dataBase58WithinByteLimit: data(encoding: BASE_58, dataSlice: { offset: 0, length: 4 })\n                                dataBase58BeyondByteLimit: data(\n                                    encoding: BASE_58\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                                dataBase64WithinByteLimit: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataBase64BeyondByteLimit: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                            }\n                            accountB: account(address: \"2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb\") {\n                                dataBase58WithinByteLimit: data(encoding: BASE_58, dataSlice: { offset: 0, length: 4 })\n                                dataBase58BeyondByteLimit: data(\n                                    encoding: BASE_58\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                                dataBase64WithinByteLimit: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataBase64BeyondByteLimit: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                            }\n                            accountC: account(address: \"4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u\") {\n                                dataBase58WithinByteLimit: data(encoding: BASE_58, dataSlice: { offset: 0, length: 4 })\n                                dataBase58BeyondByteLimit: data(\n                                    encoding: BASE_58\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                                dataBase64WithinByteLimit: data(encoding: BASE_64, dataSlice: { offset: 0, length: 4 })\n                                dataBase64BeyondByteLimit: data(\n                                    encoding: BASE_64\n                                    dataSlice: { offset: $maxDataSliceByteRange, length: 4 }\n                                )\n                            }\n                        }\n                    `;\n                    rpcGraphQL.query(source, { maxDataSliceByteRange }).catch(() => {});\n                    await jest.runAllTimersAsync();\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledTimes(4);\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 0 },\n                            encoding: 'base58',\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: maxDataSliceByteRange },\n                            encoding: 'base58',\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: 0 },\n                            encoding: 'base64',\n                        },\n                    );\n                    expect(rpc.getMultipleAccounts).toHaveBeenCalledWith(\n                        [\n                            'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr',\n                            '2KAARoNUYTddAChEdWb21bdKH6dWu51AAPFjSjRmzsbb',\n                            '4rFV8bvFpacLkvxTFuVN4pqe5s7CTyEkmYvPpu45779u',\n                        ],\n                        {\n                            commitment: 'confirmed',\n                            dataSlice: { length: 4, offset: maxDataSliceByteRange },\n                            encoding: 'base64',\n                        },\n                    );\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/__tests__/block-loader-test.ts",
    "content": "import type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\nimport type { Slot } from '@solana/rpc-types';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../../index';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('account loader', () => {\n    let rpc: Rpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>;\n    let rpcGraphQL: RpcGraphQL;\n    // Random slot for testing.\n    // Not actually used. Just needed for proper query parsing.\n    const slot = 511226n as Slot;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        rpc = {\n            getAccountInfo: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getBlock: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getMultipleAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getProgramAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getTransaction: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n        };\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    describe('cached responses', () => {\n        it('coalesces multiple requests for the same block into one', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block1: block(slot: $slot) {\n                        blockhash\n                    }\n                    block2: block(slot: $slot) {\n                        blockhash\n                    }\n                    block3: block(slot: $slot) {\n                        blockhash\n                    }\n                }\n            `;\n            rpcGraphQL.query(source, { slot }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n        });\n        it('cache resets on new tick', async () => {\n            expect.assertions(1);\n            await jest.runAllTimersAsync();\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        blockhash\n                    }\n                }\n            `;\n            // Call the query twice\n            rpcGraphQL.query(source, { slot }).catch(() => {});\n            rpcGraphQL.query(source, { slot }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getBlock).toHaveBeenCalledTimes(2);\n        });\n    });\n    describe('batch loading', () => {\n        describe('request partitioning', () => {\n            it('coalesces multiple requests for the same block but different fields into one request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block1: block(slot: $slot) {\n                            blockhash\n                        }\n                        block2: block(slot: $slot) {\n                            blockTime\n                        }\n                        block3: block(slot: $slot) {\n                            previousBlockhash\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'none',\n                });\n            });\n            it('coalesces multiple requests for the same block but one with specified `confirmed` commitment into one request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block1: block(slot: $slot) {\n                            blockhash\n                        }\n                        block2: block(slot: $slot, commitment: CONFIRMED) {\n                            blockhash\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'none',\n                });\n            });\n            it('will not coalesce multiple requests for the same block but with different commitments into one request', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block1: block(slot: $slot) {\n                            blockhash\n                        }\n                        block2: block(slot: $slot, commitment: CONFIRMED) {\n                            blockhash\n                        }\n                        block3: block(slot: $slot, commitment: FINALIZED) {\n                            blockhash\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(2);\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'confirmed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'none',\n                });\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'finalized',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'none',\n                });\n            });\n        });\n        describe('encoding requests', () => {\n            it('does not use `jsonParsed` if no parsed type is queried', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            blockhash\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'none',\n                });\n            });\n            it('uses only `base58` if one data field is requested with `base58` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                data(encoding: BASE_58)\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base58',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n            it('uses only `base64` if one data field is requested with `base64` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                data(encoding: BASE_64)\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n            it('only uses `jsonParsed` if a parsed type is queried, but data is not', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                message {\n                                    recentBlockhash\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n            it('does not call the loader twice for other base fields and `base58` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            blockhash\n                            transactions {\n                                data(encoding: BASE_58)\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base58',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n            it('does not call the loader twice for other base fields and `base64` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            blockhash\n                            transactions {\n                                data(encoding: BASE_64)\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n            it('does not call the loader twice for other base fields and inline fragment', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                message {\n                                    recentBlockhash\n                                    instructions {\n                                        ... on GenericInstruction {\n                                            programId\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n            it('will not make multiple calls for more than one inline fragment', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                message {\n                                    recentBlockhash\n                                    instructions {\n                                        ... on GenericInstruction {\n                                            programId\n                                        }\n                                        ... on CreateLookupTableInstruction {\n                                            programId\n                                        }\n                                        ... on CloseLookupTableInstruction {\n                                            programId\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n            it('uses `jsonParsed` and the requested data encoding if a parsed type is queried alongside encoded data', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                data(encoding: BASE_64)\n                                message {\n                                    recentBlockhash\n                                    instructions {\n                                        ... on GenericInstruction {\n                                            programId\n                                        }\n                                        ... on CreateLookupTableInstruction {\n                                            programId\n                                        }\n                                        ... on CloseLookupTableInstruction {\n                                            programId\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(2);\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n            it('uses only the number of requests for the number of different encodings requested', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            transactions {\n                                dataBase58: data(encoding: BASE_58)\n                                dataBase64: data(encoding: BASE_64)\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(2);\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base58',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n            });\n        });\n        describe('signatures-only requests', () => {\n            it('uses only `signatures` if the `signatures` field is requested', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            signatures\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'signatures',\n                });\n            });\n            it('uses only `signatures` if the `signatures` field is requested with other fields', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            blockhash\n                            blockTime\n                            signatures\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n                expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                    commitment: 'confirmed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'signatures',\n                });\n            });\n            it('will call once for `signatures` as well as once per encoding', async () => {\n                expect.assertions(4);\n                const source = /* GraphQL */ `\n                    query testQuery($slot: Slot!) {\n                        block(slot: $slot) {\n                            blockhash\n                            blockTime\n                            signatures\n                            transactions {\n                                dataBase58: data(encoding: BASE_58)\n                                dataBase64: data(encoding: BASE_64)\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { slot }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getBlock).toHaveBeenCalledTimes(3);\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base58',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'full',\n                });\n                expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                    commitment: 'confirmed',\n                    maxSupportedTransactionVersion: 0,\n                    transactionDetails: 'signatures',\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/__tests__/program-accounts-loader-test.ts",
    "content": "import type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../../index';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('account loader', () => {\n    let rpc: Rpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>;\n    let rpcGraphQL: RpcGraphQL;\n    // Random address for testing.\n    // Not actually used. Just needed for proper query parsing.\n    const programAddress = 'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj';\n    beforeEach(() => {\n        jest.useFakeTimers();\n        rpc = {\n            getAccountInfo: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getBlock: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getMultipleAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getProgramAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getTransaction: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n        };\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    describe('cached responses', () => {\n        it('coalesces multiple requests for the same program into one', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts1: programAccounts(programAddress: $programAddress) {\n                        lamports\n                    }\n                    programAccounts2: programAccounts(programAddress: $programAddress) {\n                        lamports\n                    }\n                    programAccounts3: programAccounts(programAddress: $programAddress) {\n                        lamports\n                    }\n                }\n            `;\n            rpcGraphQL.query(source, { programAddress }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n        });\n        it('cache resets on new tick', async () => {\n            expect.assertions(1);\n            await jest.runAllTimersAsync();\n            const source = /* GraphQL */ `\n                query testQuery($programAddress: Address!) {\n                    programAccounts(programAddress: $programAddress) {\n                        lamports\n                    }\n                }\n            `;\n            // Call the query twice\n            rpcGraphQL.query(source, { programAddress }).catch(() => {});\n            rpcGraphQL.query(source, { programAddress }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(2);\n        });\n    });\n    describe('batch loading', () => {\n        describe('request partitioning', () => {\n            it('coalesces multiple requests for the same program but different fields into one request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        programAccounts1: programAccounts(programAddress: $address) {\n                            lamports\n                        }\n                        programAccounts2: programAccounts(programAddress: $address) {\n                            space\n                        }\n                        programAccounts3: programAccounts(programAddress: $address) {\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { address: 'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('coalesces multiple requests for the same program but one with specified `confirmed` commitment into one request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        programAccounts1: programAccounts(programAddress: $address) {\n                            lamports\n                        }\n                        programAccounts2: programAccounts(programAddress: $address, commitment: CONFIRMED) {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { address: 'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n            });\n            it('will not coalesce multiple requests for the same program but with different commitments into one request', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery($address: Address!) {\n                        programAccounts1: programAccounts(programAddress: $address) {\n                            lamports\n                        }\n                        programAccounts2: programAccounts(programAddress: $address, commitment: CONFIRMED) {\n                            lamports\n                        }\n                        programAccounts3: programAccounts(programAddress: $address, commitment: FINALIZED) {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source, { address: 'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj' }).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(2);\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'base64', // GraphQL client prefers `base64`\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'finalized',\n                    encoding: 'base64', // GraphQL client prefers `base64`\n                });\n            });\n        });\n        describe('encoding requests', () => {\n            it('does not use `jsonParsed` if no parsed type is queried', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            lamports\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64',\n                    },\n                );\n            });\n            it('uses only `base58` if one data field is requested with `base58` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            data(encoding: BASE_58)\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base58',\n                    },\n                );\n            });\n            it('uses only `base64` if one data field is requested with `base64` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            data(encoding: BASE_64)\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64',\n                    },\n                );\n            });\n            it('uses only `base64+zstd` if one data field is requested with `base64+zstd` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            data(encoding: BASE_64_ZSTD)\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64+zstd',\n                    },\n                );\n            });\n            it('only uses `jsonParsed` if a parsed type is queried, but data is not', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('does not call the loader twice for other base fields and `base58` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            data(encoding: BASE_58)\n                            lamports\n                            space\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base58',\n                    },\n                );\n            });\n            it('does not call the loader twice for other base fields and `base64` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            data(encoding: BASE_64)\n                            lamports\n                            space\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64',\n                    },\n                );\n            });\n            it('does not call the loader twice for other base fields and `base64+zstd` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            data(encoding: BASE_64_ZSTD)\n                            lamports\n                            space\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64+zstd',\n                    },\n                );\n            });\n            it('does not call the loader twice for other base fields and inline fragment', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            lamports\n                            space\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('will not make multiple calls for more than one inline fragment', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            ... on MintAccount {\n                                supply\n                            }\n                            ... on TokenAccount {\n                                lamports\n                            }\n                            ... on NonceAccount {\n                                blockhash\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('uses `jsonParsed` and the requested data encoding if a parsed type is queried alongside encoded data', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            data(encoding: BASE_64)\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(2);\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                });\n            });\n            it('uses only the number of requests for the number of different encodings requested', async () => {\n                expect.assertions(5);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            dataBase58_1: data(encoding: BASE_58)\n                            dataBase58_2: data(encoding: BASE_58)\n                            dataBase58_3: data(encoding: BASE_58)\n                            dataBase64_1: data(encoding: BASE_64)\n                            dataBase64_2: data(encoding: BASE_64)\n                            dataBase64_3: data(encoding: BASE_64)\n                            dataBase64Zstd_1: data(encoding: BASE_64_ZSTD)\n                            dataBase64Zstd_2: data(encoding: BASE_64_ZSTD)\n                            dataBase64Zstd_3: data(encoding: BASE_64_ZSTD)\n                            ... on MintAccount {\n                                supply\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(4);\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'base58',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'base64',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'base64+zstd',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'jsonParsed',\n                });\n            });\n        });\n        describe('data slice requests', () => {\n            it('does not call the loader twice for data slice and other fields', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                            lamports\n                            space\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        dataSlice: { length: 10, offset: 0 },\n                        encoding: 'base64',\n                    },\n                );\n            });\n            it('coalesces a data with no data slice and data with data slice within byte limit to the same request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            dataWithNoSlice: data(encoding: BASE_64)\n                            dataWithSlice: data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith(\n                    'DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // No `dataSlice` arg since one field asked for the whole data\n                    },\n                );\n            });\n            it('coalesces non-sliced and sliced data requests across encodings', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            dataBase58WithNoSlice: data(encoding: BASE_58)\n                            dataBase58WithSlice: data(encoding: BASE_58, dataSlice: { length: 10, offset: 0 })\n                            dataBase64WithNoSlice: data(encoding: BASE_64)\n                            dataBase64WithSlice: data(encoding: BASE_64, dataSlice: { length: 20, offset: 4 })\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(2);\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'base58', // No `dataSlice` arg since one field asked for the whole data\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'base64', // No `dataSlice` arg since one field asked for the whole data\n                });\n            });\n            it('always uses separate requests for `base64+zstd` no matter the data slice', async () => {\n                expect.assertions(4);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            dataBase64ZstdWithNoSlice: data(encoding: BASE_64_ZSTD)\n                            dataBase64ZstdWithSlice1: data(encoding: BASE_64_ZSTD, dataSlice: { length: 16, offset: 4 })\n                            dataBase64ZstdWithSlice2: data(\n                                encoding: BASE_64_ZSTD\n                                dataSlice: { length: 40, offset: 12 }\n                            )\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(3);\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    encoding: 'base64+zstd',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 16, offset: 4 },\n                    encoding: 'base64+zstd',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 40, offset: 12 },\n                    encoding: 'base64+zstd',\n                });\n            });\n            it('coalesces multiple data slice requests within byte limit to the same request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            dataSlice1: data(encoding: BASE_64, dataSlice: { length: 10, offset: 0 })\n                            dataSlice2: data(encoding: BASE_64, dataSlice: { length: 16, offset: 2 })\n                            dataSlice3: data(encoding: BASE_64, dataSlice: { length: 20, offset: 6 })\n                            dataSlice4: data(encoding: BASE_64, dataSlice: { length: 10, offset: 10 })\n                            dataSlice5: data(encoding: BASE_64, dataSlice: { length: 10, offset: 30 })\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 40, offset: 0 }, // Coalesced into one slice\n                    encoding: 'base64',\n                });\n            });\n            it('splits multiple data slice requests beyond byte limit into two requests', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            dataSlice1: data(encoding: BASE_64, dataSlice: { length: 4, offset: 0 })\n                            dataSlice2: data(encoding: BASE_64, dataSlice: { length: 4, offset: 2000 })\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(2);\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 4, offset: 0 },\n                    encoding: 'base64',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 4, offset: 2000 },\n                    encoding: 'base64',\n                });\n            });\n            it('honors the byte limit across encodings', async () => {\n                expect.assertions(5);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        programAccounts(programAddress: \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\") {\n                            dataBase58WithinByteLimit: data(encoding: BASE_58, dataSlice: { length: 4, offset: 0 })\n                            dataBase58BeyondByteLimit: data(encoding: BASE_58, dataSlice: { length: 4, offset: 2000 })\n                            dataBase64WithinByteLimit: data(encoding: BASE_64, dataSlice: { length: 4, offset: 0 })\n                            dataBase64BeyondByteLimit: data(encoding: BASE_64, dataSlice: { length: 4, offset: 2000 })\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(4);\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 4, offset: 0 },\n                    encoding: 'base58',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 4, offset: 2000 },\n                    encoding: 'base58',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 4, offset: 0 },\n                    encoding: 'base64',\n                });\n                expect(rpc.getProgramAccounts).toHaveBeenCalledWith('DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj', {\n                    commitment: 'confirmed',\n                    dataSlice: { length: 4, offset: 2000 },\n                    encoding: 'base64',\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/__tests__/transaction-loader-test.ts",
    "content": "import type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../../index';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('account loader', () => {\n    let rpc: Rpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>;\n    let rpcGraphQL: RpcGraphQL;\n    // Random signature for testing.\n    // Not actually used. Just needed for proper query parsing.\n    const signature = '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk';\n    beforeEach(() => {\n        jest.useFakeTimers();\n        rpc = {\n            getAccountInfo: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getBlock: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getMultipleAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getProgramAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getTransaction: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n        };\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    describe('cached responses', () => {\n        it('coalesces multiple requests for the same transaction into one', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction1: transaction(signature: $signature) {\n                        slot\n                    }\n                    transaction2: transaction(signature: $signature) {\n                        slot\n                    }\n                    transaction3: transaction(signature: $signature) {\n                        slot\n                    }\n                }\n            `;\n            rpcGraphQL.query(source, { signature }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n        });\n        it('cache resets on new tick', async () => {\n            expect.assertions(1);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        slot\n                    }\n                }\n            `;\n            // Call the query twice\n            rpcGraphQL.query(source, { signature }).catch(() => {});\n            rpcGraphQL.query(source, { signature }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getTransaction).toHaveBeenCalledTimes(2);\n        });\n    });\n    describe('batch loading', () => {\n        describe('request partitioning', () => {\n            it('coalesces multiple requests for the same transaction but different fields into one request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction1: transaction(signature: $signature) {\n                            blockTime\n                        }\n                        transaction2: transaction(signature: $signature) {\n                            slot\n                        }\n                        transaction3: transaction(signature: $signature) {\n                            message {\n                                instructions {\n                                    ... on SplTokenInitializeMintInstruction {\n                                        decimals\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL\n                    .query(source, {\n                        signature:\n                            '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    })\n                    .catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('coalesces multiple requests for the same transaction but one with specified `confirmed` commitment into one request', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction1: transaction(signature: $signature) {\n                            blockTime\n                        }\n                        transaction2: transaction(signature: $signature, commitment: CONFIRMED) {\n                            blockTime\n                        }\n                    }\n                `;\n                rpcGraphQL\n                    .query(source, {\n                        signature:\n                            '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    })\n                    .catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n            });\n            it('will not coalesce multiple requests for the same transaction but with different commitments into one request', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery($signature: Signature!) {\n                        transaction1: transaction(signature: $signature) {\n                            blockTime\n                        }\n                        transaction2: transaction(signature: $signature, commitment: CONFIRMED) {\n                            blockTime\n                        }\n                        transaction3: transaction(signature: $signature, commitment: FINALIZED) {\n                            blockTime\n                        }\n                    }\n                `;\n                rpcGraphQL\n                    .query(source, {\n                        signature:\n                            '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    })\n                    .catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(2);\n                expect(rpc.getTransaction).toHaveBeenCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n                expect(rpc.getTransaction).toHaveBeenCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'finalized',\n                        encoding: 'base64', // GraphQL client prefers `base64`\n                    },\n                );\n            });\n        });\n        describe('encoding requests', () => {\n            it('does not use `jsonParsed` if no parsed type is queried', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            blockTime\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64',\n                    },\n                );\n            });\n            it('uses only `base58` if one data field is requested with `base58` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            data(encoding: BASE_58)\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base58',\n                    },\n                );\n            });\n            it('uses only `base64` if one data field is requested with `base64` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            data(encoding: BASE_64)\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64',\n                    },\n                );\n            });\n            it('only uses `jsonParsed` if a parsed type is queried, but data is not', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            message {\n                                instructions {\n                                    ... on SplTokenInitializeMintInstruction {\n                                        decimals\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('does not call the loader twice for other base fields and `base58` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            blockTime\n                            data(encoding: BASE_58)\n                            slot\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base58',\n                    },\n                );\n            });\n            it('does not call the loader twice for other base fields and `base64` encoding', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            blockTime\n                            data(encoding: BASE_64)\n                            slot\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64',\n                    },\n                );\n            });\n            it('does not call the loader twice for other base fields and inline fragment', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            message {\n                                instructions {\n                                    ... on SplTokenInitializeMintInstruction {\n                                        decimals\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('will not make multiple calls for more than one inline fragment', async () => {\n                expect.assertions(2);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            message {\n                                instructions {\n                                    ... on SplTokenInitializeMintInstruction {\n                                        decimals\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                    ... on SplTokenInitializeAccountInstruction {\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                    ... on SplTokenInitializeMultisigInstruction {\n                                        multisig {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n                expect(rpc.getTransaction).toHaveBeenLastCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('uses `jsonParsed` and the requested data encoding if a parsed type is queried alongside encoded data', async () => {\n                expect.assertions(3);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            data(encoding: BASE_64)\n                            message {\n                                instructions {\n                                    ... on SplTokenInitializeMintInstruction {\n                                        decimals\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(2);\n                expect(rpc.getTransaction).toHaveBeenCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64',\n                    },\n                );\n                expect(rpc.getTransaction).toHaveBeenCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n            it('uses only the number of requests for the number of different encodings requested', async () => {\n                expect.assertions(4);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        transaction(\n                            signature: \"67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk\"\n                        ) {\n                            dataBase58_1: data(encoding: BASE_58)\n                            dataBase58_2: data(encoding: BASE_58)\n                            dataBase58_3: data(encoding: BASE_58)\n                            dataBase64_1: data(encoding: BASE_64)\n                            dataBase64_2: data(encoding: BASE_64)\n                            dataBase64_3: data(encoding: BASE_64)\n                            message {\n                                instructions {\n                                    ... on SplTokenInitializeMintInstruction {\n                                        decimals\n                                        mint {\n                                            address\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getTransaction).toHaveBeenCalledTimes(3);\n                expect(rpc.getTransaction).toHaveBeenCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base58',\n                    },\n                );\n                expect(rpc.getTransaction).toHaveBeenCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'base64',\n                    },\n                );\n                expect(rpc.getTransaction).toHaveBeenCalledWith(\n                    '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk',\n                    {\n                        commitment: 'confirmed',\n                        encoding: 'jsonParsed',\n                    },\n                );\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/account.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { getBase58Codec, getBase64Codec } from '@solana/codecs-strings';\nimport type { GetAccountInfoApi, GetMultipleAccountsApi, Rpc } from '@solana/rpc';\nimport DataLoader from 'dataloader';\n\nimport { buildCoalescedFetchesByArgsHashWithDataSlice, ToFetchMap } from './coalescer';\nimport {\n    AccountLoader,\n    AccountLoaderArgs,\n    AccountLoaderArgsBase,\n    AccountLoaderValue,\n    cacheKeyFn,\n    MultipleAccountsLoaderArgs,\n} from './loader';\n\ntype Config = {\n    maxDataSliceByteRange: number;\n    maxMultipleAccountsBatchSize: number;\n};\n\ntype Encoding = 'base58' | 'base64' | 'base64+zstd';\ntype DataSlice = { length: number; offset: number };\n\nfunction getCodec(encoding: Encoding) {\n    switch (encoding) {\n        case 'base58':\n            return getBase58Codec();\n        default:\n            return getBase64Codec();\n    }\n}\n\nexport function sliceData(\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    account: any,\n    dataSlice?: DataSlice | null,\n    masterDataSlice?: DataSlice,\n) {\n    if (dataSlice) {\n        const masterOffset = masterDataSlice ? masterDataSlice.offset : 0;\n\n        const slicedData = (data: string, encoding: Encoding): string => {\n            if (encoding === 'base64+zstd') {\n                // Don't slice `base64+zstd` encoding.\n                return data;\n            }\n            const { offset, length } = dataSlice;\n            const trueOffset = offset - masterOffset;\n            const codec = getCodec(encoding);\n            return codec.decode(codec.encode(data).slice(trueOffset, trueOffset + length));\n        };\n\n        if (Array.isArray(account.data)) {\n            const [data, encoding] = account.data;\n            return {\n                ...account,\n                data: [slicedData(data, encoding), encoding],\n            };\n        } else if (typeof account.data === 'string') {\n            const data = account.data;\n            return {\n                ...account,\n                data: slicedData(data, 'base58'),\n            };\n        }\n    }\n    return account;\n}\n\n/**\n * Load an account using the RPC's `getAccountInfo` method.\n */\nasync function loadAccount(rpc: Rpc<GetAccountInfoApi>, { address, ...config }: AccountLoaderArgs) {\n    return await rpc\n        .getAccountInfo(address, config)\n        .send()\n        .then(res => res.value);\n}\n\n/**\n * Load multiple accounts using the RPC's `getMultipleAccounts` method.\n */\nasync function loadMultipleAccounts(\n    rpc: Rpc<GetMultipleAccountsApi>,\n    { addresses, ...config }: MultipleAccountsLoaderArgs,\n) {\n    return await rpc\n        .getMultipleAccounts(addresses, config)\n        .send()\n        .then(res => res.value);\n}\n\nfunction createAccountBatchLoadFn(rpc: Rpc<GetAccountInfoApi & GetMultipleAccountsApi>, config: Config) {\n    const resolveAccountUsingRpc = loadAccount.bind(null, rpc);\n    const resolveMultipleAccountsUsingRpc = loadMultipleAccounts.bind(null, rpc);\n    return (accountQueryArgs: readonly AccountLoaderArgs[]): ReturnType<AccountLoader['loadMany']> => {\n        /**\n         * Gather all the accounts that need to be fetched, grouped by address.\n         */\n        const accountsToFetch: ToFetchMap<AccountLoaderArgsBase, AccountLoaderValue> = {};\n        try {\n            return Promise.all(\n                accountQueryArgs.map(\n                    ({ address, ...args }) =>\n                        new Promise((resolve, reject) => {\n                            const accountRecords = (accountsToFetch[address] ||= []);\n                            // Apply the default commitment level.\n                            if (!args.commitment) {\n                                args.commitment = 'confirmed';\n                            }\n                            accountRecords.push({ args, promiseCallback: { reject, resolve } });\n                        }),\n                ),\n            ) as ReturnType<AccountLoader['loadMany']>;\n        } finally {\n            const { maxDataSliceByteRange, maxMultipleAccountsBatchSize } = config;\n\n            /**\n             * Group together accounts that are fetched with identical args.\n             */\n            const accountFetchesByArgsHash = buildCoalescedFetchesByArgsHashWithDataSlice(\n                accountsToFetch,\n                maxDataSliceByteRange,\n            );\n\n            /**\n             * For each set of accounts related to some common args, fetch them in the fewest number\n             * of network requests.\n             */\n            Object.values(accountFetchesByArgsHash).map(({ args, fetches: addressCallbacks }) => {\n                const addresses = Object.keys(addressCallbacks) as Address[];\n                if (addresses.length === 1) {\n                    const address = addresses[0];\n                    return Array.from({ length: 1 }, async () => {\n                        try {\n                            const result = await resolveAccountUsingRpc({ address, ...args });\n                            addressCallbacks[address].callbacks.forEach(({ callback, dataSlice }) => {\n                                callback.resolve(sliceData(result, dataSlice, args.dataSlice));\n                            });\n                        } catch (e) {\n                            addressCallbacks[address].callbacks.forEach(({ callback }) => {\n                                callback.reject(e);\n                            });\n                        }\n                    });\n                } else {\n                    return Array.from(\n                        { length: Math.ceil(addresses.length / maxMultipleAccountsBatchSize) },\n                        async (_, ii) => {\n                            const startIndex = ii * maxMultipleAccountsBatchSize;\n                            const endIndex = startIndex + maxMultipleAccountsBatchSize;\n                            const chunk = addresses.slice(startIndex, endIndex);\n                            try {\n                                const results = await resolveMultipleAccountsUsingRpc({\n                                    addresses: chunk,\n                                    ...args,\n                                });\n                                chunk.forEach((address, ii) => {\n                                    const result = results[ii];\n                                    addressCallbacks[address].callbacks.forEach(({ callback, dataSlice }) => {\n                                        callback.resolve(sliceData(result, dataSlice, args.dataSlice));\n                                    });\n                                });\n                            } catch (e) {\n                                chunk.forEach(address => {\n                                    addressCallbacks[address].callbacks.forEach(({ callback }) => {\n                                        callback.reject(e);\n                                    });\n                                });\n                            }\n                        },\n                    );\n                }\n            });\n        }\n    };\n}\n\nexport function createAccountLoader(\n    rpc: Rpc<GetAccountInfoApi & GetMultipleAccountsApi>,\n    config: Config,\n): AccountLoader {\n    const loader = new DataLoader(createAccountBatchLoadFn(rpc, config), { cacheKeyFn });\n    return {\n        load: args => loader.load(args),\n        loadMany: args => loader.loadMany(args),\n    };\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/block.ts",
    "content": "import type { GetBlockApi, Rpc } from '@solana/rpc';\nimport DataLoader from 'dataloader';\n\nimport { buildCoalescedFetchesByArgsHash, ToFetchMap } from './coalescer';\nimport { BlockLoader, BlockLoaderArgs, BlockLoaderArgsBase, BlockLoaderValue, cacheKeyFn } from './loader';\n\nasync function loadBlock(rpc: Rpc<GetBlockApi>, { slot, ...config }: BlockLoaderArgs): Promise<BlockLoaderValue> {\n    // @ts-expect-error FIX ME: https://github.com/microsoft/TypeScript/issues/43187\n    return await rpc\n        .getBlock(\n            slot,\n            // @ts-expect-error FIX ME: https://github.com/microsoft/TypeScript/issues/43187\n            config,\n        )\n        .send();\n}\n\nfunction createBlockBatchLoadFn(rpc: Rpc<GetBlockApi>) {\n    const resolveBlockUsingRpc = loadBlock.bind(null, rpc);\n    return (blockQueryArgs: readonly BlockLoaderArgs[]): ReturnType<BlockLoader['loadMany']> => {\n        /**\n         * Gather all the blocks that need to be fetched, grouped by slot.\n         */\n        const blocksToFetch: ToFetchMap<BlockLoaderArgsBase, BlockLoaderValue> = {};\n        try {\n            return Promise.all(\n                blockQueryArgs.map(\n                    ({ slot, ...args }) =>\n                        new Promise((resolve, reject) => {\n                            const blockRecords = (blocksToFetch[slot.toString()] ||= []);\n                            // Apply the default commitment level.\n                            if (!args.commitment) {\n                                args.commitment = 'confirmed';\n                            }\n                            blockRecords.push({ args, promiseCallback: { reject, resolve } });\n                        }),\n                ),\n            ) as ReturnType<BlockLoader['loadMany']>;\n        } finally {\n            /**\n             * Group together blocks that are fetched with identical args.\n             */\n            const blockFetchesByArgsHash = buildCoalescedFetchesByArgsHash(blocksToFetch, {\n                criteria: (args: BlockLoaderArgsBase) =>\n                    args.encoding === undefined && args.transactionDetails !== 'signatures',\n                defaults: (args: BlockLoaderArgsBase) => ({\n                    ...args,\n                    transactionDetails: 'none' as BlockLoaderArgsBase['transactionDetails'],\n                }),\n                hashOmit: ['encoding', 'transactionDetails'],\n            });\n\n            /**\n             * For each set of blocks related to some common args, fetch them in the fewest number\n             * of network requests.\n             */\n            Object.values(blockFetchesByArgsHash).map(({ args, fetches: blockCallbacks }) => {\n                return Object.entries(blockCallbacks).map(([slot, { callbacks }]) => {\n                    return Array.from({ length: 1 }, async () => {\n                        try {\n                            const result = await resolveBlockUsingRpc({\n                                slot: BigInt(slot),\n                                ...args,\n                            });\n                            callbacks.forEach(c => c.resolve(result));\n                        } catch (e) {\n                            callbacks.forEach(c => c.reject(e));\n                        }\n                    });\n                });\n            });\n        }\n    };\n}\n\nexport function createBlockLoader(rpc: Rpc<GetBlockApi>): BlockLoader {\n    const loader = new DataLoader(createBlockBatchLoadFn(rpc), { cacheKeyFn });\n    return {\n        load: args => loader.load({ ...args, maxSupportedTransactionVersion: 0 }),\n        loadMany: args => loader.loadMany(args.map(a => ({ ...a, maxSupportedTransactionVersion: 0 }))),\n    };\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/coalescer.ts",
    "content": "import { DataSlice } from '@solana/rpc-types';\n\nimport { BatchLoadPromiseCallback, cacheKeyFn } from './loader';\n\ntype Encoding = 'base58' | 'base64' | 'base64+zstd' | 'json' | 'jsonParsed';\n\nexport type Fetch<TArgs extends { encoding?: Encoding }, TValue> = Readonly<{\n    args: TArgs;\n    promiseCallback: BatchLoadPromiseCallback<TValue>;\n}>;\nexport type ToFetchMap<TArgs extends { encoding?: Encoding }, TValue> = {\n    [key: string]: Fetch<TArgs, TValue>[];\n};\nexport type FetchesByArgsHash<TArgs extends { encoding?: Encoding }, TValue> = {\n    [argsHash: string]: {\n        args: TArgs;\n        fetches: {\n            [key: string]: {\n                callbacks: BatchLoadPromiseCallback<TValue>[];\n            };\n        };\n    };\n};\nexport type FetchesByArgsHashWithDataSlice<TArgs extends { dataSlice?: DataSlice; encoding?: Encoding }, TValue> = {\n    [argsHash: string]: {\n        args: TArgs;\n        fetches: {\n            [key: string]: {\n                callbacks: {\n                    callback: BatchLoadPromiseCallback<TValue>;\n                    dataSlice?: DataSlice | null;\n                }[];\n            };\n        };\n    };\n};\n\nconst hashOmit = <TArgs extends object>(args: TArgs, omit: (keyof TArgs)[]) => {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const argsObj: any = {};\n    for (const [key, value] of Object.entries(args)) {\n        if (!omit.includes(key as keyof TArgs)) {\n            argsObj[key] = value;\n        }\n    }\n    return cacheKeyFn(argsObj);\n};\n\nexport function buildCoalescedFetchesByArgsHash<TArgs extends { encoding?: Encoding }, TValue>(\n    toFetchMap: ToFetchMap<TArgs, TValue>,\n    orphanConfig: {\n        criteria: (args: TArgs) => boolean;\n        defaults: (args: TArgs) => TArgs;\n        hashOmit: (keyof TArgs)[];\n    },\n): FetchesByArgsHash<TArgs, TValue> {\n    const fetchesByArgsHash: FetchesByArgsHash<TArgs, TValue> = {};\n\n    // Keep track of any fetches that don't specify an encoding, to be\n    // wrapped into another fetch that does.\n    const orphanedFetches: typeof toFetchMap = {};\n\n    Object.entries(toFetchMap).forEach(([signature, toFetch]) => {\n        toFetch.forEach(({ args, promiseCallback }) => {\n            if (orphanConfig.criteria(args)) {\n                const toFetch = (orphanedFetches[signature] ||= []);\n                toFetch.push({ args, promiseCallback });\n                return;\n            }\n\n            const argsHash = hashOmit(args, []);\n            const transactionFetches = (fetchesByArgsHash[argsHash] ||= {\n                args,\n                fetches: {},\n            });\n            const { callbacks: promiseCallbacksForSignature } = (transactionFetches.fetches[signature] ||= {\n                callbacks: [],\n            });\n            promiseCallbacksForSignature.push(promiseCallback);\n        });\n    });\n\n    // Place the orphans\n    Object.entries(orphanedFetches).forEach(([signature, toFetch]) => {\n        toFetch.forEach(({ args: orphanArgs, promiseCallback: orphanPromiseCallback }) => {\n            if (Object.keys(fetchesByArgsHash).length !== 0) {\n                for (const { fetches, args } of Object.values(fetchesByArgsHash)) {\n                    // Check if the two arg sets are a match without `encoding`\n                    if (hashOmit(orphanArgs, orphanConfig.hashOmit) === hashOmit(args, orphanConfig.hashOmit)) {\n                        const { callbacks: promiseCallbacksForSignature } = (fetches[signature] ||= {\n                            callbacks: [],\n                        });\n                        promiseCallbacksForSignature.push(orphanPromiseCallback);\n                        return;\n                    }\n                }\n            }\n            // Create a new fetch.\n            const args = orphanConfig.defaults(orphanArgs);\n            const argsHash = hashOmit(args, []);\n            const transactionFetches = (fetchesByArgsHash[argsHash] ||= {\n                args,\n                fetches: {},\n            });\n            const { callbacks: promiseCallbacksForSignature } = (transactionFetches.fetches[signature] ||= {\n                callbacks: [],\n            });\n            promiseCallbacksForSignature.push(orphanPromiseCallback);\n        });\n    });\n\n    return fetchesByArgsHash;\n}\n\nexport function buildCoalescedFetchesByArgsHashWithDataSlice<\n    TArgs extends { dataSlice?: DataSlice; encoding?: Encoding },\n    TValue,\n>(toFetchMap: ToFetchMap<TArgs, TValue>, maxDataSliceByteRange: number): FetchesByArgsHashWithDataSlice<TArgs, TValue> {\n    const fetchesByArgsHash: FetchesByArgsHashWithDataSlice<TArgs, TValue> = {};\n\n    // Keep track of any fetches that don't specify an encoding, to be\n    // wrapped into another fetch that does.\n    const orphanedFetches: typeof toFetchMap = {};\n\n    Object.entries(toFetchMap).forEach(([address, toFetch]) => {\n        toFetch.forEach(({ args, promiseCallback }) => {\n            // As per the schema, `encoding` can only be provided if a\n            // `data` field is present, and the argument is required.\n            // So we can assume if no encoding is provided, this\n            // particular fetch is not concerned with data. We can\n            // combine it with some other fetch.\n            if (!args.encoding) {\n                const toFetch = (orphanedFetches[address] ||= []);\n                toFetch.push({ args, promiseCallback });\n                return;\n            }\n            // As per the schema, `dataSlice` cannot be provided without\n            // encoding.\n            // Don't try to combine fetches with `base64+zstd` encoding.\n            if (args.encoding != 'base64+zstd' && args.dataSlice) {\n                // If the fetch arg set has `dataSlice` provided, try\n                // to combine it with another request.\n                const r = args.dataSlice;\n                for (const { fetches: fetchAddresses, args: fetchArgs } of Object.values(fetchesByArgsHash)) {\n                    /**\n                     * Add a callback to the list of callbacks for the current address,\n                     * possibly updating the `dataSlice` argument used for the entire\n                     * fetch.\n                     */\n                    const addCallbackWithDataSlice = (updateDataSlice?: DataSlice) => {\n                        const { callbacks: promiseCallbacksForAddress } = (fetchAddresses[address] ||= {\n                            callbacks: [],\n                        });\n                        promiseCallbacksForAddress.push({\n                            callback: promiseCallback,\n                            dataSlice: args.dataSlice ?? null,\n                        });\n                        if (fetchArgs.dataSlice && updateDataSlice) {\n                            fetchArgs.dataSlice = updateDataSlice;\n                        }\n                    };\n\n                    // Check if the two arg sets are a match without the `dataSlice`\n                    // argument.\n                    if (hashOmit(args, ['dataSlice']) === hashOmit(fetchArgs, ['dataSlice'])) {\n                        if (fetchArgs.dataSlice) {\n                            // The arg sets match, and the fetch arg set has a `dataSlice`\n                            // argument. Try to merge the two account fetches.\n                            const g = fetchArgs.dataSlice;\n                            if (r.offset <= g.offset && g.offset - r.offset + r.length <= maxDataSliceByteRange) {\n                                const length = Math.max(r.length, g.offset + g.length - r.offset);\n                                const offset = r.offset;\n                                addCallbackWithDataSlice({ length, offset });\n                                return;\n                            }\n                            if (r.offset >= g.offset && r.offset - g.offset + g.length <= maxDataSliceByteRange) {\n                                const length = Math.max(g.length, r.offset + r.length - g.offset);\n                                const offset = g.offset;\n                                addCallbackWithDataSlice({ length, offset });\n                                return;\n                            }\n                        } else {\n                            // The arg sets match, and the fetch arg set has no `dataSlice`\n                            // argument. Merge the two account fetches.\n                            const { length, offset } = r;\n                            addCallbackWithDataSlice({ length, offset });\n                            return;\n                        }\n                    }\n                }\n            }\n            // Either the fetch arg set has no `dataSlice` argument, or\n            // it couldn't be combined with another fetch, likely due to\n            // the wasted byte limitation.\n            // Add the fetch to the list as a new fetch.\n            const argsHash = hashOmit(args, []);\n            const accountFetches = (fetchesByArgsHash[argsHash] ||= {\n                args,\n                fetches: {},\n            });\n            const { callbacks: promiseCallbacksForAddress } = (accountFetches.fetches[address] ||= {\n                callbacks: [],\n            });\n            promiseCallbacksForAddress.push({ callback: promiseCallback, dataSlice: args.dataSlice ?? null });\n        });\n    });\n\n    // Place the orphans\n    Object.entries(orphanedFetches).forEach(([address, toFetch]) => {\n        toFetch.forEach(({ args: orphanedArgs, promiseCallback: orphanPromiseCallback }) => {\n            if (Object.keys(fetchesByArgsHash).length !== 0) {\n                for (const { fetches, args } of Object.values(fetchesByArgsHash)) {\n                    // Check if the two arg sets are a match without\n                    // `encoding` and `dataSlice` arguments.\n                    if (\n                        hashOmit(orphanedArgs, ['encoding', 'dataSlice']) === hashOmit(args, ['encoding', 'dataSlice'])\n                    ) {\n                        const { callbacks: promiseCallbacksForAddress } = (fetches[address] ||= {\n                            callbacks: [],\n                        });\n                        promiseCallbacksForAddress.push({ callback: orphanPromiseCallback });\n                        return;\n                    }\n                }\n            }\n            // Create a new fetch. Prefer `base64` encoding.\n            const args: TArgs = { ...orphanedArgs, encoding: 'base64' };\n            const argsHash = hashOmit(args, []);\n            const accountFetches = (fetchesByArgsHash[argsHash] ||= {\n                args,\n                fetches: {},\n            });\n            const { callbacks: promiseCallbacksForAddress } = (accountFetches.fetches[address] ||= {\n                callbacks: [],\n            });\n            promiseCallbacksForAddress.push({ callback: orphanPromiseCallback });\n        });\n    });\n\n    return fetchesByArgsHash;\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/index.ts",
    "content": "export { createAccountLoader } from './account';\nexport { createBlockLoader } from './block';\nexport * from './loader';\nexport { createProgramAccountsLoader } from './program-accounts';\nexport { createTransactionLoader } from './transaction';\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/loader.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport stringify from '@solana/fast-stable-stringify';\nimport type { Signature } from '@solana/keys';\nimport type { GetAccountInfoApi, GetBlockApi, GetProgramAccountsApi, GetTransactionApi } from '@solana/rpc';\nimport type {\n    Commitment,\n    GetProgramAccountsDatasizeFilter,\n    GetProgramAccountsMemcmpFilter,\n    Slot,\n} from '@solana/rpc-types';\n\nexport type BatchLoadPromiseCallback<T> = Readonly<{\n    reject: (reason?: unknown) => void;\n    resolve: (value: T) => void;\n}>;\n\n// Loader base types\nexport type LoadFn<TArgs, T> = (args: TArgs) => Promise<T>;\nexport type LoadManyFn<TArgs, T> = (args: TArgs[]) => Promise<(Error | T)[]>;\nexport type Loader<TArgs, T> = { load: LoadFn<TArgs, T>; loadMany: LoadManyFn<TArgs, T> };\n\nexport type AccountLoaderArgsBase = {\n    /**\n     * Fetch the details of the account as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    dataSlice?: { length: number; offset: number };\n    encoding?: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n};\nexport type AccountLoaderArgs = AccountLoaderArgsBase & { address: Address };\nexport type AccountLoaderValue = ReturnType<GetAccountInfoApi['getAccountInfo']>['value'] | null;\nexport type AccountLoader = Loader<AccountLoaderArgs, AccountLoaderValue>;\n\nexport type BlockLoaderArgsBase = {\n    commitment?: Omit<Commitment, 'processed'>;\n    encoding?: 'base58' | 'base64' | 'json' | 'jsonParsed';\n    maxSupportedTransactionVersion?: 'legacy' | 0;\n    rewards?: boolean;\n    transactionDetails?: 'accounts' | 'full' | 'none' | 'signatures';\n};\nexport type BlockLoaderArgs = BlockLoaderArgsBase & { slot: Slot };\nexport type BlockLoaderValue = ReturnType<GetBlockApi['getBlock']> | null;\nexport type BlockLoader = Loader<BlockLoaderArgs, BlockLoaderValue>;\n\nexport type MultipleAccountsLoaderArgs = AccountLoaderArgsBase & { addresses: Address[] };\nexport type MultipleAccountsLoaderValue = AccountLoaderValue[];\nexport type MultipleAccountsLoader = Loader<MultipleAccountsLoaderArgs, MultipleAccountsLoaderValue>;\n\nexport type ProgramAccountsLoaderArgsBase = {\n    /**\n     * Fetch the details of the accounts as of the highest slot that has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    dataSlice?: { length: number; offset: number };\n    encoding?: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';\n    filters?: (GetProgramAccountsDatasizeFilter | GetProgramAccountsMemcmpFilter)[];\n    /**\n     * Prevents accessing stale data by enforcing that the RPC node has processed transactions up to\n     * this slot\n     */\n    minContextSlot?: Slot;\n};\nexport type ProgramAccountsLoaderArgs = ProgramAccountsLoaderArgsBase & { programAddress: Address };\nexport type ProgramAccountsLoaderValue = ReturnType<GetProgramAccountsApi['getProgramAccounts']>;\nexport type ProgramAccountsLoader = Loader<ProgramAccountsLoaderArgs, ProgramAccountsLoaderValue>;\n\nexport type TransactionLoaderArgsBase = {\n    commitment?: Omit<Commitment, 'processed'>;\n    encoding?: 'base58' | 'base64' | 'json' | 'jsonParsed';\n};\nexport type TransactionLoaderArgs = TransactionLoaderArgsBase & { signature: Signature };\nexport type TransactionLoaderValue = ReturnType<GetTransactionApi['getTransaction']> | null;\nexport type TransactionLoader = Loader<TransactionLoaderArgs, TransactionLoaderValue>;\n\nexport type RpcGraphQLLoaders = {\n    account: AccountLoader;\n    block: BlockLoader;\n    programAccounts: ProgramAccountsLoader;\n    transaction: TransactionLoader;\n};\n\nexport const cacheKeyFn = (obj: unknown) => stringify(obj) ?? '';\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/program-accounts.ts",
    "content": "import type { GetProgramAccountsApi, Rpc } from '@solana/rpc';\nimport DataLoader from 'dataloader';\n\nimport { sliceData } from './account';\nimport { buildCoalescedFetchesByArgsHashWithDataSlice, ToFetchMap } from './coalescer';\nimport {\n    cacheKeyFn,\n    ProgramAccountsLoader,\n    ProgramAccountsLoaderArgs,\n    ProgramAccountsLoaderArgsBase,\n    ProgramAccountsLoaderValue,\n} from './loader';\n\ntype Config = {\n    maxDataSliceByteRange: number;\n};\n\nasync function loadProgramAccounts(\n    rpc: Rpc<GetProgramAccountsApi>,\n    { programAddress, ...config }: ProgramAccountsLoaderArgs,\n): Promise<ProgramAccountsLoaderValue> {\n    return await rpc.getProgramAccounts(programAddress, config).send();\n}\n\nfunction createProgramAccountsBatchLoadFn(rpc: Rpc<GetProgramAccountsApi>, config: Config) {\n    const resolveProgramAccountsUsingRpc = loadProgramAccounts.bind(null, rpc);\n    return (accountQueryArgs: readonly ProgramAccountsLoaderArgs[]): ReturnType<ProgramAccountsLoader['loadMany']> => {\n        /**\n         * Gather all the program-accounts that need to be fetched, grouped by\n         * program address.\n         */\n        const programAccountsToFetch: ToFetchMap<ProgramAccountsLoaderArgsBase, ProgramAccountsLoaderValue> = {};\n        try {\n            return Promise.all(\n                accountQueryArgs.map(\n                    ({ programAddress, ...args }) =>\n                        new Promise((resolve, reject) => {\n                            const accountRecords = (programAccountsToFetch[programAddress] ||= []);\n                            // Apply the default commitment level.\n                            if (!args.commitment) {\n                                args.commitment = 'confirmed';\n                            }\n                            accountRecords.push({ args, promiseCallback: { reject, resolve } });\n                        }),\n                ),\n            ) as ReturnType<ProgramAccountsLoader['loadMany']>;\n        } finally {\n            const { maxDataSliceByteRange } = config;\n\n            /**\n             * Group together program-accounts that are fetched with identical args.\n             */\n            const programAccountsFetchesByArgsHash = buildCoalescedFetchesByArgsHashWithDataSlice(\n                programAccountsToFetch,\n                maxDataSliceByteRange,\n            );\n\n            /**\n             * For each set of program-accounts related to some common args, fetch them in the fewest\n             * number of network requests.\n             */\n            Object.values(programAccountsFetchesByArgsHash).map(({ args, fetches: programAddressCallbacks }) => {\n                return Object.entries(programAddressCallbacks).map(([programAddress, { callbacks }]) => {\n                    return Array.from({ length: 1 }, async () => {\n                        try {\n                            const result = await resolveProgramAccountsUsingRpc({\n                                programAddress,\n                                ...args,\n                            } as ProgramAccountsLoaderArgs);\n                            callbacks.forEach(({ callback, dataSlice }) => {\n                                callback.resolve(sliceData(result, dataSlice, args.dataSlice));\n                            });\n                        } catch (e) {\n                            callbacks.forEach(({ callback }) => {\n                                callback.reject(e);\n                            });\n                        }\n                    });\n                });\n            });\n        }\n    };\n}\n\nexport function createProgramAccountsLoader(rpc: Rpc<GetProgramAccountsApi>, config: Config): ProgramAccountsLoader {\n    const loader = new DataLoader(createProgramAccountsBatchLoadFn(rpc, config), { cacheKeyFn });\n    return {\n        load: args => loader.load(args),\n        loadMany: args => loader.loadMany(args),\n    };\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/loaders/transaction.ts",
    "content": "import type { GetTransactionApi, Rpc } from '@solana/rpc';\nimport DataLoader from 'dataloader';\n\nimport { buildCoalescedFetchesByArgsHash, ToFetchMap } from './coalescer';\nimport {\n    cacheKeyFn,\n    TransactionLoader,\n    TransactionLoaderArgs,\n    TransactionLoaderArgsBase,\n    TransactionLoaderValue,\n} from './loader';\n\nasync function loadTransaction(\n    rpc: Rpc<GetTransactionApi>,\n    { signature, ...config }: TransactionLoaderArgs,\n): Promise<TransactionLoaderValue> {\n    // @ts-expect-error FIX ME: https://github.com/microsoft/TypeScript/issues/43187\n    return await rpc\n        .getTransaction(\n            signature,\n            // @ts-expect-error FIX ME: https://github.com/microsoft/TypeScript/issues/43187\n            config,\n        )\n        .send();\n}\n\nfunction createTransactionBatchLoadFn(rpc: Rpc<GetTransactionApi>) {\n    const resolveTransactionUsingRpc = loadTransaction.bind(null, rpc);\n    return (transactionQueryArgs: readonly TransactionLoaderArgs[]): ReturnType<TransactionLoader['loadMany']> => {\n        /**\n         * Gather all the transactions that need to be fetched, grouped by signature.\n         */\n        const transactionsToFetch: ToFetchMap<TransactionLoaderArgsBase, TransactionLoaderValue> = {};\n        try {\n            return Promise.all(\n                transactionQueryArgs.map(\n                    ({ signature, ...args }) =>\n                        new Promise((resolve, reject) => {\n                            const transactionRecords = (transactionsToFetch[signature] ||= []);\n                            // Apply the default commitment level.\n                            if (!args.commitment) {\n                                args.commitment = 'confirmed';\n                            }\n                            transactionRecords.push({ args, promiseCallback: { reject, resolve } });\n                        }),\n                ),\n            ) as ReturnType<TransactionLoader['loadMany']>;\n        } finally {\n            /**\n             * Group together transactions that are fetched with identical args.\n             */\n            const transactionFetchesByArgsHash = buildCoalescedFetchesByArgsHash(transactionsToFetch, {\n                criteria: (args: TransactionLoaderArgsBase) => args.encoding === undefined,\n                defaults: (args: TransactionLoaderArgsBase) => ({ ...args, encoding: 'base64' }),\n                hashOmit: ['encoding'],\n            });\n\n            /**\n             * For each set of transactions related to some common args, fetch them in the fewest number\n             * of network requests.\n             */\n            Object.values(transactionFetchesByArgsHash).map(({ args, fetches: transactionCallbacks }) => {\n                return Object.entries(transactionCallbacks).map(([signature, { callbacks }]) => {\n                    return Array.from({ length: 1 }, async () => {\n                        try {\n                            const result = await resolveTransactionUsingRpc({\n                                signature,\n                                ...args,\n                            } as TransactionLoaderArgs);\n                            callbacks.forEach(c => c.resolve(result));\n                        } catch (e) {\n                            callbacks.forEach(c => c.reject(e));\n                        }\n                    });\n                });\n            });\n        }\n    };\n}\n\nexport function createTransactionLoader(rpc: Rpc<GetTransactionApi>): TransactionLoader {\n    const loader = new DataLoader(createTransactionBatchLoadFn(rpc), { cacheKeyFn });\n    return {\n        load: args => loader.load(args),\n        loadMany: args => loader.loadMany(args),\n    };\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/__tests__/account-resolver-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../../index';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('account resolver', () => {\n    let rpc: Rpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>;\n    let rpcGraphQL: RpcGraphQL;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        rpc = {\n            getAccountInfo: jest.fn().mockImplementation((address: Address) => {\n                const owner =\n                    address === 'AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca'\n                        ? 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'\n                        : 'BPFLoader2111111111111111111111111111111111';\n                return {\n                    send: () =>\n                        Promise.resolve({\n                            context: {\n                                slot: 0,\n                            },\n                            value: {\n                                data: ['AA', 'base64'],\n                                owner,\n                            },\n                        }),\n                };\n            }),\n            getBlock: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getMultipleAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getProgramAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getTransaction: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n        };\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    describe('address-only requests', () => {\n        describe('in the first level', () => {\n            it('will not call the RPC for only an address', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            address\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).not.toHaveBeenCalled();\n            });\n            it('will not call the RPC for only an address in an inline fragment', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            ... on MintAccount {\n                                address\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).not.toHaveBeenCalled();\n            });\n            it('will not call the RPC for only an address in a fragment spread', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            ...GetAddress\n                        }\n                    }\n                    fragment GetAddress {\n                        address\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).not.toHaveBeenCalled();\n            });\n        });\n        describe('in the second level', () => {\n            it('will not call the RPC for only an address', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            address\n                            ownerProgram {\n                                address\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            });\n            it('will not call the RPC for only an address in an inline fragment', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            address\n                            ownerProgram {\n                                ... on MintAccount {\n                                    address\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            });\n            it('will not call the RPC for only an address in a fragment spread', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            address\n                            ownerProgram {\n                                ...GetAddress\n                            }\n                        }\n                    }\n                    fragment GetAddress {\n                        address\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).not.toHaveBeenCalled();\n            });\n        });\n        describe('in the third level', () => {\n            it('will not call the RPC for only an address', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            address\n                            ownerProgram {\n                                address\n                                ownerProgram {\n                                    address\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.advanceTimersToNextTimerAsync(); // Advance past layer 1\n                await jest.advanceTimersToNextTimerAsync(); // Advance past layer 2\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(2);\n            });\n            it('will not call the RPC for only an address in an inline fragment', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            address\n                            ownerProgram {\n                                address\n                                ownerProgram {\n                                    ... on MintAccount {\n                                        address\n                                    }\n                                }\n                            }\n                        }\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            });\n            it('will not call the RPC for only an address in a fragment spread', async () => {\n                expect.assertions(1);\n                const source = /* GraphQL */ `\n                    query testQuery {\n                        account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                            address\n                            ownerProgram {\n                                address\n                                ownerProgram {\n                                    ...GetAddress\n                                }\n                            }\n                        }\n                    }\n                    fragment GetAddress {\n                        address\n                    }\n                `;\n                rpcGraphQL.query(source).catch(() => {});\n                await jest.runAllTimersAsync();\n                expect(rpc.getAccountInfo).not.toHaveBeenCalled();\n            });\n        });\n    });\n    describe('inline fragments', () => {\n        it('will resolve inline fragments with `jsonParsed` when `jsonParsed` fields are requested', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ... on MintAccount {\n                            supply\n                        }\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n        it('will resolve inline fragments with `jsonParsed` and the proper encoding when data and `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ... on MintAccount {\n                            data(encoding: BASE_58)\n                            supply\n                        }\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(2);\n            expect(rpc.getAccountInfo).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n            expect(rpc.getAccountInfo).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base58',\n            });\n        });\n        it('will resolve inline fragments with only the proper encoding not `jsonParsed` when no `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ... on MintAccount {\n                            data(encoding: BASE_58)\n                            lamports\n                            space\n                        }\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            expect(rpc.getAccountInfo).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base58',\n            });\n            expect(rpc.getAccountInfo).not.toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n    });\n    describe('fragment spreads', () => {\n        it('will resolve fields from fragment spreads', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetLamports\n                    }\n                }\n                fragment GetLamports on Account {\n                    lamports\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base64',\n            });\n        });\n        it('will resolve fields from multiple fragment spreads', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetLamports\n                        ...GetDataBase64\n                    }\n                }\n                fragment GetLamports on Account {\n                    lamports\n                }\n                fragment GetDataBase64 on Account {\n                    data(encoding: BASE_64_ZSTD)\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base64+zstd',\n            });\n        });\n        it('will resolve fragment spreads with `jsonParsed` when `jsonParsed` fields are requested', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetLamportsAndSupplyFromMintAccount\n                    }\n                }\n                fragment GetLamportsAndSupplyFromMintAccount on Account {\n                    ... on MintAccount {\n                        lamports\n                        supply\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n        it('will resolve fragment spreads with `jsonParsed` and the proper encoding when data and `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetDataAndSupplyFromMintAccount\n                    }\n                }\n                fragment GetDataAndSupplyFromMintAccount on Account {\n                    ... on MintAccount {\n                        data(encoding: BASE_58)\n                        supply\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(2);\n            expect(rpc.getAccountInfo).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n            expect(rpc.getAccountInfo).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base58',\n            });\n        });\n        it('will resolve fragment spreads with only the proper encoding not `jsonParsed` when no `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    account(address: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetLamportsAndDataFromMintAccount\n                    }\n                }\n                fragment GetLamportsAndDataFromMintAccount on Account {\n                    ... on MintAccount {\n                        lamports\n                        data(encoding: BASE_64_ZSTD)\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getAccountInfo).toHaveBeenCalledTimes(1);\n            expect(rpc.getAccountInfo).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base64+zstd',\n            });\n            expect(rpc.getAccountInfo).not.toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/__tests__/block-inputs-test.ts",
    "content": "import {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../..';\nimport { mockBlockFull } from '../../__tests__/__setup__';\n\ntype GraphQLCompliantRpc = Rpc<\n    GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi\n>;\n\n// The `block` query takes a `BigInt` as a parameter. We need to test this\n// for various input types that might occur outside of a JavaScript\n// context, such as string or number.\ndescribe('block inputs', () => {\n    let mockRpcTransport: jest.Mock;\n    let rpc: GraphQLCompliantRpc;\n    let rpcGraphQL: RpcGraphQL;\n    beforeEach(() => {\n        mockRpcTransport = jest.fn();\n        rpc = new Proxy<GraphQLCompliantRpc>({} as GraphQLCompliantRpc, {\n            get(target, p) {\n                if (!target[p as keyof GraphQLCompliantRpc]) {\n                    const pendingRpcRequest = { send: mockRpcTransport };\n                    // @ts-expect-error - Mocking RPC methods\n                    target[p as keyof GraphQLCompliantRpc] = jest\n                        .fn()\n                        .mockReturnValue(pendingRpcRequest) as GraphQLCompliantRpc[keyof GraphQLCompliantRpc];\n                }\n                return target[p as keyof GraphQLCompliantRpc];\n            },\n        });\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    // Does not accept raw bigint, ie. 511226n\n    it('can accept a bigint parameter as variable', async () => {\n        expect.assertions(2);\n        const source = /* GraphQL */ `\n            query testQuery($block: Slot!) {\n                block(slot: $block) {\n                    blockhash\n                }\n            }\n        `;\n        mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n        const result = await rpcGraphQL.query(source, { block: 511226n });\n        expect(result).not.toHaveProperty('errors');\n        expect(result).toMatchObject({\n            data: {\n                block: {\n                    blockhash: expect.any(String),\n                },\n            },\n        });\n    });\n    it('can accept a number parameter', async () => {\n        expect.assertions(2);\n        const source = /* GraphQL */ `\n            query testQuery {\n                block(slot: 511226) {\n                    blockhash\n                }\n            }\n        `;\n        mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n        const result = await rpcGraphQL.query(source);\n        expect(result).not.toHaveProperty('errors');\n        expect(result).toMatchObject({\n            data: {\n                block: {\n                    blockhash: expect.any(String),\n                },\n            },\n        });\n    });\n    it('can accept a number parameter as variable', async () => {\n        expect.assertions(2);\n        const source = /* GraphQL */ `\n            query testQuery($block: Slot!) {\n                block(slot: $block) {\n                    blockhash\n                }\n            }\n        `;\n        mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n        const result = await rpcGraphQL.query(source, { block: 511226 });\n        expect(result).not.toHaveProperty('errors');\n        expect(result).toMatchObject({\n            data: {\n                block: {\n                    blockhash: expect.any(String),\n                },\n            },\n        });\n    });\n    it('can accept a string parameter', async () => {\n        expect.assertions(2);\n        const source = /* GraphQL */ `\n            query testQuery {\n                block(slot: \"511226\") {\n                    blockhash\n                }\n            }\n        `;\n        mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n        const result = await rpcGraphQL.query(source);\n        expect(result).not.toHaveProperty('errors');\n        expect(result).toMatchObject({\n            data: {\n                block: {\n                    blockhash: expect.any(String),\n                },\n            },\n        });\n    });\n    it('can accept a string parameter as variable', async () => {\n        expect.assertions(2);\n        const source = /* GraphQL */ `\n            query testQuery($block: Slot!) {\n                block(slot: $block) {\n                    blockhash\n                }\n            }\n        `;\n        mockRpcTransport.mockResolvedValueOnce(mockBlockFull);\n        const result = await rpcGraphQL.query(source, { block: '511226' });\n        expect(result).not.toHaveProperty('errors');\n        expect(result).toMatchObject({\n            data: {\n                block: {\n                    blockhash: expect.any(String),\n                },\n            },\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/__tests__/block-resolver-test.ts",
    "content": "import type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\nimport type { Slot } from '@solana/rpc-types';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../../index';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('block resolver', () => {\n    let rpc: Rpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>;\n    let rpcGraphQL: RpcGraphQL;\n    // Random slot for testing.\n    // Not actually used. Just needed for proper query parsing.\n    const slot = 511226n as Slot;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        rpc = {\n            getAccountInfo: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getBlock: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getMultipleAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getProgramAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getTransaction: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n        };\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    describe('fragment spreads', () => {\n        it('will resolve fields from fragment spreads', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        ...GetBlockhash\n                    }\n                }\n                fragment GetBlockhash on Block {\n                    blockhash\n                }\n            `;\n            rpcGraphQL.query(source, { slot }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n            expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                commitment: 'confirmed',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'none',\n            });\n        });\n        it('will resolve fields from multiple fragment spreads', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        ...GetBlockhash\n                        ...GetParentSlot\n                    }\n                }\n                fragment GetBlockhash on Block {\n                    blockhash\n                }\n                fragment GetParentSlot on Block {\n                    parentSlot\n                }\n            `;\n            rpcGraphQL.query(source, { slot }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n            expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                commitment: 'confirmed',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'none',\n            });\n        });\n        it('will resolve fragment spreads with `jsonParsed` when `jsonParsed` fields are requested', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        transactions {\n                            message {\n                                instructions {\n                                    ...GetGenericInstructionData\n                                }\n                            }\n                        }\n                    }\n                }\n                fragment GetGenericInstructionData on TransactionInstruction {\n                    ... on GenericInstruction {\n                        data\n                    }\n                }\n            `;\n            rpcGraphQL.query(source, { slot }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n            expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'full',\n            });\n        });\n        it('will resolve fragment spreads with `jsonParsed` and the proper encoding when data and `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        transactions {\n                            ...GetDataAndGenericInstructionData\n                        }\n                    }\n                }\n                fragment GetDataAndGenericInstructionData on Transaction {\n                    transactionData: data(encoding: BASE_58)\n                    message {\n                        instructions {\n                            ... on GenericInstruction {\n                                data\n                            }\n                        }\n                    }\n                }\n            `;\n            rpcGraphQL.query(source, { slot }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getBlock).toHaveBeenCalledTimes(2);\n            expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'full',\n            });\n            expect(rpc.getBlock).toHaveBeenCalledWith(slot, {\n                commitment: 'confirmed',\n                encoding: 'base58',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'full',\n            });\n        });\n        it('will resolve fragment spreads with only the proper encoding not `jsonParsed` when no `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery($slot: Slot!) {\n                    block(slot: $slot) {\n                        transactions {\n                            ...GetTransactionData\n                        }\n                    }\n                }\n                fragment GetTransactionData on Transaction {\n                    transactionData: data(encoding: BASE_58)\n                }\n            `;\n            rpcGraphQL.query(source, { slot }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getBlock).toHaveBeenCalledTimes(1);\n            expect(rpc.getBlock).toHaveBeenLastCalledWith(slot, {\n                commitment: 'confirmed',\n                encoding: 'base58',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'full',\n            });\n            expect(rpc.getBlock).not.toHaveBeenCalledWith(slot, {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n                maxSupportedTransactionVersion: 0,\n                transactionDetails: 'full',\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/__tests__/program-accounts-resolver-test.ts",
    "content": "import type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../../index';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('program accounts resolver', () => {\n    let rpc: Rpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>;\n    let rpcGraphQL: RpcGraphQL;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        rpc = {\n            getAccountInfo: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getBlock: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getMultipleAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getProgramAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getTransaction: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n        };\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    describe('inline fragments', () => {\n        it('will resolve inline fragments with `jsonParsed` when `jsonParsed` fields are requested', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    programAccounts(programAddress: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ... on MintAccount {\n                            supply\n                        }\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n            expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n        it('will resolve inline fragments with `jsonParsed` and the proper encoding when data and `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    programAccounts(programAddress: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ... on MintAccount {\n                            data(encoding: BASE_58)\n                            supply\n                        }\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(2);\n            expect(rpc.getProgramAccounts).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n            expect(rpc.getProgramAccounts).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base58',\n            });\n        });\n        it('will resolve inline fragments with only the proper encoding not `jsonParsed` when no `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    programAccounts(programAddress: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ... on MintAccount {\n                            data(encoding: BASE_58)\n                            lamports\n                            space\n                        }\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n            expect(rpc.getProgramAccounts).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base58',\n            });\n            expect(rpc.getProgramAccounts).not.toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n    });\n    describe('fragment spreads', () => {\n        it('will resolve fields from fragment spreads', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    programAccounts(programAddress: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetLamports\n                    }\n                }\n                fragment GetLamports on Account {\n                    lamports\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n            expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base64',\n            });\n        });\n        it('will resolve fields from multiple fragment spreads', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    programAccounts(programAddress: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetLamports\n                        ...GetDataBase64\n                    }\n                }\n                fragment GetLamports on Account {\n                    lamports\n                }\n                fragment GetDataBase64 on Account {\n                    data(encoding: BASE_64_ZSTD)\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n            expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base64+zstd',\n            });\n        });\n        it('will resolve fragment spreads with `jsonParsed` when `jsonParsed` fields are requested', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    programAccounts(programAddress: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetLamportsAndSupplyFromMintAccount\n                    }\n                }\n                fragment GetLamportsAndSupplyFromMintAccount on Account {\n                    ... on MintAccount {\n                        lamports\n                        supply\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n            expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n        it('will resolve fragment spreads with `jsonParsed` and the proper encoding when data and `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    programAccounts(programAddress: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetDataAndSupplyFromMintAccount\n                    }\n                }\n                fragment GetDataAndSupplyFromMintAccount on Account {\n                    ... on MintAccount {\n                        data(encoding: BASE_58)\n                        supply\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(2);\n            expect(rpc.getProgramAccounts).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n            expect(rpc.getProgramAccounts).toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base58',\n            });\n        });\n        it('will resolve fragment spreads with only the proper encoding not `jsonParsed` when no `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery {\n                    programAccounts(programAddress: \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\") {\n                        ...GetLamportsAndDataFromMintAccount\n                    }\n                }\n                fragment GetLamportsAndDataFromMintAccount on Account {\n                    ... on MintAccount {\n                        lamports\n                        data(encoding: BASE_64_ZSTD)\n                    }\n                }\n            `;\n            rpcGraphQL.query(source).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getProgramAccounts).toHaveBeenCalledTimes(1);\n            expect(rpc.getProgramAccounts).toHaveBeenLastCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'base64+zstd',\n            });\n            expect(rpc.getProgramAccounts).not.toHaveBeenCalledWith('AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca', {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/__tests__/transaction-resolver-test.ts",
    "content": "import type {\n    GetAccountInfoApi,\n    GetBlockApi,\n    GetMultipleAccountsApi,\n    GetProgramAccountsApi,\n    GetTransactionApi,\n    Rpc,\n} from '@solana/rpc';\n\nimport { createSolanaRpcGraphQL, RpcGraphQL } from '../../index';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('transaction resolver', () => {\n    let rpc: Rpc<GetAccountInfoApi & GetBlockApi & GetMultipleAccountsApi & GetProgramAccountsApi & GetTransactionApi>;\n    let rpcGraphQL: RpcGraphQL;\n    // Not actually used. Just needed for proper query parsing.\n    const signature = '67rSZV97NzE4B4ZeFqULqWZcNEV2KwNfDLMzecJmBheZ4sWhudqGAzypoBCKfeLkKtDQBGnkwgdrrFM8ZMaS3pkk';\n    beforeEach(() => {\n        jest.useFakeTimers();\n        rpc = {\n            getAccountInfo: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getBlock: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getMultipleAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getProgramAccounts: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n            getTransaction: jest.fn().mockReturnValue({ send: jest.fn().mockReturnValue(FOREVER_PROMISE) }),\n        };\n        rpcGraphQL = createSolanaRpcGraphQL(rpc);\n    });\n    describe('fragment spreads', () => {\n        it('will resolve fields from fragment spreads', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        ...GetBlockTime\n                    }\n                }\n                fragment GetBlockTime on Transaction {\n                    blockTime\n                }\n            `;\n            rpcGraphQL.query(source, { signature }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n            expect(rpc.getTransaction).toHaveBeenLastCalledWith(signature, {\n                commitment: 'confirmed',\n                encoding: 'base64',\n            });\n        });\n        it('will resolve fields from multiple fragment spreads', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        ...GetBlockTime\n                        ...GetDataBase64\n                    }\n                }\n                fragment GetBlockTime on Transaction {\n                    blockTime\n                }\n                fragment GetDataBase64 on Transaction {\n                    data(encoding: BASE_64)\n                }\n            `;\n            rpcGraphQL.query(source, { signature }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n            expect(rpc.getTransaction).toHaveBeenLastCalledWith(signature, {\n                commitment: 'confirmed',\n                encoding: 'base64',\n            });\n        });\n        it('will resolve fragment spreads with `jsonParsed` when `jsonParsed` fields are requested', async () => {\n            expect.assertions(2);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        message {\n                            instructions {\n                                ...GetGenericInstructionData\n                            }\n                        }\n                    }\n                }\n                fragment GetGenericInstructionData on TransactionInstruction {\n                    ... on GenericInstruction {\n                        data\n                    }\n                }\n            `;\n            rpcGraphQL.query(source, { signature }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n            expect(rpc.getTransaction).toHaveBeenLastCalledWith(signature, {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n        it('will resolve fragment spreads with `jsonParsed` and the proper encoding when data and `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        ...GetDataAndGenericInstructionData\n                    }\n                }\n                fragment GetDataAndGenericInstructionData on Transaction {\n                    transactionData: data(encoding: BASE_58)\n                    message {\n                        instructions {\n                            ... on GenericInstruction {\n                                data\n                            }\n                        }\n                    }\n                }\n            `;\n            rpcGraphQL.query(source, { signature }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getTransaction).toHaveBeenCalledTimes(2);\n            expect(rpc.getTransaction).toHaveBeenCalledWith(signature, {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n            expect(rpc.getTransaction).toHaveBeenCalledWith(signature, {\n                commitment: 'confirmed',\n                encoding: 'base58',\n            });\n        });\n        it('will resolve fragment spreads with only the proper encoding not `jsonParsed` when no `jsonParsed` fields are requested', async () => {\n            expect.assertions(3);\n            const source = /* GraphQL */ `\n                query testQuery($signature: Signature!) {\n                    transaction(signature: $signature) {\n                        ...GetTransactionData\n                    }\n                }\n                fragment GetTransactionData on Transaction {\n                    transactionData: data(encoding: BASE_58)\n                }\n            `;\n            rpcGraphQL.query(source, { signature }).catch(() => {});\n            await jest.runAllTimersAsync();\n            expect(rpc.getTransaction).toHaveBeenCalledTimes(1);\n            expect(rpc.getTransaction).toHaveBeenLastCalledWith(signature, {\n                commitment: 'confirmed',\n                encoding: 'base58',\n            });\n            expect(rpc.getTransaction).not.toHaveBeenCalledWith(signature, {\n                commitment: 'confirmed',\n                encoding: 'jsonParsed',\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/account.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Commitment, Slot } from '@solana/rpc-types';\nimport { GraphQLResolveInfo } from 'graphql';\n\nimport { RpcGraphQLContext } from '../context';\nimport { AccountLoaderValue, cacheKeyFn } from '../loaders';\nimport { buildAccountLoaderArgSetFromResolveInfo, onlyFieldsRequested } from './resolve-info';\n\ntype Encoding = 'base58' | 'base64' | 'base64+zstd';\ntype DataSlice = { length: number; offset: number };\n\nexport type EncodedAccountData = {\n    [key: string]: string;\n};\n\nexport type AccountResult = Partial<Omit<AccountLoaderValue, 'data'>> & {\n    address: Address;\n    encodedData?: EncodedAccountData;\n    jsonParsedConfigs?: {\n        accountType: string;\n        programId: Address;\n        programName: string;\n    };\n    ownerProgram?: Address;\n};\n\nexport const resolveAccountData = () => {\n    return (\n        parent: AccountResult | null,\n        args: {\n            /**\n             * Define which slice of the account's data you want the RPC to return.\n             *\n             * Use this to save network bandwidth and encoding time when you do not need the entire\n             * buffer.\n             */\n            dataSlice?: DataSlice;\n            encoding: Encoding;\n        },\n    ) => {\n        return parent === null ? null : parent.encodedData ? parent.encodedData[cacheKeyFn(args)] : null;\n    };\n};\n\nexport const resolveAccount = (fieldName?: string) => {\n    return async (\n        parent: { [x: string]: Address },\n        args: {\n            address?: Address;\n            /**\n             * Fetch the details of the account as of the highest slot that has reached this level\n             * of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n        },\n        context: RpcGraphQLContext,\n        info: GraphQLResolveInfo,\n    ): Promise<AccountResult | null> => {\n        const address = fieldName ? parent[fieldName] : args.address;\n\n        if (address) {\n            // Do not load any accounts if only the address is requested\n            if (onlyFieldsRequested(['address'], info)) {\n                return { address };\n            }\n\n            const argsSet = buildAccountLoaderArgSetFromResolveInfo({ ...args, address }, info);\n            const loadedAccounts = await context.loaders.account.loadMany(argsSet);\n\n            let result: AccountResult = {\n                address,\n                encodedData: {},\n            };\n\n            loadedAccounts.forEach((account, i) => {\n                if (account instanceof Error) {\n                    console.error(account);\n                    return;\n                }\n                if (account === null) {\n                    return;\n                }\n                if (!result.ownerProgram) {\n                    result = {\n                        ...result,\n                        ...account,\n                        ownerProgram: account.owner,\n                    };\n                }\n\n                const { data } = account;\n                const { encoding, dataSlice } = argsSet[i];\n\n                if (encoding && result.encodedData) {\n                    if (Array.isArray(data)) {\n                        result.encodedData[\n                            cacheKeyFn({\n                                dataSlice,\n                                encoding: encoding === 'jsonParsed' ? 'base64' : encoding,\n                            })\n                        ] = data[0];\n                    } else if (typeof data === 'string') {\n                        result.encodedData[\n                            cacheKeyFn({\n                                dataSlice,\n                                encoding: 'base58',\n                            })\n                        ] = data;\n                    } else if (typeof data === 'object') {\n                        const {\n                            parsed: { info: parsedData, type: accountType },\n                            program: programName,\n                            programId,\n                        } = data;\n                        result.jsonParsedConfigs = {\n                            accountType,\n                            programId,\n                            programName,\n                        };\n                        if (Array.isArray(parsedData)) {\n                            // If the `jsonParsed` data is an array, put it\n                            // into a field called `entries`.\n                            Object.assign(result, { entries: parsedData });\n                        } else {\n                            result = {\n                                ...result,\n                                ...(parsedData as object),\n                            };\n                        }\n                    }\n                }\n            });\n\n            return result;\n        }\n\n        return null;\n    };\n};\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/block.ts",
    "content": "import type { Commitment, Slot } from '@solana/rpc-types';\nimport { GraphQLResolveInfo } from 'graphql';\n\nimport { RpcGraphQLContext } from '../context';\nimport { BlockLoaderValue, cacheKeyFn } from '../loaders';\nimport { buildBlockLoaderArgSetFromResolveInfo, onlyFieldsRequested } from './resolve-info';\nimport { mapJsonParsedInnerInstructions, mapJsonParsedInstructions, TransactionResult } from './transaction';\n\nexport type BlockResult = Partial<BlockLoaderValue> & {\n    slot: Slot;\n    transactionResults?: { [i: number]: TransactionResult };\n};\n\nexport const resolveBlock = (fieldName?: string) => {\n    return async (\n        parent: { [x: string]: Slot },\n        args: {\n            commitment?: Omit<Commitment, 'processed'>;\n            slot?: Slot;\n        },\n        context: RpcGraphQLContext,\n        info: GraphQLResolveInfo,\n    ) => {\n        const slot = fieldName ? parent[fieldName] : args.slot;\n\n        if (slot) {\n            if (onlyFieldsRequested(['slot'], info)) {\n                return { slot };\n            }\n\n            const argsSet = buildBlockLoaderArgSetFromResolveInfo({ ...args, slot }, info);\n            const loadedBlocks = await context.loaders.block.loadMany(argsSet);\n\n            let result: BlockResult = {\n                slot,\n            };\n\n            loadedBlocks.forEach((loadedBlock, i) => {\n                if (loadedBlock instanceof Error) {\n                    console.error(loadedBlock);\n                    return;\n                }\n                if (loadedBlock === null) {\n                    return;\n                }\n                if (!result.blockhash) {\n                    result = {\n                        ...result,\n                        ...loadedBlock,\n                    };\n                }\n                // @ts-expect-error FIX ME: https://github.com/solana-labs/solana-web3.js/pull/2052\n                if (!result.signatures && loadedBlock.signatures) {\n                    result = {\n                        ...result,\n                        // @ts-expect-error FIX ME: https://github.com/solana-labs/solana-web3.js/pull/2052\n                        signatures: loadedBlock.signatures,\n                    };\n                }\n                if (!result.transactionResults && loadedBlock.transactions) {\n                    result.transactionResults = Array.from({ length: loadedBlock.transactions.length }, (_, i) => ({\n                        [i]: { encodedData: {} },\n                    }));\n                }\n\n                const { transactions } = loadedBlock;\n                const { encoding } = argsSet[i];\n\n                if (encoding) {\n                    transactions.forEach((loadedTransaction, j) => {\n                        const { transaction: data } = loadedTransaction;\n\n                        if (result.transactionResults) {\n                            const thisTransactionResult = (result.transactionResults[j] ||= {\n                                encodedData: {},\n                            });\n\n                            if (Array.isArray(data)) {\n                                const thisEncodedData = (thisTransactionResult.encodedData ||= {});\n                                thisEncodedData[\n                                    cacheKeyFn({\n                                        encoding,\n                                    })\n                                ] = data[0];\n                            } else if (typeof data === 'object') {\n                                const jsonParsedData: typeof data = {\n                                    ...data,\n                                    message: {\n                                        ...data.message,\n                                        instructions: mapJsonParsedInstructions(\n                                            data.message.instructions,\n                                        ) as unknown as (typeof jsonParsedData)['message']['instructions'],\n                                    },\n                                };\n\n                                const loadedInnerInstructions = loadedTransaction.meta?.innerInstructions;\n                                if (loadedInnerInstructions) {\n                                    const innerInstructions = mapJsonParsedInnerInstructions(loadedInnerInstructions);\n                                    const jsonParsedMeta = {\n                                        ...loadedTransaction.meta,\n                                        innerInstructions,\n                                    };\n                                    result.transactionResults[j] = {\n                                        ...thisTransactionResult,\n                                        ...jsonParsedData,\n                                        meta: jsonParsedMeta as unknown as TransactionResult['meta'],\n                                    };\n                                } else {\n                                    result.transactionResults[j] = {\n                                        ...thisTransactionResult,\n                                        ...jsonParsedData,\n                                    };\n                                }\n                            }\n                        }\n                    });\n                }\n            });\n            return result;\n        }\n        return null;\n    };\n};\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/program-accounts.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Commitment, GetProgramAccountsDatasizeFilter, GetProgramAccountsMemcmpFilter, Slot } from '@solana/rpc-types';\nimport type { GraphQLResolveInfo } from 'graphql';\n\nimport { RpcGraphQLContext } from '../context';\nimport { cacheKeyFn } from '../loaders';\nimport { AccountResult } from './account';\nimport { buildProgramAccountsLoaderArgSetFromResolveInfo } from './resolve-info';\n\nexport function resolveProgramAccounts(fieldName?: string) {\n    return async (\n        parent: { [x: string]: Address },\n        args: {\n            /**\n             * Fetch the details of the accounts as of the highest slot that has reached this level\n             * of commitment.\n             *\n             * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use.\n             * For example, when using an API created by a `createSolanaRpc*()` helper, the default\n             * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer\n             * on the client, the default commitment applied by the server is `\"finalized\"`.\n             */\n            commitment?: Commitment;\n            dataSizeFilters?: GetProgramAccountsDatasizeFilter[];\n            memcmpFilters?: GetProgramAccountsMemcmpFilter['memcmp'][];\n            /**\n             * Prevents accessing stale data by enforcing that the RPC node has processed\n             * transactions up to this slot\n             */\n            minContextSlot?: Slot;\n            programAddress: Address;\n        },\n        context: RpcGraphQLContext,\n        info: GraphQLResolveInfo,\n    ): Promise<AccountResult[] | null> => {\n        const programAddress = fieldName ? parent[fieldName] : args.programAddress;\n        let filters: (GetProgramAccountsDatasizeFilter | GetProgramAccountsMemcmpFilter)[] | undefined = [];\n        if (args.memcmpFilters) {\n            filters.concat(\n                args.memcmpFilters.map(memcmpFilter => ({\n                    memcmp: memcmpFilter,\n                })),\n            );\n        }\n        if (args.dataSizeFilters) {\n            filters = filters.concat(args.dataSizeFilters);\n        }\n        if (filters.length === 0) {\n            filters = undefined;\n        }\n\n        if (programAddress) {\n            const argsSet = buildProgramAccountsLoaderArgSetFromResolveInfo({ ...args, filters, programAddress }, info);\n            const loadedProgramAccountsLists = await context.loaders.programAccounts.loadMany(argsSet);\n\n            const result: {\n                [address: string]: AccountResult;\n            } = {};\n\n            loadedProgramAccountsLists.forEach((programAccounts, i) => {\n                if (programAccounts instanceof Error) {\n                    console.error(programAccounts);\n                    return;\n                }\n                programAccounts.forEach(programAccount => {\n                    const { account, pubkey: address } = programAccount;\n\n                    const thisResult = (result[address] ||= {\n                        ...account,\n                        address,\n                        encodedData: {},\n                        ownerProgram: account.owner,\n                    });\n\n                    const { data } = account;\n                    const { encoding, dataSlice } = argsSet[i];\n\n                    if (encoding && thisResult.encodedData) {\n                        if (Array.isArray(data)) {\n                            thisResult.encodedData[\n                                cacheKeyFn({\n                                    dataSlice,\n                                    encoding: encoding === 'jsonParsed' ? 'base64' : encoding,\n                                })\n                            ] = data[0];\n                        } else if (typeof data === 'string') {\n                            thisResult.encodedData[\n                                cacheKeyFn({\n                                    dataSlice,\n                                    encoding: 'base58',\n                                })\n                            ] = data;\n                        } else if (typeof data === 'object') {\n                            const {\n                                parsed: { info: parsedData, type: accountType },\n                                program: programName,\n                                programId,\n                            } = data;\n                            thisResult.jsonParsedConfigs = {\n                                accountType,\n                                programId,\n                                programName,\n                            };\n                            for (const key in parsedData as object) {\n                                thisResult[key as keyof typeof thisResult] = parsedData[key];\n                            }\n                        }\n                    }\n                });\n            });\n            return Object.values(result);\n        }\n        return null;\n    };\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/resolve-info/account.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Commitment, DataSlice, Slot } from '@solana/rpc-types';\nimport { ArgumentNode, GraphQLResolveInfo, isInterfaceType } from 'graphql';\n\nimport { AccountLoaderArgs, ProgramAccountsLoaderArgs } from '../../loaders';\nimport { injectableRootVisitor, onlyFieldsRequested } from './visitor';\n\nfunction findArgumentNodeByName(argumentNodes: readonly ArgumentNode[], name: string): ArgumentNode | undefined {\n    return argumentNodes.find(argumentNode => argumentNode.name.value === name);\n}\n\nfunction parseAccountEncodingArgument(\n    argumentNodes: readonly ArgumentNode[],\n    variableValues: {\n        [variable: string]: unknown;\n    },\n): AccountLoaderArgs['encoding'] | undefined {\n    const argumentNode = findArgumentNodeByName(argumentNodes, 'encoding');\n    if (argumentNode) {\n        if (argumentNode.value.kind === 'EnumValue') {\n            if (argumentNode.value.value === 'BASE_58') {\n                return 'base58';\n            }\n            if (argumentNode.value.value === 'BASE_64') {\n                return 'base64';\n            }\n            if (argumentNode.value.value === 'BASE_64_ZSTD') {\n                return 'base64+zstd';\n            }\n        }\n        if (argumentNode.value.kind === 'Variable') {\n            return variableValues[argumentNode.value.name.value] as AccountLoaderArgs['encoding'];\n        }\n    } else {\n        return undefined;\n    }\n}\n\nfunction parseAccountDataSliceArgument(\n    argumentNodes: readonly ArgumentNode[],\n    variableValues: { [variable: string]: unknown },\n): AccountLoaderArgs['dataSlice'] {\n    const argumentNode = findArgumentNodeByName(argumentNodes, 'dataSlice');\n    if (argumentNode) {\n        if (argumentNode.value.kind === 'ObjectValue') {\n            const offsetArg = argumentNode.value.fields?.find(field => field.name.value === 'offset');\n            const lengthArg = argumentNode.value.fields?.find(field => field.name.value === 'length');\n            const length =\n                lengthArg?.value.kind === 'IntValue'\n                    ? parseInt(lengthArg.value.value)\n                    : lengthArg?.value.kind === 'Variable'\n                      ? (variableValues[lengthArg.value.name.value] as number)\n                      : undefined;\n            const offset =\n                offsetArg?.value.kind === 'IntValue'\n                    ? parseInt(offsetArg.value.value)\n                    : offsetArg?.value.kind === 'Variable'\n                      ? (variableValues[offsetArg.value.name.value] as number)\n                      : undefined;\n            return length !== undefined && length !== null && offset !== undefined && offset !== null\n                ? { length, offset }\n                : undefined;\n        }\n        if (argumentNode.value.kind === 'Variable') {\n            return variableValues[argumentNode.value.name.value] as DataSlice;\n        }\n    } else {\n        return undefined;\n    }\n}\n\nexport function buildAccountArgSetWithVisitor<TArgs extends AccountLoaderArgs | ProgramAccountsLoaderArgs>(\n    args: TArgs,\n    info: GraphQLResolveInfo,\n): TArgs[] {\n    const argSet = [args];\n\n    function buildArgSetWithVisitor(root: Parameters<typeof injectableRootVisitor>[1]) {\n        injectableRootVisitor(info, root, {\n            fieldNodeOperation(info, node) {\n                if (node.name.value !== 'data') {\n                    return;\n                }\n                // At least `encoding` is required on the `data` field.\n                if (node.arguments) {\n                    const { variableValues } = info;\n                    const encoding = parseAccountEncodingArgument(node.arguments, variableValues);\n                    const dataSlice = parseAccountDataSliceArgument(node.arguments, variableValues);\n                    argSet.push({ ...args, dataSlice, encoding });\n                }\n            },\n            fragmentSpreadNodeOperation(_info, fragment) {\n                buildArgSetWithVisitor(fragment);\n            },\n            inlineFragmentNodeOperation(info, node) {\n                const { schema } = info;\n                const accountInterface = schema.getType('Account');\n                if (\n                    isInterfaceType(accountInterface) &&\n                    // Recursively check if the inline fragment requests any\n                    // fields outside of the `Account` interface.\n                    !onlyFieldsRequested(Object.keys(accountInterface.getFields()), info, node)\n                ) {\n                    argSet.push({ ...args, encoding: 'jsonParsed' });\n                }\n            },\n        });\n    }\n\n    buildArgSetWithVisitor(null);\n\n    return argSet;\n}\n\n/**\n * Build a set of account loader args by inspecting which fields have\n * been requested in the query (ie. `data` or inline fragments).\n */\nexport function buildAccountLoaderArgSetFromResolveInfo(\n    args: {\n        address: Address;\n        /**\n         * Fetch the details of the account as of the highest slot that has reached this level of\n         * commitment.\n         *\n         * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n         * example, when using an API created by a `createSolanaRpc*()` helper, the default\n         * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on\n         * the client, the default commitment applied by the server is `\"finalized\"`.\n         */\n        commitment?: Commitment;\n        /**\n         * Prevents accessing stale data by enforcing that the RPC node has processed transactions\n         * up to this slot\n         */\n        minContextSlot?: Slot;\n    },\n    info: GraphQLResolveInfo,\n): AccountLoaderArgs[] {\n    return buildAccountArgSetWithVisitor(args, info);\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/resolve-info/block.ts",
    "content": "import { Commitment, Slot } from '@solana/rpc-types';\nimport { GraphQLResolveInfo } from 'graphql';\n\nimport { BlockLoaderArgs } from '../../loaders';\nimport { buildTransactionArgSetWithVisitor } from './transaction';\nimport { injectableRootVisitor } from './visitor';\n\n/**\n * Build a set of block loader args by inspecting which fields have\n * been requested in the query (ie. `data` or inline fragments).\n */\nexport function buildBlockLoaderArgSetFromResolveInfo(\n    args: {\n        /**\n         * Fetch blocks from slots that have reached at least this level of commitment.\n         *\n         * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n         * example, when using an API created by a `createSolanaRpc*()` helper, the default\n         * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on\n         * the client, the default commitment applied by the server is `\"finalized\"`.\n         */\n        commitment?: Omit<Commitment, 'processed'>;\n        /**\n         * Prevents accessing stale data by enforcing that the RPC node has processed\n         * transactions up to this slot\n         */\n        minContextSlot?: Slot;\n        slot: Slot;\n    },\n    info: GraphQLResolveInfo,\n): BlockLoaderArgs[] {\n    const argSet: BlockLoaderArgs[] = [args];\n\n    function buildArgSetWithVisitor(root: Parameters<typeof injectableRootVisitor>[1]) {\n        injectableRootVisitor(info, root, {\n            fieldNodeOperation(info, node) {\n                if (node.name.value === 'signatures') {\n                    argSet.push({ ...args, transactionDetails: 'signatures' });\n                } else if (node.name.value === 'transactions') {\n                    argSet.push(...buildTransactionArgSetWithVisitor({ ...args, transactionDetails: 'full' }, info));\n                }\n            },\n            fragmentSpreadNodeOperation(_info, fragment) {\n                buildArgSetWithVisitor(fragment);\n            },\n            inlineFragmentNodeOperation(_info, _node) {\n                // Block schema doesn't support inline fragments at the\n                // root level.\n                return;\n            },\n        });\n    }\n\n    buildArgSetWithVisitor(null);\n\n    return argSet;\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/resolve-info/index.ts",
    "content": "export * from './account';\nexport * from './block';\nexport * from './program-accounts';\nexport * from './transaction';\nexport * from './visitor';\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/resolve-info/program-accounts.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Commitment, GetProgramAccountsDatasizeFilter, GetProgramAccountsMemcmpFilter, Slot } from '@solana/rpc-types';\nimport { GraphQLResolveInfo } from 'graphql';\n\nimport { ProgramAccountsLoaderArgs } from '../../loaders';\nimport { buildAccountArgSetWithVisitor } from './account';\n\n/**\n * Build a set of account loader args by inspecting which fields have\n * been requested in the query (ie. `data` or inline fragments).\n */\nexport function buildProgramAccountsLoaderArgSetFromResolveInfo(\n    args: {\n        /**\n         * Fetch the details of the accounts as of the highest slot that has reached this level of\n         * commitment.\n         *\n         * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n         * example, when using an API created by a `createSolanaRpc*()` helper, the default\n         * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on\n         * the client, the default commitment applied by the server is `\"finalized\"`.\n         */\n        commitment?: Commitment;\n        filters?: (GetProgramAccountsDatasizeFilter | GetProgramAccountsMemcmpFilter)[];\n        /**\n         * Prevents accessing stale data by enforcing that the RPC node has processed transactions\n         * up to this slot\n         */\n        minContextSlot?: Slot;\n        programAddress: Address;\n    },\n    info: GraphQLResolveInfo,\n): ProgramAccountsLoaderArgs[] {\n    return buildAccountArgSetWithVisitor(args, info);\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/resolve-info/transaction.ts",
    "content": "import { Signature } from '@solana/keys';\nimport { Commitment, Slot } from '@solana/rpc-types';\nimport { ArgumentNode, GraphQLResolveInfo } from 'graphql';\n\nimport { BlockLoaderArgs, TransactionLoaderArgs } from '../../loaders';\nimport { injectableRootVisitor } from './visitor';\n\nfunction findArgumentNodeByName(argumentNodes: readonly ArgumentNode[], name: string): ArgumentNode | undefined {\n    return argumentNodes.find(argumentNode => argumentNode.name.value === name);\n}\n\nfunction parseTransactionEncodingArgument(\n    argumentNodes: readonly ArgumentNode[],\n    variableValues: {\n        [variable: string]: unknown;\n    },\n): TransactionLoaderArgs['encoding'] | undefined {\n    const argumentNode = findArgumentNodeByName(argumentNodes, 'encoding');\n    if (argumentNode) {\n        if (argumentNode.value.kind === 'EnumValue') {\n            if (argumentNode.value.value === 'BASE_58') {\n                return 'base58';\n            }\n            if (argumentNode.value.value === 'BASE_64') {\n                return 'base64';\n            }\n        }\n        if (argumentNode.value.kind === 'Variable') {\n            return variableValues[argumentNode.value.name.value] as TransactionLoaderArgs['encoding'];\n        }\n    } else {\n        return undefined;\n    }\n}\n\nexport function buildTransactionArgSetWithVisitor<TArgs extends BlockLoaderArgs | TransactionLoaderArgs>(\n    args: TArgs,\n    info: GraphQLResolveInfo,\n): TArgs[] {\n    const argSet = [args];\n\n    function buildArgSetWithVisitor(root: Parameters<typeof injectableRootVisitor>[1]) {\n        injectableRootVisitor(info, root, {\n            fieldNodeOperation(info, node) {\n                if (node.name.value === 'message' || node.name.value === 'meta') {\n                    argSet.push({ ...args, encoding: 'jsonParsed' });\n                } else if (node.name.value === 'data') {\n                    // At least `encoding` is required on the `data` field.\n                    if (node.arguments) {\n                        const { variableValues } = info;\n                        const encoding: TransactionLoaderArgs['encoding'] = parseTransactionEncodingArgument(\n                            node.arguments,\n                            variableValues,\n                        );\n                        argSet.push({ ...args, encoding });\n                    }\n                }\n            },\n            fragmentSpreadNodeOperation(_info, fragment) {\n                buildArgSetWithVisitor(fragment);\n            },\n            inlineFragmentNodeOperation(_info, _node) {\n                // Transaction schema doesn't support inline fragments at the\n                // root level.\n                return;\n            },\n        });\n    }\n\n    buildArgSetWithVisitor(null);\n\n    return argSet;\n}\n\n/**\n * Build a set of transaction loader args by inspecting which fields have\n * been requested in the query (ie. `data` or inline fragments).\n */\nexport function buildTransactionLoaderArgSetFromResolveInfo(\n    args: {\n        /**\n         * Fetch the transaction details as of the highest slot that has reached this level of\n         * commitment.\n         *\n         * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n         * example, when using an API created by a `createSolanaRpc*()` helper, the default\n         * commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on\n         * the client, the default commitment applied by the server is `\"finalized\"`.\n         */\n        commitment?: Omit<Commitment, 'processed'>;\n        /**\n         * Prevents accessing stale data by enforcing that the RPC node has processed transactions\n         * up to this slot\n         */\n        minContextSlot?: Slot;\n        signature: Signature;\n    },\n    info: GraphQLResolveInfo,\n): TransactionLoaderArgs[] {\n    return buildTransactionArgSetWithVisitor(args, info);\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/resolve-info/visitor.ts",
    "content": "import {\n    ASTNode,\n    ASTVisitFn,\n    BREAK,\n    FieldNode,\n    FragmentDefinitionNode,\n    FragmentSpreadNode,\n    GraphQLResolveInfo,\n    InlineFragmentNode,\n    visit,\n} from 'graphql';\n\ntype InjectableVisitorOperations = {\n    fieldNodeOperation: (info: GraphQLResolveInfo, ...args: Parameters<ASTVisitFn<FieldNode>>) => void;\n    fragmentSpreadNodeOperation: (\n        info: GraphQLResolveInfo,\n        fragment: FragmentDefinitionNode,\n        ...args: Parameters<ASTVisitFn<FragmentSpreadNode>>\n    ) => void;\n    inlineFragmentNodeOperation: (\n        info: GraphQLResolveInfo,\n        ...args: Parameters<ASTVisitFn<InlineFragmentNode>>\n    ) => void;\n};\ntype RootNode = FieldNode | FragmentDefinitionNode | InlineFragmentNode;\n\n/**\n * An AST visitor that keys on the root field provided.\n * This visitor can be injected with custom logic for various types of nodes.\n */\nexport function injectableRootVisitor(\n    info: GraphQLResolveInfo,\n    rootNode: RootNode | null,\n    operations: InjectableVisitorOperations,\n) {\n    const { fieldNodes } = info;\n    const root = rootNode ?? fieldNodes[0];\n    const parentIsRoot = (ancestors: readonly (ASTNode | readonly ASTNode[])[]) =>\n        (Array.isArray(ancestors) ? ancestors[0] : ancestors) === root;\n    visit(root, {\n        Field(node, key, parent, path, ancestors) {\n            if (!parentIsRoot(ancestors)) return;\n            return operations.fieldNodeOperation(info, node, key, parent, path, ancestors);\n        },\n        FragmentSpread(node, key, parent, path, ancestors) {\n            const fragmentDefinition = info.fragments[node.name.value];\n            return operations.fragmentSpreadNodeOperation(info, fragmentDefinition, node, key, parent, path, ancestors);\n        },\n        InlineFragment(node, key, parent, path, ancestors) {\n            if (!parentIsRoot(ancestors)) return;\n            return operations.inlineFragmentNodeOperation(info, node, key, parent, path, ancestors);\n        },\n    });\n}\n\n/**\n * Determine if the query only requests the provided field names\n */\nexport function onlyFieldsRequested(fieldNames: string[], info: GraphQLResolveInfo, rootNode?: RootNode): boolean {\n    let onlyFieldsRequested = true;\n\n    function checkFieldsWithVisitor(root: RootNode | null) {\n        injectableRootVisitor(info, root, {\n            fieldNodeOperation(_info, node) {\n                // Ignore the GraphQL default fields.\n                if (node.name.value === '__id' || node.name.value === '__typename') {\n                    return;\n                }\n                onlyFieldsRequested = fieldNames.includes(node.name.value);\n                if (!onlyFieldsRequested) {\n                    return BREAK;\n                }\n            },\n            fragmentSpreadNodeOperation(_info, fragment) {\n                checkFieldsWithVisitor(fragment);\n            },\n            inlineFragmentNodeOperation(_info, node) {\n                checkFieldsWithVisitor(node);\n            },\n        });\n    }\n\n    checkFieldsWithVisitor(rootNode ?? null);\n\n    return onlyFieldsRequested;\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/resolvers/transaction.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Signature } from '@solana/keys';\nimport { Commitment } from '@solana/rpc-types';\nimport type { GraphQLResolveInfo } from 'graphql';\n\nimport { RpcGraphQLContext } from '../context';\nimport { cacheKeyFn, TransactionLoaderValue } from '../loaders';\nimport { buildTransactionLoaderArgSetFromResolveInfo, onlyFieldsRequested } from './resolve-info';\n\nexport type EncodedTransactionData = {\n    [key: string]: string;\n};\n\nexport type InstructionResult = {\n    [key: string]: unknown;\n} & {\n    jsonParsedConfigs?: {\n        instructionType: string;\n        programId: Address;\n        programName: string;\n    };\n    programId?: Address;\n};\n\nexport type TransactionResult = Partial<TransactionLoaderValue> & {\n    encodedData?: EncodedTransactionData;\n    signature?: Signature;\n};\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function mapJsonParsedInstructions(instructions: readonly any[]): InstructionResult[] {\n    return instructions.map(instruction => {\n        if ('parsed' in instruction) {\n            // `jsonParsed`\n            if (typeof instruction.parsed === 'string' && instruction.program === 'spl-memo') {\n                const { parsed: memo, program: programName, programId } = instruction;\n                const instructionType = 'memo';\n                const jsonParsedConfigs = {\n                    instructionType,\n                    programId,\n                    programName,\n                };\n                return { jsonParsedConfigs, memo, programId };\n            }\n            const {\n                parsed: { info: data, type: instructionType },\n                program: programName,\n                programId,\n            } = instruction;\n            const jsonParsedConfigs = {\n                instructionType,\n                programId,\n                programName,\n            };\n            return { jsonParsedConfigs, ...data, programId };\n        } else {\n            // `json`\n            return instruction;\n        }\n    });\n}\n\nexport function mapJsonParsedInnerInstructions(\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    innerInstructions: readonly any[],\n): { index: number; instructions: InstructionResult[] }[] {\n    return innerInstructions.map(({ index, instructions }) => ({\n        index,\n        instructions: mapJsonParsedInstructions(instructions),\n    }));\n}\n\nexport const resolveTransactionData = () => {\n    return (\n        parent: TransactionResult | null,\n        args: {\n            encoding: 'base58' | 'base64';\n        },\n    ) => {\n        return parent === null ? null : parent.encodedData ? parent.encodedData[cacheKeyFn(args)] : null;\n    };\n};\n\nexport function resolveTransaction(fieldName?: string) {\n    return async (\n        parent: { [x: string]: Signature },\n        args: {\n            commitment?: Omit<Commitment, 'processed'>;\n            signature?: Signature;\n        },\n        context: RpcGraphQLContext,\n        info: GraphQLResolveInfo,\n    ): Promise<TransactionResult | null> => {\n        const signature = fieldName ? parent[fieldName] : args.signature;\n\n        if (signature) {\n            if (onlyFieldsRequested(['signature'], info)) {\n                return { signature };\n            }\n\n            const argsSet = buildTransactionLoaderArgSetFromResolveInfo({ ...args, signature }, info);\n            const loadedTransactions = await context.loaders.transaction.loadMany(argsSet);\n\n            let result: TransactionResult = {\n                encodedData: {},\n                signature,\n            };\n\n            loadedTransactions.forEach((loadedTransaction, i) => {\n                if (loadedTransaction instanceof Error) {\n                    console.error(loadedTransaction);\n                    return;\n                }\n                if (loadedTransaction === null) {\n                    return;\n                }\n                if (!result.slot) {\n                    result = {\n                        ...result,\n                        ...loadedTransaction,\n                    };\n                }\n\n                const { transaction: data } = loadedTransaction;\n                const { encoding } = argsSet[i];\n\n                if (encoding && result.encodedData) {\n                    if (Array.isArray(data)) {\n                        result.encodedData[\n                            cacheKeyFn({\n                                encoding,\n                            })\n                        ] = data[0];\n                    } else if (typeof data === 'object') {\n                        const jsonParsedData = data;\n                        jsonParsedData.message.instructions = mapJsonParsedInstructions(\n                            jsonParsedData.message.instructions,\n                        ) as unknown as (typeof jsonParsedData)['message']['instructions'];\n\n                        const loadedInnerInstructions = loadedTransaction.meta?.innerInstructions;\n                        if (loadedInnerInstructions) {\n                            const innerInstructions = mapJsonParsedInnerInstructions(loadedInnerInstructions);\n                            const jsonParsedMeta = {\n                                ...loadedTransaction.meta,\n                                innerInstructions,\n                            };\n                            result = {\n                                ...result,\n                                ...jsonParsedData,\n                                meta: jsonParsedMeta as unknown as (typeof loadedTransaction)['meta'],\n                            };\n                        } else {\n                            result = {\n                                ...result,\n                                ...jsonParsedData,\n                            };\n                        }\n                    }\n                }\n            });\n            return result;\n        }\n        return null;\n    };\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-defs/account.ts",
    "content": "export const accountTypeDefs = /* GraphQL */ `\n    \"\"\"\n    Token-2022 Extensions (Account State)\n    \"\"\"\n    interface SplTokenExtension {\n        extension: String\n    }\n\n    \"\"\"\n    Token-2022 Extension: Confidential Transfer Fee Config\n    \"\"\"\n    type SplTokenExtensionConfidentialTransferFeeConfig implements SplTokenExtension {\n        extension: String\n        authority: Account\n        harvestToMintEnabled: Boolean\n        withdrawWithheldAuthorityElgamalPubkey: Address\n        withheldAmount: String\n    }\n\n    \"\"\"\n    Token-2022 Extension: Confidential Transfer Mint\n    \"\"\"\n    type SplTokenExtensionConfidentialTransferMint implements SplTokenExtension {\n        extension: String\n        auditorElgamalPubkey: Address\n        authority: Account\n        autoApproveNewAccounts: Boolean\n    }\n\n    \"\"\"\n    Token-2022 Extension: Default Account State\n    \"\"\"\n    type SplTokenExtensionDefaultAccountState implements SplTokenExtension {\n        extension: String\n        accountState: SplTokenDefaultAccountState\n    }\n\n    \"\"\"\n    Token-2022 Extension: Group Pointer\n    \"\"\"\n    type SplTokenExtensionGroupPointer implements SplTokenExtension {\n        extension: String\n        authority: Account\n        groupAddress: Account\n    }\n\n    \"\"\"\n    Token-2022 Extension: Group Member Pointer\n    \"\"\"\n    type SplTokenExtensionGroupMemberPointer implements SplTokenExtension {\n        extension: String\n        authority: Account\n        memberAddress: Account\n    }\n\n    \"\"\"\n    Token-2022 Extension: Interest-Bearing Config\n    \"\"\"\n    type SplTokenExtensionInterestBearingConfig implements SplTokenExtension {\n        extension: String\n        currentRate: Int\n        initializationTimestamp: BigInt\n        lastUpdateTimestamp: BigInt\n        preUpdateAverageRate: Int\n        rateAuthority: Account\n    }\n\n    \"\"\"\n    Token-2022 Extension: Metadata Pointer\n    \"\"\"\n    type SplTokenExtensionMetadataPointer implements SplTokenExtension {\n        extension: String\n        authority: Account\n        metadataAddress: Account\n    }\n\n    \"\"\"\n    Token-2022 Extension: Mint Close Authority\n    \"\"\"\n    type SplTokenExtensionMintCloseAuthority implements SplTokenExtension {\n        extension: String\n        closeAuthority: Account\n    }\n\n    \"\"\"\n    Token-2022 Extension: Non-Transferable\n    \"\"\"\n    type SplTokenExtensionNonTransferable implements SplTokenExtension {\n        extension: String\n    }\n\n    \"\"\"\n    Token-2022 Extension: Permanent Delegate\n    \"\"\"\n    type SplTokenExtensionPermanentDelegate implements SplTokenExtension {\n        extension: String\n        delegate: Account\n    }\n\n    \"\"\"\n    Token-2022 Extension: Token Group\n    \"\"\"\n    type SplTokenExtensionTokenGroup implements SplTokenExtension {\n        extension: String\n        maxSize: BigInt\n        mint: Account\n        size: BigInt\n        updateAuthority: Account\n    }\n\n    \"\"\"\n    Token-2022 Extension: Token Group Member\n    \"\"\"\n    type SplTokenExtensionTokenGroupMember implements SplTokenExtension {\n        extension: String\n        group: Account\n        memberNumber: BigInt\n        mint: Account\n    }\n\n    type SplTokenMetadataAdditionalMetadata {\n        key: String\n        value: String\n    }\n    \"\"\"\n    Token-2022 Extension: Token Metadata\n    \"\"\"\n    type SplTokenExtensionTokenMetadata implements SplTokenExtension {\n        extension: String\n        additionalMetadata: [SplTokenMetadataAdditionalMetadata]\n        mint: Account\n        name: String\n        symbol: String\n        updateAuthority: Account\n        uri: String\n    }\n\n    type SplTokenTransferFeeConfig {\n        epoch: Epoch\n        maximumFee: BigInt\n        transferFeeBasisPoints: Int\n    }\n    \"\"\"\n    Token-2022 Extension: Transfer Fee Config\n    \"\"\"\n    type SplTokenExtensionTransferFeeConfig implements SplTokenExtension {\n        extension: String\n        newerTransferFee: SplTokenTransferFeeConfig\n        olderTransferFee: SplTokenTransferFeeConfig\n        transferFeeConfigAuthority: Account\n        withdrawWithheldAuthority: Account\n        withheldAmount: BigInt\n    }\n\n    \"\"\"\n    Token-2022 Extension: Transfer Hook\n    \"\"\"\n    type SplTokenExtensionTransferHook implements SplTokenExtension {\n        extension: String\n        authority: Account\n        hookProgramId: Account\n    }\n\n    \"\"\"\n    Token-2022 Extension: Transfer Fee Amount\n    \"\"\"\n    type SplTokenExtensionTransferFeeAmount implements SplTokenExtension {\n        extension: String\n        withheldAmount: BigInt\n    }\n\n    \"\"\"\n    Token-2022 Extension: Transfer Hook Account\n    \"\"\"\n    type SplTokenExtensionTransferHookAccount implements SplTokenExtension {\n        extension: String\n        transferring: Boolean\n    }\n\n    \"\"\"\n    Token-2022 Extension: Confidential Transfer Fee Amount\n    \"\"\"\n    type SplTokenExtensionConfidentialTransferFeeAmount implements SplTokenExtension {\n        extension: String\n        withheldAmount: String\n    }\n\n    \"\"\"\n    Token-2022 Extension: NonTransferableAccount\n    \"\"\"\n    type SplTokenExtensionNonTransferableAccount implements SplTokenExtension {\n        extension: String\n    }\n\n    \"\"\"\n    Token-2022 Extension: ImmutableOwner\n    \"\"\"\n    type SplTokenExtensionImmutableOwner implements SplTokenExtension {\n        extension: String\n    }\n\n    \"\"\"\n    Token-2022 Extension: MemoTransfer\n    \"\"\"\n    type SplTokenExtensionMemoTransfer implements SplTokenExtension {\n        extension: String\n        requireIncomingTransferMemos: Boolean\n    }\n\n    \"\"\"\n    Token-2022 Extension: CpiGuard\n    \"\"\"\n    type SplTokenExtensionCpiGuard implements SplTokenExtension {\n        extension: String\n        lockCpi: Boolean\n    }\n\n    \"\"\"\n    Token-2022 Extension: Unparseable\n    \"\"\"\n    type SplTokenExtensionUnparseable implements SplTokenExtension {\n        extension: String\n    }\n\n    \"\"\"\n    Token-2022 Extension: ConfidentialTransferAccount\n    \"\"\"\n    type SplTokenExtensionConfidentialTransferAccount implements SplTokenExtension {\n        extension: String\n        actualPendingBalanceCreditCounter: Int\n        allowConfidentialCredits: Boolean\n        allowNonConfidentialCredits: Boolean\n        approved: Boolean\n        availableBalance: String\n        decryptableAvailableBalance: String\n        elgamalPubkey: String\n        expectedPendingBalanceCreditCounter: Int\n        maximumPendingBalanceCreditCounter: Int\n        pendingBalanceCreditCounter: Int\n        pendingBalanceHi: String\n        pendingBalanceLo: String\n    }\n\n    \"\"\"\n    Account interface\n    \"\"\"\n    interface Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n    }\n\n    \"\"\"\n    Generic base account type\n    \"\"\"\n    type GenericAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n    }\n\n    type NonceAccountFeeCalculator {\n        lamportsPerSignature: Lamports\n    }\n    \"\"\"\n    A nonce account\n    \"\"\"\n    type NonceAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        authority: Account\n        blockhash: Hash\n        feeCalculator: NonceAccountFeeCalculator\n    }\n\n    \"\"\"\n    A lookup table account\n    \"\"\"\n    type LookupTableAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        addresses: [Address]\n        authority: Account\n        deactivationSlot: Slot\n        lastExtendedSlot: Slot\n        lastExtendedSlotStartIndex: Int\n    }\n\n    \"\"\"\n    A mint account\n    \"\"\"\n    type MintAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        decimals: Int\n        extensions: [SplTokenExtension]\n        freezeAuthority: Account\n        isInitialized: Boolean\n        mintAuthority: Account\n        supply: BigInt\n    }\n\n    \"\"\"\n    A token account\n    \"\"\"\n    type TokenAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        extensions: [SplTokenExtension]\n        isNative: Boolean\n        mint: Account\n        owner: Account\n        state: String\n        tokenAmount: TokenAmount\n    }\n\n    type StakeAccountDataMetaAuthorized {\n        staker: Account\n        withdrawer: Account\n    }\n    type StakeAccountDataMetaLockup {\n        custodian: Account\n        epoch: Epoch\n        unixTimestamp: BigInt\n    }\n    type StakeAccountDataMeta {\n        authorized: StakeAccountDataMetaAuthorized\n        lockup: StakeAccountDataMetaLockup\n        rentExemptReserve: Lamports\n    }\n    type StakeAccountDataStakeDelegation {\n        activationEpoch: Epoch\n        deactivationEpoch: Epoch\n        stake: Lamports\n        voter: Account\n        warmupCooldownRate: Int\n    }\n    type StakeAccountDataStake {\n        creditsObserved: BigInt\n        delegation: StakeAccountDataStakeDelegation\n    }\n    \"\"\"\n    A stake account\n    \"\"\"\n    type StakeAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        meta: StakeAccountDataMeta\n        stake: StakeAccountDataStake\n    }\n\n    type VoteAccountDataAuthorizedVoter {\n        authorizedVoter: Account\n        epoch: Epoch\n    }\n    type VoteAccountDataEpochCredit {\n        credits: BigInt\n        epoch: Epoch\n        previousCredits: BigInt\n    }\n    type VoteAccountDataLastTimestamp {\n        slot: Slot\n        timestamp: BigInt\n    }\n    type VoteAccountDataVote {\n        confirmationCount: Int\n        slot: Slot\n    }\n    \"\"\"\n    A vote account\n    \"\"\"\n    type VoteAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        authorizedVoters: [VoteAccountDataAuthorizedVoter]\n        authorizedWithdrawer: Account\n        commission: Int\n        epochCredits: [VoteAccountDataEpochCredit]\n        lastTimestamp: VoteAccountDataLastTimestamp\n        node: Account\n        priorVoters: [Address]\n        rootSlot: Slot\n        votes: [VoteAccountDataVote]\n    }\n\n    \"\"\"\n    Sysvar Clock\n    \"\"\"\n    type SysvarClockAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        epoch: Epoch\n        epochStartTimestamp: BigInt\n        leaderScheduleEpoch: Epoch\n        slot: Slot\n        unixTimestamp: BigInt\n    }\n\n    \"\"\"\n    Sysvar Epoch Rewards\n    \"\"\"\n    type SysvarEpochRewardsAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        distributedRewards: Lamports\n        distributionCompleteBlockHeight: BigInt\n        totalRewards: Lamports\n    }\n\n    \"\"\"\n    Sysvar Epoch Schedule\n    \"\"\"\n    type SysvarEpochScheduleAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        firstNormalEpoch: Epoch\n        firstNormalSlot: Slot\n        leaderScheduleSlotOffset: BigInt\n        slotsPerEpoch: BigInt\n        warmup: Boolean\n    }\n\n    type FeeCalculator {\n        lamportsPerSignature: Lamports\n    }\n\n    \"\"\"\n    Sysvar Last Restart Slot\n    \"\"\"\n    type SysvarLastRestartSlotAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        lastRestartSlot: Slot\n    }\n\n    type SysvarRecentBlockhashesEntry {\n        blockhash: Hash\n        feeCalculator: FeeCalculator\n    }\n    \"\"\"\n    Sysvar Recent Blockhashes\n    \"\"\"\n    type SysvarRecentBlockhashesAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        entries: [SysvarRecentBlockhashesEntry]\n    }\n\n    \"\"\"\n    Sysvar Rent\n    \"\"\"\n    type SysvarRentAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        burnPercent: Int\n        exemptionThreshold: Int\n        lamportsPerByteYear: Lamports\n    }\n\n    type SlotHashEntry {\n        hash: Hash\n        slot: Slot\n    }\n\n    \"\"\"\n    Sysvar Slot Hashes\n    \"\"\"\n    type SysvarSlotHashesAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        entries: [SlotHashEntry]\n    }\n\n    \"\"\"\n    Sysvar Slot History\n    \"\"\"\n    type SysvarSlotHistoryAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        bits: String\n        nextSlot: Slot\n    }\n\n    type StakeHistoryEntry {\n        activating: Lamports\n        deactivating: Lamports\n        effective: Lamports\n    }\n\n    \"\"\"\n    Sysvar Stake History\n    \"\"\"\n    type SysvarStakeHistoryAccount implements Account {\n        address: Address\n        data(encoding: AccountEncoding!, dataSlice: DataSlice): String\n        executable: Boolean\n        lamports: Lamports\n        ownerProgram: Account\n        space: BigInt\n        entries: [StakeHistoryEntry]\n    }\n`;\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-defs/block.ts",
    "content": "export const blockTypeDefs = /* GraphQL */ `\n    \"\"\"\n    A Solana block\n    \"\"\"\n    type Block {\n        blockhash: Hash\n        blockHeight: BigInt\n        blockTime: BigInt\n        parentSlot: Slot\n        previousBlockhash: Hash\n        rewards: [Reward]\n        signatures: [Signature]\n        transactions: [Transaction]\n    }\n`;\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-defs/index.ts",
    "content": "import { accountTypeDefs } from './account';\nimport { blockTypeDefs } from './block';\nimport { instructionTypeDefs } from './instruction';\nimport { rootTypeDefs } from './root';\nimport { transactionTypeDefs } from './transaction';\nimport { typeTypeDefs } from './types';\n\n/**\n * Creates the GraphQL type definitions for the Solana GraphQL schema.\n *\n * @returns     Solana GraphQL type definitions.\n */\nexport function createSolanaGraphQLTypeDefs() {\n    return [accountTypeDefs, blockTypeDefs, instructionTypeDefs, rootTypeDefs, typeTypeDefs, transactionTypeDefs];\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-defs/instruction.ts",
    "content": "// *Note: Any integer value inside a transaction instruction must be `BigInt`\n// until the following issue is resolved:\n// <https://github.com/solana-labs/solana-web3.js/issues/1828>\nexport const instructionTypeDefs = /* GraphQL */ `\n    \"\"\"\n    Transaction instruction interface\n    \"\"\"\n    interface TransactionInstruction {\n        programId: Address\n    }\n\n    \"\"\"\n    Generic transaction instruction\n    \"\"\"\n    type GenericInstruction implements TransactionInstruction {\n        accounts: [Address]\n        data: Base64EncodedBytes\n        programId: Address\n    }\n\n    \"\"\"\n    AddressLookupTable: CreateLookupTable instruction\n    \"\"\"\n    type CreateLookupTableInstruction implements TransactionInstruction {\n        programId: Address\n        bumpSeed: BigInt # FIXME:*\n        lookupTableAccount: Account\n        lookupTableAuthority: Account\n        payerAccount: Account\n        recentSlot: Slot\n        systemProgram: Account\n    }\n\n    \"\"\"\n    AddressLookupTable: ExtendLookupTable instruction\n    \"\"\"\n    type ExtendLookupTableInstruction implements TransactionInstruction {\n        programId: Address\n        lookupTableAccount: Account\n        lookupTableAuthority: Account\n        newAddresses: [Address]\n        payerAccount: Account\n        systemProgram: Account\n    }\n\n    \"\"\"\n    AddressLookupTable: FreezeLookupTable instruction\n    \"\"\"\n    type FreezeLookupTableInstruction implements TransactionInstruction {\n        programId: Address\n        lookupTableAccount: Account\n        lookupTableAuthority: Account\n    }\n\n    \"\"\"\n    AddressLookupTable: DeactivateLookupTable instruction\n    \"\"\"\n    type DeactivateLookupTableInstruction implements TransactionInstruction {\n        programId: Address\n        lookupTableAccount: Account\n        lookupTableAuthority: Account\n    }\n\n    \"\"\"\n    AddressLookupTable: CloseLookupTable instruction\n    \"\"\"\n    type CloseLookupTableInstruction implements TransactionInstruction {\n        programId: Address\n        lookupTableAccount: Account\n        lookupTableAuthority: Account\n        recipient: Account\n    }\n\n    \"\"\"\n    BpfLoader: Write instruction\n    \"\"\"\n    type BpfLoaderWriteInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        bytes: Base64EncodedBytes\n        offset: BigInt # FIXME:*\n    }\n\n    \"\"\"\n    BpfLoader: Finalize instruction\n    \"\"\"\n    type BpfLoaderFinalizeInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n    }\n\n    \"\"\"\n    BpfUpgradeableLoader: InitializeBuffer instruction\n    \"\"\"\n    type BpfUpgradeableLoaderInitializeBufferInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n    }\n\n    \"\"\"\n    BpfUpgradeableLoader: Write instruction\n    \"\"\"\n    type BpfUpgradeableLoaderWriteInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        authority: Account\n        bytes: Base64EncodedBytes\n        offset: BigInt # FIXME:*\n    }\n\n    \"\"\"\n    BpfUpgradeableLoader: DeployWithMaxDataLen instruction\n    \"\"\"\n    type BpfUpgradeableLoaderDeployWithMaxDataLenInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        bufferAccount: Account\n        clockSysvar: Account\n        maxDataLen: BigInt\n        payerAccount: Account\n        programAccount: Account\n        programDataAccount: Account\n        rentSysvar: Account\n    }\n\n    \"\"\"\n    BpfUpgradeableLoader: Upgrade instruction\n    \"\"\"\n    type BpfUpgradeableLoaderUpgradeInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        bufferAccount: Account\n        clockSysvar: Account\n        programAccount: Account\n        programDataAccount: Account\n        rentSysvar: Account\n        spillAccount: Account\n    }\n\n    \"\"\"\n    BpfUpgradeableLoader: SetAuthority instruction\n    \"\"\"\n    type BpfUpgradeableLoaderSetAuthorityInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        authority: Account\n        newAuthority: Account\n    }\n\n    \"\"\"\n    BpfUpgradeableLoader: SetAuthorityChecked instruction\n    \"\"\"\n    type BpfUpgradeableLoaderSetAuthorityCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        authority: Account\n        newAuthority: Account\n    }\n\n    \"\"\"\n    BpfUpgradeableLoader: Close instruction\n    \"\"\"\n    type BpfUpgradeableLoaderCloseInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        authority: Account\n        programAccount: Account\n        recipient: Account\n    }\n\n    \"\"\"\n    BpfUpgradeableLoader: ExtendProgram instruction\n    \"\"\"\n    type BpfUpgradeableLoaderExtendProgramInstruction implements TransactionInstruction {\n        programId: Address\n        additionalBytes: BigInt\n        payerAccount: Account\n        programAccount: Account\n        programDataAccount: Account\n        systemProgram: Account\n    }\n\n    \"\"\"\n    SplAssociatedTokenAccount: Create instruction\n    \"\"\"\n    type SplAssociatedTokenCreateInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        mint: Account\n        source: Account\n        systemProgram: Account\n        tokenProgram: Account\n        wallet: Account\n    }\n\n    \"\"\"\n    SplAssociatedTokenAccount: CreateIdempotent instruction\n    \"\"\"\n    type SplAssociatedTokenCreateIdempotentInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        mint: Account\n        source: Account\n        systemProgram: Account\n        tokenProgram: Account\n        wallet: Account\n    }\n\n    \"\"\"\n    SplAssociatedTokenAccount: RecoverNested instruction\n    \"\"\"\n    type SplAssociatedTokenRecoverNestedInstruction implements TransactionInstruction {\n        programId: Address\n        destination: Account\n        nestedMint: Account\n        nestedOwner: Account\n        nestedSource: Account\n        ownerMint: Account\n        tokenProgram: Account\n        wallet: Account\n    }\n\n    \"\"\"\n    SplMemo instruction\n    \"\"\"\n    type SplMemoInstruction implements TransactionInstruction {\n        programId: Address\n        memo: String\n    }\n\n    \"\"\"\n    SplToken: InitializeMint instruction\n    \"\"\"\n    type SplTokenInitializeMintInstruction implements TransactionInstruction {\n        programId: Address\n        decimals: BigInt # FIXME:*\n        freezeAuthority: Account\n        mint: Account\n        mintAuthority: Account\n        rentSysvar: Account\n    }\n\n    \"\"\"\n    SplToken: InitializeMint2 instruction\n    \"\"\"\n    type SplTokenInitializeMint2Instruction implements TransactionInstruction {\n        programId: Address\n        decimals: BigInt # FIXME:*\n        freezeAuthority: Account\n        mint: Account\n        mintAuthority: Account\n    }\n\n    \"\"\"\n    SplToken: InitializeAccount instruction\n    \"\"\"\n    type SplTokenInitializeAccountInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        mint: Account\n        owner: Account\n        rentSysvar: Account\n    }\n\n    \"\"\"\n    SplToken: InitializeAccount2 instruction\n    \"\"\"\n    type SplTokenInitializeAccount2Instruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        mint: Account\n        owner: Account\n        rentSysvar: Account\n    }\n\n    \"\"\"\n    SplToken: InitializeAccount3 instruction\n    \"\"\"\n    type SplTokenInitializeAccount3Instruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        mint: Account\n        owner: Account\n    }\n\n    \"\"\"\n    SplToken: InitializeMultisig instruction\n    \"\"\"\n    type SplTokenInitializeMultisigInstruction implements TransactionInstruction {\n        programId: Address\n        m: BigInt # FIXME:*\n        multisig: Account\n        rentSysvar: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken: InitializeMultisig2 instruction\n    \"\"\"\n    type SplTokenInitializeMultisig2Instruction implements TransactionInstruction {\n        programId: Address\n        m: BigInt # FIXME:*\n        multisig: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken: Transfer instruction\n    \"\"\"\n    type SplTokenTransferInstruction implements TransactionInstruction {\n        programId: Address\n        amount: BigInt\n        authority: Account\n        destination: Account\n        multisigAuthority: Account\n        source: Account\n    }\n\n    \"\"\"\n    SplToken: Approve instruction\n    \"\"\"\n    type SplTokenApproveInstruction implements TransactionInstruction {\n        programId: Address\n        amount: BigInt\n        delegate: Account\n        multisigOwner: Account\n        owner: Account\n        source: Account\n    }\n\n    \"\"\"\n    SplToken: Revoke instruction\n    \"\"\"\n    type SplTokenRevokeInstruction implements TransactionInstruction {\n        programId: Address\n        multisigOwner: Account\n        owner: Account\n        source: Account\n    }\n\n    \"\"\"\n    SplToken: SetAuthority instruction\n    \"\"\"\n    type SplTokenSetAuthorityInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        authorityType: String\n        multisigAuthority: Account\n        newAuthority: Account\n    }\n\n    \"\"\"\n    SplToken: MintTo instruction\n    \"\"\"\n    type SplTokenMintToInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        amount: BigInt\n        authority: Account\n        mint: Account\n        mintAuthority: Account\n        multisigMintAuthority: Account\n    }\n\n    \"\"\"\n    SplToken: Burn instruction\n    \"\"\"\n    type SplTokenBurnInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        amount: BigInt\n        authority: Account\n        mint: Account\n        multisigAuthority: Account\n    }\n\n    \"\"\"\n    SplToken: CloseAccount instruction\n    \"\"\"\n    type SplTokenCloseAccountInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        destination: Account\n        multisigOwner: Account\n        owner: Account\n    }\n\n    \"\"\"\n    SplToken: FreezeAccount instruction\n    \"\"\"\n    type SplTokenFreezeAccountInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        freezeAuthority: Account\n        mint: Account\n        multisigFreezeAuthority: Account\n    }\n\n    \"\"\"\n    SplToken: ThawAccount instruction\n    \"\"\"\n    type SplTokenThawAccountInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        freezeAuthority: Account\n        mint: Account\n        multisigFreezeAuthority: Account\n    }\n\n    \"\"\"\n    SplToken: TransferChecked instruction\n    \"\"\"\n    type SplTokenTransferCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        amount: BigInt\n        authority: Account\n        decimals: BigInt # FIXME:*\n        destination: Account\n        mint: Account\n        multisigAuthority: Account\n        source: Account\n        tokenAmount: BigInt\n    }\n\n    \"\"\"\n    SplToken: ApproveChecked instruction\n    \"\"\"\n    type SplTokenApproveCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        delegate: Account\n        mint: Account\n        multisigOwner: Account\n        owner: Account\n        source: Account\n        tokenAmount: BigInt\n    }\n\n    \"\"\"\n    SplToken: MintToChecked instruction\n    \"\"\"\n    type SplTokenMintToCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        authority: Account\n        mint: Account\n        mintAuthority: Account\n        multisigMintAuthority: Account\n        tokenAmount: BigInt\n    }\n\n    \"\"\"\n    SplToken: BurnChecked instruction\n    \"\"\"\n    type SplTokenBurnCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        authority: Account\n        mint: Account\n        multisigAuthority: Account\n        tokenAmount: BigInt\n    }\n\n    \"\"\"\n    SplToken: SyncNative instruction\n    \"\"\"\n    type SplTokenSyncNativeInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n    }\n\n    \"\"\"\n    SplToken: GetAccountDataSize instruction\n    \"\"\"\n    type SplTokenGetAccountDataSizeInstruction implements TransactionInstruction {\n        programId: Address\n        extensionTypes: [String]\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken: InitializeImmutableOwner instruction\n    \"\"\"\n    type SplTokenInitializeImmutableOwnerInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n    }\n\n    \"\"\"\n    SplToken: AmountToUiAmount instruction\n    \"\"\"\n    type SplTokenAmountToUiAmountInstruction implements TransactionInstruction {\n        programId: Address\n        amount: BigInt\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken: UiAmountToAmount instruction\n    \"\"\"\n    type SplTokenUiAmountToAmountInstruction implements TransactionInstruction {\n        programId: Address\n        mint: Account\n        uiAmount: String\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeDefaultAccountState instruction\n    \"\"\"\n    type SplTokenInitializeDefaultAccountStateInstruction implements TransactionInstruction {\n        programId: Address\n        accountState: SplTokenDefaultAccountState\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken-2022: UpdateDefaultAccountState instruction\n    \"\"\"\n    type SplTokenUpdateDefaultAccountStateInstruction implements TransactionInstruction {\n        programId: Address\n        accountState: SplTokenDefaultAccountState\n        freezeAuthority: Account\n        mint: Account\n        multisigFreezeAuthority: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeMintCloseAuthority instruction\n    \"\"\"\n    type SplTokenInitializeMintCloseAuthorityInstruction implements TransactionInstruction {\n        programId: Address\n        mint: Account\n        newAuthority: Account\n    }\n\n    \"\"\"\n    SplToken-2022: InitializePermanentDelegate instruction\n    \"\"\"\n    type SplTokenInitializePermanentDelegateInstruction implements TransactionInstruction {\n        programId: Address\n        delegate: Account\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeGroupPointer instruction\n    \"\"\"\n    type SplTokenInitializeGroupPointerInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        groupAddress: Account\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken-2022: UpdateGroupPointer instruction\n    \"\"\"\n    type SplTokenUpdateGroupPointerInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        groupAddress: Account\n        mint: Account\n        multisigAuthority: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeGroupMemberPointer instruction\n    \"\"\"\n    type SplTokenInitializeGroupMemberPointerInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        memberAddress: Account\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken-2022: UpdateGroupMemberPointer instruction\n    \"\"\"\n    type SplTokenUpdateGroupMemberPointerInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        memberAddress: Account\n        mint: Account\n        multisigAuthority: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeMetadataPointer instruction\n    \"\"\"\n    type SplTokenInitializeMetadataPointerInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        metadataAddress: Account\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken-2022: UpdateMetadataPointer instruction\n    \"\"\"\n    type SplTokenUpdateMetadataPointerInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        metadataAddress: Account\n        mint: Account\n        multisigAuthority: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeTransferFeeConfig instruction\n    \"\"\"\n    type SplTokenInitializeTransferFeeConfig implements TransactionInstruction {\n        programId: Address\n        mint: Account\n        transferFeeBasisPoints: BigInt #*FIXME:*\n        transferFeeConfigAuthority: Account\n        withdrawWithheldAuthority: Account\n        maximumFee: BigInt #*FIXME:*\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeTransferHook instruction\n    \"\"\"\n    type SplTokenInitializeTransferHookInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        hookProgramId: Account\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken-2022: UpdateTransferHook instruction\n    \"\"\"\n    type SplTokenUpdateTransferHookInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        hookProgramId: Account\n        mint: Account\n        multisigAuthority: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: EnableCpiGuard instruction\n    \"\"\"\n    type SplTokenEnableCpiGuardInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        multisigOwner: Account\n        owner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: DisableCpiGuard instruction\n    \"\"\"\n    type SplTokenDisableCpiGuardInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        multisigOwner: Account\n        owner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: HarvestWithheldTokensToMint instruction\n    \"\"\"\n    type SplTokenHarvestWithheldTokensToMint implements TransactionInstruction {\n        programId: Address\n        mint: Account\n        sourceAccounts: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: WithdrawWithheldTokensFromAccounts instruction\n    \"\"\"\n    type SplTokenWithdrawWithheldTokensFromAccounts implements TransactionInstruction {\n        programId: Address\n        feeRecipient: Account\n        mint: Account\n        multisigWithdrawWithheldAuthority: Account\n        signers: [Address]\n        sourceAccounts: [Address]\n        withdrawWithheldAuthority: Account\n    }\n\n    \"\"\"\n    SplToken-2022: WithdrawWithheldTokensFromMint instruction\n    \"\"\"\n    type SplTokenWithdrawWithheldTokensFromMint implements TransactionInstruction {\n        programId: Address\n        feeRecipient: Account\n        mint: Account\n        withdrawWithheldAuthority: Account\n        multisigWithdrawWithheldAuthority: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: TransferCheckedWithFee instruction\n    \"\"\"\n    type SplTokenTransferCheckedWithFee implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        destination: Account\n        feeAmount: TokenAmount\n        mint: Account\n        source: Account\n        tokenAmount: TokenAmount\n        multisigAuthority: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: EnableRequiredMemoTransfers instruction\n    \"\"\"\n    type SplTokenEnableRequiredMemoTransfers implements TransactionInstruction {\n        programId: Address\n        account: Account\n        owner: Account\n        multisigOwner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: DisableRequiredMemoTransfers instruction\n    \"\"\"\n    type SplTokenDisableRequiredMemoTransfers implements TransactionInstruction {\n        programId: Address\n        account: Account\n        owner: Account\n        multisigOwner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeConfidentialTransferMint instruction\n    \"\"\"\n    type SplTokenInitializeConfidentialTransferMint implements TransactionInstruction {\n        programId: Address\n        auditorElgamalPubkey: Address\n        authority: Account\n        autoApproveNewAccounts: Boolean\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeInterestBearingConfig instruction\n    \"\"\"\n    type SplTokenInitializeInterestBearingConfig implements TransactionInstruction {\n        programId: Address\n        mint: Account\n        rate: BigInt #*FIXME:*\n        rateAuthority: Account\n    }\n\n    \"\"\"\n    SplToken-2022: UpdateInterestBearingConfigRate instruction\n    \"\"\"\n    type SplTokenUpdateInterestBearingConfigRate implements TransactionInstruction {\n        programId: Address\n        mint: Account\n        multisigRateAuthority: Account\n        newRate: BigInt #*FIXME:*\n        rateAuthority: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: ApproveConfidentialTransferAccount instruction\n    \"\"\"\n    type SplTokenApproveConfidentialTransferAccount implements TransactionInstruction {\n        programId: Address\n        account: Account\n        confidentialTransferAuditorAuthority: Account\n        mint: Account\n    }\n\n    \"\"\"\n    SplToken-2022: EmptyConfidentialTransferAccount instruction\n    \"\"\"\n    type SplTokenEmptyConfidentialTransferAccount implements TransactionInstruction {\n        programId: Address\n        account: Account\n        instructionsSysvar: Account\n        multisigOwner: Account\n        owner: Account\n        proofInstructionOffset: BigInt #*FIXME:*\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: ConfigureConfidentialTransferAccount instruction\n    \"\"\"\n    type SplTokenConfigureConfidentialTransferAccount implements TransactionInstruction {\n        programId: Address\n        account: Account\n        decryptableZeroBalance: String\n        maximumPendingBalanceCreditCounter: BigInt\n        mint: Account\n        multisigOwner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: ApplyPendingConfidentialTransferBalance instruction\n    \"\"\"\n    type SplTokenApplyPendingConfidentialTransferBalance implements TransactionInstruction {\n        programId: Address\n        account: Account\n        expectedPendingBalanceCreditCounter: BigInt\n        multisigOwner: Account\n        newDecryptableAvailableBalance: String\n        owner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: EnableConfidentialTransferConfidentialCredits instruction\n    \"\"\"\n    type SplTokenEnableConfidentialTransferConfidentialCredits implements TransactionInstruction {\n        programId: Address\n        account: Account\n        multisigOwner: Account\n        owner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: DisableConfidentialTransferConfidentialCredits instruction\n    \"\"\"\n    type SplTokenDisableConfidentialTransferConfidentialCredits implements TransactionInstruction {\n        programId: Address\n        account: Account\n        multisigOwner: Account\n        owner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: EnableConfidentialTransferNonConfidentialCredits instruction\n    \"\"\"\n    type SplTokenEnableConfidentialTransferNonConfidentialCredits implements TransactionInstruction {\n        programId: Address\n        account: Account\n        multisigOwner: Account\n        owner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: DisableConfidentialTransferNonConfidentialCredits instruction\n    \"\"\"\n    type SplTokenDisableConfidentialTransferNonConfidentialCredits implements TransactionInstruction {\n        programId: Address\n        account: Account\n        multisigOwner: Account\n        owner: Account\n        signers: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: DepositConfidentialTransfer instruction\n    \"\"\"\n    type SplTokenDepositConfidentialTransfer implements TransactionInstruction {\n        programId: Address\n        amount: BigInt\n        decimals: BigInt # FIXME:*\n        destination: Account\n        mint: Account\n        multisigOwner: Account\n        owner: Account\n        signers: [Address]\n        source: Account\n    }\n\n    \"\"\"\n    SplToken-2022: WithdrawConfidentialTransfer instruction\n    \"\"\"\n    type SplTokenWithdrawConfidentialTransfer implements TransactionInstruction {\n        programId: Address\n        amount: BigInt\n        decimals: BigInt # FIXME:*\n        destination: Account\n        instructionsSysvar: Account\n        newDecryptableAvailableBalance: String\n        mint: Account\n        multisigOwner: Account\n        owner: Account\n        proofInstructionOffset: BigInt #*FIXME:*\n        signers: [Address]\n        source: Account\n    }\n\n    \"\"\"\n    SplToken-2022: ConfidentialTransfer instruction\n    \"\"\"\n    type SplTokenConfidentialTransfer implements TransactionInstruction {\n        programId: Address\n        destination: Account\n        instructionsSysvar: Account\n        mint: Account\n        multisigOwner: Account\n        newSourceDecryptableAvailableBalance: String\n        owner: Account\n        proofInstructionOffset: BigInt #*FIXME:*\n        signers: [Address]\n        source: Account\n    }\n\n    \"\"\"\n    SplToken-2022: ConfidentialTransferWithSplitProofs instruction\n    \"\"\"\n    type SplTokenConfidentialTransferWithSplitProofs implements TransactionInstruction {\n        programId: Address\n        batchedGroupedCiphertext2HandlesValidityContext: Account\n        batchedRangeProofContext: Account\n        ciphertextCommitmentEqualityContext: Account\n        closeSplitContextStateOnExecution: Boolean\n        contextStateOwner: Account\n        destination: Account\n        lamportDestination: Account\n        mint: Account\n        newSourceDecryptableAvailableBalance: String\n        noOpOnUninitializedSplitContextState: Boolean\n        owner: Account\n        source: Account\n    }\n\n    \"\"\"\n    SplToken-2022: UpdateConfidentialTransferMint instruction\n    \"\"\"\n    type SplTokenUpdateConfidentialTransferMint implements TransactionInstruction {\n        programId: Address\n        auditorElgamalPubkey: Address\n        authority: Account\n        autoApproveNewAccounts: Boolean\n        confidentialTransferMintAuthority: Account\n        mint: Account\n        newConfidentialTransferMintAuthority: Account\n    }\n\n    \"\"\"\n    SplToken-2022: WithdrawWithheldConfidentialTransferTokensFromMint instruction\n    \"\"\"\n    type SplTokenWithdrawWithheldConfidentialTransferTokensFromMint implements TransactionInstruction {\n        programId: Address\n        feeRecipient: Account\n        instructionsSysvar: Account\n        mint: Account\n        multisigWithdrawWithheldAuthority: Account\n        proofInstructionOffset: BigInt #*FIXME:*\n        signers: [Address]\n        withdrawWithheldAuthority: Account\n    }\n\n    \"\"\"\n    SplToken-2022: WithdrawWithheldConfidentialTransferTokensFromAccounts instruction\n    \"\"\"\n    type SplTokenWithdrawWithheldConfidentialTransferTokensFromAccounts implements TransactionInstruction {\n        programId: Address\n        feeRecipient: Account\n        instructionsSysvar: Account\n        mint: Account\n        multisigWithdrawWithheldAuthority: Account\n        proofInstructionOffset: BigInt #*FIXME:*\n        signers: [Address]\n        sourceAccounts: [Address]\n        withdrawWithheldAuthority: Account\n    }\n\n    \"\"\"\n    SplToken-2022: HarvestWithheldConfidentialTransferTokensToMint instruction\n    \"\"\"\n    type SplTokenHarvestWithheldConfidentialTransferTokensToMint implements TransactionInstruction {\n        programId: Address\n        mint: Account\n        sourceAccounts: [Address]\n    }\n\n    \"\"\"\n    SplToken-2022: EnableConfidentialTransferFeeHarvestToMint instruction\n    \"\"\"\n    type SplTokenEnableConfidentialTransferFeeHarvestToMint implements TransactionInstruction {\n        programId: Address\n        account: Account\n        owner: Account\n        multisigOwner: Account\n        signers: Address\n    }\n\n    \"\"\"\n    SplToken-2022: DisableConfidentialTransferFeeHarvestToMint instruction\n    \"\"\"\n    type SplTokenDisableConfidentialTransferFeeHarvestToMint implements TransactionInstruction {\n        programId: Address\n        account: Account\n        multisigOwner: Account\n        owner: Account\n        signers: Address\n    }\n\n    \"\"\"\n    SplToken-2022: InitializeConfidentialTransferFeeConfig instruction\n    \"\"\"\n    type SplTokenInitializeConfidentialTransferFeeConfig implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        harvestToMintEnabled: Boolean\n        mint: Account\n        withdrawWithheldAuthorityElgamalPubkey: Address\n        withheldAmount: String\n    }\n\n    \"\"\"\n    SplToken-2022: Reallocate instruction\n    \"\"\"\n    type SplTokenReallocate implements TransactionInstruction {\n        programId: Address\n        account: Account\n        extensionTypes: [SplTokenExtensionType]\n        owner: Account\n        multisigOwner: Account\n        payer: Account\n        signers: [Address]\n        systemProgram: Account\n    }\n\n    \"\"\"\n    Spl Token Group: InitializeGroup instruction\n    \"\"\"\n    type SplTokenGroupInitializeGroup implements TransactionInstruction {\n        programId: Address\n        group: Account\n        maxSize: BigInt\n        mint: Account\n        mintAuthority: Account\n        updateAuthority: Account\n    }\n\n    \"\"\"\n    Spl Token Group: UpdateGroupMaxSize instruction\n    \"\"\"\n    type SplTokenGroupUpdateGroupMaxSize implements TransactionInstruction {\n        programId: Address\n        group: Account\n        maxSize: BigInt\n        updateAuthority: Account\n    }\n\n    \"\"\"\n    Spl Token Group: UpdateGroupAuthority instruction\n    \"\"\"\n    type SplTokenGroupUpdateGroupAuthority implements TransactionInstruction {\n        programId: Address\n        group: Account\n        newAuthority: Account\n        updateAuthority: Account\n    }\n\n    \"\"\"\n    Spl Token Group: InitializeMember instruction\n    \"\"\"\n    type SplTokenGroupInitializeMember implements TransactionInstruction {\n        programId: Address\n        group: Account\n        groupUpdateAuthority: Account\n        member: Account\n        memberMint: Account\n        memberMintAuthority: Account\n    }\n\n    \"\"\"\n    Spl Token Metadata: InitializeMetadata instruction\n    \"\"\"\n    type SplTokenMetadataInitialize implements TransactionInstruction {\n        programId: Address\n        metadata: Account\n        mint: Account\n        mintAuthority: Account\n        name: String\n        symbol: String\n        updateAuthority: Account\n        uri: String\n    }\n\n    \"\"\"\n    Spl Token Metadata: UpdateField instruction\n    \"\"\"\n    type SplTokenMetadataUpdateField implements TransactionInstruction {\n        programId: Address\n        field: String\n        metadata: Account\n        updateAuthority: Account\n        value: String\n    }\n\n    \"\"\"\n    Spl Token Metadata: RemoveKey instruction\n    \"\"\"\n    type SplTokenMetadataRemoveKey implements TransactionInstruction {\n        programId: Address\n        idempotent: Boolean\n        key: String\n        metadata: Account\n        updateAuthority: Account\n    }\n\n    \"\"\"\n    Spl Token Metadata: UpdateAuthority instruction\n    \"\"\"\n    type SplTokenMetadataUpdateAuthority implements TransactionInstruction {\n        programId: Address\n        metadata: Account\n        newAuthority: Account\n        updateAuthority: Account\n    }\n\n    \"\"\"\n    Spl Token Metadata: Emit instruction\n    \"\"\"\n    type SplTokenMetadataEmit implements TransactionInstruction {\n        programId: Address\n        metadata: Account\n        end: BigInt\n        start: BigInt\n    }\n\n    type Lockup {\n        custodian: Account\n        epoch: Epoch\n        unixTimestamp: BigInt\n    }\n\n    \"\"\"\n    Stake: Initialize instruction\n    \"\"\"\n    type StakeInitializeInstructionDataAuthorized {\n        staker: Account\n        withdrawer: Account\n    }\n    type StakeInitializeInstruction implements TransactionInstruction {\n        programId: Address\n        authorized: StakeInitializeInstructionDataAuthorized\n        lockup: Lockup\n        rentSysvar: Account\n        stakeAccount: Account\n    }\n\n    \"\"\"\n    Stake: Authorize instruction\n    \"\"\"\n    type StakeAuthorizeInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        authorityType: String\n        clockSysvar: Account\n        custodian: Account\n        newAuthority: Account\n        stakeAccount: Account\n    }\n\n    \"\"\"\n    Stake: DelegateStake instruction\n    \"\"\"\n    type StakeDelegateStakeInstruction implements TransactionInstruction {\n        programId: Address\n        clockSysvar: Account\n        stakeAccount: Account\n        stakeAuthority: Account\n        stakeConfigAccount: Account\n        stakeHistorySysvar: Account\n        voteAccount: Account\n    }\n\n    \"\"\"\n    Stake: Split instruction\n    \"\"\"\n    type StakeSplitInstruction implements TransactionInstruction {\n        programId: Address\n        lamports: Lamports\n        newSplitAccount: Account\n        stakeAccount: Account\n        stakeAuthority: Account\n    }\n\n    \"\"\"\n    Stake: Withdraw instruction\n    \"\"\"\n    type StakeWithdrawInstruction implements TransactionInstruction {\n        programId: Address\n        clockSysvar: Account\n        destination: Account\n        lamports: Lamports\n        stakeAccount: Account\n        withdrawAuthority: Account\n    }\n\n    \"\"\"\n    Stake: Deactivate instruction\n    \"\"\"\n    type StakeDeactivateInstruction implements TransactionInstruction {\n        programId: Address\n        clockSysvar: Account\n        stakeAccount: Account\n        stakeAuthority: Account\n    }\n\n    \"\"\"\n    Stake: SetLockup instruction\n    \"\"\"\n    type StakeSetLockupInstruction implements TransactionInstruction {\n        programId: Address\n        custodian: Account\n        lockup: Lockup\n        stakeAccount: Account\n    }\n\n    \"\"\"\n    Stake: Merge instruction\n    \"\"\"\n    type StakeMergeInstruction implements TransactionInstruction {\n        programId: Address\n        clockSysvar: Account\n        destination: Account\n        source: Account\n        stakeAuthority: Account\n        stakeHistorySysvar: Account\n    }\n\n    \"\"\"\n    Stake: AuthorizeWithSeed instruction\n    \"\"\"\n    type StakeAuthorizeWithSeedInstruction implements TransactionInstruction {\n        programId: Address\n        authorityBase: Account\n        authorityOwner: Account\n        authoritySeed: String\n        authorityType: String\n        clockSysvar: Account\n        custodian: Account\n        newAuthorized: Account\n        stakeAccount: Account\n    }\n\n    \"\"\"\n    Stake: InitializeChecked instruction\n    \"\"\"\n    type StakeInitializeCheckedInstructionDataAuthorized {\n        staker: Account\n        withdrawer: Account\n    }\n    type StakeInitializeCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        authorized: StakeInitializeCheckedInstructionDataAuthorized\n        lockup: Lockup\n        rentSysvar: Account\n        stakeAccount: Account\n    }\n\n    \"\"\"\n    Stake: AuthorizeChecked instruction\n    \"\"\"\n    type StakeAuthorizeCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        authorityType: String\n        clockSysvar: Account\n        custodian: Account\n        newAuthority: Account\n        stakeAccount: Account\n    }\n\n    \"\"\"\n    Stake: AuthorizeCheckedWithSeed instruction\n    \"\"\"\n    type StakeAuthorizeCheckedWithSeedInstruction implements TransactionInstruction {\n        programId: Address\n        authorityBase: Account\n        authorityOwner: Account\n        authoritySeed: String\n        authorityType: String\n        clockSysvar: Account\n        custodian: Account\n        newAuthorized: Account\n        stakeAccount: Account\n    }\n\n    \"\"\"\n    Stake: SetLockupChecked instruction\n    \"\"\"\n    type StakeSetLockupCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        custodian: Account\n        lockup: Lockup\n        stakeAccount: Account\n    }\n\n    \"\"\"\n    Stake: DeactivateDelinquent instruction\n    \"\"\"\n    type StakeDeactivateDelinquentInstruction implements TransactionInstruction {\n        programId: Address\n        referenceVoteAccount: Account\n        stakeAccount: Account\n        voteAccount: Account\n    }\n\n    \"\"\"\n    Stake: Redelegate instruction\n    \"\"\"\n    type StakeRedelegateInstruction implements TransactionInstruction {\n        programId: Address\n        newStakeAccount: Account\n        stakeAccount: Account\n        stakeAuthority: Account\n        stakeConfigAccount: Account\n        voteAccount: Account\n    }\n\n    \"\"\"\n    System: CreateAccount instruction\n    \"\"\"\n    type CreateAccountInstruction implements TransactionInstruction {\n        programId: Address\n        lamports: Lamports\n        newAccount: Account\n        owner: Account\n        source: Account\n        space: BigInt\n    }\n\n    \"\"\"\n    System: Assign instruction\n    \"\"\"\n    type AssignInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        owner: Account\n    }\n\n    \"\"\"\n    System: Transfer instruction\n    \"\"\"\n    type TransferInstruction implements TransactionInstruction {\n        programId: Address\n        destination: Account\n        lamports: Lamports\n        source: Account\n    }\n\n    \"\"\"\n    System: CreateAccountWithSeed instruction\n    \"\"\"\n    type CreateAccountWithSeedInstruction implements TransactionInstruction {\n        programId: Address\n        base: Account\n        lamports: Lamports\n        owner: Account\n        seed: String\n        space: BigInt\n    }\n\n    \"\"\"\n    System: AdvanceNonceAccount instruction\n    \"\"\"\n    type AdvanceNonceAccountInstruction implements TransactionInstruction {\n        programId: Address\n        nonceAccount: Account\n        nonceAuthority: Account\n        recentBlockhashesSysvar: Account\n    }\n\n    \"\"\"\n    System: WithdrawNonceAccount instruction\n    \"\"\"\n    type WithdrawNonceAccountInstruction implements TransactionInstruction {\n        programId: Address\n        destination: Account\n        lamports: Lamports\n        nonceAccount: Account\n        nonceAuthority: Account\n        recentBlockhashesSysvar: Account\n        rentSysvar: Account\n    }\n\n    \"\"\"\n    System: InitializeNonceAccount instruction\n    \"\"\"\n    type InitializeNonceAccountInstruction implements TransactionInstruction {\n        programId: Address\n        nonceAccount: Account\n        nonceAuthority: Account\n        recentBlockhashesSysvar: Account\n        rentSysvar: Account\n    }\n\n    \"\"\"\n    System: AuthorizeNonceAccount instruction\n    \"\"\"\n    type AuthorizeNonceAccountInstruction implements TransactionInstruction {\n        programId: Address\n        newAuthorized: Account\n        nonceAccount: Account\n        nonceAuthority: Account\n    }\n\n    \"\"\"\n    System: UpgradeNonceAccount instruction\n    \"\"\"\n    type UpgradeNonceAccountInstruction implements TransactionInstruction {\n        programId: Address\n        nonceAccount: Account\n        nonceAuthority: Account\n    }\n\n    \"\"\"\n    System: Allocate instruction\n    \"\"\"\n    type AllocateInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        space: BigInt\n    }\n\n    \"\"\"\n    System: AllocateWithSeed instruction\n    \"\"\"\n    type AllocateWithSeedInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        base: Address\n        owner: Account\n        seed: String\n        space: BigInt\n    }\n\n    \"\"\"\n    System: AssignWithSeed instruction\n    \"\"\"\n    type AssignWithSeedInstruction implements TransactionInstruction {\n        programId: Address\n        account: Account\n        base: Address\n        owner: Account\n        seed: String\n    }\n\n    \"\"\"\n    System: TransferWithSeed instruction\n    \"\"\"\n    type TransferWithSeedInstruction implements TransactionInstruction {\n        programId: Address\n        destination: Account\n        lamports: Lamports\n        source: Account\n        sourceBase: Address\n        sourceOwner: Account\n        sourceSeed: String\n    }\n\n    \"\"\"\n    Vote: InitializeAccount instruction\n    \"\"\"\n    type VoteInitializeAccountInstruction implements TransactionInstruction {\n        programId: Address\n        authorizedVoter: Account\n        authorizedWithdrawer: Account\n        clockSysvar: Account\n        commission: BigInt # FIXME:*\n        node: Account\n        rentSysvar: Account\n        voteAccount: Account\n    }\n\n    \"\"\"\n    Vote: Authorize instruction\n    \"\"\"\n    type VoteAuthorizeInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        authorityType: String\n        clockSysvar: Account\n        newAuthority: Account\n        voteAccount: Account\n    }\n\n    \"\"\"\n    Vote: AuthorizeWithSeed instruction\n    \"\"\"\n    type VoteAuthorizeWithSeedInstruction implements TransactionInstruction {\n        programId: Address\n        authorityBaseKey: String\n        authorityOwner: Account\n        authoritySeed: String\n        authorityType: String\n        clockSysvar: Account\n        newAuthority: Account\n        voteAccount: Account\n    }\n\n    \"\"\"\n    Vote: AuthorizeCheckedWithSeed instruction\n    \"\"\"\n    type VoteAuthorizeCheckedWithSeedInstruction implements TransactionInstruction {\n        programId: Address\n        authorityBaseKey: String\n        authorityOwner: Account\n        authoritySeed: String\n        authorityType: String\n        clockSysvar: Account\n        newAuthority: Account\n        voteAccount: Account\n    }\n\n    type Vote {\n        hash: Hash\n        slots: [Slot]\n        timestamp: BigInt\n    }\n\n    \"\"\"\n    Vote: Vote instruction\n    \"\"\"\n    type VoteVoteInstruction implements TransactionInstruction {\n        programId: Address\n        clockSysvar: Account\n        slotHashesSysvar: Account\n        vote: Vote\n        voteAccount: Account\n        voteAuthority: Account\n    }\n\n    type VoteStateUpdateLockout {\n        confirmationCount: BigInt # FIXME:*\n        slot: Slot\n    }\n    type VoteStateUpdate {\n        hash: Hash\n        lockouts: [VoteStateUpdateLockout]\n        root: Slot\n        timestamp: BigInt\n    }\n\n    \"\"\"\n    Vote: UpdateVoteState instruction\n    \"\"\"\n    type VoteUpdateVoteStateInstruction implements TransactionInstruction {\n        programId: Address\n        hash: Hash\n        voteAccount: Account\n        voteAuthority: Account\n        voteStateUpdate: VoteStateUpdate\n    }\n\n    \"\"\"\n    Vote: UpdateVoteStateSwitch instruction\n    \"\"\"\n    type VoteUpdateVoteStateSwitchInstruction implements TransactionInstruction {\n        programId: Address\n        hash: Hash\n        voteAccount: Account\n        voteAuthority: Account\n        voteStateUpdate: VoteStateUpdate\n    }\n\n    \"\"\"\n    Vote: CompactUpdateVoteState instruction\n    \"\"\"\n    type VoteCompactUpdateVoteStateInstruction implements TransactionInstruction {\n        programId: Address\n        hash: Hash\n        voteAccount: Account\n        voteAuthority: Account\n        voteStateUpdate: VoteStateUpdate\n    }\n\n    \"\"\"\n    Vote: CompactUpdateVoteStateSwitch instruction\n    \"\"\"\n    type VoteCompactUpdateVoteStateSwitchInstruction implements TransactionInstruction {\n        programId: Address\n        hash: Hash\n        voteAccount: Account\n        voteAuthority: Account\n        voteStateUpdate: VoteStateUpdate\n    }\n\n    \"\"\"\n    Vote: Withdraw instruction\n    \"\"\"\n    type VoteWithdrawInstruction implements TransactionInstruction {\n        programId: Address\n        destination: Account\n        lamports: Lamports\n        voteAccount: Account\n        withdrawAuthority: Account\n    }\n\n    \"\"\"\n    Vote: UpdateValidatorIdentity instruction\n    \"\"\"\n    type VoteUpdateValidatorIdentityInstruction implements TransactionInstruction {\n        programId: Address\n        newValidatorIdentity: Account\n        voteAccount: Account\n        withdrawAuthority: Account\n    }\n\n    \"\"\"\n    Vote: UpdateCommission instruction\n    \"\"\"\n    type VoteUpdateCommissionInstruction implements TransactionInstruction {\n        programId: Address\n        commission: BigInt # FIXME:*\n        voteAccount: Account\n        withdrawAuthority: Account\n    }\n\n    \"\"\"\n    Vote: VoteSwitch instruction\n    \"\"\"\n    type VoteVoteSwitchInstruction implements TransactionInstruction {\n        programId: Address\n        clockSysvar: Account\n        hash: Hash\n        slotHashesSysvar: Account\n        vote: Vote\n        voteAccount: Account\n        voteAuthority: Account\n    }\n\n    \"\"\"\n    Vote: AuthorizeChecked instruction\n    \"\"\"\n    type VoteAuthorizeCheckedInstruction implements TransactionInstruction {\n        programId: Address\n        authority: Account\n        authorityType: String\n        clockSysvar: Account\n        newAuthority: Account\n        voteAccount: Account\n    }\n`;\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-defs/root.ts",
    "content": "export const rootTypeDefs = /* GraphQL */ `\n    type Query {\n        account(address: Address!, commitment: Commitment, minContextSlot: Slot): Account\n        block(slot: Slot!, commitment: CommitmentWithoutProcessed): Block\n        programAccounts(\n            programAddress: Address!\n            commitment: Commitment\n            dataSizeFilters: [ProgramAccountsDataSizeFilter]\n            memcmpFilters: [ProgramAccountsMemcmpFilter]\n            minContextSlot: Slot\n        ): [Account]\n        transaction(signature: Signature!, commitment: CommitmentWithoutProcessed): Transaction\n    }\n\n    schema {\n        query: Query\n    }\n`;\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-defs/transaction.ts",
    "content": "export const transactionTypeDefs = /* GraphQL */ `\n    type TransactionStatusOk {\n        Ok: String\n    }\n    type TransactionStatusErr {\n        Err: String\n    }\n    union TransactionStatus = TransactionStatusOk | TransactionStatusErr\n\n    type TransactionLoadedAddresses {\n        readonly: [Address]\n        writable: [Address]\n    }\n\n    type TransactionInnerInstruction {\n        index: Int\n        instructions: [TransactionInstruction]\n    }\n\n    type TransactionMeta {\n        computeUnitsConsumed: BigInt\n        err: String\n        fee: Lamports\n        innerInstructions: [TransactionInnerInstruction]\n        loadedAddresses: TransactionLoadedAddresses\n        logMessages: [String]\n        postBalances: [Lamports]\n        postTokenBalances: [TokenBalance]\n        preBalances: [Lamports]\n        preTokenBalances: [TokenBalance]\n        returnData: ReturnData\n        rewards: [Reward]\n        status: TransactionStatus\n    }\n\n    type TransactionMessageAccountKey {\n        pubkey: Address\n        signer: Boolean\n        source: String\n        writable: Boolean\n    }\n\n    type TransactionMessageAddressTableLookup {\n        accountKey: Address\n        readonlyIndexes: [Int]\n        writableIndexes: [Int]\n    }\n\n    type TransactionMessageHeader {\n        numReadonlySignedAccounts: Int\n        numReadonlyUnsignedAccounts: Int\n        numRequiredSignatures: Int\n    }\n\n    type TransactionMessage {\n        accountKeys: [TransactionMessageAccountKey]\n        addressTableLookups: [TransactionMessageAddressTableLookup]\n        header: TransactionMessageHeader\n        instructions: [TransactionInstruction]\n        recentBlockhash: Hash\n    }\n\n    \"\"\"\n    A Solana transaction\n    \"\"\"\n    type Transaction {\n        blockTime: BigInt\n        data(encoding: TransactionEncoding!): String\n        message: TransactionMessage\n        meta: TransactionMeta\n        signatures: [Signature]\n        slot: Slot\n        version: String\n    }\n`;\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-defs/types.ts",
    "content": "export const typeTypeDefs = /* GraphQL */ `\n    enum AccountEncoding {\n        BASE_58\n        BASE_64\n        BASE_64_ZSTD\n    }\n\n    scalar Address\n\n    scalar Base58EncodedBytes\n\n    scalar Base64EncodedBytes\n\n    scalar Base64ZstdEncodedBytes\n\n    scalar BigInt\n\n    enum Commitment {\n        CONFIRMED\n        FINALIZED\n        PROCESSED\n    }\n\n    enum CommitmentWithoutProcessed {\n        CONFIRMED\n        FINALIZED\n    }\n\n    input DataSlice {\n        offset: Int!\n        length: Int!\n    }\n\n    scalar Epoch\n\n    scalar Hash\n\n    scalar Lamports\n\n    input ProgramAccountsDataSizeFilter {\n        dataSize: BigInt!\n    }\n\n    enum ProgramAccountsMemcmpFilterAccountEncoding {\n        BASE_58\n        BASE_64\n    }\n\n    input ProgramAccountsMemcmpFilter {\n        bytes: String!\n        encoding: ProgramAccountsMemcmpFilterAccountEncoding!\n        offset: BigInt!\n    }\n\n    type ReturnData {\n        data: Base64EncodedBytes\n        programId: Address\n    }\n\n    type Reward {\n        commission: Int\n        lamports: Lamports\n        postBalance: BigInt\n        pubkey: Address\n        rewardType: String\n    }\n\n    scalar Signature\n\n    scalar Slot\n\n    enum SplTokenDefaultAccountState {\n        FROZEN\n        INITIALIZED\n        UNINITIALIZED\n    }\n\n    enum SplTokenExtensionType {\n        UNINITIALIZED\n        TRANSFER_FEE_CONFIG\n        TRANSFER_FEE_AMOUNT\n        MINT_CLOSE_AUTHORITY\n        CONFIDENTIAL_TRANSFER_MINT\n        CONFIDENTIAL_TRANSFER_ACCOUNT\n        DEFAULT_ACCOUNT_STATE\n        IMMUTABLE_OWNER\n        MEMO_TRANSFER\n        NON_TRANSFERABLE\n        INTEREST_BEARING_CONFIG\n        CPI_GUARD\n        PERMANENT_DELEGATE\n        NON_TRANSFERABLE_ACCOUNT\n        CONFIDENTIAL_TRANSFER_FEE_CONFIG\n        CONFIDENTIAL_TRANSFER_FEE_AMOUNT\n        TRANSFER_HOOK\n        TRANSFER_HOOK_ACCOUNT\n        METADATA_POINTER\n        TOKEN_METADATA\n        GROUP_POINTER\n        GROUP_MEMBER_POINTER\n        TOKEN_GROUP\n        TOKEN_GROUP_MEMBER\n        UNPARSEABLE_EXTENSION\n    }\n\n    type TokenAmount {\n        amount: BigInt\n        decimals: Int\n        uiAmount: BigInt\n        uiAmountString: String\n    }\n\n    type TokenBalance {\n        accountIndex: Int\n        mint: Account\n        owner: Account\n        programId: Address\n        uiTokenAmount: TokenAmount\n    }\n\n    enum TransactionEncoding {\n        BASE_58\n        BASE_64\n    }\n`;\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-resolvers/account.ts",
    "content": "import { AccountResult, resolveAccount, resolveAccountData } from '../../resolvers/account';\n\ntype Token2022ExtensionResult = {\n    extension: string;\n    state: object;\n};\n\nconst resolveTokenExtensions = () => {\n    return (parent: (AccountResult & { extensions?: Token2022ExtensionResult[] }) | null) => {\n        if (parent != null && parent.extensions != undefined) {\n            return parent.extensions.map(e => {\n                const { extension, state } = e;\n                return {\n                    extension,\n                    ...state,\n                };\n            });\n        }\n        return null;\n    };\n};\n\nconst resolveAdditionalTokenMetadata = () => {\n    return (parent: { additionalMetadata?: [string, string][] }) => {\n        if (parent.additionalMetadata != undefined) {\n            return parent.additionalMetadata.map(([key, value]) => {\n                return {\n                    key,\n                    value,\n                };\n            });\n        }\n        return null;\n    };\n};\n\nfunction resolveTokenExtensionType(extensionResult: Token2022ExtensionResult) {\n    if (extensionResult.extension === 'confidentialTransferFeeConfig') {\n        return 'SplTokenExtensionConfidentialTransferFeeConfig';\n    }\n    if (extensionResult.extension === 'confidentialTransferMint') {\n        return 'SplTokenExtensionConfidentialTransferMint';\n    }\n    if (extensionResult.extension === 'defaultAccountState') {\n        return 'SplTokenExtensionDefaultAccountState';\n    }\n    if (extensionResult.extension === 'groupPointer') {\n        return 'SplTokenExtensionGroupPointer';\n    }\n    if (extensionResult.extension === 'groupMemberPointer') {\n        return 'SplTokenExtensionGroupMemberPointer';\n    }\n    if (extensionResult.extension === 'interestBearingConfig') {\n        return 'SplTokenExtensionInterestBearingConfig';\n    }\n    if (extensionResult.extension === 'metadataPointer') {\n        return 'SplTokenExtensionMetadataPointer';\n    }\n    if (extensionResult.extension === 'mintCloseAuthority') {\n        return 'SplTokenExtensionMintCloseAuthority';\n    }\n    if (extensionResult.extension === 'nonTransferable') {\n        return 'SplTokenExtensionNonTransferable';\n    }\n    if (extensionResult.extension === 'permanentDelegate') {\n        return 'SplTokenExtensionPermanentDelegate';\n    }\n    if (extensionResult.extension === 'tokenGroup') {\n        return 'SplTokenExtensionTokenGroup';\n    }\n    if (extensionResult.extension === 'tokenGroupMember') {\n        return 'SplTokenExtensionTokenGroupMember';\n    }\n    if (extensionResult.extension === 'tokenMetadata') {\n        return 'SplTokenExtensionTokenMetadata';\n    }\n    if (extensionResult.extension === 'transferFeeConfig') {\n        return 'SplTokenExtensionTransferFeeConfig';\n    }\n    if (extensionResult.extension === 'transferHook') {\n        return 'SplTokenExtensionTransferHook';\n    }\n    if (extensionResult.extension === 'confidentialTransferAccount') {\n        return 'SplTokenExtensionConfidentialTransferAccount';\n    }\n    if (extensionResult.extension === 'transferFeeAmount') {\n        return 'SplTokenExtensionTransferFeeAmount';\n    }\n    if (extensionResult.extension === 'transferHookAccount') {\n        return 'SplTokenExtensionTransferHookAccount';\n    }\n    if (extensionResult.extension === 'confidentialTransferFeeAmount') {\n        return 'SplTokenExtensionConfidentialTransferFeeAmount';\n    }\n    if (extensionResult.extension === 'nonTransferableAccount') {\n        return 'SplTokenExtensionNonTransferableAccount';\n    }\n    if (extensionResult.extension === 'immutableOwner') {\n        return 'SplTokenExtensionImmutableOwner';\n    }\n    if (extensionResult.extension === 'memoTransfer') {\n        return 'SplTokenExtensionMemoTransfer';\n    }\n    if (extensionResult.extension === 'cpiGuard') {\n        return 'SplTokenExtensionCpiGuard';\n    }\n    if (extensionResult.extension === 'unparseableExtension') {\n        return 'SplTokenExtensionUnparseable';\n    }\n}\n\nexport const accountTypeResolvers = {\n    Account: {\n        __resolveType: (accountResult: AccountResult) => {\n            const { jsonParsedConfigs } = accountResult;\n            if (jsonParsedConfigs) {\n                if (jsonParsedConfigs.programName === 'nonce') {\n                    return 'NonceAccount';\n                }\n                if (\n                    jsonParsedConfigs.programName === 'spl-token' ||\n                    jsonParsedConfigs.programName === 'spl-token-2022'\n                ) {\n                    if (jsonParsedConfigs.accountType === 'mint') {\n                        return 'MintAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'account') {\n                        return 'TokenAccount';\n                    }\n                }\n                if (jsonParsedConfigs.programName === 'stake') {\n                    return 'StakeAccount';\n                }\n                if (jsonParsedConfigs.accountType === 'vote' && jsonParsedConfigs.programName === 'vote') {\n                    return 'VoteAccount';\n                }\n                if (\n                    jsonParsedConfigs.accountType === 'lookupTable' &&\n                    jsonParsedConfigs.programName === 'address-lookup-table'\n                ) {\n                    return 'LookupTableAccount';\n                }\n                if (jsonParsedConfigs.programName === 'sysvar') {\n                    if (jsonParsedConfigs.accountType === 'clock') {\n                        return 'SysvarClockAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'epochRewards') {\n                        return 'SysvarEpochRewardsAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'epochSchedule') {\n                        return 'SysvarEpochScheduleAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'lastRestartSlot') {\n                        return 'SysvarLastRestartSlotAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'recentBlockhashes') {\n                        return 'SysvarRecentBlockhashesAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'rent') {\n                        return 'SysvarRentAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'slotHashes') {\n                        return 'SysvarSlotHashesAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'slotHistory') {\n                        return 'SysvarSlotHistoryAccount';\n                    }\n                    if (jsonParsedConfigs.accountType === 'stakeHistory') {\n                        return 'SysvarStakeHistoryAccount';\n                    }\n                }\n            }\n            return 'GenericAccount';\n        },\n    },\n    GenericAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    LookupTableAccount: {\n        authority: resolveAccount('authority'),\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    MintAccount: {\n        data: resolveAccountData(),\n        extensions: resolveTokenExtensions(),\n        freezeAuthority: resolveAccount('freezeAuthority'),\n        mintAuthority: resolveAccount('mintAuthority'),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    NonceAccount: {\n        authority: resolveAccount('authority'),\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SplTokenExtension: {\n        __resolveType: resolveTokenExtensionType,\n    },\n    SplTokenExtensionConfidentialTransferFeeConfig: {\n        authority: resolveAccount('authority'),\n    },\n    SplTokenExtensionConfidentialTransferMint: {\n        authority: resolveAccount('authority'),\n    },\n    SplTokenExtensionGroupMemberPointer: {\n        authority: resolveAccount('authority'),\n        memberAddress: resolveAccount('memberAddress'),\n    },\n    SplTokenExtensionGroupPointer: {\n        authority: resolveAccount('authority'),\n        groupAddress: resolveAccount('groupAddress'),\n    },\n    SplTokenExtensionInterestBearingConfig: {\n        rateAuthority: resolveAccount('rateAuthority'),\n    },\n    SplTokenExtensionMetadataPointer: {\n        authority: resolveAccount('authority'),\n        metadataAddress: resolveAccount('metadataAddress'),\n    },\n    SplTokenExtensionMintCloseAuthority: {\n        closeAuthority: resolveAccount('closeAuthority'),\n    },\n    SplTokenExtensionPermanentDelegate: {\n        delegate: resolveAccount('delegate'),\n    },\n    SplTokenExtensionTokenGroup: {\n        mint: resolveAccount('mint'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenExtensionTokenGroupMember: {\n        group: resolveAccount('group'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenExtensionTokenMetadata: {\n        additionalMetadata: resolveAdditionalTokenMetadata(),\n        mint: resolveAccount('mint'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenExtensionTransferFeeConfig: {\n        transferFeeConfigAuthority: resolveAccount('transferFeeConfigAuthority'),\n        withdrawWithheldAuthority: resolveAccount('withdrawWithheldAuthority'),\n    },\n    SplTokenExtensionTransferHook: {\n        authority: resolveAccount('authority'),\n        hookProgramId: resolveAccount('programId'),\n    },\n    StakeAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    StakeAccountDataMetaAuthorized: {\n        staker: resolveAccount('staker'),\n        withdrawer: resolveAccount('withdrawer'),\n    },\n    StakeAccountDataMetaLockup: {\n        custodian: resolveAccount('custodian'),\n    },\n    StakeAccountDataStakeDelegation: {\n        voter: resolveAccount('voter'),\n    },\n    SysvarClockAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SysvarEpochRewardsAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SysvarEpochScheduleAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SysvarLastRestartSlotAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SysvarRecentBlockhashesAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SysvarRentAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SysvarSlotHashesAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SysvarSlotHistoryAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    SysvarStakeHistoryAccount: {\n        data: resolveAccountData(),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    TokenAccount: {\n        data: resolveAccountData(),\n        extensions: resolveTokenExtensions(),\n        mint: resolveAccount('mint'),\n        owner: resolveAccount('owner'),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    VoteAccount: {\n        authorizedWithdrawer: resolveAccount('authorizedWithdrawer'),\n        data: resolveAccountData(),\n        node: resolveAccount('nodePubkey'),\n        ownerProgram: resolveAccount('ownerProgram'),\n    },\n    VoteAccountDataAuthorizedVoter: {\n        authorizedVoter: resolveAccount('authorizedVoter'),\n    },\n};\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-resolvers/block.ts",
    "content": "import { BlockResult } from '../../resolvers/block';\n\nexport const blockTypeResolvers = {\n    Block: {\n        transactions: (parent?: BlockResult) =>\n            parent?.transactionResults ? Object.values(parent.transactionResults) : null,\n    },\n};\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-resolvers/index.ts",
    "content": "import type { makeExecutableSchema } from '@graphql-tools/schema';\n\nimport { accountTypeResolvers } from './account';\nimport { blockTypeResolvers } from './block';\nimport { instructionTypeResolvers } from './instruction';\nimport { rootTypeResolvers } from './root';\nimport { transactionTypeResolvers } from './transaction';\nimport { typeTypeResolvers } from './types';\n\n/**\n * Create the GraphQL type resolvers for the Solana GraphQL schema.\n *\n * @returns     Solana GraphQL type resolvers.\n */\nexport function createSolanaGraphQLTypeResolvers(): Parameters<typeof makeExecutableSchema>[0]['resolvers'] {\n    return {\n        ...accountTypeResolvers,\n        ...blockTypeResolvers,\n        ...instructionTypeResolvers,\n        ...rootTypeResolvers,\n        ...transactionTypeResolvers,\n        ...typeTypeResolvers,\n    };\n}\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-resolvers/instruction.ts",
    "content": "import { resolveAccount } from '../../resolvers/account';\nimport { InstructionResult } from '../../resolvers/transaction';\n\nexport const instructionTypeResolvers = {\n    AdvanceNonceAccountInstruction: {\n        nonceAccount: resolveAccount('nonceAccount'),\n        nonceAuthority: resolveAccount('nonceAuthority'),\n        recentBlockhashesSysvar: resolveAccount('recentBlockhashesSysvar'),\n    },\n    AllocateInstruction: {\n        account: resolveAccount('account'),\n    },\n    AllocateWithSeedInstruction: {\n        account: resolveAccount('account'),\n        owner: resolveAccount('owner'),\n    },\n    AssignInstruction: {\n        account: resolveAccount('account'),\n        owner: resolveAccount('owner'),\n    },\n    AssignWithSeedInstruction: {\n        account: resolveAccount('account'),\n        owner: resolveAccount('owner'),\n    },\n    AuthorizeNonceAccountInstruction: {\n        newAuthorized: resolveAccount('newAuthorized'),\n        nonceAccount: resolveAccount('nonceAccount'),\n        nonceAuthority: resolveAccount('nonceAuthority'),\n    },\n    BpfLoaderFinalizeInstruction: {\n        account: resolveAccount('account'),\n    },\n    BpfLoaderWriteInstruction: {\n        account: resolveAccount('account'),\n    },\n    BpfUpgradeableLoaderCloseInstruction: {\n        account: resolveAccount('account'),\n        authority: resolveAccount('authority'),\n        programAccount: resolveAccount('programAccount'),\n        recipient: resolveAccount('recipient'),\n    },\n    BpfUpgradeableLoaderDeployWithMaxDataLenInstruction: {\n        authority: resolveAccount('authority'),\n        bufferAccount: resolveAccount('bufferAccount'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        payerAccount: resolveAccount('payerAccount'),\n        programAccount: resolveAccount('programAccount'),\n        programDataAccount: resolveAccount('programDataAccount'),\n        rentSysvar: resolveAccount('rentSysvar'),\n    },\n    BpfUpgradeableLoaderExtendProgramInstruction: {\n        payerAccount: resolveAccount('payerAccount'),\n        programAccount: resolveAccount('programAccount'),\n        programDataAccount: resolveAccount('programDataAccount'),\n        systemProgram: resolveAccount('systemProgram'),\n    },\n    BpfUpgradeableLoaderInitializeBufferInstruction: {\n        account: resolveAccount('account'),\n    },\n    BpfUpgradeableLoaderSetAuthorityCheckedInstruction: {\n        account: resolveAccount('account'),\n        authority: resolveAccount('authority'),\n        newAuthority: resolveAccount('newAuthority'),\n    },\n    BpfUpgradeableLoaderSetAuthorityInstruction: {\n        account: resolveAccount('account'),\n        authority: resolveAccount('authority'),\n        newAuthority: resolveAccount('newAuthority'),\n    },\n    BpfUpgradeableLoaderUpgradeInstruction: {\n        authority: resolveAccount('authority'),\n        bufferAccount: resolveAccount('bufferAccount'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        programAccount: resolveAccount('programAccount'),\n        programDataAccount: resolveAccount('programDataAccount'),\n        rentSysvar: resolveAccount('rentSysvar'),\n    },\n    BpfUpgradeableLoaderWriteInstruction: {\n        account: resolveAccount('account'),\n        authority: resolveAccount('authority'),\n    },\n    CloseLookupTableInstruction: {\n        lookupTableAccount: resolveAccount('lookupTableAccount'),\n        lookupTableAuthority: resolveAccount('lookupTableAuthority'),\n        recipient: resolveAccount('recipient'),\n    },\n    CreateAccountInstruction: {\n        newAccount: resolveAccount('newAccount'),\n        owner: resolveAccount('owner'),\n        source: resolveAccount('source'),\n    },\n    CreateAccountWithSeedInstruction: {\n        base: resolveAccount('base'),\n        owner: resolveAccount('owner'),\n        seed: resolveAccount('seed'),\n    },\n    CreateLookupTableInstruction: {\n        lookupTableAccount: resolveAccount('lookupTableAccount'),\n        lookupTableAuthority: resolveAccount('lookupTableAuthority'),\n        payerAccount: resolveAccount('payerAccount'),\n        systemProgram: resolveAccount('systemProgram'),\n    },\n    DeactivateLookupTableInstruction: {\n        lookupTableAccount: resolveAccount('lookupTableAccount'),\n        lookupTableAuthority: resolveAccount('lookupTableAuthority'),\n    },\n    ExtendLookupTableInstruction: {\n        lookupTableAccount: resolveAccount('lookupTableAccount'),\n        lookupTableAuthority: resolveAccount('lookupTableAuthority'),\n        payerAccount: resolveAccount('payerAccount'),\n        systemProgram: resolveAccount('systemProgram'),\n    },\n    FreezeLookupTableInstruction: {\n        lookupTableAccount: resolveAccount('lookupTableAccount'),\n        lookupTableAuthority: resolveAccount('lookupTableAuthority'),\n    },\n    InitializeNonceAccountInstruction: {\n        nonceAccount: resolveAccount('nonceAccount'),\n        nonceAuthority: resolveAccount('nonceAuthority'),\n        recentBlockhashesSysvar: resolveAccount('recentBlockhashesSysvar'),\n        rentSysvar: resolveAccount('rentSysvar'),\n    },\n    Lockup: {\n        custodian: resolveAccount('custodian'),\n    },\n    SplAssociatedTokenCreateIdempotentInstruction: {\n        account: resolveAccount('account'),\n        mint: resolveAccount('mint'),\n        source: resolveAccount('source'),\n        systemProgram: resolveAccount('systemProgram'),\n        tokenProgram: resolveAccount('tokenProgram'),\n        wallet: resolveAccount('wallet'),\n    },\n    SplAssociatedTokenCreateInstruction: {\n        account: resolveAccount('account'),\n        mint: resolveAccount('mint'),\n        source: resolveAccount('source'),\n        systemProgram: resolveAccount('systemProgram'),\n        tokenProgram: resolveAccount('tokenProgram'),\n        wallet: resolveAccount('wallet'),\n    },\n    SplAssociatedTokenRecoverNestedInstruction: {\n        destination: resolveAccount('destination'),\n        nestedMint: resolveAccount('nestedMint'),\n        nestedOwner: resolveAccount('nestedOwner'),\n        nestedSource: resolveAccount('nestedSource'),\n        ownerMint: resolveAccount('ownerMint'),\n        tokenProgram: resolveAccount('tokenProgram'),\n        wallet: resolveAccount('wallet'),\n    },\n    SplTokenAmountToUiAmountInstruction: {\n        mint: resolveAccount('mint'),\n    },\n    SplTokenApplyPendingConfidentialTransferBalance: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenApproveCheckedInstruction: {\n        delegate: resolveAccount('delegate'),\n        mint: resolveAccount('mint'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n        source: resolveAccount('source'),\n    },\n    SplTokenApproveConfidentialTransferAccount: {\n        account: resolveAccount('account'),\n        confidentialTransferAuditorAuthority: resolveAccount('confidentialTransferAuditorAuthority'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenApproveInstruction: {\n        delegate: resolveAccount('delegate'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n        source: resolveAccount('source'),\n    },\n    SplTokenBurnCheckedInstruction: {\n        account: resolveAccount('account'),\n        authority: resolveAccount('authority'),\n        mint: resolveAccount('mint'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n    },\n    SplTokenBurnInstruction: {\n        account: resolveAccount('account'),\n        authority: resolveAccount('authority'),\n        mint: resolveAccount('mint'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n    },\n    SplTokenCloseAccountInstruction: {\n        account: resolveAccount('account'),\n        destination: resolveAccount('destination'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenConfidentialTransfer: {\n        destination: resolveAccount('destination'),\n        instructionsSysvar: resolveAccount('instructionsSysvar'),\n        mint: resolveAccount('mint'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n        source: resolveAccount('source'),\n    },\n    SplTokenConfidentialTransferWithSplitProofs: {\n        batchedGroupedCiphertext2HandlesValidityContext: resolveAccount(\n            'batchedGroupedCiphertext2HandlesValidityContext',\n        ),\n        batchedRangeProofContext: resolveAccount('batchedRangeProofContext'),\n        ciphertextCommitmentEqualityContext: resolveAccount('ciphertextCommitmentEqualityContext'),\n        contextStateOwner: resolveAccount('contextStateOwner'),\n        destination: resolveAccount('destination'),\n        lamportDestination: resolveAccount('lamportDestination'),\n        mint: resolveAccount('mint'),\n        owner: resolveAccount('owner'),\n        source: resolveAccount('source'),\n    },\n    SplTokenConfigureConfidentialTransferAccount: {\n        account: resolveAccount('account'),\n        mint: resolveAccount('mint'),\n        multisigOwner: resolveAccount('multisigOwner'),\n    },\n    SplTokenDepositConfidentialTransfer: {\n        destination: resolveAccount('destination'),\n        mint: resolveAccount('mint'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n        source: resolveAccount('source'),\n    },\n    SplTokenDisableConfidentialTransferConfidentialCredits: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenDisableConfidentialTransferFeeHarvestToMint: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenDisableConfidentialTransferNonConfidentialCredits: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenDisableCpiGuardInstruction: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenDisableRequiredMemoTransfers: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenEmptyConfidentialTransferAccount: {\n        account: resolveAccount('account'),\n        instructionsSysvar: resolveAccount('instructionsSysvar'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenEnableConfidentialTransferConfidentialCredits: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenEnableConfidentialTransferFeeHarvestToMint: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenEnableConfidentialTransferNonConfidentialCredits: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenEnableCpiGuardInstruction: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenEnableRequiredMemoTransfers: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenFreezeAccountInstruction: {\n        account: resolveAccount('account'),\n        freezeAuthority: resolveAccount('freezeAuthority'),\n        mint: resolveAccount('mint'),\n        multisigFreezeAuthority: resolveAccount('multisigFreezeAuthority'),\n    },\n    SplTokenGetAccountDataSizeInstruction: {\n        mint: resolveAccount('mint'),\n    },\n    SplTokenGroupInitializeGroup: {\n        group: resolveAccount('group'),\n        mint: resolveAccount('mint'),\n        mintAuthority: resolveAccount('mintAuthority'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenGroupInitializeMember: {\n        group: resolveAccount('group'),\n        groupUpdateAuthority: resolveAccount('groupUpdateAuthority'),\n        member: resolveAccount('member'),\n        memberMint: resolveAccount('memberMint'),\n        memberMintAuthority: resolveAccount('memberMintAuthority'),\n    },\n    SplTokenGroupUpdateGroupAuthority: {\n        group: resolveAccount('group'),\n        newAuthority: resolveAccount('newAuthority'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenGroupUpdateGroupMaxSize: {\n        group: resolveAccount('group'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenHarvestWithheldConfidentialTransferTokensToMint: {\n        mint: resolveAccount('mint'),\n    },\n    SplTokenHarvestWithheldTokensToMint: {\n        mint: resolveAccount('mint'),\n    },\n    SplTokenInitializeAccount2Instruction: {\n        account: resolveAccount('account'),\n        mint: resolveAccount('mint'),\n        owner: resolveAccount('owner'),\n        rentSysvar: resolveAccount('rentSysvar'),\n    },\n    SplTokenInitializeAccount3Instruction: {\n        account: resolveAccount('account'),\n        mint: resolveAccount('mint'),\n        owner: resolveAccount('owner'),\n    },\n    SplTokenInitializeAccountInstruction: {\n        account: resolveAccount('account'),\n        mint: resolveAccount('mint'),\n        owner: resolveAccount('owner'),\n        rentSysvar: resolveAccount('rentSysvar'),\n    },\n    SplTokenInitializeConfidentialTransferFeeConfig: {\n        authority: resolveAccount('authority'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenInitializeConfidentialTransferMint: {\n        authority: resolveAccount('authority'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenInitializeDefaultAccountStateInstruction: {\n        mint: resolveAccount('mint'),\n    },\n    SplTokenInitializeGroupMemberPointerInstruction: {\n        authority: resolveAccount('authority'),\n        memberAddress: resolveAccount('memberAddress'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenInitializeGroupPointerInstruction: {\n        authority: resolveAccount('authority'),\n        groupAddress: resolveAccount('groupAddress'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenInitializeInterestBearingConfig: {\n        mint: resolveAccount('mint'),\n        rateAuthority: resolveAccount('rateAuthority'),\n    },\n    SplTokenInitializeMetadataPointerInstruction: {\n        authority: resolveAccount('authority'),\n        metadataAddress: resolveAccount('metadataAddress'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenInitializeMint2Instruction: {\n        freezeAuthority: resolveAccount('freezeAuthority'),\n        mint: resolveAccount('mint'),\n        mintAuthority: resolveAccount('mintAuthority'),\n    },\n    SplTokenInitializeMintCloseAuthorityInstruction: {\n        mint: resolveAccount('mint'),\n        newAuthority: resolveAccount('newAuthority'),\n    },\n    SplTokenInitializeMintInstruction: {\n        freezeAuthority: resolveAccount('freezeAuthority'),\n        mint: resolveAccount('mint'),\n        mintAuthority: resolveAccount('mintAuthority'),\n        rentSysvar: resolveAccount('rentSysvar'),\n    },\n    SplTokenInitializeMultisig2Instruction: {\n        multisig: resolveAccount('multisig'),\n    },\n    SplTokenInitializeMultisigInstruction: {\n        multisig: resolveAccount('multisig'),\n        rentSysvar: resolveAccount('rentSysvar'),\n    },\n    SplTokenInitializePermanentDelegateInstruction: {\n        delegate: resolveAccount('delegate'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenInitializeTransferFeeConfig: {\n        mint: resolveAccount('mint'),\n        transferFeeConfigAuthority: resolveAccount('transferFeeConfigAuthority'),\n        withdrawWithheldAuthority: resolveAccount('withdrawWithheldAuthority'),\n    },\n    SplTokenInitializeTransferHookInstruction: {\n        authority: resolveAccount('authority'),\n        hookProgramId: resolveAccount('programId'),\n        mint: resolveAccount('mint'),\n    },\n    SplTokenMetadataEmit: {\n        metadata: resolveAccount('metadata'),\n    },\n    SplTokenMetadataInitialize: {\n        metadata: resolveAccount('metadata'),\n        mint: resolveAccount('mint'),\n        mintAuthority: resolveAccount('mintAuthority'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenMetadataRemoveKey: {\n        metadata: resolveAccount('metadata'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenMetadataUpdateAuthority: {\n        metadata: resolveAccount('metadata'),\n        newAuthority: resolveAccount('newAuthority'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenMetadataUpdateField: {\n        metadata: resolveAccount('metadata'),\n        updateAuthority: resolveAccount('updateAuthority'),\n    },\n    SplTokenMintToCheckedInstruction: {\n        account: resolveAccount('account'),\n        authority: resolveAccount('authority'),\n        mint: resolveAccount('mint'),\n        mintAuthority: resolveAccount('mintAuthority'),\n        multisigMintAuthority: resolveAccount('multisigMintAuthority'),\n    },\n    SplTokenMintToInstruction: {\n        account: resolveAccount('account'),\n        authority: resolveAccount('authority'),\n        mint: resolveAccount('mint'),\n        mintAuthority: resolveAccount('mintAuthority'),\n        multisigMintAuthority: resolveAccount('multisigMintAuthority'),\n    },\n    SplTokenReallocate: {\n        account: resolveAccount('account'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n        payer: resolveAccount('payer'),\n        systemProgram: resolveAccount('systemProgram'),\n    },\n    SplTokenRevokeInstruction: {\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n        source: resolveAccount('source'),\n    },\n    SplTokenSetAuthorityInstruction: {\n        authority: resolveAccount('authority'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n        newAuthority: resolveAccount('newAuthority'),\n    },\n    SplTokenSyncNativeInstruction: {\n        account: resolveAccount('account'),\n    },\n    SplTokenThawAccountInstruction: {\n        account: resolveAccount('account'),\n        freezeAuthority: resolveAccount('freezeAuthority'),\n        mint: resolveAccount('mint'),\n        multisigFreezeAuthority: resolveAccount('multisigFreezeAuthority'),\n    },\n    SplTokenTransferCheckedInstruction: {\n        authority: resolveAccount('authority'),\n        destination: resolveAccount('destination'),\n        mint: resolveAccount('mint'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n        source: resolveAccount('source'),\n    },\n    SplTokenTransferCheckedWithFee: {\n        authority: resolveAccount('authority'),\n        destination: resolveAccount('destination'),\n        mint: resolveAccount('mint'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n        source: resolveAccount('source'),\n    },\n    SplTokenTransferInstruction: {\n        authority: resolveAccount('authority'),\n        destination: resolveAccount('destination'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n        source: resolveAccount('source'),\n    },\n    SplTokenUiAmountToAmountInstruction: {\n        mint: resolveAccount('mint'),\n    },\n    SplTokenUpdateConfidentialTransferMint: {\n        authority: resolveAccount('authority'),\n        confidentialTransferMintAuthority: resolveAccount('confidentialTransferMintAuthority'),\n        mint: resolveAccount('mint'),\n        newConfidentialTransferMintAuthority: resolveAccount('newConfidentialTransferMintAuthority'),\n    },\n    SplTokenUpdateDefaultAccountStateInstruction: {\n        freezeAuthority: resolveAccount('freezeAuthority'),\n        mint: resolveAccount('mint'),\n        multisigFreezeAuthority: resolveAccount('multisigFreezeAuthority'),\n    },\n    SplTokenUpdateGroupMemberPointerInstruction: {\n        authority: resolveAccount('authority'),\n        memberAddress: resolveAccount('memberAddress'),\n        mint: resolveAccount('mint'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n    },\n    SplTokenUpdateGroupPointerInstruction: {\n        authority: resolveAccount('authority'),\n        groupAddress: resolveAccount('groupAddress'),\n        mint: resolveAccount('mint'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n    },\n    SplTokenUpdateInterestBearingConfigRate: {\n        mint: resolveAccount('mint'),\n        multisigRateAuthority: resolveAccount('multisigRateAuthority'),\n        rateAuthority: resolveAccount('rateAuthority'),\n    },\n    SplTokenUpdateMetadataPointerInstruction: {\n        authority: resolveAccount('authority'),\n        metadataAddress: resolveAccount('metadataAddress'),\n        mint: resolveAccount('mint'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n    },\n    SplTokenUpdateTransferHookInstruction: {\n        authority: resolveAccount('authority'),\n        hookProgramId: resolveAccount('programId'),\n        mint: resolveAccount('mint'),\n        multisigAuthority: resolveAccount('multisigAuthority'),\n    },\n    SplTokenWithdrawConfidentialTransfer: {\n        destination: resolveAccount('destination'),\n        instructionsSysvar: resolveAccount('instructionsSysvar'),\n        mint: resolveAccount('mint'),\n        multisigOwner: resolveAccount('multisigOwner'),\n        owner: resolveAccount('owner'),\n        source: resolveAccount('source'),\n    },\n    SplTokenWithdrawWithheldConfidentialTransferTokensFromAccounts: {\n        feeRecipient: resolveAccount('feeRecipient'),\n        instructionsSysvar: resolveAccount('instructionsSysvar'),\n        mint: resolveAccount('mint'),\n        multisigWithdrawWithheldAuthority: resolveAccount('multisigWithdrawWithheldAuthority'),\n        withdrawWithheldAuthority: resolveAccount('withdrawWithheldAuthority'),\n    },\n    SplTokenWithdrawWithheldConfidentialTransferTokensFromMint: {\n        feeRecipient: resolveAccount('feeRecipient'),\n        instructionsSysvar: resolveAccount('instructionsSysvar'),\n        mint: resolveAccount('mint'),\n        multisigWithdrawWithheldAuthority: resolveAccount('multisigWithdrawWithheldAuthority'),\n        withdrawWithheldAuthority: resolveAccount('withdrawWithheldAuthority'),\n    },\n    SplTokenWithdrawWithheldTokensFromAccounts: {\n        feeRecipient: resolveAccount('feeRecipient'),\n        mint: resolveAccount('mint'),\n        multisigWithdrawWithheldAuthority: resolveAccount('multisigWithdrawWithheldAuthority'),\n        withdrawWithheldAuthority: resolveAccount('withdrawWithheldAuthority'),\n    },\n    SplTokenWithdrawWithheldTokensFromMint: {\n        feeRecipient: resolveAccount('feeRecipient'),\n        mint: resolveAccount('mint'),\n        multisigWithdrawWithheldAuthority: resolveAccount('multisigWithdrawWithheldAuthority'),\n        withdrawWithheldAuthority: resolveAccount('withdrawWithheldAuthority'),\n    },\n    StakeAuthorizeCheckedInstruction: {\n        authority: resolveAccount('authority'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        custodian: resolveAccount('custodian'),\n        newAuthority: resolveAccount('newAuthority'),\n        stakeAccount: resolveAccount('stakeAccount'),\n    },\n    StakeAuthorizeCheckedWithSeedInstruction: {\n        authorityBase: resolveAccount('authorityBase'),\n        authorityOwner: resolveAccount('authorityOwner'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        custodian: resolveAccount('custodian'),\n        newAuthorized: resolveAccount('newAuthorized'),\n        stakeAccount: resolveAccount('stakeAccount'),\n    },\n    StakeAuthorizeInstruction: {\n        authority: resolveAccount('authority'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        custodian: resolveAccount('custodian'),\n        newAuthority: resolveAccount('newAuthority'),\n        stakeAccount: resolveAccount('stakeAccount'),\n    },\n    StakeAuthorizeWithSeedInstruction: {\n        authorityBase: resolveAccount('authorityBase'),\n        authorityOwner: resolveAccount('authorityOwner'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        custodian: resolveAccount('custodian'),\n        newAuthorized: resolveAccount('newAuthorized'),\n        stakeAccount: resolveAccount('stakeAccount'),\n    },\n    StakeDeactivateDelinquentInstruction: {\n        referenceVoteAccount: resolveAccount('referenceVoteAccount'),\n        stakeAccount: resolveAccount('stakeAccount'),\n        voteAccount: resolveAccount('voteAccount'),\n    },\n    StakeDeactivateInstruction: {\n        clockSysvar: resolveAccount('clockSysvar'),\n        stakeAccount: resolveAccount('stakeAccount'),\n        stakeAuthority: resolveAccount('stakeAuthority'),\n    },\n    StakeDelegateStakeInstruction: {\n        clockSysvar: resolveAccount('clockSysvar'),\n        stakeAccount: resolveAccount('stakeAccount'),\n        stakeAuthority: resolveAccount('stakeAuthority'),\n        stakeConfigAccount: resolveAccount('stakeConfigAccount'),\n        stakeHistorySysvar: resolveAccount('stakeHistorySysvar'),\n        voteAccount: resolveAccount('voteAccount'),\n    },\n    StakeInitializeCheckedInstruction: {\n        rentSysvar: resolveAccount('rentSysvar'),\n        stakeAccount: resolveAccount('stakeAccount'),\n    },\n    StakeInitializeCheckedInstructionDataAuthorized: {\n        staker: resolveAccount('staker'),\n        withdrawer: resolveAccount('withdrawer'),\n    },\n    StakeInitializeInstruction: {\n        rentSysvar: resolveAccount('rentSysvar'),\n        stakeAccount: resolveAccount('stakeAccount'),\n    },\n    StakeInitializeInstructionDataAuthorized: {\n        staker: resolveAccount('staker'),\n        withdrawer: resolveAccount('withdrawer'),\n    },\n    StakeMergeInstruction: {\n        clockSysvar: resolveAccount('clockSysvar'),\n        destination: resolveAccount('destination'),\n        source: resolveAccount('source'),\n        stakeAuthority: resolveAccount('stakeAuthority'),\n        stakeHistorySysvar: resolveAccount('stakeHistorySysvar'),\n    },\n    StakeRedelegateInstruction: {\n        newStakeAccount: resolveAccount('newStakeAccount'),\n        stakeAccount: resolveAccount('stakeAccount'),\n        stakeAuthority: resolveAccount('stakeAuthority'),\n        stakeConfigAccount: resolveAccount('stakeConfigAccount'),\n        voteAccount: resolveAccount('voteAccount'),\n    },\n    StakeSetLockupCheckedInstruction: {\n        custodian: resolveAccount('custodian'),\n        stakeAccount: resolveAccount('stakeAccount'),\n    },\n    StakeSetLockupInstruction: {\n        custodian: resolveAccount('custodian'),\n        stakeAccount: resolveAccount('stakeAccount'),\n    },\n    StakeSplitInstruction: {\n        newSplitAccount: resolveAccount('newSplitAccount'),\n        stakeAccount: resolveAccount('stakeAccount'),\n        stakeAuthority: resolveAccount('stakeAuthority'),\n    },\n    StakeWithdrawInstruction: {\n        clockSysvar: resolveAccount('clockSysvar'),\n        destination: resolveAccount('destination'),\n        stakeAccount: resolveAccount('stakeAccount'),\n        withdrawAuthority: resolveAccount('withdrawAuthority'),\n    },\n    TransactionInstruction: {\n        __resolveType(instructionResult: InstructionResult) {\n            const { jsonParsedConfigs } = instructionResult;\n            if (jsonParsedConfigs) {\n                if (jsonParsedConfigs.programName === 'address-lookup-table') {\n                    if (jsonParsedConfigs.instructionType === 'createLookupTable') {\n                        return 'CreateLookupTableInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'freezeLookupTable') {\n                        return 'FreezeLookupTableInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'extendLookupTable') {\n                        return 'ExtendLookupTableInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'deactivateLookupTable') {\n                        return 'DeactivateLookupTableInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'closeLookupTable') {\n                        return 'CloseLookupTableInstruction';\n                    }\n                }\n                if (jsonParsedConfigs.programName === 'bpf-loader') {\n                    if (jsonParsedConfigs.instructionType === 'write') {\n                        return 'BpfLoaderWriteInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'finalize') {\n                        return 'BpfLoaderFinalizeInstruction';\n                    }\n                }\n                if (jsonParsedConfigs.programName === 'bpf-upgradeable-loader') {\n                    if (jsonParsedConfigs.instructionType === 'initializeBuffer') {\n                        return 'BpfUpgradeableLoaderInitializeBufferInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'write') {\n                        return 'BpfUpgradeableLoaderWriteInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'deployWithMaxDataLen') {\n                        return 'BpfUpgradeableLoaderDeployWithMaxDataLenInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'upgrade') {\n                        return 'BpfUpgradeableLoaderUpgradeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'setAuthority') {\n                        return 'BpfUpgradeableLoaderSetAuthorityInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'setAuthorityChecked') {\n                        return 'BpfUpgradeableLoaderSetAuthorityCheckedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'close') {\n                        return 'BpfUpgradeableLoaderCloseInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'extendProgram') {\n                        return 'BpfUpgradeableLoaderExtendProgramInstruction';\n                    }\n                }\n                if (jsonParsedConfigs.programName === 'spl-associated-token-account') {\n                    if (jsonParsedConfigs.instructionType === 'create') {\n                        return 'SplAssociatedTokenCreateInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'createIdempotent') {\n                        return 'SplAssociatedTokenCreateIdempotentInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'recoverNested') {\n                        return 'SplAssociatedTokenRecoverNestedInstruction';\n                    }\n                }\n                if (jsonParsedConfigs.programName === 'spl-memo') {\n                    return 'SplMemoInstruction';\n                }\n                if (jsonParsedConfigs.programName === 'spl-token') {\n                    if (jsonParsedConfigs.instructionType === 'initializeMint') {\n                        return 'SplTokenInitializeMintInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeMint2') {\n                        return 'SplTokenInitializeMint2Instruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeAccount') {\n                        return 'SplTokenInitializeAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeAccount2') {\n                        return 'SplTokenInitializeAccount2Instruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeAccount3') {\n                        return 'SplTokenInitializeAccount3Instruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeMultisig') {\n                        return 'SplTokenInitializeMultisigInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeMultisig2') {\n                        return 'SplTokenInitializeMultisig2Instruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'transfer') {\n                        return 'SplTokenTransferInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'approve') {\n                        return 'SplTokenApproveInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'revoke') {\n                        return 'SplTokenRevokeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'setAuthority') {\n                        return 'SplTokenSetAuthorityInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'mintTo') {\n                        return 'SplTokenMintToInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'burn') {\n                        return 'SplTokenBurnInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'closeAccount') {\n                        return 'SplTokenCloseAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'freezeAccount') {\n                        return 'SplTokenFreezeAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'thawAccount') {\n                        return 'SplTokenThawAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'transferChecked') {\n                        return 'SplTokenTransferCheckedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'approveChecked') {\n                        return 'SplTokenApproveCheckedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'mintToChecked') {\n                        return 'SplTokenMintToCheckedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'burnChecked') {\n                        return 'SplTokenBurnCheckedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'syncNative') {\n                        return 'SplTokenSyncNativeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'getAccountDataSize') {\n                        return 'SplTokenGetAccountDataSizeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeImmutableOwner') {\n                        return 'SplTokenInitializeImmutableOwnerInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'amountToUiAmount') {\n                        return 'SplTokenAmountToUiAmountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'uiAmountToAmount') {\n                        return 'SplTokenUiAmountToAmountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeMintCloseAuthority') {\n                        return 'SplTokenInitializeMintCloseAuthorityInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializePermanentDelegate') {\n                        return 'SplTokenInitializePermanentDelegateInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeGroupPointer') {\n                        return 'SplTokenInitializeGroupPointerInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateGroupPointer') {\n                        return 'SplTokenUpdateGroupPointerInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeGroupMemberPointer') {\n                        return 'SplTokenInitializeGroupMemberPointerInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateGroupMemberPointer') {\n                        return 'SplTokenUpdateGroupMemberPointerInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeMetadataPointer') {\n                        return 'SplTokenInitializeMetadataPointerInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateMetadataPointer') {\n                        return 'SplTokenUpdateMetadataPointerInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeTransferFeeConfig') {\n                        return 'SplTokenInitializeTransferFeeConfig';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'transferCheckedWithFee') {\n                        return 'SplTokenTransferCheckedWithFee';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeTransferHook') {\n                        return 'SplTokenInitializeTransferHookInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateTransferHook') {\n                        return 'SplTokenUpdateTransferHookInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeDefaultAccountState') {\n                        return 'SplTokenInitializeDefaultAccountStateInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateDefaultAccountState') {\n                        return 'SplTokenUpdateDefaultAccountStateInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'disableCpiGuard') {\n                        return 'SplTokenDisableCpiGuardInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'enableCpiGuard') {\n                        return 'SplTokenEnableCpiGuardInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'harvestWithheldTokensToMint') {\n                        return 'SplTokenHarvestWithheldTokensToMint';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'withdrawWithheldTokensFromAccounts') {\n                        return 'SplTokenWithdrawWithheldTokensFromAccounts';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'withdrawWithheldTokensFromMint') {\n                        return 'SplTokenWithdrawWithheldTokensFromMint';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'enableRequiredMemoTransfers') {\n                        return 'SplTokenEnableRequiredMemoTransfers';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'disableRequiredMemoTransfers') {\n                        return 'SplTokenDisableRequiredMemoTransfers';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeConfidentialTransferMint') {\n                        return 'SplTokenInitializeConfidentialTransferMint';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeInterestBearingConfig') {\n                        return 'SplTokenInitializeInterestBearingConfig';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateInterestBearingConfigRate') {\n                        return 'SplTokenUpdateInterestBearingConfigRate';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'approveConfidentialTransferAccount') {\n                        return 'SplTokenApproveConfidentialTransferAccount';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'emptyConfidentialTransferAccount') {\n                        return 'SplTokenEmptyConfidentialTransferAccount';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'configureConfidentialTransferAccount') {\n                        return 'SplTokenConfigureConfidentialTransferAccount';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'applyPendingConfidentialTransferBalance') {\n                        return 'SplTokenApplyPendingConfidentialTransferBalance';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'enableConfidentialTransferConfidentialCredits') {\n                        return 'SplTokenEnableConfidentialTransferConfidentialCredits';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'disableConfidentialTransferConfidentialCredits') {\n                        return 'SplTokenDisableConfidentialTransferConfidentialCredits';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'enableConfidentialTransferNonConfidentialCredits') {\n                        return 'SplTokenEnableConfidentialTransferNonConfidentialCredits';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'disableNonConfidentialTransferConfidentialCredits') {\n                        return 'SplTokenDisableConfidentialTransferNonConfidentialCredits';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'depositConfidentialTransfer') {\n                        return 'SplTokenDepositConfidentialTransfer';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'withdrawConfidentialTransfer') {\n                        return 'SplTokenWithdrawConfidentialTransfer';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'confidentialTransfer') {\n                        return 'SplTokenConfidentialTransfer';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'confidentialTransferWithSplitProofs') {\n                        return 'SplTokenConfidentialTransferWithSplitProofs';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateConfidentialTransferMint') {\n                        return 'SplTokenUpdateConfidentialTransferMint';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'withdrawWithheldConfidentialTransferTokensFromMint') {\n                        return 'SplTokenWithdrawWithheldConfidentialTransferTokensFromMint';\n                    }\n                    if (\n                        jsonParsedConfigs.instructionType === 'withdrawWithheldConfidentialTransferTokensFromAccounts'\n                    ) {\n                        return 'SplTokenWithdrawWithheldConfidentialTransferTokensFromAccounts';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'harvestWithheldConfidentialTransferTokensToMint') {\n                        return 'SplTokenHarvestWithheldConfidentialTransferTokensToMint';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'enableConfidentialTransferFeeHarvestToMint') {\n                        return 'SplTokenEnableConfidentialTransferFeeHarvestToMint';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'disableConfidentialTransferFeeHarvestToMint') {\n                        return 'SplTokenDisableConfidentialTransferFeeHarvestToMint';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeConfidentialTransferFeeConfig') {\n                        return 'SplTokenInitializeConfidentialTransferFeeConfig';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeTokenGroup') {\n                        return 'SplTokenGroupInitializeGroup';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateTokenGroupMaxSize') {\n                        return 'SplTokenGroupUpdateGroupMaxSize';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateTokenGroupAuthority') {\n                        return 'SplTokenGroupUpdateGroupAuthority';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeTokenGroupMember') {\n                        return 'SplTokenGroupInitializeMember';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeTokenMetadata') {\n                        return 'SplTokenMetadataInitialize';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateTokenMetadataField') {\n                        return 'SplTokenMetadataUpdateField';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'removeTokenMetadataKey') {\n                        return 'SplTokenMetadataRemoveKey';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateTokenMetadataAuthority') {\n                        return 'SplTokenMetadataUpdateAuthority';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'emitTokenMetadata') {\n                        return 'SplTokenMetadataEmit';\n                    }\n                    if (jsonParsedConfigs?.instructionType === 'reallocate') {\n                        return 'SplTokenReallocate';\n                    }\n                }\n                if (jsonParsedConfigs.programName === 'stake') {\n                    if (jsonParsedConfigs.instructionType === 'initialize') {\n                        return 'StakeInitializeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorize') {\n                        return 'StakeAuthorizeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'delegate') {\n                        return 'StakeDelegateStakeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'split') {\n                        return 'StakeSplitInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'withdraw') {\n                        return 'StakeWithdrawInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'deactivate') {\n                        return 'StakeDeactivateInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'setLockup') {\n                        return 'StakeSetLockupInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'merge') {\n                        return 'StakeMergeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorizeWithSeed') {\n                        return 'StakeAuthorizeWithSeedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeChecked') {\n                        return 'StakeInitializeCheckedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorizeChecked') {\n                        return 'StakeAuthorizeCheckedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorizeCheckedWithSeed') {\n                        return 'StakeAuthorizeCheckedWithSeedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'setLockupChecked') {\n                        return 'StakeSetLockupCheckedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'deactivateDelinquent') {\n                        return 'StakeDeactivateDelinquentInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'redelegate') {\n                        return 'StakeRedelegateInstruction';\n                    }\n                }\n                if (jsonParsedConfigs.programName === 'system') {\n                    if (jsonParsedConfigs.instructionType === 'createAccount') {\n                        return 'CreateAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'assign') {\n                        return 'AssignInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'transfer') {\n                        return 'TransferInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'createAccountWithSeed') {\n                        return 'CreateAccountWithSeedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'advanceNonceAccount') {\n                        return 'AdvanceNonceAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'withdrawNonceAccount') {\n                        return 'WithdrawNonceAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'initializeNonceAccount') {\n                        return 'InitializeNonceAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorizeNonceAccount') {\n                        return 'AuthorizeNonceAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'upgradeNonceAccount') {\n                        return 'UpgradeNonceAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'allocate') {\n                        return 'AllocateInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'allocateWithSeed') {\n                        return 'AllocateWithSeedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'assignWithSeed') {\n                        return 'AssignWithSeedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'transferWithSeed') {\n                        return 'TransferWithSeedInstruction';\n                    }\n                }\n                if (jsonParsedConfigs.programName === 'vote') {\n                    if (jsonParsedConfigs.instructionType === 'initialize') {\n                        return 'VoteInitializeAccountInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorize') {\n                        return 'VoteAuthorizeInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorizeWithSeed') {\n                        return 'VoteAuthorizeWithSeedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorizeCheckedWithSeed') {\n                        return 'VoteAuthorizeCheckedWithSeedInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'vote') {\n                        return 'VoteVoteInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updatevotestate') {\n                        return 'VoteUpdateVoteStateInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updatevotestateswitch') {\n                        return 'VoteUpdateVoteStateSwitchInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'compactupdatevotestate') {\n                        return 'VoteCompactUpdateVoteStateInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'compactupdatevotestateswitch') {\n                        return 'VoteCompactUpdateVoteStateSwitchInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'withdraw') {\n                        return 'VoteWithdrawInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateValidatorIdentity') {\n                        return 'VoteUpdateValidatorIdentityInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'updateCommission') {\n                        return 'VoteUpdateCommissionInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'voteSwitch') {\n                        return 'VoteVoteSwitchInstruction';\n                    }\n                    if (jsonParsedConfigs.instructionType === 'authorizeChecked') {\n                        return 'VoteAuthorizeCheckedInstruction';\n                    }\n                }\n            }\n            return 'GenericInstruction';\n        },\n    },\n    TransferInstruction: {\n        destination: resolveAccount('destination'),\n        source: resolveAccount('source'),\n    },\n    TransferWithSeedInstruction: {\n        destination: resolveAccount('destination'),\n        source: resolveAccount('source'),\n        sourceOwner: resolveAccount('sourceOwner'),\n    },\n    UpgradeNonceAccountInstruction: {\n        nonceAccount: resolveAccount('nonceAccount'),\n        nonceAuthority: resolveAccount('nonceAuthority'),\n    },\n    VoteAuthorizeCheckedInstruction: {\n        authority: resolveAccount('authority'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        newAuthority: resolveAccount('newAuthority'),\n        voteAccount: resolveAccount('voteAccount'),\n    },\n    VoteAuthorizeCheckedWithSeedInstruction: {\n        authorityOwner: resolveAccount('authorityOwner'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        newAuthority: resolveAccount('newAuthority'),\n        voteAccount: resolveAccount('voteAccount'),\n    },\n    VoteAuthorizeInstruction: {\n        authority: resolveAccount('authority'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        newAuthority: resolveAccount('newAuthority'),\n        voteAccount: resolveAccount('voteAccount'),\n    },\n    VoteAuthorizeWithSeedInstruction: {\n        authorityOwner: resolveAccount('authorityOwner'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        newAuthority: resolveAccount('newAuthority'),\n        voteAccount: resolveAccount('voteAccount'),\n    },\n    VoteCompactUpdateVoteStateInstruction: {\n        voteAccount: resolveAccount('voteAccount'),\n        voteAuthority: resolveAccount('voteAuthority'),\n    },\n    VoteCompactUpdateVoteStateSwitchInstruction: {\n        voteAccount: resolveAccount('voteAccount'),\n        voteAuthority: resolveAccount('voteAuthority'),\n    },\n    VoteInitializeAccountInstruction: {\n        authorizedVoter: resolveAccount('authorizedVoter'),\n        authorizedWithdrawer: resolveAccount('authorizedWithdrawer'),\n        clockSysvar: resolveAccount('clockSysvar'),\n        node: resolveAccount('node'),\n\n        rentSysvar: resolveAccount('rentSysvar'),\n        voteAccount: resolveAccount('voteAccount'),\n    },\n    VoteUpdateCommissionInstruction: {\n        voteAccount: resolveAccount('voteAccount'),\n        withdrawAuthority: resolveAccount('withdrawAuthority'),\n    },\n    VoteUpdateValidatorIdentityInstruction: {\n        newValidatorIdentity: resolveAccount('newValidatorIdentity'),\n\n        voteAccount: resolveAccount('voteAccount'),\n        withdrawAuthority: resolveAccount('withdrawAuthority'),\n    },\n    VoteUpdateVoteStateInstruction: {\n        voteAccount: resolveAccount('voteAccount'),\n        voteAuthority: resolveAccount('voteAuthority'),\n    },\n    VoteUpdateVoteStateSwitchInstruction: {\n        voteAccount: resolveAccount('voteAccount'),\n        voteAuthority: resolveAccount('voteAuthority'),\n    },\n    VoteVoteInstruction: {\n        clockSysvar: resolveAccount('clockSysvar'),\n        slotHashesSysvar: resolveAccount('slotHashesSysvar'),\n        voteAccount: resolveAccount('voteAccount'),\n        voteAuthority: resolveAccount('voteAuthority'),\n    },\n    VoteVoteSwitchInstruction: {\n        clockSysvar: resolveAccount('clockSysvar'),\n        slotHashesSysvar: resolveAccount('slotHashesSysvar'),\n        voteAccount: resolveAccount('voteAccount'),\n        voteAuthority: resolveAccount('voteAuthority'),\n    },\n    VoteWithdrawInstruction: {\n        voteAccount: resolveAccount('voteAccount'),\n        withdrawAuthority: resolveAccount('withdrawAuthority'),\n    },\n    WithdrawNonceAccountInstruction: {\n        destination: resolveAccount('destination'),\n        nonceAccount: resolveAccount('nonceAccount'),\n        nonceAuthority: resolveAccount('nonceAuthority'),\n        recentBlockhashesSysvar: resolveAccount('recentBlockhashesSysvar'),\n        rentSysvar: resolveAccount('rentSysvar'),\n    },\n};\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-resolvers/root.ts",
    "content": "import type { makeExecutableSchema } from '@graphql-tools/schema';\n\nimport { resolveAccount } from '../../resolvers/account';\nimport { resolveBlock } from '../../resolvers/block';\nimport { resolveProgramAccounts } from '../../resolvers/program-accounts';\nimport { resolveTransaction } from '../../resolvers/transaction';\n\nexport const rootTypeResolvers: Parameters<typeof makeExecutableSchema>[0]['resolvers'] = {\n    Query: {\n        account: resolveAccount(),\n        block: resolveBlock(),\n        programAccounts: resolveProgramAccounts(),\n        transaction: resolveTransaction(),\n    },\n};\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-resolvers/transaction.ts",
    "content": "import { resolveTransactionData } from '../../resolvers/transaction';\n\nexport const transactionTypeResolvers = {\n    Transaction: {\n        data: resolveTransactionData(),\n    },\n};\n"
  },
  {
    "path": "packages/rpc-graphql/src/schema/type-resolvers/types.ts",
    "content": "import { Kind } from 'graphql';\n\nimport { resolveAccount } from '../../resolvers/account';\n\nconst stringScalarAlias = {\n    __parseLiteral(ast: { kind: Kind; value: bigint | boolean | number | string }): string | null {\n        if (ast.kind === Kind.STRING) {\n            return ast.value.toString();\n        }\n        return null;\n    },\n    __parseValue(value: string): string {\n        return value;\n    },\n    __serialize(value: string): string {\n        return value;\n    },\n};\n\nconst bigIntScalarAlias = {\n    __parseLiteral(ast: { kind: Kind; value: bigint | boolean | number | string }): bigint | null {\n        if (ast.kind === Kind.STRING || ast.kind === Kind.INT || ast.kind === Kind.FLOAT) {\n            return BigInt(ast.value);\n        }\n        return null;\n    },\n    __parseValue(value: string): bigint {\n        return BigInt(value);\n    },\n    __serialize(value: string): bigint {\n        return BigInt(value);\n    },\n};\n\nexport const typeTypeResolvers = {\n    AccountEncoding: {\n        BASE_58: 'base58',\n        BASE_64: 'base64',\n        BASE_64_ZSTD: 'base64+zstd',\n    },\n    Address: stringScalarAlias,\n    Base58EncodedBytes: stringScalarAlias,\n    Base64EncodedBytes: stringScalarAlias,\n    Base64ZstdEncodedBytes: stringScalarAlias,\n    BigInt: bigIntScalarAlias,\n    Commitment: {\n        CONFIRMED: 'confirmed',\n        FINALIZED: 'finalized',\n        PROCESSED: 'processed',\n    },\n    CommitmentWithoutProcessed: {\n        CONFIRMED: 'confirmed',\n        FINALIZED: 'finalized',\n    },\n    Epoch: bigIntScalarAlias,\n    Hash: stringScalarAlias,\n    Lamports: bigIntScalarAlias,\n    ProgramAccountsMemcmpFilterAccountEncoding: {\n        BASE_58: 'base58',\n        BASE_64: 'base64',\n    },\n    Signature: stringScalarAlias,\n    Slot: bigIntScalarAlias,\n    SplTokenDefaultAccountState: {\n        FROZEN: 'frozen',\n        INITIALIZED: 'initialized',\n        UNINITIALIZED: 'uninitialized',\n    },\n    SplTokenExtensionType: {\n        CONFIDENTIAL_TRANSFER_ACCOUNT: 'confidentialTransferAccount',\n        CONFIDENTIAL_TRANSFER_FEE_AMOUNT: 'confidentialTransferFeeAmount',\n        CONFIDENTIAL_TRANSFER_FEE_CONFIG: 'confidentialTransferFeeConfig',\n        CONFIDENTIAL_TRANSFER_MINT: 'confidentialTransferMint',\n        CPI_GUARD: 'cpiGuard',\n        DEFAULT_ACCOUNT_STATE: 'defaultAccountState',\n        GROUP_MEMBER_POINTER: 'groupMemberPointer',\n        GROUP_POINTER: 'groupPointer',\n        IMMUTABLE_OWNER: 'immutableOwner',\n        INTEREST_BEARING_CONFIG: 'interestBearingConfig',\n        MEMO_TRANSFER: 'memoTransfer',\n        METADATA_POINTER: 'metadataPointer',\n        MINT_CLOSE_AUTHORITY: 'mintCloseAuthority',\n        NON_TRANSFERABLE: 'nonTransferable',\n        NON_TRANSFERABLE_ACCOUNT: 'nonTransferableAccount',\n        PERMANENT_DELEGATE: 'permanentDelegate',\n        TOKEN_GROUP: 'tokenGroup',\n        TOKEN_GROUP_MEMBER: 'tokenGroupMember',\n        TOKEN_METADATA: 'tokenMetadata',\n        TRANSFER_FEE_AMOUNT: 'transferFeeAmount',\n        TRANSFER_FEE_CONFIG: 'transferFeeConfig',\n        TRANSFER_HOOK: 'transferHook',\n        TRANSFER_HOOK_ACCOUNT: 'transferHookAccount',\n        UNINITIALIZED: 'uninitialized',\n        UNPARSEABLE_EXTENSION: 'unparseableExtension',\n    },\n    TokenBalance: {\n        mint: resolveAccount('mint'),\n        owner: resolveAccount('owner'),\n    },\n    TransactionEncoding: {\n        BASE_58: 'base58',\n        BASE_64: 'base64',\n    },\n};\n"
  },
  {
    "path": "packages/rpc-graphql/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-graphql/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2017\", \"ES2020.BigInt\", \"ES2022.Error\"],\n        \"resolveJsonModule\": true\n    },\n    \"display\": \"@solana/rpc-graphql\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-parsed-types/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-parsed-types/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-parsed-types/CHANGELOG.md",
    "content": "# @solana/rpc-parsed-types\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1544](https://github.com/anza-xyz/kit/pull/1544) [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update RPC types for Agave v3.x validator compatibility.\n\n    **`@solana/rpc-parsed-types`**: `JsonParsedVoteAccount` now includes `blockRevenueCollector`, `blockRevenueCommissionBps`, `blsPubkeyCompressed`, `inflationRewardsCollector`, `inflationRewardsCommissionBps`, `pendingDelegatorRewards`, and a `latency` field on each vote entry.\n\n    **`@solana/rpc-api`**: `SimulateTransactionApiResponseBase` now includes `fee`, `loadedAddresses`, `preBalances`, `postBalances`, `preTokenBalances`, and `postTokenBalances`.\n\n    **`@solana/errors`**: `RpcSimulateTransactionResult` updated with the same new fields.\n\n    **Note on `replacementBlockhash`**: Agave v3.x validators now always return `replacementBlockhash` in `simulateTransaction` responses (as `null` when `replaceRecentBlockhash` is not set). Kit's types still model this field as conditionally present based on config. A future breaking change will move it to the base response type as `TransactionBlockhashLifetime | null` to match v3.x behavior. Consumers using v3.x validators may see this field at runtime even when Kit's types don't surface it.\n\n    **Note on Agave v3.x validator behavior**: Validators running Agave v3.x no longer return a dedicated `TRANSACTION_SIGNATURE_VERIFICATION_FAILURE` RPC error for invalid signatures in `simulateTransaction` or `sendTransaction`. Instead, `simulateTransaction` returns a result with `err: \"SignatureFailure\"`, and `sendTransaction` returns a preflight failure with the signature error as the cause. This is a validator-level change and does not affect Kit's API surface.\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n## 6.6.0\n\n## 6.5.0\n\n## 6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n## 6.1.0\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n## 5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n## 5.3.0\n\n## 5.2.0\n\n## 5.1.0\n\n## 5.0.0\n\n## 4.0.0\n\n## 3.0.0\n\n## 2.3.0\n\n## 2.2.1\n\n## 2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n## 2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n## 2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n"
  },
  {
    "path": "packages/rpc-parsed-types/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-parsed-types/README.md",
    "content": "[![npm][npm-image]][npm-url] [![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-types?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-types?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-types\n\n# @solana/rpc-parsed-types\n\nThis package defines types for parsed objects returned by methods of the [Solana JSON-RPC](https://docs.solana.com/api/http). It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n"
  },
  {
    "path": "packages/rpc-parsed-types/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-parsed-types\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Type definitions for parsed types used in the Solana RPC\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-parsed-types\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"devDependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/__typetests__/address-lookup-table-accounts-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { StringifiedBigInt } from '@solana/rpc-types';\n\nimport { JsonParsedAddressLookupTableAccount } from '../address-lookup-table-accounts';\n\nconst account = {\n    info: {\n        addresses: [\n            'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address,\n            'FWscgV4VDSsMxkQg7jZ4HksqjLyadJS5RiCnAVZv2se9' as Address,\n        ],\n        authority: '4msgK65vdz5ADUAB3eTQGpF388NuQUAoknLxutUQJd5B' as Address,\n        deactivationSlot: '204699277' as StringifiedBigInt,\n        lastExtendedSlot: '204699234' as StringifiedBigInt,\n        lastExtendedSlotStartIndex: 20,\n    },\n};\n\naccount satisfies JsonParsedAddressLookupTableAccount;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/__typetests__/bpf-upgradeable-loader-accounts-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Base64EncodedDataResponse } from '@solana/rpc-types';\n\nimport { JsonParsedBpfUpgradeableLoaderProgramAccount } from '../bpf-upgradeable-loader-accounts';\n\n// program account\n{\n    const account = {\n        info: {\n            programData: '3vnUTQbDuCgfVn7yQcigUwMQNGkLBZ7GfKWb3gYbAY23' as Address,\n        },\n        type: 'program' as const,\n    };\n    account satisfies JsonParsedBpfUpgradeableLoaderProgramAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedBpfUpgradeableLoaderProgramAccount;\n    if (account.type === 'program') {\n        account.info.programData satisfies Address;\n    }\n}\n\n// program data account\n{\n    const account = {\n        info: {\n            authority: '7g4Los4WMQnpxYiBJpU1HejBiM6xCk5RDFGCABhWE9M6' as Address,\n            data: ['f0VMRgIBAAAAAAAAA', 'base64'] as Base64EncodedDataResponse,\n            slot: 259942942n,\n        },\n        type: 'programData' as const,\n    };\n    account satisfies JsonParsedBpfUpgradeableLoaderProgramAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedBpfUpgradeableLoaderProgramAccount;\n    if (account.type === 'programData') {\n        account.info.slot satisfies bigint;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/__typetests__/config-accounts-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { JsonParsedConfigProgramAccount } from '../config-accounts';\n\n// stake config account\n{\n    const account = {\n        info: {\n            slashPenalty: 12,\n            warmupCooldownRate: 0.25,\n        },\n        type: 'stakeConfig' as const,\n    };\n    account satisfies JsonParsedConfigProgramAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedConfigProgramAccount;\n    if (account.type === 'stakeConfig') {\n        account.info.slashPenalty satisfies number;\n    }\n}\n\n// validator info account\n{\n    const account = {\n        info: {\n            configData: {\n                name: 'HoldTheNode',\n                website: 'https://holdthenode.com',\n            },\n            keys: [\n                {\n                    pubkey: 'Va1idator1nfo111111111111111111111111111111' as Address,\n                    signer: false,\n                },\n                {\n                    pubkey: '5hvJ19nRgtzAkosb5bcx9bqeN2QA1Qwxq4M349Q2L6s2' as Address,\n                    signer: true,\n                },\n            ],\n        },\n        type: 'validatorInfo' as const,\n    };\n    account satisfies JsonParsedConfigProgramAccount;\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/__typetests__/nonce-accounts-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Blockhash, StringifiedBigInt } from '@solana/rpc-types';\n\nimport { JsonParsedNonceAccount } from '../nonce-accounts';\n\n{\n    const account = {\n        info: {\n            authority: '3xxDCjN8s6MgNHwdRExRLa6gHmmRTWPnUdzkbKfEgNAe' as Address,\n            blockhash: 'TcVy2wVcs7WqWVopv8LAJBHQfqVYZrm8UDqjDvBFQt8' as Blockhash,\n            feeCalculator: {\n                lamportsPerSignature: '5000' as StringifiedBigInt,\n            },\n        },\n    };\n    account satisfies JsonParsedNonceAccount;\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/__typetests__/stake-accounts-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { StringifiedBigInt, UnixTimestamp } from '@solana/rpc-types';\n\nimport type { JsonParsedStakeProgramAccount } from '../stake-accounts';\n\n// initialized stake account\n{\n    const account = {\n        info: {\n            meta: {\n                authorized: {\n                    staker: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V' as Address,\n                    withdrawer: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V' as Address,\n                },\n                lockup: {\n                    custodian: '11111111111111111111111111111111' as Address,\n                    epoch: 0n,\n                    unixTimestamp: 0n as UnixTimestamp,\n                },\n                rentExemptReserve: '2282880' as StringifiedBigInt,\n            },\n            stake: {\n                creditsObserved: 169965713n,\n                delegation: {\n                    activationEpoch: '386' as StringifiedBigInt,\n                    deactivationEpoch: '471' as StringifiedBigInt,\n                    stake: '8007935' as StringifiedBigInt,\n                    voter: 'CertusDeBmqN8ZawdkxK5kFGMwBXdudvWHYwtNgNhvLu' as Address,\n                    warmupCooldownRate: 0.25,\n                },\n            },\n        },\n        type: 'initialized' as const,\n    };\n    account satisfies JsonParsedStakeProgramAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedStakeProgramAccount;\n    if (account.type === 'initialized') {\n        account.info.meta.authorized.staker satisfies Address;\n    }\n}\n\n// delegated stake account\n{\n    const account = {\n        info: {\n            meta: {\n                authorized: {\n                    staker: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V' as Address,\n                    withdrawer: '3HRNKNXafhr3wE9NSXRpNVdFYt6EVygdqFwqf6WpG57V' as Address,\n                },\n                lockup: {\n                    custodian: '11111111111111111111111111111111' as Address,\n                    epoch: 0n,\n                    unixTimestamp: 0n as UnixTimestamp,\n                },\n                rentExemptReserve: '2282880' as StringifiedBigInt,\n            },\n            stake: {\n                creditsObserved: 169965713n,\n                delegation: {\n                    activationEpoch: '386' as StringifiedBigInt,\n                    deactivationEpoch: '471' as StringifiedBigInt,\n                    stake: '8007935' as StringifiedBigInt,\n                    voter: 'CertusDeBmqN8ZawdkxK5kFGMwBXdudvWHYwtNgNhvLu' as Address,\n                    warmupCooldownRate: 0.25,\n                },\n            },\n        },\n        type: 'delegated' as const,\n    };\n    account satisfies JsonParsedStakeProgramAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedStakeProgramAccount;\n    if (account.type === 'delegated') {\n        account.info.meta.authorized.staker satisfies Address;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/__typetests__/sysvar-accounts-typetest.ts",
    "content": "import { Blockhash, Epoch, Slot, StringifiedBigInt, UnixTimestamp } from '@solana/rpc-types';\n\nimport { JsonParsedSysvarAccount } from '../sysvar-accounts';\n\n// clock sysvar\n{\n    const account = {\n        info: {\n            epoch: 0n as Epoch,\n            epochStartTimestamp: 1704907181n as UnixTimestamp,\n            leaderScheduleEpoch: 1n as Epoch,\n            slot: 90829n as Slot,\n            unixTimestamp: 1704998009n as UnixTimestamp,\n        },\n        type: 'clock' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'clock') {\n        account.info.epoch satisfies Epoch;\n    }\n}\n\n// epoch schedule account\n{\n    const account = {\n        info: {\n            firstNormalEpoch: 0n as Epoch,\n            firstNormalSlot: 0n as Slot,\n            leaderScheduleSlotOffset: 432000n,\n            slotsPerEpoch: 432000n,\n            warmup: false,\n        },\n        type: 'epochSchedule' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'epochSchedule') {\n        account.info.firstNormalEpoch satisfies Epoch;\n    }\n}\n\n// fees account\n{\n    const account = {\n        info: {\n            feeCalculator: {\n                lamportsPerSignature: '0' as StringifiedBigInt,\n            },\n        },\n        type: 'fees' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'fees') {\n        account.info.feeCalculator.lamportsPerSignature satisfies StringifiedBigInt;\n    }\n}\n\n// recent blockhashes account\n{\n    const account = {\n        info: [\n            {\n                blockhash: 'Gy5GKD5p7UmUWF2BEm3TAUP4PSLTw9puSUbuoH5xPdzk' as Blockhash,\n                feeCalculator: {\n                    lamportsPerSignature: '5000' as StringifiedBigInt,\n                },\n            },\n            {\n                blockhash: 'FvNKRQk7TuFXVmXEM4XEubXdYREaeiWX56SL97taEhAQ' as Blockhash,\n                feeCalculator: {\n                    lamportsPerSignature: '5000' as StringifiedBigInt,\n                },\n            },\n        ],\n        type: 'recentBlockhashes' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'recentBlockhashes') {\n        account.info[0].blockhash satisfies Blockhash;\n    }\n}\n\n// rent account\n{\n    const account = {\n        info: {\n            burnPercent: 50,\n            exemptionThreshold: 2.0,\n            lamportsPerByteYear: '3480' as StringifiedBigInt,\n        },\n        type: 'rent' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'rent') {\n        account.info.burnPercent satisfies number;\n    }\n}\n\n// slot hashes account\n{\n    const account = {\n        info: [\n            {\n                hash: 'BAwX3h9EtGqBGnvXqgBoTZL19iHY8PKeCS9AVWFsVLQ8',\n                slot: 149694n as Slot,\n            },\n            {\n                hash: '7HdyQAb5kaZ9RjTuX8uejYXj86J3P2foNfDkqLAFNYFF',\n                slot: 149693n as Slot,\n            },\n        ],\n        type: 'slotHashes' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'slotHashes') {\n        account.info[0].hash satisfies string;\n    }\n}\n\n// slot history account\n{\n    const account = {\n        info: {\n            bits: '1111100000',\n            nextSlot: 150104n as Slot,\n        },\n        type: 'slotHistory' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'slotHistory') {\n        account.info.bits satisfies string;\n    }\n}\n\n// stake history account\n{\n    const account = {\n        info: [\n            {\n                epoch: 683n as Epoch,\n                stakeHistory: {\n                    activating: 0n,\n                    deactivating: 0n,\n                    effective: 6561315032320n,\n                },\n            },\n            {\n                epoch: 682n as Epoch,\n                stakeHistory: {\n                    activating: 0n,\n                    deactivating: 0n,\n                    effective: 506560815032320n,\n                },\n            },\n        ],\n        type: 'stakeHistory' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'stakeHistory') {\n        account.info[0].epoch satisfies Epoch;\n    }\n}\n\n// last restart slot account\n{\n    const account = {\n        info: {\n            lastRestartSlot: 0n as Slot,\n        },\n        type: 'lastRestartSlot' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'lastRestartSlot') {\n        account.info.lastRestartSlot satisfies Slot;\n    }\n}\n\n// epoch rewards account\n{\n    const account = {\n        info: {\n            distributedRewards: 100n,\n            distributionCompleteBlockHeight: 1000n,\n            totalRewards: 200n,\n        },\n        type: 'epochRewards' as const,\n    };\n    account satisfies JsonParsedSysvarAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedSysvarAccount;\n    if (account.type === 'epochRewards') {\n        account.info.totalRewards satisfies bigint;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/__typetests__/token-accounts-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { StringifiedBigInt, StringifiedNumber } from '@solana/rpc-types';\n\nimport { JsonParsedTokenProgramAccount } from '../token-accounts';\n\n// token account\n{\n    const account = {\n        info: {\n            isNative: false,\n            mint: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address,\n            owner: '6UsGbaMgchgj4wiwKKuE1v5URHdcDfEiMSM25QpesKir' as Address,\n            state: 'initialized' as const,\n            tokenAmount: {\n                amount: '9999999779500000' as StringifiedBigInt,\n                decimals: 6,\n                uiAmount: 9999999779.5,\n                uiAmountString: '9999999779.5' as StringifiedNumber,\n            },\n        },\n        type: 'account' as const,\n    };\n    account satisfies JsonParsedTokenProgramAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedTokenProgramAccount;\n    if (account.type === 'account') {\n        account.info.mint satisfies Address;\n    }\n}\n\n// mint account\n{\n    const account = {\n        info: {\n            decimals: 6,\n            freezeAuthority: null,\n            isInitialized: true,\n            mintAuthority: 'Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr' as Address,\n            supply: '1792635195340523528' as StringifiedBigInt,\n        },\n        type: 'mint' as const,\n    };\n    account satisfies JsonParsedTokenProgramAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedTokenProgramAccount;\n    if (account.type === 'mint') {\n        account.info.supply satisfies StringifiedBigInt;\n    }\n}\n\n// multisig account\n{\n    const account = {\n        info: {\n            isInitialized: true,\n            numRequiredSigners: 2,\n            numValidSigners: 2,\n            signers: [\n                'Fkc4FN7PPhyGsAcHPW3dBBJ4BvtYkDr2rBFBgFpvy3nB' as Address,\n                '5scSndUhfZJ8j8wZz5UNHhvuPBhvN1RboTdkKSvFHLtW' as Address,\n            ],\n        },\n        type: 'multisig' as const,\n    };\n    account satisfies JsonParsedTokenProgramAccount;\n}\n\n{\n    const account = {} as unknown as JsonParsedTokenProgramAccount;\n    if (account.type === 'multisig') {\n        account.info.numRequiredSigners satisfies number;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/__typetests__/vote-accounts-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Epoch, Slot, StringifiedBigInt, UnixTimestamp } from '@solana/rpc-types';\n\nimport { JsonParsedVoteAccount } from '../vote-accounts';\n\nconst account = {\n    info: {\n        authorizedVoters: [\n            {\n                authorizedVoter: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr' as Address,\n                epoch: 529n as Epoch,\n            },\n        ],\n        authorizedWithdrawer: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr' as Address,\n        blockRevenueCollector: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr' as Address,\n        blockRevenueCommissionBps: 10000n,\n        blsPubkeyCompressed: null,\n        commission: 50,\n        epochCredits: [\n            {\n                credits: '68697256' as StringifiedBigInt,\n                epoch: 466n as Epoch,\n                previousCredits: '68325825' as StringifiedBigInt,\n            },\n            {\n                credits: '69068118' as StringifiedBigInt,\n                epoch: 467n as Epoch,\n                previousCredits: '68697256' as StringifiedBigInt,\n            },\n        ],\n        inflationRewardsCollector: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr' as Address,\n        inflationRewardsCommissionBps: 5000n,\n        lastTimestamp: {\n            slot: 228884530n as Slot,\n            timestamp: 1689090220n as UnixTimestamp,\n        },\n        nodePubkey: 'HMU77m6WSL9Xew9YvVCgz1hLuhzamz74eD9avi4XPdr' as Address,\n        pendingDelegatorRewards: '0' as StringifiedBigInt,\n        priorVoters: [],\n        rootSlot: 228884499n as Slot,\n        votes: [\n            {\n                confirmationCount: 31,\n                latency: 0n,\n                slot: 228884500n as Slot,\n            },\n            {\n                confirmationCount: 30,\n                latency: 0n,\n                slot: 228884501n as Slot,\n            },\n        ],\n    },\n};\n\naccount satisfies JsonParsedVoteAccount;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/address-lookup-table-accounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { StringifiedBigInt } from '@solana/rpc-types';\n\nimport { RpcParsedInfo } from './rpc-parsed-type';\n\nexport type JsonParsedAddressLookupTableAccount = RpcParsedInfo<{\n    addresses: readonly Address[];\n    authority?: Address;\n    deactivationSlot: StringifiedBigInt;\n    lastExtendedSlot: StringifiedBigInt;\n    lastExtendedSlotStartIndex: number;\n}>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/bpf-upgradeable-loader-accounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Base64EncodedDataResponse, Slot } from '@solana/rpc-types';\n\nimport type { RpcParsedType } from './rpc-parsed-type';\n\ntype JsonParsedBpfProgramAccount = Readonly<{\n    programData: Address;\n}>;\n\ntype JsonParsedBpfProgramDataAccount = Readonly<{\n    authority?: Address;\n    data: Base64EncodedDataResponse;\n    slot: Slot;\n}>;\n\nexport type JsonParsedBpfUpgradeableLoaderProgramAccount =\n    | RpcParsedType<'program', JsonParsedBpfProgramAccount>\n    | RpcParsedType<'programData', JsonParsedBpfProgramDataAccount>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/config-accounts.ts",
    "content": "import type { Address } from '@solana/addresses';\n\nimport type { RpcParsedType } from './rpc-parsed-type';\n\ntype JsonParsedStakeConfigAccount = Readonly<{\n    slashPenalty: number;\n    warmupCooldownRate: number;\n}>;\n\ntype JsonParsedValidatorInfoAccount = Readonly<{\n    configData: unknown;\n    keys: {\n        pubkey: Address;\n        signer: boolean;\n    }[];\n}>;\n\nexport type JsonParsedConfigProgramAccount =\n    | RpcParsedType<'stakeConfig', JsonParsedStakeConfigAccount>\n    | RpcParsedType<'validatorInfo', JsonParsedValidatorInfoAccount>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/index.ts",
    "content": "/**\n * This package defines types for parsed objects returned by methods of the\n * [Solana JSON-RPC](https://docs.solana.com/api/http). It can be used standalone, but it is also\n * exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './address-lookup-table-accounts';\nexport * from './bpf-upgradeable-loader-accounts';\nexport * from './config-accounts';\nexport * from './nonce-accounts';\nexport * from './rpc-parsed-type';\nexport * from './stake-accounts';\nexport * from './sysvar-accounts';\nexport * from './token-accounts';\nexport * from './vote-accounts';\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/nonce-accounts.ts",
    "content": "import { Address } from '@solana/addresses';\nimport type { Blockhash, StringifiedBigInt } from '@solana/rpc-types';\n\nimport { RpcParsedInfo } from './rpc-parsed-type';\n\nexport type JsonParsedNonceAccount = RpcParsedInfo<{\n    authority: Address;\n    blockhash: Blockhash;\n    feeCalculator: Readonly<{\n        lamportsPerSignature: StringifiedBigInt;\n    }>;\n}>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/rpc-parsed-type.ts",
    "content": "export type RpcParsedType<TType extends string, TInfo> = Readonly<{\n    info: TInfo;\n    type: TType;\n}>;\n\nexport type RpcParsedInfo<TInfo> = Readonly<{\n    info: TInfo;\n}>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/stake-accounts.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { StringifiedBigInt, UnixTimestamp } from '@solana/rpc-types';\n\nimport { RpcParsedType } from './rpc-parsed-type';\n\ntype JsonParsedStakeAccount = Readonly<{\n    meta: Readonly<{\n        authorized: Readonly<{\n            staker: Address;\n            withdrawer: Address;\n        }>;\n        lockup: Readonly<{\n            custodian: Address;\n            epoch: bigint;\n            unixTimestamp: UnixTimestamp;\n        }>;\n        rentExemptReserve: StringifiedBigInt;\n    }>;\n    stake: Readonly<{\n        creditsObserved: bigint;\n        delegation: Readonly<{\n            activationEpoch: StringifiedBigInt;\n            deactivationEpoch: StringifiedBigInt;\n            stake: StringifiedBigInt;\n            voter: Address;\n            warmupCooldownRate: number;\n        }>;\n    }> | null;\n}>;\n\nexport type JsonParsedStakeProgramAccount =\n    | RpcParsedType<'delegated', JsonParsedStakeAccount>\n    | RpcParsedType<'initialized', JsonParsedStakeAccount>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/sysvar-accounts.ts",
    "content": "import type { Blockhash, Epoch, Slot, StringifiedBigInt, UnixTimestamp } from '@solana/rpc-types';\n\nimport { RpcParsedType } from './rpc-parsed-type';\n\ntype FeeCalculator = Readonly<{\n    lamportsPerSignature: StringifiedBigInt;\n}>;\n\ntype JsonParsedClockAccount = Readonly<{\n    epoch: Epoch;\n    epochStartTimestamp: UnixTimestamp;\n    leaderScheduleEpoch: Epoch;\n    slot: Slot;\n    unixTimestamp: UnixTimestamp;\n}>;\n\ntype JsonParsedEpochScheduleAccount = Readonly<{\n    firstNormalEpoch: Epoch;\n    firstNormalSlot: Slot;\n    leaderScheduleSlotOffset: bigint;\n    slotsPerEpoch: bigint;\n    warmup: boolean;\n}>;\n\ntype JsonParsedFeesAccount_DEPRECATED = Readonly<{\n    feeCalculator: FeeCalculator;\n}>;\n\ntype JsonParsedRecentBlockhashesAccount_DEPRECATED = Readonly<{\n    blockhash: Blockhash;\n    feeCalculator: FeeCalculator;\n}>[];\n\ntype JsonParsedRentAccount = Readonly<{\n    burnPercent: number;\n    exemptionThreshold: number;\n    lamportsPerByteYear: StringifiedBigInt;\n}>;\n\ntype JsonParsedSlotHashesAccount = Readonly<{\n    hash: string;\n    slot: Slot;\n}>[];\n\ntype JsonParsedSlotHistoryAccount = Readonly<{\n    bits: string;\n    nextSlot: Slot;\n}>;\n\ntype JsonParsedStakeHistoryAccount = Readonly<{\n    epoch: Epoch;\n    stakeHistory: Readonly<{\n        activating: bigint;\n        deactivating: bigint;\n        effective: bigint;\n    }>;\n}>[];\n\ntype JsonParsedLastRestartSlotAccount = Readonly<{\n    lastRestartSlot: Slot;\n}>;\n\ntype JsonParsedEpochRewardsAccount = Readonly<{\n    distributedRewards: bigint;\n    distributionCompleteBlockHeight: bigint;\n    totalRewards: bigint;\n}>;\n\nexport type JsonParsedSysvarAccount =\n    | RpcParsedType<'clock', JsonParsedClockAccount>\n    | RpcParsedType<'epochRewards', JsonParsedEpochRewardsAccount>\n    | RpcParsedType<'epochSchedule', JsonParsedEpochScheduleAccount>\n    | RpcParsedType<'fees', JsonParsedFeesAccount_DEPRECATED>\n    | RpcParsedType<'lastRestartSlot', JsonParsedLastRestartSlotAccount>\n    | RpcParsedType<'recentBlockhashes', JsonParsedRecentBlockhashesAccount_DEPRECATED>\n    | RpcParsedType<'rent', JsonParsedRentAccount>\n    | RpcParsedType<'slotHashes', JsonParsedSlotHashesAccount>\n    | RpcParsedType<'slotHistory', JsonParsedSlotHistoryAccount>\n    | RpcParsedType<'stakeHistory', JsonParsedStakeHistoryAccount>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/token-accounts.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { StringifiedBigInt, TokenAmount } from '@solana/rpc-types';\n\nimport { RpcParsedType } from './rpc-parsed-type';\n\ntype TokenAccountState = 'frozen' | 'initialized' | 'uninitialized';\n\nexport type JsonParsedTokenAccount = Readonly<{\n    closeAuthority?: Address;\n    delegate?: Address;\n    delegatedAmount?: TokenAmount;\n    extensions?: readonly unknown[];\n    isNative: boolean;\n    mint: Address;\n    owner: Address;\n    rentExemptReserve?: TokenAmount;\n    state: TokenAccountState;\n    tokenAmount: TokenAmount;\n}>;\n\ntype JsonParsedMintAccount = Readonly<{\n    decimals: number;\n    extensions?: readonly unknown[];\n    freezeAuthority: Address | null;\n    isInitialized: boolean;\n    mintAuthority: Address | null;\n    supply: StringifiedBigInt;\n}>;\n\ntype JsonParsedMultisigAccount = Readonly<{\n    isInitialized: boolean;\n    numRequiredSigners: number;\n    numValidSigners: number;\n    signers: readonly Address[];\n}>;\n\nexport type JsonParsedTokenProgramAccount =\n    | RpcParsedType<'account', JsonParsedTokenAccount>\n    | RpcParsedType<'mint', JsonParsedMintAccount>\n    | RpcParsedType<'multisig', JsonParsedMultisigAccount>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/src/vote-accounts.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Epoch, Slot, StringifiedBigInt, UnixTimestamp } from '@solana/rpc-types';\n\nimport { RpcParsedInfo } from './rpc-parsed-type';\n\nexport type JsonParsedVoteAccount = RpcParsedInfo<{\n    authorizedVoters: Readonly<{\n        authorizedVoter: Address;\n        epoch: Epoch;\n    }>[];\n    authorizedWithdrawer: Address;\n    /** The address that collects block revenue (tips/MEV) */\n    blockRevenueCollector: Address;\n    /** Block revenue commission in basis points */\n    blockRevenueCommissionBps: bigint;\n    /** Compressed BLS public key, or `null` if not set */\n    blsPubkeyCompressed: string | null;\n    commission: number;\n    epochCredits: Readonly<{\n        credits: StringifiedBigInt;\n        epoch: Epoch;\n        previousCredits: StringifiedBigInt;\n    }>[];\n    /** The address that collects inflation rewards */\n    inflationRewardsCollector: Address;\n    /** Inflation rewards commission in basis points */\n    inflationRewardsCommissionBps: bigint;\n    lastTimestamp: Readonly<{\n        slot: Slot;\n        timestamp: UnixTimestamp;\n    }>;\n    nodePubkey: Address;\n    /** Pending delegator rewards */\n    pendingDelegatorRewards: StringifiedBigInt;\n    priorVoters: Readonly<{\n        authorizedPubkey: Address;\n        epochOfLastAuthorizedSwitch: Epoch;\n        targetEpoch: Epoch;\n    }>[];\n    rootSlot: Slot | null;\n    votes: Readonly<{\n        confirmationCount: number;\n        /** The latency of this vote, in slots */\n        latency: bigint;\n        slot: Slot;\n    }>[];\n}>;\n"
  },
  {
    "path": "packages/rpc-parsed-types/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"ES2015\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-types\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-parsed-types/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-spec/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-spec/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-spec/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-spec/CHANGELOG.md",
    "content": "# @solana/rpc-spec\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/rpc-spec-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n    - @solana/rpc-spec-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n    - @solana/rpc-spec-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/rpc-spec-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n    - @solana/rpc-spec-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.4.0\n    - @solana/rpc-spec-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n    - @solana/rpc-spec-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/rpc-spec-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/rpc-spec-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/rpc-spec-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.1\n    - @solana/rpc-spec-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.0\n    - @solana/rpc-spec-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/rpc-spec-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/rpc-spec-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/rpc-spec-types@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n    - @solana/rpc-spec-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n    - @solana/rpc-spec-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n    - @solana/rpc-spec-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/rpc-spec-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-spec-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`81c83b1`](https://github.com/anza-xyz/kit/commit/81c83b12dd0e145bf7d08182e01824f2f14e5ee5)]:\n    - @solana/errors@3.0.0\n    - @solana/rpc-spec-types@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- [#508](https://github.com/anza-xyz/kit/pull/508) [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677) Thanks [@calintje](https://github.com/calintje)! - Fix RPC objects incorrectly appearing as thenable Promises which caused silent program termination when awaited.\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/rpc-spec-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.1\n    - @solana/rpc-spec-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.0\n    - @solana/rpc-spec-types@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-spec-types@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n    - @solana/rpc-spec-types@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3221](https://github.com/solana-labs/solana-web3.js/pull/3221) [`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `isJsonRpcPayload` helper method\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3146](https://github.com/solana-labs/solana-web3.js/pull/3146) [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcRequest` type to `RpcApiRequestPlan` to make room for new `RpcRequest` type\n\n- [#3429](https://github.com/solana-labs/solana-web3.js/pull/3429) [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcApiRequestPlan` to `RpcPlan` to stay consistent with the `RpcSusbscriptionsPlan` of the RPC Subscription architecture.\n\n- [#3507](https://github.com/solana-labs/solana-web3.js/pull/3507) [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fixed a bug where the subcription server's response would not be detected, because of a mismatch in the format of the `id`. Now all RPC message ids are strings, for avoidance of doubt.\n\n- [#3393](https://github.com/solana-labs/solana-web3.js/pull/3393) [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Move RpcRequest and RpcResponse types to rpc-spec-types\n\n- [#3145](https://github.com/solana-labs/solana-web3.js/pull/3145) [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type\n\n- [#3213](https://github.com/solana-labs/solana-web3.js/pull/3213) [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcApi: no longer extend RpcApiMethods + remove export\n\n- [#3147](https://github.com/solana-labs/solana-web3.js/pull/3147) [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `RpcRequest` and `RpcResponse` types with `RpcRequestTransformer` and `RpcResponseTransformer` functions\n\n- [#2950](https://github.com/solana-labs/solana-web3.js/pull/2950) [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor rpc-spec to remove requirement for transports to implement parts of JSON RPC spec\n\n- [#3150](https://github.com/solana-labs/solana-web3.js/pull/3150) [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcApi` use new `RpcRequestTransformer` and `RpcResponseTransformer`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3432](https://github.com/solana-labs/solana-web3.js/pull/3432) [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Redesign the `RpcPlan` by using a plan executor function.\n\n    This change replaces the `payload` and `responseTransformer` attributes of the `RpcPlan` type (returned by the RPC API) in favour of a new `execute` function that accepts an `RpcTransport` and an optional `AbortSignal` and return an `RpcResponse`. That way, the RPC API is able to completely wrap the RPC Transport layer and can do things like: not calling the transport at all for caching purposes or calling the transport multiple times for retries or even for aggregating responses from multiple RPC calls.\n\n    See the following PRs for more details:\n    - [PR #3430](https://github.com/solana-labs/solana-web3.js/pull/3430)\n    - [PR #3431](https://github.com/solana-labs/solana-web3.js/pull/3431)\n\n- [#3229](https://github.com/solana-labs/solana-web3.js/pull/3229) [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make API plans return payloads\n\n- [#3148](https://github.com/solana-labs/solana-web3.js/pull/3148) [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcTransport` return new `RpcReponse` type instead of parsed JSON data\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#2751](https://github.com/solana-labs/solana-web3.js/pull/2751) [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow Rpc Request params to be any type, instead of requiring an array\n\n- [#3230](https://github.com/solana-labs/solana-web3.js/pull/3230) [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `createRpcApi` to `createJsonRpcApi`\n\n- [#3394](https://github.com/solana-labs/solana-web3.js/pull/3394) [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use RpcRequest in createRpcMessage helper\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/errors@2.0.0\n    - @solana/rpc-spec-types@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/rpc-spec-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- [#3507](https://github.com/solana-labs/solana-web3.js/pull/3507) [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fixed a bug where the subcription server's response would not be detected, because of a mismatch in the format of the `id`. Now all RPC message ids are strings, for avoidance of doubt.\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-spec-types@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3221](https://github.com/solana-labs/solana-web3.js/pull/3221) [`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `isJsonRpcPayload` helper method\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3146](https://github.com/solana-labs/solana-web3.js/pull/3146) [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcRequest` type to `RpcApiRequestPlan` to make room for new `RpcRequest` type\n\n- [#3429](https://github.com/solana-labs/solana-web3.js/pull/3429) [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcApiRequestPlan` to `RpcPlan` to stay consistent with the `RpcSusbscriptionsPlan` of the RPC Subscription architecture.\n\n- [#3393](https://github.com/solana-labs/solana-web3.js/pull/3393) [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Move RpcRequest and RpcResponse types to rpc-spec-types\n\n- [#3145](https://github.com/solana-labs/solana-web3.js/pull/3145) [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type\n\n- [#3213](https://github.com/solana-labs/solana-web3.js/pull/3213) [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcApi: no longer extend RpcApiMethods + remove export\n\n- [#3147](https://github.com/solana-labs/solana-web3.js/pull/3147) [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `RpcRequest` and `RpcResponse` types with `RpcRequestTransformer` and `RpcResponseTransformer` functions\n\n- [#3150](https://github.com/solana-labs/solana-web3.js/pull/3150) [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcApi` use new `RpcRequestTransformer` and `RpcResponseTransformer`\n\n- [#3432](https://github.com/solana-labs/solana-web3.js/pull/3432) [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Redesign the `RpcPlan` by using a plan executor function.\n\n    This change replaces the `payload` and `responseTransformer` attributes of the `RpcPlan` type (returned by the RPC API) in favour of a new `execute` function that accepts an `RpcTransport` and an optional `AbortSignal` and return an `RpcResponse`. That way, the RPC API is able to completely wrap the RPC Transport layer and can do things like: not calling the transport at all for caching purposes or calling the transport multiple times for retries or even for aggregating responses from multiple RPC calls.\n\n    See the following PRs for more details:\n    - [PR #3430](https://github.com/solana-labs/solana-web3.js/pull/3430)\n    - [PR #3431](https://github.com/solana-labs/solana-web3.js/pull/3431)\n\n- [#3229](https://github.com/solana-labs/solana-web3.js/pull/3229) [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make API plans return payloads\n\n- [#3148](https://github.com/solana-labs/solana-web3.js/pull/3148) [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcTransport` return new `RpcReponse` type instead of parsed JSON data\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3230](https://github.com/solana-labs/solana-web3.js/pull/3230) [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `createRpcApi` to `createJsonRpcApi`\n\n- [#3394](https://github.com/solana-labs/solana-web3.js/pull/3394) [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use RpcRequest in createRpcMessage helper\n\n- Updated dependencies [[`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/rpc-spec-types@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-spec-types@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2950](https://github.com/solana-labs/solana-web3.js/pull/2950) [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor rpc-spec to remove requirement for transports to implement parts of JSON RPC spec\n\n- Updated dependencies []:\n    - @solana/rpc-spec-types@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#2751](https://github.com/solana-labs/solana-web3.js/pull/2751) [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow Rpc Request params to be any type, instead of requiring an array\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-spec-types@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/rpc-spec-types@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n    - @solana/rpc-spec-types@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-spec/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-spec/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-spec?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-spec?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-spec\n\n# @solana/rpc-spec\n\nThis package contains types that describe the implementation of the JSON RPC API, as well as methods to create one. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nThis API is designed to be used as follows:\n\n```ts\nconst rpc =\n    // Step 1 - Create a `Rpc` instance. This may be stateful.\n    createSolanaRpc(mainnet('https://api.mainnet-beta.solana.com'));\nconst response = await rpc\n    // Step 2 - Call supported methods on it to produce `PendingRpcRequest` objects.\n    .getLatestBlockhash({ commitment: 'confirmed' })\n    // Step 3 - Call the `send()` method on those pending requests to trigger them.\n    .send({ abortSignal: AbortSignal.timeout(10_000) });\n```\n\n## Types\n\n### `PendingRpcRequest<TResponse>`\n\nPending requests are the result of calling a supported method on a `Rpc` object. They encapsulate all of the information necessary to make the request without actually making it.\n\nCalling the `send(options)` method on a `PendingRpcRequest<TResponse>` will trigger the request and return a promise for `TResponse`.\n\nCalling the `reactiveStore()` method fires the request immediately and synchronously returns a [`ReactiveActionStore`](https://github.com/anza-xyz/kit/tree/main/packages/subscribable) compatible with `useSyncExternalStore`, Svelte stores, and other reactive primitives. The store starts in `status: 'running'`, transitions to `success` or `error` when the request settles, and can be re-fired via `dispatch()` or cancelled via `reset()`.\n\n```ts\nconst store = rpc.getAccountInfo(address).reactiveStore();\nconst state = useSyncExternalStore(store.subscribe, store.getState);\nif (state.status === 'error') return <ErrorMessage error={state.error} onRetry={store.dispatch} />;\nif (state.status === 'running' && !state.data) return <Spinner />;\nreturn <View data={state.data!} />;\n```\n\n### `Rpc<TRpcMethods, TRpcTransport>`\n\nAn object that exposes all of the functions described by `TRpcMethods`. Calling each method returns a `PendingRpcRequest<TResponse>` where `TResponse` is that method's response type.\n\n### `RpcApi<TRpcMethods>`\n\nFor each of `TRpcMethods`, this object exposes a method with the same name that maps between its input arguments and a `RpcPlan<TResponse>` that implements the execution of a JSON RPC request to fetch `TResponse`.\n\n### `RpcPlan`\n\nThis type allows an `RpcApi` to describe how a particular request should be issued to the JSON RPC server. Given a function that was called on a `Rpc`, this object exposes an `execute` function that dictates which request will be sent, how the underlying transport will be used, and how the responses will be transformed.\n\nThis function accepts a `RpcTransport` and an `AbortSignal` and asynchronously returns a `RpcResponse`. This gives us the opportunity to:\n\n- define the `payload` from the requested method name and parameters before passing it to the transport.\n- call the underlying transport zero, one or multiple times depending on the use-case (e.g. caching or aggregating multiple responses).\n- transform the response from the JSON RPC server, in case it does not match the `TResponse` specified by the `PendingRpcRequest<TResponse>` returned from that function.\n\n### `RpcSendOptions`\n\nA configuration object consisting of the following properties:\n\n- `abortSignal`: An optional signal that you can supply when triggering a `PendingRpcRequest` that you might later need to abort.\n\n### `RpcTransport`\n\nAny function that implements this interface can act as a transport for a `Rpc`. It need only return a promise for a response given the following config:\n\n- `payload`: A value of arbitrary type to be sent.\n- `signal`: An optional `AbortSignal` on which the `'abort'` event will be fired if the request should be cancelled.\n\n## Functions\n\n### `createRpc(config)`\n\nCreates a `Rpc` instance given an `RpcApi<TRpcMethods>` and a `RpcTransport` capable of fulfilling them.\n\n#### Arguments\n\nA config object with the following properties:\n\n- `api`: An instance of `RpcApi`\n- `transport`: A function that implements the `RpcTransport` interface\n\n### `createJsonRpcApi(config)`\n\nCreates a JavaScript proxy that converts _any_ function call called on it to a `RpcPlan` by creating an `execute` function that:\n\n- sets the transport payload to a JSON RPC v2 payload object with the requested `methodName` and `params` properties, optionally transformed by `config.requestTransformer`.\n- transforms the transport's response using the `config.responseTransformer` function, if provided.\n\n```ts\n// For example, given this `RpcApi`:\nconst rpcApi = createJsonRpcApi({\n    requestTransformer: (...rawParams) => rawParams.reverse(),\n    responseTransformer: response => response.result,\n});\n\n// ...the following function call:\nrpcApi.foo('bar', { baz: 'bat' });\n\n// ...will produce an `RpcPlan` that:\n// -   Uses the following payload: { id: 1, jsonrpc: '2.0', method: 'foo', params: [{ baz: 'bat' }, 'bar'] }.\n// -   Returns the \"result\" property of the RPC response.\n```\n\n#### Arguments\n\nA config object with the following properties:\n\n- `requestTransformer<T>(request: RpcRequest<T>): RpcRequest`: An optional function that transforms the `RpcRequest` before it is sent to the JSON RPC server.\n- `responseTransformer<T>(response: RpcResponse, request: RpcRequest): RpcResponse<T>`: An optional function that transforms the `RpcResponse` before it is returned to the caller.\n\n### `isJsonRpcPayload(payload)`\n\nA helper function that returns `true` if the given payload is a JSON RPC v2 payload. This means, the payload is an object such that:\n\n- It has a `jsonrpc` property with a value of `'2.0'`.\n- It has a `method` property that is a string.\n- It has a `params` property of any type.\n\n```ts\nimport { isJsonRpcPayload } from '@solana/rpc-spec';\n\nif (isJsonRpcPayload(payload)) {\n    const payloadMethod: string = payload.method;\n    const payloadParams: unknown = payload.params;\n}\n```\n"
  },
  {
    "path": "packages/rpc-spec/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-spec\",\n    \"version\": \"6.9.0\",\n    \"description\": \"A generic implementation of JSON RPCs using proxies\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-spec\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/rpc-spec-types\": \"workspace:*\",\n        \"@solana/subscribable\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-spec/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-spec/src/__tests__/rpc-api-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport type { RpcRequest } from '@solana/rpc-spec-types';\n\nimport { createJsonRpcApi } from '../rpc-api';\nimport type { RpcTransport } from '../rpc-transport';\n\ntype DummyApi = {\n    someMethod(...args: unknown[]): unknown;\n};\n\ndescribe('createJsonRpcApi', () => {\n    let transport: jest.Mock & RpcTransport;\n    beforeEach(() => {\n        transport = jest.fn();\n    });\n    it('returns a plan containing a function to execute the plan', () => {\n        // Given a dummy API.\n        const api = createJsonRpcApi<DummyApi>();\n\n        // When we call a method on the API.\n        const plan = api.someMethod(1, 'two', { three: [4] });\n\n        // Then we expect the plan to contain an `execute` function.\n        expect(plan).toHaveProperty('execute');\n        expect(typeof plan.execute).toBe('function');\n    });\n    it('applies the request transformer to the provided method name', async () => {\n        expect.assertions(1);\n\n        // Given a dummy API with a request transformer that appends 'Transformed' to the method name.\n        const api = createJsonRpcApi<DummyApi>({\n            requestTransformer: (request: RpcRequest) => ({\n                ...request,\n                methodName: `${request.methodName}Transformed`,\n            }),\n        });\n\n        // When we call a method on the API.\n        const plan = api.someMethod();\n\n        // Then we expect the plan executor to pass the transformed method name to the transport.\n        await plan.execute({ transport });\n        expect(transport).toHaveBeenCalledWith(\n            expect.objectContaining({\n                payload: expect.objectContaining({\n                    method: 'someMethodTransformed',\n                }),\n            }),\n        );\n    });\n    it('applies the request transformer to the provided params', async () => {\n        expect.assertions(1);\n\n        // Given a dummy API with a request transformer that doubles the provided params.\n        const api = createJsonRpcApi<DummyApi>({\n            requestTransformer: (request: RpcRequest) => ({\n                ...request,\n                params: (request.params as number[]).map(x => x * 2),\n            }),\n        });\n\n        // When we call a method on the API.\n        const plan = api.someMethod(1, 2, 3);\n\n        // Then we expect the plan executor to pass the transformed params to the transport.\n        await plan.execute({ transport });\n        expect(transport).toHaveBeenCalledWith(\n            expect.objectContaining({\n                payload: expect.objectContaining({\n                    params: [2, 4, 6],\n                }),\n            }),\n        );\n    });\n    it(\"applies the response transformer to the transport's response\", async () => {\n        expect.assertions(1);\n\n        // Given a dummy API with a response transformer that doubles the response.\n        const responseTransformer = (response: unknown) => (response as number) * 2;\n        const api = createJsonRpcApi<DummyApi>({ responseTransformer });\n\n        // And given a transport that returns a mock response.\n        transport.mockResolvedValue(42);\n\n        // When we call a method on the API.\n        const plan = api.someMethod(1, 2, 3);\n\n        // Then we expect the plan to use the response transformer.\n        const response = await plan.execute({ transport });\n        expect(response).toBe(84);\n    });\n    it('returns a frozen object', () => {\n        // Given a dummy API.\n        const api = createJsonRpcApi<DummyApi>();\n\n        // When we call a method on the API.\n        const plan = api.someMethod();\n\n        // Then we expect the returned plan to be frozen.\n        expect(plan).toBeFrozenObject();\n    });\n    it('also returns a frozen object with a request transformer', () => {\n        // Given a dummy API with a request transformer.\n        const api = createJsonRpcApi<DummyApi>({\n            requestTransformer: (request: RpcRequest) => ({ ...request, methodName: 'transformed' }),\n        });\n\n        // When we call a method on the API.\n        const plan = api.someMethod();\n\n        // Then we expect the returned plan to be frozen.\n        expect(plan).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/rpc-spec/src/__tests__/rpc-test.ts",
    "content": "import { SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD, SolanaError } from '@solana/errors';\nimport { createRpcMessage } from '@solana/rpc-spec-types';\n\nimport { createRpc, Rpc } from '../rpc';\nimport { RpcApi, RpcPlan } from '../rpc-api';\nimport { RpcTransport } from '../rpc-transport';\n\ninterface TestRpcMethods {\n    someMethod(...args: unknown[]): unknown;\n}\n\ndescribe('JSON-RPC 2.0', () => {\n    let makeHttpRequest: RpcTransport;\n    beforeEach(() => {\n        makeHttpRequest = jest.fn(\n            () =>\n                new Promise(_ => {\n                    /* never resolve */\n                }),\n        );\n    });\n    describe('when no API plan is available for a method', () => {\n        let rpc: Rpc<TestRpcMethods>;\n        beforeEach(() => {\n            rpc = createRpc({\n                api: {} as RpcApi<TestRpcMethods>,\n                transport: makeHttpRequest,\n            });\n        });\n        it('throws an error', () => {\n            expect(() => rpc.someMethod('some', 'params', 123)).toThrow(\n                new SolanaError(SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD, {\n                    method: 'someMethod',\n                    params: ['some', 'params', 123],\n                }),\n            );\n        });\n    });\n    describe('when using a simple RPC API proxy', () => {\n        let rpc: Rpc<TestRpcMethods>;\n        beforeEach(() => {\n            rpc = createRpc({\n                api: new Proxy({} as RpcApi<TestRpcMethods>, {\n                    get(_, methodName) {\n                        return (...params: unknown[]): RpcPlan<TestRpcMethods> => ({\n                            execute: ({ signal, transport }) =>\n                                transport({\n                                    payload: createRpcMessage({ methodName: methodName.toString(), params }),\n                                    signal,\n                                }),\n                        });\n                    },\n                }),\n                transport: makeHttpRequest,\n            });\n        });\n        it('sends a request to the transport', () => {\n            rpc.someMethod(123)\n                .send()\n                .catch(() => {});\n            expect(makeHttpRequest).toHaveBeenCalledWith({\n                payload: { ...createRpcMessage({ methodName: 'someMethod', params: [123] }), id: expect.any(String) },\n            });\n        });\n        it('returns results from the transport', async () => {\n            expect.assertions(1);\n            (makeHttpRequest as jest.Mock).mockResolvedValueOnce(123);\n            const result = await rpc.someMethod().send();\n            expect(result).toBe(123);\n        });\n        it('throws errors from the transport', async () => {\n            expect.assertions(1);\n            const transportError = new Error('o no');\n            (makeHttpRequest as jest.Mock).mockRejectedValueOnce(transportError);\n            const sendPromise = rpc.someMethod().send();\n            await expect(sendPromise).rejects.toThrow(transportError);\n        });\n        it('should not be thenable', () => {\n            expect.assertions(1);\n            expect(rpc).not.toHaveProperty('then');\n        });\n    });\n    describe('when calling reactiveStore() on a pending request', () => {\n        let execute: jest.Mock;\n        let rpc: Rpc<TestRpcMethods>;\n        beforeEach(() => {\n            jest.useFakeTimers();\n            execute = jest.fn(\n                () =>\n                    new Promise(() => {\n                        /* never resolve */\n                    }),\n            );\n            rpc = createRpc({\n                api: new Proxy({} as RpcApi<TestRpcMethods>, {\n                    get() {\n                        return (..._params: unknown[]): RpcPlan<unknown> => ({ execute });\n                    },\n                }),\n                transport: makeHttpRequest,\n            });\n        });\n        afterEach(() => {\n            jest.useRealTimers();\n        });\n        it('fires the request on creation with a non-aborted signal', () => {\n            rpc.someMethod(123).reactiveStore();\n            expect(execute).toHaveBeenCalledTimes(1);\n            const { signal } = execute.mock.calls[0][0];\n            expect(signal).toBeInstanceOf(AbortSignal);\n            expect(signal.aborted).toBe(false);\n        });\n        it('forwards the transport to the plan on creation', () => {\n            rpc.someMethod(123).reactiveStore();\n            expect(execute).toHaveBeenCalledWith(expect.objectContaining({ transport: makeHttpRequest }));\n        });\n        it('returns a store synchronously in the `running` status', () => {\n            const store = rpc.someMethod(123).reactiveStore();\n            expect(store.getState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'running',\n            });\n        });\n        it('transitions to `success` with resolved data once the plan resolves', async () => {\n            expect.assertions(1);\n            const { promise, resolve } = Promise.withResolvers<number>();\n            execute.mockReturnValueOnce(promise);\n            const store = rpc.someMethod(123).reactiveStore();\n            resolve(42);\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toStrictEqual({\n                data: 42,\n                error: undefined,\n                status: 'success',\n            });\n        });\n        it('transitions to `error` when the plan rejects', async () => {\n            expect.assertions(1);\n            const { promise, reject } = Promise.withResolvers<number>();\n            execute.mockReturnValueOnce(promise);\n            const store = rpc.someMethod(123).reactiveStore();\n            const error = new Error('o no');\n            reject(error);\n            await jest.runAllTimersAsync();\n            expect(store.getState()).toStrictEqual({\n                data: undefined,\n                error,\n                status: 'error',\n            });\n        });\n        it('notifies subscribers when state changes', async () => {\n            expect.assertions(2);\n            const { promise, resolve } = Promise.withResolvers<number>();\n            execute.mockReturnValueOnce(promise);\n            const store = rpc.someMethod(123).reactiveStore();\n            const subscriberA = jest.fn();\n            const subscriberB = jest.fn();\n            store.subscribe(subscriberA);\n            store.subscribe(subscriberB);\n            resolve(42);\n            await jest.runAllTimersAsync();\n            expect(subscriberA).toHaveBeenCalledTimes(1);\n            expect(subscriberB).toHaveBeenCalledTimes(1);\n        });\n        it('re-fires the plan when dispatch() is called', async () => {\n            expect.assertions(1);\n            // request 1: rejects\n            execute.mockRejectedValueOnce(new Error('o no'));\n            const store = rpc.someMethod(123).reactiveStore();\n            await jest.runAllTimersAsync();\n            // request 2: resolves\n            execute.mockResolvedValueOnce(42);\n            store.dispatch();\n            await jest.runAllTimersAsync();\n            expect(execute).toHaveBeenCalledTimes(2);\n        });\n        it('aborts the in-flight signal and returns to idle when reset() is called', () => {\n            const store = rpc.someMethod(123).reactiveStore();\n            const { signal } = execute.mock.calls[0][0];\n            expect(signal.aborted).toBe(false);\n            store.reset();\n            expect(signal.aborted).toBe(true);\n            expect(store.getState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'idle',\n            });\n        });\n    });\n    describe('when calling a method having a concrete implementation', () => {\n        let rpc: Rpc<TestRpcMethods>;\n        beforeEach(() => {\n            rpc = createRpc({\n                api: {\n                    someMethod(...params: unknown[]): RpcPlan<unknown> {\n                        const payload = createRpcMessage({\n                            methodName: 'someMethodAugmented',\n                            params: [...params, 'augmented', 'params'],\n                        });\n                        return { execute: ({ signal, transport }) => transport({ payload, signal }) };\n                    },\n                } as RpcApi<TestRpcMethods>,\n                transport: makeHttpRequest,\n            });\n        });\n        it('converts the returned request to a JSON-RPC 2.0 message and sends it to the transport', () => {\n            rpc.someMethod(123)\n                .send()\n                .catch(() => {});\n            expect(makeHttpRequest).toHaveBeenCalledWith({\n                payload: {\n                    ...createRpcMessage({ methodName: 'someMethodAugmented', params: [123, 'augmented', 'params'] }),\n                    id: expect.any(String),\n                },\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-spec/src/__tests__/rpc-transport-test.ts",
    "content": "import { isJsonRpcPayload } from '../rpc-transport';\n\ndescribe('isJsonRpcPayload', () => {\n    it('recognizes JSON RPC payloads', () => {\n        expect(isJsonRpcPayload({ jsonrpc: '2.0', method: 'getFoo', params: [123] })).toBe(true);\n    });\n    it('returns false if the payload is not an object', () => {\n        expect(isJsonRpcPayload(undefined)).toBe(false);\n        expect(isJsonRpcPayload(null)).toBe(false);\n        expect(isJsonRpcPayload(true)).toBe(false);\n        expect(isJsonRpcPayload(false)).toBe(false);\n        expect(isJsonRpcPayload([])).toBe(false);\n        expect(isJsonRpcPayload('o hai')).toBe(false);\n        expect(isJsonRpcPayload(123)).toBe(false);\n        expect(isJsonRpcPayload(123n)).toBe(false);\n    });\n    it('returns false if the payload is an empty object', () => {\n        expect(isJsonRpcPayload({})).toBe(false);\n    });\n    it('returns false if the payload is not a JSON RPC v2', () => {\n        expect(isJsonRpcPayload({ jsonrpc: '42.0', method: 'getFoo', params: [123] })).toBe(false);\n    });\n    it('returns false if the method name is missing', () => {\n        expect(isJsonRpcPayload({ jsonrpc: '2.0', params: [123] })).toBe(false);\n    });\n    it('returns false if the parameters are missing', () => {\n        expect(isJsonRpcPayload({ jsonrpc: '2.0', method: 'getFoo' })).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/rpc-spec/src/__typetests__/rpc-api-typetest.ts",
    "content": "import { createJsonRpcApi, RpcApi } from '../rpc-api';\n\ntype NftCollectionDetailsApiResponse = Readonly<{\n    address: string;\n    circulatingSupply: number;\n    description: string;\n    erc1155: boolean;\n    erc721: boolean;\n    genesisBlock: string;\n    genesisTransaction: string;\n    name: string;\n    totalSupply: number;\n}>;\n\ntype NftCollectionDetailsApi = {\n    qn_fetchNFTCollectionDetails(args: { contracts: string[] }): NftCollectionDetailsApiResponse;\n};\n\ntype QuickNodeRpcMethods = NftCollectionDetailsApi;\n\ncreateJsonRpcApi<QuickNodeRpcMethods>() satisfies RpcApi<QuickNodeRpcMethods>;\n"
  },
  {
    "path": "packages/rpc-spec/src/__typetests__/rpc-transport-typetest.ts",
    "content": "import { isJsonRpcPayload } from '../rpc-transport';\n\n{\n    // [isJsonRpcPayload]: It narrows the type of the payload to a JSON RPC payload.\n    const payload = {} as unknown;\n    if (isJsonRpcPayload(payload)) {\n        payload satisfies { jsonrpc: '2.0'; method: string; params: unknown };\n    }\n}\n"
  },
  {
    "path": "packages/rpc-spec/src/__typetests__/rpc-typetest.ts",
    "content": "import { createRpc, Rpc } from '../rpc';\nimport { createJsonRpcApi } from '../rpc-api';\nimport { RpcTransport } from '../rpc-transport';\n\ntype MyApiMethods = {\n    bar(): string;\n    foo(): number;\n};\n\nconst api = createJsonRpcApi<MyApiMethods>();\nconst transport = null as unknown as RpcTransport;\n\ncreateRpc({ api, transport }) satisfies Rpc<MyApiMethods>;\n"
  },
  {
    "path": "packages/rpc-spec/src/index.ts",
    "content": "/**\n * This package contains types that describe the implementation of the JSON RPC API, as well as\n * methods to create one. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * This API is designed to be used as follows:\n *\n * ```ts\n * const rpc =\n *     // Step 1 - Create a `Rpc` instance. This may be stateful.\n *     createSolanaRpc(mainnet('https://api.mainnet-beta.solana.com'));\n * const response = await rpc\n *     // Step 2 - Call supported methods on it to produce `PendingRpcRequest` objects.\n *     .getLatestBlockhash({ commitment: 'confirmed' })\n *     // Step 3 - Call the `send()` method on those pending requests to trigger them.\n *     .send({ abortSignal: AbortSignal.timeout(10_000) });\n * ```\n *\n * @packageDocumentation\n */\nexport * from './rpc';\nexport * from './rpc-api';\nexport * from './rpc-transport';\n"
  },
  {
    "path": "packages/rpc-spec/src/rpc-api.ts",
    "content": "import {\n    Callable,\n    createRpcMessage,\n    RpcRequestTransformer,\n    RpcResponse,\n    RpcResponseTransformer,\n} from '@solana/rpc-spec-types';\n\nimport type { RpcTransport } from './rpc-transport';\n\nexport type RpcApiConfig = Readonly<{\n    /**\n     * An optional function that transforms the {@link RpcRequest} before it is sent to the JSON RPC\n     * server.\n     *\n     * This is useful when the params supplied by the caller need to be transformed before\n     * forwarding the message to the server. Use cases for this include applying defaults,\n     * forwarding calls to renamed methods, and serializing complex values.\n     */\n    requestTransformer?: RpcRequestTransformer;\n    /**\n     * An optional function that transforms the {@link RpcResponse} before it is returned to the\n     * caller.\n     *\n     * Use cases for this include constructing complex data types from serialized data, and throwing\n     * exceptions.\n     */\n    responseTransformer?: RpcResponseTransformer;\n}>;\n\n/**\n * This type allows an {@link RpcApi} to describe how a particular request should be issued to the\n * JSON RPC server.\n *\n * Given a function that was called on a {@link Rpc}, this object exposes an `execute` function that\n * dictates which request will be sent, how the underlying transport will be used, and how the\n * responses will be transformed.\n *\n * This function accepts a {@link RpcTransport} and an `AbortSignal` and asynchronously returns a\n * {@link RpcResponse}. This gives us the opportunity to:\n *\n * - define the `payload` from the requested method name and parameters before passing it to the\n *   transport.\n * - call the underlying transport zero, one or multiple times depending on the use-case (e.g.\n *   caching or aggregating multiple responses).\n * - transform the response from the JSON RPC server, in case it does not match the `TResponse`\n *   specified by the {@link PendingRpcRequest | PendingRpcRequest<TResponse>} returned from that\n *   function.\n */\nexport type RpcPlan<TResponse> = {\n    execute: (\n        config: Readonly<{\n            signal?: AbortSignal;\n            transport: RpcTransport;\n        }>,\n    ) => Promise<RpcResponse<TResponse>>;\n};\n\n/**\n * For each of `TRpcMethods`, this object exposes a method with the same name that maps between its\n * input arguments and a {@link RpcPlan | RpcPlan<TResponse>} that implements the execution of a\n * JSON RPC request to fetch `TResponse`.\n */\nexport type RpcApi<TRpcMethods> = {\n    [MethodName in keyof TRpcMethods]: RpcReturnTypeMapper<TRpcMethods[MethodName]>;\n};\n\ntype RpcReturnTypeMapper<TRpcMethod> = TRpcMethod extends Callable\n    ? (...rawParams: unknown[]) => RpcPlan<ReturnType<TRpcMethod>>\n    : never;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype RpcApiMethod = (...args: any) => any;\ninterface RpcApiMethods {\n    [methodName: string]: RpcApiMethod;\n}\n\n/**\n * Creates a JavaScript proxy that converts _any_ function call called on it to a {@link RpcPlan} by\n * creating an `execute` function that:\n *\n * - sets the transport payload to a JSON RPC v2 payload object with the requested `methodName` and\n *   `params` properties, optionally transformed by {@link RpcApiConfig.requestTransformer}.\n * - transforms the transport's response using the {@link RpcApiConfig.responseTransformer}\n *   function, if provided.\n *\n * @example\n * ```ts\n * // For example, given this `RpcApi`:\n * const rpcApi = createJsonRpcApi({\n *     requestTransformer: (...rawParams) => rawParams.reverse(),\n *     responseTransformer: response => response.result,\n * });\n *\n * // ...the following function call:\n * rpcApi.foo('bar', { baz: 'bat' });\n *\n * // ...will produce a `RpcPlan` that:\n * // -   Uses the following payload: { id: 1, jsonrpc: '2.0', method: 'foo', params: [{ baz: 'bat' }, 'bar'] }.\n * // -   Returns the \"result\" property of the RPC response.\n * ```\n */\nexport function createJsonRpcApi<TRpcMethods extends RpcApiMethods>(config?: RpcApiConfig): RpcApi<TRpcMethods> {\n    return new Proxy({} as RpcApi<TRpcMethods>, {\n        defineProperty() {\n            return false;\n        },\n        deleteProperty() {\n            return false;\n        },\n        get<TMethodName extends keyof RpcApi<TRpcMethods>>(\n            ...args: Parameters<NonNullable<ProxyHandler<RpcApi<TRpcMethods>>['get']>>\n        ) {\n            const [_, p] = args;\n            const methodName = p.toString() as keyof TRpcMethods as string;\n            return function (\n                ...rawParams: Parameters<\n                    TRpcMethods[TMethodName] extends CallableFunction ? TRpcMethods[TMethodName] : never\n                >\n            ): RpcPlan<ReturnType<TRpcMethods[TMethodName]>> {\n                const rawRequest = Object.freeze({ methodName, params: rawParams });\n                const request = config?.requestTransformer ? config?.requestTransformer(rawRequest) : rawRequest;\n                return Object.freeze(<RpcPlan<ReturnType<TRpcMethods[TMethodName]>>>{\n                    execute: async ({ signal, transport }) => {\n                        const payload = createRpcMessage(request);\n                        const response = await transport({ payload, signal });\n                        if (!config?.responseTransformer) {\n                            return response;\n                        }\n                        return config.responseTransformer(response, request);\n                    },\n                });\n            };\n        },\n    });\n}\n"
  },
  {
    "path": "packages/rpc-spec/src/rpc-transport.ts",
    "content": "import { RpcResponse } from '@solana/rpc-spec-types';\n\ntype Config = Readonly<{\n    /** A value of arbitrary type to be sent to a RPC server */\n    payload: unknown;\n    /**\n     * An optional `AbortSignal` on which the `'abort'` event will be fired if the request should be\n     * cancelled.\n     */\n    signal?: AbortSignal;\n}>;\n\n/**\n * A function that can act as a transport for a {@link Rpc}. It need only return a promise for a\n * response given the supplied config.\n */\nexport type RpcTransport = {\n    <TResponse>(config: Config): Promise<RpcResponse<TResponse>>;\n};\n\n/**\n * Returns `true` if the given payload is a JSON RPC v2 payload.\n *\n * This means, the payload is an object such that:\n *\n * - It has a `jsonrpc` property with a value of `'2.0'`.\n * - It has a `method` property that is a string.\n * - It has a `params` property of any type.\n *\n * @example\n * ```ts\n * import { isJsonRpcPayload } from '@solana/rpc-spec';\n *\n * if (isJsonRpcPayload(payload)) {\n *     const payloadMethod: string = payload.method;\n *     const payloadParams: unknown = payload.params;\n * }\n * ```\n */\nexport function isJsonRpcPayload(payload: unknown): payload is Readonly<{\n    jsonrpc: '2.0';\n    method: string;\n    params: unknown;\n}> {\n    if (payload == null || typeof payload !== 'object' || Array.isArray(payload)) {\n        return false;\n    }\n    return (\n        'jsonrpc' in payload &&\n        payload.jsonrpc === '2.0' &&\n        'method' in payload &&\n        typeof payload.method === 'string' &&\n        'params' in payload\n    );\n}\n"
  },
  {
    "path": "packages/rpc-spec/src/rpc.ts",
    "content": "import { SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD, SolanaError } from '@solana/errors';\nimport { Callable, Flatten, OverloadImplementations, UnionToIntersection } from '@solana/rpc-spec-types';\nimport { createReactiveActionStore, ReactiveActionStore } from '@solana/subscribable';\n\nimport { RpcApi, RpcPlan } from './rpc-api';\nimport { RpcTransport } from './rpc-transport';\n\nexport type RpcConfig<TRpcMethods, TRpcTransport extends RpcTransport> = Readonly<{\n    api: RpcApi<TRpcMethods>;\n    transport: TRpcTransport;\n}>;\n\n/**\n * An object that exposes all of the functions described by `TRpcMethods`.\n *\n * Calling each method returns a {@link PendingRpcRequest | PendingRpcRequest<TResponse>} where\n * `TResponse` is that method's response type.\n */\nexport type Rpc<TRpcMethods> = {\n    [TMethodName in keyof TRpcMethods]: PendingRpcRequestBuilder<OverloadImplementations<TRpcMethods, TMethodName>>;\n};\n\n/**\n * Pending requests are the result of calling a supported method on a {@link Rpc} object. They\n * encapsulate all of the information necessary to make the request without actually making it.\n *\n * Calling the {@link PendingRpcRequest.send | `send(options)`} method on a\n * {@link PendingRpcRequest | PendingRpcRequest<TResponse>} will trigger the request and return a\n * promise for `TResponse`.\n *\n * Calling the {@link PendingRpcRequest.reactiveStore | `reactiveStore()`} method will fire the\n * request and return a {@link ReactiveActionStore} compatible with `useSyncExternalStore`, Svelte\n * stores, and other reactive primitives.\n */\nexport type PendingRpcRequest<TResponse> = {\n    /**\n     * Synchronously returns a {@link ReactiveActionStore} that fires the request on construction\n     * and holds its lifecycle state. Compatible with `useSyncExternalStore` and other reactive\n     * primitives that expect a `{ subscribe, getState }` contract. Call `dispatch()` to re-fire the\n     * request (for example after an error), or `reset()` to abort the in-flight call and return to\n     * `status: 'idle'`.\n     *\n     * @example\n     * ```ts\n     * const store = rpc.getAccountInfo(address).reactiveStore();\n     * const state = useSyncExternalStore(store.subscribe, store.getState);\n     * if (state.status === 'error') return <ErrorMessage error={state.error} onRetry={store.dispatch} />;\n     * if (state.status === 'running' && !state.data) return <Spinner />;\n     * return <View data={state.data!} />;\n     * ```\n     */\n    reactiveStore(): ReactiveActionStore<[], TResponse>;\n    send(options?: RpcSendOptions): Promise<TResponse>;\n};\n\nexport type RpcSendOptions = Readonly<{\n    /**\n     * An optional signal that you can supply when triggering a {@link PendingRpcRequest} that you\n     * might later need to abort.\n     */\n    abortSignal?: AbortSignal;\n}>;\n\ntype PendingRpcRequestBuilder<TMethodImplementations> = UnionToIntersection<\n    Flatten<{\n        [P in keyof TMethodImplementations]: PendingRpcRequestReturnTypeMapper<TMethodImplementations[P]>;\n    }>\n>;\n\ntype PendingRpcRequestReturnTypeMapper<TMethodImplementation> =\n    // Check that this property of the TRpcMethods interface is, in fact, a function.\n    TMethodImplementation extends Callable\n        ? (...args: Parameters<TMethodImplementation>) => PendingRpcRequest<ReturnType<TMethodImplementation>>\n        : never;\n\n/**\n * Creates a {@link Rpc} instance given a {@link RpcApi | RpcApi<TRpcMethods>} and a\n * {@link RpcTransport} capable of fulfilling them.\n */\nexport function createRpc<TRpcMethods, TRpcTransport extends RpcTransport>(\n    rpcConfig: RpcConfig<TRpcMethods, TRpcTransport>,\n): Rpc<TRpcMethods> {\n    return makeProxy(rpcConfig);\n}\n\nfunction makeProxy<TRpcMethods, TRpcTransport extends RpcTransport>(\n    rpcConfig: RpcConfig<TRpcMethods, TRpcTransport>,\n): Rpc<TRpcMethods> {\n    return new Proxy(rpcConfig.api, {\n        defineProperty() {\n            return false;\n        },\n        deleteProperty() {\n            return false;\n        },\n        get(target, p, receiver) {\n            if (p === 'then') {\n                return undefined;\n            }\n            return function (...rawParams: unknown[]) {\n                const methodName = p.toString();\n                const getApiPlan = Reflect.get(target, methodName, receiver);\n                if (!getApiPlan) {\n                    throw new SolanaError(SOLANA_ERROR__RPC__API_PLAN_MISSING_FOR_RPC_METHOD, {\n                        method: methodName,\n                        params: rawParams,\n                    });\n                }\n                const apiPlan = getApiPlan(...rawParams);\n                return createPendingRpcRequest(rpcConfig, apiPlan);\n            };\n        },\n    }) as Rpc<TRpcMethods>;\n}\n\nfunction createPendingRpcRequest<TRpcMethods, TRpcTransport extends RpcTransport, TResponse>(\n    { transport }: RpcConfig<TRpcMethods, TRpcTransport>,\n    plan: RpcPlan<TResponse>,\n): PendingRpcRequest<TResponse> {\n    return {\n        reactiveStore(): ReactiveActionStore<[], TResponse> {\n            const store = createReactiveActionStore<[], TResponse>(signal => plan.execute({ signal, transport }));\n            store.dispatch();\n            return store;\n        },\n        async send(options?: RpcSendOptions): Promise<TResponse> {\n            return await plan.execute({ signal: options?.abortSignal, transport });\n        },\n    };\n}\n"
  },
  {
    "path": "packages/rpc-spec/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-spec/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\", \"ES2024.Promise\"]\n    },\n    \"display\": \"@solana/rpc-spec\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-spec/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-spec-types/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-spec-types/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-spec-types/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-spec-types/CHANGELOG.md",
    "content": "# @solana/rpc-spec-types\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n## 6.6.0\n\n## 6.5.0\n\n## 6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n## 6.1.0\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n## 5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n## 5.3.0\n\n## 5.2.0\n\n## 5.1.0\n\n## 5.0.0\n\n## 4.0.0\n\n## 3.0.0\n\n### Major Changes\n\n- [#732](https://github.com/anza-xyz/kit/pull/732) [`81c83b1`](https://github.com/anza-xyz/kit/commit/81c83b12dd0e145bf7d08182e01824f2f14e5ee5) Thanks [@nonergodic](https://github.com/nonergodic)! - BREAKING CHANGE: Rename `stringifyJsonWithBigints` to `stringifyJsonWithBigInts` for consistency with the rest of the API.\n\n## 2.3.0\n\n## 2.2.1\n\n## 2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n## 2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3507](https://github.com/solana-labs/solana-web3.js/pull/3507) [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fixed a bug where the subcription server's response would not be detected, because of a mismatch in the format of the `id`. Now all RPC message ids are strings, for avoidance of doubt.\n\n- [#3393](https://github.com/solana-labs/solana-web3.js/pull/3393) [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Move RpcRequest and RpcResponse types to rpc-spec-types\n\n- [#3145](https://github.com/solana-labs/solana-web3.js/pull/3145) [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3394](https://github.com/solana-labs/solana-web3.js/pull/3394) [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use RpcRequest in createRpcMessage helper\n\n## 2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- [#3507](https://github.com/solana-labs/solana-web3.js/pull/3507) [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fixed a bug where the subcription server's response would not be detected, because of a mismatch in the format of the `id`. Now all RPC message ids are strings, for avoidance of doubt.\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3393](https://github.com/solana-labs/solana-web3.js/pull/3393) [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Move RpcRequest and RpcResponse types to rpc-spec-types\n\n- [#3145](https://github.com/solana-labs/solana-web3.js/pull/3145) [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3394](https://github.com/solana-labs/solana-web3.js/pull/3394) [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use RpcRequest in createRpcMessage helper\n\n## 2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n## 2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n"
  },
  {
    "path": "packages/rpc-spec-types/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-spec-types/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-spec-types?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-spec-types?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-spec-types\n\n# @solana/rpc-spec-types\n\nThis package contains core types that can be used on both RPC and RPC Subscriptions specifications. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Types\n\n### `RpcRequest`\n\nAn object that describes the elements of a RPC or RPC Subscriptions request. It consists of the following properties:\n\n- `methodName`: The name of the RPC method or subscription requested.\n- `params`: The parameters to be passed to the RPC server.\n\n### `RpcRequestTransformer`\n\nA function that accepts a `RpcRequest` and returns another `RpcRequest`. This allows the `RpcApi` to transform the request before it is sent to the RPC server.\n\n### `RpcResponse`\n\nA type that represents the response from a RPC server. This could be any sort of data which is why `RpcResponse` defaults to `unknown`. You may use a type parameter to specify the shape of the response — e.g. `RpcResponse<{ result: number }>`.\n\n### `RpcResponseTransformer`\n\nA function that accepts a `RpcResponse` and returns another `RpcResponse`. This allows the `RpcApi` to transform the response before it is returned to the caller.\n"
  },
  {
    "path": "packages/rpc-spec-types/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-spec-types\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Shared generic JSON RPC specifications\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-spec-types\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-spec-types/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-spec-types/src/__tests__/large-json-file.json",
    "content": "[\n    {\n        \"_id\": \"66c71d2bd28af9a3c7f1a766\",\n        \"index\": 0,\n        \"guid\": \"b6465798-e542-4eb0-a5c1-59e3933290ee\",\n        \"isActive\": false,\n        \"balance\": \"$1,274.63\",\n        \"lamports\": 142302234983644260,\n        \"picture\": \"http://placehold.it/32x32\",\n        \"age\": 29,\n        \"eyeColor\": \"blue\",\n        \"name\": \"Collier Carson\",\n        \"gender\": \"male\",\n        \"company\": \"NAMEBOX\",\n        \"email\": \"colliercarson@namebox.com\",\n        \"phone\": \"+1 (888) 428-2044\",\n        \"address\": \"826 Irving Place, Colton, Illinois, 4908\",\n        \"about\": \"Consectetur reprehenderit aliqua eu esse voluptate cupidatat sint anim ex ipsum pariatur eu laborum. Mollit exercitation excepteur consectetur exercitation. Duis non incididunt pariatur consectetur tempor esse nulla aute ad. Ut exercitation tempor duis mollit. Mollit labore sint non est cillum. In esse ullamco fugiat velit est amet ad laboris occaecat officia nisi.\",\n        \"registered\": \"2024-01-12T05:09:11 -00:00\",\n        \"latitude\": 49.638368,\n        \"longitude\": -113.827497,\n        \"tags\": [\"qui\", \"excepteur\", \"aliquip\", \"amet\", \"ipsum\", \"labore\", \"officia\"],\n        \"friends\": [\n            { \"id\": 0, \"name\": \"Jeannette Galloway\" },\n            { \"id\": 1, \"name\": \"Gordon Murray\" },\n            { \"id\": 2, \"name\": \"Randolph Sullivan\" }\n        ]\n    },\n    {\n        \"_id\": \"66c71d2b0a5ca9a164428ff8\",\n        \"index\": 1,\n        \"guid\": \"dafaa74b-5fa0-4181-9ba7-371aea1188a2\",\n        \"isActive\": false,\n        \"balance\": \"$2,863.05\",\n        \"lamports\": 142302234983644260,\n        \"picture\": \"http://placehold.it/32x32\",\n        \"age\": 38,\n        \"eyeColor\": \"green\",\n        \"name\": \"Shields Fischer\",\n        \"gender\": \"male\",\n        \"company\": \"RONELON\",\n        \"email\": \"shieldsfischer@ronelon.com\",\n        \"phone\": \"+1 (988) 401-2468\",\n        \"address\": \"431 Norman Avenue, Innsbrook, New Mexico, 5118\",\n        \"about\": \"Magna velit tempor est sint elit commodo mollit mollit exercitation reprehenderit id in ullamco quis. Sint reprehenderit minim voluptate culpa fugiat et aliqua enim ipsum. Nostrud magna dolore excepteur occaecat non ex sint eiusmod. Occaecat deserunt labore nostrud veniam adipisicing ullamco esse. Aliqua sunt nostrud proident veniam cupidatat voluptate enim ipsum. Dolore consequat anim eiusmod laboris sunt pariatur anim fugiat sunt velit quis officia. Enim dolore laborum commodo eiusmod nisi nisi.\",\n        \"registered\": \"2019-11-17T03:40:22 -00:00\",\n        \"latitude\": 11.324387,\n        \"longitude\": -80.832796,\n        \"tags\": [\"eu\", \"voluptate\", \"id\", \"id\", \"dolor\", \"nostrud\", \"nulla\"],\n        \"friends\": [\n            { \"id\": 0, \"name\": \"Vilma Fox\" },\n            { \"id\": 1, \"name\": \"Concetta Ross\" },\n            { \"id\": 2, \"name\": \"Wilkins Howe\" }\n        ]\n    },\n    {\n        \"_id\": \"66c71d2bcdba189600f87199\",\n        \"index\": 2,\n        \"guid\": \"06835d94-0a4f-4e89-b889-798c59918fad\",\n        \"isActive\": true,\n        \"balance\": \"$2,307.46\",\n        \"lamports\": 142302234983644260,\n        \"picture\": \"http://placehold.it/32x32\",\n        \"age\": 33,\n        \"eyeColor\": \"green\",\n        \"name\": \"Penelope Cabrera\",\n        \"gender\": \"female\",\n        \"company\": \"GLUKGLUK\",\n        \"email\": \"penelopecabrera@glukgluk.com\",\n        \"phone\": \"+1 (884) 419-2242\",\n        \"address\": \"743 Dooley Street, Jessie, Palau, 8602\",\n        \"about\": \"Culpa ut veniam reprehenderit do. Sunt ut excepteur cillum laboris esse occaecat officia amet et duis nostrud excepteur. Incididunt reprehenderit ullamco incididunt velit incididunt esse officia eu dolor irure nostrud eiusmod ut quis. Irure mollit consequat sunt commodo non exercitation. Aliquip labore aute sunt deserunt ullamco proident est esse. Minim velit voluptate consequat voluptate dolore. Eu commodo Lorem sint aliquip amet do do ad culpa Lorem nulla anim quis.\",\n        \"registered\": \"2019-10-10T10:38:26 -01:00\",\n        \"latitude\": 34.456814,\n        \"longitude\": 60.745321,\n        \"tags\": [\"est\", \"qui\", \"cupidatat\", \"excepteur\", \"ut\", \"ad\", \"veniam\"],\n        \"friends\": [\n            { \"id\": 0, \"name\": \"Elizabeth Huber\" },\n            { \"id\": 1, \"name\": \"Sally Robbins\" },\n            { \"id\": 2, \"name\": \"Daisy Hunt\" }\n        ]\n    },\n    {\n        \"_id\": \"66c71d2bf99c62818eb44055\",\n        \"index\": 3,\n        \"guid\": \"c496d7cc-eaf8-4b86-ab12-bb9fd9946d21\",\n        \"isActive\": false,\n        \"balance\": \"$1,885.35\",\n        \"lamports\": 142302234983644260,\n        \"picture\": \"http://placehold.it/32x32\",\n        \"age\": 30,\n        \"eyeColor\": \"blue\",\n        \"name\": \"Mae Fulton\",\n        \"gender\": \"female\",\n        \"company\": \"COREPAN\",\n        \"email\": \"maefulton@corepan.com\",\n        \"phone\": \"+1 (898) 433-2640\",\n        \"address\": \"494 Greene Avenue, Dyckesville, South Carolina, 4544\",\n        \"about\": \"Id commodo quis sint sint voluptate culpa deserunt ad anim sint reprehenderit. Proident occaecat non et dolore magna aliquip ut adipisicing enim officia aliquip consequat. Ullamco reprehenderit cupidatat in est proident aliquip minim sint elit eu magna irure velit.\",\n        \"registered\": \"2022-12-24T04:14:42 -00:00\",\n        \"latitude\": -78.635799,\n        \"longitude\": 53.578193,\n        \"tags\": [\"minim\", \"eu\", \"sint\", \"culpa\", \"consequat\", \"ullamco\", \"exercitation\"],\n        \"friends\": [\n            { \"id\": 0, \"name\": \"Patrick Middleton\" },\n            { \"id\": 1, \"name\": \"Buchanan Patton\" },\n            { \"id\": 2, \"name\": \"Marilyn Cash\" }\n        ]\n    },\n    {\n        \"_id\": \"66c71d2b17723c12ff35509a\",\n        \"index\": 4,\n        \"guid\": \"892f741f-39a6-4157-8deb-3fa5cb7c89ac\",\n        \"isActive\": false,\n        \"balance\": \"$1,720.04\",\n        \"lamports\": 142302234983644260,\n        \"picture\": \"http://placehold.it/32x32\",\n        \"age\": 29,\n        \"eyeColor\": \"blue\",\n        \"name\": \"Nell Newton\",\n        \"gender\": \"female\",\n        \"company\": \"ASIMILINE\",\n        \"email\": \"nellnewton@asimiline.com\",\n        \"phone\": \"+1 (973) 445-2478\",\n        \"address\": \"494 Elton Street, Alafaya, Arizona, 1347\",\n        \"about\": \"Aliquip consectetur dolor pariatur qui. Enim consequat adipisicing aliqua Lorem amet consectetur irure est laborum ipsum. Magna exercitation excepteur incididunt cupidatat aliquip do tempor non. Et mollit quis quis tempor enim cillum id fugiat. Nisi eiusmod cillum reprehenderit in eiusmod labore est fugiat et officia.\",\n        \"registered\": \"2014-06-19T08:01:53 -01:00\",\n        \"latitude\": 59.571221,\n        \"longitude\": -78.053459,\n        \"tags\": [\"fugiat\", \"deserunt\", \"laborum\", \"eu\", \"sit\", \"ex\", \"dolor\"],\n        \"friends\": [\n            { \"id\": 0, \"name\": \"Cheryl Harding\" },\n            { \"id\": 1, \"name\": \"Laurie Logan\" },\n            { \"id\": 2, \"name\": \"Johns Moody\" }\n        ]\n    },\n    {\n        \"_id\": \"66c71d2b5ee698e22b8e9925\",\n        \"index\": 5,\n        \"guid\": \"ba974954-e9e1-4d8c-8847-3f28e3a6175b\",\n        \"isActive\": false,\n        \"balance\": \"$3,203.47\",\n        \"lamports\": 142302234983644260,\n        \"picture\": \"http://placehold.it/32x32\",\n        \"age\": 22,\n        \"eyeColor\": \"blue\",\n        \"name\": \"Albert Harmon\",\n        \"gender\": \"male\",\n        \"company\": \"EXOBLUE\",\n        \"email\": \"albertharmon@exoblue.com\",\n        \"phone\": \"+1 (954) 439-3813\",\n        \"address\": \"313 Fountain Avenue, Beason, Rhode Island, 9738\",\n        \"about\": \"Dolor excepteur nisi ut aliqua occaecat non ipsum irure id eu proident duis nulla. Ex dolor do excepteur aliqua officia consectetur ea reprehenderit occaecat sit qui aliquip aute. Occaecat proident cillum in ullamco nostrud laboris nisi excepteur. Incididunt velit cupidatat veniam fugiat.\",\n        \"registered\": \"2016-11-18T08:07:12 -00:00\",\n        \"latitude\": 42.687475,\n        \"longitude\": 39.897468,\n        \"tags\": [\"minim\", \"in\", \"adipisicing\", \"officia\", \"culpa\", \"in\", \"do\"],\n        \"friends\": [\n            { \"id\": 0, \"name\": \"Macdonald Mckinney\" },\n            { \"id\": 1, \"name\": \"Virginia Crawford\" },\n            { \"id\": 2, \"name\": \"Jimmie Lawrence\" }\n        ]\n    },\n    {\n        \"_id\": \"66c71d2b06572e5de0348e08\",\n        \"index\": 6,\n        \"guid\": \"59bd67a0-44e0-43dd-aebf-2b7422f273b5\",\n        \"isActive\": true,\n        \"balance\": \"$2,639.98\",\n        \"lamports\": 142302234983644260,\n        \"picture\": \"http://placehold.it/32x32\",\n        \"age\": 38,\n        \"eyeColor\": \"blue\",\n        \"name\": \"Jannie Case\",\n        \"gender\": \"female\",\n        \"company\": \"VALREDA\",\n        \"email\": \"janniecase@valreda.com\",\n        \"phone\": \"+1 (851) 464-3024\",\n        \"address\": \"201 Pierrepont Place, Whitehaven, Marshall Islands, 7595\",\n        \"about\": \"Dolore laboris anim non sint cillum cupidatat enim veniam aliqua amet ipsum anim sit ipsum. Id labore labore nostrud incididunt. Lorem culpa quis ad dolor cupidatat elit aliqua officia laborum. Reprehenderit irure dolore do sunt do dolor laborum officia Lorem anim cupidatat consequat. Sunt aute est ad laborum ea magna elit esse sit in nostrud laborum sint. Proident velit eu id laboris commodo aliqua nisi elit consectetur ut exercitation commodo ut ad. Id aute tempor laboris officia fugiat non consectetur nisi ipsum cillum sint anim anim consequat.\",\n        \"registered\": \"2014-10-10T02:16:44 -01:00\",\n        \"latitude\": 11.356616,\n        \"longitude\": -64.69489,\n        \"tags\": [\"culpa\", \"qui\", \"exercitation\", \"elit\", \"veniam\", \"aliquip\", \"Lorem\"],\n        \"friends\": [\n            { \"id\": 0, \"name\": \"Bowers Britt\" },\n            { \"id\": 1, \"name\": \"Tommie Morris\" },\n            { \"id\": 2, \"name\": \"Olsen Pollard\" }\n        ]\n    }\n]\n"
  },
  {
    "path": "packages/rpc-spec-types/src/__tests__/parse-json-with-bigints-test.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\n\nimport { parseJsonWithBigInts } from '../parse-json-with-bigints';\n\nconst MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);\nconst MAX_SAFE_INTEGER_PLUS_ONE = BigInt(Number.MAX_SAFE_INTEGER) + 1n;\n\ndescribe('parseJsonWithBigInts', () => {\n    it.each`\n        input                                   | expectedBigInt\n        ${'0'}                                  | ${0n}\n        ${'-0'}                                 | ${-0n}\n        ${'1'}                                  | ${1n}\n        ${'-1'}                                 | ${-1n}\n        ${'42'}                                 | ${42n}\n        ${'-42'}                                | ${-42n}\n        ${'1e5'}                                | ${100000n}\n        ${'-1e5'}                               | ${-100000n}\n        ${'1E5'}                                | ${100000n}\n        ${'-1E5'}                               | ${-100000n}\n        ${'123e+32'}                            | ${123n * 10n ** 32n}\n        ${'-123e+32'}                           | ${-123n * 10n ** 32n}\n        ${'123E+32'}                            | ${123n * 10n ** 32n}\n        ${'-123E+32'}                           | ${-123n * 10n ** 32n}\n        ${MAX_SAFE_INTEGER.toString()}          | ${MAX_SAFE_INTEGER}\n        ${MAX_SAFE_INTEGER_PLUS_ONE.toString()} | ${MAX_SAFE_INTEGER_PLUS_ONE}\n    `('parses $input as a bigint', ({ expectedBigInt, input }) => {\n        expect(parseJsonWithBigInts(input)).toBe(expectedBigInt);\n    });\n    it('parses BigInts within nested structures', () => {\n        const input = '{ \"alice\": 42, \"bob\": [3.14, 3e+8, { \"baz\": 1234567890123456789012345678901234567890 }] }';\n        expect(parseJsonWithBigInts(input)).toStrictEqual({\n            alice: 42n,\n            bob: [3.14, BigInt(3e8), { baz: 1234567890123456789012345678901234567890n }],\n        });\n    });\n    it.each`\n        input            | expectedNumber\n        ${'0.5'}         | ${0.5}\n        ${'-0.5'}        | ${-0.5}\n        ${'3.14159265'}  | ${3.14159265}\n        ${'-3.14159265'} | ${-3.14159265}\n        ${'1e-5'}        | ${1e-5}\n        ${'-1e-5'}       | ${-1e-5}\n        ${'1E-5'}        | ${1e-5}\n        ${'-1E-5'}       | ${-1e-5}\n        ${'1e-32'}       | ${1e-32}\n        ${'-1189e-32'}   | ${-1189e-32}\n    `('parses $input as a number', ({ expectedNumber, input }) => {\n        expect(parseJsonWithBigInts(input)).toBe(expectedNumber);\n    });\n    it.each([\n        'null',\n        'false',\n        'true',\n        '[]',\n        '[null, true, false]',\n        '{}',\n        '{ \"foo\": \"bar\" }',\n        '\"\"',\n        '\"Hello World\"',\n        '\"42 apples\"',\n        '\"base64\"',\n        '\"\\\\base64\"',\n        '\"\\\\\"base64\"',\n        '\"\\\\\\\\base64\"',\n        '\"\\\\\"\\\\\"base64\"',\n        '\"\\\\\\\\\\\\\"base64\"',\n        '\"\\\\\\\\\\\\\"\\\\\"base64\"',\n        '\"He said: \\\\\"I will eat 3 bananas\\\\\"\"',\n        '{ \"message_100\": \"Hello to the 1st World\" }',\n        '{ \"message_200\": \"Hello to the \\\\\"2nd World\\\\\"\" }',\n        '{\"data\":[\"\",\"base64\"]}',\n    ])('does not alter the value of %s', input => {\n        expect(parseJsonWithBigInts(input)).toStrictEqual(JSON.parse(input));\n    });\n    it('can parse complex JSON files', () => {\n        const largeJsonPath = path.join(__dirname, 'large-json-file.json');\n        const largeJsonString = fs.readFileSync(largeJsonPath, 'utf8');\n        const expectedResult = JSON.parse(largeJsonString, (key, value) => {\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (key === 'lamports') return 142302234983644260n;\n            // eslint-disable-next-line jest/no-conditional-in-test\n            if (typeof value === 'number' && Number.isInteger(value)) return BigInt(value);\n            return value;\n        });\n        expect(parseJsonWithBigInts(largeJsonString)).toStrictEqual(expectedResult);\n    });\n});\n"
  },
  {
    "path": "packages/rpc-spec-types/src/__tests__/rpc-message-test.ts",
    "content": "import { createRpcMessage } from '../rpc-message';\n\ndescribe('createRpcMessage', () => {\n    it('auto-increments ids with each new message', () => {\n        const request = { methodName: 'foo', params: 'bar' };\n        const { id: firstId } = createRpcMessage(request);\n        const { id: secondId } = createRpcMessage(request);\n        expect(Number(secondId) - Number(firstId)).toBe(1);\n    });\n    it('returns a well-formed JSON-RPC 2.0 message', () => {\n        const request = { methodName: 'someMethod', params: [1, 2, 3] };\n        expect(createRpcMessage(request)).toStrictEqual({\n            id: expect.any(String),\n            jsonrpc: '2.0',\n            method: 'someMethod',\n            params: [1, 2, 3],\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-spec-types/src/__tests__/stringify-json-with-bigints-test.ts",
    "content": "import { stringifyJsonWithBigInts } from '../stringify-json-with-bigints';\n\nconst MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);\nconst MAX_SAFE_INTEGER_PLUS_ONE = BigInt(Number.MAX_SAFE_INTEGER) + 1n;\n\ndescribe('stringifyJsonWithBigInts', () => {\n    it.each`\n        input                        | expectedString\n        ${0n}                        | ${'0'}\n        ${-0n}                       | ${'0'}\n        ${1n}                        | ${'1'}\n        ${-1n}                       | ${'-1'}\n        ${42n}                       | ${'42'}\n        ${-42n}                      | ${'-42'}\n        ${100000n}                   | ${'100000'}\n        ${-100000n}                  | ${'-100000'}\n        ${123n * 10n ** 32n}         | ${'12300000000000000000000000000000000'}\n        ${-123n * 10n ** 32n}        | ${'-12300000000000000000000000000000000'}\n        ${MAX_SAFE_INTEGER}          | ${MAX_SAFE_INTEGER.toString()}\n        ${MAX_SAFE_INTEGER_PLUS_ONE} | ${MAX_SAFE_INTEGER_PLUS_ONE.toString()}\n    `('strigifies bigint $input as a numerical value', ({ expectedString, input }) => {\n        expect(stringifyJsonWithBigInts(input)).toBe(expectedString);\n    });\n    it('strigifies BigInts within nested structures', () => {\n        const input = {\n            alice: 42n,\n            bob: [3.14, BigInt(3e8), { baz: 1234567890123456789012345678901234567890n }],\n        };\n        expect(stringifyJsonWithBigInts(input)).toBe(\n            '{\"alice\":42,\"bob\":[3.14,300000000,{\"baz\":1234567890123456789012345678901234567890}]}',\n        );\n    });\n    it.each`\n        input          | expectedString\n        ${0.5}         | ${'0.5'}\n        ${-0.5}        | ${'-0.5'}\n        ${3.14159265}  | ${'3.14159265'}\n        ${-3.14159265} | ${'-3.14159265'}\n        ${1e-5}        | ${'0.00001'}\n        ${-1e-5}       | ${'-0.00001'}\n        ${1e-32}       | ${'1e-32'}\n        ${-1189e-32}   | ${'-1.189e-29'}\n    `('strigifies number $input as a numerical value', ({ expectedString, input }) => {\n        expect(stringifyJsonWithBigInts(input)).toBe(expectedString);\n    });\n    it.each([\n        null,\n        false,\n        true,\n        [],\n        [null, true, false],\n        {},\n        { foo: 'bar' },\n        '',\n        'Hello World',\n        '42 apples',\n        'base64',\n        '\"base64',\n        '\"\"base64',\n        '\\\\base64',\n        '\\\\\"base64',\n        '\\\\\"\"base64',\n        '\\\\\\\\base64',\n        '\\\\\\\\\"base64',\n        '\\\\\\\\\"\"base64',\n        'He said: \"I will eat 3 bananas\"',\n        { message_100: 'Hello to the 1st World' },\n        { message_200: 'Hello to the \"2nd World\"' },\n        { data: ['', 'base64'] },\n    ])('does not alter the value of %s', input => {\n        expect(stringifyJsonWithBigInts(input)).toBe(JSON.stringify(input));\n    });\n});\n"
  },
  {
    "path": "packages/rpc-spec-types/src/index.ts",
    "content": "/**\n * This package contains core types that can be used on both RPC and RPC Subscriptions\n * specifications. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './overloads';\nexport * from './parse-json-with-bigints';\nexport * from './rpc-message';\nexport * from './rpc-request';\nexport * from './rpc-response';\nexport * from './stringify-json-with-bigints';\nexport * from './type-helpers';\n"
  },
  {
    "path": "packages/rpc-spec-types/src/overloads.ts",
    "content": "export type OverloadImplementations<T, U extends keyof T> = Overloads<T[U]>;\nexport type Overloads<T> = Overloads31<T>;\ntype Overloads31<T> =\n    // Have an RPC method with more than 31 overloads? Add another section and update this comment\n    T extends {\n        (...args: infer A1): infer R1;\n        (...args: infer A2): infer R2;\n        (...args: infer A3): infer R3;\n        (...args: infer A4): infer R4;\n        (...args: infer A5): infer R5;\n        (...args: infer A6): infer R6;\n        (...args: infer A7): infer R7;\n        (...args: infer A8): infer R8;\n        (...args: infer A9): infer R9;\n        (...args: infer A10): infer R10;\n        (...args: infer A11): infer R11;\n        (...args: infer A12): infer R12;\n        (...args: infer A13): infer R13;\n        (...args: infer A14): infer R14;\n        (...args: infer A15): infer R15;\n        (...args: infer A16): infer R16;\n        (...args: infer A17): infer R17;\n        (...args: infer A18): infer R18;\n        (...args: infer A19): infer R19;\n        (...args: infer A20): infer R20;\n        (...args: infer A21): infer R21;\n        (...args: infer A22): infer R22;\n        (...args: infer A23): infer R23;\n        (...args: infer A24): infer R24;\n        (...args: infer A25): infer R25;\n        (...args: infer A26): infer R26;\n        (...args: infer A27): infer R27;\n        (...args: infer A28): infer R28;\n        (...args: infer A29): infer R29;\n        (...args: infer A30): infer R30;\n        (...args: infer A31): infer R31;\n    }\n        ? [\n              (...args: A1) => R1,\n              (...args: A2) => R2,\n              (...args: A3) => R3,\n              (...args: A4) => R4,\n              (...args: A5) => R5,\n              (...args: A6) => R6,\n              (...args: A7) => R7,\n              (...args: A8) => R8,\n              (...args: A9) => R9,\n              (...args: A10) => R10,\n              (...args: A11) => R11,\n              (...args: A12) => R12,\n              (...args: A13) => R13,\n              (...args: A14) => R14,\n              (...args: A15) => R15,\n              (...args: A16) => R16,\n              (...args: A17) => R17,\n              (...args: A18) => R18,\n              (...args: A19) => R19,\n              (...args: A20) => R20,\n              (...args: A21) => R21,\n              (...args: A22) => R22,\n              (...args: A23) => R23,\n              (...args: A24) => R24,\n              (...args: A25) => R25,\n              (...args: A26) => R26,\n              (...args: A27) => R27,\n              (...args: A28) => R28,\n              (...args: A29) => R29,\n              (...args: A30) => R30,\n              (...args: A31) => R31,\n          ]\n        : Overloads30<T>;\ntype Overloads30<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n    (...args: infer A17): infer R17;\n    (...args: infer A18): infer R18;\n    (...args: infer A19): infer R19;\n    (...args: infer A20): infer R20;\n    (...args: infer A21): infer R21;\n    (...args: infer A22): infer R22;\n    (...args: infer A23): infer R23;\n    (...args: infer A24): infer R24;\n    (...args: infer A25): infer R25;\n    (...args: infer A26): infer R26;\n    (...args: infer A27): infer R27;\n    (...args: infer A28): infer R28;\n    (...args: infer A29): infer R29;\n    (...args: infer A30): infer R30;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n          (...args: A17) => R17,\n          (...args: A18) => R18,\n          (...args: A19) => R19,\n          (...args: A20) => R20,\n          (...args: A21) => R21,\n          (...args: A22) => R22,\n          (...args: A23) => R23,\n          (...args: A24) => R24,\n          (...args: A25) => R25,\n          (...args: A26) => R26,\n          (...args: A27) => R27,\n          (...args: A28) => R28,\n          (...args: A29) => R29,\n          (...args: A30) => R30,\n      ]\n    : Overloads29<T>;\ntype Overloads29<T> =\n    // Have an RPC method with more than 32 overloads? Add another section and update this comment\n    T extends {\n        (...args: infer A1): infer R1;\n        (...args: infer A2): infer R2;\n        (...args: infer A3): infer R3;\n        (...args: infer A4): infer R4;\n        (...args: infer A5): infer R5;\n        (...args: infer A6): infer R6;\n        (...args: infer A7): infer R7;\n        (...args: infer A8): infer R8;\n        (...args: infer A9): infer R9;\n        (...args: infer A10): infer R10;\n        (...args: infer A11): infer R11;\n        (...args: infer A12): infer R12;\n        (...args: infer A13): infer R13;\n        (...args: infer A14): infer R14;\n        (...args: infer A15): infer R15;\n        (...args: infer A16): infer R16;\n        (...args: infer A17): infer R17;\n        (...args: infer A18): infer R18;\n        (...args: infer A19): infer R19;\n        (...args: infer A20): infer R20;\n        (...args: infer A21): infer R21;\n        (...args: infer A22): infer R22;\n        (...args: infer A23): infer R23;\n        (...args: infer A24): infer R24;\n        (...args: infer A25): infer R25;\n        (...args: infer A26): infer R26;\n        (...args: infer A27): infer R27;\n        (...args: infer A28): infer R28;\n        (...args: infer A29): infer R29;\n    }\n        ? [\n              (...args: A1) => R1,\n              (...args: A2) => R2,\n              (...args: A3) => R3,\n              (...args: A4) => R4,\n              (...args: A5) => R5,\n              (...args: A6) => R6,\n              (...args: A7) => R7,\n              (...args: A8) => R8,\n              (...args: A9) => R9,\n              (...args: A10) => R10,\n              (...args: A11) => R11,\n              (...args: A12) => R12,\n              (...args: A13) => R13,\n              (...args: A14) => R14,\n              (...args: A15) => R15,\n              (...args: A16) => R16,\n              (...args: A17) => R17,\n              (...args: A18) => R18,\n              (...args: A19) => R19,\n              (...args: A20) => R20,\n              (...args: A21) => R21,\n              (...args: A22) => R22,\n              (...args: A23) => R23,\n              (...args: A24) => R24,\n              (...args: A25) => R25,\n              (...args: A26) => R26,\n              (...args: A27) => R27,\n              (...args: A28) => R28,\n              (...args: A29) => R29,\n          ]\n        : Overloads28<T>;\ntype Overloads28<T> =\n    // Have an RPC method with more than 32 overloads? Add another section and update this comment\n    T extends {\n        (...args: infer A1): infer R1;\n        (...args: infer A2): infer R2;\n        (...args: infer A3): infer R3;\n        (...args: infer A4): infer R4;\n        (...args: infer A5): infer R5;\n        (...args: infer A6): infer R6;\n        (...args: infer A7): infer R7;\n        (...args: infer A8): infer R8;\n        (...args: infer A9): infer R9;\n        (...args: infer A10): infer R10;\n        (...args: infer A11): infer R11;\n        (...args: infer A12): infer R12;\n        (...args: infer A13): infer R13;\n        (...args: infer A14): infer R14;\n        (...args: infer A15): infer R15;\n        (...args: infer A16): infer R16;\n        (...args: infer A17): infer R17;\n        (...args: infer A18): infer R18;\n        (...args: infer A19): infer R19;\n        (...args: infer A20): infer R20;\n        (...args: infer A21): infer R21;\n        (...args: infer A22): infer R22;\n        (...args: infer A23): infer R23;\n        (...args: infer A24): infer R24;\n        (...args: infer A25): infer R25;\n        (...args: infer A26): infer R26;\n        (...args: infer A27): infer R27;\n        (...args: infer A28): infer R28;\n    }\n        ? [\n              (...args: A1) => R1,\n              (...args: A2) => R2,\n              (...args: A3) => R3,\n              (...args: A4) => R4,\n              (...args: A5) => R5,\n              (...args: A6) => R6,\n              (...args: A7) => R7,\n              (...args: A8) => R8,\n              (...args: A9) => R9,\n              (...args: A10) => R10,\n              (...args: A11) => R11,\n              (...args: A12) => R12,\n              (...args: A13) => R13,\n              (...args: A14) => R14,\n              (...args: A15) => R15,\n              (...args: A16) => R16,\n              (...args: A17) => R17,\n              (...args: A18) => R18,\n              (...args: A19) => R19,\n              (...args: A20) => R20,\n              (...args: A21) => R21,\n              (...args: A22) => R22,\n              (...args: A23) => R23,\n              (...args: A24) => R24,\n              (...args: A25) => R25,\n              (...args: A26) => R26,\n              (...args: A27) => R27,\n              (...args: A28) => R28,\n          ]\n        : Overloads27<T>;\ntype Overloads27<T> =\n    // Have an RPC method with more than 32 overloads? Add another section and update this comment\n    T extends {\n        (...args: infer A1): infer R1;\n        (...args: infer A2): infer R2;\n        (...args: infer A3): infer R3;\n        (...args: infer A4): infer R4;\n        (...args: infer A5): infer R5;\n        (...args: infer A6): infer R6;\n        (...args: infer A7): infer R7;\n        (...args: infer A8): infer R8;\n        (...args: infer A9): infer R9;\n        (...args: infer A10): infer R10;\n        (...args: infer A11): infer R11;\n        (...args: infer A12): infer R12;\n        (...args: infer A13): infer R13;\n        (...args: infer A14): infer R14;\n        (...args: infer A15): infer R15;\n        (...args: infer A16): infer R16;\n        (...args: infer A17): infer R17;\n        (...args: infer A18): infer R18;\n        (...args: infer A19): infer R19;\n        (...args: infer A20): infer R20;\n        (...args: infer A21): infer R21;\n        (...args: infer A22): infer R22;\n        (...args: infer A23): infer R23;\n        (...args: infer A24): infer R24;\n        (...args: infer A25): infer R25;\n        (...args: infer A26): infer R26;\n        (...args: infer A27): infer R27;\n    }\n        ? [\n              (...args: A1) => R1,\n              (...args: A2) => R2,\n              (...args: A3) => R3,\n              (...args: A4) => R4,\n              (...args: A5) => R5,\n              (...args: A6) => R6,\n              (...args: A7) => R7,\n              (...args: A8) => R8,\n              (...args: A9) => R9,\n              (...args: A10) => R10,\n              (...args: A11) => R11,\n              (...args: A12) => R12,\n              (...args: A13) => R13,\n              (...args: A14) => R14,\n              (...args: A15) => R15,\n              (...args: A16) => R16,\n              (...args: A17) => R17,\n              (...args: A18) => R18,\n              (...args: A19) => R19,\n              (...args: A20) => R20,\n              (...args: A21) => R21,\n              (...args: A22) => R22,\n              (...args: A23) => R23,\n              (...args: A24) => R24,\n              (...args: A25) => R25,\n              (...args: A26) => R26,\n              (...args: A27) => R27,\n          ]\n        : Overloads26<T>;\ntype Overloads26<T> =\n    // Have an RPC method with more than 32 overloads? Add another section and update this comment\n    T extends {\n        (...args: infer A1): infer R1;\n        (...args: infer A2): infer R2;\n        (...args: infer A3): infer R3;\n        (...args: infer A4): infer R4;\n        (...args: infer A5): infer R5;\n        (...args: infer A6): infer R6;\n        (...args: infer A7): infer R7;\n        (...args: infer A8): infer R8;\n        (...args: infer A9): infer R9;\n        (...args: infer A10): infer R10;\n        (...args: infer A11): infer R11;\n        (...args: infer A12): infer R12;\n        (...args: infer A13): infer R13;\n        (...args: infer A14): infer R14;\n        (...args: infer A15): infer R15;\n        (...args: infer A16): infer R16;\n        (...args: infer A17): infer R17;\n        (...args: infer A18): infer R18;\n        (...args: infer A19): infer R19;\n        (...args: infer A20): infer R20;\n        (...args: infer A21): infer R21;\n        (...args: infer A22): infer R22;\n        (...args: infer A23): infer R23;\n        (...args: infer A24): infer R24;\n        (...args: infer A25): infer R25;\n        (...args: infer A26): infer R26;\n    }\n        ? [\n              (...args: A1) => R1,\n              (...args: A2) => R2,\n              (...args: A3) => R3,\n              (...args: A4) => R4,\n              (...args: A5) => R5,\n              (...args: A6) => R6,\n              (...args: A7) => R7,\n              (...args: A8) => R8,\n              (...args: A9) => R9,\n              (...args: A10) => R10,\n              (...args: A11) => R11,\n              (...args: A12) => R12,\n              (...args: A13) => R13,\n              (...args: A14) => R14,\n              (...args: A15) => R15,\n              (...args: A16) => R16,\n              (...args: A17) => R17,\n              (...args: A18) => R18,\n              (...args: A19) => R19,\n              (...args: A20) => R20,\n              (...args: A21) => R21,\n              (...args: A22) => R22,\n              (...args: A23) => R23,\n              (...args: A24) => R24,\n              (...args: A25) => R25,\n              (...args: A26) => R26,\n          ]\n        : Overloads25<T>;\ntype Overloads25<T> =\n    // Have an RPC method with more than 32 overloads? Add another section and update this comment\n    T extends {\n        (...args: infer A1): infer R1;\n        (...args: infer A2): infer R2;\n        (...args: infer A3): infer R3;\n        (...args: infer A4): infer R4;\n        (...args: infer A5): infer R5;\n        (...args: infer A6): infer R6;\n        (...args: infer A7): infer R7;\n        (...args: infer A8): infer R8;\n        (...args: infer A9): infer R9;\n        (...args: infer A10): infer R10;\n        (...args: infer A11): infer R11;\n        (...args: infer A12): infer R12;\n        (...args: infer A13): infer R13;\n        (...args: infer A14): infer R14;\n        (...args: infer A15): infer R15;\n        (...args: infer A16): infer R16;\n        (...args: infer A17): infer R17;\n        (...args: infer A18): infer R18;\n        (...args: infer A19): infer R19;\n        (...args: infer A20): infer R20;\n        (...args: infer A21): infer R21;\n        (...args: infer A22): infer R22;\n        (...args: infer A23): infer R23;\n        (...args: infer A24): infer R24;\n        (...args: infer A25): infer R25;\n    }\n        ? [\n              (...args: A1) => R1,\n              (...args: A2) => R2,\n              (...args: A3) => R3,\n              (...args: A4) => R4,\n              (...args: A5) => R5,\n              (...args: A6) => R6,\n              (...args: A7) => R7,\n              (...args: A8) => R8,\n              (...args: A9) => R9,\n              (...args: A10) => R10,\n              (...args: A11) => R11,\n              (...args: A12) => R12,\n              (...args: A13) => R13,\n              (...args: A14) => R14,\n              (...args: A15) => R15,\n              (...args: A16) => R16,\n              (...args: A17) => R17,\n              (...args: A18) => R18,\n              (...args: A19) => R19,\n              (...args: A20) => R20,\n              (...args: A21) => R21,\n              (...args: A22) => R22,\n              (...args: A23) => R23,\n              (...args: A24) => R24,\n              (...args: A25) => R25,\n          ]\n        : Overloads24<T>;\ntype Overloads24<T> =\n    // Have an RPC method with more than 32 overloads? Add another section and update this comment\n    T extends {\n        (...args: infer A1): infer R1;\n        (...args: infer A2): infer R2;\n        (...args: infer A3): infer R3;\n        (...args: infer A4): infer R4;\n        (...args: infer A5): infer R5;\n        (...args: infer A6): infer R6;\n        (...args: infer A7): infer R7;\n        (...args: infer A8): infer R8;\n        (...args: infer A9): infer R9;\n        (...args: infer A10): infer R10;\n        (...args: infer A11): infer R11;\n        (...args: infer A12): infer R12;\n        (...args: infer A13): infer R13;\n        (...args: infer A14): infer R14;\n        (...args: infer A15): infer R15;\n        (...args: infer A16): infer R16;\n        (...args: infer A17): infer R17;\n        (...args: infer A18): infer R18;\n        (...args: infer A19): infer R19;\n        (...args: infer A20): infer R20;\n        (...args: infer A21): infer R21;\n        (...args: infer A22): infer R22;\n        (...args: infer A23): infer R23;\n        (...args: infer A24): infer R24;\n    }\n        ? [\n              (...args: A1) => R1,\n              (...args: A2) => R2,\n              (...args: A3) => R3,\n              (...args: A4) => R4,\n              (...args: A5) => R5,\n              (...args: A6) => R6,\n              (...args: A7) => R7,\n              (...args: A8) => R8,\n              (...args: A9) => R9,\n              (...args: A10) => R10,\n              (...args: A11) => R11,\n              (...args: A12) => R12,\n              (...args: A13) => R13,\n              (...args: A14) => R14,\n              (...args: A15) => R15,\n              (...args: A16) => R16,\n              (...args: A17) => R17,\n              (...args: A18) => R18,\n              (...args: A19) => R19,\n              (...args: A20) => R20,\n              (...args: A21) => R21,\n              (...args: A22) => R22,\n              (...args: A23) => R23,\n              (...args: A24) => R24,\n          ]\n        : Overloads23<T>;\ntype Overloads23<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n    (...args: infer A17): infer R17;\n    (...args: infer A18): infer R18;\n    (...args: infer A19): infer R19;\n    (...args: infer A20): infer R20;\n    (...args: infer A21): infer R21;\n    (...args: infer A22): infer R22;\n    (...args: infer A23): infer R23;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n          (...args: A17) => R17,\n          (...args: A18) => R18,\n          (...args: A19) => R19,\n          (...args: A20) => R20,\n          (...args: A21) => R21,\n          (...args: A22) => R22,\n          (...args: A23) => R23,\n      ]\n    : Overloads22<T>;\ntype Overloads22<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n    (...args: infer A17): infer R17;\n    (...args: infer A18): infer R18;\n    (...args: infer A19): infer R19;\n    (...args: infer A20): infer R20;\n    (...args: infer A21): infer R21;\n    (...args: infer A22): infer R22;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n          (...args: A17) => R17,\n          (...args: A18) => R18,\n          (...args: A19) => R19,\n          (...args: A20) => R20,\n          (...args: A21) => R21,\n          (...args: A22) => R22,\n      ]\n    : Overloads21<T>;\ntype Overloads21<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n    (...args: infer A17): infer R17;\n    (...args: infer A18): infer R18;\n    (...args: infer A19): infer R19;\n    (...args: infer A20): infer R20;\n    (...args: infer A21): infer R21;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n          (...args: A17) => R17,\n          (...args: A18) => R18,\n          (...args: A19) => R19,\n          (...args: A20) => R20,\n          (...args: A21) => R21,\n      ]\n    : Overloads20<T>;\ntype Overloads20<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n    (...args: infer A17): infer R17;\n    (...args: infer A18): infer R18;\n    (...args: infer A19): infer R19;\n    (...args: infer A20): infer R20;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n          (...args: A17) => R17,\n          (...args: A18) => R18,\n          (...args: A19) => R19,\n          (...args: A20) => R20,\n      ]\n    : Overloads19<T>;\ntype Overloads19<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n    (...args: infer A17): infer R17;\n    (...args: infer A18): infer R18;\n    (...args: infer A19): infer R19;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n          (...args: A17) => R17,\n          (...args: A18) => R18,\n          (...args: A19) => R19,\n      ]\n    : Overloads18<T>;\ntype Overloads18<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n    (...args: infer A17): infer R17;\n    (...args: infer A18): infer R18;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n          (...args: A17) => R17,\n          (...args: A18) => R18,\n      ]\n    : Overloads17<T>;\ntype Overloads17<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n    (...args: infer A17): infer R17;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n          (...args: A17) => R17,\n      ]\n    : Overloads16<T>;\ntype Overloads16<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n    (...args: infer A16): infer R16;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n          (...args: A16) => R16,\n      ]\n    : Overloads15<T>;\ntype Overloads15<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n    (...args: infer A15): infer R15;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n          (...args: A15) => R15,\n      ]\n    : Overloads14<T>;\ntype Overloads14<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n    (...args: infer A14): infer R14;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n          (...args: A14) => R14,\n      ]\n    : Overloads13<T>;\ntype Overloads13<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n    (...args: infer A13): infer R13;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n          (...args: A13) => R13,\n      ]\n    : Overloads12<T>;\ntype Overloads12<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n    (...args: infer A12): infer R12;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n          (...args: A12) => R12,\n      ]\n    : Overloads11<T>;\ntype Overloads11<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n    (...args: infer A11): infer R11;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n          (...args: A11) => R11,\n      ]\n    : Overloads10<T>;\ntype Overloads10<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n    (...args: infer A10): infer R10;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n          (...args: A10) => R10,\n      ]\n    : Overloads9<T>;\ntype Overloads9<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n    (...args: infer A9): infer R9;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n          (...args: A9) => R9,\n      ]\n    : Overloads8<T>;\ntype Overloads8<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n    (...args: infer A8): infer R8;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n          (...args: A8) => R8,\n      ]\n    : Overloads7<T>;\ntype Overloads7<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n    (...args: infer A7): infer R7;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n          (...args: A7) => R7,\n      ]\n    : Overloads6<T>;\ntype Overloads6<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n    (...args: infer A6): infer R6;\n}\n    ? [\n          (...args: A1) => R1,\n          (...args: A2) => R2,\n          (...args: A3) => R3,\n          (...args: A4) => R4,\n          (...args: A5) => R5,\n          (...args: A6) => R6,\n      ]\n    : Overloads5<T>;\ntype Overloads5<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n    (...args: infer A5): infer R5;\n}\n    ? [(...args: A1) => R1, (...args: A2) => R2, (...args: A3) => R3, (...args: A4) => R4, (...args: A5) => R5]\n    : Overloads4<T>;\ntype Overloads4<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n    (...args: infer A4): infer R4;\n}\n    ? [(...args: A1) => R1, (...args: A2) => R2, (...args: A3) => R3, (...args: A4) => R4]\n    : Overloads3<T>;\ntype Overloads3<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n    (...args: infer A3): infer R3;\n}\n    ? [(...args: A1) => R1, (...args: A2) => R2, (...args: A3) => R3]\n    : Overloads2<T>;\ntype Overloads2<T> = T extends {\n    (...args: infer A1): infer R1;\n    (...args: infer A2): infer R2;\n}\n    ? [(...args: A1) => R1, (...args: A2) => R2]\n    : Overloads1<T>;\ntype Overloads1<T> = T extends {\n    (...args: infer A1): infer R1;\n}\n    ? [(...args: A1) => R1]\n    : unknown;\n"
  },
  {
    "path": "packages/rpc-spec-types/src/parse-json-with-bigints.ts",
    "content": "/**\n * This function is a replacement for `JSON.parse` that can handle large\n * unsafe integers by parsing them as BigInts. It transforms every\n * numerical value into a BigInt without loss of precision.\n */\nexport function parseJsonWithBigInts(json: string): unknown {\n    return JSON.parse(wrapIntegersInBigIntValueObject(json), (_, value) => {\n        return isBigIntValueObject(value) ? unwrapBigIntValueObject(value) : value;\n    });\n}\n\nfunction wrapIntegersInBigIntValueObject(json: string): string {\n    const out = [];\n    let inQuote = false;\n    for (let ii = 0; ii < json.length; ii++) {\n        let isEscaped = false;\n        if (json[ii] === '\\\\') {\n            out.push(json[ii++]);\n            isEscaped = !isEscaped;\n        }\n        if (json[ii] === '\"') {\n            out.push(json[ii]);\n            if (!isEscaped) {\n                inQuote = !inQuote;\n            }\n            continue;\n        }\n        if (!inQuote) {\n            const consumedNumber = consumeNumber(json, ii);\n            if (consumedNumber?.length) {\n                ii += consumedNumber.length - 1;\n                // Don't wrap numbers that contain a decimal point or a negative exponent.\n                if (consumedNumber.match(/\\.|[eE]-/)) {\n                    out.push(consumedNumber);\n                } else {\n                    out.push(wrapBigIntValueObject(consumedNumber));\n                }\n                continue;\n            }\n        }\n        out.push(json[ii]);\n    }\n\n    return out.join('');\n}\n\nfunction consumeNumber(json: string, ii: number): string | null {\n    /** @see https://stackoverflow.com/a/13340826/11440277 */\n    const JSON_NUMBER_REGEX = /^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?/;\n\n    // Stop early if the first character isn't a digit or a minus sign.\n    if (!json[ii]?.match(/[-\\d]/)) {\n        return null;\n    }\n\n    // Otherwise, check if the next characters form a valid JSON number.\n    const numberMatch = json.slice(ii).match(JSON_NUMBER_REGEX);\n    return numberMatch ? numberMatch[0] : null;\n}\n\ntype BigIntValueObject = {\n    // `$` implies 'this is a value object'.\n    // `n` implies 'interpret the value as a bigint'.\n    $n: string;\n};\n\nfunction wrapBigIntValueObject(value: string): string {\n    return `{\"$n\":\"${value}\"}`;\n}\n\nfunction unwrapBigIntValueObject({ $n }: BigIntValueObject): bigint {\n    if ($n.match(/[eE]/)) {\n        const [units, exponent] = $n.split(/[eE]/);\n        return BigInt(units) * BigInt(10) ** BigInt(exponent);\n    }\n    return BigInt($n);\n}\n\nfunction isBigIntValueObject(value: unknown): value is BigIntValueObject {\n    return !!value && typeof value === 'object' && '$n' in value && typeof value.$n === 'string';\n}\n"
  },
  {
    "path": "packages/rpc-spec-types/src/rpc-message.ts",
    "content": "import { RpcRequest } from './rpc-request';\n\nlet _nextMessageId = 0n;\nfunction getNextMessageId(): string {\n    const id = _nextMessageId;\n    _nextMessageId++;\n    return id.toString();\n}\n\n/**\n * Returns a spec-compliant JSON RPC 2.0 message, given a method name and some params.\n *\n * Generates a new `id` on each call by incrementing a `bigint` and casting it to a string.\n */\nexport function createRpcMessage<TParams>(request: RpcRequest<TParams>) {\n    return {\n        id: getNextMessageId(),\n        jsonrpc: '2.0',\n        method: request.methodName,\n        params: request.params,\n    };\n}\n"
  },
  {
    "path": "packages/rpc-spec-types/src/rpc-request.ts",
    "content": "/**\n * Describes the elements of a {@link Rpc} or {@link RpcSubscriptions} request.\n */\nexport type RpcRequest<TParams = unknown> = {\n    /** Rhe name of the RPC method or subscription requested */\n    readonly methodName: string;\n    /** The parameters to be passed to the RPC server */\n    readonly params: TParams;\n};\n\n/**\n * A function that accepts a {@link RpcRequest} and returns another {@link RpcRequest}.\n *\n * This allows the {@link RpcApi} to transform the request before it is sent to the RPC server.\n */\nexport type RpcRequestTransformer = {\n    <TParams>(request: RpcRequest<TParams>): RpcRequest;\n};\n"
  },
  {
    "path": "packages/rpc-spec-types/src/rpc-response.ts",
    "content": "import type { RpcRequest } from './rpc-request';\n\n/**\n * Represents the response from a RPC server.\n *\n * This could be any sort of data which is why {@link RpcResponse} defaults to `unknown`. You may\n * use a type parameter to specify the shape of the response — e.g.\n * `RpcResponse<{ result: number }>`.\n */\nexport type RpcResponse<TResponse = unknown> = TResponse;\n\n/**\n * A function that accepts a {@link RpcResponse} and returns another {@link RpcResponse}.\n *\n * This allows the {@link RpcApi} to transform the response before it is returned to the caller.\n */\nexport type RpcResponseTransformer<TResponse = unknown> = {\n    (response: RpcResponse, request: RpcRequest): RpcResponse<TResponse>;\n};\n\ninterface HasIdentifier {\n    readonly id: string;\n}\n\ntype RpcErrorResponsePayload = Readonly<{\n    code: number;\n    data?: unknown;\n    message: string;\n}>;\n\nexport type RpcResponseData<TResponse> = HasIdentifier &\n    Readonly<{ error: RpcErrorResponsePayload } | { result: TResponse }>;\n"
  },
  {
    "path": "packages/rpc-spec-types/src/stringify-json-with-bigints.ts",
    "content": "/**\n * Transforms a value into a JSON string, whilst rendering bigints as large unsafe integers.\n */\nexport function stringifyJsonWithBigInts(value: unknown, space?: number | string): string {\n    return unwrapBigIntValueObject(\n        JSON.stringify(value, (_, v) => (typeof v === 'bigint' ? wrapBigIntValueObject(v) : v), space),\n    );\n}\n\ntype BigIntValueObject = {\n    // `$` implies 'this is a value object'.\n    // `n` implies 'interpret the value as a bigint'.\n    $n: string;\n};\n\nfunction wrapBigIntValueObject(value: bigint): BigIntValueObject {\n    return { $n: `${value}` };\n}\n\nfunction unwrapBigIntValueObject(value: string): string {\n    return value.replace(/\\{\\s*\"\\$n\"\\s*:\\s*\"(-?\\d+)\"\\s*\\}/g, '$1');\n}\n"
  },
  {
    "path": "packages/rpc-spec-types/src/type-helpers.ts",
    "content": "// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Callable = (...args: any[]) => any;\nexport type Flatten<T> = T extends (infer Item)[] ? Item : never;\nexport type UnionToIntersection<T> = (T extends unknown ? (x: T) => unknown : never) extends (x: infer R) => unknown\n    ? R\n    : never;\n"
  },
  {
    "path": "packages/rpc-spec-types/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-spec-types/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-spec-types\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-spec-types/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-subscriptions/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-subscriptions/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-subscriptions/CHANGELOG.md",
    "content": "# @solana/rpc-subscriptions\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`8d73de5`](https://github.com/anza-xyz/kit/commit/8d73de5241d709946431f2fdda74f2a0df5e9529), [`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/promises@6.9.0\n    - @solana/errors@6.9.0\n    - @solana/fast-stable-stringify@6.9.0\n    - @solana/functional@6.9.0\n    - @solana/rpc-spec-types@6.9.0\n    - @solana/rpc-subscriptions-api@6.9.0\n    - @solana/rpc-subscriptions-channel-websocket@6.9.0\n    - @solana/rpc-subscriptions-spec@6.9.0\n    - @solana/rpc-transformers@6.9.0\n    - @solana/rpc-types@6.9.0\n    - @solana/subscribable@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`f53ce07`](https://github.com/anza-xyz/kit/commit/f53ce0796c782e79490e1cf11a55e28fb62b8c8f), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n    - @solana/fast-stable-stringify@6.8.0\n    - @solana/functional@6.8.0\n    - @solana/promises@6.8.0\n    - @solana/rpc-spec-types@6.8.0\n    - @solana/rpc-subscriptions-api@6.8.0\n    - @solana/rpc-subscriptions-channel-websocket@6.8.0\n    - @solana/rpc-subscriptions-spec@6.8.0\n    - @solana/rpc-transformers@6.8.0\n    - @solana/rpc-types@6.8.0\n    - @solana/subscribable@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n    - @solana/fast-stable-stringify@6.7.0\n    - @solana/functional@6.7.0\n    - @solana/promises@6.7.0\n    - @solana/rpc-spec-types@6.7.0\n    - @solana/rpc-subscriptions-api@6.7.0\n    - @solana/rpc-subscriptions-channel-websocket@6.7.0\n    - @solana/rpc-subscriptions-spec@6.7.0\n    - @solana/rpc-transformers@6.7.0\n    - @solana/rpc-types@6.7.0\n    - @solana/subscribable@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/rpc-subscriptions-api@6.6.0\n    - @solana/rpc-subscriptions-channel-websocket@6.6.0\n    - @solana/rpc-subscriptions-spec@6.6.0\n    - @solana/rpc-transformers@6.6.0\n    - @solana/rpc-types@6.6.0\n    - @solana/subscribable@6.6.0\n    - @solana/fast-stable-stringify@6.6.0\n    - @solana/functional@6.6.0\n    - @solana/promises@6.6.0\n    - @solana/rpc-spec-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n    - @solana/fast-stable-stringify@6.5.0\n    - @solana/functional@6.5.0\n    - @solana/promises@6.5.0\n    - @solana/rpc-spec-types@6.5.0\n    - @solana/rpc-subscriptions-api@6.5.0\n    - @solana/rpc-subscriptions-channel-websocket@6.5.0\n    - @solana/rpc-subscriptions-spec@6.5.0\n    - @solana/rpc-transformers@6.5.0\n    - @solana/rpc-types@6.5.0\n    - @solana/subscribable@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-types@6.4.0\n    - @solana/rpc-subscriptions-api@6.4.0\n    - @solana/rpc-transformers@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/fast-stable-stringify@6.4.0\n    - @solana/functional@6.4.0\n    - @solana/promises@6.4.0\n    - @solana/rpc-spec-types@6.4.0\n    - @solana/rpc-subscriptions-channel-websocket@6.4.0\n    - @solana/rpc-subscriptions-spec@6.4.0\n    - @solana/subscribable@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n    - @solana/fast-stable-stringify@6.3.1\n    - @solana/functional@6.3.1\n    - @solana/promises@6.3.1\n    - @solana/rpc-spec-types@6.3.1\n    - @solana/rpc-subscriptions-api@6.3.1\n    - @solana/rpc-subscriptions-channel-websocket@6.3.1\n    - @solana/rpc-subscriptions-spec@6.3.1\n    - @solana/rpc-transformers@6.3.1\n    - @solana/rpc-types@6.3.1\n    - @solana/subscribable@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/rpc-subscriptions-channel-websocket@6.3.0\n    - @solana/rpc-subscriptions-spec@6.3.0\n    - @solana/rpc-transformers@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/subscribable@6.3.0\n    - @solana/rpc-subscriptions-api@6.3.0\n    - @solana/fast-stable-stringify@6.3.0\n    - @solana/functional@6.3.0\n    - @solana/promises@6.3.0\n    - @solana/rpc-spec-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/rpc-subscriptions-channel-websocket@6.2.0\n    - @solana/rpc-subscriptions-spec@6.2.0\n    - @solana/rpc-transformers@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/subscribable@6.2.0\n    - @solana/rpc-subscriptions-api@6.2.0\n    - @solana/fast-stable-stringify@6.2.0\n    - @solana/functional@6.2.0\n    - @solana/promises@6.2.0\n    - @solana/rpc-spec-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/rpc-subscriptions-channel-websocket@6.1.0\n    - @solana/rpc-subscriptions-spec@6.1.0\n    - @solana/rpc-transformers@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/subscribable@6.1.0\n    - @solana/rpc-subscriptions-api@6.1.0\n    - @solana/fast-stable-stringify@6.1.0\n    - @solana/functional@6.1.0\n    - @solana/promises@6.1.0\n    - @solana/rpc-spec-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-subscriptions-api@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/fast-stable-stringify@6.0.1\n    - @solana/functional@6.0.1\n    - @solana/promises@6.0.1\n    - @solana/rpc-spec-types@6.0.1\n    - @solana/rpc-subscriptions-channel-websocket@6.0.1\n    - @solana/rpc-subscriptions-spec@6.0.1\n    - @solana/rpc-transformers@6.0.1\n    - @solana/rpc-types@6.0.1\n    - @solana/subscribable@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-subscriptions-api@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/fast-stable-stringify@6.0.0\n    - @solana/functional@6.0.0\n    - @solana/promises@6.0.0\n    - @solana/rpc-spec-types@6.0.0\n    - @solana/rpc-subscriptions-channel-websocket@6.0.0\n    - @solana/rpc-subscriptions-spec@6.0.0\n    - @solana/rpc-transformers@6.0.0\n    - @solana/rpc-types@6.0.0\n    - @solana/subscribable@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/rpc-subscriptions-channel-websocket@5.5.1\n    - @solana/rpc-subscriptions-spec@5.5.1\n    - @solana/rpc-transformers@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/subscribable@5.5.1\n    - @solana/rpc-subscriptions-api@5.5.1\n    - @solana/fast-stable-stringify@5.5.1\n    - @solana/functional@5.5.1\n    - @solana/promises@5.5.1\n    - @solana/rpc-spec-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/rpc-subscriptions-channel-websocket@5.5.0\n    - @solana/rpc-subscriptions-spec@5.5.0\n    - @solana/rpc-transformers@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/subscribable@5.5.0\n    - @solana/rpc-subscriptions-api@5.5.0\n    - @solana/fast-stable-stringify@5.5.0\n    - @solana/functional@5.5.0\n    - @solana/promises@5.5.0\n    - @solana/rpc-spec-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/rpc-subscriptions-channel-websocket@5.4.0\n    - @solana/rpc-subscriptions-spec@5.4.0\n    - @solana/fast-stable-stringify@5.4.0\n    - @solana/rpc-subscriptions-api@5.4.0\n    - @solana/rpc-transformers@5.4.0\n    - @solana/rpc-spec-types@5.4.0\n    - @solana/subscribable@5.4.0\n    - @solana/functional@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/promises@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n    - @solana/fast-stable-stringify@5.3.0\n    - @solana/functional@5.3.0\n    - @solana/promises@5.3.0\n    - @solana/rpc-spec-types@5.3.0\n    - @solana/rpc-subscriptions-api@5.3.0\n    - @solana/rpc-subscriptions-channel-websocket@5.3.0\n    - @solana/rpc-subscriptions-spec@5.3.0\n    - @solana/rpc-transformers@5.3.0\n    - @solana/rpc-types@5.3.0\n    - @solana/subscribable@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`7d5a57c`](https://github.com/anza-xyz/kit/commit/7d5a57c209140fd7cd4721a2dc9a4ab10b8ac907)]:\n    - @solana/errors@5.2.0\n    - @solana/rpc-subscriptions-channel-websocket@5.2.0\n    - @solana/rpc-subscriptions-spec@5.2.0\n    - @solana/rpc-transformers@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/subscribable@5.2.0\n    - @solana/rpc-subscriptions-api@5.2.0\n    - @solana/fast-stable-stringify@5.2.0\n    - @solana/functional@5.2.0\n    - @solana/promises@5.2.0\n    - @solana/rpc-spec-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n    - @solana/rpc-subscriptions-channel-websocket@5.1.0\n    - @solana/rpc-subscriptions-spec@5.1.0\n    - @solana/rpc-transformers@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/subscribable@5.1.0\n    - @solana/rpc-subscriptions-api@5.1.0\n    - @solana/fast-stable-stringify@5.1.0\n    - @solana/functional@5.1.0\n    - @solana/promises@5.1.0\n    - @solana/rpc-spec-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/rpc-subscriptions-api@5.0.0\n    - @solana/rpc-transformers@5.0.0\n    - @solana/rpc-subscriptions-channel-websocket@5.0.0\n    - @solana/rpc-subscriptions-spec@5.0.0\n    - @solana/subscribable@5.0.0\n    - @solana/fast-stable-stringify@5.0.0\n    - @solana/functional@5.0.0\n    - @solana/promises@5.0.0\n    - @solana/rpc-spec-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#904](https://github.com/anza-xyz/kit/pull/904) [`9e8bfe4`](https://github.com/anza-xyz/kit/commit/9e8bfe460886124d1d12e444e7452db631c0ac6f) Thanks [@steveluscher](https://github.com/steveluscher)! - yExported all of the channel creators that form part of `createDefaultSolanaRpcSubscriptionsChannelCreator()` so that developers can configure their own custom channels\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-subscriptions-api@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/rpc-subscriptions-channel-websocket@4.0.0\n    - @solana/rpc-subscriptions-spec@4.0.0\n    - @solana/rpc-transformers@4.0.0\n    - @solana/subscribable@4.0.0\n    - @solana/fast-stable-stringify@4.0.0\n    - @solana/functional@4.0.0\n    - @solana/promises@4.0.0\n    - @solana/rpc-spec-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`81c83b1`](https://github.com/anza-xyz/kit/commit/81c83b12dd0e145bf7d08182e01824f2f14e5ee5)]:\n    - @solana/errors@3.0.0\n    - @solana/rpc-spec-types@3.0.0\n    - @solana/rpc-subscriptions-api@3.0.0\n    - @solana/rpc-subscriptions-channel-websocket@3.0.0\n    - @solana/rpc-subscriptions-spec@3.0.0\n    - @solana/rpc-transformers@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/subscribable@3.0.0\n    - @solana/fast-stable-stringify@3.0.0\n    - @solana/functional@3.0.0\n    - @solana/promises@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/rpc-subscriptions-spec@2.3.0\n    - @solana/rpc-subscriptions-api@2.3.0\n    - @solana/rpc-subscriptions-channel-websocket@2.3.0\n    - @solana/rpc-transformers@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/subscribable@2.3.0\n    - @solana/fast-stable-stringify@2.3.0\n    - @solana/functional@2.3.0\n    - @solana/promises@2.3.0\n    - @solana/rpc-spec-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies [[`e881fca`](https://github.com/anza-xyz/kit/commit/e881fca9ea0154d0eeaec682697042f86502b86d)]:\n    - @solana/rpc-subscriptions-spec@2.2.1\n    - @solana/rpc-subscriptions-api@2.2.1\n    - @solana/rpc-subscriptions-channel-websocket@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/fast-stable-stringify@2.2.1\n    - @solana/functional@2.2.1\n    - @solana/promises@2.2.1\n    - @solana/rpc-spec-types@2.2.1\n    - @solana/rpc-transformers@2.2.1\n    - @solana/rpc-types@2.2.1\n    - @solana/subscribable@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-transformers@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/rpc-subscriptions-api@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/fast-stable-stringify@2.2.0\n    - @solana/functional@2.2.0\n    - @solana/promises@2.2.0\n    - @solana/rpc-spec-types@2.2.0\n    - @solana/rpc-subscriptions-channel-websocket@2.2.0\n    - @solana/rpc-subscriptions-spec@2.2.0\n    - @solana/subscribable@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`7e7b2ef`](https://github.com/anza-xyz/kit/commit/7e7b2efebfd8de431e4381cc3d3fa117d3228030), [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-transformers@2.1.1\n    - @solana/rpc-subscriptions-channel-websocket@2.1.1\n    - @solana/rpc-subscriptions-spec@2.1.1\n    - @solana/fast-stable-stringify@2.1.1\n    - @solana/rpc-subscriptions-api@2.1.1\n    - @solana/rpc-spec-types@2.1.1\n    - @solana/subscribable@2.1.1\n    - @solana/functional@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/promises@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065) Thanks [@steveluscher](https://github.com/steveluscher)! - Disabled the `MaxListenersExceededWarning` in Node when creating event targets for internal use\n\n- [`70eb596`](https://github.com/anza-xyz/kit/commit/70eb596bdff9d95d607a937615190a0d8111ad3c) Thanks [@steveluscher](https://github.com/steveluscher)! - The online/offline checker in the subscriptions implementation no longer throws an error when hosted in the Content Scripts environment of a browser extension\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n    - @solana/subscribable@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/rpc-subscriptions-channel-websocket@2.1.0\n    - @solana/rpc-subscriptions-spec@2.1.0\n    - @solana/rpc-subscriptions-api@2.1.0\n    - @solana/rpc-transformers@2.1.0\n    - @solana/fast-stable-stringify@2.1.0\n    - @solana/functional@2.1.0\n    - @solana/promises@2.1.0\n    - @solana/rpc-spec-types@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3507](https://github.com/solana-labs/solana-web3.js/pull/3507) [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fixed a bug where the subcription server's response would not be detected, because of a mismatch in the format of the `id`. Now all RPC message ids are strings, for avoidance of doubt.\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Change first argument of `onIntegerOverflow` handler from `methodName: string` to `request: RpcRequest`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3455](https://github.com/solana-labs/solana-web3.js/pull/3455) [`500a991`](https://github.com/solana-labs/solana-web3.js/commit/500a991d292638eaee1fa48a7b94acfe2ff83cb7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Adds a channel creator function called `createDefaultSolanaRpcSubscriptionsChannelCreator`. This function works similarly to `createDefaultRpcSubscriptionsChannelCreator` but with some Solana-specific defaults. For instance, it safely handles `BigInt` values in JSON messages since Solana RPC servers accept and return integers larger than `Number.MAX_SAFE_INTEGER`.\n\n- [#3072](https://github.com/solana-labs/solana-web3.js/pull/3072) [`c122c75`](https://github.com/solana-labs/solana-web3.js/commit/c122c75936e8fa5364edf114a5182cf119b26922) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a memory leak with transaction confirmation and subscriptions\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- [#3451](https://github.com/solana-labs/solana-web3.js/pull/3451) [`8f94a9e`](https://github.com/solana-labs/solana-web3.js/commit/8f94a9ede71b32662bff991e6def68bc9e8bc921) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a \\`getRpcSubscriptionsChannelWithBigIntJSONSerialization\\` helper function that parses and stringifies JSON messages with support for \\`BigInt\\` values. Any integer value is parsed as a \\`BigInt\\` in order to safely handle numbers that exceed the JavaScript \\`Number.MAX_SAFE_INTEGER\\` value.\n\n- [#3406](https://github.com/solana-labs/solana-web3.js/pull/3406) [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Replace subscriptionConfigurationHash with RpcRequest in RpcSubscriptionPlan\n\n- [#2504](https://github.com/solana-labs/solana-web3.js/pull/2504) [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763) Thanks [@steveluscher](https://github.com/steveluscher)! - Replaced `fast-stable-stringify` with our fork\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc) Thanks [@steveluscher](https://github.com/steveluscher)! - We refactored the lower levels of the subscriptions API entirely.\n\n    Previously, all layers of the subscriptions implementation, from the `WebSocket` transport to the API that developers use, dealt in `AsyncIterables`. These are notoriously difficult to code in such a way that expresses all of the ways in which a subscription might be cancelled or error out. Very slight omissions of care could open memory leaks that would bring down the simplest of apps. The new subscriptions infra in Release Candidate 2 deals with event-based subscriptions all the way up to the highest level API, at which point the subscription is vended to the application as an `AsyncIterable`.\n\n    This has eliminated several classes of memory leak and has made it easier to implement higher-level transports (like the autopinger and the subscription coalescer). Additionally, this update introduces a new channel pool implementation that opens new `WebSocket` connections when existing ones become ‘full.’ Lastly, performance in the new implementation has been improved through a new demultiplexing utility that can separate `message` events into several channels based on arbitrary criteria, meaning you can apply transforms to the message right at the source, and vend subscriptions to downstream consumers that care only about one particular kind of message.\n\n- Updated dependencies [[`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677), [`5ed19c6`](https://github.com/solana-labs/solana-web3.js/commit/5ed19c6c3c6e7a1bacde8c23c438ecb85454b126), [`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`17c373d`](https://github.com/solana-labs/solana-web3.js/commit/17c373dec6dd167ea5b4e37e213067aa05fa4e14), [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`8c2cb9f`](https://github.com/solana-labs/solana-web3.js/commit/8c2cb9f44a52b3c27bc15c2c972bea1aae1622e7), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d), [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4), [`92655fd`](https://github.com/solana-labs/solana-web3.js/commit/92655fda6631339f07c6cd7097ed9e2518f86853), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc)]:\n    - @solana/rpc-subscriptions-spec@2.0.0\n    - @solana/rpc-subscriptions-api@2.0.0\n    - @solana/fast-stable-stringify@2.0.0\n    - @solana/errors@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/rpc-transformers@2.0.0\n    - @solana/rpc-spec-types@2.0.0\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0\n    - @solana/subscribable@2.0.0\n    - @solana/functional@2.0.0\n    - @solana/promises@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0-rc.4\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.4\n    - @solana/rpc-transformers@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/subscribable@2.0.0-rc.4\n    - @solana/rpc-subscriptions-api@2.0.0-rc.4\n    - @solana/fast-stable-stringify@2.0.0-rc.4\n    - @solana/functional@2.0.0-rc.4\n    - @solana/promises@2.0.0-rc.4\n    - @solana/rpc-spec-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- [#3507](https://github.com/solana-labs/solana-web3.js/pull/3507) [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fixed a bug where the subcription server's response would not be detected, because of a mismatch in the format of the `id`. Now all RPC message ids are strings, for avoidance of doubt.\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-spec-types@2.0.0-rc.3\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.3\n    - @solana/rpc-transformers@2.0.0-rc.3\n    - @solana/rpc-subscriptions-api@2.0.0-rc.3\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/fast-stable-stringify@2.0.0-rc.3\n    - @solana/functional@2.0.0-rc.3\n    - @solana/promises@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n    - @solana/subscribable@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Change first argument of `onIntegerOverflow` handler from `methodName: string` to `request: RpcRequest`\n\n- [#3455](https://github.com/solana-labs/solana-web3.js/pull/3455) [`500a991`](https://github.com/solana-labs/solana-web3.js/commit/500a991d292638eaee1fa48a7b94acfe2ff83cb7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Adds a channel creator function called `createDefaultSolanaRpcSubscriptionsChannelCreator`. This function works similarly to `createDefaultRpcSubscriptionsChannelCreator` but with some Solana-specific defaults. For instance, it safely handles `BigInt` values in JSON messages since Solana RPC servers accept and return integers larger than `Number.MAX_SAFE_INTEGER`.\n\n- [#3451](https://github.com/solana-labs/solana-web3.js/pull/3451) [`8f94a9e`](https://github.com/solana-labs/solana-web3.js/commit/8f94a9ede71b32662bff991e6def68bc9e8bc921) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a \\`getRpcSubscriptionsChannelWithBigIntJSONSerialization\\` helper function that parses and stringifies JSON messages with support for \\`BigInt\\` values. Any integer value is parsed as a \\`BigInt\\` in order to safely handle numbers that exceed the JavaScript \\`Number.MAX_SAFE_INTEGER\\` value.\n\n- [#3406](https://github.com/solana-labs/solana-web3.js/pull/3406) [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Replace subscriptionConfigurationHash with RpcRequest in RpcSubscriptionPlan\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc) Thanks [@steveluscher](https://github.com/steveluscher)! - We refactored the lower levels of the subscriptions API entirely.\n\n    Previously, all layers of the subscriptions implementation, from the `WebSocket` transport to the API that developers use, dealt in `AsyncIterables`. These are notoriously difficult to code in such a way that expresses all of the ways in which a subscription might be cancelled or error out. Very slight omissions of care could open memory leaks that would bring down the simplest of apps. The new subscriptions infra in Release Candidate 2 deals with event-based subscriptions all the way up to the highest level API, at which point the subscription is vended to the application as an `AsyncIterable`.\n\n    This has eliminated several classes of memory leak and has made it easier to implement higher-level transports (like the autopinger and the subscription coalescer). Additionally, this update introduces a new channel pool implementation that opens new `WebSocket` connections when existing ones become ‘full.’ Lastly, performance in the new implementation has been improved through a new demultiplexing utility that can separate `message` events into several channels based on arbitrary criteria, meaning you can apply transforms to the message right at the source, and vend subscriptions to downstream consumers that care only about one particular kind of message.\n\n- Updated dependencies [[`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`17c373d`](https://github.com/solana-labs/solana-web3.js/commit/17c373dec6dd167ea5b4e37e213067aa05fa4e14), [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`8c2cb9f`](https://github.com/solana-labs/solana-web3.js/commit/8c2cb9f44a52b3c27bc15c2c972bea1aae1622e7), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c), [`92655fd`](https://github.com/solana-labs/solana-web3.js/commit/92655fda6631339f07c6cd7097ed9e2518f86853), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc)]:\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.2\n    - @solana/rpc-subscriptions-api@2.0.0-rc.2\n    - @solana/rpc-transformers@2.0.0-rc.2\n    - @solana/rpc-spec-types@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/subscribable@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0-rc.2\n    - @solana/fast-stable-stringify@2.0.0-rc.2\n    - @solana/functional@2.0.0-rc.2\n    - @solana/promises@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- [#3072](https://github.com/solana-labs/solana-web3.js/pull/3072) [`c122c75`](https://github.com/solana-labs/solana-web3.js/commit/c122c75936e8fa5364edf114a5182cf119b26922) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a memory leak with transaction confirmation and subscriptions\n\n- Updated dependencies [[`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8), [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d)]:\n    - @solana/promises@2.0.0-rc.1\n    - @solana/rpc-subscriptions-api@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/fast-stable-stringify@2.0.0-rc.1\n    - @solana/functional@2.0.0-rc.1\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.1\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0-rc.1\n    - @solana/rpc-transformers@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- Updated dependencies [[`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/rpc-transformers@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0-rc.0\n    - @solana/rpc-subscriptions-api@2.0.0-rc.0\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n    - @solana/fast-stable-stringify@2.0.0-rc.0\n    - @solana/functional@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0-preview.4\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.4\n    - @solana/fast-stable-stringify@2.0.0-preview.4\n    - @solana/rpc-subscriptions-api@2.0.0-preview.4\n    - @solana/rpc-transformers@2.0.0-preview.4\n    - @solana/functional@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2504](https://github.com/solana-labs/solana-web3.js/pull/2504) [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763) Thanks [@steveluscher](https://github.com/steveluscher)! - Replaced `fast-stable-stringify` with our fork\n\n- Updated dependencies [[`5ed19c6`](https://github.com/solana-labs/solana-web3.js/commit/5ed19c6c3c6e7a1bacde8c23c438ecb85454b126), [`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4)]:\n    - @solana/fast-stable-stringify@2.0.0-preview.3\n    - @solana/errors@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/rpc-transformers@2.0.0-preview.3\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.3\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0-preview.3\n    - @solana/rpc-subscriptions-api@2.0.0-preview.3\n    - @solana/functional@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n    - @solana/functional@2.0.0-preview.2\n    - @solana/rpc-subscriptions-api@2.0.0-preview.2\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.2\n    - @solana/rpc-subscriptions-channel-websocket@2.0.0-preview.2\n    - @solana/rpc-transformers@2.0.0-preview.2\n    - @solana/rpc-types@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-subscriptions/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-subscriptions/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-subscriptions?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-subscriptions?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-subscriptions\n\n# @solana/rpc-subscriptions\n\nThis package contains types that implement RPC subscriptions as required by the Solana RPC. Additionally, it incorporates some useful defaults that make working with subscriptions easier, more performant, and more reliable. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Functions\n\n### `createDefaultRpcSubscriptionsChannelCreator(config)`\n\nCreates a function that returns new subscription channels when called.\n\n### `createDefaultSolanaRpcSubscriptionsChannelCreator(config)`\n\nSimilar to `createDefaultRpcSubscriptionsChannelCreator` with some Solana-specific defaults. For instance, it safely handles `BigInt` values in JSON messages since Solana RPC servers accept and return integers larger than `Number.MAX_SAFE_INTEGER`.\n\n#### Arguments\n\nA config object with the following properties:\n\n- `intervalMs`: The number of milliseconds to wait since the last message sent or received over the channel before sending a ping message to keep the channel open.\n- `maxSubscriptionsPerChannel`: The number of subscribers that may share a channel before a new channel must be created (default: 100). It is important that you set this to the maximum number of subscriptions that your RPC provider recommends making over a single connection; the default is set deliberately low, so as to comply with the restrictive limits of the public mainnet RPC node.\n- `minChannels`: The number of channels to create before reusing a channel for a new subscription.\n- `sendBufferHighWatermark`: The number of bytes of data to admit into the `WebSocket` buffer before buffering data on the client. -`url`: The URL of the web socket server. Must use the `ws` or `wss` protocols.\n\n### `getChannelPoolingChannelCreator(createChannel, { maxSubscriptionsPerChannel, minChannels })`\n\nGiven a channel creator, will return a new channel creator with the following behavior.\n\n1. When called, returns a `RpcSubscriptionsChannel`. Adds that channel to a pool.\n2. When called again, creates and returns new `RpcSubscriptionChannels` up to the number specified by `minChannels`.\n3. When `minChannels` channels have been created, subsequent calls vend whichever existing channel from the pool has the fewest subscribers, or the next one in rotation in the event of a tie.\n4. Once all channels carry the number of subscribers specified by the number `maxSubscriptionsPerChannel`, new channels in excess of `minChannel` will be created, returned, and added to the pool.\n5. A channel will be destroyed once all of its subscribers' abort signals fire.\n\n### `getRpcSubscriptionsChannelWithJSONSerialization(channel)`\n\nGiven a `RpcSubscriptionsChannel`, will return a new channel that parses data published to the `'message'` channel as JSON, and JSON-stringifies messages sent via the `send(message)` method.\n\n### `getRpcSubscriptionsChannelWithBigIntJSONSerialization(channel)`\n\nSimilarly, to `getRpcSubscriptionsChannelWithJSONSerialization`, this function will stringify and parse JSON message to and from the given `string` channel. However, this function parses any integer value as a `BigInt` in order to safely handle numbers that exceed the JavaScript `Number.MAX_SAFE_INTEGER` value.\n\n### `getRpcSubscriptionsChannelWithAutoping(channel)`\n\nGiven a `RpcSubscriptionsChannel`, will return a new channel that sends a ping message to the inner channel if a message has not been sent or received in the last `intervalMs`. In web browsers, this implementation sends no ping when the network is down, and sends a ping immediately upon the network coming back up.\n\n### `getRpcSubscriptionsTransportWithSubscriptionCoalescing(transport)`\n\nGiven a `RpcSubscriptionsTransport`, will return a new transport that coalesces identical subscriptions into a single subscription request to the server. The determination of whether a subscription is the same as another is based on the `rpcRequest` returned by its `RpcSubscriptionsPlan`. The subscription will only be aborted once all subscribers abort, or there is an error.\n"
  },
  {
    "path": "packages/rpc-subscriptions/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-subscriptions\",\n    \"version\": \"6.9.0\",\n    \"description\": \"A library for subscribing to Solana RPC notifications\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-subscriptions\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/fast-stable-stringify\": \"workspace:*\",\n        \"@solana/functional\": \"workspace:*\",\n        \"@solana/promises\": \"workspace:*\",\n        \"@solana/rpc-spec-types\": \"workspace:*\",\n        \"@solana/rpc-subscriptions-api\": \"workspace:*\",\n        \"@solana/rpc-subscriptions-channel-websocket\": \"workspace:*\",\n        \"@solana/rpc-subscriptions-spec\": \"workspace:*\",\n        \"@solana/rpc-transformers\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/subscribable\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/event-target-impl\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__tests__/rpc-integer-overflow-error-test.ts",
    "content": "import { SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from '../rpc-integer-overflow-error';\n\ndescribe('createSolanaJsonRpcIntegerOverflowError()', () => {\n    it('creates a `SolanaError`', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [2 /* third argument */], 1n);\n        expect(error).toBeInstanceOf(SolanaError);\n    });\n    it('creates a `SolanaError` with the code `SOLANA_ERROR__RPC__INTEGER_OVERFLOW`', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [2 /* third argument */], 1n);\n        expect(error).toHaveProperty('context.__code', SOLANA_ERROR__RPC__INTEGER_OVERFLOW);\n    });\n    it('creates a `SolanaError` with the correct context for a path-less violation', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [2 /* third argument */], 1n);\n        expect(error).toEqual(\n            new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n                argumentLabel: '3rd',\n                keyPath: [2],\n                methodName: 'someMethod',\n                optionalPathLabel: '',\n                value: 1n,\n            }),\n        );\n    });\n    it('creates a `SolanaError` with the correct context for a violation with a deep path', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [0 /* first argument */, 'foo', 'bar'], 1n);\n        expect(error).toHaveProperty('context.optionalPathLabel', ' at path `foo.bar`');\n        expect(error).toHaveProperty('context.path', 'foo.bar');\n    });\n    it('omits the error factory function itself from the stack trace', () => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [0 /* first argument */, 'foo', 'bar'], 1n);\n        expect(error.stack).not.toMatch(/createSolanaJsonRpcIntegerOverflowError/);\n    });\n    it.each(\n        Object.entries({\n            ...(() => {\n                const out: Record<number, string> = {};\n                Array.from({ length: 100 }).forEach((_, ii) => {\n                    const lastDigit = ii % 10;\n                    // eslint-disable-next-line jest/no-conditional-in-test\n                    if (lastDigit === 0) {\n                        out[ii] = `${ii + 1}st`;\n                        // eslint-disable-next-line jest/no-conditional-in-test\n                    } else if (lastDigit === 1) {\n                        out[ii] = `${ii + 1}nd`;\n                        // eslint-disable-next-line jest/no-conditional-in-test\n                    } else if (lastDigit === 2) {\n                        out[ii] = `${ii + 1}rd`;\n                    } else {\n                        out[ii] = `${ii + 1}th`;\n                    }\n                });\n                return out;\n            })(),\n            10: '11th',\n            11: '12th',\n            12: '13th',\n        }),\n    )('computes the correct ordinal when crafting the argument label', (index, expectedLabel) => {\n        const error = createSolanaJsonRpcIntegerOverflowError('someMethod', [parseInt(index, 10)], 1n);\n        expect(error).toHaveProperty('context.argumentLabel', expectedLabel);\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__tests__/rpc-subscriptions-autopinger-test.ts",
    "content": "import { SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, SolanaError } from '@solana/errors';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\n\nimport { getRpcSubscriptionsChannelWithAutoping } from '../rpc-subscriptions-autopinger';\n\nconst MOCK_INTERVAL_MS = 60_000;\n\ndescribe('getRpcSubscriptionsChannelWithAutoping', () => {\n    let mockChannel: RpcSubscriptionsChannel<unknown, unknown>;\n    let mockOn: jest.Mock;\n    let mockSend: jest.Mock;\n    let mockWindowAddEventListener: jest.Mock;\n    let originalWindowAddEventListener: typeof globalThis.addEventListener;\n    function receiveError(error?: unknown) {\n        mockOn.mock.calls.filter(([type]) => type === 'error').forEach(([_, listener]) => listener(error));\n    }\n    function receiveMessage(message: unknown) {\n        mockOn.mock.calls.filter(([type]) => type === 'message').forEach(([_, listener]) => listener(message));\n    }\n    function dispatchWindowEvent(eventName: 'offline' | 'online') {\n        mockWindowAddEventListener.mock.calls\n            .filter(([type]) => type === eventName)\n            .forEach(([_, listener]) => listener());\n    }\n    beforeEach(() => {\n        jest.useFakeTimers();\n        if (__BROWSER__) {\n            originalWindowAddEventListener = globalThis.addEventListener;\n            globalThis.addEventListener = mockWindowAddEventListener = jest.fn();\n        }\n        mockOn = jest.fn().mockReturnValue(() => {});\n        mockSend = jest.fn().mockResolvedValue(void 0);\n        mockChannel = {\n            on: mockOn,\n            send: mockSend,\n        };\n    });\n    afterEach(() => {\n        if (__BROWSER__) {\n            globalThis.addEventListener = originalWindowAddEventListener;\n        }\n    });\n    it('sends a ping message to the channel at the specified interval', async () => {\n        expect.assertions(4);\n        getRpcSubscriptionsChannelWithAutoping({\n            abortSignal: new AbortController().signal,\n            channel: mockChannel,\n            intervalMs: MOCK_INTERVAL_MS,\n        });\n        // First ping.\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS - 1);\n        expect(mockSend).not.toHaveBeenCalled();\n        await jest.advanceTimersByTimeAsync(1);\n        expect(mockSend).toHaveBeenCalledWith(\n            expect.objectContaining({\n                jsonrpc: '2.0',\n                method: 'ping',\n            }),\n        );\n        // Second ping.\n        mockSend.mockClear();\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS - 1);\n        expect(mockSend).not.toHaveBeenCalled();\n        await jest.advanceTimersByTimeAsync(1);\n        expect(mockSend).toHaveBeenCalledWith(\n            expect.objectContaining({\n                jsonrpc: '2.0',\n                method: 'ping',\n            }),\n        );\n    });\n    it('continues to ping even though send fataled with a non-connection-closed exception', async () => {\n        expect.assertions(1);\n        mockSend.mockRejectedValue(\n            // Anything other than `SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED`.\n            'o no',\n        );\n        getRpcSubscriptionsChannelWithAutoping({\n            abortSignal: new AbortController().signal,\n            channel: mockChannel,\n            intervalMs: MOCK_INTERVAL_MS,\n        });\n        // First ping.\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n        // Second ping.\n        mockSend.mockClear();\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n        expect(mockSend).toHaveBeenCalledWith(\n            expect.objectContaining({\n                jsonrpc: '2.0',\n                method: 'ping',\n            }),\n        );\n    });\n    it('does not send a ping until interval milliseconds after the last sent message', async () => {\n        expect.assertions(3);\n        const autopingChannel = getRpcSubscriptionsChannelWithAutoping({\n            abortSignal: new AbortController().signal,\n            channel: mockChannel,\n            intervalMs: MOCK_INTERVAL_MS,\n        });\n        autopingChannel.send('hi').catch(() => {});\n        mockSend.mockClear();\n        await jest.advanceTimersByTimeAsync(500);\n        expect(mockSend).not.toHaveBeenCalled();\n        autopingChannel.send('hi').catch(() => {});\n        mockSend.mockClear();\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS - 1);\n        expect(mockSend).not.toHaveBeenCalled();\n        await jest.advanceTimersByTimeAsync(1);\n        expect(mockSend).toHaveBeenCalledWith(\n            expect.objectContaining({\n                jsonrpc: '2.0',\n                method: 'ping',\n            }),\n        );\n    });\n    it('does not send a ping until interval milliseconds after the last received message', async () => {\n        expect.assertions(3);\n        getRpcSubscriptionsChannelWithAutoping({\n            abortSignal: new AbortController().signal,\n            channel: mockChannel,\n            intervalMs: MOCK_INTERVAL_MS,\n        });\n        await jest.advanceTimersByTimeAsync(500);\n        expect(mockSend).not.toHaveBeenCalled();\n        receiveMessage('hi');\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS - 1);\n        expect(mockSend).not.toHaveBeenCalled();\n        await jest.advanceTimersByTimeAsync(1);\n        expect(mockSend).toHaveBeenCalledWith(\n            expect.objectContaining({\n                jsonrpc: '2.0',\n                method: 'ping',\n            }),\n        );\n    });\n    it('does not send a ping after a channel error', async () => {\n        expect.assertions(2);\n        getRpcSubscriptionsChannelWithAutoping({\n            abortSignal: new AbortController().signal,\n            channel: mockChannel,\n            intervalMs: MOCK_INTERVAL_MS,\n        });\n        // First ping.\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n        expect(mockSend).toHaveBeenCalledWith(\n            expect.objectContaining({\n                jsonrpc: '2.0',\n                method: 'ping',\n            }),\n        );\n        receiveError('o no');\n        // No more pings.\n        mockSend.mockClear();\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n        expect(mockSend).not.toHaveBeenCalled();\n    });\n    it('does not send a ping after send fatals with a connection closed error', async () => {\n        expect.assertions(1);\n        mockSend.mockRejectedValue(new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED));\n        getRpcSubscriptionsChannelWithAutoping({\n            abortSignal: new AbortController().signal,\n            channel: mockChannel,\n            intervalMs: MOCK_INTERVAL_MS,\n        });\n        // First ping.\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n        // No more pings.\n        mockSend.mockClear();\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n        expect(mockSend).not.toHaveBeenCalled();\n    });\n    it('does not send a ping after the abort signal fires', async () => {\n        expect.assertions(2);\n        const abortController = new AbortController();\n        getRpcSubscriptionsChannelWithAutoping({\n            abortSignal: abortController.signal,\n            channel: mockChannel,\n            intervalMs: MOCK_INTERVAL_MS,\n        });\n        // First ping.\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n        expect(mockSend).toHaveBeenCalledWith(\n            expect.objectContaining({\n                jsonrpc: '2.0',\n                method: 'ping',\n            }),\n        );\n        abortController.abort();\n        // No more pings.\n        mockSend.mockClear();\n        await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n        expect(mockSend).not.toHaveBeenCalled();\n    });\n    if (__BROWSER__) {\n        it('stops pinging the connection when it goes offline', async () => {\n            expect.assertions(1);\n            getRpcSubscriptionsChannelWithAutoping({\n                abortSignal: new AbortController().signal,\n                channel: mockChannel,\n                intervalMs: MOCK_INTERVAL_MS,\n            });\n            dispatchWindowEvent('offline');\n            await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n            expect(mockSend).not.toHaveBeenCalled();\n        });\n        describe('when the network connection is offline to start', () => {\n            beforeEach(() => {\n                const originalNavigator = globalThis.navigator;\n                jest.spyOn(globalThis, 'navigator', 'get').mockImplementation(() => ({\n                    ...originalNavigator,\n                    onLine: false,\n                }));\n            });\n            it('does not ping the connection', async () => {\n                expect.assertions(1);\n                getRpcSubscriptionsChannelWithAutoping({\n                    abortSignal: new AbortController().signal,\n                    channel: mockChannel,\n                    intervalMs: MOCK_INTERVAL_MS,\n                });\n                await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS);\n                expect(mockSend).not.toHaveBeenCalled();\n            });\n            it('pings the connection immediately when the connection comes back online', async () => {\n                expect.assertions(1);\n                getRpcSubscriptionsChannelWithAutoping({\n                    abortSignal: new AbortController().signal,\n                    channel: mockChannel,\n                    intervalMs: MOCK_INTERVAL_MS,\n                });\n                await jest.advanceTimersByTimeAsync(500);\n                dispatchWindowEvent('online');\n                expect(mockSend).toHaveBeenCalledWith(\n                    expect.objectContaining({\n                        jsonrpc: '2.0',\n                        method: 'ping',\n                    }),\n                );\n            });\n            it('pings the connection interval milliseconds after the connection comes back online', async () => {\n                expect.assertions(3);\n                getRpcSubscriptionsChannelWithAutoping({\n                    abortSignal: new AbortController().signal,\n                    channel: mockChannel,\n                    intervalMs: MOCK_INTERVAL_MS,\n                });\n                await jest.advanceTimersByTimeAsync(500);\n                dispatchWindowEvent('online');\n                mockSend.mockClear();\n                expect(mockSend).not.toHaveBeenCalled();\n                await jest.advanceTimersByTimeAsync(MOCK_INTERVAL_MS - 1);\n                expect(mockSend).not.toHaveBeenCalled();\n                await jest.advanceTimersByTimeAsync(1);\n                expect(mockSend).toHaveBeenCalledWith(\n                    expect.objectContaining({\n                        jsonrpc: '2.0',\n                        method: 'ping',\n                    }),\n                );\n            });\n        });\n    }\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__tests__/rpc-subscriptions-channel-pool-test.ts",
    "content": "import { RpcSubscriptionsChannel, RpcSubscriptionsChannelCreator } from '@solana/rpc-subscriptions-spec';\n\nimport { getChannelPoolingChannelCreator } from '../rpc-subscriptions-channel-pool';\nimport { ChannelPoolEntry, createChannelPool } from '../rpc-subscriptions-channel-pool-internal';\n\njest.mock('../rpc-subscriptions-channel-pool-internal.ts');\n\ndescribe('getChannelPoolingChannelCreator', () => {\n    let channelPool: { entries: ChannelPoolEntry[]; freeChannelIndex: number };\n    let createChannel: jest.MockedFunction<RpcSubscriptionsChannelCreator<unknown, unknown>>;\n    beforeEach(() => {\n        channelPool = { entries: [], freeChannelIndex: -1 };\n        jest.mocked(createChannelPool).mockReturnValue(channelPool);\n        createChannel = jest\n            .fn()\n            // We need this to return a new promise on every call.\n            // eslint-disable-next-line jest/prefer-mock-promise-shorthand\n            .mockImplementation(() =>\n                Promise.resolve({\n                    on: jest.fn().mockReturnValue(() => {}),\n                    send: jest.fn().mockResolvedValue(void 0),\n                }),\n            );\n    });\n    it('creates a new channel when there are fewer than `minChannels`', async () => {\n        expect.assertions(2);\n        const newChannel = {} as RpcSubscriptionsChannel<unknown, unknown>;\n        createChannel.mockResolvedValue(newChannel);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        await poolingChannelCreator({ abortSignal: new AbortController().signal });\n        expect(createChannel).toHaveBeenCalledTimes(1);\n        expect(channelPool).toMatchObject({\n            entries: [{ channel: newChannel, subscriptionCount: 1 }],\n            freeChannelIndex: 0,\n        });\n    });\n    it('increments the subscriber count of an existing channel pool entry when vending it', () => {\n        const newChannel = {} as RpcSubscriptionsChannel<unknown, unknown>;\n        createChannel.mockResolvedValue(newChannel);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        expect(channelPool).toMatchObject({\n            entries: [{ channel: newChannel, subscriptionCount: 2 }],\n            freeChannelIndex: 0,\n        });\n    });\n    it('creates a new channel pool entry when the existing one already has `maxSubscriptionsPerChannel` consumers', () => {\n        const newChannelA = {} as RpcSubscriptionsChannel<unknown, unknown>;\n        const newChannelB = {} as RpcSubscriptionsChannel<unknown, unknown>;\n        createChannel.mockResolvedValueOnce(newChannelA).mockResolvedValueOnce(newChannelB);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: 1,\n            minChannels: 1,\n        });\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        expect(channelPool).toMatchObject({\n            entries: [\n                { channel: newChannelA, subscriptionCount: 1 },\n                { channel: newChannelB, subscriptionCount: 1 },\n            ],\n            freeChannelIndex: -1,\n        });\n    });\n    it('destroys a channel when the last subscriber aborts', () => {\n        const newChannelA = {} as RpcSubscriptionsChannel<unknown, unknown>;\n        const newChannelB = {} as RpcSubscriptionsChannel<unknown, unknown>;\n        createChannel.mockResolvedValueOnce(newChannelA).mockResolvedValueOnce(newChannelB);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        const abortController = new AbortController();\n        poolingChannelCreator({ abortSignal: abortController.signal }).catch(() => {});\n        expect(channelPool).toMatchObject({\n            entries: [{ channel: newChannelA, subscriptionCount: 1 }],\n            freeChannelIndex: 0,\n        });\n        abortController.abort();\n        expect(channelPool).toMatchObject({\n            entries: [],\n            freeChannelIndex: -1,\n        });\n    });\n    it('moves the free channel index to the next channel with the most capacity when destroying the existing one', () => {\n        const channelPool = { entries: [] as ChannelPoolEntry[], freeChannelIndex: -1 };\n        jest.mocked(createChannelPool).mockReturnValue(channelPool);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        const abortController = new AbortController();\n        poolingChannelCreator({ abortSignal: abortController.signal }).catch(() => {});\n        channelPool.entries = [\n            { subscriptionCount: 2 },\n            ...channelPool.entries,\n            { subscriptionCount: 3 },\n        ] as ChannelPoolEntry[];\n        channelPool.freeChannelIndex = 1;\n        expect(channelPool).toMatchObject({\n            entries: [{ subscriptionCount: 2 }, { subscriptionCount: 1 }, { subscriptionCount: 3 }],\n            freeChannelIndex: 1,\n        });\n        abortController.abort();\n        expect(channelPool).toMatchObject({\n            entries: [{ subscriptionCount: 2 }, { subscriptionCount: 3 }],\n            freeChannelIndex: 0,\n        });\n    });\n    it('preserves the free channel index when destroying a channel even if that channel is now tied for the highest capacity', () => {\n        const channelPool = { entries: [] as ChannelPoolEntry[], freeChannelIndex: -1 };\n        jest.mocked(createChannelPool).mockReturnValue(channelPool);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        const abortController = new AbortController();\n        poolingChannelCreator({ abortSignal: abortController.signal }).catch(() => {});\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        channelPool.entries = [...channelPool.entries, { subscriptionCount: 1 }] as ChannelPoolEntry[];\n        channelPool.freeChannelIndex = 1;\n        expect(channelPool).toMatchObject({\n            entries: [{ subscriptionCount: 2 }, { subscriptionCount: 1 }],\n            freeChannelIndex: 1,\n        });\n        abortController.abort();\n        expect(channelPool).toMatchObject({\n            entries: [{ subscriptionCount: 1 }, { subscriptionCount: 1 }],\n            freeChannelIndex: 1,\n        });\n    });\n    it('resets the free channel index whenever destroying a channel results in there being fewer than `minChannels`', () => {\n        const channelPool = { entries: [] as ChannelPoolEntry[], freeChannelIndex: -1 };\n        jest.mocked(createChannelPool).mockReturnValue(channelPool);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: 2,\n            minChannels: 2,\n        });\n        const abortController = new AbortController();\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        poolingChannelCreator({ abortSignal: abortController.signal }).catch(() => {});\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        expect(channelPool).toMatchObject({\n            entries: [{ subscriptionCount: 2 }, { subscriptionCount: 1 }],\n            freeChannelIndex: 1,\n        });\n        abortController.abort();\n        expect(channelPool).toMatchObject({\n            entries: [{ subscriptionCount: 2 }],\n            freeChannelIndex: -1,\n        });\n    });\n    it('vends an existing channel when called in a separate runloop', async () => {\n        expect.assertions(1);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        const channelA = await poolingChannelCreator({ abortSignal: new AbortController().signal });\n        const channelB = await poolingChannelCreator({ abortSignal: new AbortController().signal });\n        expect(channelA).toBe(channelB);\n    });\n    it('vends an existing channel when called concurrently in the same runloop', async () => {\n        expect.assertions(1);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        const [channelA, channelB] = await Promise.all([\n            poolingChannelCreator({ abortSignal: new AbortController().signal }),\n            poolingChannelCreator({ abortSignal: new AbortController().signal }),\n        ]);\n        expect(channelA).toBe(channelB);\n    });\n    it(\"fires a created channel's abort signal when the outer signal is aborted\", async () => {\n        expect.assertions(1);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        const abortController = new AbortController();\n        await poolingChannelCreator({ abortSignal: abortController.signal });\n        abortController.abort();\n        expect(createChannel.mock.lastCall?.[0].abortSignal).toHaveProperty('aborted', true);\n    });\n    it(\"fires a created channel's abort signal when the outer signal is aborted within the runloop\", () => {\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        const abortController = new AbortController();\n        poolingChannelCreator({ abortSignal: abortController.signal }).catch(() => {});\n        abortController.abort();\n        expect(createChannel.mock.lastCall?.[0].abortSignal).toHaveProperty('aborted', true);\n    });\n    it('vends the next existing channel with the fewest consumers', async () => {\n        expect.assertions(2);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: 2,\n            minChannels: 1,\n        });\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        expect(channelPool).toMatchObject({\n            entries: [{ subscriptionCount: 2 }, { subscriptionCount: 1 }],\n            freeChannelIndex: 1,\n        });\n        const channel = poolingChannelCreator({ abortSignal: new AbortController().signal });\n        await expect(channel).resolves.toBe(await channelPool.entries[1].channel);\n    });\n    it('does not create a channel pool entry when the channel fails to construct', async () => {\n        expect.assertions(3);\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        createChannel.mockRejectedValueOnce('o no');\n        const channelA = poolingChannelCreator({ abortSignal: new AbortController().signal });\n        const channelB = poolingChannelCreator({ abortSignal: new AbortController().signal });\n        await expect(channelA).rejects.toBe('o no');\n        await expect(channelB).rejects.toBe('o no');\n        expect(channelPool).toMatchObject({ entries: [], freeChannelIndex: -1 });\n    });\n    it(\"destroys a channel's pool entry when the channel encounters an error message\", async () => {\n        expect.assertions(2);\n        jest.useFakeTimers();\n        const poolingChannelCreator = getChannelPoolingChannelCreator(createChannel, {\n            maxSubscriptionsPerChannel: Number.POSITIVE_INFINITY,\n            minChannels: 1,\n        });\n        const errorListeners: CallableFunction[] = [];\n        createChannel.mockResolvedValue({\n            on(type, listener) {\n                // eslint-disable-next-line jest/no-conditional-in-test\n                if (type === 'error') {\n                    errorListeners.push(listener);\n                }\n                return () => {};\n            },\n            send: jest.fn(),\n        });\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        poolingChannelCreator({ abortSignal: new AbortController().signal }).catch(() => {});\n        expect(channelPool).toMatchObject({\n            entries: [{ subscriptionCount: 2 }],\n            freeChannelIndex: 0,\n        });\n        // Allow time for the channel to open and the error listener attach.\n        await jest.runAllTimersAsync();\n        errorListeners.forEach(listener => {\n            listener('o no');\n        });\n        expect(channelPool).toMatchObject({ entries: [], freeChannelIndex: -1 });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__tests__/rpc-subscriptions-coalescer-test.ts",
    "content": "import type { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\n\nimport { getRpcSubscriptionsTransportWithSubscriptionCoalescing } from '../rpc-subscriptions-coalescer';\n\ndescribe('getRpcSubscriptionsTransportWithSubscriptionCoalescing', () => {\n    let mockInnerTransport: jest.Mock;\n    let mockOn: jest.Mock;\n    let coalescedTransport: RpcSubscriptionsTransport;\n    function receiveError(err?: unknown) {\n        mockOn.mock.calls.filter(([type]) => type === 'error').forEach(([_, listener]) => listener(err));\n    }\n    beforeEach(() => {\n        mockOn = jest.fn();\n        mockInnerTransport = jest.fn().mockResolvedValue({ on: mockOn });\n        coalescedTransport = getRpcSubscriptionsTransportWithSubscriptionCoalescing(mockInnerTransport);\n    });\n    it('returns the inner transport', async () => {\n        expect.assertions(1);\n        const expectedDataPublisher = { on: mockOn };\n        mockInnerTransport.mockResolvedValue(expectedDataPublisher);\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n            signal: new AbortController().signal,\n        };\n        const transportPromise = coalescedTransport(config);\n        await expect(transportPromise).resolves.toBe(expectedDataPublisher);\n    });\n    it('passes the `execute` config to the inner transport', () => {\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n            signal: new AbortController().signal,\n        };\n        coalescedTransport(config).catch(() => {});\n        expect(mockInnerTransport).toHaveBeenCalledWith(\n            expect.objectContaining({\n                execute: config.execute,\n            }),\n        );\n    });\n    it('passes the `rpcRequest` config to the inner transport', () => {\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n            signal: new AbortController().signal,\n        };\n        coalescedTransport(config).catch(() => {});\n        expect(mockInnerTransport).toHaveBeenCalledWith(\n            expect.objectContaining({\n                request: { methodName: 'foo', params: [] },\n            }),\n        );\n    });\n    it('calls the inner transport once per subscriber whose hashes do not match, in the same runloop', () => {\n        const config = {\n            execute: jest.fn(),\n            signal: new AbortController().signal,\n        };\n        coalescedTransport({\n            request: { methodName: 'methodA', params: [] },\n            ...config,\n        }).catch(() => {});\n        coalescedTransport({\n            request: { methodName: 'methodB', params: [] },\n            ...config,\n        }).catch(() => {});\n        expect(mockInnerTransport).toHaveBeenCalledTimes(2);\n    });\n    it('calls the inner transport once per subscriber whose hashes do not match, in different runloops', async () => {\n        expect.assertions(1);\n        const config = {\n            execute: jest.fn(),\n            signal: new AbortController().signal,\n        };\n        await coalescedTransport({ ...config, request: { methodName: 'methodA', params: [] } });\n        await coalescedTransport({ ...config, request: { methodName: 'methodB', params: [] } });\n        expect(mockInnerTransport).toHaveBeenCalledTimes(2);\n    });\n    it('only calls the inner transport once, in the same runloop', () => {\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n            signal: new AbortController().signal,\n        };\n        coalescedTransport(config).catch(() => {});\n        coalescedTransport(config).catch(() => {});\n        expect(mockInnerTransport).toHaveBeenCalledTimes(1);\n    });\n    it('only calls the inner transport once, in different runloops', async () => {\n        expect.assertions(1);\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n            signal: new AbortController().signal,\n        };\n        await coalescedTransport(config);\n        await coalescedTransport(config);\n        expect(mockInnerTransport).toHaveBeenCalledTimes(1);\n    });\n    it('delivers the same value to each subscriber, in the same runloop', async () => {\n        expect.assertions(1);\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n            signal: new AbortController().signal,\n        };\n        const [publisherA, publisherB] = await Promise.all([coalescedTransport(config), coalescedTransport(config)]);\n        expect(publisherA).toBe(publisherB);\n    });\n    it('delivers the same value to each subscriber, in different runloops', async () => {\n        expect.assertions(1);\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n            signal: new AbortController().signal,\n        };\n        const publisherA = await coalescedTransport(config);\n        const publisherB = await coalescedTransport(config);\n        expect(publisherA).toBe(publisherB);\n    });\n    it('does not fire the inner abort signal if fewer than all subscribers abort, in the same runloop', () => {\n        jest.useFakeTimers();\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n        };\n        const abortControllerB = new AbortController();\n        coalescedTransport({ ...config, signal: new AbortController().signal }).catch(() => {});\n        coalescedTransport({ ...config, signal: abortControllerB.signal }).catch(() => {});\n        abortControllerB.abort();\n        jest.runAllTicks();\n        expect(mockInnerTransport.mock.lastCall?.[0].signal).toHaveProperty('aborted', false);\n    });\n    it('fires the inner abort signal if all subscribers abort, in the same runloop', () => {\n        jest.useFakeTimers();\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n        };\n        const abortControllerA = new AbortController();\n        const abortControllerB = new AbortController();\n        coalescedTransport({ ...config, signal: abortControllerA.signal }).catch(() => {});\n        coalescedTransport({ ...config, signal: abortControllerB.signal }).catch(() => {});\n        abortControllerA.abort();\n        abortControllerB.abort();\n        jest.runAllTicks();\n        expect(mockInnerTransport.mock.lastCall?.[0].signal).toHaveProperty('aborted', true);\n    });\n    it('fires the inner abort signal if all subscribers abort, in different runloops', async () => {\n        expect.assertions(1);\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n        };\n        const abortControllerA = new AbortController();\n        const abortControllerB = new AbortController();\n        coalescedTransport({ ...config, signal: abortControllerA.signal }).catch(() => {});\n        await jest.runAllTimersAsync();\n        coalescedTransport({ ...config, signal: abortControllerB.signal }).catch(() => {});\n        await jest.runAllTimersAsync();\n        abortControllerA.abort();\n        abortControllerB.abort();\n        jest.runAllTicks();\n        expect(mockInnerTransport.mock.lastCall?.[0].signal).toHaveProperty('aborted', true);\n    });\n    it('does not fire the inner abort signal if the subscriber count is non zero at the end of the runloop, despite having aborted all in the middle of it', () => {\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n        };\n        const abortControllerA = new AbortController();\n        coalescedTransport({ ...config, signal: abortControllerA.signal }).catch(() => {});\n        abortControllerA.abort();\n        coalescedTransport({ ...config, signal: new AbortController().signal }).catch(() => {});\n        jest.runAllTicks();\n        expect(mockInnerTransport.mock.lastCall?.[0].signal).toHaveProperty('aborted', false);\n    });\n    it('does not re-coalesce new requests behind an errored transport', async () => {\n        expect.assertions(1);\n        jest.useFakeTimers();\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n        };\n        coalescedTransport({ ...config, signal: new AbortController().signal }).catch(() => {});\n        await jest.runAllTimersAsync();\n        receiveError('o no');\n        coalescedTransport({ ...config, signal: new AbortController().signal }).catch(() => {});\n        expect(mockInnerTransport).toHaveBeenCalledTimes(2);\n    });\n    it('does not cancel a newly-coalesced transport when an old errored one is aborted', async () => {\n        expect.assertions(2);\n        jest.useFakeTimers();\n        const config = {\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n        };\n        const abortControllerA = new AbortController();\n        /**\n         * PHASE 1\n         * Create and fail a transport.\n         */\n        await coalescedTransport({ ...config, signal: abortControllerA.signal });\n        receiveError('o no');\n        mockInnerTransport.mockClear();\n        /**\n         * PHASE 2\n         * Create a new transport\n         */\n        const publisherA = await coalescedTransport({ ...config, signal: new AbortController().signal });\n        /**\n         * PHASE 3\n         * Abort the original subscriber\n         */\n        abortControllerA.abort();\n        jest.runAllTicks();\n        /**\n         * PHASE 4\n         * Create a new transport and expect it to coalesce behind the one in phase 2\n         */\n        const publisherB = await coalescedTransport({ ...config, signal: new AbortController().signal });\n        expect(publisherA).toBe(publisherB);\n        expect(mockInnerTransport).toHaveBeenCalledTimes(1);\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__tests__/rpc-subscriptions-functional-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountNotificationsApi, SolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\nimport { createSubscriptionRpc, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport {\n    createDefaultRpcSubscriptionsTransport,\n    createDefaultSolanaRpcSubscriptionsChannelCreator,\n    createSolanaRpcSubscriptionsApi,\n} from '..';\n\nfunction createLocalhostSolanaRpcSubscriptions(): RpcSubscriptions<SolanaRpcSubscriptionsApi> {\n    return createSubscriptionRpc({\n        api: createSolanaRpcSubscriptionsApi(),\n        transport: createDefaultRpcSubscriptionsTransport({\n            createChannel: createDefaultSolanaRpcSubscriptionsChannelCreator({ url: 'ws://localhost:8900' }),\n        }),\n    });\n}\n\ndescribe('accountNotifications', () => {\n    let rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi>;\n    beforeEach(() => {\n        rpcSubscriptions = createLocalhostSolanaRpcSubscriptions();\n    });\n\n    it('can subscribe to account notifications', async () => {\n        expect.hasAssertions();\n        const abortController = new AbortController();\n        try {\n            const subscriptionPromise = rpcSubscriptions\n                .accountNotifications('4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc' as Address)\n                .subscribe({ abortSignal: abortController.signal });\n\n            await expect(subscriptionPromise).resolves.toEqual(\n                expect.objectContaining({\n                    [Symbol.asyncIterator]: expect.any(Function),\n                }),\n            );\n        } finally {\n            abortController.abort();\n        }\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__tests__/rpc-subscriptions-json-bigint-test.ts",
    "content": "import { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\n\nimport { getRpcSubscriptionsChannelWithBigIntJSONSerialization } from '../rpc-subscriptions-json-bigint';\n\nconst MAX_SAFE_INTEGER_PLUS_ONE = BigInt(Number.MAX_SAFE_INTEGER) + 1n;\n\ndescribe('getRpcSubscriptionsChannelWithBigIntJSONSerialization', () => {\n    let mockOn: jest.Mock;\n    let mockChannel: RpcSubscriptionsChannel<string, string>;\n    function receiveMessage(message: unknown) {\n        mockOn.mock.calls.filter(([type]) => type === 'message').forEach(([_, listener]) => listener(message));\n    }\n    beforeEach(() => {\n        mockOn = jest.fn();\n        mockChannel = {\n            on: mockOn,\n            send: jest.fn().mockResolvedValue(void 0),\n        };\n    });\n    it('forwards JSON-serialized large integers to the underlying channel', () => {\n        const channel = getRpcSubscriptionsChannelWithBigIntJSONSerialization(mockChannel);\n        channel.send({ value: MAX_SAFE_INTEGER_PLUS_ONE }).catch(() => {});\n        expect(mockChannel.send).toHaveBeenCalledWith(`{\"value\":${MAX_SAFE_INTEGER_PLUS_ONE}}`);\n    });\n    it('deserializes large integers received from the underlying channel as JSON', () => {\n        const channel = getRpcSubscriptionsChannelWithBigIntJSONSerialization(mockChannel);\n        const messageListener = jest.fn();\n        channel.on('message', messageListener);\n        receiveMessage(`{\"value\":${MAX_SAFE_INTEGER_PLUS_ONE}}`);\n        expect(messageListener).toHaveBeenCalledWith({ value: MAX_SAFE_INTEGER_PLUS_ONE });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__tests__/rpc-subscriptions-json-test.ts",
    "content": "import { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\n\nimport { getRpcSubscriptionsChannelWithJSONSerialization } from '../rpc-subscriptions-json';\n\ndescribe('getRpcSubscriptionsChannelWithJSONSerialization', () => {\n    let mockOn: jest.Mock;\n    let channel: RpcSubscriptionsChannel<string, string>;\n    function receiveMessage(message: unknown) {\n        mockOn.mock.calls.filter(([type]) => type === 'message').forEach(([_, listener]) => listener(message));\n    }\n    beforeEach(() => {\n        mockOn = jest.fn();\n        channel = {\n            on: mockOn,\n            send: jest.fn().mockResolvedValue(void 0),\n        };\n    });\n    it('forwards JSON-serialized messages to the underlying channel', () => {\n        const channelWithJSONSerialization = getRpcSubscriptionsChannelWithJSONSerialization(channel);\n        channelWithJSONSerialization.send('hello').catch(() => {});\n        expect(channel.send).toHaveBeenCalledWith(JSON.stringify('hello'));\n    });\n    it('deserializes messages received from the underlying channel as JSON', () => {\n        const channelWithJSONSerialization = getRpcSubscriptionsChannelWithJSONSerialization(channel);\n        const messageListener = jest.fn();\n        channelWithJSONSerialization.on('message', messageListener);\n        receiveMessage(JSON.stringify('hello'));\n        expect(messageListener).toHaveBeenCalledWith('hello');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__tests__/rpc-subscriptions-transport-test.ts",
    "content": "import { createRpcSubscriptionsTransportFromChannelCreator } from '../rpc-subscriptions-transport';\n\ndescribe('createRpcSubscriptionsTransportFromChannelCreator', () => {\n    beforeEach(() => {\n        jest.useFakeTimers();\n    });\n    it('creates a function that calls `createChannel` with the abort signal', () => {\n        const mockCreateChannel = jest.fn();\n        const creator = createRpcSubscriptionsTransportFromChannelCreator(mockCreateChannel);\n        const abortSignal = new AbortController().signal;\n        creator({\n            execute: jest.fn(),\n            request: { methodName: 'foo', params: [] },\n            signal: abortSignal,\n        }).catch(() => {});\n        expect(mockCreateChannel).toHaveBeenCalledWith({ abortSignal });\n    });\n    it('creates a function that calls `execute` with the created channel', async () => {\n        expect.assertions(1);\n        const creator = createRpcSubscriptionsTransportFromChannelCreator(jest.fn().mockResolvedValue('MOCK_CHANNEL'));\n        const mockExecute = jest.fn();\n        creator({\n            execute: mockExecute,\n            request: { methodName: 'foo', params: [] },\n            signal: new AbortController().signal,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(mockExecute).toHaveBeenCalledWith(\n            expect.objectContaining({\n                channel: 'MOCK_CHANNEL',\n            }),\n        );\n    });\n    it('creates a function that calls `execute` with the abort signal', async () => {\n        expect.assertions(1);\n        const creator = createRpcSubscriptionsTransportFromChannelCreator(jest.fn());\n        const mockExecute = jest.fn();\n        const signal = new AbortController().signal;\n        creator({\n            execute: mockExecute,\n            request: { methodName: 'foo', params: [] },\n            signal,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(mockExecute).toHaveBeenCalledWith(\n            expect.objectContaining({\n                signal,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/__typetests__/rpc-subscriptions-clusters-typetest.ts",
    "content": "import type { SolanaRpcSubscriptionsApi, SolanaRpcSubscriptionsApiUnstable } from '@solana/rpc-subscriptions-api';\nimport type {\n    RpcSubscriptions,\n    RpcSubscriptionsChannelCreator,\n    RpcSubscriptionsTransport,\n} from '@solana/rpc-subscriptions-spec';\nimport { devnet, mainnet, testnet } from '@solana/rpc-types';\n\nimport {\n    createSolanaRpcSubscriptions,\n    createSolanaRpcSubscriptions_UNSTABLE,\n    createSolanaRpcSubscriptionsFromTransport,\n} from '../rpc-subscriptions';\nimport { createDefaultRpcSubscriptionsChannelCreator } from '../rpc-subscriptions-channel';\nimport type {\n    RpcSubscriptionsChannelCreatorDevnet,\n    RpcSubscriptionsChannelCreatorMainnet,\n    RpcSubscriptionsChannelCreatorTestnet,\n    RpcSubscriptionsDevnet,\n    RpcSubscriptionsMainnet,\n    RpcSubscriptionsTestnet,\n    RpcSubscriptionsTransportDevnet,\n    RpcSubscriptionsTransportMainnet,\n    RpcSubscriptionsTransportTestnet,\n} from '../rpc-subscriptions-clusters';\nimport { createRpcSubscriptionsTransportFromChannelCreator } from '../rpc-subscriptions-transport';\n\n// Define cluster-aware URLs and transports.\n\nconst genericUrl = 'http://localhost:8899';\nconst devnetUrl = devnet('https://api.devnet.solana.com');\nconst testnetUrl = testnet('https://api.testnet.solana.com');\nconst mainnetUrl = mainnet('https://api.mainnet-beta.solana.com');\n\n// [DESCRIBE] createDefaultRpcSubscriptionsChannelCreator.\n{\n    const genericChannelCreator = createDefaultRpcSubscriptionsChannelCreator({ url: genericUrl });\n    const devnetChannelCreator = createDefaultRpcSubscriptionsChannelCreator({ url: devnetUrl });\n    const testnetChannelCreator = createDefaultRpcSubscriptionsChannelCreator({ url: testnetUrl });\n    const mainnetChannelCreator = createDefaultRpcSubscriptionsChannelCreator({ url: mainnetUrl });\n\n    // When no cluster is specified, it should be a generic `RpcSubscriptionsChannel`.\n    {\n        genericChannelCreator satisfies RpcSubscriptionsChannelCreator<unknown, unknown>;\n        // @ts-expect-error Should not be a testnet channel\n        genericChannelCreator satisfies RpcSubscriptionsChannelCreatorDevnet<unknown, unknown>;\n        // @ts-expect-error Should not be a testnet channel\n        genericChannelCreator satisfies RpcSubscriptionsChannelCreatorTestnet<unknown, unknown>;\n        // @ts-expect-error Should not be a mainnet channel\n        genericChannelCreator satisfies RpcSubscriptionsChannelCreatorMainnet<unknown, unknown>;\n    }\n\n    // Devnet cluster should be `RpcSubscriptionsChannelCreatorDevnet`.\n    {\n        devnetChannelCreator satisfies RpcSubscriptionsChannelCreatorDevnet<unknown, unknown>;\n        // @ts-expect-error Should not be a testnet channel\n        devnetChannelCreator satisfies RpcSubscriptionsChannelCreatorTestnet<unknown, unknown>;\n        // @ts-expect-error Should not be a mainnet channel\n        devnetChannelCreator satisfies RpcSubscriptionsChannelCreatorMainnet<unknown, unknown>;\n    }\n\n    // Testnet cluster should be `RpcSubscriptionsChannelCreatorTestnet`.\n    {\n        testnetChannelCreator satisfies RpcSubscriptionsChannelCreatorTestnet<unknown, unknown>;\n        // @ts-expect-error Should not be a devnet channel\n        testnetChannelCreator satisfies RpcSubscriptionsChannelCreatorDevnet<unknown, unknown>;\n        // @ts-expect-error Should not be a mainnet channel\n        testnetChannelCreator satisfies RpcSubscriptionsChannelCreatorMainnet<unknown, unknown>;\n    }\n\n    // Mainnet cluster should be `RpcSubscriptionsChannelCreatorMainnet`.\n    {\n        mainnetChannelCreator satisfies RpcSubscriptionsChannelCreatorMainnet<unknown, unknown>;\n        // @ts-expect-error Should not be a devnet channel\n        mainnetChannelCreator satisfies RpcSubscriptionsChannelCreatorDevnet<unknown, unknown>;\n        // @ts-expect-error Should not be a testnet channel\n        mainnetChannelCreator satisfies RpcSubscriptionsChannelCreatorTestnet<unknown, unknown>;\n    }\n}\n\n// [DESCRIBE] createRpcSubscriptionsTransportFromChannelCreator.\n{\n    const genericTransport = createRpcSubscriptionsTransportFromChannelCreator(\n        null as unknown as RpcSubscriptionsChannelCreator<unknown, unknown>,\n    );\n    const devnetTransport = createRpcSubscriptionsTransportFromChannelCreator(\n        null as unknown as RpcSubscriptionsChannelCreatorDevnet<unknown, unknown>,\n    );\n    const testnetTransport = createRpcSubscriptionsTransportFromChannelCreator(\n        null as unknown as RpcSubscriptionsChannelCreatorTestnet<unknown, unknown>,\n    );\n    const mainnetTransport = createRpcSubscriptionsTransportFromChannelCreator(\n        null as unknown as RpcSubscriptionsChannelCreatorMainnet<unknown, unknown>,\n    );\n\n    // When no cluster is specified, it should be a generic `RpcSubscriptionsTransport{\n    {\n        genericTransport satisfies RpcSubscriptionsTransport;\n        // @ts-expect-error Should not be a testnet channel\n        genericTransport satisfies RpcSubscriptionsTransportDevnet;\n        // @ts-expect-error Should not be a testnet channel\n        genericTransport satisfies RpcSubscriptionsTransportTestnet;\n        // @ts-expect-error Should not be a mainnet channel\n        genericTransport satisfies RpcSubscriptionsTransportMainnet;\n    }\n\n    // Devnet cluster should be `RpcSubscriptionsTransportDevnet`.\n    {\n        devnetTransport satisfies RpcSubscriptionsTransportDevnet;\n        // @ts-expect-error Should not be a testnet channel\n        devnetTransport satisfies RpcSubscriptionsTransportTestnet;\n        // @ts-expect-error Should not be a mainnet channel\n        devnetTransport satisfies RpcSubscriptionsTransportMainnet;\n    }\n\n    // Testnet cluster should be `RpcSubscriptionsTransportTestnet`.\n    {\n        testnetTransport satisfies RpcSubscriptionsTransportTestnet;\n        // @ts-expect-error Should not be a devnet channel\n        testnetTransport satisfies RpcSubscriptionsTransportDevnet;\n        // @ts-expect-error Should not be a mainnet channel\n        testnetTransport satisfies RpcSubscriptionsTransportMainnet;\n    }\n\n    // Mainnet cluster should be `RpcSubscriptionsTransportMainnet`.\n    {\n        mainnetTransport satisfies RpcSubscriptionsTransportMainnet;\n        // @ts-expect-error Should not be a devnet channel\n        mainnetTransport satisfies RpcSubscriptionsTransportDevnet;\n        // @ts-expect-error Should not be a testnet channel\n        mainnetTransport satisfies RpcSubscriptionsTransportTestnet;\n    }\n}\n\n// [DESCRIBE] createSolanaRpcSubscriptionsFromTransport.\n{\n    const genericRpc = createSolanaRpcSubscriptionsFromTransport(null as unknown as RpcSubscriptionsTransport);\n    const devnetRpc = createSolanaRpcSubscriptionsFromTransport(null as unknown as RpcSubscriptionsTransportDevnet);\n    const testnetRpc = createSolanaRpcSubscriptionsFromTransport(null as unknown as RpcSubscriptionsTransportTestnet);\n    const mainnetRpc = createSolanaRpcSubscriptionsFromTransport(null as unknown as RpcSubscriptionsTransportMainnet);\n\n    // Checking stable subscriptions.\n    {\n        genericRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        devnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        testnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        mainnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n\n        // @ts-expect-error Should not have unstable subscriptions\n        genericRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        // @ts-expect-error Should not have unstable subscriptions\n        devnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        // @ts-expect-error Should not have unstable subscriptions\n        testnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        // @ts-expect-error Should not have unstable subscriptions\n        mainnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n    }\n\n    // When no cluster is specified, it should be a generic `RpcSubscriptions`.\n    {\n        genericRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a devnet RPC\n        genericRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a testnet RPC\n        genericRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a mainnet RPC\n        genericRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>;\n    }\n\n    // Devnet cluster should be `RpcSubscriptionsDevnet`.\n    {\n        devnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        devnetRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a testnet RPC\n        devnetRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a mainnet RPC\n        devnetRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>;\n    }\n\n    // Testnet cluster should be `RpcSubscriptionsTestnet`.\n    {\n        testnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        testnetRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a devnet RPC\n        testnetRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a mainnet RPC\n        testnetRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>;\n    }\n\n    // Mainnet cluster should be `RpcSubscriptionsMainnet`.\n    {\n        mainnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        mainnetRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a devnet RPC\n        mainnetRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a testnet RPC\n        mainnetRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi>;\n    }\n}\n\n// [DESCRIBE] createSolanaRpcSubscriptions.\n{\n    const genericRpc = createSolanaRpcSubscriptions(genericUrl);\n    const devnetRpc = createSolanaRpcSubscriptions(devnetUrl);\n    const testnetRpc = createSolanaRpcSubscriptions(testnetUrl);\n    const mainnetRpc = createSolanaRpcSubscriptions(mainnetUrl);\n\n    // Checking stable subscriptions.\n    {\n        genericRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        devnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        testnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        mainnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n\n        // @ts-expect-error Should not have unstable subscriptions\n        genericRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        // @ts-expect-error Should not have unstable subscriptions\n        devnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        // @ts-expect-error Should not have unstable subscriptions\n        testnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        // @ts-expect-error Should not have unstable subscriptions\n        mainnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n    }\n\n    // When no cluster is specified, it should be a generic `RpcSubscriptions`.\n    {\n        genericRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a devnet RPC\n        genericRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a testnet RPC\n        genericRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a mainnet RPC\n        genericRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>;\n    }\n\n    // Devnet cluster should be `RpcSubscriptionsDevnet`.\n    {\n        devnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        devnetRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a testnet RPC\n        devnetRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a mainnet RPC\n        devnetRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>;\n    }\n\n    // Testnet cluster should be `RpcSubscriptionsTestnet`.\n    {\n        testnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        testnetRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a devnet RPC\n        testnetRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a mainnet RPC\n        testnetRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>;\n    }\n\n    // Mainnet cluster should be `RpcSubscriptionsMainnet`.\n    {\n        mainnetRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi>;\n        mainnetRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a devnet RPC\n        mainnetRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi>;\n        // @ts-expect-error Should not be a testnet RPC\n        mainnetRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi>;\n    }\n}\n\n// [DESCRIBE] createSolanaRpcSubscriptions_UNSTABLE.\n{\n    const genericRpc = createSolanaRpcSubscriptions_UNSTABLE(genericUrl);\n    const devnetRpc = createSolanaRpcSubscriptions_UNSTABLE(devnetUrl);\n    const testnetRpc = createSolanaRpcSubscriptions_UNSTABLE(testnetUrl);\n    const mainnetRpc = createSolanaRpcSubscriptions_UNSTABLE(mainnetUrl);\n\n    // Checking unstable subscriptions.\n    {\n        genericRpc satisfies RpcSubscriptions<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        devnetRpc satisfies RpcSubscriptionsDevnet<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        testnetRpc satisfies RpcSubscriptionsTestnet<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n        mainnetRpc satisfies RpcSubscriptionsMainnet<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/index.ts",
    "content": "/**\n * This package contains types that implement RPC subscriptions as required by the Solana RPC.\n * Additionally, it incorporates some useful defaults that make working with subscriptions easier,\n * more performant, and more reliable. It can be used standalone, but it is also exported as part of\n * Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from '@solana/rpc-subscriptions-api';\nexport * from '@solana/rpc-subscriptions-spec';\n\nexport * from './rpc-default-config';\nexport * from './rpc-subscriptions-autopinger';\nexport * from './rpc-subscriptions-channel-pool';\nexport * from './rpc-subscriptions-channel';\nexport * from './rpc-subscriptions-clusters';\nexport * from './rpc-subscriptions-coalescer';\nexport * from './rpc-subscriptions-json-bigint';\nexport * from './rpc-subscriptions-json';\nexport * from './rpc-subscriptions-transport';\nexport * from './rpc-subscriptions';\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-default-config.ts",
    "content": "import type { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\n\nimport { createSolanaJsonRpcIntegerOverflowError } from './rpc-integer-overflow-error';\n\nexport const DEFAULT_RPC_SUBSCRIPTIONS_CONFIG: Partial<\n    NonNullable<Parameters<typeof createSolanaRpcSubscriptionsApi>[0]>\n> = {\n    defaultCommitment: 'confirmed',\n    onIntegerOverflow(request, keyPath, value) {\n        throw createSolanaJsonRpcIntegerOverflowError(request.methodName, keyPath, value);\n    },\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-integer-overflow-error.ts",
    "content": "import { safeCaptureStackTrace, SOLANA_ERROR__RPC__INTEGER_OVERFLOW, SolanaError } from '@solana/errors';\nimport type { KeyPath } from '@solana/rpc-transformers';\n\nexport function createSolanaJsonRpcIntegerOverflowError(\n    methodName: string,\n    keyPath: KeyPath,\n    value: bigint,\n): SolanaError<typeof SOLANA_ERROR__RPC__INTEGER_OVERFLOW> {\n    let argumentLabel = '';\n    if (typeof keyPath[0] === 'number') {\n        const argPosition = keyPath[0] + 1;\n        const lastDigit = argPosition % 10;\n        const lastTwoDigits = argPosition % 100;\n        if (lastDigit == 1 && lastTwoDigits != 11) {\n            argumentLabel = argPosition + 'st';\n        } else if (lastDigit == 2 && lastTwoDigits != 12) {\n            argumentLabel = argPosition + 'nd';\n        } else if (lastDigit == 3 && lastTwoDigits != 13) {\n            argumentLabel = argPosition + 'rd';\n        } else {\n            argumentLabel = argPosition + 'th';\n        }\n    } else {\n        argumentLabel = `\\`${keyPath[0].toString()}\\``;\n    }\n    const path =\n        keyPath.length > 1\n            ? keyPath\n                  .slice(1)\n                  .map(pathPart => (typeof pathPart === 'number' ? `[${pathPart}]` : pathPart))\n                  .join('.')\n            : undefined;\n    const error = new SolanaError(SOLANA_ERROR__RPC__INTEGER_OVERFLOW, {\n        argumentLabel,\n        keyPath: keyPath as readonly (number | string | symbol)[],\n        methodName,\n        optionalPathLabel: path ? ` at path \\`${path}\\`` : '',\n        value,\n        ...(path !== undefined ? { path } : undefined),\n    });\n    safeCaptureStackTrace(error, createSolanaJsonRpcIntegerOverflowError);\n    return error;\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-autopinger.ts",
    "content": "import { isSolanaError, SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED } from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\nimport type { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\n\ntype Config<TChannel extends RpcSubscriptionsChannel<unknown, unknown>> = Readonly<{\n    abortSignal: AbortSignal;\n    channel: TChannel;\n    intervalMs: number;\n}>;\n\nconst PING_PAYLOAD = {\n    jsonrpc: '2.0',\n    method: 'ping',\n} as const;\n\n/**\n * Given a {@link RpcSubscriptionsChannel}, will return a new channel that sends a ping message to\n * the inner channel if a message has not been sent or received in the last `intervalMs`. In web\n * browsers, this implementation sends no ping when the network is down, and sends a ping\n * immediately upon the network coming back up.\n */\nexport function getRpcSubscriptionsChannelWithAutoping<TChannel extends RpcSubscriptionsChannel<object, unknown>>({\n    abortSignal: callerAbortSignal,\n    channel,\n    intervalMs,\n}: Config<TChannel>): TChannel {\n    let intervalId: ReturnType<typeof setInterval> | undefined;\n    function sendPing() {\n        channel.send(PING_PAYLOAD).catch((e: unknown) => {\n            if (isSolanaError(e, SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED)) {\n                pingerAbortController.abort();\n            }\n        });\n    }\n    function restartPingTimer() {\n        clearInterval(intervalId);\n        intervalId = setInterval(sendPing, intervalMs);\n    }\n    const pingerAbortController = new AbortController();\n    pingerAbortController.signal.addEventListener('abort', () => {\n        clearInterval(intervalId);\n    });\n    callerAbortSignal.addEventListener('abort', () => {\n        pingerAbortController.abort();\n    });\n    channel.on(\n        'error',\n        () => {\n            pingerAbortController.abort();\n        },\n        { signal: pingerAbortController.signal },\n    );\n    channel.on('message', restartPingTimer, { signal: pingerAbortController.signal });\n    if (!__BROWSER__ || globalThis.navigator.onLine) {\n        restartPingTimer();\n    }\n    if (__BROWSER__) {\n        globalThis.addEventListener(\n            'offline',\n            function handleOffline() {\n                clearInterval(intervalId);\n            },\n            { signal: pingerAbortController.signal },\n        );\n        globalThis.addEventListener(\n            'online',\n            function handleOnline() {\n                sendPing();\n                restartPingTimer();\n            },\n            { signal: pingerAbortController.signal },\n        );\n    }\n    return {\n        ...channel,\n        send(...args) {\n            if (!pingerAbortController.signal.aborted) {\n                restartPingTimer();\n            }\n            return channel.send(...args);\n        },\n    };\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-channel-pool-internal.ts",
    "content": "import { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\n\nexport type ChannelPoolEntry = {\n    channel: PromiseLike<RpcSubscriptionsChannel<unknown, unknown>> | RpcSubscriptionsChannel<unknown, unknown>;\n    readonly dispose: () => void;\n    subscriptionCount: number;\n};\n\ntype ChannelPool = { readonly entries: ChannelPoolEntry[]; freeChannelIndex: number };\n\nexport function createChannelPool(): ChannelPool {\n    return {\n        entries: [],\n        freeChannelIndex: -1,\n    };\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-channel-pool.ts",
    "content": "import { AbortController } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannelCreator } from '@solana/rpc-subscriptions-spec';\n\nimport { ChannelPoolEntry, createChannelPool } from './rpc-subscriptions-channel-pool-internal';\n\ntype Config = Readonly<{\n    maxSubscriptionsPerChannel: number;\n    minChannels: number;\n}>;\n\n/**\n * Given a channel creator, will return a new channel creator with the following behavior.\n *\n * 1. When called, returns a {@link RpcSubscriptionsChannel}. Adds that channel to a pool.\n * 2. When called again, creates and returns new\n *    {@link RpcSubscriptionChannel | RpcSubscriptionChannels} up to the number specified by\n *    `minChannels`.\n * 3. When `minChannels` channels have been created, subsequent calls vend whichever existing\n *    channel from the pool has the fewest subscribers, or the next one in rotation in the event of\n *    a tie.\n * 4. Once all channels carry the number of subscribers specified by the number\n *    `maxSubscriptionsPerChannel`, new channels in excess of `minChannel` will be created,\n *    returned, and added to the pool.\n * 5. A channel will be destroyed once all of its subscribers' abort signals fire.\n */\nexport function getChannelPoolingChannelCreator<\n    TChannelCreator extends RpcSubscriptionsChannelCreator<unknown, unknown>,\n>(createChannel: TChannelCreator, { maxSubscriptionsPerChannel, minChannels }: Config): TChannelCreator {\n    const pool = createChannelPool();\n    /**\n     * This function advances the free channel index to the pool entry with the most capacity. It\n     * sets the index to `-1` if all channels are full.\n     */\n    function recomputeFreeChannelIndex() {\n        if (pool.entries.length < minChannels) {\n            // Don't set the free channel index until the pool fills up; we want to keep creating\n            // channels before we start rotating among them.\n            pool.freeChannelIndex = -1;\n            return;\n        }\n        let mostFreeChannel: Readonly<{ poolIndex: number; subscriptionCount: number }> | undefined;\n        for (let ii = 0; ii < pool.entries.length; ii++) {\n            const nextPoolIndex = (pool.freeChannelIndex + ii + 2) % pool.entries.length;\n            const nextPoolEntry =\n                // Start from the item two positions after the current item. This way, the\n                // search will finish on the item after the current one. This ensures that, if\n                // any channels tie for having the most capacity, the one that will be chosen is\n                // the one immediately to the current one's right (wrapping around).\n                pool.entries[nextPoolIndex];\n            if (\n                nextPoolEntry.subscriptionCount < maxSubscriptionsPerChannel &&\n                (!mostFreeChannel || mostFreeChannel.subscriptionCount >= nextPoolEntry.subscriptionCount)\n            ) {\n                mostFreeChannel = {\n                    poolIndex: nextPoolIndex,\n                    subscriptionCount: nextPoolEntry.subscriptionCount,\n                };\n            }\n        }\n        pool.freeChannelIndex = mostFreeChannel?.poolIndex ?? -1;\n    }\n    return function getExistingChannelWithMostCapacityOrCreateChannel({ abortSignal }) {\n        let poolEntry: ChannelPoolEntry;\n        function destroyPoolEntry() {\n            const index = pool.entries.findIndex(entry => entry === poolEntry);\n            pool.entries.splice(index, 1);\n            poolEntry.dispose();\n            recomputeFreeChannelIndex();\n        }\n        if (pool.freeChannelIndex === -1) {\n            const abortController = new AbortController();\n            const newChannelPromise = createChannel({ abortSignal: abortController.signal });\n            newChannelPromise\n                .then(newChannel => {\n                    newChannel.on('error', destroyPoolEntry, { signal: abortController.signal });\n                })\n                .catch(destroyPoolEntry);\n            poolEntry = {\n                channel: newChannelPromise,\n                dispose() {\n                    abortController.abort();\n                },\n                subscriptionCount: 0,\n            };\n            pool.entries.push(poolEntry);\n        } else {\n            poolEntry = pool.entries[pool.freeChannelIndex];\n        }\n        /**\n         * A note about subscription counts.\n         * Because of https://github.com/solana-labs/solana/pull/18943, two subscriptions for\n         * materially the same notification will be coalesced on the server. This means they will be\n         * assigned the same subscription id, and will occupy one subscription slot. We can't tell,\n         * from here, whether a subscription will be treated in this way or not, so we\n         * unconditionally increment the subscription count every time a subscription request is\n         * made. This may result in subscription channels being treated as out-of-capacity when in\n         * fact they are not.\n         */\n        poolEntry.subscriptionCount++;\n        abortSignal.addEventListener('abort', function destroyConsumer() {\n            poolEntry.subscriptionCount--;\n            if (poolEntry.subscriptionCount === 0) {\n                destroyPoolEntry();\n            } else if (pool.freeChannelIndex !== -1) {\n                // Back the free channel index up one position, and recompute it.\n                pool.freeChannelIndex--;\n                recomputeFreeChannelIndex();\n            }\n        });\n        recomputeFreeChannelIndex();\n        return poolEntry.channel;\n    } as TChannelCreator;\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-channel.ts",
    "content": "import { createWebSocketChannel } from '@solana/rpc-subscriptions-channel-websocket';\nimport type { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport type { ClusterUrl } from '@solana/rpc-types';\n\nimport { getRpcSubscriptionsChannelWithAutoping } from './rpc-subscriptions-autopinger';\nimport { getChannelPoolingChannelCreator } from './rpc-subscriptions-channel-pool';\nimport { RpcSubscriptionsChannelCreatorFromClusterUrl } from './rpc-subscriptions-clusters';\nimport { getRpcSubscriptionsChannelWithJSONSerialization } from './rpc-subscriptions-json';\nimport { getRpcSubscriptionsChannelWithBigIntJSONSerialization } from './rpc-subscriptions-json-bigint';\n\nexport type DefaultRpcSubscriptionsChannelConfig<TClusterUrl extends ClusterUrl> = Readonly<{\n    /**\n     * The number of milliseconds to wait since the last message sent or received over the channel\n     * before sending a ping message to keep the channel open.\n     */\n    intervalMs?: number;\n    /**\n     * The number of subscribers that may share a channel before a new channel must be created.\n     *\n     * It is important that you set this to the maximum number of subscriptions that your RPC\n     * provider recommends making over a single connection; the default is set deliberately low, so\n     * as to comply with the restrictive limits of the public mainnet RPC node.\n     *\n     * @defaultValue 100\n     */\n    maxSubscriptionsPerChannel?: number;\n    /** The number of channels to create before reusing a channel for a new subscription. */\n    minChannels?: number;\n    /**\n     * The number of bytes of data to admit into the\n     * [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) buffer before\n     * buffering data on the client.\n     */\n    sendBufferHighWatermark?: number;\n    /** The URL of the web socket server. Must use the `ws` or `wss` protocols. */\n    url: TClusterUrl;\n}>;\n\n/**\n * Similar to {@link createDefaultRpcSubscriptionsChannelCreator} with some Solana-specific\n * defaults.\n *\n * For instance, it safely handles `BigInt` values in JSON messages since Solana RPC servers accept\n * and return integers larger than [`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER).\n */\nexport function createDefaultSolanaRpcSubscriptionsChannelCreator<TClusterUrl extends ClusterUrl>(\n    config: DefaultRpcSubscriptionsChannelConfig<TClusterUrl>,\n): RpcSubscriptionsChannelCreatorFromClusterUrl<TClusterUrl, unknown, unknown> {\n    return createDefaultRpcSubscriptionsChannelCreatorImpl({\n        ...config,\n        jsonSerializer: getRpcSubscriptionsChannelWithBigIntJSONSerialization,\n    });\n}\n\n/**\n * Creates a function that returns new subscription channels when called.\n */\nexport function createDefaultRpcSubscriptionsChannelCreator<TClusterUrl extends ClusterUrl>(\n    config: DefaultRpcSubscriptionsChannelConfig<TClusterUrl>,\n): RpcSubscriptionsChannelCreatorFromClusterUrl<TClusterUrl, unknown, unknown> {\n    return createDefaultRpcSubscriptionsChannelCreatorImpl({\n        ...config,\n        jsonSerializer: getRpcSubscriptionsChannelWithJSONSerialization,\n    });\n}\n\nfunction createDefaultRpcSubscriptionsChannelCreatorImpl<TClusterUrl extends ClusterUrl>(\n    config: DefaultRpcSubscriptionsChannelConfig<TClusterUrl> & {\n        jsonSerializer: (channel: RpcSubscriptionsChannel<string, string>) => RpcSubscriptionsChannel<unknown, unknown>;\n    },\n): RpcSubscriptionsChannelCreatorFromClusterUrl<TClusterUrl, unknown, unknown> {\n    if (/^wss?:/i.test(config.url) === false) {\n        const protocolMatch = config.url.match(/^([^:]+):/);\n        throw new DOMException(\n            protocolMatch\n                ? \"Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or \" +\n                      `'wss'. '${protocolMatch[1]}:' is not allowed.`\n                : `Failed to construct 'WebSocket': The URL '${config.url}' is invalid.`,\n        );\n    }\n    const { intervalMs, ...rest } = config;\n    const createDefaultRpcSubscriptionsChannel = (({ abortSignal }) => {\n        return createWebSocketChannel({\n            ...rest,\n            sendBufferHighWatermark:\n                config.sendBufferHighWatermark ??\n                // Let 128KB of data into the WebSocket buffer before buffering it in the app.\n                131_072,\n            signal: abortSignal,\n        })\n            .then(config.jsonSerializer)\n            .then(channel =>\n                getRpcSubscriptionsChannelWithAutoping({\n                    abortSignal,\n                    channel,\n                    intervalMs: intervalMs ?? 5_000,\n                }),\n            );\n    }) as RpcSubscriptionsChannelCreatorFromClusterUrl<TClusterUrl, unknown, unknown>;\n    return getChannelPoolingChannelCreator(createDefaultRpcSubscriptionsChannel, {\n        maxSubscriptionsPerChannel:\n            config.maxSubscriptionsPerChannel ??\n            /**\n             * A note about this default. The idea here is that, because some RPC providers impose\n             * an upper limit on the number of subscriptions you can make per channel, we must\n             * choose a number low enough to avoid hitting that limit. Without knowing what provider\n             * a given person is using, or what their limit is, we have to choose the lowest of all\n             * known limits. As of this writing (October 2024) that is the public mainnet RPC node\n             * (api.mainnet-beta.solana.com) at 100 subscriptions.\n             */\n            100,\n        minChannels: config.minChannels ?? 1,\n    });\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-clusters.ts",
    "content": "import type {\n    RpcSubscriptions,\n    RpcSubscriptionsChannel,\n    RpcSubscriptionsChannelCreator,\n    RpcSubscriptionsTransport,\n} from '@solana/rpc-subscriptions-spec';\nimport type { ClusterUrl, DevnetUrl, MainnetUrl, TestnetUrl } from '@solana/rpc-types';\n\nexport type RpcSubscriptionsChannelCreatorDevnet<TOutboundMessage, TInboundMessage> = RpcSubscriptionsChannelCreator<\n    TOutboundMessage,\n    TInboundMessage\n> & {\n    '~cluster': 'devnet';\n};\nexport type RpcSubscriptionsChannelCreatorTestnet<TOutboundMessage, TInboundMessage> = RpcSubscriptionsChannelCreator<\n    TOutboundMessage,\n    TInboundMessage\n> & {\n    '~cluster': 'testnet';\n};\nexport type RpcSubscriptionsChannelCreatorMainnet<TOutboundMessage, TInboundMessage> = RpcSubscriptionsChannelCreator<\n    TOutboundMessage,\n    TInboundMessage\n> & {\n    '~cluster': 'mainnet';\n};\nexport type RpcSubscriptionsChannelCreatorWithCluster<TOutboundMessage, TInboundMessage> =\n    | RpcSubscriptionsChannelCreatorDevnet<TOutboundMessage, TInboundMessage>\n    | RpcSubscriptionsChannelCreatorMainnet<TOutboundMessage, TInboundMessage>\n    | RpcSubscriptionsChannelCreatorTestnet<TOutboundMessage, TInboundMessage>;\nexport type RpcSubscriptionsChannelCreatorFromClusterUrl<\n    TClusterUrl extends ClusterUrl,\n    TOutboundMessage,\n    TInboundMessage,\n> = TClusterUrl extends DevnetUrl\n    ? RpcSubscriptionsChannelCreatorDevnet<TOutboundMessage, TInboundMessage>\n    : TClusterUrl extends TestnetUrl\n      ? RpcSubscriptionsChannelCreatorTestnet<TOutboundMessage, TInboundMessage>\n      : TClusterUrl extends MainnetUrl\n        ? RpcSubscriptionsChannelCreatorMainnet<TOutboundMessage, TInboundMessage>\n        : RpcSubscriptionsChannelCreator<TOutboundMessage, TInboundMessage>;\n\n/**\n * A {@link RpcSubscriptionsChannel} that communicates with the devnet cluster.\n *\n * Such channels are understood to communicate with a RPC server that services devnet, and as such\n * might only be accepted for use as the channel of a {@link RpcSubscriptionsTransportDevnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * You can use the ability to assert on the type of RPC channel at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable programs or data.\n */\nexport type RpcSubscriptionsChannelDevnet<TOutboundMessage, TInboundMessage> = RpcSubscriptionsChannel<\n    TOutboundMessage,\n    TInboundMessage\n> & { '~cluster': 'devnet' };\n/**\n * A {@link RpcSubscriptionsChannel} that communicates with the testnet cluster.\n *\n * Such channels are understood to communicate with a RPC server that services testnet, and as such\n * might only be accepted for use as the channel of a {@link RpcSubscriptionsTransportTestnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * You can use the ability to assert on the type of RPC channel at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable programs or data.\n */\nexport type RpcSubscriptionsChannelTestnet<TOutboundMessage, TInboundMessage> = RpcSubscriptionsChannel<\n    TOutboundMessage,\n    TInboundMessage\n> & { '~cluster': 'testnet' };\n/**\n * A {@link RpcSubscriptionsChannel} that communicates with the mainnet cluster.\n *\n * Such channels are understood to communicate with a RPC server that services mainnet, and as such\n * might only be accepted for use as the channel of a {@link RpcSubscriptionsTransportMainnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * You can use the ability to assert on the type of RPC channel at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable programs or data.\n */\nexport type RpcSubscriptionsChannelMainnet<TOutboundMessage, TInboundMessage> = RpcSubscriptionsChannel<\n    TOutboundMessage,\n    TInboundMessage\n> & { '~cluster': 'mainnet' };\nexport type RpcSubscriptionsChannelWithCluster<TOutboundMessage, TInboundMessage> =\n    | RpcSubscriptionsChannelDevnet<TOutboundMessage, TInboundMessage>\n    | RpcSubscriptionsChannelMainnet<TOutboundMessage, TInboundMessage>\n    | RpcSubscriptionsChannelTestnet<TOutboundMessage, TInboundMessage>;\n/**\n * Given a {@link ClusterUrl}, this utility type will resolve to as specific a\n * {@link RpcSubscriptionsChannel} as possible.\n *\n * @example\n * ```ts\n * function createCustomSubscriptionsChannel<TClusterUrl extends ClusterUrl>(\n *     clusterUrl: TClusterUrl,\n * ): RpcSubscriptionsChannelFromClusterUrl<TClusterUrl> {\n *     /* ... *\\/\n * }\n *\n * const channel = createCustomSubscriptionsChannel(testnet('ws://api.testnet.solana.com'));\n * channel satisfies RpcSubscriptionsChannelTestnet; // OK\n * ```\n */\nexport type RpcSubscriptionsChannelFromClusterUrl<\n    TClusterUrl extends ClusterUrl,\n    TOutboundMessage,\n    TInboundMessage,\n> = TClusterUrl extends DevnetUrl\n    ? RpcSubscriptionsChannelDevnet<TOutboundMessage, TInboundMessage>\n    : TClusterUrl extends TestnetUrl\n      ? RpcSubscriptionsChannelTestnet<TOutboundMessage, TInboundMessage>\n      : TClusterUrl extends MainnetUrl\n        ? RpcSubscriptionsChannelMainnet<TOutboundMessage, TInboundMessage>\n        : RpcSubscriptionsChannel<TOutboundMessage, TInboundMessage>;\n\n/**\n * A {@link RpcSubscriptionsTransport} that communicates with the devnet cluster.\n *\n * Such transports are understood to communicate with a RPC server that services devnet, and as such\n * might only be accepted for use as the transport of a {@link RpcSubscriptionsDevnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * You can use the ability to assert on the type of RPC transport at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable programs or data.\n */\nexport type RpcSubscriptionsTransportDevnet = RpcSubscriptionsTransport & { '~cluster': 'devnet' };\n/**\n * A {@link RpcSubscriptionsTransport} that communicates with the testnet cluster.\n *\n * Such transports are understood to communicate with a RPC server that services testnet, and as\n * such might only be accepted for use as the transport of a {@link RpcSubscriptionsTestnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * You can use the ability to assert on the type of RPC transport at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable programs or data.\n */\nexport type RpcSubscriptionsTransportTestnet = RpcSubscriptionsTransport & { '~cluster': 'testnet' };\n/**\n * A {@link RpcSubscriptionsTransport} that communicates with the mainnet cluster.\n *\n * Such transports are understood to communicate with a RPC server that services mainnet, and as\n * such might only be accepted for use as the transport of a {@link RpcSubscriptionsMainnet}.\n *\n * This is useful in cases where you need to make assertions about what capabilities a RPC offers.\n * You can use the ability to assert on the type of RPC transport at compile time to prevent calling\n * unimplemented methods or presuming the existence of unavailable programs or data.\n */\nexport type RpcSubscriptionsTransportMainnet = RpcSubscriptionsTransport & { '~cluster': 'mainnet' };\nexport type RpcSubscriptionsTransportWithCluster =\n    | RpcSubscriptionsTransportDevnet\n    | RpcSubscriptionsTransportMainnet\n    | RpcSubscriptionsTransportTestnet;\n/**\n * Given a {@link ClusterUrl}, this utility type will resolve to as specific a\n * {@link RpcSubscriptionsTransport} as possible.\n *\n * @example\n * ```ts\n * function createCustomSubscriptionsTransport<TClusterUrl extends ClusterUrl>(\n *     clusterUrl: TClusterUrl,\n * ): RpcSubscriptionsTransportFromClusterUrl<TClusterUrl> {\n *     /* ... *\\/\n * }\n *\n * const transport = createCustomSubscriptionsTransport(testnet('ws://api.testnet.solana.com'));\n * transport satisfies RpcSubscriptionsTransportTestnet; // OK\n * ```\n */\nexport type RpcSubscriptionsTransportFromClusterUrl<TClusterUrl extends ClusterUrl> = TClusterUrl extends DevnetUrl\n    ? RpcSubscriptionsTransportDevnet\n    : TClusterUrl extends TestnetUrl\n      ? RpcSubscriptionsTransportTestnet\n      : TClusterUrl extends MainnetUrl\n        ? RpcSubscriptionsTransportMainnet\n        : RpcSubscriptionsTransport;\n/**\n * A {@link RpcSubscriptions} that supports the RPC Subscriptions methods available on the devnet\n * cluster.\n *\n * This is useful in cases where you need to make assertions about the suitability of a RPC for a\n * given purpose. For example, you might like to make it a type error to combine certain types with\n * RPCs belonging to certain clusters, at compile time.\n *\n * @example\n * ```ts\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address<'ReAL1111111111111111111111111111'>,\n *     rpcSubscriptions: RpcSubscriptionsMainnet<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>>;\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address<'TeST1111111111111111111111111111'>,\n *     rpcSubscriptions: RpcSubscriptionsDevnet<unknown> | RpcTestnet<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>>;\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address,\n *     rpcSubscriptions: RpcSubscriptions<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>> {\n *     /* ... *\\/\n * }\n * const rpcSubscriptions = createSolanaRpcSubscriptions(devnet('https://api.devnet.solana.com'));\n * await subscribeToSpecialAccountNotifications(address('ReAL1111111111111111111111111111'), rpcSubscriptions); // ERROR\n * ```\n */\nexport type RpcSubscriptionsDevnet<TRpcMethods> = RpcSubscriptions<TRpcMethods> & { '~cluster': 'devnet' };\n/**\n * A {@link RpcSubscriptions} that supports the RPC Subscriptions methods available on the testnet\n * cluster.\n *\n * This is useful in cases where you need to make assertions about the suitability of a RPC for a\n * given purpose. For example, you might like to make it a type error to combine certain types with\n * RPCs belonging to certain clusters, at compile time.\n *\n * @example\n * ```ts\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address<'ReAL1111111111111111111111111111'>,\n *     rpcSubscriptions: RpcSubscriptionsMainnet<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>>;\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address<'TeST1111111111111111111111111111'>,\n *     rpcSubscriptions: RpcSubscriptionsDevnet<unknown> | RpcTestnet<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>>;\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address,\n *     rpcSubscriptions: RpcSubscriptions<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>> {\n *     /* ... *\\/\n * }\n * const rpcSubscriptions = createSolanaRpcSubscriptions(devnet('https://api.devnet.solana.com'));\n * await subscribeToSpecialAccountNotifications(address('ReAL1111111111111111111111111111'), rpcSubscriptions); // ERROR\n * ```\n */\n\nexport type RpcSubscriptionsTestnet<TRpcMethods> = RpcSubscriptions<TRpcMethods> & { '~cluster': 'testnet' };\n/**\n * A {@link RpcSubscriptions} that supports the RPC Subscriptions methods available on the mainnet\n * cluster.\n *\n * This is useful in cases where you need to make assertions about the suitability of a RPC for a\n * given purpose. For example, you might like to make it a type error to combine certain types with\n * RPCs belonging to certain clusters, at compile time.\n *\n * @example\n * ```ts\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address<'ReAL1111111111111111111111111111'>,\n *     rpcSubscriptions: RpcSubscriptionsMainnet<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>>;\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address<'TeST1111111111111111111111111111'>,\n *     rpcSubscriptions: RpcSubscriptionsDevnet<unknown> | RpcTestnet<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>>;\n * async function subscribeToSpecialAccountNotifications(\n *     address: Address,\n *     rpcSubscriptions: RpcSubscriptions<unknown>,\n *     abortSignal: AbortSignal,\n * ): Promise<AsyncIterable<SpecialAccountInfo>> {\n *     /* ... *\\/\n * }\n * const rpcSubscriptions = createSolanaRpcSubscriptions(devnet('https://api.devnet.solana.com'));\n * await subscribeToSpecialAccountNotifications(address('ReAL1111111111111111111111111111'), rpcSubscriptions); // ERROR\n * ```\n */\nexport type RpcSubscriptionsMainnet<TRpcMethods> = RpcSubscriptions<TRpcMethods> & { '~cluster': 'mainnet' };\n/**\n * Given a {@link RpcSubscriptionsTransport} and a set of RPC methods denoted by `TRpcMethods`, this\n * utility type will resolve to a {@link RpcSubscriptions} that supports those methods on as\n * specific a cluster as possible.\n *\n * @example\n * ```ts\n * function createCustomRpcSubscriptions<TRpcSubscriptionsTransport extends RpcSubscriptionsTransport>(\n *     transport: TRpcSubscriptionsTransport,\n * ): RpcSubscriptionsFromTransport<MyCustomRpcMethods, TRpcSubscriptionsTransport> {\n *     /* ... *\\/\n * }\n * const transport = createDefaultRpcSubscriptionsTransport({\n *     createChannel: createDefaultSolanaRpcSubscriptionsChannelCreator({\n *         url: mainnet('ws://rpc.company'),\n *     }),\n * });\n * transport satisfies RpcSubscriptionsTransportMainnet; // OK\n * const rpcSubscriptions = createCustomRpcSubscriptions(transport);\n * rpcSubscriptions satisfies RpcSubscriptionsMainnet<MyCustomRpcMethods>; // OK\n * ```\n */\nexport type RpcSubscriptionsFromTransport<\n    TRpcMethods,\n    TRpcSubscriptionsTransport extends RpcSubscriptionsTransport,\n> = TRpcSubscriptionsTransport extends RpcSubscriptionsTransportDevnet\n    ? RpcSubscriptionsDevnet<TRpcMethods>\n    : TRpcSubscriptionsTransport extends RpcSubscriptionsTransportTestnet\n      ? RpcSubscriptionsTestnet<TRpcMethods>\n      : TRpcSubscriptionsTransport extends RpcSubscriptionsTransportMainnet\n        ? RpcSubscriptionsMainnet<TRpcMethods>\n        : RpcSubscriptions<TRpcMethods>;\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-coalescer.ts",
    "content": "import { AbortController } from '@solana/event-target-impl';\nimport fastStableStringify from '@solana/fast-stable-stringify';\nimport { RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\nimport { DataPublisher } from '@solana/subscribable';\n\ntype CacheEntry = {\n    readonly abortController: AbortController;\n    readonly dataPublisherPromise: Promise<DataPublisher>;\n    numSubscribers: number;\n};\n\n/**\n * Given a {@link RpcSubscriptionsTransport}, will return a new transport that coalesces identical\n * subscriptions into a single subscription request to the server. The determination of whether a\n * subscription is the same as another is based on the `rpcRequest` returned by its\n * {@link RpcSubscriptionsPlan}. The subscription will only be aborted once all subscribers abort,\n * or there is an error.\n */\nexport function getRpcSubscriptionsTransportWithSubscriptionCoalescing<TTransport extends RpcSubscriptionsTransport>(\n    transport: TTransport,\n): TTransport {\n    const cache = new Map<string, CacheEntry>();\n    return function rpcSubscriptionsTransportWithSubscriptionCoalescing(config) {\n        const { request, signal } = config;\n        const subscriptionConfigurationHash = fastStableStringify([request.methodName, request.params]);\n\n        let cachedDataPublisherPromise = cache.get(subscriptionConfigurationHash);\n        if (!cachedDataPublisherPromise) {\n            const abortController = new AbortController();\n            const dataPublisherPromise = transport({\n                ...config,\n                signal: abortController.signal,\n            });\n            dataPublisherPromise\n                .then(dataPublisher => {\n                    dataPublisher.on(\n                        'error',\n                        () => {\n                            cache.delete(subscriptionConfigurationHash);\n                            abortController.abort();\n                        },\n                        { signal: abortController.signal },\n                    );\n                })\n                .catch(() => {});\n            cache.set(\n                subscriptionConfigurationHash,\n                (cachedDataPublisherPromise = {\n                    abortController,\n                    dataPublisherPromise,\n                    numSubscribers: 0,\n                }),\n            );\n        }\n        cachedDataPublisherPromise.numSubscribers++;\n        signal.addEventListener(\n            'abort',\n            () => {\n                cachedDataPublisherPromise.numSubscribers--;\n                if (cachedDataPublisherPromise.numSubscribers === 0) {\n                    queueMicrotask(() => {\n                        if (cachedDataPublisherPromise.numSubscribers === 0) {\n                            cache.delete(subscriptionConfigurationHash);\n                            cachedDataPublisherPromise.abortController.abort();\n                        }\n                    });\n                }\n            },\n            { signal: cachedDataPublisherPromise.abortController.signal },\n        );\n        return cachedDataPublisherPromise.dataPublisherPromise;\n    } as TTransport;\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-json-bigint.ts",
    "content": "import { pipe } from '@solana/functional';\nimport { parseJsonWithBigInts, stringifyJsonWithBigInts } from '@solana/rpc-spec-types';\nimport {\n    RpcSubscriptionsChannel,\n    transformChannelInboundMessages,\n    transformChannelOutboundMessages,\n} from '@solana/rpc-subscriptions-spec';\n\n/**\n * Similarly, to {@link getRpcSubscriptionsChannelWithJSONSerialization}, this function will\n * stringify and parse JSON message to and from the given `string` channel. However, this function\n * parses any integer value as a `BigInt` in order to safely handle numbers that exceed the\n * JavaScript [`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER)\n * value.\n */\nexport function getRpcSubscriptionsChannelWithBigIntJSONSerialization(\n    channel: RpcSubscriptionsChannel<string, string>,\n): RpcSubscriptionsChannel<unknown, unknown> {\n    return pipe(\n        channel,\n        c => transformChannelInboundMessages(c, parseJsonWithBigInts),\n        c => transformChannelOutboundMessages(c, stringifyJsonWithBigInts),\n    );\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-json.ts",
    "content": "import { pipe } from '@solana/functional';\nimport {\n    RpcSubscriptionsChannel,\n    transformChannelInboundMessages,\n    transformChannelOutboundMessages,\n} from '@solana/rpc-subscriptions-spec';\n\n/**\n * Given a {@link RpcSubscriptionsChannel}, will return a new channel that parses data published to\n * the `'message'` channel as JSON, and JSON-stringifies messages sent via the\n * {@link RpcSubscriptionsChannel.send | send(message)} method.\n */\nexport function getRpcSubscriptionsChannelWithJSONSerialization(\n    channel: RpcSubscriptionsChannel<string, string>,\n): RpcSubscriptionsChannel<unknown, unknown> {\n    return pipe(\n        channel,\n        c => transformChannelInboundMessages(c, JSON.parse),\n        c => transformChannelOutboundMessages(c, JSON.stringify),\n    );\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions-transport.ts",
    "content": "import { pipe } from '@solana/functional';\nimport { RpcSubscriptionsChannelCreator, RpcSubscriptionsTransport } from '@solana/rpc-subscriptions-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport {\n    RpcSubscriptionsChannelCreatorDevnet,\n    RpcSubscriptionsChannelCreatorFromClusterUrl,\n    RpcSubscriptionsChannelCreatorMainnet,\n    RpcSubscriptionsChannelCreatorTestnet,\n    RpcSubscriptionsTransportDevnet,\n    RpcSubscriptionsTransportFromClusterUrl,\n    RpcSubscriptionsTransportMainnet,\n    RpcSubscriptionsTransportTestnet,\n} from './rpc-subscriptions-clusters';\nimport { getRpcSubscriptionsTransportWithSubscriptionCoalescing } from './rpc-subscriptions-coalescer';\n\nexport type DefaultRpcSubscriptionsTransportConfig<TClusterUrl extends ClusterUrl> = Readonly<{\n    createChannel: RpcSubscriptionsChannelCreatorFromClusterUrl<TClusterUrl, unknown, unknown>;\n}>;\n\n/**\n * Creates a {@link RpcSubscriptionsTransport} with some default behaviours.\n *\n * The default behaviours include:\n * - Logic that coalesces multiple subscriptions for the same notifications with the same arguments\n *   into a single subscription.\n *\n * @param config\n */\nexport function createDefaultRpcSubscriptionsTransport<TClusterUrl extends ClusterUrl>({\n    createChannel,\n}: DefaultRpcSubscriptionsTransportConfig<TClusterUrl>) {\n    return pipe(\n        createRpcSubscriptionsTransportFromChannelCreator(\n            createChannel,\n        ) as RpcSubscriptionsTransport as RpcSubscriptionsTransportFromClusterUrl<TClusterUrl>,\n        transport => getRpcSubscriptionsTransportWithSubscriptionCoalescing(transport),\n    );\n}\n\nexport function createRpcSubscriptionsTransportFromChannelCreator<\n    TChannelCreator extends RpcSubscriptionsChannelCreator<TOutboundMessage, TInboundMessage>,\n    TInboundMessage,\n    TOutboundMessage,\n>(createChannel: TChannelCreator) {\n    return (async ({ execute, signal }) => {\n        const channel = await createChannel({ abortSignal: signal });\n        return await execute({ channel, signal });\n    }) as TChannelCreator extends RpcSubscriptionsChannelCreatorDevnet<TOutboundMessage, TInboundMessage>\n        ? RpcSubscriptionsTransportDevnet\n        : TChannelCreator extends RpcSubscriptionsChannelCreatorTestnet<TOutboundMessage, TInboundMessage>\n          ? RpcSubscriptionsTransportTestnet\n          : TChannelCreator extends RpcSubscriptionsChannelCreatorMainnet<TOutboundMessage, TInboundMessage>\n            ? RpcSubscriptionsTransportMainnet\n            : RpcSubscriptionsTransport;\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/src/rpc-subscriptions.ts",
    "content": "import type { SolanaRpcSubscriptionsApi, SolanaRpcSubscriptionsApiUnstable } from '@solana/rpc-subscriptions-api';\nimport { createSolanaRpcSubscriptionsApi } from '@solana/rpc-subscriptions-api';\nimport {\n    createSubscriptionRpc,\n    RpcSubscriptionsApiMethods,\n    type RpcSubscriptionsTransport,\n} from '@solana/rpc-subscriptions-spec';\nimport { ClusterUrl } from '@solana/rpc-types';\n\nimport { DEFAULT_RPC_SUBSCRIPTIONS_CONFIG } from './rpc-default-config';\nimport {\n    createDefaultSolanaRpcSubscriptionsChannelCreator,\n    DefaultRpcSubscriptionsChannelConfig,\n} from './rpc-subscriptions-channel';\nimport type { RpcSubscriptionsFromTransport } from './rpc-subscriptions-clusters';\nimport { createDefaultRpcSubscriptionsTransport } from './rpc-subscriptions-transport';\n\ntype Config<TClusterUrl extends ClusterUrl> = DefaultRpcSubscriptionsChannelConfig<TClusterUrl>;\n\nfunction createSolanaRpcSubscriptionsImpl<TClusterUrl extends ClusterUrl, TApi extends RpcSubscriptionsApiMethods>(\n    clusterUrl: TClusterUrl,\n    config?: Omit<Config<TClusterUrl>, 'url'>,\n) {\n    const transport = createDefaultRpcSubscriptionsTransport({\n        createChannel: createDefaultSolanaRpcSubscriptionsChannelCreator({ ...config, url: clusterUrl }),\n    });\n    return createSolanaRpcSubscriptionsFromTransport<typeof transport, TApi>(transport);\n}\n\n/**\n * Creates a {@link RpcSubscriptions} instance that exposes the Solana JSON RPC WebSocket API given\n * a cluster URL and some optional channel config. See\n * {@link createDefaultRpcSubscriptionsChannelCreator} for the shape of the channel config.\n */\nexport function createSolanaRpcSubscriptions<TClusterUrl extends ClusterUrl>(\n    clusterUrl: TClusterUrl,\n    config?: Omit<Config<TClusterUrl>, 'url'>,\n) {\n    return createSolanaRpcSubscriptionsImpl<TClusterUrl, SolanaRpcSubscriptionsApi>(clusterUrl, config);\n}\n\n/**\n * Creates a {@link RpcSubscriptions} instance that exposes the Solana JSON RPC WebSocket API,\n * including its unstable methods, given a cluster URL and some optional channel config. See\n * {@link createDefaultRpcSubscriptionsChannelCreator} for the shape of the channel config.\n */\nexport function createSolanaRpcSubscriptions_UNSTABLE<TClusterUrl extends ClusterUrl>(\n    clusterUrl: TClusterUrl,\n    config?: Omit<Config<TClusterUrl>, 'url'>,\n) {\n    return createSolanaRpcSubscriptionsImpl<TClusterUrl, SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>(\n        clusterUrl,\n        config,\n    );\n}\n\n/**\n * Creates a {@link RpcSubscriptions} instance that exposes the Solana JSON RPC WebSocket API given\n * the supplied {@link RpcSubscriptionsTransport}.\n */\nexport function createSolanaRpcSubscriptionsFromTransport<\n    TTransport extends RpcSubscriptionsTransport,\n    TApi extends RpcSubscriptionsApiMethods = SolanaRpcSubscriptionsApi,\n>(transport: TTransport) {\n    return createSubscriptionRpc({\n        api: createSolanaRpcSubscriptionsApi<TApi>(DEFAULT_RPC_SUBSCRIPTIONS_CONFIG),\n        transport,\n    }) as RpcSubscriptionsFromTransport<TApi, TTransport>;\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-subscriptions\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/CHANGELOG.md",
    "content": "# @solana/rpc-subscriptions-api\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/addresses@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/rpc-subscriptions-spec@6.9.0\n    - @solana/rpc-transformers@6.9.0\n    - @solana/rpc-types@6.9.0\n    - @solana/transaction-messages@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`f53ce07`](https://github.com/anza-xyz/kit/commit/f53ce0796c782e79490e1cf11a55e28fb62b8c8f), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439)]:\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/rpc-subscriptions-spec@6.8.0\n    - @solana/rpc-transformers@6.8.0\n    - @solana/rpc-types@6.8.0\n    - @solana/transaction-messages@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/rpc-subscriptions-spec@6.7.0\n    - @solana/rpc-transformers@6.7.0\n    - @solana/rpc-types@6.7.0\n    - @solana/transaction-messages@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/transactions@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/rpc-subscriptions-spec@6.6.0\n    - @solana/rpc-transformers@6.6.0\n    - @solana/rpc-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/rpc-subscriptions-spec@6.5.0\n    - @solana/rpc-transformers@6.5.0\n    - @solana/rpc-types@6.5.0\n    - @solana/transaction-messages@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888)]:\n    - @solana/transaction-messages@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/rpc-transformers@6.4.0\n    - @solana/rpc-subscriptions-spec@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/rpc-subscriptions-spec@6.3.1\n    - @solana/rpc-transformers@6.3.1\n    - @solana/rpc-types@6.3.1\n    - @solana/transaction-messages@6.3.1\n    - @solana/transactions@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/rpc-subscriptions-spec@6.3.0\n    - @solana/rpc-transformers@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/transaction-messages@6.3.0\n    - @solana/transactions@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/rpc-subscriptions-spec@6.2.0\n    - @solana/rpc-transformers@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/transaction-messages@6.2.0\n    - @solana/transactions@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/transaction-messages@6.1.0\n    - @solana/transactions@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/rpc-subscriptions-spec@6.1.0\n    - @solana/rpc-transformers@6.1.0\n    - @solana/rpc-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies [[`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492), [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462)]:\n    - @solana/transaction-messages@6.0.1\n    - @solana/transactions@6.0.1\n    - @solana/addresses@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/rpc-subscriptions-spec@6.0.1\n    - @solana/rpc-transformers@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926), [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a), [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db)]:\n    - @solana/transaction-messages@6.0.0\n    - @solana/transactions@6.0.0\n    - @solana/addresses@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/rpc-subscriptions-spec@6.0.0\n    - @solana/rpc-transformers@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/rpc-subscriptions-spec@5.5.1\n    - @solana/rpc-transformers@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/transaction-messages@5.5.1\n    - @solana/transactions@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/rpc-subscriptions-spec@5.5.0\n    - @solana/rpc-transformers@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/transaction-messages@5.5.0\n    - @solana/transactions@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/rpc-subscriptions-spec@5.4.0\n    - @solana/transaction-messages@5.4.0\n    - @solana/rpc-transformers@5.4.0\n    - @solana/transactions@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/keys@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/rpc-subscriptions-spec@5.3.0\n    - @solana/rpc-transformers@5.3.0\n    - @solana/rpc-types@5.3.0\n    - @solana/transaction-messages@5.3.0\n    - @solana/transactions@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/keys@5.2.0\n    - @solana/transaction-messages@5.2.0\n    - @solana/transactions@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/rpc-subscriptions-spec@5.2.0\n    - @solana/rpc-transformers@5.2.0\n    - @solana/rpc-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951), [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd)]:\n    - @solana/addresses@5.1.0\n    - @solana/transactions@5.1.0\n    - @solana/transaction-messages@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/rpc-subscriptions-spec@5.1.0\n    - @solana/rpc-transformers@5.1.0\n    - @solana/rpc-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/rpc-transformers@5.0.0\n    - @solana/transaction-messages@5.0.0\n    - @solana/transactions@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/keys@5.0.0\n    - @solana/rpc-subscriptions-spec@5.0.0\n\n## 4.0.0\n\n### Major Changes\n\n- [#550](https://github.com/anza-xyz/kit/pull/550) [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a) Thanks [@steveluscher](https://github.com/steveluscher)! - Removed `rentEpoch` from the `AccountInfoBase` type. This property is no longer relevant post SIMD-215. Developers whose applications rely on this property being numeric should either eliminate it or hardcode it to `18_446_744_073_709_551_615n`.\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b), [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013)]:\n    - @solana/transactions@4.0.0\n    - @solana/keys@4.0.0\n    - @solana/transaction-messages@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/rpc-subscriptions-spec@4.0.0\n    - @solana/rpc-transformers@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02), [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6), [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642), [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845), [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf)]:\n    - @solana/transaction-messages@3.0.0\n    - @solana/transactions@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/keys@3.0.0\n    - @solana/rpc-subscriptions-spec@3.0.0\n    - @solana/rpc-transformers@3.0.0\n    - @solana/rpc-types@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a), [`53e1336`](https://github.com/anza-xyz/kit/commit/53e1336149878c84048e0fde5c7e7ace6cc1e97f), [`eb61d94`](https://github.com/anza-xyz/kit/commit/eb61d94786e212fc23778d445a94b86d2b1b024f), [`bbcb913`](https://github.com/anza-xyz/kit/commit/bbcb913839d33abc746f38d6e65e7bfd30cd2ac6), [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`e6c0568`](https://github.com/anza-xyz/kit/commit/e6c0568ef34fdc04075af27eb102851123a02be0), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/transaction-messages@2.3.0\n    - @solana/transactions@2.3.0\n    - @solana/rpc-subscriptions-spec@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/keys@2.3.0\n    - @solana/rpc-transformers@2.3.0\n    - @solana/rpc-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies [[`e881fca`](https://github.com/anza-xyz/kit/commit/e881fca9ea0154d0eeaec682697042f86502b86d)]:\n    - @solana/rpc-subscriptions-spec@2.2.1\n    - @solana/addresses@2.2.1\n    - @solana/keys@2.2.1\n    - @solana/rpc-transformers@2.2.1\n    - @solana/rpc-types@2.2.1\n    - @solana/transaction-messages@2.2.1\n    - @solana/transactions@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/addresses@2.2.0\n    - @solana/keys@2.2.0\n    - @solana/rpc-transformers@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/transaction-messages@2.2.0\n    - @solana/transactions@2.2.0\n    - @solana/rpc-subscriptions-spec@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`7e7b2ef`](https://github.com/anza-xyz/kit/commit/7e7b2efebfd8de431e4381cc3d3fa117d3228030), [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`776e18d`](https://github.com/anza-xyz/kit/commit/776e18d75c759a839608069c61da3f70b775540b), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-transformers@2.1.1\n    - @solana/rpc-subscriptions-spec@2.1.1\n    - @solana/transaction-messages@2.1.1\n    - @solana/transactions@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/keys@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/keys@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/rpc-subscriptions-spec@2.1.0\n    - @solana/transaction-messages@2.1.0\n    - @solana/transactions@2.1.0\n    - @solana/rpc-transformers@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3218](https://github.com/solana-labs/solana-web3.js/pull/3218) [`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcSubscriptionsApi: no longer extend RpcApiSubscriptionsMethods\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3150](https://github.com/solana-labs/solana-web3.js/pull/3150) [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcApi` use new `RpcRequestTransformer` and `RpcResponseTransformer`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#3406](https://github.com/solana-labs/solana-web3.js/pull/3406) [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Replace subscriptionConfigurationHash with RpcRequest in RpcSubscriptionPlan\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc) Thanks [@steveluscher](https://github.com/steveluscher)! - We refactored the lower levels of the subscriptions API entirely.\n\n    Previously, all layers of the subscriptions implementation, from the `WebSocket` transport to the API that developers use, dealt in `AsyncIterables`. These are notoriously difficult to code in such a way that expresses all of the ways in which a subscription might be cancelled or error out. Very slight omissions of care could open memory leaks that would bring down the simplest of apps. The new subscriptions infra in Release Candidate 2 deals with event-based subscriptions all the way up to the highest level API, at which point the subscription is vended to the application as an `AsyncIterable`.\n\n    This has eliminated several classes of memory leak and has made it easier to implement higher-level transports (like the autopinger and the subscription coalescer). Additionally, this update introduces a new channel pool implementation that opens new `WebSocket` connections when existing ones become ‘full.’ Lastly, performance in the new implementation has been improved through a new demultiplexing utility that can separate `message` events into several channels based on arbitrary criteria, meaning you can apply transforms to the message right at the source, and vend subscriptions to downstream consumers that care only about one particular kind of message.\n\n- Updated dependencies [[`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`17c373d`](https://github.com/solana-labs/solana-web3.js/commit/17c373dec6dd167ea5b4e37e213067aa05fa4e14), [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4), [`92655fd`](https://github.com/solana-labs/solana-web3.js/commit/92655fda6631339f07c6cd7097ed9e2518f86853), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/rpc-subscriptions-spec@2.0.0\n    - @solana/transactions@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/rpc-transformers@2.0.0\n    - @solana/keys@2.0.0\n    - @solana/transaction-messages@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/keys@2.0.0-rc.4\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.4\n    - @solana/rpc-transformers@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/transaction-messages@2.0.0-rc.4\n    - @solana/transactions@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.3\n    - @solana/rpc-transformers@2.0.0-rc.3\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/keys@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n    - @solana/transaction-messages@2.0.0-rc.3\n    - @solana/transactions@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3218](https://github.com/solana-labs/solana-web3.js/pull/3218) [`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcSubscriptionsApi: no longer extend RpcApiSubscriptionsMethods\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3150](https://github.com/solana-labs/solana-web3.js/pull/3150) [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcApi` use new `RpcRequestTransformer` and `RpcResponseTransformer`\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#3406](https://github.com/solana-labs/solana-web3.js/pull/3406) [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Replace subscriptionConfigurationHash with RpcRequest in RpcSubscriptionPlan\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc) Thanks [@steveluscher](https://github.com/steveluscher)! - We refactored the lower levels of the subscriptions API entirely.\n\n    Previously, all layers of the subscriptions implementation, from the `WebSocket` transport to the API that developers use, dealt in `AsyncIterables`. These are notoriously difficult to code in such a way that expresses all of the ways in which a subscription might be cancelled or error out. Very slight omissions of care could open memory leaks that would bring down the simplest of apps. The new subscriptions infra in Release Candidate 2 deals with event-based subscriptions all the way up to the highest level API, at which point the subscription is vended to the application as an `AsyncIterable`.\n\n    This has eliminated several classes of memory leak and has made it easier to implement higher-level transports (like the autopinger and the subscription coalescer). Additionally, this update introduces a new channel pool implementation that opens new `WebSocket` connections when existing ones become ‘full.’ Lastly, performance in the new implementation has been improved through a new demultiplexing utility that can separate `message` events into several channels based on arbitrary criteria, meaning you can apply transforms to the message right at the source, and vend subscriptions to downstream consumers that care only about one particular kind of message.\n\n- Updated dependencies [[`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`17c373d`](https://github.com/solana-labs/solana-web3.js/commit/17c373dec6dd167ea5b4e37e213067aa05fa4e14), [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c), [`92655fd`](https://github.com/solana-labs/solana-web3.js/commit/92655fda6631339f07c6cd7097ed9e2518f86853), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc)]:\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.2\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/rpc-transformers@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/transaction-messages@2.0.0-rc.2\n    - @solana/transactions@2.0.0-rc.2\n    - @solana/keys@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies [[`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302)]:\n    - @solana/keys@2.0.0-rc.1\n    - @solana/transactions@2.0.0-rc.1\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.1\n    - @solana/rpc-transformers@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n    - @solana/transaction-messages@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957)]:\n    - @solana/transaction-messages@2.0.0-rc.0\n    - @solana/rpc-transformers@2.0.0-rc.0\n    - @solana/transactions@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/keys@2.0.0-rc.0\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/keys@2.0.0-preview.4\n    - @solana/transaction-messages@2.0.0-preview.4\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.4\n    - @solana/rpc-transformers@2.0.0-preview.4\n    - @solana/transactions@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/transactions@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/transaction-messages@2.0.0-preview.3\n    - @solana/keys@2.0.0-preview.3\n    - @solana/rpc-transformers@2.0.0-preview.3\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/addresses@2.0.0-preview.2\n    - @solana/keys@2.0.0-preview.2\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.2\n    - @solana/rpc-transformers@2.0.0-preview.2\n    - @solana/rpc-types@2.0.0-preview.2\n    - @solana/transactions@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-subscriptions-api?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-subscriptions-api?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-subscriptions-api\n\n# @solana/rpc-subscriptions-api\n\nThis package contains types that describe the [methods](https://solana.com/docs/rpc/websocket) of the Solana JSON RPC Subscriptions API, and utilities for creating a `RpcSubscriptionsApi` implementation with sensible defaults. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nEach RPC subscriptions method is described in terms of a TypeScript type of the following form:\n\n```ts\ntype ExampleApi = {\n    thingNotifications(address: Address): Thing;\n};\n```\n\nA `RpcSubscriptionsApi` that implements `ExampleApi` will ultimately expose its defined methods on any `RpcSubscriptions` that uses it.\n\n```ts\nconst rpcSubscriptions: RpcSubscriptions<ExampleApi> = createExampleRpcSubscriptions(/* ... */);\nconst thingNotifications = await rpc\n    .thingNotifications(address('95DpK3y3GF7U8s1k4EvZ7xqyeCkhsHeZaE97iZpHUGMN'))\n    .subscribe({ abortSignal: AbortSignal.timeout(5_000) });\ntry {\n    for await (const thing of thingNotifications) {\n        console.log('Got a thing', thing);\n    }\n} catch (e) {\n    console.error('Our subscription to `Thing` notifications has failed', e);\n} finally {\n    console.log('We are done listening for `Thing` notifications');\n}\n```\n\n## Types\n\n### `SolanaRpcSubscriptionsApi{Devnet|Testnet|Mainnet}`\n\nThese types represent the RPC subscription methods available on a specific Solana cluster.\n\n## Functions\n\n### `createSolanaRpcSubscriptionsApi(config)`\n\nCreates a `RpcSubscriptionsApi` implementation of the Solana JSON RPC Subscriptions API with some default behaviours.\n\nThe default behaviours include:\n\n- A transform that converts `bigint` inputs to `number` for compatibility with version 1.0 of the Solana JSON RPC.\n- A transform that calls the config's `onIntegerOverflow` handler whenever a `bigint` input would overflow a JavaScript IEEE 754 number. See [this](https://github.com/solana-labs/solana-web3.js/issues/1116) GitHub issue for more information.\n- A transform that applies a default commitment wherever not specified\n\n#### Arguments\n\nA config object with the following properties:\n\n- `defaultCommitment`: An optional default `Commitment` value. Given an RPC method that takes `commitment` as a parameter, this value will be used when the caller does not supply one.\n- `onIntegerOverflow(request, keyPath, value): void`: An optional function that will be called whenever a `bigint` input exceeds that which can be expressed using JavaScript numbers. This is used in the default `SolanaRpcSubscriptionsApi` to throw an exception rather than to allow truncated values to propagate through a program.\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-subscriptions-api\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Defines all default Solana RPC subscriptions as types\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-subscriptions-api\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/rpc-subscriptions-spec\": \"workspace:*\",\n        \"@solana/rpc-transformers\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/rpc-subscriptions-channel-websocket\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/__setup__.ts",
    "content": "import { createWebSocketChannel } from '@solana/rpc-subscriptions-channel-websocket';\nimport { createSubscriptionRpc, RpcSubscriptions, RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\n\nimport {\n    createSolanaRpcSubscriptionsApi_UNSTABLE,\n    SolanaRpcSubscriptionsApi,\n    SolanaRpcSubscriptionsApiUnstable,\n} from '..';\n\nexport function createLocalhostSolanaRpcSubscriptions(): RpcSubscriptions<\n    SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable\n> {\n    return createSubscriptionRpc({\n        api: createSolanaRpcSubscriptionsApi_UNSTABLE(),\n        async transport({ execute, signal }) {\n            const webSocketChannel = await createWebSocketChannel({\n                sendBufferHighWatermark: Number.POSITIVE_INFINITY,\n                signal,\n                url: 'ws://127.0.0.1:8900',\n            });\n            const channel = {\n                ...webSocketChannel,\n                on(type, listener, options) {\n                    if (type !== 'message') {\n                        return webSocketChannel.on(type, listener, options);\n                    }\n                    return webSocketChannel.on(\n                        'message',\n                        function deserializingListener(message: string) {\n                            const deserializedMessage = JSON.parse(message);\n                            listener(deserializedMessage);\n                        },\n                        options,\n                    );\n                },\n                send(message) {\n                    const serializedMessage = JSON.stringify(message);\n                    return webSocketChannel.send(serializedMessage);\n                },\n            } as RpcSubscriptionsChannel<unknown, unknown>;\n            return await execute({ channel, signal });\n        },\n    });\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/account-notifications-test.ts",
    "content": "import type { Commitment } from '@solana/rpc-types';\n\ndescribe('accountNotifications', () => {\n    ([undefined, 'confirmed', 'finalized', 'processed'] as (Commitment | undefined)[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it.todo('produces account notifications');\n        });\n    });\n\n    describe('when called with base58 encoding', () => {\n        it.todo('produces account notifications with annotated base58 encoding');\n    });\n\n    describe('when called with base64 encoding', () => {\n        it.todo('produces account notifications with annotated base64 encoding');\n    });\n\n    describe('when called with base64+zstd encoding', () => {\n        it.todo('produces account notifications with annotated base64+zstd encoding');\n    });\n\n    describe('when called with jsonParsed encoding', () => {\n        describe('for an account without parse-able JSON data', () => {\n            it.todo('produces account notifications as base64');\n        });\n\n        describe('for an account with parse-able JSON data', () => {\n            it.todo('produces account notifications with parsed JSON data for AddressLookupTable account');\n\n            it.todo('produces account notifications with parsed JSON data for BpfLoaderUpgradeable account');\n\n            it.todo('produces account notifications with parsed JSON data for Config validator account');\n\n            it.todo('produces account notifications with parsed JSON data for Config stake account');\n\n            it.todo('produces account notifications with parsed JSON data for Nonce account');\n\n            it.todo('produces account notifications with parsed JSON data for SPL Token mint account');\n\n            it.todo('produces account notifications with parsed JSON data for SPL Token token account');\n\n            it.todo('produces account notifications with parsed JSON data for SPL token multisig account');\n\n            it.todo('produces account notifications with parsed JSON data for SPL Token 22 mint account');\n\n            it.todo('produces account notifications with parsed JSON data for Stake account');\n\n            it.todo('produces account notifications with parsed JSON data for Sysvar rent account');\n\n            it.todo('produces account notifications with parsed JSON data for Vote account');\n        });\n    });\n\n    describe('when called with no encoding', () => {\n        it.todo('produces account notifications with base58 data without an annotation');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/block-notifications-test.ts",
    "content": "describe('blockNotifications', () => {\n    (\n        ['all', { mentionsAccountOrProgram: 'Vote111111111111111111111111111111111111111' }] as (\n            | 'all'\n            | { mentionsAccountOrProgram: string }\n        )[]\n    ).forEach(filter => {\n        describe(`filter: ${JSON.stringify(filter)}`, () => {\n            describe('when `transactionDetails` is set to `none`', () => {\n                describe('when called with rewards set to false', () => {\n                    it.todo('returns an empty array for transactions and an empty array for rewards');\n                });\n\n                describe('when called with rewards set to true', () => {\n                    it.todo('returns no transactions and an array of rewards for rewards');\n                });\n            });\n\n            describe('when `transactionDetails` is set to `signatures`', () => {\n                describe('returns transactions with only signatures', () => {\n                    it.todo('when maxSupportedTransactionVersion is set');\n                    it.todo('when maxSupportedTransactionVersion is not set');\n                    it.todo('when called without additional config');\n                });\n            });\n\n            describe('when `transactionDetails` is set to `accounts`', () => {\n                describe('returns transactions with only signatures and an annotated list of accounts', () => {\n                    it.todo('when maxSupportedTransactionVersion is set');\n                    it.todo('when maxSupportedTransactionVersion is not set');\n                    it.todo('when called without additional config');\n                });\n            });\n\n            describe('when `transactionDetails` is set to `full`', () => {\n                describe('returns transactions with the correct shape', () => {\n                    it.todo('when called with json encoding and maxSupportedTransactionVersion is set');\n                    it.todo('when called with jsonParsed encoding and maxSupportedTransactionVersion is set');\n                    it.todo('when called with base58 encoding and maxSupportedTransactionVersion is set');\n                    it.todo('when called with base64 encoding and maxSupportedTransactionVersion is set');\n                    it.todo('when called with json encoding and maxSupportedTransactionVersion is not set');\n                    it.todo('when called with jsonParsed encoding and maxSupportedTransactionVersion is not set');\n                    it.todo('when called with base58 encoding and maxSupportedTransactionVersion is not set');\n                    it.todo('when called with base64 encoding and maxSupportedTransactionVersion is not set');\n                    it.todo('when called without additional config');\n                });\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/index-test.ts",
    "content": "import { executeRpcPubSubSubscriptionPlan, type RpcSubscriptionsApi } from '@solana/rpc-subscriptions-spec';\n\nimport { createSolanaRpcSubscriptionsApi } from '../index';\n\ntype TestRpcSubscriptionNotifications = {\n    thingNotifications(...args: unknown[]): unknown;\n};\n\njest.mock('@solana/rpc-subscriptions-spec', () => ({\n    ...jest.requireActual('@solana/rpc-subscriptions-spec'),\n    executeRpcPubSubSubscriptionPlan: jest.fn().mockReturnValue(\n        new Promise(() => {\n            /* never resolves */\n        }),\n    ),\n}));\n\ndescribe('createSolanaRpcSubscriptionsApi', () => {\n    let api: RpcSubscriptionsApi<TestRpcSubscriptionNotifications>;\n    beforeEach(() => {\n        api = createSolanaRpcSubscriptionsApi();\n    });\n    it('creates a subscription plan that synthesizes the correct subscribe/unsubscribe method names from the name of the notification', () => {\n        const { execute } = api.thingNotifications();\n        void execute({\n            channel: {\n                on: jest.fn(),\n                send: jest.fn(),\n            },\n            signal: new AbortController().signal,\n        });\n        expect(executeRpcPubSubSubscriptionPlan).toHaveBeenCalledWith(\n            expect.objectContaining({\n                subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n                unsubscribeMethodName: 'thingUnsubscribe',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/logs-notifications-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Commitment } from '@solana/rpc-types';\n\ndescribe('logsNotifications', () => {\n    (\n        ['all', 'allWithVotes', { mentions: ['Vote111111111111111111111111111111111111111'] as [Address] }] as (\n            | 'all'\n            | 'allWithVotes'\n            | { mentions: [Address] }\n        )[]\n    ).forEach(filter => {\n        // Note: Can't do finalized because it requires too much time to wait for the transaction to be finalized.\n        // Note: processed is also unreliable because it requires non-vote transactions to occur after this subscription opens,\n        // while confirmed can produce notifications for previously sent transactions that are confirmed in this subscription window.\n        (['confirmed'] as Commitment[]).forEach(commitment => {\n            describe(`with filter ${JSON.stringify(filter)} and commitment ${JSON.stringify(commitment)}`, () => {\n                // Unfortunately, CI will run subscriptions tests _after_ HTTP, so there will be no logs to listen to.\n                it.todo('produces logs notifications');\n            });\n        });\n    });\n    describe('for a failed transaction', () => {\n        // TODO: Reproduce a failed transaction.\n        // In this case, the logs would be null, and the `err` field would have an object\n        it.todo('produces an error object and null logs');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/program-notifications-test.ts",
    "content": "import type { Commitment } from '@solana/rpc-types';\n\ndescribe('programNotifications', () => {\n    (['confirmed', 'finalized', 'processed'] as Commitment[]).forEach(commitment => {\n        describe(`when called with \\`${commitment}\\` commitment`, () => {\n            it.todo('produces program account notifications');\n        });\n    });\n\n    describe('when called with a program with no accounts', () => {\n        it.todo('returns an empty list');\n    });\n\n    describe('when called with base58 encoding', () => {\n        it.todo('produces program account notifications with annotated base58 encoding');\n    });\n\n    describe('when called with base64 encoding', () => {\n        it.todo('produces program account notifications with annotated base64 encoding');\n    });\n\n    describe('when called with base64+zstd encoding', () => {\n        it.todo('produces program account notifications with annotated base64+zstd encoding');\n    });\n\n    describe('when called with jsonParsed encoding', () => {\n        describe('for an account without parse-able JSON data', () => {\n            it.todo('falls back to annotated base64');\n        });\n\n        describe('for an account with parse-able JSON data', () => {\n            it.todo('returns parsed JSON data for AddressLookupTable account');\n\n            it.todo('returns parsed JSON data for BpfLoaderUpgradeable account');\n\n            it.todo('returns parsed JSON data for Config validator account');\n\n            it.todo('returns parsed JSON data for Config stake account');\n\n            it.todo('returns parsed JSON data for Nonce account');\n\n            it.todo('returns parsed JSON data for SPL Token mint account');\n\n            it.todo('returns parsed JSON data for SPL Token token account');\n\n            it.todo('returns parsed JSON data for SPL token multisig account');\n\n            it.todo('returns parsed JSON data for SPL Token 22 mint account');\n\n            it.todo('returns parsed JSON data for Stake account');\n\n            it.todo('returns parsed JSON data for Sysvar rent account');\n\n            it.todo('returns parsed JSON data for Vote account');\n        });\n    });\n\n    describe('when called with no encoding', () => {\n        it.todo('returns base58 data without an annotation');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/root-notifications-test.ts",
    "content": "describe('rootNotifications', () => {\n    // TODO: A change in root takes too long to occur in order for our tests to pass.\n    it.todo('produces root notifications');\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/signature-notifications-test.ts",
    "content": "import type { Commitment } from '@solana/rpc-types';\n\ndescribe('signatureNotifications', () => {\n    ([undefined, 'confirmed', 'finalized', 'processed'] as (Commitment | undefined)[]).forEach(commitment => {\n        describe(`with commitment ${JSON.stringify(commitment)}`, () => {\n            // TODO: No deterministic way to get a valid transaction signature without sending one\n            it.todo('produces signature notifications');\n        });\n    });\n    describe('on failed transaction', () => {\n        it.todo('produces object transaction error');\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/slot-notifications-test.ts",
    "content": "import { type RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport type { SlotNotificationsApi } from '../slot-notifications';\nimport { createLocalhostSolanaRpcSubscriptions } from './__setup__';\n\ndescribe('slotNotifications', () => {\n    let rpc: RpcSubscriptions<SlotNotificationsApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpcSubscriptions();\n    });\n\n    it('produces slot notifications', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        try {\n            const slotNotifications = await rpc.slotNotifications().subscribe({ abortSignal: abortController.signal });\n            const iterator = slotNotifications[Symbol.asyncIterator]();\n            await expect(iterator.next()).resolves.toHaveProperty('value', {\n                parent: expect.any(BigInt),\n                root: expect.any(BigInt),\n                slot: expect.any(BigInt),\n            });\n        } finally {\n            abortController.abort();\n        }\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/slots-updates-notifications-test.ts",
    "content": "import { type RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport type { SlotsUpdatesNotificationsApi } from '../slots-updates-notifications';\nimport { createLocalhostSolanaRpcSubscriptions } from './__setup__';\n\ndescribe('slotsUpdatesNotifications', () => {\n    let rpc: RpcSubscriptions<SlotsUpdatesNotificationsApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpcSubscriptions();\n    });\n\n    it('produces slots updates notifications', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        try {\n            const slotsUpdatesNotifications = await rpc\n                .slotsUpdatesNotifications()\n                .subscribe({ abortSignal: abortController.signal });\n            const iterator = slotsUpdatesNotifications[Symbol.asyncIterator]();\n            await expect(iterator.next()).resolves.toHaveProperty(\n                'value',\n                expect.objectContaining({\n                    slot: expect.any(BigInt),\n                    timestamp: expect.any(BigInt),\n                    type: expect.any(String),\n                }),\n            );\n        } finally {\n            abortController.abort();\n        }\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__tests__/vote-notifications-test.ts",
    "content": "import { type RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\n\nimport type { VoteNotificationsApi } from '../vote-notifications';\nimport { createLocalhostSolanaRpcSubscriptions } from './__setup__';\n\ndescribe('voteNotifications', () => {\n    let rpc: RpcSubscriptions<VoteNotificationsApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpcSubscriptions();\n    });\n\n    it('produces vote notifications', async () => {\n        expect.assertions(1);\n\n        const abortController = new AbortController();\n        try {\n            const voteNotifications = await rpc.voteNotifications().subscribe({ abortSignal: abortController.signal });\n            const iterator = voteNotifications[Symbol.asyncIterator]();\n            await expect(iterator.next()).resolves.toHaveProperty(\n                'value',\n                expect.objectContaining({\n                    hash: expect.any(String),\n                    signature: expect.any(String),\n                    slots: expect.arrayContaining([expect.any(BigInt)]),\n                    // TODO: Test for null. It appears this is maybe non-deterministic? Seems to maybe occur on delayed votes?\n                    timestamp: expect.any(BigInt),\n                    votePubkey: expect.any(String),\n                }),\n            );\n        } finally {\n            abortController.abort();\n        }\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/account-notifications-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { Address } from '@solana/addresses';\nimport type { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type {\n    Base58EncodedBytes,\n    Base58EncodedDataResponse,\n    Base64EncodedDataResponse,\n    Base64EncodedZStdCompressedDataResponse,\n    Lamports,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\nimport type { AccountNotificationsApi } from '../account-notifications';\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<AccountNotificationsApi>;\n// See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n// data is 'test data'\n// Note: In type tests, it doesn't matter if the account is actually JSON-parseable\nconst pubkey =\n    'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\ntype TNotificationBase = Readonly<{\n    executable: boolean;\n    lamports: Lamports;\n    owner: Address;\n}>;\n\n// No optional configs\nrpcSubscriptions.accountNotifications(pubkey) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            data: Base58EncodedBytes;\n        }\n    >\n>;\nrpcSubscriptions\n    .accountNotifications(pubkey)\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                data: Base58EncodedBytes;\n            }\n        >\n    >\n>;\n// With optional configs\nrpcSubscriptions.accountNotifications(pubkey, { commitment: 'confirmed' }) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            data: Base58EncodedBytes;\n        }\n    >\n>;\nrpcSubscriptions\n    .accountNotifications(pubkey, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                data: Base58EncodedBytes;\n            }\n        >\n    >\n>;\n// Base58 encoded data\nrpcSubscriptions.accountNotifications(pubkey, { encoding: 'base58' }) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            data: Base58EncodedDataResponse;\n        }\n    >\n>;\nrpcSubscriptions\n    .accountNotifications(pubkey, { encoding: 'base58' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                data: Base58EncodedDataResponse;\n            }\n        >\n    >\n>;\n// Base64 encoded data\nrpcSubscriptions.accountNotifications(pubkey, { encoding: 'base64' }) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            data: Base64EncodedDataResponse;\n        }\n    >\n>;\nrpcSubscriptions\n    .accountNotifications(pubkey, { encoding: 'base64' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                data: Base64EncodedDataResponse;\n            }\n        >\n    >\n>;\n// Base64 + ZSTD encoded data\nrpcSubscriptions.accountNotifications(pubkey, { encoding: 'base64+zstd' }) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            data: Base64EncodedZStdCompressedDataResponse;\n        }\n    >\n>;\nrpcSubscriptions\n    .accountNotifications(pubkey, { encoding: 'base64+zstd' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                data: Base64EncodedZStdCompressedDataResponse;\n            }\n        >\n    >\n>;\n// JSON parsed data\nrpcSubscriptions.accountNotifications(pubkey, { encoding: 'jsonParsed' }) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            data:\n                | Base64EncodedDataResponse\n                | Readonly<{\n                      parsed: unknown;\n                      program: string;\n                      space: bigint;\n                  }>;\n        }\n    >\n>;\nrpcSubscriptions\n    .accountNotifications(pubkey, { encoding: 'jsonParsed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                data:\n                    | Base64EncodedDataResponse\n                    | Readonly<{\n                          parsed: unknown;\n                          program: string;\n                          space: bigint;\n                      }>;\n            }\n        >\n    >\n>;\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/block-notifications-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { Address } from '@solana/addresses';\nimport type { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type {\n    Base58EncodedBytes,\n    Base58EncodedDataResponse,\n    Base64EncodedDataResponse,\n    Blockhash,\n    Lamports,\n    Reward,\n    Slot,\n    SolanaRpcResponse,\n    TokenBalance,\n    TransactionError,\n    TransactionStatus,\n} from '@solana/rpc-types';\nimport type { TransactionVersion } from '@solana/transaction-messages';\n\nimport type { BlockNotificationsApi } from '../block-notifications';\n\ntype BlockNotificationsApiNotificationBase = SolanaRpcResponse<\n    Readonly<{\n        block: {\n            blockHeight: bigint;\n            blockTime: bigint;\n            blockhash: string;\n            parentSlot: bigint;\n            previousBlockhash: string;\n        } | null;\n        err: string | null;\n        slot: Slot;\n    }>\n>;\ntype BlockNotificationsApiNotificationWithRewards = SolanaRpcResponse<\n    Readonly<{\n        block: {\n            rewards: readonly Reward[];\n        } | null;\n    }>\n>;\ntype BlockNotificationsApiNotificationWithSignatures = SolanaRpcResponse<\n    Readonly<{\n        block: {\n            signatures: readonly Base58EncodedBytes[];\n        } | null;\n    }>\n>;\ntype BlockNotificationsApiNotificationWithTransactions<TTransactionType> = SolanaRpcResponse<\n    Readonly<{\n        block: {\n            transactions: readonly TTransactionType[];\n        } | null;\n    }>\n>;\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<BlockNotificationsApi>;\n\n// First overload\n// Rewards set to `false`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    showRewards: false,\n    transactionDetails: 'none',\n}) satisfies PendingRpcSubscriptionsRequest<BlockNotificationsApiNotificationBase>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        showRewards: false,\n        transactionDetails: 'none',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase>\n>;\n// No rewards\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    showRewards: false,\n    transactionDetails: 'none',\n    // @ts-expect-error no rewards\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        showRewards: false,\n        transactionDetails: 'none',\n    })\n    // @ts-expect-error no rewards\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards>\n>;\n\n// First overload with configs\n// Rewards set to `false`\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'processed',\n    encoding: 'base64',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n    transactionDetails: 'none',\n}) satisfies PendingRpcSubscriptionsRequest<BlockNotificationsApiNotificationBase>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'processed',\n        encoding: 'base64',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n        transactionDetails: 'none',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase>\n>;\n// No rewards\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'processed',\n    encoding: 'base64',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n    transactionDetails: 'none',\n    // @ts-expect-error no rewards\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'processed',\n        encoding: 'base64',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n        transactionDetails: 'none',\n    })\n    // @ts-expect-error no rewards\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards>\n>;\n\n// Second overload\n// Rewards defaults to `true`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    transactionDetails: 'none',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        transactionDetails: 'none',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards>\n>;\n\n// Second overload with configs\n// Rewards defaults to `true`\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'base58',\n    maxSupportedTransactionVersion: 0,\n    transactionDetails: 'none',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'base58',\n        maxSupportedTransactionVersion: 0,\n        transactionDetails: 'none',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards>\n>;\n\n// Second overload\n// Rewards set to `true`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    showRewards: true,\n    transactionDetails: 'none',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        showRewards: true,\n        transactionDetails: 'none',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards>\n>;\n\n// Second overload with configs\n// Rewards set to `true`\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'base58',\n    maxSupportedTransactionVersion: 0,\n    showRewards: true,\n    transactionDetails: 'none',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'base58',\n        maxSupportedTransactionVersion: 0,\n        showRewards: true,\n        transactionDetails: 'none',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithRewards>\n>;\n\n// Third overload\n// Rewards set to `false`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    showRewards: false,\n    transactionDetails: 'signatures',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithSignatures\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        showRewards: false,\n        transactionDetails: 'signatures',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithSignatures>\n>;\n// No rewards\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    showRewards: false,\n    transactionDetails: 'signatures',\n    // @ts-expect-error no rewards\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithSignatures\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        showRewards: false,\n        transactionDetails: 'signatures',\n    })\n    // @ts-expect-error no rewards\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithSignatures\n    >\n>;\n\n// Third overload with configs\n// Rewards set to `false`\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'json',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n    transactionDetails: 'signatures',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithSignatures\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'json',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n        transactionDetails: 'signatures',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<BlockNotificationsApiNotificationBase & BlockNotificationsApiNotificationWithSignatures>\n>;\n// No rewards\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'json',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n    transactionDetails: 'signatures',\n    // @ts-expect-error no rewards\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithSignatures\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'json',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n        transactionDetails: 'signatures',\n    })\n    // @ts-expect-error no rewards\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithSignatures\n    >\n>;\n\n// Fourth overload\n// Rewards defaults to `true`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    transactionDetails: 'signatures',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithSignatures\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        transactionDetails: 'signatures',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithSignatures\n    >\n>;\n\n// Fourth overload with configs\n// Rewards defaults to `true`\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'jsonParsed',\n    maxSupportedTransactionVersion: 0,\n    transactionDetails: 'signatures',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithSignatures\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'jsonParsed',\n        maxSupportedTransactionVersion: 0,\n        transactionDetails: 'signatures',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithSignatures\n    >\n>;\n\n// // Fourth overload\n// // Rewards set to `true`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    showRewards: true,\n    transactionDetails: 'signatures',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithSignatures\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        showRewards: true,\n        transactionDetails: 'signatures',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithSignatures\n    >\n>;\n\n// Fourth overload with configs\n// Rewards set to `true`\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'jsonParsed',\n    maxSupportedTransactionVersion: 0,\n    transactionDetails: 'signatures',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithSignatures\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'jsonParsed',\n        maxSupportedTransactionVersion: 0,\n        transactionDetails: 'signatures',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithSignatures\n    >\n>;\n\ntype ExpectedMetaForAccountsBase = {\n    err: TransactionError | null;\n    fee: Lamports;\n    postBalances: readonly Lamports[];\n    postTokenBalances?: readonly TokenBalance[];\n    preBalances: readonly Lamports[];\n    preTokenBalances?: readonly TokenBalance[];\n    status: TransactionStatus;\n};\n\ntype ExpectedTransactionForAccountsBaseLegacy = {\n    meta: ExpectedMetaForAccountsBase | null;\n    transaction: {\n        accountKeys: readonly Readonly<{\n            pubkey: string;\n            signer: boolean;\n            source: 'transaction';\n            writable: boolean;\n        }>[];\n        signatures: readonly Base58EncodedBytes[];\n    };\n};\n\ntype ExpectedTransactionForAccountsBaseVersioned = {\n    meta: ExpectedMetaForAccountsBase | null;\n    transaction: {\n        accountKeys: readonly Readonly<{\n            pubkey: string;\n            signer: boolean;\n            source: 'lookupTable' | 'transaction';\n            writable: boolean;\n        }>[];\n        signatures: readonly Base58EncodedBytes[];\n    };\n    version: TransactionVersion;\n};\n\n// Fifth overload\n// Rewards set to `false`\n// Max supported transaction version set to 0\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n    >\n>;\n\n// Fifth overload with configs\n// Rewards set to `false`\n// Max supported transaction version set to 0\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'base64',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'base64',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n    >\n>;\n\n// Sixth overload\n// Rewards set to `false`\n// Max supported transaction version defaults to `legacy`\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'base64',\n    showRewards: false,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'base64',\n        showRewards: false,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseLegacy>\n    >\n>;\n\n// Sixth overload with configs\n// Rewards set to `false`\n// Max supported transaction version defaults to `legacy`\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'base64',\n    showRewards: false,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'base64',\n        showRewards: false,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseLegacy>\n    >\n>;\n\n// Seventh overload\n// Rewards defaults to `true`\n// Max supported transaction version set to 0\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    maxSupportedTransactionVersion: 0,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        maxSupportedTransactionVersion: 0,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n    >\n>;\n\n// Seventh overload with configs\n// Rewards defaults to `true`\n// Max supported transaction version set to 0\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'base64',\n    maxSupportedTransactionVersion: 0,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'base64',\n        maxSupportedTransactionVersion: 0,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n    >\n>;\n\n// Seventh overload\n// Rewards set to `true`\n// Max supported transaction version set to 0\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    maxSupportedTransactionVersion: 0,\n    showRewards: true,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        maxSupportedTransactionVersion: 0,\n        showRewards: true,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n    >\n>;\n\n// Seventh overload with configs\n// Rewards set to `true`\n// Max supported transaction version set to 0\nrpcSubscriptions.blockNotifications('all', {\n    commitment: 'confirmed',\n    encoding: 'base64',\n    maxSupportedTransactionVersion: 0,\n    showRewards: true,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        commitment: 'confirmed',\n        encoding: 'base64',\n        maxSupportedTransactionVersion: 0,\n        showRewards: true,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseVersioned>\n    >\n>;\n\n// Eighth overload\n// Rewards defaults to `true`\n// Max supported transaction version defaults to `legacy`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseLegacy>\n    >\n>;\n\n// Eighth overload\n// Rewards set to `true`\n// Max supported transaction version defaults to `legacy`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    showRewards: true,\n    transactionDetails: 'accounts',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        showRewards: true,\n        transactionDetails: 'accounts',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForAccountsBaseLegacy>\n    >\n>;\n\ntype ExpectedMetaForFullBase58 = {\n    computeUnitsConsumed?: bigint;\n    err: TransactionError | null;\n    fee: Lamports;\n    innerInstructions: readonly Readonly<{\n        index: number;\n        instructions: readonly Readonly<{\n            accounts: readonly number[];\n            data: Base58EncodedBytes;\n            programIdIndex: number;\n            stackHeight?: number;\n        }>[];\n    }>[];\n    logMessages: readonly string[] | null;\n    postBalances: readonly Lamports[];\n    postTokenBalances?: readonly TokenBalance[];\n    preBalances: readonly Lamports[];\n    preTokenBalances?: readonly TokenBalance[];\n    returnData?: Readonly<{\n        data: Base64EncodedDataResponse;\n        programId: Address;\n    }>;\n    rewards: readonly Reward[] | null;\n    status: TransactionStatus;\n};\n\ntype ExpectedTransactionForFullBase58Legacy = {\n    meta: ExpectedMetaForFullBase58 | null;\n    transaction: Base58EncodedDataResponse;\n};\n\ntype ExpectedTransactionForFullBase58Versioned = {\n    meta:\n        | (ExpectedMetaForFullBase58 &\n              Readonly<{\n                  loadedAddresses: {\n                      readonly: readonly Address[];\n                      writable: readonly Address[];\n                  };\n              }>)\n        | null;\n    transaction: Base58EncodedDataResponse;\n    version: TransactionVersion;\n};\n\n// Ninth overload\n// Rewards set to `false`\n// Max supported transaction version set to 0\n// Encoding set to `base58`\n// Transaction details default to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base58',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Versioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base58',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Versioned>\n    >\n>;\n\n// Ninth overload\n// Rewards set to `false`\n// Max supported transaction version set to 0\n// Encoding set to `base58`\n// Transaction details set to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base58',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n    transactionDetails: 'full',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Versioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base58',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n        transactionDetails: 'full',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Versioned>\n    >\n>;\n\n// Tenth overload\n// Rewards set to `false`\n// Max supported transaction defaults to `legacy`\n// Encoding set to `base58`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base58',\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Legacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base58',\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Legacy>\n    >\n>;\n\n// Tenth overload\n// Rewards set to `false`\n// Max supported transaction defaults to `legacy`\n// Encoding set to `base58`\n// Transaction details set to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base58',\n    showRewards: false,\n    transactionDetails: 'full',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Legacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base58',\n        showRewards: false,\n        transactionDetails: 'full',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Legacy>\n    >\n>;\n\n// Eleventh overload\n// Rewards defaults to `true`\n// Max supported transaction version set to 0\n// Encoding set to `base58`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base58',\n    maxSupportedTransactionVersion: 0,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Versioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base58',\n        maxSupportedTransactionVersion: 0,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Versioned>\n    >\n>;\n\n// Eleventh overload\n// Rewards set to `true`\n// Max supported transaction version set to 0\n// Encoding set to `base58`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base58',\n    maxSupportedTransactionVersion: 0,\n    showRewards: true,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Versioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base58',\n        maxSupportedTransactionVersion: 0,\n        showRewards: true,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Versioned>\n    >\n>;\n\n// Twelfth overload\n// Rewards defaults to `true`\n// Max supported transaction defaults to `legacy`\n// Encoding set to `base58`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base58',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Legacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base58',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Legacy>\n    >\n>;\n\n// Twelfth overload\n// Rewards set to `true`\n// Max supported transaction defaults to `legacy`\n// Encoding set to `base58`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base58',\n    showRewards: true,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Legacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base58',\n        showRewards: true,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase58Legacy>\n    >\n>;\n\ntype ExpectedMetaForFullBase64 = {\n    computeUnitsConsumed?: bigint;\n    err: TransactionError | null;\n    fee: Lamports;\n    innerInstructions: readonly Readonly<{\n        index: number;\n        instructions: readonly Readonly<{\n            accounts: readonly number[];\n            data: Base58EncodedBytes;\n            programIdIndex: number;\n            stackHeight?: number;\n        }>[];\n    }>[];\n    logMessages: readonly string[] | null;\n    postBalances: readonly Lamports[];\n    postTokenBalances?: readonly TokenBalance[];\n    preBalances: readonly Lamports[];\n    preTokenBalances?: readonly TokenBalance[];\n    returnData?: Readonly<{\n        data: Base64EncodedDataResponse;\n        programId: Address;\n    }>;\n    rewards: readonly Reward[] | null;\n    status: TransactionStatus;\n};\n\ntype ExpectedTransactionForFullBase64Legacy = {\n    meta: ExpectedMetaForFullBase64 | null;\n    transaction: Base64EncodedDataResponse;\n};\n\ntype ExpectedTransactionForFullBase64Versioned = {\n    meta:\n        | (ExpectedMetaForFullBase64 &\n              Readonly<{\n                  loadedAddresses: {\n                      readonly: readonly Address[];\n                      writable: readonly Address[];\n                  };\n              }>)\n        | null;\n    transaction: Base64EncodedDataResponse;\n    version: TransactionVersion;\n};\n\n// Thirteenth overload\n// Rewards set to `false`\n// Max supported transaction version set to 0\n// Encoding set to `base64`\n// Transaction details default to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base64',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Versioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base64',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Versioned>\n    >\n>;\n\n// Thirteenth overload\n// Rewards set to `false`\n// Max supported transaction version set to 0\n// Encoding set to `base64`\n// Transaction details set to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base64',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n    transactionDetails: 'full',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Versioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base64',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n        transactionDetails: 'full',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Versioned>\n    >\n>;\n\n// Fourteenth overload\n// Rewards set to `false`\n// Max supported transaction defaults to `legacy`\n// Encoding set to `base64`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base64',\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Legacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base64',\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Legacy>\n    >\n>;\n\n// Fourteenth overload\n// Rewards set to `false`\n// Max supported transaction defaults to `legacy`\n// Encoding set to `base64`\n// Transaction details set to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base64',\n    showRewards: false,\n    transactionDetails: 'full',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Legacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base64',\n        showRewards: false,\n        transactionDetails: 'full',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Legacy>\n    >\n>;\n\n// Fifteenth overload\n// Rewards defaults to `true`\n// Max supported transaction version set to 0\n// Encoding set to `base64`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base64',\n    maxSupportedTransactionVersion: 0,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Legacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base64',\n        maxSupportedTransactionVersion: 0,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Legacy>\n    >\n>;\n\n// // Sixteenth overload\n// // Rewards defaults to `true`\n// // Max supported transaction defaults to `legacy`\n// // Encoding set to `base64`\n// // Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'base64',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Legacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'base64',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullBase64Legacy>\n    >\n>;\n\ntype ExpectedParsedTransactionInstruction = Readonly<{\n    parsed: {\n        info?: object;\n        type: string;\n    };\n    program: string;\n    programId: Address;\n}>;\n\ntype ExpectedPartiallyDecodedTransactionInstruction = Readonly<{\n    accounts: readonly Address[];\n    data: Base58EncodedBytes;\n    programId: Address;\n}>;\n\ntype ExpectedTransactionInstructionForFullJsonParsed =\n    | ExpectedParsedTransactionInstruction\n    | ExpectedPartiallyDecodedTransactionInstruction;\n\ntype ExpectedMetaForFullJsonParsedBase = {\n    computeUnitsConsumed?: bigint;\n    err: TransactionError | null;\n    fee: Lamports;\n    innerInstructions: readonly Readonly<{\n        index: number;\n        instructions: readonly ExpectedTransactionInstructionForFullJsonParsed[];\n    }>[];\n    logMessages: readonly string[] | null;\n    postBalances: readonly Lamports[];\n    postTokenBalances?: readonly TokenBalance[];\n    preBalances: readonly Lamports[];\n    preTokenBalances?: readonly TokenBalance[];\n    returnData?: Readonly<{\n        data: Base64EncodedDataResponse;\n        programId: Address;\n    }>;\n    rewards: readonly Reward[] | null;\n    status: TransactionStatus;\n};\n\ntype ExpectedMetaForFullJsonParsedLoadedAddresses = Readonly<{\n    loadedAddresses: {\n        readonly: readonly Address[];\n        writable: readonly Address[];\n    };\n}>;\n\ntype ExpectedTransactionForFullJsonParsedBase = {\n    message: {\n        header: {\n            numReadonlySignedAccounts: number;\n            numReadonlyUnsignedAccounts: number;\n            numRequiredSignatures: number;\n        };\n        instructions: readonly ExpectedTransactionInstructionForFullJsonParsed[];\n        recentBlockhash: Blockhash;\n    };\n    signatures: readonly Base58EncodedBytes[];\n};\n\ntype ExpectedTransactionForFullJsonParsedLegacy = {\n    meta: ExpectedMetaForFullJsonParsedBase | null;\n    transaction: ExpectedTransactionForFullJsonParsedBase & {\n        message: Readonly<{\n            accountKeys: readonly Readonly<{\n                pubkey: string;\n                signer: boolean;\n                source: 'transaction';\n                writable: boolean;\n            }>[];\n        }>;\n    };\n};\n\ntype ExpectedTransactionForFullJsonParsedVersioned = {\n    meta: (ExpectedMetaForFullJsonParsedBase & ExpectedMetaForFullJsonParsedLoadedAddresses) | null;\n    transaction: ExpectedTransactionForFullJsonParsedBase & {\n        message: Readonly<{\n            accountKeys: readonly Readonly<{\n                pubkey: string;\n                signer: boolean;\n                source: 'lookupTable' | 'transaction';\n                writable: boolean;\n            }>[];\n        }>;\n    };\n    version: TransactionVersion;\n};\n\n// Seventeenth overload\n// Rewards set to `false`\n// Max supported transaction version set to 0\n// Encoding set to `jsonParsed`\n// Transaction details default to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'jsonParsed',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonParsedVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'jsonParsed',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonParsedVersioned>\n    >\n>;\n\n// Eighteenth overload\n// Rewards set to `false`\n// Max supported transaction defaults to `legacy`\n// Encoding set to `jsonParsed`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'jsonParsed',\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonParsedLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'jsonParsed',\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonParsedLegacy>\n    >\n>;\n\n// Nineteenth overload\n// Rewards defaults to `true`\n// Max supported transaction version set to 0\n// Encoding set to `jsonParsed`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'jsonParsed',\n    maxSupportedTransactionVersion: 0,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonParsedVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'jsonParsed',\n        maxSupportedTransactionVersion: 0,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonParsedVersioned>\n    >\n>;\n\n// Twentieth overload\n// Rewards defaults to `true`\n// Max supported transaction defaults to `legacy`\n// Encoding set to `jsonParsed`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'jsonParsed',\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonParsedLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'jsonParsed',\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonParsedLegacy>\n    >\n>;\n\ntype ExpectedTransactionInstructionForFullJson = {\n    accounts: readonly number[];\n    data: Base58EncodedBytes;\n    programIdIndex: number;\n};\n\ntype ExpectedMetaForFullJsonBase = {\n    computeUnitsConsumed?: bigint;\n    err: TransactionError | null;\n    fee: Lamports;\n    innerInstructions: readonly Readonly<{\n        index: number;\n        instructions: readonly ExpectedTransactionInstructionForFullJson[];\n    }>[];\n    logMessages: readonly string[] | null;\n    postBalances: readonly Lamports[];\n    postTokenBalances?: readonly TokenBalance[];\n    preBalances: readonly Lamports[];\n    preTokenBalances?: readonly TokenBalance[];\n    returnData?: Readonly<{\n        data: Base64EncodedDataResponse;\n        programId: Address;\n    }>;\n    rewards: readonly Reward[] | null;\n    status: TransactionStatus;\n};\n\ntype ExpectedMetaForFullJsonLoadedAddresses = Readonly<{\n    loadedAddresses: {\n        readonly: readonly Address[];\n        writable: readonly Address[];\n    };\n}>;\n\ntype ExpectedTransactionForFullJsonBase = {\n    message: {\n        accountKeys: readonly Address[];\n        header: {\n            numReadonlySignedAccounts: number;\n            numReadonlyUnsignedAccounts: number;\n            numRequiredSignatures: number;\n        };\n        instructions: readonly ExpectedTransactionInstructionForFullJson[];\n        recentBlockhash: Blockhash;\n    };\n    signatures: readonly Base58EncodedBytes[];\n};\n\ntype ExpectedTransactionForFullJsonLegacy = {\n    meta: ExpectedMetaForFullJsonBase | null;\n    transaction: ExpectedTransactionForFullJsonBase;\n};\n\ntype ExpectedTransactionForFullJsonVersioned = {\n    meta: (ExpectedMetaForFullJsonBase & ExpectedMetaForFullJsonLoadedAddresses) | null;\n    transaction: ExpectedTransactionForFullJsonBase;\n    version: TransactionVersion;\n};\n\n// Twenty-first overload\n// Rewards set to `false`\n// Max supported transaction version set to 0\n// Encoding defaults to `json`\n// Transaction details default to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonVersioned>\n    >\n>;\n\n// Twenty-first overload\n// Rewards set to `false`\n// Max supported transaction version set to 0\n// Encoding set to `json`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    encoding: 'json',\n    maxSupportedTransactionVersion: 0,\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonVersioned>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        encoding: 'json',\n        maxSupportedTransactionVersion: 0,\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonVersioned>\n    >\n>;\n\n// Twenty-second overload\n// Rewards set to `false`\n// Max supported transaction defaults to `legacy`\n// Encoding defaults to `json`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    showRewards: false,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        showRewards: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonLegacy>\n    >\n>;\n\n// Twenty-third overload\n// Rewards defaults to `true`\n// Max supported transaction version set to 0\n// Encoding defaults to `json`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all', {\n    // No extra configs\n    maxSupportedTransactionVersion: 0,\n}) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', {\n        // No extra configs\n        maxSupportedTransactionVersion: 0,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonLegacy>\n    >\n>;\n\n// Twenty-fourth overload\n// Rewards defaults to `true`\n// Max supported transaction defaults to `legacy`\n// Encoding defaults to `json`\n// Transaction details defaults to `full`\nrpcSubscriptions.blockNotifications('all') satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonLegacy>\n>;\nrpcSubscriptions.blockNotifications('all').subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonLegacy>\n    >\n>;\n\n// Twenty-fourth overload with configs\nrpcSubscriptions.blockNotifications('all', { commitment: 'confirmed' }) satisfies PendingRpcSubscriptionsRequest<\n    BlockNotificationsApiNotificationBase &\n        BlockNotificationsApiNotificationWithRewards &\n        BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonLegacy>\n>;\nrpcSubscriptions\n    .blockNotifications('all', { commitment: 'confirmed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        BlockNotificationsApiNotificationBase &\n            BlockNotificationsApiNotificationWithRewards &\n            BlockNotificationsApiNotificationWithTransactions<ExpectedTransactionForFullJsonLegacy>\n    >\n>;\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/logs-notifications-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type { SolanaRpcResponse, TransactionError } from '@solana/rpc-types';\n\nimport type { LogsNotificationsApi } from '../logs-notifications';\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<LogsNotificationsApi>;\n\ntype TNotification = SolanaRpcResponse<\n    Readonly<{\n        err: TransactionError | null;\n        logs: readonly string[] | null;\n        signature: Signature;\n    }>\n>;\nrpcSubscriptions.logsNotifications('all') satisfies PendingRpcSubscriptionsRequest<TNotification>;\nrpcSubscriptions.logsNotifications('all').subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<TNotification>\n>;\nrpcSubscriptions.logsNotifications('all', {\n    commitment: 'confirmed',\n}) satisfies PendingRpcSubscriptionsRequest<TNotification>;\nrpcSubscriptions\n    .logsNotifications('all', { commitment: 'confirmed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotification>>;\n\nrpcSubscriptions.logsNotifications('allWithVotes') satisfies PendingRpcSubscriptionsRequest<TNotification>;\nrpcSubscriptions\n    .logsNotifications('allWithVotes')\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotification>>;\nrpcSubscriptions.logsNotifications('allWithVotes', {\n    commitment: 'confirmed',\n}) satisfies PendingRpcSubscriptionsRequest<TNotification>;\nrpcSubscriptions\n    .logsNotifications('allWithVotes', { commitment: 'confirmed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotification>>;\n\nrpcSubscriptions.logsNotifications({\n    mentions: ['11111111111111111111111111111111' as Address],\n}) satisfies PendingRpcSubscriptionsRequest<TNotification>;\nrpcSubscriptions\n    .logsNotifications({ mentions: ['11111111111111111111111111111111' as Address] })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotification>>;\nrpcSubscriptions.logsNotifications(\n    { mentions: ['11111111111111111111111111111111' as Address] },\n    { commitment: 'confirmed' },\n) satisfies PendingRpcSubscriptionsRequest<TNotification>;\nrpcSubscriptions\n    .logsNotifications({ mentions: ['11111111111111111111111111111111' as Address] }, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotification>>;\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/program-notifications-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { Address } from '@solana/addresses';\nimport type { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type {\n    Base58EncodedBytes,\n    Base58EncodedDataResponse,\n    Base64EncodedBytes,\n    Base64EncodedDataResponse,\n    Base64EncodedZStdCompressedDataResponse,\n    Lamports,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\nimport type { ProgramNotificationsApi } from '../program-notifications';\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<ProgramNotificationsApi>;\n// See scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json\n// Note: Only using this address for type tests. It's not actually a program.\nconst programId =\n    'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G' as Address<'GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G'>;\n\ntype TNotificationBase = Readonly<{\n    account: Readonly<{\n        executable: boolean;\n        lamports: Lamports;\n        owner: Address;\n    }>;\n    pubkey: Address;\n}>;\n\n// No optional configs\nrpcSubscriptions.programNotifications(programId) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            account: {\n                data: Base58EncodedBytes;\n            };\n        }\n    >\n>;\nrpcSubscriptions\n    .programNotifications(programId)\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                account: {\n                    data: Base58EncodedBytes;\n                };\n            }\n        >\n    >\n>;\n// With optional configs\nrpcSubscriptions.programNotifications(programId, {\n    commitment: 'confirmed',\n}) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            account: {\n                data: Base58EncodedBytes;\n            };\n        }\n    >\n>;\nrpcSubscriptions\n    .programNotifications(programId, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                account: {\n                    data: Base58EncodedBytes;\n                };\n            }\n        >\n    >\n>;\n// Base58 encoded data\nrpcSubscriptions.programNotifications(programId, { encoding: 'base58' }) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            account: {\n                data: Base58EncodedDataResponse;\n            };\n        }\n    >\n>;\nrpcSubscriptions\n    .programNotifications(programId, { encoding: 'base58' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                account: {\n                    data: Base58EncodedDataResponse;\n                };\n            }\n        >\n    >\n>;\n// Base64 encoded data\nrpcSubscriptions.programNotifications(programId, { encoding: 'base64' }) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            account: {\n                data: Base64EncodedDataResponse;\n            };\n        }\n    >\n>;\nrpcSubscriptions\n    .programNotifications(programId, { encoding: 'base64' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                account: {\n                    data: Base64EncodedDataResponse;\n                };\n            }\n        >\n    >\n>;\n// Base64 + ZSTD encoded data\nrpcSubscriptions.programNotifications(programId, {\n    encoding: 'base64+zstd',\n}) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            account: {\n                data: Base64EncodedZStdCompressedDataResponse;\n            };\n        }\n    >\n>;\nrpcSubscriptions\n    .programNotifications(programId, { encoding: 'base64+zstd' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                account: {\n                    data: Base64EncodedZStdCompressedDataResponse;\n                };\n            }\n        >\n    >\n>;\n// JSON parsed data\nrpcSubscriptions.programNotifications(programId, {\n    encoding: 'jsonParsed',\n}) satisfies PendingRpcSubscriptionsRequest<\n    SolanaRpcResponse<\n        TNotificationBase & {\n            account: {\n                data:\n                    | Base64EncodedDataResponse\n                    | Readonly<{\n                          parsed: unknown;\n                          program: string;\n                          space: bigint;\n                      }>;\n            };\n        }\n    >\n>;\nrpcSubscriptions\n    .programNotifications(programId, { encoding: 'jsonParsed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<\n        SolanaRpcResponse<\n            TNotificationBase & {\n                account: {\n                    data:\n                        | Base64EncodedDataResponse\n                        | Readonly<{\n                              parsed: unknown;\n                              program: string;\n                              space: bigint;\n                          }>;\n                };\n            }\n        >\n    >\n>;\n\n// Filters\n({\n    filters: [\n        {\n            memcmp: {\n                bytes: 'bytes' as Base58EncodedBytes,\n                encoding: 'base58',\n                offset: 0n,\n            },\n        },\n    ],\n}) satisfies Parameters<RpcSubscriptions<ProgramNotificationsApi>['programNotifications']>[1];\n// Can't flop them\n({\n    filters: [\n        {\n            // @ts-expect-error Can't flop the encodings\n            memcmp: {\n                bytes: 'bytes' as Base58EncodedBytes,\n                encoding: 'base64',\n                offset: 0n,\n            },\n        },\n    ],\n}) satisfies Parameters<RpcSubscriptions<ProgramNotificationsApi>['programNotifications']>[1];\n({\n    filters: [\n        {\n            memcmp: {\n                bytes: 'bytes' as Base64EncodedBytes,\n                encoding: 'base64',\n                offset: 0n,\n            },\n        },\n    ],\n}) satisfies Parameters<RpcSubscriptions<ProgramNotificationsApi>['programNotifications']>[1];\n// Can't flop them\n({\n    filters: [\n        {\n            // @ts-expect-error Can't flop the encodings\n            memcmp: {\n                bytes: 'bytes' as Base64EncodedBytes,\n                encoding: 'base58',\n                offset: 0n,\n            },\n        },\n    ],\n}) satisfies Parameters<RpcSubscriptions<ProgramNotificationsApi>['programNotifications']>[1];\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/root-notifications-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type { Slot } from '@solana/rpc-types';\n\nimport type { RootNotificationsApi } from '../root-notifications';\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<RootNotificationsApi>;\n\ntype TNotification = Slot;\nrpcSubscriptions.rootNotifications() satisfies PendingRpcSubscriptionsRequest<TNotification>;\nrpcSubscriptions.rootNotifications().subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<TNotification>\n>;\n\n// @ts-expect-error Takes no params.\nrpcSubscriptions.rootNotifications({ commitment: 'finalized' });\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/rpc-subscriptions-api-typetest.ts",
    "content": "import { SolanaRpcSubscriptionsApi, SolanaRpcSubscriptionsApiUnstable } from '..';\n\n'accountNotifications' satisfies keyof SolanaRpcSubscriptionsApi;\n// @ts-expect-error RPC subscriptions API does not have this method\n'someMadeUpNotifications' satisfies keyof SolanaRpcSubscriptionsApi;\n\n// if we extend the RPC API with additional methods, we can access them on keyof\ntype testRpcSubscriptionsApi = SolanaRpcSubscriptionsApi & {\n    someMadeUpNotifications: () => void;\n};\n'someMadeUpNotifications' satisfies keyof testRpcSubscriptionsApi;\n\n// slots updates notifications are available on unstable API only\n'slotsUpdatesNotifications' satisfies keyof SolanaRpcSubscriptionsApiUnstable;\n// @ts-expect-error RPC subscriptions API does not have this method\n'slotsUpdatesNotifications' satisfies keyof SolanaRpcSubscriptionsApi;\n\n// vote notifications are available on unstable API only\n'voteNotifications' satisfies keyof SolanaRpcSubscriptionsApiUnstable;\n// @ts-expect-error RPC subscriptions API does not have this method\n'voteNotifications' satisfies keyof SolanaRpcSubscriptionsApi;\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/signature-notifications-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { Signature } from '@solana/keys';\nimport type { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type { SolanaRpcResponse, TransactionError } from '@solana/rpc-types';\n\nimport type { SignatureNotificationsApi } from '../signature-notifications';\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<SignatureNotificationsApi>;\n\ntype TNotificationReceived = SolanaRpcResponse<Readonly<string>>;\ntype TNotificationProcessed = SolanaRpcResponse<\n    Readonly<{\n        err: TransactionError | null;\n    }>\n>;\n\nrpcSubscriptions.signatureNotifications(\n    'xxxxx' as Signature,\n) satisfies PendingRpcSubscriptionsRequest<TNotificationProcessed>;\nrpcSubscriptions\n    .signatureNotifications('xxxxx' as Signature)\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotificationProcessed>>;\n\nrpcSubscriptions.signatureNotifications('xxxxx' as Signature, {\n    commitment: 'confirmed',\n}) satisfies PendingRpcSubscriptionsRequest<TNotificationProcessed>;\nrpcSubscriptions\n    .signatureNotifications('xxxxx' as Signature, { commitment: 'confirmed' })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotificationProcessed>>;\n\nrpcSubscriptions.signatureNotifications('xxxxx' as Signature, {\n    commitment: 'confirmed',\n    enableReceivedNotification: false,\n}) satisfies PendingRpcSubscriptionsRequest<TNotificationProcessed>;\nrpcSubscriptions\n    .signatureNotifications('xxxxx' as Signature, {\n        commitment: 'confirmed',\n        enableReceivedNotification: false,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotificationProcessed>>;\n\nrpcSubscriptions.signatureNotifications('xxxxx' as Signature, {\n    commitment: 'confirmed',\n    enableReceivedNotification: true,\n}) satisfies PendingRpcSubscriptionsRequest<TNotificationProcessed | TNotificationReceived>;\nrpcSubscriptions\n    .signatureNotifications('xxxxx' as Signature, {\n        commitment: 'confirmed',\n        enableReceivedNotification: true,\n    })\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<TNotificationProcessed | TNotificationReceived>\n>;\nrpcSubscriptions.signatureNotifications('xxxxx' as Signature, {\n    commitment: 'confirmed',\n    enableReceivedNotification: true,\n    // @ts-expect-error Should have both notification types\n}) satisfies PendingRpcSubscription<TNotificationProcessed>;\nrpcSubscriptions\n    .signatureNotifications('xxxxx' as Signature, {\n        commitment: 'confirmed',\n        enableReceivedNotification: true,\n    })\n    // @ts-expect-error Should have both notification types\n    .subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<AsyncIterable<TNotificationProcessed>>;\n\nvoid (async () => {\n    // [DESCRIBE] When `enableReceivedNotification` is true\n    {\n        // It is the literal string `'receivedSignature'` when the value is a string.\n        const notifications = await rpcSubscriptions\n            .signatureNotifications('xxxxx' as Signature, { enableReceivedNotification: true })\n            .subscribe({ abortSignal: AbortSignal.any([]) });\n        for await (const notif of notifications) {\n            if (typeof notif.value === 'string') {\n                notif.value satisfies 'receivedSignature';\n            }\n        }\n    }\n    {\n        // It is an object with a nullable error property when the value is not a string.\n        const notifications = await rpcSubscriptions\n            .signatureNotifications('xxxxx' as Signature, { enableReceivedNotification: true })\n            .subscribe({ abortSignal: AbortSignal.any([]) });\n        for await (const notif of notifications) {\n            if (typeof notif.value !== 'string') {\n                notif.value.err satisfies TransactionError | null;\n            }\n        }\n    }\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/slot-notifications-typetest.ts",
    "content": "import type { RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type { Slot } from '@solana/rpc-types';\n\nimport type { SlotNotificationsApi } from '../slot-notifications';\n\nvoid (async () => {\n    const rpcSubcriptions = null as unknown as RpcSubscriptions<SlotNotificationsApi>;\n    const slotNotifications = await rpcSubcriptions\n        .slotNotifications()\n        .subscribe({ abortSignal: new AbortController().signal });\n\n    slotNotifications satisfies AsyncIterable<\n        Readonly<{\n            parent: Slot;\n            root: Slot;\n            slot: Slot;\n        }>\n    >;\n\n    // @ts-expect-error Takes no params.\n    rpcSubscriptions.slotNotifications({ commitment: 'finalized' });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/slots-updates-notifications-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type { Slot } from '@solana/rpc-types';\n\nimport type { SlotsUpdatesNotificationsApi } from '../slots-updates-notifications';\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<SlotsUpdatesNotificationsApi>;\n\ntype TNotification = Readonly<{\n    parent?: Slot;\n    slot: Slot;\n    timestamp: bigint;\n    type: 'completed' | 'createdBank' | 'dead' | 'firstShredReceived' | 'frozen' | 'optimisticConfirmation' | 'root';\n}>;\nrpcSubscriptions.slotsUpdatesNotifications() satisfies PendingRpcSubscriptionsRequest<TNotification>;\nrpcSubscriptions.slotsUpdatesNotifications().subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<TNotification>\n>;\n\n// @ts-expect-error Takes no params.\nrpcSubscriptions.slotsUpdatesNotifications({ commitment: 'finalized' });\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/__typetests__/vote-notifications-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { PendingRpcSubscriptionsRequest, RpcSubscriptions } from '@solana/rpc-subscriptions-spec';\nimport type { Blockhash, Slot, UnixTimestamp } from '@solana/rpc-types';\n\nimport { VoteNotificationsApi } from '../vote-notifications';\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<VoteNotificationsApi>;\n\ntype VoteNotificationsApiNotification = Readonly<{\n    hash: Blockhash;\n    signature: Signature;\n    slots: readonly Slot[];\n    timestamp: UnixTimestamp | null;\n    votePubkey: Address;\n}>;\nrpcSubscriptions.voteNotifications() satisfies PendingRpcSubscriptionsRequest<VoteNotificationsApiNotification>;\nrpcSubscriptions.voteNotifications().subscribe({ abortSignal: new AbortController().signal }) satisfies Promise<\n    AsyncIterable<VoteNotificationsApiNotification>\n>;\n\n// @ts-expect-error Takes no params.\nrpcSubscriptions.voteNotifications({ commitment: 'finalized' });\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/account-notifications.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithJsonData,\n    Commitment,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype AccountNotificationsApiCommonConfig = Readonly<{\n    /**\n     * Get notified when a modification to an account has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcSubscriptionsApi} in\n     * use. For example, when using an API created by a `createSolanaRpcSubscriptions*()` helper,\n     * the default commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API\n     * layer on the client, the default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n}>;\n\nexport type AccountNotificationsApi = {\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of the\n     * account at the specified address.\n     *\n     * The notification format is the same as seen in the {@link GetAccountInfoApi.getAccountInfo}\n     * RPC HTTP method.\n     *\n     * If the account has data, it will be returned in the response as a tuple whose first element\n     * is a base64-encoded string.\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/websocket/accountsubscribe\n     */\n    accountNotifications(\n        address: Address,\n        config: AccountNotificationsApiCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ): SolanaRpcResponse<AccountInfoBase & AccountInfoWithBase64EncodedData>;\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of the\n     * account at the specified address.\n     *\n     * The notification format is the same as seen in the {@link GetAccountInfoApi.getAccountInfo}\n     * RPC HTTP method.\n     *\n     * If the account has data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/websocket/accountsubscribe\n     */\n    accountNotifications(\n        address: Address,\n        config: AccountNotificationsApiCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n            }>,\n    ): SolanaRpcResponse<AccountInfoBase & AccountInfoWithBase64EncodedZStdCompressedData>;\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of the\n     * account at the specified address.\n     *\n     * The notification format is the same as seen in the {@link GetAccountInfoApi.getAccountInfo}\n     * RPC HTTP method.\n     *\n     * If the account has data, the server will attempt to process it using a parser specific to the\n     * account's owning program. If successful, the parsed data will be returned in the response as\n     * JSON. Otherwise, the raw account data will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/websocket/accountsubscribe\n     */\n    accountNotifications(\n        address: Address,\n        config: AccountNotificationsApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ): SolanaRpcResponse<AccountInfoBase & AccountInfoWithJsonData>;\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of the\n     * account at the specified address.\n     *\n     * The notification format is the same as seen in the {@link GetAccountInfoApi.getAccountInfo}\n     * RPC HTTP method.\n     *\n     * If the account has data, it will be returned in the response as a tuple whose first element\n     * is a base58-encoded string. If the account contains more than 129 bytes of data, the `data`\n     * field will materialize as the string `\"error: data too large for bs58 encoding\"`.\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/websocket/accountsubscribe\n     */\n    accountNotifications(\n        address: Address,\n        config: AccountNotificationsApiCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ): SolanaRpcResponse<AccountInfoBase & AccountInfoWithBase58EncodedData>;\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of the\n     * account at the specified address.\n     *\n     * The notification format is the same as seen in the {@link GetAccountInfoApi.getAccountInfo}\n     * RPC HTTP method.\n     *\n     * If the account has data, it will be returned in the response as a base58-encoded string. If\n     * the account contains more than 129 bytes of data, the `data` field will materialize as the\n     * string `\"error: data too large for bs58 encoding\"`.\n     *\n     * {@label base58-legacy}\n     * @see https://solana.com/docs/rpc/websocket/accountsubscribe\n     */\n    accountNotifications(\n        address: Address,\n        config?: AccountNotificationsApiCommonConfig,\n    ): SolanaRpcResponse<AccountInfoBase & AccountInfoWithBase58Bytes>;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/block-notifications.ts",
    "content": "import { Address } from '@solana/addresses';\nimport type {\n    Base58EncodedBytes,\n    Blockhash,\n    Commitment,\n    Reward,\n    Slot,\n    SolanaRpcResponse,\n    TransactionForAccounts,\n    TransactionForFullBase58,\n    TransactionForFullBase64,\n    TransactionForFullJson,\n    TransactionForFullJsonParsed,\n    UnixTimestamp,\n} from '@solana/rpc-types';\nimport type { TransactionVersion } from '@solana/transaction-messages';\n\n// Subscription notification types\n\ntype BlockNotificationsNotificationBase = Readonly<{\n    /**\n     * Errors can arise in generating a block notification.\n     * If an error is encountered, this field will contain the error, and the `block` field will return null.\n     * @see https://github.com/anza-xyz/agave/blob/6ea51280ddc235ed93e16906c3427efd20cd7ce4/rpc/src/rpc_subscriptions.rs#L1059-L1074\n     * @see https://github.com/anza-xyz/agave/blob/6ea51280ddc235ed93e16906c3427efd20cd7ce4/rpc-client-api/src/response.rs#L507-L514\n     */\n    err: string | null;\n    slot: Slot;\n}>;\n\ntype BlockNotificationsNotificationBlock = Readonly<{\n    /** The number of blocks beneath this block */\n    blockHeight: bigint;\n    /** Estimated production time, as Unix timestamp */\n    blockTime: UnixTimestamp;\n    /** the blockhash of this block */\n    blockhash: Blockhash;\n    /** The slot index of this block's parent */\n    parentSlot: Slot;\n    /** The blockhash of this block's parent */\n    previousBlockhash: Blockhash;\n}>;\n\ntype BlockNotificationsNotificationBlockWithRewards = Readonly<{\n    /** Block-level rewards */\n    rewards: readonly Reward[];\n}>;\n\ntype BlockNotificationsNotificationBlockWithSignatures = Readonly<{\n    /** List of signatures applied to transactions in this block */\n    signatures: readonly Base58EncodedBytes[];\n}>;\n\ntype BlockNotificationsNotificationBlockWithTransactions<TTransaction> = Readonly<{\n    transactions: readonly TTransaction[];\n}>;\n\n// Subscription parameter types\n\ntype BlockNotificationsFilter =\n    | 'all'\n    | {\n          /**\n           * This filter matches when a transaction mentions the provided address. If no transaction\n           * mentions this address in a given block, then no notification will be sent for that\n           * block.\n           */\n          mentionsAccountOrProgram: Address;\n      };\n\ntype BlockNotificationsCommonConfig = Readonly<{\n    /**\n     * Get notified when a new block has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcSubscriptionsApi} in\n     * use. For example, when using an API created by a `createSolanaRpcSubscriptions*()` helper,\n     * the default commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API\n     * layer on the client, the default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Omit<Commitment, 'processed'>;\n    /**\n     * Determines how the transaction property should be encoded in the response.\n     *\n     * - `'base58'` produces a tuple whose first element is the wire transaction as a base58-encoded\n     *   string.\n     * - `'base64'` produces a tuple whose first element is the wire transaction as a base64-encoded\n     *   string.\n     * - `'json'` produces an object with `message` and `signatures` properties. The `instructions`\n     *   property of the message is an array of instructions, each an object containing the indices\n     *   of the instruction's accounts, the instruction data, the index of the program address, and\n     *   optionally the stack height if it is an inner instruction.\n     * - `'jsonParsed'` produces an object with `message` and `signatures` properties. This property\n     *   will cause the server to attempt to process each instruction using a parser specific to its\n     *   program. If successful, the parsed instruction will be returned in the response as JSON.\n     *   Otherwise, each instruction will be returned according to the rules of `'json'` encoding.\n     *\n     * @defaultValue \"json\"\n     */\n    encoding?: BlockNotificationsEncoding;\n    /**\n     * The newest transaction version that the caller wants to receive in the response. This\n     * argument has no effect unless the {@link GetBlockCommonConfig.transactionDetails | transactionDetails}\n     * argument is set to `'accounts'` or `'full'`.\n     *\n     * When not supplied, only legacy (unversioned) transactions will be returned, and no `version`\n     * property will be returned in the response.\n     *\n     * If a block contains any transaction at a version higher than this, the server will throw\n     * {@link SolanaErrorCode.SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION | SOLANA_ERROR__JSON_RPC__SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION}.\n     */\n    maxSupportedTransactionVersion?: BlockNotificationsMaxSupportedTransactionVersion;\n    /**\n     * Set this to `false` to omit block rewards from the response. These typically only\n     * materialize on the first block of an epoch.\n     * @defaultValue true\n     */\n    rewards?: boolean;\n    /**\n     * The level of transaction detail to include in the response.\n     *\n     * - `'accounts'` includes signatures, an annotated list of accounts, and some transaction\n     *   metadata.\n     * - `'full'` includes the entire transaction message and its signatures.\n     * - `'none'` excludes transaction details completely.\n     * - `'signatures'` includes transaction signatures only.\n     *\n     * @defaultValue \"full\"\n     */\n    transactionDetails?: BlockNotificationTransactionDetailsMode;\n}>;\n\ntype BlockNotificationsEncoding = 'base58' | 'base64' | 'json' | 'jsonParsed';\ntype BlockNotificationTransactionDetailsMode = 'accounts' | 'full' | 'none' | 'signatures';\n\ntype BlockNotificationsMaxSupportedTransactionVersion = Exclude<TransactionVersion, 'legacy'>;\n\nexport type BlockNotificationsApi = {\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter.\n     *\n     * {@label transactions-none--rewards-none}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=none, rewards=false, encoding + maxSupportedTransactionVersion irrelevant\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: BlockNotificationsEncoding;\n                maxSupportedTransactionVersion?: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards: false;\n                transactionDetails: 'none';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block: BlockNotificationsNotificationBlock | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter.\n     *\n     * {@label transactions-none--rewards-included}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=none, rewards=missing/true, encoding + maxSupportedTransactionVersion irrelevant\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: BlockNotificationsEncoding;\n                maxSupportedTransactionVersion?: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards?: true;\n                transactionDetails: 'none';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block: (BlockNotificationsNotificationBlock & BlockNotificationsNotificationBlockWithRewards) | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * signatures of transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-signatures--rewards-none}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=signatures, rewards=false, encoding + maxSupportedTransactionVersion irrelevant\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: BlockNotificationsEncoding;\n                maxSupportedTransactionVersion?: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards: false;\n                transactionDetails: 'signatures';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block: (BlockNotificationsNotificationBlock & BlockNotificationsNotificationBlockWithSignatures) | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * signatures of transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-signatures--rewards-included}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=signatures, rewards=missing/true, encoding + maxSupportedTransactionVersion irrelevant\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: BlockNotificationsEncoding;\n                maxSupportedTransactionVersion?: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards?: true;\n                transactionDetails: 'signatures';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithSignatures)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-accounts--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=accounts, rewards=false, maxSupportedTransactionVersion=0, encoding irrelevant\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: BlockNotificationsEncoding;\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards: false;\n                transactionDetails: 'accounts';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForAccounts<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-accounts--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=accounts, rewards=false, maxSupportedTransactionVersion=missing, encoding irrelevant\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: BlockNotificationsEncoding;\n                showRewards: false;\n                transactionDetails: 'accounts';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForAccounts<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-accounts--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=accounts, rewards=missing/true, maxSupportedTransactionVersion=0, encoding irrelevant\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: BlockNotificationsEncoding;\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards?: true;\n                transactionDetails: 'accounts';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForAccounts<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-accounts--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=accounts, rewards=missing/true, maxSupportedTransactionVersion=missing, encoding irrelevant\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: BlockNotificationsEncoding;\n                showRewards?: true;\n                transactionDetails: 'accounts';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForAccounts<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-base58--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=base58, rewards=false, maxSupportedTransactionVersion=0\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForFullBase58<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-base58--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=base58, rewards=false, maxSupportedTransactionVersion=missing\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n                showRewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForFullBase58<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-base58--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=base58, rewards=missing/true, maxSupportedTransactionVersion=0\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForFullBase58<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-base58--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=base58, rewards=missing/true, maxSupportedTransactionVersion=missing\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n                showRewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForFullBase58<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-base64--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=base64, rewards=false, maxSupportedTransactionVersion=0\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForFullBase64<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-base64--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=base64, rewards=false, maxSupportedTransactionVersion=missing\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n                showRewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForFullBase64<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-base64--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=base64, rewards=missing/true, maxSupportedTransactionVersion=0\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForFullBase64<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-base64--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=base64, rewards=missing/true, maxSupportedTransactionVersion=missing\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n                showRewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForFullBase64<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-parsed--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=jsonParsed, rewards=false, maxSupportedTransactionVersion=0\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForFullJsonParsed<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-parsed--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=jsonParsed, rewards=false, maxSupportedTransactionVersion=missing\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n                showRewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForFullJsonParsed<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-parsed--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=jsonParsed, rewards=missing/true, maxSupportedTransactionVersion=0\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForFullJsonParsed<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-parsed--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=jsonParsed, rewards=missing/true, maxSupportedTransactionVersion=missing\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n                showRewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForFullJsonParsed<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-json--rewards-none--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=json (default), rewards=false, maxSupportedTransactionVersion=0\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: 'json';\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForFullJson<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-json--rewards-none--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=json (default), rewards=false, maxSupportedTransactionVersion=missing\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: 'json';\n                showRewards: false;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForFullJson<void>>)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-json--rewards-included--version-specified}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=json (default), rewards=missing/true, maxSupportedTransactionVersion=0\n        config: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: 'json';\n                maxSupportedTransactionVersion: BlockNotificationsMaxSupportedTransactionVersion;\n                showRewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<\n                              TransactionForFullJson<BlockNotificationsMaxSupportedTransactionVersion>\n                          >)\n                    | null;\n            }>\n    >;\n    /**\n     * Subscribe to receive notifications anytime a new block reaches the specified level of\n     * commitment.\n     *\n     * The notification format is the same as seen in the {@link GetBlockApi.getBlock} RPC HTTP\n     * method.\n     *\n     * @param filter Notifications will only be produced for blocks that match this filter. Only\n     * transactions that match this filter will be included in the block.\n     *\n     * {@label transactions-json--rewards-included--version-legacy}\n     * @see https://solana.com/docs/rpc/websocket/blocksubscribe\n     */\n    blockNotifications(\n        filter: BlockNotificationsFilter,\n        // transactionDetails=full (default), encoding=json (default), rewards=missing/true, maxSupportedTransactionVersion=missing\n        config?: BlockNotificationsCommonConfig &\n            Readonly<{\n                encoding?: 'json';\n                showRewards?: true;\n                transactionDetails?: 'full';\n            }>,\n    ): SolanaRpcResponse<\n        BlockNotificationsNotificationBase &\n            Readonly<{\n                block:\n                    | (BlockNotificationsNotificationBlock &\n                          BlockNotificationsNotificationBlockWithRewards &\n                          BlockNotificationsNotificationBlockWithTransactions<TransactionForFullJson<void>>)\n                    | null;\n            }>\n    >;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/index.ts",
    "content": "import {\n    createRpcSubscriptionsApi,\n    executeRpcPubSubSubscriptionPlan,\n    RpcSubscriptionsApi,\n    RpcSubscriptionsApiMethods,\n} from '@solana/rpc-subscriptions-spec';\nimport {\n    AllowedNumericKeypaths,\n    getDefaultRequestTransformerForSolanaRpc,\n    getDefaultResponseTransformerForSolanaRpcSubscriptions,\n    jsonParsedAccountsConfigs,\n    KEYPATH_WILDCARD,\n    RequestTransformerConfig,\n} from '@solana/rpc-transformers';\n\nimport { AccountNotificationsApi } from './account-notifications';\nimport { BlockNotificationsApi } from './block-notifications';\nimport { LogsNotificationsApi } from './logs-notifications';\nimport { ProgramNotificationsApi } from './program-notifications';\nimport { RootNotificationsApi } from './root-notifications';\nimport { SignatureNotificationsApi } from './signature-notifications';\nimport { SlotNotificationsApi } from './slot-notifications';\nimport { SlotsUpdatesNotificationsApi } from './slots-updates-notifications';\nimport { VoteNotificationsApi } from './vote-notifications';\n\nexport type SolanaRpcSubscriptionsApi = AccountNotificationsApi &\n    LogsNotificationsApi &\n    ProgramNotificationsApi &\n    RootNotificationsApi &\n    SignatureNotificationsApi &\n    SlotNotificationsApi;\nexport type SolanaRpcSubscriptionsApiUnstable = BlockNotificationsApi &\n    SlotsUpdatesNotificationsApi &\n    VoteNotificationsApi;\n\nexport type {\n    AccountNotificationsApi,\n    BlockNotificationsApi,\n    LogsNotificationsApi,\n    ProgramNotificationsApi,\n    RootNotificationsApi,\n    SignatureNotificationsApi,\n    SlotNotificationsApi,\n    SlotsUpdatesNotificationsApi,\n    VoteNotificationsApi,\n};\n\ntype Config = RequestTransformerConfig;\n\nfunction createSolanaRpcSubscriptionsApi_INTERNAL<TApi extends RpcSubscriptionsApiMethods>(\n    config?: Config,\n): RpcSubscriptionsApi<TApi> {\n    const requestTransformer = getDefaultRequestTransformerForSolanaRpc(config);\n    const responseTransformer = getDefaultResponseTransformerForSolanaRpcSubscriptions({\n        allowedNumericKeyPaths: getAllowedNumericKeypaths(),\n    });\n    return createRpcSubscriptionsApi<TApi>({\n        planExecutor({ request, ...rest }) {\n            return executeRpcPubSubSubscriptionPlan({\n                ...rest,\n                responseTransformer,\n                subscribeRequest: { ...request, methodName: request.methodName.replace(/Notifications$/, 'Subscribe') },\n                unsubscribeMethodName: request.methodName.replace(/Notifications$/, 'Unsubscribe'),\n            });\n        },\n        requestTransformer,\n    });\n}\n\nexport function createSolanaRpcSubscriptionsApi<TApi extends RpcSubscriptionsApiMethods = SolanaRpcSubscriptionsApi>(\n    config?: Config,\n): RpcSubscriptionsApi<TApi> {\n    return createSolanaRpcSubscriptionsApi_INTERNAL<TApi>(config);\n}\n\nexport function createSolanaRpcSubscriptionsApi_UNSTABLE(config?: Config) {\n    return createSolanaRpcSubscriptionsApi_INTERNAL<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>(\n        config,\n    );\n}\n\nlet memoizedKeypaths: AllowedNumericKeypaths<\n    RpcSubscriptionsApi<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>\n>;\n\n/**\n * These are keypaths at the end of which you will find a numeric value that should *not* be upcast\n * to a `bigint`. These are values that are legitimately defined as `u8` or `usize` on the backend.\n */\nfunction getAllowedNumericKeypaths(): AllowedNumericKeypaths<\n    RpcSubscriptionsApi<SolanaRpcSubscriptionsApi & SolanaRpcSubscriptionsApiUnstable>\n> {\n    if (!memoizedKeypaths) {\n        memoizedKeypaths = {\n            accountNotifications: jsonParsedAccountsConfigs.map(c => ['value', ...c]),\n            blockNotifications: [\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'preTokenBalances',\n                    KEYPATH_WILDCARD,\n                    'accountIndex',\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'preTokenBalances',\n                    KEYPATH_WILDCARD,\n                    'uiTokenAmount',\n                    'decimals',\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'postTokenBalances',\n                    KEYPATH_WILDCARD,\n                    'accountIndex',\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'postTokenBalances',\n                    KEYPATH_WILDCARD,\n                    'uiTokenAmount',\n                    'decimals',\n                ],\n                ['value', 'block', 'transactions', KEYPATH_WILDCARD, 'meta', 'rewards', KEYPATH_WILDCARD, 'commission'],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'innerInstructions',\n                    KEYPATH_WILDCARD,\n                    'index',\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'innerInstructions',\n                    KEYPATH_WILDCARD,\n                    'instructions',\n                    KEYPATH_WILDCARD,\n                    'programIdIndex',\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'meta',\n                    'innerInstructions',\n                    KEYPATH_WILDCARD,\n                    'instructions',\n                    KEYPATH_WILDCARD,\n                    'accounts',\n                    KEYPATH_WILDCARD,\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'transaction',\n                    'message',\n                    'addressTableLookups',\n                    KEYPATH_WILDCARD,\n                    'writableIndexes',\n                    KEYPATH_WILDCARD,\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'transaction',\n                    'message',\n                    'addressTableLookups',\n                    KEYPATH_WILDCARD,\n                    'readonlyIndexes',\n                    KEYPATH_WILDCARD,\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'transaction',\n                    'message',\n                    'instructions',\n                    KEYPATH_WILDCARD,\n                    'programIdIndex',\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'transaction',\n                    'message',\n                    'instructions',\n                    KEYPATH_WILDCARD,\n                    'accounts',\n                    KEYPATH_WILDCARD,\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'transaction',\n                    'message',\n                    'header',\n                    'numReadonlySignedAccounts',\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'transaction',\n                    'message',\n                    'header',\n                    'numReadonlyUnsignedAccounts',\n                ],\n                [\n                    'value',\n                    'block',\n                    'transactions',\n                    KEYPATH_WILDCARD,\n                    'transaction',\n                    'message',\n                    'header',\n                    'numRequiredSignatures',\n                ],\n                ['value', 'block', 'rewards', KEYPATH_WILDCARD, 'commission'],\n            ],\n            programNotifications: jsonParsedAccountsConfigs.flatMap(c => [\n                ['value', KEYPATH_WILDCARD, 'account', ...c],\n                [KEYPATH_WILDCARD, 'account', ...c],\n            ]),\n        };\n    }\n    return memoizedKeypaths;\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/logs-notifications.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { Commitment, SolanaRpcResponse, TransactionError } from '@solana/rpc-types';\n\ntype LogsNotificationsApiNotification = SolanaRpcResponse<\n    Readonly<{\n        /** Error if transaction failed, null if transaction succeeded. */\n        err: TransactionError | null;\n        /** Array of log messages the transaction instructions output during execution. */\n        logs: readonly string[];\n        /** Transaction signature as base-58 encoded string */\n        signature: Signature;\n    }>\n>;\n\ntype LogsNotificationsApiConfig = Readonly<{\n    /**\n     * Get notified on logs from new transactions that have reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcSubscriptionsApi} in\n     * use. For example, when using an API created by a `createSolanaRpcSubscriptions*()` helper,\n     * the default commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API\n     * layer on the client, the default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n}>;\n\nexport type LogsNotificationsApi = {\n    /**\n     * Subscribe to receive notifications containing the logs of all non-vote transactions.\n     *\n     * {@label non-vote}\n     * @see https://solana.com/docs/rpc/websocket/logssubscribe\n     */\n    logsNotifications(filter: 'all', config?: LogsNotificationsApiConfig): LogsNotificationsApiNotification;\n    /**\n     * Subscribe to receive notifications containing the logs of all transactions.\n     *\n     * {@label all}\n     * @see https://solana.com/docs/rpc/websocket/logssubscribe\n     */\n    logsNotifications(filter: 'allWithVotes', config?: LogsNotificationsApiConfig): LogsNotificationsApiNotification;\n    /**\n     * Subscribe to receive notifications containing the logs of transactions that mention the\n     * supplied program or account.\n\n    * {@label all-that-mention}\n     * @see https://solana.com/docs/rpc/websocket/logssubscribe\n     */\n    logsNotifications(\n        filter: {\n            /**\n             * This filter matches when a transaction mentions the single address provided.\n             *\n             * This filter currently only supports one address per method call. Listing additional\n             * addresses will result in an error.\n             */\n            mentions: [Address];\n        },\n        config?: LogsNotificationsApiConfig,\n    ): LogsNotificationsApiNotification;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/program-notifications.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type {\n    AccountInfoBase,\n    AccountInfoWithBase58Bytes,\n    AccountInfoWithBase58EncodedData,\n    AccountInfoWithBase64EncodedData,\n    AccountInfoWithBase64EncodedZStdCompressedData,\n    AccountInfoWithJsonData,\n    AccountInfoWithPubkey,\n    Commitment,\n    GetProgramAccountsDatasizeFilter,\n    GetProgramAccountsMemcmpFilter,\n    SolanaRpcResponse,\n} from '@solana/rpc-types';\n\ntype ProgramNotificationsApiNotificationBase<TData> = SolanaRpcResponse<AccountInfoWithPubkey<AccountInfoBase & TData>>;\n\ntype ProgramNotificationsApiCommonConfig = Readonly<{\n    /**\n     * Get notified when a modification to an account has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcSubscriptionsApi} in\n     * use. For example, when using an API created by a `createSolanaRpcSubscriptions*()` helper,\n     * the default commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API\n     * layer on the client, the default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Limits results to those that match all of these filters.\n     *\n     * This is useful when your aim is to find program accounts whose purpose is uniquely determined\n     * by having a data buffer of a known size, or whose data contains a known series of bytes (eg.\n     * a discriminator).\n     *\n     * You can specify up to 4 filters.\n     *\n     * @defaultValue When omitted, no filters are applied.\n     */\n    filters?: readonly Readonly<GetProgramAccountsDatasizeFilter | GetProgramAccountsMemcmpFilter>[];\n}>;\n\nexport type ProgramNotificationsApi = {\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of any\n     * account owned by the program at the given address changes.\n     *\n     * The notification format is the same as seen in the\n     * {@link GetProgramAccountsApi.getProgramAccounts} RPC HTTP method.\n     *\n     * If the account has data, it will be returned in the response as a tuple whose first element\n     * is a base64-encoded string.\n     *\n     * {@label base64}\n     * @see https://solana.com/docs/rpc/websocket/programsubscribe\n     */\n    programNotifications(\n        programId: Address,\n        config: ProgramNotificationsApiCommonConfig &\n            Readonly<{\n                encoding: 'base64';\n            }>,\n    ): ProgramNotificationsApiNotificationBase<AccountInfoWithBase64EncodedData>;\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of any\n     * account owned by the program at the given address changes.\n     *\n     * The notification format is the same as seen in the\n     * {@link GetProgramAccountsApi.getProgramAccounts} RPC HTTP method.\n     *\n     * If the account has data, it will first be compressed using\n     * [ZStandard](https://facebook.github.io/zstd/) and the result will be returned in the response\n     * as a tuple whose first element is a base64-encoded string.\n     *\n     * {@label base64-zstd-compressed}\n     * @see https://solana.com/docs/rpc/websocket/programsubscribe\n     */\n    programNotifications(\n        programId: Address,\n        config: ProgramNotificationsApiCommonConfig &\n            Readonly<{\n                encoding: 'base64+zstd';\n            }>,\n    ): ProgramNotificationsApiNotificationBase<AccountInfoWithBase64EncodedZStdCompressedData>;\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of any\n     * account owned by the program at the given address changes.\n     *\n     * The notification format is the same as seen in the\n     * {@link GetProgramAccountsApi.getProgramAccounts} RPC HTTP method.\n     *\n     * If the account has data, the server will attempt to process it using a parser specific to the\n     * account's owning program. If successful, the parsed data will be returned in the response as\n     * JSON. Otherwise, the raw account data will be returned in the response as a tuple whose first\n     * element is a base64-encoded string.\n     *\n     * {@label parsed}\n     * @see https://solana.com/docs/rpc/websocket/programsubscribe\n     */\n    programNotifications(\n        programId: Address,\n        config: ProgramNotificationsApiCommonConfig &\n            Readonly<{\n                encoding: 'jsonParsed';\n            }>,\n    ): ProgramNotificationsApiNotificationBase<AccountInfoWithJsonData>;\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of any\n     * account owned by the program at the given address changes.\n     *\n     * The notification format is the same as seen in the\n     * {@link GetProgramAccountsApi.getProgramAccounts} RPC HTTP method.\n     *\n     * If the account has data, it will be returned in the response as a tuple whose first element\n     * is a base58-encoded string. If the account contains more than 129 bytes of data, the `data`\n     * field will materialize as the string `\"error: data too large for bs58 encoding\"`.\n     *\n     * {@label base58}\n     * @see https://solana.com/docs/rpc/websocket/programsubscribe\n     */\n    programNotifications(\n        programId: Address,\n        config: ProgramNotificationsApiCommonConfig &\n            Readonly<{\n                encoding: 'base58';\n            }>,\n    ): ProgramNotificationsApiNotificationBase<AccountInfoWithBase58EncodedData>;\n    /**\n     * Subscribe for notifications when there is a change in the {@link Lamports} or data of any\n     * account owned by the program at the given address changes.\n     *\n     * The notification format is the same as seen in the\n     * {@link GetProgramAccountsApi.getProgramAccounts} RPC HTTP method.\n     *\n     * If the account has data, it will be returned in the response as a base58-encoded string. If\n     * the account contains more than 129 bytes of data, the `data` field will materialize as the\n     * string `\"error: data too large for bs58 encoding\"`.\n     *\n     * {@label base58-legacy}\n     * @see https://solana.com/docs/rpc/websocket/programsubscribe\n     */\n    programNotifications(\n        programId: Address,\n        config?: ProgramNotificationsApiCommonConfig,\n    ): ProgramNotificationsApiNotificationBase<AccountInfoWithBase58Bytes>;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/root-notifications.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype RootNotificationsApiNotification = Slot;\n\nexport type RootNotificationsApi = {\n    /**\n     * Subscribe to receive notifications anytime a new root is set by the validator.\n     *\n     * @returns The number of the rooted slot\n     * @see https://solana.com/docs/rpc/websocket/rootsubscribe\n     */\n    rootNotifications(): RootNotificationsApiNotification;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/signature-notifications.ts",
    "content": "import type { Signature } from '@solana/keys';\nimport type { Commitment, SolanaRpcResponse, TransactionError } from '@solana/rpc-types';\n\ntype SignatureNotificationsApiNotificationReceived = SolanaRpcResponse<Readonly<'receivedSignature'>>;\n\ntype SignatureNotificationsApiNotificationProcessed = SolanaRpcResponse<\n    Readonly<{\n        /** Error if transaction failed, null if transaction succeeded. */\n        err: TransactionError | null;\n    }>\n>;\n\ntype SignatureNotificationsApiConfigBase = Readonly<{\n    /**\n     * Get notified when the transaction with the specified signature has reached this level of\n     * commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcSubscriptionsApi} in\n     * use. For example, when using an API created by a `createSolanaRpcSubscriptions*()` helper,\n     * the default commitment is `\"confirmed\"` unless configured otherwise. Unmitigated by an API\n     * layer on the client, the default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /**\n     * Whether or not to subscribe for notifications when signatures are received by the RPC, in\n     * addition to when they are processed.\n     *\n     * @defaultValue false\n     */\n    enableReceivedNotification?: boolean;\n}>;\n\nexport type SignatureNotificationsApi = {\n    /**\n     * Subscribe to a receive a notification when the transaction identified by the given signature\n     * is received by the cluster, then again when it reaches the specified level of commitment.\n     *\n     * This subscription will not issue notifications for events that have already happened. To\n     * fetch the commitment status of any transaction at a point in time use the\n     * {@link GetSignatureStatusesApi.getSignatureStatuses | getSignatureStatuses} method of the RPC\n     * API.\n     *\n     * @param signature Transaction signature as base-58 encoded string\n     *\n     * @see https://solana.com/docs/rpc/websocket/signaturesubscribe\n     */\n    signatureNotifications(\n        signature: Signature,\n        config: Readonly<{\n            enableReceivedNotification: true;\n        }> &\n            SignatureNotificationsApiConfigBase,\n    ): SignatureNotificationsApiNotificationProcessed | SignatureNotificationsApiNotificationReceived;\n    /**\n     * Subscribe to a receive a notification when the transaction identified by the given signature\n     * reaches the specified level of commitment.\n     *\n     * This subscription will not issue notifications for events that have already happened. To\n     * fetch the commitment status of any transaction at a point in time use the\n     * {@link GetSignatureStatusesApi.getSignatureStatuses | getSignatureStatuses} method of the RPC\n     * API.\n     *\n     * @param signature Transaction signature as base-58 encoded string\n     *\n     * @see https://solana.com/docs/rpc/websocket/signaturesubscribe\n     */\n    signatureNotifications(\n        signature: Signature,\n        config?: Readonly<{\n            enableReceivedNotification?: false;\n        }> &\n            SignatureNotificationsApiConfigBase,\n    ): SignatureNotificationsApiNotificationProcessed;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/slot-notifications.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype SlotNotificationsApiNotification = Readonly<{\n    /** The parent slot */\n    parent: Slot;\n    /** The current root slot */\n    root: Slot;\n    /** The newly set slot value */\n    slot: Slot;\n}>;\n\nexport type SlotNotificationsApi = {\n    /**\n     * Subscribe to receive notifications anytime a slot is processed by the validator.\n     *\n     * @see https://solana.com/docs/rpc/websocket/slotsubscribe\n     */\n    slotNotifications(): SlotNotificationsApiNotification;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/slots-updates-notifications.ts",
    "content": "import type { Slot } from '@solana/rpc-types';\n\ntype SlotsUpdatesNotificationsApiNotificationBase = Readonly<{\n    /** The newly updated slot */\n    slot: Slot;\n    /** The Unix timestamp of the update in milliseconds */\n    timestamp: bigint;\n    type: 'completed' | 'firstShredReceived' | 'optimisticConfirmation' | 'root';\n}>;\n\ntype SlotsUpdatesNotificationsApiNotificationCreatedBank = Readonly<{\n    /** The parent slot */\n    parent: Slot;\n    type: 'createdBank';\n}> &\n    SlotsUpdatesNotificationsApiNotificationBase;\n\ntype SlotsUpdatesNotificationsApiNotificationDead = Readonly<{\n    err: string;\n    type: 'dead';\n}> &\n    SlotsUpdatesNotificationsApiNotificationBase;\n\ntype SlotsUpdatesNotificationsApiNotificationFrozen = Readonly<{\n    stats: Readonly<{\n        maxTransactionsPerEntry: bigint;\n        numFailedTransactions: bigint;\n        numSuccessfulTransactions: bigint;\n        numTransactionEntries: bigint;\n    }>;\n    type: 'frozen';\n}> &\n    SlotsUpdatesNotificationsApiNotificationBase;\n\ntype SlotsUpdatesNotificationsApiNotification =\n    | SlotsUpdatesNotificationsApiNotificationBase\n    | SlotsUpdatesNotificationsApiNotificationCreatedBank\n    | SlotsUpdatesNotificationsApiNotificationDead\n    | SlotsUpdatesNotificationsApiNotificationFrozen;\n\nexport type SlotsUpdatesNotificationsApi = {\n    /**\n     * Subscribe to receive a notification from the validator on a variety of updates on every slot.\n     *\n     * This subscription is unstable. The format of this subscription may change in the future, and\n     * may not be supported by every node.\n     *\n     * @see https://solana.com/docs/rpc/websocket/slotsupdatessubscribe\n     */\n    slotsUpdatesNotifications(): SlotsUpdatesNotificationsApiNotification;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/src/vote-notifications.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { Signature } from '@solana/keys';\nimport type { Blockhash, Slot, UnixTimestamp } from '@solana/rpc-types';\n\ntype VoteNotificationsApiNotification = Readonly<{\n    /** The vote hash */\n    hash: Blockhash;\n    /** The signature of the transaction that contained this vote */\n    signature: Signature;\n    /** The slots covered by the vote */\n    slots: readonly Slot[];\n    /** The timestamp of the vote */\n    timestamp: UnixTimestamp | null;\n    /** The address of the vote account */\n    votePubkey: Address;\n}>;\n\nexport type VoteNotificationsApi = {\n    /**\n     * Subscribe to receive notifications anytime a new vote is observed in gossip.\n     *\n     * These votes are pre-consensus therefore there is no guarantee these votes will enter the\n     * ledger.\n     *\n     * This subscription is unstable and only available if the validator was started with the\n     * `--rpc-pubsub-enable-vote-subscription` flag. The format of this subscription may change in\n     * the future.\n     *\n     * @see https://solana.com/docs/rpc/websocket/votesubscribe\n     */\n    voteNotifications(): VoteNotificationsApiNotification;\n};\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-subscriptions-api\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-api/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/CHANGELOG.md",
    "content": "# @solana/rpc-subscriptions-channel-websocket\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/functional@6.9.0\n    - @solana/rpc-subscriptions-spec@6.9.0\n    - @solana/subscribable@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`f53ce07`](https://github.com/anza-xyz/kit/commit/f53ce0796c782e79490e1cf11a55e28fb62b8c8f), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n    - @solana/functional@6.8.0\n    - @solana/rpc-subscriptions-spec@6.8.0\n    - @solana/subscribable@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n    - @solana/functional@6.7.0\n    - @solana/rpc-subscriptions-spec@6.7.0\n    - @solana/subscribable@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/rpc-subscriptions-spec@6.6.0\n    - @solana/subscribable@6.6.0\n    - @solana/functional@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n    - @solana/functional@6.5.0\n    - @solana/rpc-subscriptions-spec@6.5.0\n    - @solana/subscribable@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.4.0\n    - @solana/functional@6.4.0\n    - @solana/rpc-subscriptions-spec@6.4.0\n    - @solana/subscribable@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n    - @solana/functional@6.3.1\n    - @solana/rpc-subscriptions-spec@6.3.1\n    - @solana/subscribable@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/rpc-subscriptions-spec@6.3.0\n    - @solana/subscribable@6.3.0\n    - @solana/functional@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/rpc-subscriptions-spec@6.2.0\n    - @solana/subscribable@6.2.0\n    - @solana/functional@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/rpc-subscriptions-spec@6.1.0\n    - @solana/subscribable@6.1.0\n    - @solana/functional@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.1\n    - @solana/functional@6.0.1\n    - @solana/rpc-subscriptions-spec@6.0.1\n    - @solana/subscribable@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.0\n    - @solana/functional@6.0.0\n    - @solana/rpc-subscriptions-spec@6.0.0\n    - @solana/subscribable@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/rpc-subscriptions-spec@5.5.1\n    - @solana/subscribable@5.5.1\n    - @solana/functional@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/rpc-subscriptions-spec@5.5.0\n    - @solana/subscribable@5.5.0\n    - @solana/functional@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/rpc-subscriptions-spec@5.4.0\n    - @solana/subscribable@5.4.0\n    - @solana/functional@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n    - @solana/functional@5.3.0\n    - @solana/rpc-subscriptions-spec@5.3.0\n    - @solana/subscribable@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- [#1163](https://github.com/anza-xyz/kit/pull/1163) [`7d5a57c`](https://github.com/anza-xyz/kit/commit/7d5a57c209140fd7cd4721a2dc9a4ab10b8ac907) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Node users no longer need to manually install `ws`. Browser builds remain unaffected as conditional exports ensure `ws` is never bundled for browser environments.\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n    - @solana/rpc-subscriptions-spec@5.2.0\n    - @solana/subscribable@5.2.0\n    - @solana/functional@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n    - @solana/rpc-subscriptions-spec@5.1.0\n    - @solana/subscribable@5.1.0\n    - @solana/functional@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/rpc-subscriptions-spec@5.0.0\n    - @solana/subscribable@5.0.0\n    - @solana/functional@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-subscriptions-spec@4.0.0\n    - @solana/subscribable@4.0.0\n    - @solana/functional@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f)]:\n    - @solana/errors@3.0.0\n    - @solana/rpc-subscriptions-spec@3.0.0\n    - @solana/subscribable@3.0.0\n    - @solana/functional@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/rpc-subscriptions-spec@2.3.0\n    - @solana/subscribable@2.3.0\n    - @solana/functional@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies [[`e881fca`](https://github.com/anza-xyz/kit/commit/e881fca9ea0154d0eeaec682697042f86502b86d)]:\n    - @solana/rpc-subscriptions-spec@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/functional@2.2.1\n    - @solana/subscribable@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.0\n    - @solana/functional@2.2.0\n    - @solana/rpc-subscriptions-spec@2.2.0\n    - @solana/subscribable@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-subscriptions-spec@2.1.1\n    - @solana/subscribable@2.1.1\n    - @solana/functional@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065) Thanks [@steveluscher](https://github.com/steveluscher)! - Disabled the `MaxListenersExceededWarning` in Node when creating event targets for internal use\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n    - @solana/subscribable@2.1.0\n    - @solana/rpc-subscriptions-spec@2.1.0\n    - @solana/functional@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc) Thanks [@steveluscher](https://github.com/steveluscher)! - We refactored the lower levels of the subscriptions API entirely.\n\n    Previously, all layers of the subscriptions implementation, from the `WebSocket` transport to the API that developers use, dealt in `AsyncIterables`. These are notoriously difficult to code in such a way that expresses all of the ways in which a subscription might be cancelled or error out. Very slight omissions of care could open memory leaks that would bring down the simplest of apps. The new subscriptions infra in Release Candidate 2 deals with event-based subscriptions all the way up to the highest level API, at which point the subscription is vended to the application as an `AsyncIterable`.\n\n    This has eliminated several classes of memory leak and has made it easier to implement higher-level transports (like the autopinger and the subscription coalescer). Additionally, this update introduces a new channel pool implementation that opens new `WebSocket` connections when existing ones become ‘full.’ Lastly, performance in the new implementation has been improved through a new demultiplexing utility that can separate `message` events into several channels based on arbitrary criteria, meaning you can apply transforms to the message right at the source, and vend subscriptions to downstream consumers that care only about one particular kind of message.\n\n- Updated dependencies [[`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677), [`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`17c373d`](https://github.com/solana-labs/solana-web3.js/commit/17c373dec6dd167ea5b4e37e213067aa05fa4e14), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`8c2cb9f`](https://github.com/solana-labs/solana-web3.js/commit/8c2cb9f44a52b3c27bc15c2c972bea1aae1622e7), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`92655fd`](https://github.com/solana-labs/solana-web3.js/commit/92655fda6631339f07c6cd7097ed9e2518f86853), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc)]:\n    - @solana/rpc-subscriptions-spec@2.0.0\n    - @solana/errors@2.0.0\n    - @solana/subscribable@2.0.0\n    - @solana/functional@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.4\n    - @solana/subscribable@2.0.0-rc.4\n    - @solana/functional@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/functional@2.0.0-rc.3\n    - @solana/subscribable@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc) Thanks [@steveluscher](https://github.com/steveluscher)! - We refactored the lower levels of the subscriptions API entirely.\n\n    Previously, all layers of the subscriptions implementation, from the `WebSocket` transport to the API that developers use, dealt in `AsyncIterables`. These are notoriously difficult to code in such a way that expresses all of the ways in which a subscription might be cancelled or error out. Very slight omissions of care could open memory leaks that would bring down the simplest of apps. The new subscriptions infra in Release Candidate 2 deals with event-based subscriptions all the way up to the highest level API, at which point the subscription is vended to the application as an `AsyncIterable`.\n\n    This has eliminated several classes of memory leak and has made it easier to implement higher-level transports (like the autopinger and the subscription coalescer). Additionally, this update introduces a new channel pool implementation that opens new `WebSocket` connections when existing ones become ‘full.’ Lastly, performance in the new implementation has been improved through a new demultiplexing utility that can separate `message` events into several channels based on arbitrary criteria, meaning you can apply transforms to the message right at the source, and vend subscriptions to downstream consumers that care only about one particular kind of message.\n\n- Updated dependencies [[`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`17c373d`](https://github.com/solana-labs/solana-web3.js/commit/17c373dec6dd167ea5b4e37e213067aa05fa4e14), [`8c2cb9f`](https://github.com/solana-labs/solana-web3.js/commit/8c2cb9f44a52b3c27bc15c2c972bea1aae1622e7), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`92655fd`](https://github.com/solana-labs/solana-web3.js/commit/92655fda6631339f07c6cd7097ed9e2518f86853), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc)]:\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.2\n    - @solana/subscribable@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/functional@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.1\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-subscriptions-channel-websocket?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-subscriptions-channel-websocket?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-subscriptions-channel-websocket\n\n# @solana/rpc-subscriptions-channel-websocket\n\nThis package allows developers to create custom RPC Subscriptions channels. Using these primitives, developers can create custom channels that perform transforms on messages sent and received, perform autopings, and implement custom channel pooling strategies.\n\n## Functions\n\n### `createWebSocketChannel()`\n\nCreates an object that represents an open channel to a `WebSocket` server.\n\nYou can use it to send messages by calling its `send()` function and you can receive them by subscribing to the `RpcSubscriptionChannelEvents` it emits.\n\n```ts\nimport { createWebSocketChannel } from '@solana/rpc-subscriptions-channel-websocket';\n\nconst abortController = new AbortController();\nconst webSocketChannel = await createWebSocketChannel({\n    sendBufferHighWatermark: Number.POSITIVE_INFINITY,\n    signal: abortController.signal,\n    url: 'wss://api.mainnet-beta.solana.com',\n});\nconst channel = {\n    ...webSocketChannel,\n    on(type, listener, options) {\n        if (type !== 'message') {\n            return webSocketChannel.on(type, listener, options);\n        }\n        return webSocketChannel.on(\n            'message',\n            function deserializingListener(message: string) {\n                const deserializedMessage = JSON.parse(message);\n                listener(deserializedMessage);\n            },\n            options,\n        );\n    },\n    send(message) {\n        const serializedMessage = JSON.stringify(message);\n        return webSocketChannel.send(serializedMessage);\n    },\n} as RpcSubscriptionsChannel<unknown, unknown>;\nchannel.on(\n    'error',\n    e => {\n        console.log('Received error', e);\n        abortController.abort();\n    },\n    { signal: abortController.signal },\n);\nchannel.on(\n    'message',\n    m => {\n        console.log('Received message', m);\n        abortController.abort();\n    },\n    { signal: abortController.signal },\n);\nawait channel.send({ id: 1, jsonrpc: '2.0', method: 'getSlot' });\n```\n\n#### Config\n\n##### `sendBufferHighWatermark`\n\nThe number of bytes to admit into the WebSocket's send buffer before queueing messages on the client.\n\nWhen you call `send()` on a `WebSocket` the runtime might add the message to a buffer rather than send it right away. In the event that `socket.bufferedAmount` exceeds the value configured here, messages will be added to a queue in your application code instead of being sent to the WebSocket, until such time as the `bufferedAmount` falls back below the high watermark.\n\n##### `signal`\n\nAn `AbortSignal` to fire when you want to explicitly close the `WebSocket`.\n\nIf the channel is open it will be closed with the code `1000`, representing a normal closure. If the channel has not been established yet, firing this signal will result in the `AbortError` being thrown to the caller who was trying to open the channel.\n\n##### `url`\n\nA string representing the target endpoint. In Node, it must be an absolute URL using the `ws` or `wss` protocol.\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-subscriptions-channel-websocket\",\n    \"version\": \"6.9.0\",\n    \"description\": \"An RPC Subscriptions transport that uses WebSockets\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-subscriptions-channel-websocket\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/functional\": \"workspace:*\",\n        \"@solana/rpc-subscriptions-spec\": \"workspace:*\",\n        \"@solana/subscribable\": \"workspace:*\",\n        \"ws\": \"^8.19.0\"\n    },\n    \"devDependencies\": {\n        \"@solana/event-target-impl\": \"workspace:*\",\n        \"@solana/ws-impl\": \"workspace:*\",\n        \"jest-websocket-mock\": \"^2.5.0\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/src/__mocks__/@solana/ws-impl.ts",
    "content": "export { WebSocket as default } from 'mock-socket';\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/src/__tests__/websocket-channel-test.ts",
    "content": "import {\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n    SolanaError,\n} from '@solana/errors';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport WS from 'jest-websocket-mock';\nimport { Client } from 'mock-socket';\n\nimport { createWebSocketChannel } from '../websocket-channel';\n\nconst MOCK_SEND_BUFFER_HIGH_WATERMARK = 42069;\n\ndescribe('createWebSocketChannel', () => {\n    let ws: WS;\n    function getLatestClient() {\n        const clients = ws.server.clients();\n        return clients[clients.length - 1];\n    }\n    beforeEach(() => {\n        ws = new WS('wss://fake', {\n            jsonProtocol: false,\n        });\n    });\n    afterEach(() => {\n        WS.clean();\n    });\n    it('does not resolve until the socket is open', async () => {\n        expect.assertions(2);\n        const channelPromise = createWebSocketChannel({\n            sendBufferHighWatermark: 0,\n            signal: new AbortController().signal,\n            url: 'wss://fake',\n        });\n        const client = getLatestClient();\n        expect(client).toHaveProperty('readyState', WebSocket.CONNECTING);\n        await channelPromise;\n        expect(client).toHaveProperty('readyState', WebSocket.OPEN);\n    });\n    it('throws when the socket fails to connect', async () => {\n        expect.assertions(1);\n        const channelPromise = createWebSocketChannel({\n            sendBufferHighWatermark: 0,\n            signal: new AbortController().signal,\n            url: 'ws://fake', // Wrong URL!\n        });\n        await expect(channelPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n                errorEvent: {} as Event,\n            }),\n        );\n    });\n    it('throws if the signal is already aborted', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        abortController.abort();\n        const channelPromise = createWebSocketChannel({\n            sendBufferHighWatermark: 0,\n            signal: abortController.signal,\n            url: 'ws://fake', // Wrong URL!\n        });\n        await expect(channelPromise).rejects.toThrow(/operation was aborted/);\n    });\n    it('throws when the channel is aborted before a connection is established', async () => {\n        expect.assertions(2);\n        const abortController = new AbortController();\n        const channelPromise = createWebSocketChannel({\n            sendBufferHighWatermark: 0,\n            signal: abortController.signal,\n            url: 'wss://fake',\n        });\n        const client = getLatestClient();\n        expect(client).toHaveProperty('readyState', WebSocket.CONNECTING);\n        abortController.abort();\n        await expect(channelPromise).rejects.toThrow(/operation was aborted/);\n    });\n});\n\ndescribe('a websocket channel', () => {\n    let abortController: AbortController;\n    let channelPromise: Promise<RpcSubscriptionsChannel<ArrayBufferLike | ArrayBufferView | Blob | string, string>>;\n    let ws: WS;\n    function getLatestClient() {\n        const clients = ws.server.clients();\n        return clients[clients.length - 1];\n    }\n    beforeEach(() => {\n        abortController = new AbortController();\n        ws = new WS('wss://fake', {\n            jsonProtocol: false,\n        });\n        channelPromise = createWebSocketChannel({\n            sendBufferHighWatermark: MOCK_SEND_BUFFER_HIGH_WATERMARK,\n            signal: abortController.signal,\n            url: 'wss://fake',\n        });\n    });\n    afterEach(() => {\n        WS.clean();\n    });\n    describe('given an open connection', () => {\n        let channel: RpcSubscriptionsChannel<ArrayBufferLike | ArrayBufferView | Blob | string, string>;\n        beforeEach(async () => {\n            channel = await channelPromise;\n        });\n        it('publishes messages to message listeners', () => {\n            const messageListenerA = jest.fn();\n            const messageListenerB = jest.fn();\n            channel.on('message', messageListenerB);\n            channel.on('message', messageListenerA);\n            const expectedMessage = 'message';\n            ws.send(expectedMessage);\n            expect(messageListenerA).toHaveBeenCalledWith(expectedMessage);\n            expect(messageListenerB).toHaveBeenCalledWith(expectedMessage);\n        });\n        it('does not publish messages received between the time the channel is aborted and the time the connection closes', () => {\n            const messageListener = jest.fn();\n            channel.on('message', messageListener);\n            abortController.abort();\n            expect(getLatestClient()).toHaveProperty('readyState', WebSocket.CLOSING);\n            ws.send('message');\n            expect(messageListener).not.toHaveBeenCalled();\n        });\n        it('publishes errors to error listeners when the connection closes in an unclean manner', () => {\n            const errorListener = jest.fn();\n            channel.on('error', errorListener);\n            const closeOptions = {\n                code: 1006 /* abnormal closure */,\n                reason: 'o no',\n                wasClean: false,\n            };\n            ws.close(closeOptions);\n            expect(errorListener).toHaveBeenCalledWith(\n                new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n                    cause: expect.objectContaining(closeOptions),\n                }),\n            );\n            expect(errorListener.mock.lastCall[0].cause).toMatchObject(closeOptions);\n        });\n        it('publishes errors to error listeners when the connection closes cleanly with a non-1000 code', () => {\n            const errorListener = jest.fn();\n            channel.on('error', errorListener);\n            const closeOptions = {\n                code: 1011 /* internal error */,\n                reason: 'o no',\n                wasClean: true,\n            };\n            ws.server.close(closeOptions);\n            expect(errorListener).toHaveBeenCalledWith(\n                new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n                    cause: expect.objectContaining(closeOptions),\n                }),\n            );\n            expect(errorListener.mock.lastCall[0].cause).toMatchObject(closeOptions);\n        });\n        it('does not publish errors to error listeners when the connection closes cleanly with a 1000 code', () => {\n            const errorListener = jest.fn();\n            channel.on('error', errorListener);\n            const errorDetails = {\n                code: 1000 /* normal closure */,\n                reason: 'I enjoyed our little chat',\n                wasClean: true,\n            };\n            ws.error(errorDetails);\n            expect(errorListener).not.toHaveBeenCalled();\n        });\n        it('does not publish errors received between the time the channel is aborted and the time it closes', () => {\n            const errorListener = jest.fn();\n            channel.on('error', errorListener);\n            abortController.abort();\n            expect(getLatestClient()).toHaveProperty('readyState', WebSocket.CLOSING);\n            ws.error({\n                code: 666,\n                reason: 'o no',\n                wasClean: false,\n            });\n            expect(errorListener).not.toHaveBeenCalled();\n        });\n        it('sends a message to the websocket', async () => {\n            expect.assertions(1);\n            channel.send('message').catch(() => {});\n            await expect(ws).toReceiveMessage('message');\n        });\n        it('throws when sending a message to a closing channel', async () => {\n            expect.assertions(2);\n            const client = getLatestClient();\n            abortController.abort();\n            expect(client).toHaveProperty('readyState', WebSocket.CLOSING);\n            await expect(channel.send('message')).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED),\n            );\n        });\n        it('throws when sending a message to a closed channel', async () => {\n            expect.assertions(2);\n            const client = getLatestClient();\n            abortController.abort();\n            await ws.closed;\n            expect(client).toHaveProperty('readyState', WebSocket.CLOSED);\n            await expect(channel.send('message')).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED),\n            );\n        });\n        describe('given the send buffer is filled past the high watermark', () => {\n            let client: Client;\n            let oldBufferedAmount: number;\n            beforeEach(async () => {\n                client = await ws.connected;\n                oldBufferedAmount = client.bufferedAmount;\n                // eslint-disable-next-line @typescript-eslint/no-explicit-any\n                (client as any).bufferedAmount = MOCK_SEND_BUFFER_HIGH_WATERMARK + 1;\n            });\n            afterEach(() => {\n                // eslint-disable-next-line @typescript-eslint/no-explicit-any\n                (client as any).bufferedAmount = oldBufferedAmount;\n            });\n            it('queues messages until the buffer falls to the high watermark', async () => {\n                expect.assertions(2);\n                let resolved = false;\n                channel\n                    .send('message')\n                    .then(() => {\n                        resolved = true;\n                    })\n                    .catch(() => {});\n                await Promise.resolve(); // Flush Promise queue.\n                expect(resolved).toBe(false);\n                // eslint-disable-next-line @typescript-eslint/no-explicit-any\n                (client as any).bufferedAmount = MOCK_SEND_BUFFER_HIGH_WATERMARK;\n                await expect(ws).toReceiveMessage('message');\n            });\n            it('protects against modification of `ArrayBufferView` messages while queued', async () => {\n                expect.assertions(1);\n                const message = new Uint8Array(1) satisfies ArrayBufferView;\n                message[0] = 42;\n                channel.send(message).catch(() => {});\n                message[0] = 255; // Some modification\n                // eslint-disable-next-line @typescript-eslint/no-explicit-any\n                (client as any).bufferedAmount = MOCK_SEND_BUFFER_HIGH_WATERMARK;\n                await expect(ws).toReceiveMessage(new Uint8Array([42]));\n            });\n            it('fatals when the channel is closed while a message is queued', async () => {\n                expect.assertions(1);\n                const sendPromise = channel.send('message');\n                abortController.abort();\n                await expect(sendPromise).rejects.toThrow(\n                    new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED),\n                );\n            });\n            it('fatals when the channel encounters an error while a message is queued', async () => {\n                expect.assertions(1);\n                const sendPromise = channel.send('message');\n                ws.error({\n                    code: 1006 /* abnormal closure */,\n                    reason: 'o no',\n                    wasClean: false,\n                });\n                await expect(sendPromise).rejects.toThrow(\n                    new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED),\n                );\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/src/__typetests__/websocket-channel-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\n\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\n\nimport { createWebSocketChannel } from '../websocket-channel';\n\nconst config = {\n    sendBufferHighWatermark: 0,\n    signal: AbortSignal.any([]),\n    url: 'ws://localhost:8899',\n};\n\n// [DESCRIBE] createWebSocketChannel\n{\n    // It creates a channel that takes in a `WebSocketMessage` and produces a stream of `string`\n    {\n        createWebSocketChannel(config) satisfies Promise<\n            RpcSubscriptionsChannel<ArrayBufferLike | ArrayBufferView | Blob | string, string>\n        >;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/src/index.ts",
    "content": "/**\n * This package allows developers to create custom RPC Subscriptions channels. Using these\n * primitives, developers can create custom channels that perform transforms on messages sent and\n * received, perform autopings, and implement custom channel pooling strategies.\n *\n * @packageDocumentation\n */\nexport * from './websocket-channel';\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/src/websocket-channel.ts",
    "content": "import {\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n    SolanaError,\n} from '@solana/errors';\nimport { EventTarget } from '@solana/event-target-impl';\nimport { RpcSubscriptionsChannel } from '@solana/rpc-subscriptions-spec';\nimport { getDataPublisherFromEventEmitter } from '@solana/subscribable';\nimport WebSocket from '@solana/ws-impl';\n\nexport type Config = Readonly<{\n    /**\n     * The number of bytes to admit into the WebSocket's send buffer before queueing messages on the\n     * client.\n     *\n     * When you call {@link RpcSubscriptionsChannel.send | `send()`} on a `WebSocket` the runtime\n     * might add the message to a buffer rather than send it right away. In the event that\n     * `socket.bufferedAmount` exceeds the value configured here, messages will be added to a queue\n     * in your application code instead of being sent to the WebSocket, until such time as the\n     * `bufferedAmount` falls back below the high watermark.\n     */\n    sendBufferHighWatermark: number;\n    /**\n     * An `AbortSignal` to fire when you want to explicitly close the `WebSocket`.\n     *\n     * If the channel is open it will be closed with a normal closure code\n     * (https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1) If the channel has not been\n     * established yet, firing this signal will result in the `AbortError` being thrown to the\n     * caller who was trying to open the channel.\n     */\n    signal: AbortSignal;\n    /**\n     * A string representing the target endpoint.\n     *\n     * In Node, it must be an absolute URL using the `ws` or `wss` protocol.\n     */\n    url: string;\n}>;\n\ntype WebSocketMessage = ArrayBufferLike | ArrayBufferView | Blob | string;\n\nconst NORMAL_CLOSURE_CODE = 1000; // https://www.rfc-editor.org/rfc/rfc6455.html#section-7.4.1\n\n/**\n * Creates an object that represents an open channel to a `WebSocket` server.\n *\n * You can use it to send messages by calling its\n * {@link RpcSubscriptionsChannel.send | `send()`} function and you can receive them by subscribing\n * to the {@link RpcSubscriptionChannelEvents} it emits.\n */\nexport function createWebSocketChannel({\n    sendBufferHighWatermark,\n    signal,\n    url,\n}: Config): Promise<RpcSubscriptionsChannel<WebSocketMessage, string>> {\n    if (signal.aborted) {\n        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n        return Promise.reject(signal.reason);\n    }\n    let bufferDrainWatcher: Readonly<{ onCancel(): void; promise: Promise<void> }> | undefined;\n    let hasConnected = false;\n    const listenerRemovers = new Set<() => void>();\n    function cleanupListeners() {\n        listenerRemovers.forEach(r => {\n            r();\n        });\n        listenerRemovers.clear();\n    }\n    function handleAbort() {\n        cleanupListeners();\n        if (!hasConnected) {\n            rejectOpen(signal.reason);\n        }\n        if (webSocket.readyState !== WebSocket.CLOSED && webSocket.readyState !== WebSocket.CLOSING) {\n            webSocket.close(NORMAL_CLOSURE_CODE);\n        }\n    }\n    function handleClose(ev: CloseEvent) {\n        cleanupListeners();\n        bufferDrainWatcher?.onCancel();\n        signal.removeEventListener('abort', handleAbort);\n        webSocket.removeEventListener('close', handleClose);\n        webSocket.removeEventListener('error', handleError);\n        webSocket.removeEventListener('message', handleMessage);\n        webSocket.removeEventListener('open', handleOpen);\n        if (!signal.aborted && !(ev.wasClean && ev.code === NORMAL_CLOSURE_CODE)) {\n            eventTarget.dispatchEvent(\n                new CustomEvent('error', {\n                    detail: new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED, {\n                        cause: ev,\n                    }),\n                }),\n            );\n        }\n    }\n    function handleError(ev: Event) {\n        if (signal.aborted) {\n            return;\n        }\n        if (!hasConnected) {\n            const failedToConnectError = new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT, {\n                errorEvent: ev,\n            });\n            rejectOpen(failedToConnectError);\n            eventTarget.dispatchEvent(\n                new CustomEvent('error', {\n                    detail: failedToConnectError,\n                }),\n            );\n        }\n    }\n    function handleMessage(ev: MessageEvent) {\n        if (signal.aborted) {\n            return;\n        }\n        eventTarget.dispatchEvent(new CustomEvent('message', { detail: ev.data }));\n    }\n    const eventTarget = new EventTarget();\n    const dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n    function handleOpen() {\n        hasConnected = true;\n        resolveOpen({\n            ...dataPublisher,\n            async send(message) {\n                if (webSocket.readyState !== WebSocket.OPEN) {\n                    throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED);\n                }\n                if (!bufferDrainWatcher && webSocket.bufferedAmount > sendBufferHighWatermark) {\n                    let onCancel!: () => void;\n                    const promise = new Promise<void>((resolve, reject) => {\n                        const intervalId = setInterval(() => {\n                            if (\n                                webSocket.readyState !== WebSocket.OPEN ||\n                                !(webSocket.bufferedAmount > sendBufferHighWatermark)\n                            ) {\n                                clearInterval(intervalId);\n                                bufferDrainWatcher = undefined;\n                                resolve();\n                            }\n                        }, 16);\n                        onCancel = () => {\n                            bufferDrainWatcher = undefined;\n                            clearInterval(intervalId);\n                            reject(\n                                new SolanaError(\n                                    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n                                ),\n                            );\n                        };\n                    });\n                    bufferDrainWatcher = {\n                        onCancel,\n                        promise,\n                    };\n                }\n                if (bufferDrainWatcher) {\n                    if (ArrayBuffer.isView(message) && !(message instanceof DataView)) {\n                        const TypedArrayConstructor = message.constructor as {\n                            new (...args: [typeof message]): typeof message;\n                        };\n                        // Clone the message to prevent mutation while queued.\n                        message = new TypedArrayConstructor(message);\n                    }\n                    await bufferDrainWatcher.promise;\n                }\n                webSocket.send(message);\n            },\n        });\n    }\n    const webSocket = new WebSocket(url);\n    signal.addEventListener('abort', handleAbort);\n    webSocket.addEventListener('close', handleClose);\n    webSocket.addEventListener('error', handleError);\n    webSocket.addEventListener('message', handleMessage);\n    webSocket.addEventListener('open', handleOpen);\n    let rejectOpen!: (e: SolanaError) => void;\n    let resolveOpen!: (value: RpcSubscriptionsChannel<WebSocketMessage, string>) => void;\n    return new Promise<RpcSubscriptionsChannel<WebSocketMessage, string>>((resolve, reject) => {\n        rejectOpen = reject;\n        resolveOpen = resolve;\n    });\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-subscriptions-channel-websocket\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-channel-websocket/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/CHANGELOG.md",
    "content": "# @solana/rpc-subscriptions-spec\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`8d73de5`](https://github.com/anza-xyz/kit/commit/8d73de5241d709946431f2fdda74f2a0df5e9529), [`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/promises@6.9.0\n    - @solana/errors@6.9.0\n    - @solana/rpc-spec-types@6.9.0\n    - @solana/subscribable@6.9.0\n\n## 6.8.0\n\n### Minor Changes\n\n- [#1524](https://github.com/anza-xyz/kit/pull/1524) [`f53ce07`](https://github.com/anza-xyz/kit/commit/f53ce0796c782e79490e1cf11a55e28fb62b8c8f) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `ReactiveStore` type and `createReactiveStoreFromDataPublisher()` to `@solana/subscribable`, and a `reactive()` method to pending subscriptions in `@solana/rpc-subscriptions-spec` that returns a reactive store compatible with `useSyncExternalStore`, Svelte stores, and other reactive primitives.\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`f53ce07`](https://github.com/anza-xyz/kit/commit/f53ce0796c782e79490e1cf11a55e28fb62b8c8f), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n    - @solana/promises@6.8.0\n    - @solana/rpc-spec-types@6.8.0\n    - @solana/subscribable@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n    - @solana/promises@6.7.0\n    - @solana/rpc-spec-types@6.7.0\n    - @solana/subscribable@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/subscribable@6.6.0\n    - @solana/promises@6.6.0\n    - @solana/rpc-spec-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n    - @solana/promises@6.5.0\n    - @solana/rpc-spec-types@6.5.0\n    - @solana/subscribable@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.4.0\n    - @solana/promises@6.4.0\n    - @solana/rpc-spec-types@6.4.0\n    - @solana/subscribable@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n    - @solana/promises@6.3.1\n    - @solana/rpc-spec-types@6.3.1\n    - @solana/subscribable@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/subscribable@6.3.0\n    - @solana/promises@6.3.0\n    - @solana/rpc-spec-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/subscribable@6.2.0\n    - @solana/promises@6.2.0\n    - @solana/rpc-spec-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/subscribable@6.1.0\n    - @solana/promises@6.1.0\n    - @solana/rpc-spec-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.1\n    - @solana/promises@6.0.1\n    - @solana/rpc-spec-types@6.0.1\n    - @solana/subscribable@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.0\n    - @solana/promises@6.0.0\n    - @solana/rpc-spec-types@6.0.0\n    - @solana/subscribable@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/subscribable@5.5.1\n    - @solana/promises@5.5.1\n    - @solana/rpc-spec-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/subscribable@5.5.0\n    - @solana/promises@5.5.0\n    - @solana/rpc-spec-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/rpc-spec-types@5.4.0\n    - @solana/subscribable@5.4.0\n    - @solana/promises@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n    - @solana/promises@5.3.0\n    - @solana/rpc-spec-types@5.3.0\n    - @solana/subscribable@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n    - @solana/subscribable@5.2.0\n    - @solana/promises@5.2.0\n    - @solana/rpc-spec-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n    - @solana/subscribable@5.1.0\n    - @solana/promises@5.1.0\n    - @solana/rpc-spec-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/subscribable@5.0.0\n    - @solana/promises@5.0.0\n    - @solana/rpc-spec-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/subscribable@4.0.0\n    - @solana/promises@4.0.0\n    - @solana/rpc-spec-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`81c83b1`](https://github.com/anza-xyz/kit/commit/81c83b12dd0e145bf7d08182e01824f2f14e5ee5)]:\n    - @solana/errors@3.0.0\n    - @solana/rpc-spec-types@3.0.0\n    - @solana/subscribable@3.0.0\n    - @solana/promises@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- [#508](https://github.com/anza-xyz/kit/pull/508) [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677) Thanks [@calintje](https://github.com/calintje)! - Fix RPC objects incorrectly appearing as thenable Promises which caused silent program termination when awaited.\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/subscribable@2.3.0\n    - @solana/promises@2.3.0\n    - @solana/rpc-spec-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- [#633](https://github.com/anza-xyz/kit/pull/633) [`e881fca`](https://github.com/anza-xyz/kit/commit/e881fca9ea0154d0eeaec682697042f86502b86d) Thanks [@github-actions](https://github.com/apps/github-actions)! - Repaired a bug that could cause subscriptions to become 'stuck' and fail to send their unsubscribe message to the RPC, despite the last consumer in your app having released the subscription by calling `AbortController#abort()`\n\n- Updated dependencies []:\n    - @solana/errors@2.2.1\n    - @solana/promises@2.2.1\n    - @solana/rpc-spec-types@2.2.1\n    - @solana/subscribable@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.0\n    - @solana/promises@2.2.0\n    - @solana/rpc-spec-types@2.2.0\n    - @solana/subscribable@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-spec-types@2.1.1\n    - @solana/subscribable@2.1.1\n    - @solana/promises@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065) Thanks [@steveluscher](https://github.com/steveluscher)! - Disabled the `MaxListenersExceededWarning` in Node when creating event targets for internal use\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n    - @solana/subscribable@2.1.0\n    - @solana/promises@2.1.0\n    - @solana/rpc-spec-types@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3218](https://github.com/solana-labs/solana-web3.js/pull/3218) [`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcSubscriptionsApi: no longer extend RpcApiSubscriptionsMethods\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3145](https://github.com/solana-labs/solana-web3.js/pull/3145) [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type\n\n- [#3449](https://github.com/solana-labs/solana-web3.js/pull/3449) [`17c373d`](https://github.com/solana-labs/solana-web3.js/commit/17c373dec6dd167ea5b4e37e213067aa05fa4e14) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `transformChannelInboundMessages` and `transformChannelOutboundMessages` helper functions to transform incoming and outgoing messages on a given channel.\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3406](https://github.com/solana-labs/solana-web3.js/pull/3406) [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Replace subscriptionConfigurationHash with RpcRequest in RpcSubscriptionPlan\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3433](https://github.com/solana-labs/solana-web3.js/pull/3433) [`92655fd`](https://github.com/solana-labs/solana-web3.js/commit/92655fda6631339f07c6cd7097ed9e2518f86853) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `executeSubscriptionPlan` to `execute` in `RpcSubscriptionsPlan`\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3394](https://github.com/solana-labs/solana-web3.js/pull/3394) [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use RpcRequest in createRpcMessage helper\n\n- [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc) Thanks [@steveluscher](https://github.com/steveluscher)! - We refactored the lower levels of the subscriptions API entirely.\n\n    Previously, all layers of the subscriptions implementation, from the `WebSocket` transport to the API that developers use, dealt in `AsyncIterables`. These are notoriously difficult to code in such a way that expresses all of the ways in which a subscription might be cancelled or error out. Very slight omissions of care could open memory leaks that would bring down the simplest of apps. The new subscriptions infra in Release Candidate 2 deals with event-based subscriptions all the way up to the highest level API, at which point the subscription is vended to the application as an `AsyncIterable`.\n\n    This has eliminated several classes of memory leak and has made it easier to implement higher-level transports (like the autopinger and the subscription coalescer). Additionally, this update introduces a new channel pool implementation that opens new `WebSocket` connections when existing ones become ‘full.’ Lastly, performance in the new implementation has been improved through a new demultiplexing utility that can separate `message` events into several channels based on arbitrary criteria, meaning you can apply transforms to the message right at the source, and vend subscriptions to downstream consumers that care only about one particular kind of message.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`8c2cb9f`](https://github.com/solana-labs/solana-web3.js/commit/8c2cb9f44a52b3c27bc15c2c972bea1aae1622e7), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/errors@2.0.0\n    - @solana/rpc-spec-types@2.0.0\n    - @solana/subscribable@2.0.0\n    - @solana/promises@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/subscribable@2.0.0-rc.4\n    - @solana/promises@2.0.0-rc.4\n    - @solana/rpc-spec-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-spec-types@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/promises@2.0.0-rc.3\n    - @solana/subscribable@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3218](https://github.com/solana-labs/solana-web3.js/pull/3218) [`1d87b3c`](https://github.com/solana-labs/solana-web3.js/commit/1d87b3c9fb5637cdceb31c5675e876d8fe088677) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Clean up SolanaRpcSubscriptionsApi: no longer extend RpcApiSubscriptionsMethods\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3145](https://github.com/solana-labs/solana-web3.js/pull/3145) [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `RpcResponse` type to `RpcResponseData` to make room for a new `RpcResponse` type\n\n- [#3449](https://github.com/solana-labs/solana-web3.js/pull/3449) [`17c373d`](https://github.com/solana-labs/solana-web3.js/commit/17c373dec6dd167ea5b4e37e213067aa05fa4e14) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `transformChannelInboundMessages` and `transformChannelOutboundMessages` helper functions to transform incoming and outgoing messages on a given channel.\n\n- [#3406](https://github.com/solana-labs/solana-web3.js/pull/3406) [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Replace subscriptionConfigurationHash with RpcRequest in RpcSubscriptionPlan\n\n- [#3433](https://github.com/solana-labs/solana-web3.js/pull/3433) [`92655fd`](https://github.com/solana-labs/solana-web3.js/commit/92655fda6631339f07c6cd7097ed9e2518f86853) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `executeSubscriptionPlan` to `execute` in `RpcSubscriptionsPlan`\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3394](https://github.com/solana-labs/solana-web3.js/pull/3394) [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use RpcRequest in createRpcMessage helper\n\n- [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc) Thanks [@steveluscher](https://github.com/steveluscher)! - We refactored the lower levels of the subscriptions API entirely.\n\n    Previously, all layers of the subscriptions implementation, from the `WebSocket` transport to the API that developers use, dealt in `AsyncIterables`. These are notoriously difficult to code in such a way that expresses all of the ways in which a subscription might be cancelled or error out. Very slight omissions of care could open memory leaks that would bring down the simplest of apps. The new subscriptions infra in Release Candidate 2 deals with event-based subscriptions all the way up to the highest level API, at which point the subscription is vended to the application as an `AsyncIterable`.\n\n    This has eliminated several classes of memory leak and has made it easier to implement higher-level transports (like the autopinger and the subscription coalescer). Additionally, this update introduces a new channel pool implementation that opens new `WebSocket` connections when existing ones become ‘full.’ Lastly, performance in the new implementation has been improved through a new demultiplexing utility that can separate `message` events into several channels based on arbitrary criteria, meaning you can apply transforms to the message right at the source, and vend subscriptions to downstream consumers that care only about one particular kind of message.\n\n- Updated dependencies [[`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`8c2cb9f`](https://github.com/solana-labs/solana-web3.js/commit/8c2cb9f44a52b3c27bc15c2c972bea1aae1622e7), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/rpc-spec-types@2.0.0-rc.2\n    - @solana/subscribable@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/promises@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.1\n    - @solana/rpc-spec-types@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/rpc-spec-types@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-spec-types@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/rpc-spec-types@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n    - @solana/rpc-spec-types@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-subscriptions-spec?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-subscriptions-spec?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-subscriptions-spec\n\n# @solana/rpc-subscriptions-spec\n\nThis package contains types that describe the implementation of the JSON RPC Subscriptions API, as well as methods to create one. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nThis API is designed to be used as follows:\n\n```ts\nconst rpcSubscriptions =\n    // Step 1 - Create a `RpcSubscriptions` instance. This may be stateful.\n    createSolanaRpcSubscriptions(mainnet('wss://api.mainnet-beta.solana.com'));\nconst response = await rpcSubscriptions\n    // Step 2 - Call supported methods on it to produce `PendingRpcSubscriptionsRequest` objects.\n    .slotNotifications({ commitment: 'confirmed' })\n    // Step 3 - Call the `subscribe()` method on those pending requests to trigger them.\n    .subscribe({ abortSignal: AbortSignal.timeout(10_000) });\n// Step 4 - Iterate over the result.\ntry {\n    for await (const slotNotification of slotNotifications) {\n        console.log('Got a slot notification', slotNotification);\n    }\n} catch (e) {\n    console.error('The subscription closed unexpectedly', e);\n} finally {\n    console.log('We have stopped listening for notifications');\n}\n```\n\n## Types\n\n### `RpcSubscriptionsChannel<TOutboundMessage, TInboundMessage>`\n\nA channel is a `DataPublisher` on which you can subscribe to events of type `RpcSubscriptionChannelEvents<TInboundMessage>`. Additionally, you can use this object to send messages of type `TOutboundMessage` back to the remote end by calling its `send(message)` method.\n\n### `RpcSubscriptionsChannelCreator<TOutboundMessage, TInboundMessage>`\n\nA channel creator is a function that accepts an `AbortSignal`, returns a new `RpcSubscriptionsChannel`, and tears down the channel when the abort signal fires.\n\n### `RpcSubscriptionChannelEvents<TInboundMessage>`\n\nSubscription channels publish events on two channel names:\n\n- `error`: Fires when the channel closes unexpectedly\n- `message`: Fires on every message received from the remote end\n\n## Functions\n\n### `executeRpcPubSubSubscriptionPlan({ channel, responseTransformer, signal, subscribeRequest, unsubscribeMethodName })`\n\nGiven a channel, this function executes the particular subscription plan required by the Solana JSON RPC Subscriptions API.\n\n1. Calls the `subscribeRequest` on the remote RPC\n2. Waits for a response containing the subscription id\n3. Returns a `DataPublisher` that publishes notifications related to that subscriptions id, filtering out all others\n4. Calls the `unsubscribeMethodName` on the remote RPC when the abort signal is fired.\n\n### `transformChannelInboundMessages(channel, transform)`\n\nGiven a channel with inbound messages of type `T` and a function of type `T => U`, returns a new channel with inbound messages of type `U`. Note that this only affects messages of type `\"message\"` and thus, does not affect incoming error messages.\n\nFor instance, it can be used to parse incoming JSON messages:\n\n```ts\nconst transformedChannel = transformChannelInboundMessages(channel, JSON.parse);\n```\n\n### `transformChannelOutboundMessages(channel, transform)`\n\nGiven a channel with outbound messages of type `T` and a function of type `U => T`, returns a new channel with outbound messages of type `U`.\n\nFor instance, it can be used to stringify JSON messages before sending them over the wire:\n\n```ts\nconst transformedChannel = transformChannelOutboundMessages(channel, JSON.stringify);\n```\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-subscriptions-spec\",\n    \"version\": \"6.9.0\",\n    \"description\": \"A generic implementation of JSON RPC Subscriptions using proxies\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-subscriptions-spec\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/promises\": \"workspace:*\",\n        \"@solana/rpc-spec-types\": \"workspace:*\",\n        \"@solana/subscribable\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/event-target-impl\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/__tests__/rpc-subscriptions-api-test.ts",
    "content": "import { createRpcSubscriptionsApi, RpcSubscriptionsPlan } from '../rpc-subscriptions-api';\nimport { RpcSubscriptionsChannel } from '../rpc-subscriptions-channel';\n\ndescribe('createRpcSubscriptionsApi', () => {\n    let mockChannel: RpcSubscriptionsChannel<unknown, unknown>;\n    beforeEach(() => {\n        mockChannel = { on: jest.fn(), send: jest.fn() };\n    });\n    describe('execute', () => {\n        it('calls the plan executor with the expected params', () => {\n            const mockPlanExecutor = jest.fn().mockResolvedValue({\n                execute: jest.fn(),\n                request: { methodName: 'foo', params: [] },\n            } as RpcSubscriptionsPlan<unknown>);\n            const api = createRpcSubscriptionsApi({ planExecutor: mockPlanExecutor });\n            const expectedParams = [1, 'hi', 3];\n            const expectedSignal = new AbortController().signal;\n            api.foo(...expectedParams)\n                .execute({\n                    channel: mockChannel,\n                    signal: expectedSignal,\n                })\n                .catch(() => {});\n            expect(mockPlanExecutor).toHaveBeenCalledWith({\n                channel: mockChannel,\n                request: { methodName: 'foo', params: expectedParams },\n                signal: expectedSignal,\n            });\n        });\n    });\n    describe('rpcRequest', () => {\n        it('provides the initial request object by default', () => {\n            const api = createRpcSubscriptionsApi({ planExecutor: jest.fn() });\n            const result = api.foo('hi');\n            expect(result.request).toEqual({ methodName: 'foo', params: ['hi'] });\n        });\n        it('provides the transformed request object when a request transformer is provided', () => {\n            const api = createRpcSubscriptionsApi({\n                planExecutor: jest.fn(),\n                requestTransformer: jest.fn().mockReturnValue({ methodName: 'bar', params: [1, 2, 3] }),\n            });\n            const result = api.foo('hi');\n            expect(result.request).toEqual({ methodName: 'bar', params: [1, 2, 3] });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/__tests__/rpc-subscriptions-channel-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    RpcSubscriptionsChannel,\n    transformChannelInboundMessages,\n    transformChannelOutboundMessages,\n} from '../rpc-subscriptions-channel';\n\ntype Irrelevant = { readonly brand: unique symbol };\n\nfunction createMockChannel<TOutboundMessage, TInboundMessage>(): RpcSubscriptionsChannel<\n    TOutboundMessage,\n    TInboundMessage\n> {\n    return {\n        on: jest.fn().mockReturnValue(() => {}),\n        send: jest.fn().mockResolvedValue(void 0),\n    };\n}\n\nfunction getMockReceive<TOutboundMessage, TInboundMessage>(\n    mockChannel: RpcSubscriptionsChannel<TOutboundMessage, TInboundMessage>,\n) {\n    return (type: 'error' | 'message', value: unknown) => {\n        (mockChannel.on as jest.Mock).mock.calls\n            .filter(([t]) => t === type)\n            .forEach(([_, subscriber]) => subscriber(value));\n    };\n}\n\ndescribe('transformChannelInboundMessages', () => {\n    it('transforms the incoming messages of a channel', () => {\n        // Given a mock channel receiving strings.\n        const mockChannel = createMockChannel<Irrelevant, string>();\n        const mockReceive = getMockReceive(mockChannel);\n\n        // When we transform incoming string messages to their length.\n        const channel = transformChannelInboundMessages(mockChannel, (message: string) => message.length);\n        channel satisfies RpcSubscriptionsChannel<Irrelevant, number>;\n\n        // Then the transformed channel should receive the length of the incoming messages.\n        const listener = jest.fn();\n        channel.on('message', listener);\n        mockReceive('message', 'Hello World!');\n        expect(listener).toHaveBeenCalledWith(12);\n    });\n\n    it('can be used to parse JSON messages', () => {\n        // Given a mock channel receiving JSON strings.\n        const mockChannel = createMockChannel<Irrelevant, string>();\n        const mockReceive = getMockReceive(mockChannel);\n\n        // When we transform incoming JSON strings to their parsed values.\n        const channel = transformChannelInboundMessages(mockChannel, JSON.parse);\n        channel satisfies RpcSubscriptionsChannel<Irrelevant, unknown>;\n\n        // Then the transformed channel should receive JSON parsed values of incoming messages.\n        const listener = jest.fn();\n        channel.on('message', listener);\n        mockReceive('message', '{\"hello\": \"world\"}');\n        expect(listener).toHaveBeenCalledWith({ hello: 'world' });\n    });\n\n    it('does not affect error messages', () => {\n        // Given a mock channel receiving strings.\n        const mockChannel = createMockChannel<Irrelevant, string>();\n        const mockReceive = getMockReceive(mockChannel);\n\n        // When we transform incoming string messages to their length.\n        const channel = transformChannelInboundMessages(mockChannel, (message: string) => message.length);\n        channel satisfies RpcSubscriptionsChannel<Irrelevant, number>;\n\n        // Then error messages are not affected by the transformation.\n        const listener = jest.fn();\n        channel.on('error', listener);\n        mockReceive('error', 'Hello Errors!');\n        expect(listener).toHaveBeenCalledWith('Hello Errors!');\n    });\n\n    it('returns a frozen channel', () => {\n        // Given a mock channel receiving strings.\n        const mockChannel = createMockChannel<Irrelevant, string>();\n\n        // When we transform incoming string messages to their length.\n        const channel = transformChannelInboundMessages(mockChannel, (message: string) => message.length);\n\n        // Then we expect the transformed channel to be a frozen object.\n        expect(channel).toBeFrozenObject();\n    });\n});\n\ndescribe('transformChannelOutboundMessages', () => {\n    it('transforms the outgoing messages of a channel', async () => {\n        expect.assertions(1);\n\n        // Given a mock channel receiving numbers.\n        const mockChannel = createMockChannel<number, Irrelevant>();\n\n        // When we transform outgoing string messages to their length.\n        const channel = transformChannelOutboundMessages(mockChannel, (message: string) => message.length);\n        channel satisfies RpcSubscriptionsChannel<string, Irrelevant>;\n\n        // Then the transformed channel should send the length of the outgoing messages.\n        await channel.send('Hello World!');\n        expect(mockChannel.send).toHaveBeenCalledWith(12);\n    });\n\n    it('can be used to stringify JSON messages', async () => {\n        expect.assertions(1);\n\n        // Given a mock channel sending JSON strings.\n        const mockChannel = createMockChannel<string, Irrelevant>();\n\n        // When we transform outgoing JSON messages to their stringified values.\n        const channel = transformChannelOutboundMessages(mockChannel, JSON.stringify);\n        channel satisfies RpcSubscriptionsChannel<unknown, Irrelevant>;\n\n        // Then the transformed channel should send JSON stringified values of outgoing messages.\n        await channel.send({ hello: 'world' });\n        expect(mockChannel.send).toHaveBeenCalledWith('{\"hello\":\"world\"}');\n    });\n\n    it('returns a frozen channel', () => {\n        // Given a mock channel.\n        const mockChannel = createMockChannel<number, Irrelevant>();\n\n        // When we get a new channel that transforms outgoing messages.\n        const channel = transformChannelOutboundMessages(mockChannel, (message: string) => message.length);\n\n        // Then we expect the transformed channel to be a frozen object.\n        expect(channel).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/__tests__/rpc-subscriptions-pubsub-plan-test.ts",
    "content": "import {\n    SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__EXPECTED_SERVER_SUBSCRIPTION_ID,\n    SolanaError,\n} from '@solana/errors';\nimport { DataPublisher } from '@solana/subscribable';\n\nimport { RpcSubscriptionChannelEvents, RpcSubscriptionsChannel } from '../rpc-subscriptions-channel';\nimport { executeRpcPubSubSubscriptionPlan } from '../rpc-subscriptions-pubsub-plan';\n\nlet mockId = 0;\nlet lastMessageId: number;\njest.mock('@solana/rpc-spec-types', () => ({\n    ...jest.requireActual('@solana/rpc-spec-types'),\n    createRpcMessage(...args: never[]) {\n        lastMessageId = mockId++;\n        return {\n            ...jest.requireActual('@solana/rpc-spec-types').createRpcMessage(...args),\n            id: lastMessageId,\n        };\n    },\n}));\n\ndescribe('executeRpcPubSubSubscriptionPlan', () => {\n    let abortController: AbortController;\n    let mockChannel: { on: jest.Mock; send: unknown };\n    let mockSend: jest.Mock;\n    function receiveError(err?: unknown) {\n        mockChannel.on.mock.calls.filter(([type]) => type === 'error').forEach(([_, listener]) => listener(err));\n    }\n    function receiveMessage(message: unknown) {\n        mockChannel.on.mock.calls.filter(([type]) => type === 'message').forEach(([_, listener]) => listener(message));\n    }\n    beforeEach(() => {\n        abortController = new AbortController();\n        mockSend = jest.fn().mockResolvedValue(void 0);\n        mockChannel = {\n            on: jest.fn().mockReturnValue(() => {}),\n            send: mockSend,\n        };\n    });\n    it('rejects when already aborted', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        abortController.abort();\n        const publisherPromise = executeRpcPubSubSubscriptionPlan({\n            channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n            signal: abortController.signal,\n            subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n            unsubscribeMethodName: 'thingUnsubscribe',\n        });\n        await expect(publisherPromise).rejects.toThrow();\n    });\n    it('subscribes to the channel for errors', () => {\n        executeRpcPubSubSubscriptionPlan({\n            channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n            signal: abortController.signal,\n            subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n            unsubscribeMethodName: 'thingUnsubscribe',\n        }).catch(() => {});\n        expect(mockChannel.on).toHaveBeenCalledWith('error', expect.any(Function), {\n            signal: abortController.signal,\n        });\n    });\n    it('sends the expected subscribe message', () => {\n        const expectedParams = [1, 2, 3];\n        executeRpcPubSubSubscriptionPlan({\n            channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n            signal: abortController.signal,\n            subscribeRequest: { methodName: 'thingSubscribe', params: expectedParams },\n            unsubscribeMethodName: 'thingUnsubscribe',\n        }).catch(() => {});\n        expect(mockSend).toHaveBeenCalledWith(\n            expect.objectContaining({\n                id: expect.any(Number),\n                jsonrpc: '2.0',\n                method: 'thingSubscribe',\n                params: expectedParams,\n            }),\n        );\n    });\n    describe('given that the subscribe message fails to send', () => {\n        beforeEach(() => {\n            mockSend.mockRejectedValue('o no');\n        });\n        it(\"rejects with the send method's rejection\", async () => {\n            expect.assertions(1);\n            const publisherPromise = executeRpcPubSubSubscriptionPlan({\n                channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n                signal: abortController.signal,\n                subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n                unsubscribeMethodName: 'thingUnsubscribe',\n            });\n            await expect(publisherPromise).rejects.toBe('o no');\n        });\n        it('does not send an unsubscribe message when aborted', () => {\n            expect.assertions(1);\n            mockSend.mockClear();\n            abortController.abort();\n            expect(mockSend).not.toHaveBeenCalled();\n        });\n    });\n    describe('given that the server has not yet acknowledged the subscription', () => {\n        let publisherPromise: ReturnType<typeof executeRpcPubSubSubscriptionPlan>;\n        beforeEach(() => {\n            publisherPromise = executeRpcPubSubSubscriptionPlan({\n                channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n                signal: abortController.signal,\n                subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n                unsubscribeMethodName: 'thingUnsubscribe',\n            });\n        });\n        afterEach(() => {\n            publisherPromise.catch(() => {});\n        });\n        it('rejects when aborted', async () => {\n            expect.assertions(1);\n            abortController.abort();\n            await expect(publisherPromise).rejects.toThrow();\n        });\n        it('does not send an unsubscribe message when aborted', () => {\n            expect.assertions(1);\n            mockSend.mockClear();\n            abortController.abort();\n            expect(mockSend).not.toHaveBeenCalled();\n        });\n    });\n    it(\"throws when the server's subscription acknowledgement does not contain a subscription id number\", async () => {\n        expect.assertions(1);\n        const publisherPromise = executeRpcPubSubSubscriptionPlan({\n            channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n            signal: abortController.signal,\n            subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n            unsubscribeMethodName: 'thingUnsubscribe',\n        });\n        await Promise.resolve();\n        receiveMessage({ id: lastMessageId, jsonrpc: '2.0', result: undefined });\n        await expect(publisherPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__EXPECTED_SERVER_SUBSCRIPTION_ID),\n        );\n    });\n    describe('given that the server has already acknowledged the subscription', () => {\n        let expectedSubscriptionId: number;\n        let publisherPromise: Promise<\n            DataPublisher<Omit<RpcSubscriptionChannelEvents<unknown>, 'message'> & { notification: unknown }>\n        >;\n        let mockResponseTransformer: jest.Mock;\n        beforeEach(async () => {\n            jest.useFakeTimers();\n            mockResponseTransformer = jest.fn().mockImplementation(result => result);\n            publisherPromise = executeRpcPubSubSubscriptionPlan({\n                channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n                responseTransformer: mockResponseTransformer,\n                signal: abortController.signal,\n                subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n                unsubscribeMethodName: 'thingUnsubscribe',\n            });\n            await jest.runAllTimersAsync();\n            receiveMessage({ id: lastMessageId, jsonrpc: '2.0', result: (expectedSubscriptionId = 123) });\n        });\n        it('publishes errors', async () => {\n            expect.assertions(1);\n            const publisher = await publisherPromise;\n            const errorListener = jest.fn();\n            publisher.on('error', errorListener);\n            receiveError('o no');\n            expect(errorListener).toHaveBeenCalledWith('o no');\n        });\n        it('publishes notifications that match this subscription id', async () => {\n            expect.assertions(1);\n            const publisher = await publisherPromise;\n            const notificationListener = jest.fn();\n            publisher.on('notification', notificationListener);\n            receiveMessage({\n                jsonrpc: '2.0',\n                method: 'thingNotification',\n                params: {\n                    result: 'hi',\n                    subscription: expectedSubscriptionId,\n                },\n            });\n            expect(notificationListener).toHaveBeenCalledWith('hi');\n        });\n        it('throws when a caller tries to listen to an unsupported channel', async () => {\n            expect.assertions(1);\n            const publisher = await publisherPromise;\n            const badListener = jest.fn();\n            expect(() => {\n                publisher.on(\n                    // @ts-expect-error This test supplies a bad event name on purpose.\n                    'bad',\n                    badListener,\n                );\n            }).toThrow(\n                new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED, {\n                    channelName: 'bad',\n                    supportedChannelNames: ['notification', 'error'],\n                }),\n            );\n        });\n        it('publishes notifications transformed by the response transformer that match this subscription id', async () => {\n            expect.assertions(1);\n            mockResponseTransformer.mockImplementation(result => `now hear this: ${result}`);\n            const publisher = await publisherPromise;\n            const notificationListener = jest.fn();\n            publisher.on('notification', notificationListener);\n            receiveMessage({\n                jsonrpc: '2.0',\n                method: 'thingNotification',\n                params: {\n                    result: 'hi',\n                    subscription: expectedSubscriptionId,\n                },\n            });\n            expect(notificationListener).toHaveBeenCalledWith('now hear this: hi');\n        });\n        it('calls the response transformer only once per notification, even when there are multiple subscribers', async () => {\n            expect.assertions(1);\n            const publisher = await publisherPromise;\n            const notificationListenerA = jest.fn();\n            const notificationListenerB = jest.fn();\n            publisher.on('notification', notificationListenerA);\n            publisher.on('notification', notificationListenerB);\n            receiveMessage({\n                jsonrpc: '2.0',\n                method: 'thingNotification',\n                params: {\n                    result: 'hi',\n                    subscription: expectedSubscriptionId,\n                },\n            });\n            expect(mockResponseTransformer).toHaveBeenCalledTimes(1);\n        });\n        it(\"does not publish notifications that don't match this subscription id\", async () => {\n            expect.assertions(1);\n            const publisher = await publisherPromise;\n            const notificationListener = jest.fn();\n            publisher.on('notification', notificationListener);\n            receiveMessage({\n                jsonrpc: '2.0',\n                method: 'thingNotification',\n                params: {\n                    result: 'hi',\n                    subscription: expectedSubscriptionId + 1,\n                },\n            });\n            expect(notificationListener).not.toHaveBeenCalled();\n        });\n        it('sends an unsubscribe message when aborted', () => {\n            expect.assertions(1);\n            mockSend.mockClear();\n            abortController.abort();\n            expect(mockSend).toHaveBeenCalledWith(\n                expect.objectContaining({\n                    id: expect.any(Number),\n                    jsonrpc: '2.0',\n                    method: 'thingUnsubscribe',\n                    params: [expectedSubscriptionId],\n                }),\n            );\n        });\n        describe('but then later errors', () => {\n            beforeEach(() => {\n                receiveError('o no');\n            });\n            it('does not send an unsubscribe message when aborted', () => {\n                expect.assertions(1);\n                mockSend.mockClear();\n                abortController.abort();\n                expect(mockSend).not.toHaveBeenCalled();\n            });\n        });\n        describe('and then acknowledges a subsequent subscription with the same subscription id', () => {\n            let secondAbortController: AbortController;\n            beforeEach(async () => {\n                jest.useFakeTimers();\n                secondAbortController = new AbortController();\n                executeRpcPubSubSubscriptionPlan({\n                    channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n                    signal: secondAbortController.signal,\n                    subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n                    unsubscribeMethodName: 'thingUnsubscribe',\n                }).catch(() => {});\n                await jest.runAllTimersAsync();\n                receiveMessage({ id: lastMessageId, jsonrpc: '2.0', result: (expectedSubscriptionId = 123) });\n            });\n            /**\n             * Because of https://github.com/solana-labs/solana/pull/18943, two subscriptions for\n             * materially the same notification will be coalesced on the server. This means they\n             * will be assigned the same subscription id, and will occupy one subscription slot. We\n             * must be careful not to send the unsubscribe message until the last subscriber aborts.\n             */\n            it('does not send the unsubscribe message when fewer than all of the subscriptions are aborted', () => {\n                mockSend.mockClear();\n                abortController.abort();\n                expect(mockSend).not.toHaveBeenCalled();\n            });\n            it('sends the unsubscribe message once all of the subscriptions abort', () => {\n                mockSend.mockClear();\n                abortController.abort();\n                secondAbortController.abort();\n                expect(mockSend).toHaveBeenCalledWith(\n                    expect.objectContaining({ method: 'thingUnsubscribe', params: [expectedSubscriptionId] }),\n                );\n            });\n        });\n        describe('and then acknowledges a subsequent subscription with a different subscription id', () => {\n            let secondAbortController: AbortController;\n            let priorSubscriptionId: number;\n            beforeEach(async () => {\n                jest.useFakeTimers();\n                priorSubscriptionId = expectedSubscriptionId;\n                secondAbortController = new AbortController();\n                executeRpcPubSubSubscriptionPlan({\n                    channel: mockChannel as RpcSubscriptionsChannel<unknown, unknown>,\n                    signal: secondAbortController.signal,\n                    subscribeRequest: { methodName: 'thingSubscribe', params: [] },\n                    unsubscribeMethodName: 'thingUnsubscribe',\n                }).catch(() => {});\n                await jest.runAllTimersAsync();\n                receiveMessage({ id: lastMessageId, jsonrpc: '2.0', result: (expectedSubscriptionId = 456) });\n            });\n            it('sends the unsubscribe message when the prior subscription aborts', () => {\n                mockSend.mockClear();\n                abortController.abort();\n                expect(mockSend).toHaveBeenCalledWith(\n                    expect.objectContaining({ method: 'thingUnsubscribe', params: [priorSubscriptionId] }),\n                );\n            });\n            it('sends the unsubscribe message when that latest subscription aborts', () => {\n                mockSend.mockClear();\n                secondAbortController.abort();\n                expect(mockSend).toHaveBeenCalledWith(\n                    expect.objectContaining({ method: 'thingUnsubscribe', params: [expectedSubscriptionId] }),\n                );\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/__tests__/rpc-subscriptions-test.ts",
    "content": "import { SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN, SolanaError } from '@solana/errors';\nimport { DataPublisher } from '@solana/subscribable';\n\nimport { createSubscriptionRpc, type RpcSubscriptions } from '../rpc-subscriptions';\nimport { RpcSubscriptionsTransport } from '../rpc-subscriptions-transport';\n\ninterface TestRpcSubscriptionNotifications {\n    thingNotifications(...args: unknown[]): { value: number };\n}\n\ndescribe('createSubscriptionRpc', () => {\n    let rpcSubscriptions: RpcSubscriptions<TestRpcSubscriptionNotifications>;\n\n    beforeEach(() => {\n        rpcSubscriptions = createSubscriptionRpc<TestRpcSubscriptionNotifications>({\n            // @ts-expect-error Does not implement API on purpose\n            api: {},\n            transport: jest.fn(),\n        });\n    });\n\n    it('throws when the API produces no subscription plan', () => {\n        expect(() => {\n            rpcSubscriptions.thingNotifications();\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN, {\n                notificationName: 'thingNotifications',\n            }),\n        );\n    });\n\n    it('should not be thenable', () => {\n        expect(rpcSubscriptions).not.toHaveProperty('then');\n    });\n});\n\ndescribe('PendingRpcSubscriptionsRequest.reactive()', () => {\n    let mockTransport: jest.MockedFunction<RpcSubscriptionsTransport>;\n    let mockOn: jest.Mock;\n    let mockDataPublisher: DataPublisher;\n    let rpcSubscriptions: RpcSubscriptions<TestRpcSubscriptionNotifications>;\n    function publish(type: string, payload: unknown) {\n        mockOn.mock.calls.filter(([actualType]) => actualType === type).forEach(([_, listener]) => listener(payload));\n    }\n    beforeEach(() => {\n        mockOn = jest.fn().mockReturnValue(function unsubscribe() {});\n        mockDataPublisher = { on: mockOn };\n        mockTransport = jest.fn().mockResolvedValue(mockDataPublisher);\n        rpcSubscriptions = createSubscriptionRpc<TestRpcSubscriptionNotifications>({\n            api: {\n                thingNotifications(...args: unknown[]) {\n                    return {\n                        execute: jest.fn().mockResolvedValue(mockDataPublisher),\n                        request: { methodName: 'thingNotifications', params: args },\n                    };\n                },\n            },\n            transport: mockTransport,\n        });\n    });\n\n    it('passes the abort signal to the transport', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        await rpcSubscriptions.thingNotifications().reactive({ abortSignal: abortController.signal });\n        expect(mockTransport).toHaveBeenCalledWith(expect.objectContaining({ signal: abortController.signal }));\n    });\n    it('returns a store whose getState() starts as undefined', async () => {\n        expect.assertions(1);\n        const store = await rpcSubscriptions\n            .thingNotifications()\n            .reactive({ abortSignal: new AbortController().signal });\n        expect(store.getState()).toBeUndefined();\n    });\n    it('returns a store whose getState() reflects incoming notifications', async () => {\n        expect.assertions(1);\n        const store = await rpcSubscriptions\n            .thingNotifications()\n            .reactive({ abortSignal: new AbortController().signal });\n        publish('notification', { value: 42 });\n        expect(store.getState()).toStrictEqual({ value: 42 });\n    });\n    it('calls store subscribers when a notification arrives', async () => {\n        expect.assertions(1);\n        const store = await rpcSubscriptions\n            .thingNotifications()\n            .reactive({ abortSignal: new AbortController().signal });\n        const subscriber = jest.fn();\n        store.subscribe(subscriber);\n        publish('notification', { value: 42 });\n        expect(subscriber).toHaveBeenCalledTimes(1);\n    });\n    it('surfaces errors via getError()', async () => {\n        expect.assertions(2);\n        const store = await rpcSubscriptions\n            .thingNotifications()\n            .reactive({ abortSignal: new AbortController().signal });\n        expect(store.getError()).toBeUndefined();\n        const error = new Error('o no');\n        publish('error', error);\n        expect(store.getError()).toBe(error);\n    });\n});\n\ndescribe('PendingRpcSubscriptionsRequest.reactiveStore()', () => {\n    let mockTransport: jest.MockedFunction<RpcSubscriptionsTransport>;\n    let mockOn: jest.Mock;\n    let mockDataPublisher: DataPublisher;\n    let rpcSubscriptions: RpcSubscriptions<TestRpcSubscriptionNotifications>;\n    function publish(type: string, payload: unknown) {\n        mockOn.mock.calls.filter(([actualType]) => actualType === type).forEach(([_, listener]) => listener(payload));\n    }\n    // Two ticks: one for the `createDataPublisher()` promise to resolve inside `connect()`,\n    // one for the `.then` handler that wires up the `on(...)` listeners.\n    async function flushMicrotasks() {\n        await Promise.resolve();\n        await Promise.resolve();\n    }\n    beforeEach(() => {\n        mockOn = jest.fn().mockReturnValue(function unsubscribe() {});\n        mockDataPublisher = { on: mockOn };\n        mockTransport = jest.fn().mockResolvedValue(mockDataPublisher);\n        rpcSubscriptions = createSubscriptionRpc<TestRpcSubscriptionNotifications>({\n            api: {\n                thingNotifications(...args: unknown[]) {\n                    return {\n                        execute: jest.fn().mockResolvedValue(mockDataPublisher),\n                        request: { methodName: 'thingNotifications', params: args },\n                    };\n                },\n            },\n            transport: mockTransport,\n        });\n    });\n\n    it('passes the abort signal to the transport', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        rpcSubscriptions.thingNotifications().reactiveStore({ abortSignal: abortController.signal });\n        await flushMicrotasks();\n        expect(mockTransport).toHaveBeenCalledWith(expect.objectContaining({ signal: abortController.signal }));\n    });\n    it('returns a store that starts in `loading` status before the transport resolves', () => {\n        const store = rpcSubscriptions\n            .thingNotifications()\n            .reactiveStore({ abortSignal: new AbortController().signal });\n        expect(store.getUnifiedState()).toStrictEqual({\n            data: undefined,\n            error: undefined,\n            status: 'loading',\n        });\n    });\n    it('returns a store whose state reflects incoming notifications', async () => {\n        expect.assertions(1);\n        const store = rpcSubscriptions\n            .thingNotifications()\n            .reactiveStore({ abortSignal: new AbortController().signal });\n        await flushMicrotasks();\n        publish('notification', { value: 42 });\n        expect(store.getUnifiedState()).toStrictEqual({\n            data: { value: 42 },\n            error: undefined,\n            status: 'loaded',\n        });\n    });\n    it('calls store subscribers when a notification arrives', async () => {\n        expect.assertions(1);\n        const store = rpcSubscriptions\n            .thingNotifications()\n            .reactiveStore({ abortSignal: new AbortController().signal });\n        await flushMicrotasks();\n        const subscriber = jest.fn();\n        store.subscribe(subscriber);\n        publish('notification', { value: 42 });\n        expect(subscriber).toHaveBeenCalledTimes(1);\n    });\n    it('surfaces errors via getUnifiedState()', async () => {\n        expect.assertions(1);\n        const store = rpcSubscriptions\n            .thingNotifications()\n            .reactiveStore({ abortSignal: new AbortController().signal });\n        await flushMicrotasks();\n        const error = new Error('o no');\n        publish('error', error);\n        expect(store.getUnifiedState()).toStrictEqual({\n            data: undefined,\n            error,\n            status: 'error',\n        });\n    });\n    it('re-invokes the transport on retry() after an error', async () => {\n        expect.assertions(1);\n        const store = rpcSubscriptions\n            .thingNotifications()\n            .reactiveStore({ abortSignal: new AbortController().signal });\n        await flushMicrotasks();\n        publish('error', new Error('stream died'));\n        store.retry();\n        await flushMicrotasks();\n        expect(mockTransport).toHaveBeenCalledTimes(2);\n    });\n    it('aborts the signal forwarded to the data publisher listeners when the caller aborts', async () => {\n        expect.assertions(2);\n        const abortController = new AbortController();\n        rpcSubscriptions.thingNotifications().reactiveStore({ abortSignal: abortController.signal });\n        await flushMicrotasks();\n        const onCall = mockOn.mock.calls.find(([channel]: [string]) => channel === 'notification');\n        const listenerSignal = (onCall![2] as { signal: AbortSignal }).signal;\n        expect(listenerSignal.aborted).toBe(false);\n        abortController.abort();\n        expect(listenerSignal.aborted).toBe(true);\n    });\n    it('returns the same getUnifiedState() snapshot across consecutive calls when state has not changed', async () => {\n        expect.assertions(2);\n        const store = rpcSubscriptions\n            .thingNotifications()\n            .reactiveStore({ abortSignal: new AbortController().signal });\n        await flushMicrotasks();\n        expect(store.getUnifiedState()).toBe(store.getUnifiedState());\n        publish('notification', { value: 42 });\n        expect(store.getUnifiedState()).toBe(store.getUnifiedState());\n    });\n});\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/__typetests__/rpc-subscriptions-api-typetest.ts",
    "content": "import { createRpcSubscriptionsApi, RpcSubscriptionsApi } from '../rpc-subscriptions-api';\n\ntype NftCollectionDetailsApiResponse = Readonly<{\n    address: string;\n    circulatingSupply: number;\n    description: string;\n    erc1155: boolean;\n    erc721: boolean;\n    genesisBlock: string;\n    genesisTransaction: string;\n    name: string;\n    totalSupply: number;\n}>;\n\ntype NftCollectionDetailsApi = {\n    qn_fetchNFTCollectionDetails(args: { contracts: string[] }): NftCollectionDetailsApiResponse;\n};\n\ntype QuickNodeRpcMethods = NftCollectionDetailsApi;\n\ncreateRpcSubscriptionsApi<QuickNodeRpcMethods>(\n    ...(null as unknown as Parameters<typeof createRpcSubscriptionsApi>),\n) satisfies RpcSubscriptionsApi<QuickNodeRpcMethods>;\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/__typetests__/rpc-subscriptions-typetest.ts",
    "content": "import { createSubscriptionRpc, RpcSubscriptions } from '../rpc-subscriptions';\nimport { createRpcSubscriptionsApi } from '../rpc-subscriptions-api';\nimport { RpcSubscriptionsTransport } from '../rpc-subscriptions-transport';\n\ntype MySubscriptionApiMethods = {\n    bar(): string;\n    foo(): number;\n};\n\nconst api = createRpcSubscriptionsApi<MySubscriptionApiMethods>(\n    ...(null as unknown as Parameters<typeof createRpcSubscriptionsApi>),\n);\nconst transport = null as unknown as RpcSubscriptionsTransport;\n\ncreateSubscriptionRpc({ api, transport }) satisfies RpcSubscriptions<MySubscriptionApiMethods>;\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/index.ts",
    "content": "/**\n * This package contains types that describe the implementation of the JSON RPC Subscriptions API,\n * as well as methods to create one. It can be used standalone, but it is also exported as part of\n * Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @example\n * ```ts\n * const rpcSubscriptions =\n *     // Step 1 - Create a `RpcSubscriptions` instance. This may be stateful.\n *     createSolanaRpcSubscriptions(mainnet('wss://api.mainnet-beta.solana.com'));\n * const response = await rpcSubscriptions\n *     // Step 2 - Call supported methods on it to produce `PendingRpcSubscriptionsRequest` objects.\n *     .slotNotifications({ commitment: 'confirmed' })\n *     // Step 3 - Call the `subscribe()` method on those pending requests to trigger them.\n *     .subscribe({ abortSignal: AbortSignal.timeout(10_000) });\n * // Step 4 - Iterate over the result.\n * try {\n *     for await (const slotNotification of slotNotifications) {\n *         console.log('Got a slot notification', slotNotification);\n *     }\n * } catch (e) {\n *     console.error('The subscription closed unexpectedly', e);\n * } finally {\n *     console.log('We have stopped listening for notifications');\n * }\n * ```\n *\n * @packageDocumentation\n */\nexport * from './rpc-subscriptions-request';\nexport * from './rpc-subscriptions';\nexport * from './rpc-subscriptions-api';\nexport * from './rpc-subscriptions-channel';\nexport * from './rpc-subscriptions-pubsub-plan';\nexport * from './rpc-subscriptions-transport';\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/rpc-subscriptions-api.ts",
    "content": "import { Callable, RpcRequest, RpcRequestTransformer } from '@solana/rpc-spec-types';\nimport { DataPublisher } from '@solana/subscribable';\n\nimport { RpcSubscriptionsChannel } from './rpc-subscriptions-channel';\nimport { RpcSubscriptionsTransportDataEvents } from './rpc-subscriptions-transport';\n\nexport type RpcSubscriptionsApiConfig<TApiMethods extends RpcSubscriptionsApiMethods> = Readonly<{\n    planExecutor: RpcSubscriptionsPlanExecutor<ReturnType<TApiMethods[keyof TApiMethods]>>;\n    /**\n     * An optional function that transforms the {@link RpcRequest} before it is sent to the JSON RPC\n     * server.\n     *\n     * This is useful when the params supplied by the caller need to be transformed before\n     * forwarding the message to the server. Use cases for this include applying defaults,\n     * forwarding calls to renamed methods, and serializing complex values.\n     */\n    requestTransformer?: RpcRequestTransformer;\n}>;\n\n/**\n * A function that implements a protocol for subscribing and unsubscribing from notifications given\n * a {@link RpcSubscriptionsChannel}, a {@link RpcRequest}, and an `AbortSignal`.\n *\n * @returns A {@link DataPublisher} that emits {@link RpcSubscriptionsTransportDataEvents}\n */\ntype RpcSubscriptionsPlanExecutor<TNotification> = (\n    config: Readonly<{\n        channel: RpcSubscriptionsChannel<unknown, unknown>;\n        request: RpcRequest;\n        signal: AbortSignal;\n    }>,\n) => Promise<DataPublisher<RpcSubscriptionsTransportDataEvents<TNotification>>>;\n\n/**\n * This type allows an {@link RpcSubscriptionsApi} to describe how a particular subscription should\n * be issued to the JSON RPC server.\n *\n * Given a function that was called on a {@link RpcSubscriptions}, this object exposes an `execute`\n * function that dictates which subscription request will be sent, how the underlying transport will\n * be used, and how the notifications will be transformed.\n *\n * This function accepts a {@link RpcSubscriptionsChannel} and an `AbortSignal` and asynchronously\n * returns a {@link DataPublisher}. This gives us the opportunity to:\n *\n * - define the `payload` from the requested method name and parameters before passing it to the\n *   channel.\n * - call the underlying channel zero, one or multiple times depending on the use-case (e.g.\n *   caching or coalescing multiple subscriptions).\n * - transform the notification from the JSON RPC server, in case it does not match the\n *   `TNotification` specified by the\n *   {@link PendingRpcSubscriptionsRequest | PendingRpcSubscriptionsRequest<TNotification>} emitted\n *   from the publisher returned.\n */\nexport type RpcSubscriptionsPlan<TNotification> = Readonly<{\n    /**\n     * This method may be called with a newly-opened channel or a pre-established channel.\n     */\n    execute: (\n        config: Readonly<{\n            channel: RpcSubscriptionsChannel<unknown, unknown>;\n            signal: AbortSignal;\n        }>,\n    ) => Promise<DataPublisher<RpcSubscriptionsTransportDataEvents<TNotification>>>;\n    /**\n     * This request is used to uniquely identify the subscription.\n     * It typically comes from the method name and parameters of the subscription call,\n     * after potentially being transformed by the RPC Subscriptions API.\n     */\n    request: RpcRequest;\n}>;\n\n/**\n * For each of `TRpcSubscriptionsMethods`, this object exposes a method with the same name that maps\n * between its input arguments and a\n * {@link RpcSubscriptionsPlan | RpcSubscriptionsPlan<TNotification>} that implements the execution\n * of a JSON RPC subscription for `TNotifications`.\n */\nexport type RpcSubscriptionsApi<TRpcSubscriptionMethods> = {\n    [MethodName in keyof TRpcSubscriptionMethods]: RpcSubscriptionsReturnTypeMapper<\n        TRpcSubscriptionMethods[MethodName]\n    >;\n};\n\ntype RpcSubscriptionsReturnTypeMapper<TRpcMethod> = TRpcMethod extends Callable\n    ? (...rawParams: unknown[]) => RpcSubscriptionsPlan<ReturnType<TRpcMethod>>\n    : never;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype RpcSubscriptionsApiMethod = (...args: any) => any;\nexport interface RpcSubscriptionsApiMethods {\n    [methodName: string]: RpcSubscriptionsApiMethod;\n}\n\n/**\n * Creates a JavaScript proxy that converts _any_ function call called on it to a\n * {@link RpcSubscriptionsPlan} by creating an `execute` function that:\n *\n * - calls the supplied {@link RpcSubscriptionsApiConfig.planExecutor} with a JSON RPC v2 payload\n *   object with the requested `methodName` and `params` properties, optionally transformed by\n *   {@link RpcSubscriptionsApiConfig.requestTransformer}.\n *\n * @example\n * ```ts\n * // For example, given this `RpcSubscriptionsApi`:\n * const rpcSubscriptionsApi = createJsonRpcSubscriptionsApi({\n *     async planExecutor({ channel, request }) {\n *         await channel.send(request);\n *         return {\n *             ...channel,\n *             on(type, listener, options) {\n *                 if (type !== 'message') {\n *                     return channel.on(type, listener, options);\n *                 }\n *                 return channel.on(\n *                     'message',\n *                     function resultGettingListener(message) {\n *                         listener(message.result);\n *                     },\n *                     options,\n *                 );\n *             }\n *         }\n *     },\n *     requestTransformer: (...rawParams) => rawParams.reverse(),\n * });\n *\n * // ...the following function call:\n * rpcSubscriptionsApi.foo('bar', { baz: 'bat' });\n *\n * // ...will produce a `RpcSubscriptionsPlan` that:\n * // -   Uses the following payload: { id: 1, jsonrpc: '2.0', method: 'foo', params: [{ baz: 'bat' }, 'bar'] }.\n * // -   Emits the \"result\" property of each RPC Subscriptions message.\n * ```\n */\nexport function createRpcSubscriptionsApi<TRpcSubscriptionsApiMethods extends RpcSubscriptionsApiMethods>(\n    config: RpcSubscriptionsApiConfig<TRpcSubscriptionsApiMethods>,\n): RpcSubscriptionsApi<TRpcSubscriptionsApiMethods> {\n    return new Proxy({} as RpcSubscriptionsApi<TRpcSubscriptionsApiMethods>, {\n        defineProperty() {\n            return false;\n        },\n        deleteProperty() {\n            return false;\n        },\n        get<TNotificationName extends keyof RpcSubscriptionsApi<TRpcSubscriptionsApiMethods>>(\n            ...args: Parameters<NonNullable<ProxyHandler<RpcSubscriptionsApi<TRpcSubscriptionsApiMethods>>['get']>>\n        ) {\n            const [_, p] = args;\n            const methodName = p.toString() as keyof TRpcSubscriptionsApiMethods as string;\n            return function (\n                ...params: Parameters<\n                    TRpcSubscriptionsApiMethods[TNotificationName] extends CallableFunction\n                        ? TRpcSubscriptionsApiMethods[TNotificationName]\n                        : never\n                >\n            ): RpcSubscriptionsPlan<ReturnType<TRpcSubscriptionsApiMethods[TNotificationName]>> {\n                const rawRequest = { methodName, params };\n                const request = config.requestTransformer ? config.requestTransformer(rawRequest) : rawRequest;\n                return {\n                    execute(planConfig) {\n                        return config.planExecutor({ ...planConfig, request });\n                    },\n                    request,\n                };\n            };\n        },\n    });\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/rpc-subscriptions-channel.ts",
    "content": "import {\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT,\n    SolanaError,\n} from '@solana/errors';\nimport { DataPublisher } from '@solana/subscribable';\n\ntype RpcSubscriptionsChannelSolanaErrorCode =\n    | typeof SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CLOSED_BEFORE_MESSAGE_BUFFERED\n    | typeof SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_CONNECTION_CLOSED\n    | typeof SOLANA_ERROR__RPC_SUBSCRIPTIONS__CHANNEL_FAILED_TO_CONNECT;\n\nexport type RpcSubscriptionChannelEvents<TInboundMessage> = {\n    /**\n     * Fires when the channel closes unexpectedly.\n     * @eventProperty\n     */\n    error: SolanaError<RpcSubscriptionsChannelSolanaErrorCode>;\n    /**\n     * Fires on every message received from the remote end.\n     * @eventProperty\n     */\n    message: TInboundMessage;\n};\n\n/**\n * A {@link DataPublisher} on which you can subscribe to events of type\n * {@link RpcSubscriptionChannelEvents | RpcSubscriptionChannelEvents<TInboundMessage>}.\n * Additionally, you can use this object to send messages of type `TOutboundMessage` back to the\n * remote end by calling its {@link RpcSubscriptionsChannel.send | `send(message)`} method.\n */\nexport interface RpcSubscriptionsChannel<TOutboundMessage, TInboundMessage> extends DataPublisher<\n    RpcSubscriptionChannelEvents<TInboundMessage>\n> {\n    send(message: TOutboundMessage): Promise<void>;\n}\n\n/**\n * A channel creator is a function that accepts an `AbortSignal`, returns a new\n * {@link RpcSubscriptionsChannel}, and tears down the channel when the abort signal fires.\n */\nexport type RpcSubscriptionsChannelCreator<TOutboundMessage, TInboundMessage> = (\n    config: Readonly<{\n        abortSignal: AbortSignal;\n    }>,\n) => Promise<RpcSubscriptionsChannel<TOutboundMessage, TInboundMessage>>;\n\n/**\n * Given a channel with inbound messages of type `T` and a function of type `T => U`, returns a new\n * channel with inbound messages of type `U`.\n *\n * Note that this only affects messages of type `\"message\"` and thus, does not affect incoming error\n * messages.\n *\n * @example Parsing incoming JSON messages\n * ```ts\n * const transformedChannel = transformChannelInboundMessages(channel, JSON.parse);\n * ```\n */\nexport function transformChannelInboundMessages<TOutboundMessage, TNewInboundMessage, TInboundMessage>(\n    channel: RpcSubscriptionsChannel<TOutboundMessage, TInboundMessage>,\n    transform: (message: TInboundMessage) => TNewInboundMessage,\n): RpcSubscriptionsChannel<TOutboundMessage, TNewInboundMessage> {\n    return Object.freeze<RpcSubscriptionsChannel<TOutboundMessage, TNewInboundMessage>>({\n        ...channel,\n        on(type, subscriber, options) {\n            if (type !== 'message') {\n                return channel.on(\n                    type,\n                    subscriber as (data: RpcSubscriptionChannelEvents<TInboundMessage>[typeof type]) => void,\n                    options,\n                );\n            }\n            return channel.on(\n                'message',\n                message => (subscriber as (data: TNewInboundMessage) => void)(transform(message)),\n                options,\n            );\n        },\n    });\n}\n\n/**\n * Given a channel with outbound messages of type `T` and a function of type `U => T`, returns a new\n * channel with outbound messages of type `U`.\n *\n * @example Stringifying JSON messages before sending them over the wire\n * ```ts\n * const transformedChannel = transformChannelOutboundMessages(channel, JSON.stringify);\n * ```\n */\nexport function transformChannelOutboundMessages<TNewOutboundMessage, TOutboundMessage, TInboundMessage>(\n    channel: RpcSubscriptionsChannel<TOutboundMessage, TInboundMessage>,\n    transform: (message: TNewOutboundMessage) => TOutboundMessage,\n): RpcSubscriptionsChannel<TNewOutboundMessage, TInboundMessage> {\n    return Object.freeze<RpcSubscriptionsChannel<TNewOutboundMessage, TInboundMessage>>({\n        ...channel,\n        send: message => channel.send(transform(message)),\n    });\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/rpc-subscriptions-pubsub-plan.ts",
    "content": "import {\n    getSolanaErrorFromJsonRpcError,\n    SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED,\n    SOLANA_ERROR__RPC_SUBSCRIPTIONS__EXPECTED_SERVER_SUBSCRIPTION_ID,\n    SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\nimport { safeRace } from '@solana/promises';\nimport { createRpcMessage, RpcRequest, RpcResponseData, RpcResponseTransformer } from '@solana/rpc-spec-types';\nimport { DataPublisher } from '@solana/subscribable';\nimport { demultiplexDataPublisher } from '@solana/subscribable';\n\nimport { RpcSubscriptionChannelEvents } from './rpc-subscriptions-channel';\nimport { RpcSubscriptionsChannel } from './rpc-subscriptions-channel';\n\ntype Config<TNotification> = Readonly<{\n    channel: RpcSubscriptionsChannel<unknown, RpcNotification<TNotification> | RpcResponseData<RpcSubscriptionId>>;\n    responseTransformer?: RpcResponseTransformer;\n    signal: AbortSignal;\n    subscribeRequest: RpcRequest;\n    unsubscribeMethodName: string;\n}>;\n\ntype RpcNotification<TNotification> = Readonly<{\n    method: string;\n    params: Readonly<{\n        result: TNotification;\n        subscription: number;\n    }>;\n}>;\n\ntype RpcSubscriptionId = number;\n\ntype RpcSubscriptionNotificationEvents<TNotification> = Omit<RpcSubscriptionChannelEvents<TNotification>, 'message'> & {\n    notification: TNotification;\n};\n\nconst subscriberCountBySubscriptionIdByChannel = new WeakMap<WeakKey, Record<number, number>>();\nfunction decrementSubscriberCountAndReturnNewCount(channel: WeakKey, subscriptionId?: number): number | undefined {\n    return augmentSubscriberCountAndReturnNewCount(-1, channel, subscriptionId);\n}\nfunction incrementSubscriberCount(channel: WeakKey, subscriptionId?: number): void {\n    augmentSubscriberCountAndReturnNewCount(1, channel, subscriptionId);\n}\nfunction getSubscriberCountBySubscriptionIdForChannel(channel: WeakKey): Record<number, number> {\n    let subscriberCountBySubscriptionId = subscriberCountBySubscriptionIdByChannel.get(channel);\n    if (!subscriberCountBySubscriptionId) {\n        subscriberCountBySubscriptionIdByChannel.set(channel, (subscriberCountBySubscriptionId = {}));\n    }\n    return subscriberCountBySubscriptionId;\n}\nfunction augmentSubscriberCountAndReturnNewCount(\n    amount: -1 | 1,\n    channel: WeakKey,\n    subscriptionId?: number,\n): number | undefined {\n    if (subscriptionId === undefined) {\n        return;\n    }\n    const subscriberCountBySubscriptionId = getSubscriberCountBySubscriptionIdForChannel(channel);\n    if (!subscriberCountBySubscriptionId[subscriptionId] && amount > 0) {\n        subscriberCountBySubscriptionId[subscriptionId] = 0;\n    }\n    const newCount = amount + subscriberCountBySubscriptionId[subscriptionId];\n    if (newCount <= 0) {\n        delete subscriberCountBySubscriptionId[subscriptionId];\n    } else {\n        subscriberCountBySubscriptionId[subscriptionId] = newCount;\n    }\n    return newCount;\n}\n\nconst cache = new WeakMap();\nfunction getMemoizedDemultiplexedNotificationPublisherFromChannelAndResponseTransformer<TNotification>(\n    channel: RpcSubscriptionsChannel<unknown, RpcNotification<TNotification>>,\n    subscribeRequest: RpcRequest,\n    responseTransformer?: RpcResponseTransformer,\n): DataPublisher<{\n    [channelName: `notification:${number}`]: TNotification;\n}> {\n    let publisherByResponseTransformer = cache.get(channel);\n    if (!publisherByResponseTransformer) {\n        cache.set(channel, (publisherByResponseTransformer = new WeakMap()));\n    }\n    const responseTransformerKey = responseTransformer ?? channel;\n    let publisher = publisherByResponseTransformer.get(responseTransformerKey);\n    if (!publisher) {\n        publisherByResponseTransformer.set(\n            responseTransformerKey,\n            (publisher = demultiplexDataPublisher(channel, 'message', rawMessage => {\n                const message = rawMessage as RpcNotification<unknown> | RpcResponseData<unknown>;\n                if (!('method' in message)) {\n                    return;\n                }\n                const transformedNotification = responseTransformer\n                    ? responseTransformer(message.params.result, subscribeRequest)\n                    : message.params.result;\n                return [`notification:${message.params.subscription}`, transformedNotification];\n            })),\n        );\n    }\n    return publisher;\n}\n\n/**\n * Given a channel, this function executes the particular subscription plan required by the Solana\n * JSON RPC Subscriptions API.\n *\n * @param config\n *\n * 1. Calls the `subscribeRequest` on the remote RPC\n * 2. Waits for a response containing the subscription id\n * 3. Returns a {@link DataPublisher} that publishes notifications related to that subscriptions id,\n *    filtering out all others\n * 4. Calls the `unsubscribeMethodName` on the remote RPC when the abort signal is fired.\n */\nexport async function executeRpcPubSubSubscriptionPlan<TNotification>({\n    channel,\n    responseTransformer,\n    signal,\n    subscribeRequest,\n    unsubscribeMethodName,\n}: Config<TNotification>): Promise<DataPublisher<RpcSubscriptionNotificationEvents<TNotification>>> {\n    let subscriptionId: number | undefined;\n    channel.on(\n        'error',\n        () => {\n            // An error on the channel indicates that the subscriptions are dead.\n            // There is no longer any sense hanging on to subscription ids.\n            // Erasing it here will prevent the unsubscribe code from running.\n            subscriptionId = undefined;\n            subscriberCountBySubscriptionIdByChannel.delete(channel);\n        },\n        { signal },\n    );\n    /**\n     * STEP 1\n     * Create a promise that rejects if this subscription is aborted and sends\n     * the unsubscribe message if the subscription is active at that time.\n     */\n    const abortPromise = new Promise<never>((_, reject) => {\n        function handleAbort(this: AbortSignal) {\n            /**\n             * Because of https://github.com/solana-labs/solana/pull/18943, two subscriptions for\n             * materially the same notification will be coalesced on the server. This means they\n             * will be assigned the same subscription id, and will occupy one subscription slot. We\n             * must be careful not to send the unsubscribe message until the last subscriber aborts.\n             */\n            if (decrementSubscriberCountAndReturnNewCount(channel, subscriptionId) === 0) {\n                const unsubscribePayload = createRpcMessage({\n                    methodName: unsubscribeMethodName,\n                    params: [subscriptionId],\n                });\n                subscriptionId = undefined;\n                channel.send(unsubscribePayload).catch(() => {});\n            }\n            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\n            reject(this.reason);\n        }\n        if (signal.aborted) {\n            handleAbort.call(signal);\n        } else {\n            signal.addEventListener('abort', handleAbort);\n        }\n    });\n    /**\n     * STEP 2\n     * Send the subscription request.\n     */\n    const subscribePayload = createRpcMessage(subscribeRequest);\n    await channel.send(subscribePayload);\n    /**\n     * STEP 3\n     * Wait for the acknowledgement from the server with the subscription id.\n     */\n    const subscriptionIdPromise = new Promise<RpcSubscriptionId>((resolve, reject) => {\n        const abortController = new AbortController();\n        signal.addEventListener('abort', abortController.abort.bind(abortController));\n        const options = { signal: abortController.signal } as const;\n        channel.on(\n            'error',\n            err => {\n                abortController.abort();\n                reject(err);\n            },\n            options,\n        );\n        channel.on(\n            'message',\n            message => {\n                if (message && typeof message === 'object' && 'id' in message && message.id === subscribePayload.id) {\n                    abortController.abort();\n                    if ('error' in message) {\n                        reject(getSolanaErrorFromJsonRpcError(message.error));\n                    } else {\n                        resolve(message.result);\n                    }\n                }\n            },\n            options,\n        );\n    });\n    subscriptionId = await safeRace([abortPromise, subscriptionIdPromise]);\n    if (subscriptionId == null) {\n        throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__EXPECTED_SERVER_SUBSCRIPTION_ID);\n    }\n    incrementSubscriberCount(channel, subscriptionId);\n    /**\n     * STEP 4\n     * Filter out notifications unrelated to this subscription.\n     */\n    const notificationPublisher = getMemoizedDemultiplexedNotificationPublisherFromChannelAndResponseTransformer(\n        channel,\n        subscribeRequest,\n        responseTransformer,\n    );\n    const notificationKey = `notification:${subscriptionId}` as const;\n    return {\n        on(type, listener, options) {\n            switch (type) {\n                case 'notification':\n                    return notificationPublisher.on(\n                        notificationKey,\n                        listener as (data: RpcSubscriptionNotificationEvents<TNotification>['notification']) => void,\n                        options,\n                    );\n                case 'error':\n                    return channel.on(\n                        'error',\n                        listener as (data: RpcSubscriptionNotificationEvents<TNotification>['error']) => void,\n                        options,\n                    );\n                default:\n                    throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__DATA_PUBLISHER_CHANNEL_UNIMPLEMENTED, {\n                        channelName: type,\n                        supportedChannelNames: ['notification', 'error'],\n                    });\n            }\n        },\n    };\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/rpc-subscriptions-request.ts",
    "content": "import { ReactiveStreamStore } from '@solana/subscribable';\n\n/**\n * Pending subscriptions are the result of calling a supported method on a {@link RpcSubscriptions}\n * object. They encapsulate all of the information necessary to make the subscription without\n * actually making it.\n *\n * Calling the {@link PendingRpcSubscriptionsRequest.subscribe | `subscribe(options)`} method on a\n * {@link PendingRpcSubscriptionsRequest | PendingRpcSubscriptionsRequest<TNotification>} will\n * trigger the subscription and return a promise for an async iterable that vends `TNotifications`.\n *\n * Calling the {@link PendingRpcSubscriptionsRequest.reactiveStore | `reactiveStore(options)`}\n * method will return a {@link ReactiveStreamStore} compatible with `useSyncExternalStore`, Svelte\n * stores, and other reactive primitives.\n */\nexport type PendingRpcSubscriptionsRequest<TNotification> = {\n    /**\n     * Triggers the subscription and returns a promise for a {@link ReactiveStreamStore} that holds\n     * the latest notification. Compatible with `useSyncExternalStore` and other reactive primitives\n     * that expect a `{ subscribe, getState }` contract.\n     *\n     * @example\n     * ```ts\n     * const store = await rpc.accountNotifications(address).reactive({ abortSignal });\n     * // React — throw error from snapshot to surface via Error Boundary\n     * const state = useSyncExternalStore(store.subscribe, () => {\n     *     if (store.getError()) throw store.getError();\n     *     return store.getState();\n     * });\n     * ```\n     *\n     * @deprecated Use {@link PendingRpcSubscriptionsRequest.reactiveStore | `reactiveStore()`}\n     * instead. The synchronous variant returns a store that reconnects on\n     * {@link ReactiveStreamStore.retry | `retry()`} after an error, whereas the store returned by\n     * `reactive()` cannot recover once its underlying `DataPublisher` has failed.\n     */\n    reactive(options: RpcSubscribeOptions): Promise<ReactiveStreamStore<TNotification>>;\n    /**\n     * Synchronously returns a {@link ReactiveStreamStore} that subscribes in the background and\n     * holds the latest notification. Compatible with `useSyncExternalStore` and other reactive\n     * primitives that expect a `{ subscribe, getUnifiedState }` contract. The store opens a fresh\n     * subscription on construction and on every {@link ReactiveStreamStore.retry | `retry()`}.\n     *\n     * @example\n     * ```ts\n     * const store = rpc.accountNotifications(address).reactiveStore({ abortSignal });\n     * // React — the unified snapshot has stable identity per update.\n     * const state = useSyncExternalStore(store.subscribe, store.getUnifiedState);\n     * if (state.status === 'error') return <ErrorMessage error={state.error} onRetry={store.retry} />;\n     * if (state.status === 'loading') return <Spinner />;\n     * return <View data={state.data} />;\n     * ```\n     */\n    reactiveStore(options: RpcSubscribeOptions): ReactiveStreamStore<TNotification>;\n    /**\n     * Triggers the subscription and returns a promise for an async iterable of notifications.\n     * Use `for await...of` to consume notifications as they arrive. Abort the signal to\n     * unsubscribe.\n     *\n     * @example\n     * ```ts\n     * const notifications = await rpc.accountNotifications(address).subscribe({ abortSignal });\n     * for await (const notification of notifications) {\n     *     console.log('Account changed:', notification);\n     * }\n     * ```\n     */\n    subscribe(options: RpcSubscribeOptions): Promise<AsyncIterable<TNotification>>;\n};\n\nexport type RpcSubscribeOptions = Readonly<{\n    /** An `AbortSignal` to fire when you want to unsubscribe */\n    abortSignal: AbortSignal;\n}>;\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/rpc-subscriptions-transport.ts",
    "content": "import { SolanaError } from '@solana/errors';\nimport { DataPublisher } from '@solana/subscribable';\n\nimport { RpcSubscriptionsPlan } from './rpc-subscriptions-api';\n\nexport type RpcSubscriptionsTransportDataEvents<TNotification> = {\n    /**\n     * Fires when there is an error with the subscription or the channel.\n     * @eventProperty\n     */\n    error: SolanaError;\n    /**\n     * Fires on every notification received.\n     * @eventProperty\n     */\n    notification: TNotification;\n};\n\ninterface RpcSubscriptionsTransportConfig<TNotification> extends RpcSubscriptionsPlan<TNotification> {\n    /** An `AbortSignal` to fire when you want to unsubscribe */\n    signal: AbortSignal;\n}\n\n/**\n * A function that can act as a transport for a {@link RpcSubscriptions}. It need only return a\n * promise for a {@link DataPublisher} given the supplied config.\n */\nexport interface RpcSubscriptionsTransport {\n    <TNotification>(\n        config: RpcSubscriptionsTransportConfig<TNotification>,\n    ): Promise<DataPublisher<RpcSubscriptionsTransportDataEvents<TNotification>>>;\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/src/rpc-subscriptions.ts",
    "content": "import { SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN, SolanaError } from '@solana/errors';\nimport { Callable, Flatten, OverloadImplementations, UnionToIntersection } from '@solana/rpc-spec-types';\nimport {\n    createAsyncIterableFromDataPublisher,\n    createReactiveStoreFromDataPublisher,\n    createReactiveStoreFromDataPublisherFactory,\n} from '@solana/subscribable';\n\nimport { RpcSubscriptionsApi, RpcSubscriptionsPlan } from './rpc-subscriptions-api';\nimport { PendingRpcSubscriptionsRequest, RpcSubscribeOptions } from './rpc-subscriptions-request';\nimport { RpcSubscriptionsTransport } from './rpc-subscriptions-transport';\n\nexport type RpcSubscriptionsConfig<TRpcMethods> = Readonly<{\n    api: RpcSubscriptionsApi<TRpcMethods>;\n    transport: RpcSubscriptionsTransport;\n}>;\n\n/**\n * An object that exposes all of the functions described by `TRpcSubscriptionsMethods`.\n *\n * Calling each method returns a\n * {@link PendingRpcSubscriptionsRequest | PendingRpcSubscriptionsRequest<TNotification>} where\n * `TNotification` is that method's notification type.\n */\nexport type RpcSubscriptions<TRpcSubscriptionsMethods> = {\n    [TMethodName in keyof TRpcSubscriptionsMethods]: PendingRpcSubscriptionsRequestBuilder<\n        OverloadImplementations<TRpcSubscriptionsMethods, TMethodName>\n    >;\n};\n\ntype PendingRpcSubscriptionsRequestBuilder<TSubscriptionMethodImplementations> = UnionToIntersection<\n    Flatten<{\n        [P in keyof TSubscriptionMethodImplementations]: PendingRpcSubscriptionsRequestReturnTypeMapper<\n            TSubscriptionMethodImplementations[P]\n        >;\n    }>\n>;\n\ntype PendingRpcSubscriptionsRequestReturnTypeMapper<TSubscriptionMethodImplementation> =\n    // Check that this property of the TRpcSubscriptionMethods interface is, in fact, a function.\n    TSubscriptionMethodImplementation extends Callable\n        ? (\n              ...args: Parameters<TSubscriptionMethodImplementation>\n          ) => PendingRpcSubscriptionsRequest<ReturnType<TSubscriptionMethodImplementation>>\n        : never;\n\n/**\n * Creates a {@link RpcSubscriptions} instance given a\n * {@link RpcSubscriptionsApi | RpcSubscriptionsApi<TRpcSubscriptionsApiMethods>} and a\n * {@link RpcSubscriptionsTransport} capable of fulfilling them.\n */\nexport function createSubscriptionRpc<TRpcSubscriptionsApiMethods>(\n    rpcConfig: RpcSubscriptionsConfig<TRpcSubscriptionsApiMethods>,\n): RpcSubscriptions<TRpcSubscriptionsApiMethods> {\n    return new Proxy(rpcConfig.api, {\n        defineProperty() {\n            return false;\n        },\n        deleteProperty() {\n            return false;\n        },\n        get(target, p, receiver) {\n            if (p === 'then') {\n                return undefined;\n            }\n            return function (...rawParams: unknown[]) {\n                const notificationName = p.toString();\n                const createRpcSubscriptionPlan = Reflect.get(target, notificationName, receiver);\n                if (!createRpcSubscriptionPlan) {\n                    throw new SolanaError(SOLANA_ERROR__RPC_SUBSCRIPTIONS__CANNOT_CREATE_SUBSCRIPTION_PLAN, {\n                        notificationName,\n                    });\n                }\n                const subscriptionPlan = createRpcSubscriptionPlan(...rawParams);\n                return createPendingRpcSubscription(rpcConfig.transport, subscriptionPlan);\n            };\n        },\n    }) as RpcSubscriptions<TRpcSubscriptionsApiMethods>;\n}\n\nfunction createPendingRpcSubscription<TNotification>(\n    transport: RpcSubscriptionsTransport,\n    subscriptionsPlan: RpcSubscriptionsPlan<TNotification>,\n): PendingRpcSubscriptionsRequest<TNotification> {\n    return {\n        async reactive({ abortSignal }: RpcSubscribeOptions) {\n            const notificationsDataPublisher = await transport({\n                signal: abortSignal,\n                ...subscriptionsPlan,\n            });\n            return createReactiveStoreFromDataPublisher<TNotification>({\n                abortSignal,\n                dataChannelName: 'notification',\n                dataPublisher: notificationsDataPublisher,\n                errorChannelName: 'error',\n            });\n        },\n        reactiveStore({ abortSignal }: RpcSubscribeOptions) {\n            return createReactiveStoreFromDataPublisherFactory<TNotification>({\n                abortSignal,\n                createDataPublisher() {\n                    return transport({ signal: abortSignal, ...subscriptionsPlan });\n                },\n                dataChannelName: 'notification',\n                errorChannelName: 'error',\n            });\n        },\n        async subscribe({ abortSignal }: RpcSubscribeOptions): Promise<AsyncIterable<TNotification>> {\n            const notificationsDataPublisher = await transport({\n                signal: abortSignal,\n                ...subscriptionsPlan,\n            });\n            return createAsyncIterableFromDataPublisher<TNotification>({\n                abortSignal,\n                dataChannelName: 'notification',\n                dataPublisher: notificationsDataPublisher,\n                errorChannelName: 'error',\n            });\n        },\n    };\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-subscriptions-spec\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-subscriptions-spec/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-transformers/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-transformers/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-transformers/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-transformers/CHANGELOG.md",
    "content": "# @solana/rpc-transformers\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/errors@6.9.0\n    - @solana/functional@6.9.0\n    - @solana/nominal-types@6.9.0\n    - @solana/rpc-spec-types@6.9.0\n    - @solana/rpc-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n    - @solana/functional@6.8.0\n    - @solana/nominal-types@6.8.0\n    - @solana/rpc-spec-types@6.8.0\n    - @solana/rpc-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n    - @solana/functional@6.7.0\n    - @solana/nominal-types@6.7.0\n    - @solana/rpc-spec-types@6.7.0\n    - @solana/rpc-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/rpc-types@6.6.0\n    - @solana/functional@6.6.0\n    - @solana/nominal-types@6.6.0\n    - @solana/rpc-spec-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n    - @solana/functional@6.5.0\n    - @solana/nominal-types@6.5.0\n    - @solana/rpc-spec-types@6.5.0\n    - @solana/rpc-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-types@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/functional@6.4.0\n    - @solana/nominal-types@6.4.0\n    - @solana/rpc-spec-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n    - @solana/functional@6.3.1\n    - @solana/nominal-types@6.3.1\n    - @solana/rpc-spec-types@6.3.1\n    - @solana/rpc-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/functional@6.3.0\n    - @solana/nominal-types@6.3.0\n    - @solana/rpc-spec-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/functional@6.2.0\n    - @solana/nominal-types@6.2.0\n    - @solana/rpc-spec-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/functional@6.1.0\n    - @solana/nominal-types@6.1.0\n    - @solana/rpc-spec-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.1\n    - @solana/functional@6.0.1\n    - @solana/nominal-types@6.0.1\n    - @solana/rpc-spec-types@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.0\n    - @solana/functional@6.0.0\n    - @solana/nominal-types@6.0.0\n    - @solana/rpc-spec-types@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/functional@5.5.1\n    - @solana/nominal-types@5.5.1\n    - @solana/rpc-spec-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/functional@5.5.0\n    - @solana/nominal-types@5.5.0\n    - @solana/rpc-spec-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- [#1186](https://github.com/anza-xyz/kit/pull/1186) [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix type of error in sendTransaction preflight error\n\n    Some fields in `RpcSimulateTransactionResult` were incorrectly typed as number when they should have been bigint. At runtime these were bigint because of a bug.\n\n    At runtime all numeric fields in `RpcSimulateTransactionResult` were a bigint, but those typed as number are now correct.\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/rpc-spec-types@5.4.0\n    - @solana/nominal-types@5.4.0\n    - @solana/functional@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n    - @solana/functional@5.3.0\n    - @solana/nominal-types@5.3.0\n    - @solana/rpc-spec-types@5.3.0\n    - @solana/rpc-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/functional@5.2.0\n    - @solana/nominal-types@5.2.0\n    - @solana/rpc-spec-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/functional@5.1.0\n    - @solana/nominal-types@5.1.0\n    - @solana/rpc-spec-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/functional@5.0.0\n    - @solana/nominal-types@5.0.0\n    - @solana/rpc-spec-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/functional@4.0.0\n    - @solana/nominal-types@4.0.0\n    - @solana/rpc-spec-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`81c83b1`](https://github.com/anza-xyz/kit/commit/81c83b12dd0e145bf7d08182e01824f2f14e5ee5)]:\n    - @solana/errors@3.0.0\n    - @solana/rpc-spec-types@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/functional@3.0.0\n    - @solana/nominal-types@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/functional@2.3.0\n    - @solana/nominal-types@2.3.0\n    - @solana/rpc-spec-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.1\n    - @solana/functional@2.2.1\n    - @solana/nominal-types@2.2.1\n    - @solana/rpc-spec-types@2.2.1\n    - @solana/rpc-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/nominal-types@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/functional@2.2.0\n    - @solana/rpc-spec-types@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#353](https://github.com/anza-xyz/kit/pull/353) [`7e7b2ef`](https://github.com/anza-xyz/kit/commit/7e7b2efebfd8de431e4381cc3d3fa117d3228030) Thanks [@steveluscher](https://github.com/steveluscher)! - Removed `OPTIONS_OBJECT_POSITION_BY_METHOD`, `downcastNodeToNumberIfBigint()`, `applyDefaultCommitment()`, `getIntegerOverflowNodeVisitor()`, `getBigIntUpcastVisitor()`, and `getTreeWalker()` from the exports of `@solana/rpc-transformer`\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-spec-types@2.1.1\n    - @solana/nominal-types@2.1.1\n    - @solana/functional@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/functional@2.1.0\n    - @solana/rpc-spec-types@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Change first argument of `onIntegerOverflow` handler from `methodName: string` to `request: RpcRequest`\n\n- [#3163](https://github.com/solana-labs/solana-web3.js/pull/3163) [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `getThrowSolanaErrorResponseTransformer`, `getResultResponseTransformer`, `getBigIntUpcastResponseTransformer` and `getTreeWalkerResponseTransformer` helpers\n\n- [#2950](https://github.com/solana-labs/solana-web3.js/pull/2950) [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor rpc-spec to remove requirement for transports to implement parts of JSON RPC spec\n\n- [#3150](https://github.com/solana-labs/solana-web3.js/pull/3150) [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcApi` use new `RpcRequestTransformer` and `RpcResponseTransformer`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `getIntegerOverflowRequestTransformer`, `getBigIntDowncastRequestTransformer` and `getTreeWalkerRequestTransformer` helpers\n\n- [#3159](https://github.com/solana-labs/solana-web3.js/pull/3159) [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `getDefaultCommitmentRequestTransformer` helper\n\n- [#3184](https://github.com/solana-labs/solana-web3.js/pull/3184) [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove temporary fix for Agave issue 479\n\n    The fix is now deployed on mainnet-beta (See https://github.com/anza-xyz/agave/issues/479 and https://github.com/anza-xyz/agave/pull/483).\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#2415](https://github.com/solana-labs/solana-web3.js/pull/2415) [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4) Thanks [@steveluscher](https://github.com/steveluscher)! - Improve transaction sending reliability for those who skip preflight (simulation) when calling `sendTransaction`\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/errors@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/rpc-spec-types@2.0.0\n    - @solana/functional@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/functional@2.0.0-rc.4\n    - @solana/rpc-spec-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-spec-types@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/functional@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Change first argument of `onIntegerOverflow` handler from `methodName: string` to `request: RpcRequest`\n\n- [#3163](https://github.com/solana-labs/solana-web3.js/pull/3163) [`29d5113`](https://github.com/solana-labs/solana-web3.js/commit/29d5113b2c6f8c7907127ad992bad1329edbd7e7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `getThrowSolanaErrorResponseTransformer`, `getResultResponseTransformer`, `getBigIntUpcastResponseTransformer` and `getTreeWalkerResponseTransformer` helpers\n\n- [#3150](https://github.com/solana-labs/solana-web3.js/pull/3150) [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcApi` use new `RpcRequestTransformer` and `RpcResponseTransformer`\n\n- [#3161](https://github.com/solana-labs/solana-web3.js/pull/3161) [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `getIntegerOverflowRequestTransformer`, `getBigIntDowncastRequestTransformer` and `getTreeWalkerRequestTransformer` helpers\n\n- [#3159](https://github.com/solana-labs/solana-web3.js/pull/3159) [`747b9ab`](https://github.com/solana-labs/solana-web3.js/commit/747b9abb90c6baeec73a284d87a324bf3caeab03) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `getDefaultCommitmentRequestTransformer` helper\n\n- [#3184](https://github.com/solana-labs/solana-web3.js/pull/3184) [`28ca5d1`](https://github.com/solana-labs/solana-web3.js/commit/28ca5d17d4c574a690a5bf29d4f1fe0ad8f5883c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove temporary fix for Agave issue 479\n\n    The fix is now deployed on mainnet-beta (See https://github.com/anza-xyz/agave/issues/479 and https://github.com/anza-xyz/agave/pull/483).\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/rpc-spec-types@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/functional@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.1\n    - @solana/functional@2.0.0-rc.1\n    - @solana/rpc-spec@2.0.0-rc.1\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2950](https://github.com/solana-labs/solana-web3.js/pull/2950) [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor rpc-spec to remove requirement for transports to implement parts of JSON RPC spec\n\n- Updated dependencies [[`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/rpc-spec@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/rpc-subscriptions-spec@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n    - @solana/functional@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597)]:\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.4\n    - @solana/functional@2.0.0-preview.4\n    - @solana/rpc-spec@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2415](https://github.com/solana-labs/solana-web3.js/pull/2415) [`c801637`](https://github.com/solana-labs/solana-web3.js/commit/c801637bcf94930be832c57817166da2d2fdb1a4) Thanks [@steveluscher](https://github.com/steveluscher)! - Improve transaction sending reliability for those who skip preflight (simulation) when calling `sendTransaction`\n\n- Updated dependencies [[`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83)]:\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/rpc-spec@2.0.0-preview.3\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.3\n    - @solana/functional@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/rpc-spec@2.0.0-preview.2\n    - @solana/rpc-subscriptions-spec@2.0.0-preview.2\n    - @solana/rpc-types@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-transformers/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-transformers/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-transformers?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-transformers?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-transformers\n\n# @solana/rpc-transformers\n\nThis package contains helpers for transforming Solana JSON RPC and RPC Subscriptions requests, responses, and notifications in various ways appropriate for use in a JavaScript application.\n\n## Request Transformers\n\n### `getDefaultRequestTransformerForSolanaRpc(config)`\n\nReturns the default request transformer for the Solana RPC API. Under the hood, this function composes multiple `RpcRequestTransformers` together such as the `getDefaultCommitmentTransformer`, the `getIntegerOverflowRequestTransformer` and the `getBigIntDowncastRequestTransformer`.\n\n```ts\nimport { getDefaultRequestTransformerForSolanaRpc } from '@solana/rpc-transformers';\n\nconst requestTransformer = getDefaultRequestTransformerForSolanaRpc({\n    defaultCommitment: 'confirmed',\n    onIntegerOverflow: (request, keyPath, value) => {\n        throw new Error(`Integer overflow at ${keyPath.join('.')}: ${value}`);\n    },\n});\n```\n\n### `getDefaultCommitmentRequestTransformer(config)`\n\nCreates a transformer that adds the provided default commitment to the configuration object of the request when applicable.\n\n```ts\nimport { getDefaultCommitmentRequestTransformer, OPTIONS_OBJECT_POSITION_BY_METHOD } from '@solana/rpc-transformers';\n\nconst requestTransformer = getDefaultCommitmentRequestTransformer({\n    defaultCommitment: 'confirmed',\n    optionsObjectPositionByMethod: OPTIONS_OBJECT_POSITION_BY_METHOD,\n});\n```\n\n### `getIntegerOverflowRequestTransformer(handler)`\n\nCreates a transformer that traverses the request parameters and executes the provided handler when an integer overflow is detected.\n\n```ts\nimport { getIntegerOverflowRequestTransformer } from '@solana/rpc-transformers';\n\nconst requestTransformer = getIntegerOverflowRequestTransformer((request, keyPath, value) => {\n    throw new Error(`Integer overflow at ${keyPath.join('.')}: ${value}`);\n});\n```\n\n### `getBigIntDowncastRequestTransformer()`\n\nCreates a transformer that downcasts all `BigInt` values to `Number`.\n\n```ts\nimport { getBigIntDowncastRequestTransformer } from '@solana/rpc-transformers';\n\nconst requestTransformer = getBigIntDowncastRequestTransformer();\n```\n\n### `getTreeWalkerRequestTransformer(visitors, initialState)`\n\nCreates a transformer that traverses the request parameters and executes the provided visitors at each node. A custom initial state can be provided but must at least provide `{ keyPath: [] }`.\n\n```ts\nimport { getTreeWalkerRequestTransformer } from '@solana/rpc-transformers';\n\nconst requestTransformer = getTreeWalkerRequestTransformer(\n    [\n        // Replaces foo.bar with \"baz\".\n        (node, state) => (state.keyPath === ['foo', 'bar'] ? 'baz' : node),\n        // Increments all numbers by 1.\n        node => (typeof node === number ? node + 1 : node),\n    ],\n    { keyPath: [] },\n);\n```\n\n## Response Transformers\n\n### `getDefaultResponseTransformerForSolanaRpc(config)`\n\nReturns the default response transformer for the Solana RPC API. Under the hood, this function composes multiple `RpcResponseTransformers` together such as the `getThrowSolanaErrorResponseTransformer`, the `getResultResponseTransformer` and the `getBigIntUpcastResponseTransformer`.\n\n```ts\nimport { getDefaultResponseTransformerForSolanaRpc } from '@solana/rpc-transformers';\n\nconst responseTransformer = getDefaultResponseTransformerForSolanaRpc({\n    allowedNumericKeyPaths: getAllowedNumericKeypaths(),\n});\n```\n\n### `getThrowSolanaErrorResponseTransformer()`\n\nReturns a transformer that throws a `SolanaError` with the appropriate RPC error code if the body of the RPC response contains an error.\n\n```ts\nimport { getThrowSolanaErrorResponseTransformer } from '@solana/rpc-transformers';\n\nconst responseTransformer = getThrowSolanaErrorResponseTransformer();\n```\n\n### `getResultResponseTransformer()`\n\nReturns a transformer that extracts the `result` field from the body of the RPC response. For instance, we go from `{ jsonrpc: '2.0', result: 'foo', id: 1 }` to `'foo'`.\n\n```ts\nimport { getResultResponseTransformer } from '@solana/rpc-transformers';\n\nconst responseTransformer = getResultResponseTransformer();\n```\n\n### `getBigIntUpcastResponseTransformer(allowedNumericKeyPaths)`\n\nReturns a transformer that upcasts all `Number` values to `BigInts` unless they match within the provided `KeyPaths`. In other words, the provided `KeyPaths` will remain as `Number` values, any other numeric value will be upcasted to a `BigInt`. Note that you can use `KEYPATH_WILDCARD` to match any key within a `KeyPath`.\n\n```ts\nimport { getBigIntUpcastResponseTransformer } from '@solana/rpc-transformers';\n\nconst responseTransformer = getBigIntUpcastResponseTransformer([\n    ['index'],\n    ['instructions', KEYPATH_WILDCARD, 'accounts', KEYPATH_WILDCARD],\n    ['instructions', KEYPATH_WILDCARD, 'programIdIndex'],\n    ['instructions', KEYPATH_WILDCARD, 'stackHeight'],\n]);\n```\n\n### `getTreeWalkerResponseTransformer(visitors, initialState)`\n\nCreates a transformer that traverses the json response and executes the provided visitors at each node. A custom initial state can be provided but must at least provide `{ keyPath: [] }`.\n\n```ts\nimport { getTreeWalkerResponseTransformer } from '@solana/rpc-transformers';\n\nconst responseTransformer = getTreeWalkerResponseTransformer(\n    [\n        // Replaces foo.bar with \"baz\".\n        (node, state) => (state.keyPath === ['foo', 'bar'] ? 'baz' : node),\n        // Increments all numbers by 1.\n        node => (typeof node === number ? node + 1 : node),\n    ],\n    { keyPath: [] },\n);\n```\n"
  },
  {
    "path": "packages/rpc-transformers/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-transformers\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Reusable transformers for patching RPC inputs and outputs\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-transformers\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/functional\": \"workspace:*\",\n        \"@solana/nominal-types\": \"workspace:*\",\n        \"@solana/rpc-spec-types\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-transformers/src/__tests__/request-transformer-bigint-downcast-test.ts",
    "content": "import { downcastNodeToNumberIfBigint } from '../request-transformer-bigint-downcast-internal';\n\ndescribe('bigint downcast visitor', () => {\n    it.each([10, '10', null, undefined, Symbol()])('returns the value `%p` as-is', value => {\n        expect(downcastNodeToNumberIfBigint(value)).toBe(value);\n    });\n    describe('given a `bigint` as input', () => {\n        const input = 10n;\n        it('casts the input to a `number`', () => {\n            expect(downcastNodeToNumberIfBigint(input)).toBe(Number(input));\n        });\n    });\n    describe('given a `bigint` two larger than `Number.MAX_SAFE_INTEGER` as input', () => {\n        const input = BigInt(Number.MAX_SAFE_INTEGER) + 2n; // 9007199254740993\n        it('casts the input to a `number`', () => {\n            expect(input - BigInt(downcastNodeToNumberIfBigint(input)))\n                // Incorrectly rounds to 9007199254740992, leaving a difference of 1.\n                .toBe(1n);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transformers/src/__tests__/request-transformer-default-commitment-test.ts",
    "content": "import type { Commitment } from '@solana/rpc-types';\n\nimport { applyDefaultCommitment } from '../request-transformer-default-commitment-internal';\n\nconst MOCK_COMMITMENT_PROPERTY_NAME = 'commitmentProperty';\n\ndescribe('applyDefaultCommitment', () => {\n    describe.each([0, 1, 2])('in relation to a method whose commitment config is argument #%s', expectedPosition => {\n        it('adds the default commitment when absent from the call', () => {\n            expect.assertions(1);\n            expect(\n                applyDefaultCommitment({\n                    commitmentPropertyName: MOCK_COMMITMENT_PROPERTY_NAME,\n                    optionsObjectPositionInParams: expectedPosition,\n                    overrideCommitment: 'processed',\n                    params: [],\n                }),\n            ).toEqual([\n                ...new Array(expectedPosition).map(() => expect.anything()),\n                { [MOCK_COMMITMENT_PROPERTY_NAME]: 'processed' },\n            ]);\n        });\n        describe.each(['confirmed', 'finalized', 'processed'] as Commitment[])(\n            'when the default commitment is set to `%s`',\n            defaultCommitment => {\n                describe.each(['confirmed', 'processed'])(\n                    'and the params already specify a commitment of `%s`',\n                    existingCommitment => {\n                        it('does not overwrite it', () => {\n                            const params = [\n                                ...new Array(expectedPosition),\n                                { [MOCK_COMMITMENT_PROPERTY_NAME]: existingCommitment },\n                            ];\n                            expect(\n                                applyDefaultCommitment({\n                                    commitmentPropertyName: MOCK_COMMITMENT_PROPERTY_NAME,\n                                    optionsObjectPositionInParams: expectedPosition,\n                                    overrideCommitment: defaultCommitment,\n                                    params,\n                                }),\n                            ).toBe(params);\n                        });\n                    },\n                );\n                describe.each(['finalized', undefined])(\n                    'and the params already specify a commitment of `%s`',\n                    existingCommitment => {\n                        it('removes the commitment property when there are other properties in the config object', () => {\n                            expect.assertions(1);\n                            const params = [\n                                ...new Array(expectedPosition),\n                                { [MOCK_COMMITMENT_PROPERTY_NAME]: existingCommitment, other: 'property' },\n                            ];\n                            expect(\n                                applyDefaultCommitment({\n                                    commitmentPropertyName: MOCK_COMMITMENT_PROPERTY_NAME,\n                                    optionsObjectPositionInParams: expectedPosition,\n                                    overrideCommitment: defaultCommitment,\n                                    params,\n                                }),\n                            ).toStrictEqual([\n                                ...new Array(expectedPosition).map(() => expect.anything()),\n                                { other: 'property' },\n                            ]);\n                        });\n                        it('sets the config object to `undefined` when there are no other properties left and the config object is not the last param', () => {\n                            expect.assertions(1);\n                            const params = [\n                                ...new Array(expectedPosition),\n                                { [MOCK_COMMITMENT_PROPERTY_NAME]: existingCommitment },\n                                'someParam',\n                            ];\n                            expect(\n                                applyDefaultCommitment({\n                                    commitmentPropertyName: MOCK_COMMITMENT_PROPERTY_NAME,\n                                    optionsObjectPositionInParams: expectedPosition,\n                                    overrideCommitment: defaultCommitment,\n                                    params,\n                                }),\n                            ).toStrictEqual([\n                                ...new Array(expectedPosition).map(() => expect.anything()),\n                                undefined,\n                                'someParam',\n                            ]);\n                        });\n                        it('truncates the params when there are no other properties left and the config object is the last param', () => {\n                            expect.assertions(1);\n                            const params = [\n                                ...new Array(expectedPosition),\n                                { [MOCK_COMMITMENT_PROPERTY_NAME]: existingCommitment },\n                            ];\n                            expect(\n                                applyDefaultCommitment({\n                                    commitmentPropertyName: MOCK_COMMITMENT_PROPERTY_NAME,\n                                    optionsObjectPositionInParams: expectedPosition,\n                                    overrideCommitment: defaultCommitment,\n                                    params,\n                                }),\n                            ).toStrictEqual([...new Array(expectedPosition).map(() => expect.anything())]);\n                        });\n                    },\n                );\n            },\n        );\n        it.each([null, 1, '1', 1n, [1, 2, 3]])(\n            \"does not overwrite the existing param when it's a non-object like `%s`\",\n            paramInConfigPosition => {\n                expect.assertions(1);\n                const params = [...new Array(expectedPosition), paramInConfigPosition];\n                expect(\n                    applyDefaultCommitment({\n                        commitmentPropertyName: MOCK_COMMITMENT_PROPERTY_NAME,\n                        optionsObjectPositionInParams: expectedPosition,\n                        overrideCommitment: 'processed',\n                        params,\n                    }),\n                ).toBe(params);\n            },\n        );\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transformers/src/__tests__/request-transformer-integer-overflow-test.ts",
    "content": "import { getIntegerOverflowNodeVisitor } from '../request-transformer-integer-overflow-internal';\nimport { TraversalState } from '../tree-traversal';\n\nconst MOCK_TRAVERSAL_STATE = {\n    keyPath: [1, 'foo', 'bar'],\n};\n\ndescribe('integer overflow visitor', () => {\n    let onIntegerOverflow: jest.Mock;\n    let visitNode: <T>(value: T, state: TraversalState) => T;\n    beforeEach(() => {\n        onIntegerOverflow = jest.fn().mockImplementation(([_, v]) => v);\n        visitNode = getIntegerOverflowNodeVisitor(onIntegerOverflow);\n    });\n    it.each([10, 10n, '10', null, undefined, Symbol()])('returns the value `%p` as-is', value => {\n        expect(visitNode(value, MOCK_TRAVERSAL_STATE)).toBe(value);\n    });\n    describe.each([\n        ['value above `Number.MAX_SAFE_INTEGER`', BigInt(Number.MAX_SAFE_INTEGER) + 1n],\n        ['value below `Number.MAX_SAFE_INTEGER`', -BigInt(Number.MAX_SAFE_INTEGER) - 1n],\n    ])('when passed a %s', (_, value) => {\n        it('calls `onIntegerOverflow` with the key path and the value', () => {\n            visitNode(value, MOCK_TRAVERSAL_STATE);\n            expect(onIntegerOverflow).toHaveBeenCalledWith(MOCK_TRAVERSAL_STATE.keyPath, value);\n        });\n    });\n    it('does not call `onIntegerOverflow` when passed `Number.MAX_SAFE_INTEGER`', () => {\n        visitNode(BigInt(Number.MAX_SAFE_INTEGER), MOCK_TRAVERSAL_STATE);\n        expect(onIntegerOverflow).not.toHaveBeenCalled();\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transformers/src/__tests__/request-transformer-test.ts",
    "content": "import type { RpcRequestTransformer } from '@solana/rpc-spec-types';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { getDefaultRequestTransformerForSolanaRpc } from '../request-transformer';\nimport { OPTIONS_OBJECT_POSITION_BY_METHOD } from '../request-transformer-options-object-position-config';\n\ndescribe('getDefaultRequestTransformerForSolanaRpc', () => {\n    describe('given no config', () => {\n        let createRequest: (params: unknown) => { methodName: 'getFoo'; params: unknown };\n        let requestTransformer: RpcRequestTransformer;\n        beforeEach(() => {\n            createRequest = params => ({ methodName: 'getFoo', params });\n            requestTransformer = getDefaultRequestTransformerForSolanaRpc();\n        });\n        describe('given an array as input', () => {\n            const input = [10n, 10, '10', ['10', [10, 10n], 10n]] as const;\n            it('casts the bigints in the array to a `number`, recursively', () => {\n                const request = createRequest(input);\n                expect(requestTransformer(request).params).toStrictEqual([\n                    Number(input[0]),\n                    input[1],\n                    input[2],\n                    [input[3][0], [input[3][1][0], Number(input[3][1][0])], Number(input[3][2])],\n                ]);\n            });\n        });\n        describe('given an object as input', () => {\n            const input = { a: 10n, b: 10, c: { c1: '10', c2: 10n } } as const;\n            it('casts the bigints in the array to a `number`, recursively', () => {\n                const request = createRequest(input);\n                expect(requestTransformer(request).params).toStrictEqual({\n                    a: Number(input.a),\n                    b: input.b,\n                    c: { c1: input.c.c1, c2: Number(input.c.c2) },\n                });\n            });\n        });\n    });\n    describe('with respect to the default commitment', () => {\n        const METHODS_SUBJECT_TO_COMMITMENT_DEFAULTING = [\n            'accountNotifications',\n            'blockNotifications',\n            'getAccountInfo',\n            'getBalance',\n            'getBlock',\n            'getBlockHeight',\n            'getBlockProduction',\n            'getBlocks',\n            'getBlocksWithLimit',\n            'getEpochInfo',\n            'getFeeForMessage',\n            'getInflationGovernor',\n            'getInflationReward',\n            'getLargestAccounts',\n            'getLatestBlockhash',\n            'getLeaderSchedule',\n            'getMinimumBalanceForRentExemption',\n            'getMultipleAccounts',\n            'getProgramAccounts',\n            'getSignaturesForAddress',\n            'getSlot',\n            'getSlotLeader',\n            'getStakeMinimumDelegation',\n            'getSupply',\n            'getTokenAccountBalance',\n            'getTokenAccountsByDelegate',\n            'getTokenAccountsByOwner',\n            'getTokenLargestAccounts',\n            'getTokenSupply',\n            'getTransaction',\n            'getTransactionCount',\n            'getVoteAccounts',\n            'isBlockhashValid',\n            'logsNotifications',\n            'programNotifications',\n            'requestAirdrop',\n            'signatureNotifications',\n            'simulateTransaction',\n        ];\n        describe.each(['processed', 'confirmed'] as Commitment[])(\n            'with the default commitment set to `%s`',\n            defaultCommitment => {\n                let requestTransformer: RpcRequestTransformer;\n                beforeEach(() => {\n                    requestTransformer = getDefaultRequestTransformerForSolanaRpc({ defaultCommitment });\n                });\n                it.each(METHODS_SUBJECT_TO_COMMITMENT_DEFAULTING)(\n                    'adds a default commitment on calls for `%s`',\n                    methodName => {\n                        expect(requestTransformer({ methodName, params: [] }).params).toContainEqual({\n                            commitment: defaultCommitment,\n                        });\n                    },\n                );\n                it('adds a default preflight commitment on calls to `sendTransaction`', () => {\n                    expect(requestTransformer({ methodName: 'sendTransaction', params: [] }).params).toContainEqual({\n                        preflightCommitment: defaultCommitment,\n                    });\n                });\n            },\n        );\n        describe('with the default commitment set to `finalized`', () => {\n            let requestTransformer: RpcRequestTransformer;\n            beforeEach(() => {\n                requestTransformer = getDefaultRequestTransformerForSolanaRpc({ defaultCommitment: 'finalized' });\n            });\n            it.each(METHODS_SUBJECT_TO_COMMITMENT_DEFAULTING)('adds no commitment on calls for `%s`', methodName => {\n                expect(requestTransformer({ methodName, params: [] }).params).not.toContainEqual(\n                    expect.objectContaining({ commitment: expect.anything() }),\n                );\n            });\n            it('adds no preflight commitment on calls to `sendTransaction`', () => {\n                expect(requestTransformer({ methodName: 'sendTransaction', params: [] }).params).not.toContainEqual(\n                    expect.objectContaining({ preflightCommitment: expect.anything() }),\n                );\n            });\n        });\n        describe('with no default commitment set', () => {\n            let requestTransformer: RpcRequestTransformer;\n            beforeEach(() => {\n                requestTransformer = getDefaultRequestTransformerForSolanaRpc();\n            });\n            it.each(METHODS_SUBJECT_TO_COMMITMENT_DEFAULTING)('sets no commitment on calls to `%s`', methodName => {\n                expect(requestTransformer({ methodName, params: [] }).params).not.toContainEqual(\n                    expect.objectContaining({ commitment: expect.anything() }),\n                );\n            });\n            it('adds no preflight commitment on calls to `sendTransaction`', () => {\n                expect(requestTransformer({ methodName: 'sendTransaction', params: [] }).params).not.toContainEqual(\n                    expect.objectContaining({ preflightCommitment: expect.anything() }),\n                );\n            });\n        });\n        describe.each(['finalized', undefined])(\n            'when the params already specify a commitment of `%s`',\n            existingCommitment => {\n                describe.each(METHODS_SUBJECT_TO_COMMITMENT_DEFAULTING)('on calls to `%s`', methodName => {\n                    const optionsObjectPosition = OPTIONS_OBJECT_POSITION_BY_METHOD[methodName];\n                    it('removes the commitment property on calls to `%s` when there are other properties in the config object', () => {\n                        expect.assertions(1);\n                        const params = [\n                            ...new Array(optionsObjectPosition),\n                            { commitment: existingCommitment, other: 'property' },\n                        ];\n                        const requestTransformer = getDefaultRequestTransformerForSolanaRpc();\n                        expect(requestTransformer({ methodName, params }).params).toStrictEqual([\n                            ...new Array(optionsObjectPosition).map(() => expect.anything()),\n                            { other: 'property' },\n                        ]);\n                    });\n                    it('deletes the commitment on calls to `%s` when there are no other properties left and the config object is not the last param', () => {\n                        expect.assertions(1);\n                        const params = [\n                            ...new Array(optionsObjectPosition),\n                            { commitment: existingCommitment },\n                            'someParam',\n                        ];\n                        const requestTransformer = getDefaultRequestTransformerForSolanaRpc();\n                        expect(requestTransformer({ methodName, params }).params).toStrictEqual([\n                            ...new Array(optionsObjectPosition).map(() => expect.anything()),\n                            undefined,\n                            'someParam',\n                        ]);\n                    });\n                    it('truncates the params on calls to `%s` when there are no other properties left and the config object is the last param', () => {\n                        expect.assertions(1);\n                        const params = [...new Array(optionsObjectPosition), { commitment: existingCommitment }];\n                        const requestTransformer = getDefaultRequestTransformerForSolanaRpc();\n                        expect(requestTransformer({ methodName, params }).params).toStrictEqual([\n                            ...new Array(optionsObjectPosition).map(() => expect.anything()),\n                        ]);\n                    });\n                });\n                it('removes the preflight commitment property on calls to `%s` when there are other properties in the config object', () => {\n                    expect.assertions(1);\n                    const optionsObjectPosition = OPTIONS_OBJECT_POSITION_BY_METHOD['sendTransaction'];\n                    const params = [\n                        ...new Array(optionsObjectPosition),\n                        { other: 'property', preflightCommitment: existingCommitment },\n                    ];\n                    const requestTransformer = getDefaultRequestTransformerForSolanaRpc();\n                    expect(requestTransformer({ methodName: 'sendTransaction', params }).params).toStrictEqual([\n                        ...new Array(optionsObjectPosition).map(() => expect.anything()),\n                        { other: 'property' },\n                    ]);\n                });\n                it('deletes the preflight commitment on calls to `%s` when there are no other properties left and the config object is not the last param', () => {\n                    expect.assertions(1);\n                    const optionsObjectPosition = OPTIONS_OBJECT_POSITION_BY_METHOD['sendTransaction'];\n                    const params = [\n                        ...new Array(optionsObjectPosition),\n                        { preflightCommitment: existingCommitment },\n                        'someParam',\n                    ];\n                    const requestTransformer = getDefaultRequestTransformerForSolanaRpc();\n                    expect(requestTransformer({ methodName: 'sendTransaction', params }).params).toStrictEqual([\n                        ...new Array(optionsObjectPosition).map(() => expect.anything()),\n                        undefined,\n                        'someParam',\n                    ]);\n                });\n                it('truncates the params on calls to `%s` when there are no other properties left and the config object is the last param', () => {\n                    expect.assertions(1);\n                    const optionsObjectPosition = OPTIONS_OBJECT_POSITION_BY_METHOD['sendTransaction'];\n                    const params = [...new Array(optionsObjectPosition), { preflightCommitment: existingCommitment }];\n                    const requestTransformer = getDefaultRequestTransformerForSolanaRpc();\n                    expect(requestTransformer({ methodName: 'sendTransaction', params }).params).toStrictEqual([\n                        ...new Array(optionsObjectPosition).map(() => expect.anything()),\n                    ]);\n                });\n            },\n        );\n    });\n    describe('given an integer overflow handler', () => {\n        let onIntegerOverflow: jest.Mock;\n        let requestTransformer: RpcRequestTransformer;\n        let createRequest = (params: unknown) => ({ methodName: 'getFoo', params });\n        beforeEach(() => {\n            onIntegerOverflow = jest.fn();\n            requestTransformer = getDefaultRequestTransformerForSolanaRpc({ onIntegerOverflow });\n            createRequest = params => ({ methodName: 'getFoo', params });\n        });\n        Object.entries({\n            'value above `Number.MAX_SAFE_INTEGER`': BigInt(Number.MAX_SAFE_INTEGER) + 1n,\n            'value below `Number.MAX_SAFE_INTEGER`': -BigInt(Number.MAX_SAFE_INTEGER) - 1n,\n        }).forEach(([description, value]) => {\n            it('calls `onIntegerOverflow` when passed a value ' + description, () => {\n                const request = createRequest(value);\n                requestTransformer(request);\n                expect(onIntegerOverflow).toHaveBeenCalledWith(\n                    request,\n                    [], // Equivalent to `params`\n                    value,\n                );\n            });\n            it('calls `onIntegerOverflow` when passed a nested array having a value ' + description, () => {\n                const request = createRequest([1, 2, [3, value]]);\n                requestTransformer(request);\n                expect(onIntegerOverflow).toHaveBeenCalledWith(\n                    request,\n                    [2, 1], // Equivalent to `params[2][1]`.\n                    value,\n                );\n            });\n            it('calls `onIntegerOverflow` when passed a nested object having a value ' + description, () => {\n                const request = createRequest({ a: 1, b: { b1: 2, b2: value } });\n                requestTransformer(request);\n                expect(onIntegerOverflow).toHaveBeenCalledWith(\n                    request,\n                    ['b', 'b2'], // Equivalent to `params.b.b2`.\n                    value,\n                );\n            });\n            it('does not call `onIntegerOverflow` when passed `Number.MAX_SAFE_INTEGER`', () => {\n                const request = createRequest(BigInt(Number.MAX_SAFE_INTEGER));\n                requestTransformer(request);\n                expect(onIntegerOverflow).not.toHaveBeenCalled();\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transformers/src/__tests__/response-transformer-bigint-upcast-test.ts",
    "content": "import { getBigIntUpcastVisitor } from '../response-transformer-bigint-upcast-internal';\nimport { TraversalState } from '../tree-traversal';\n\nconst MOCK_TRAVERSAL_STATE = {\n    keyPath: [],\n};\n\ndescribe('bigint upcast visitor', () => {\n    describe('given no allowed numeric keypaths', () => {\n        let visitNode: (value: unknown, state: TraversalState) => unknown;\n        beforeEach(() => {\n            visitNode = getBigIntUpcastVisitor([]);\n        });\n        it.each([10n, '10', null, undefined, Symbol()])('returns the value `%p` as-is', value => {\n            expect(visitNode(value, MOCK_TRAVERSAL_STATE)).toBe(value);\n        });\n        describe('given a `number` as input', () => {\n            const input = 10;\n            it('casts the input to a `bigint`', () => {\n                expect(visitNode(input, MOCK_TRAVERSAL_STATE)).toBe(BigInt(input));\n            });\n        });\n        describe('given a non-integer `number` as input', () => {\n            const input = 10.5;\n            it('returns the value as-is', () => {\n                expect(visitNode(input, MOCK_TRAVERSAL_STATE)).toBe(input);\n            });\n        });\n    });\n    describe('given an allowed numeric keypath', () => {\n        let visitNode: (value: unknown, state: TraversalState) => unknown;\n        beforeEach(() => {\n            visitNode = getBigIntUpcastVisitor([[0, 1, 2]]);\n        });\n        it('casts the input to a `bigint` when the key path does not match', () => {\n            expect(visitNode(10, { keyPath: [0, 1, 3] })).toBe(BigInt(10));\n        });\n        it('does not cast the input to a `bigint` when the key path matches', () => {\n            expect(visitNode(10, { keyPath: [0, 1, 2] })).toBe(10);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transformers/src/__tests__/response-transformer-test.ts",
    "content": "import { SOLANA_ERROR__JSON_RPC__PARSE_ERROR, SolanaError } from '@solana/errors';\nimport { RpcRequest } from '@solana/rpc-spec-types';\n\nimport { getDefaultResponseTransformerForSolanaRpc } from '../response-transformer';\nimport { KEYPATH_WILDCARD } from '../tree-traversal';\n\ndescribe('getDefaultResponseTransformerForSolanaRpc', () => {\n    describe('given an array as input', () => {\n        const input = [10, 10n, '10', ['10', [10n, 10], 10]] as const;\n        const request = {} as RpcRequest;\n        const response = { result: input };\n        it('casts the numbers in the array to a `bigint`, recursively', () => {\n            const transformer = getDefaultResponseTransformerForSolanaRpc();\n            expect(transformer(response, request)).toStrictEqual([\n                BigInt(input[0]),\n                input[1],\n                input[2],\n                [input[3][0], [input[3][1][0], BigInt(input[3][1][0])], BigInt(input[3][2])],\n            ]);\n        });\n    });\n    describe('given an object as input', () => {\n        const input = { a: 10, b: 10n, c: { c1: '10', c2: 10 } } as const;\n        const request = {} as RpcRequest;\n        const response = { result: input };\n\n        it('casts the numbers in the object to `bigints`, recursively', () => {\n            const transformer = getDefaultResponseTransformerForSolanaRpc();\n            expect(transformer(response, request)).toStrictEqual({\n                a: BigInt(input.a),\n                b: input.b,\n                c: { c1: input.c.c1, c2: BigInt(input.c.c2) },\n            });\n        });\n    });\n    describe('where allowlisted numeric values are concerned', () => {\n        it.each`\n            description                                          | allowedKeyPaths                                      | expectation                                                         | input\n            ${'nested array of numeric responses'}               | ${[[0], [1, 1], [1, 2, 1]]}                          | ${[10, [10n, 10, [10n, 10]]]}                                       | ${[10, [10, 10, [10, 10]]]}\n            ${'nested array of numeric responses with wildcard'} | ${[[KEYPATH_WILDCARD], [2, KEYPATH_WILDCARD]]}       | ${[1, [2n], [3, 33, 333], 4]}                                       | ${[1, [2], [3, 33, 333], 4]}\n            ${'nested array of objects with numeric responses'}  | ${[['a', 'b', KEYPATH_WILDCARD, 'c']]}               | ${{ a: { b: [{ c: 5, d: 5n }, { c: 10, d: 10n }] } }}               | ${{ a: { b: [{ c: 5, d: 5 }, { c: 10, d: 10 }] } }}\n            ${'nested object of numeric responses'}              | ${[['a'], ['b', 'b2', 'b2_1'], ['b', 'b2', 'b2_3']]} | ${{ a: 10, b: { b1: 10n, b2: { b2_1: 10, b2_2: 10n, b2_3: 10 } } }} | ${{ a: 10, b: { b1: 10, b2: { b2_1: 10, b2_2: 10, b2_3: 10 } } }}\n            ${'numeric response'}                                | ${[[]]}                                              | ${10}                                                               | ${10}\n        `(\n            'performs no `bigint` upcasts on $description when the allowlist is of the form in test case $#',\n            ({ allowedKeyPaths, expectation, input }) => {\n                const transformer = getDefaultResponseTransformerForSolanaRpc({\n                    allowedNumericKeyPaths: { getFoo: allowedKeyPaths },\n                });\n                const request = { methodName: 'getFoo' } as RpcRequest;\n                const response = { result: input };\n                expect(transformer(response, request)).toStrictEqual(expectation);\n            },\n        );\n    });\n    describe('given a JSON RPC error as input', () => {\n        const request = {} as RpcRequest;\n        const response = {\n            error: { code: SOLANA_ERROR__JSON_RPC__PARSE_ERROR, message: 'o no' },\n        };\n\n        it('throws it as a SolanaError', () => {\n            const transformer = getDefaultResponseTransformerForSolanaRpc();\n            expect(() => transformer(response, request)).toThrow(\n                new SolanaError(SOLANA_ERROR__JSON_RPC__PARSE_ERROR, { __serverMessage: 'o no' }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transformers/src/__tests__/response-transformer-throw-solana-error-test.ts",
    "content": "import { getSolanaErrorFromJsonRpcError } from '@solana/errors';\nimport { RpcRequest } from '@solana/rpc-spec-types';\n\nimport { getThrowSolanaErrorResponseTransformer } from '../response-transformer-throw-solana-error';\n\njest.mock('@solana/errors', () => ({\n    ...jest.requireActual('@solana/errors'),\n    getSolanaErrorFromJsonRpcError: jest.fn(),\n}));\n\ndescribe('getThrowSolanaErrorResponseTransformer', () => {\n    let mockGetSolanaErrorFromJsonRpcError: jest.Mock;\n    const request = { methodName: 'getBalance' } as RpcRequest;\n\n    beforeEach(() => {\n        mockGetSolanaErrorFromJsonRpcError = getSolanaErrorFromJsonRpcError as jest.Mock;\n        mockGetSolanaErrorFromJsonRpcError.mockClear();\n    });\n\n    describe('when the response contains a result', () => {\n        it('returns the response as-is', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const response = { result: { value: 123n } };\n\n            const result = transformer(response, request);\n\n            expect(result).toStrictEqual(response);\n            expect(mockGetSolanaErrorFromJsonRpcError).not.toHaveBeenCalled();\n        });\n\n        it('returns complex result objects unchanged', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const response = {\n                result: {\n                    context: { slot: 123n },\n                    value: [{ account: 'test', lamports: 456n }],\n                },\n            };\n\n            const result = transformer(response, request);\n\n            expect(result).toStrictEqual(response);\n            expect(mockGetSolanaErrorFromJsonRpcError).not.toHaveBeenCalled();\n        });\n    });\n\n    describe('when the response contains an error', () => {\n        it('throws a SolanaError for a standard RPC error', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Mock Solana Error');\n            const errorResponse = {\n                error: { code: -32600, message: 'Invalid Request' },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledWith(errorResponse.error);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledTimes(1);\n        });\n    });\n\n    describe('when the response contains a sendTransaction preflight failure (-32002)', () => {\n        it('transforms BigInt values in error.data before throwing for numeric error code', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Preflight failure');\n            const errorResponse = {\n                error: {\n                    code: -32002,\n                    data: {\n                        accounts: null,\n                        err: 'InsufficientFundsForRent',\n                        innerInstructions: null,\n                        loadedAccountsDataSize: 100n, // Should be downcast to number\n                        logs: ['log1', 'log2'],\n                        replacementBlockhash: null,\n                        returnData: null,\n                        unitsConsumed: 5000n, // Should remain as BigInt\n                    },\n                    message: 'Transaction simulation failed',\n                },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledTimes(1);\n\n            // Verify that the error was transformed before being passed\n            const transformedError = mockGetSolanaErrorFromJsonRpcError.mock.calls[0][0];\n            expect(transformedError).toHaveProperty('code', -32002);\n            expect(transformedError).toHaveProperty('data');\n            expect(transformedError.data).toHaveProperty('loadedAccountsDataSize', 100);\n            expect(transformedError.data).toHaveProperty('unitsConsumed', 5000n);\n        });\n\n        it('transforms BigInt values in error.data before throwing for bigint error code', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Preflight failure');\n            const errorResponse = {\n                error: {\n                    code: -32002n, // BigInt code\n                    data: {\n                        accounts: null,\n                        err: 'InsufficientFundsForRent',\n                        innerInstructions: null,\n                        loadedAccountsDataSize: 100n,\n                        logs: ['log1', 'log2'],\n                        replacementBlockhash: null,\n                        returnData: null,\n                        unitsConsumed: 5000n,\n                    },\n                    message: 'Transaction simulation failed',\n                },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledTimes(1);\n\n            // Verify that the error was transformed before being passed\n            const transformedError = mockGetSolanaErrorFromJsonRpcError.mock.calls[0][0];\n            expect(transformedError).toHaveProperty('code', -32002n);\n            expect(transformedError).toHaveProperty('data');\n            expect(transformedError.data).toHaveProperty('loadedAccountsDataSize', 100);\n            expect(transformedError.data).toHaveProperty('unitsConsumed', 5000n);\n        });\n\n        it('handles preflight failure with nested account data', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Preflight failure');\n            const errorResponse = {\n                error: {\n                    code: -32002,\n                    data: {\n                        accounts: [\n                            {\n                                data: ['base64data', 'base64'],\n                                executable: false,\n                                lamports: 1000000n, // Should remain as bigint\n                                owner: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',\n                                rentEpoch: 361n,\n                            },\n                        ],\n                    },\n                    message: 'Transaction simulation failed',\n                },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledTimes(1);\n\n            const transformedError = mockGetSolanaErrorFromJsonRpcError.mock.calls[0][0];\n            expect(transformedError).toHaveProperty('code', -32002);\n            expect(transformedError).toHaveProperty('data');\n            expect(transformedError.data).toHaveProperty('accounts');\n            const account = transformedError.data.accounts[0];\n            expect(account).toHaveProperty('lamports', 1000000n);\n            expect(account).toHaveProperty('rentEpoch', 361n);\n        });\n\n        it('handles preflight failure with nested inner instructions data', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Preflight failure');\n            const errorResponse = {\n                error: {\n                    code: -32002,\n                    data: {\n                        innerInstructions: [\n                            {\n                                index: 0n, // Should be downcast to number\n                                instructions: [\n                                    {\n                                        accounts: [0n, 1n], // Should be downcast to number\n                                        data: 'base64data',\n                                        programIdIndex: 2n, // Should be downcast to number\n                                        stackHeight: null,\n                                    },\n                                ],\n                            },\n                        ],\n                    },\n                    message: 'Transaction simulation failed',\n                },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledTimes(1);\n\n            const transformedError = mockGetSolanaErrorFromJsonRpcError.mock.calls[0][0];\n            expect(transformedError).toHaveProperty('code', -32002);\n            expect(transformedError).toHaveProperty('data');\n            expect(transformedError.data).toHaveProperty('innerInstructions');\n            const innerInstruction = transformedError.data.innerInstructions[0];\n            expect(innerInstruction).toHaveProperty('index', 0);\n            const instruction = innerInstruction.instructions[0];\n            expect(instruction).toHaveProperty('accounts', [0, 1]);\n            expect(instruction).toHaveProperty('programIdIndex', 2);\n        });\n\n        it('handles preflight failure without data field', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Preflight failure');\n            const errorResponse = {\n                error: {\n                    code: -32002,\n                    message: 'Transaction simulation failed',\n                },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledWith(errorResponse.error);\n        });\n\n        it('handles preflight failure with null data', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Preflight failure');\n            const errorResponse = {\n                error: {\n                    code: -32002,\n                    data: null,\n                    message: 'Transaction simulation failed',\n                },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledWith(errorResponse.error);\n        });\n    });\n\n    describe('edge cases', () => {\n        it('handles error without code property', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Malformed error');\n            const errorResponse = {\n                error: { message: 'Something went wrong' },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledWith(errorResponse.error);\n        });\n\n        it('handles null error', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Null error');\n            const errorResponse = {\n                error: null,\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledWith(null);\n        });\n\n        it('handles error code that is not -32002', () => {\n            const transformer = getThrowSolanaErrorResponseTransformer();\n            const mockError = new Error('Other error');\n            const errorResponse = {\n                error: {\n                    code: -32603,\n                    data: {\n                        someField: 100n,\n                    },\n                    message: 'Internal error',\n                },\n            };\n\n            mockGetSolanaErrorFromJsonRpcError.mockImplementation(() => {\n                throw mockError;\n            });\n\n            expect(() => transformer(errorResponse, request)).toThrow(mockError);\n            // Should not transform data for non-preflight errors\n            expect(mockGetSolanaErrorFromJsonRpcError).toHaveBeenCalledWith(errorResponse.error);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transformers/src/index.ts",
    "content": "/**\n * This package contains helpers for transforming Solana JSON RPC and RPC Subscriptions requests,\n * responses, and notifications in various ways appropriate for use in a JavaScript application.\n *\n * @packageDocumentation\n */\nexport * from './request-transformer';\nexport * from './request-transformer-bigint-downcast';\nexport * from './request-transformer-default-commitment';\nexport * from './request-transformer-integer-overflow';\nexport * from './response-transformer';\nexport * from './response-transformer-allowed-numeric-values';\nexport * from './response-transformer-bigint-upcast';\nexport * from './response-transformer-result';\nexport * from './response-transformer-throw-solana-error';\nexport * from './tree-traversal';\n"
  },
  {
    "path": "packages/rpc-transformers/src/request-transformer-bigint-downcast-internal.ts",
    "content": "export function downcastNodeToNumberIfBigint(value: bigint): number;\nexport function downcastNodeToNumberIfBigint<T>(value: T): T;\nexport function downcastNodeToNumberIfBigint(value: unknown): unknown {\n    return typeof value === 'bigint'\n        ? // FIXME(solana-labs/solana/issues/30341) Create a data type to represent u64 in the Solana\n          // JSON RPC implementation so that we can throw away this entire patcher instead of unsafely\n          // downcasting `bigints` to `numbers`.\n          Number(value)\n        : value;\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/request-transformer-bigint-downcast.ts",
    "content": "import { downcastNodeToNumberIfBigint } from './request-transformer-bigint-downcast-internal';\nimport { getTreeWalkerRequestTransformer } from './tree-traversal';\n\n/**\n * Creates a transformer that downcasts all `BigInt` values to `Number`.\n *\n * @example\n * ```ts\n * import { getBigIntDowncastRequestTransformer } from '@solana/rpc-transformers';\n *\n * const requestTransformer = getBigIntDowncastRequestTransformer();\n * ```\n *\n */\nexport function getBigIntDowncastRequestTransformer() {\n    return getTreeWalkerRequestTransformer([downcastNodeToNumberIfBigint], { keyPath: [] });\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/request-transformer-default-commitment-internal.ts",
    "content": "import { Commitment } from '@solana/rpc-types';\n\nexport function applyDefaultCommitment({\n    commitmentPropertyName,\n    params,\n    optionsObjectPositionInParams,\n    overrideCommitment,\n}: Readonly<{\n    commitmentPropertyName: string;\n    optionsObjectPositionInParams: number;\n    overrideCommitment?: Commitment;\n    params: unknown[];\n}>) {\n    const paramInTargetPosition = params[optionsObjectPositionInParams];\n    if (\n        // There's no config.\n        paramInTargetPosition === undefined ||\n        // There is a config object.\n        (paramInTargetPosition && typeof paramInTargetPosition === 'object' && !Array.isArray(paramInTargetPosition))\n    ) {\n        if (\n            // The config object already has a commitment set.\n            paramInTargetPosition &&\n            commitmentPropertyName in paramInTargetPosition\n        ) {\n            if (\n                !paramInTargetPosition[commitmentPropertyName as keyof typeof paramInTargetPosition] ||\n                paramInTargetPosition[commitmentPropertyName as keyof typeof paramInTargetPosition] === 'finalized'\n            ) {\n                // Delete the commitment property; `finalized` is already the server default.\n                const nextParams = [...params];\n                const {\n                    [commitmentPropertyName as keyof typeof paramInTargetPosition]: _, // eslint-disable-line @typescript-eslint/no-unused-vars\n                    ...rest\n                } = paramInTargetPosition;\n                if (Object.keys(rest).length > 0) {\n                    nextParams[optionsObjectPositionInParams] = rest;\n                } else {\n                    if (optionsObjectPositionInParams === nextParams.length - 1) {\n                        nextParams.length--;\n                    } else {\n                        nextParams[optionsObjectPositionInParams] = undefined;\n                    }\n                }\n                return nextParams;\n            }\n        } else if (overrideCommitment !== 'finalized') {\n            // Apply the default commitment.\n            const nextParams = [...params];\n            nextParams[optionsObjectPositionInParams] = {\n                ...paramInTargetPosition,\n                [commitmentPropertyName]: overrideCommitment,\n            };\n            return nextParams;\n        }\n    }\n    return params;\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/request-transformer-default-commitment.ts",
    "content": "import type { RpcRequest, RpcRequestTransformer } from '@solana/rpc-spec-types';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { applyDefaultCommitment } from './request-transformer-default-commitment-internal';\n\n/**\n * Creates a transformer that adds the provided default commitment to the configuration object of the request when applicable.\n *\n * @param config\n *\n * @example\n * ```ts\n * import { getDefaultCommitmentRequestTransformer, OPTIONS_OBJECT_POSITION_BY_METHOD } from '@solana/rpc-transformers';\n *\n * const requestTransformer = getDefaultCommitmentRequestTransformer({\n *     defaultCommitment: 'confirmed',\n *     optionsObjectPositionByMethod: OPTIONS_OBJECT_POSITION_BY_METHOD,\n * });\n */\nexport function getDefaultCommitmentRequestTransformer({\n    defaultCommitment,\n    optionsObjectPositionByMethod,\n}: Readonly<{\n    defaultCommitment?: Commitment;\n    optionsObjectPositionByMethod: Record<string, number>;\n}>): RpcRequestTransformer {\n    return <TParams>(request: RpcRequest<TParams>): RpcRequest => {\n        const { params, methodName } = request;\n\n        // We only apply default commitment to array parameters.\n        if (!Array.isArray(params)) {\n            return request;\n        }\n\n        // Find the position of the options object in the parameters and abort if not found.\n        const optionsObjectPositionInParams = optionsObjectPositionByMethod[methodName];\n        if (optionsObjectPositionInParams == null) {\n            return request;\n        }\n\n        return Object.freeze({\n            methodName,\n            params: applyDefaultCommitment({\n                commitmentPropertyName: methodName === 'sendTransaction' ? 'preflightCommitment' : 'commitment',\n                optionsObjectPositionInParams,\n                overrideCommitment: defaultCommitment,\n                params,\n            }),\n        });\n    };\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/request-transformer-integer-overflow-internal.ts",
    "content": "import { KeyPath, TraversalState } from './tree-traversal';\n\nexport function getIntegerOverflowNodeVisitor(onIntegerOverflow: (keyPath: KeyPath, value: bigint) => void) {\n    return <T>(value: T, { keyPath }: TraversalState): T => {\n        if (typeof value === 'bigint') {\n            if (onIntegerOverflow && (value > Number.MAX_SAFE_INTEGER || value < -Number.MAX_SAFE_INTEGER)) {\n                onIntegerOverflow(keyPath as (number | string)[], value);\n            }\n        }\n        return value;\n    };\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/request-transformer-integer-overflow.ts",
    "content": "import { RpcRequest } from '@solana/rpc-spec-types';\n\nimport { getIntegerOverflowNodeVisitor } from './request-transformer-integer-overflow-internal';\nimport { getTreeWalkerRequestTransformer, KeyPath } from './tree-traversal';\n\nexport type IntegerOverflowHandler = (request: RpcRequest, keyPath: KeyPath, value: bigint) => void;\n\n/**\n * Creates a transformer that traverses the request parameters and executes the provided handler\n * when an integer overflow is detected.\n *\n * @example\n * ```ts\n * import { getIntegerOverflowRequestTransformer } from '@solana/rpc-transformers';\n *\n * const requestTransformer = getIntegerOverflowRequestTransformer((request, keyPath, value) => {\n *     throw new Error(`Integer overflow at ${keyPath.join('.')}: ${value}`);\n * });\n * ```\n */\nexport function getIntegerOverflowRequestTransformer(onIntegerOverflow: IntegerOverflowHandler) {\n    return <TParams>(request: RpcRequest<TParams>): RpcRequest => {\n        const transformer = getTreeWalkerRequestTransformer(\n            [getIntegerOverflowNodeVisitor((...args) => onIntegerOverflow(request, ...args))],\n            { keyPath: [] },\n        );\n        return transformer(request);\n    };\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/request-transformer-options-object-position-config.ts",
    "content": "export const OPTIONS_OBJECT_POSITION_BY_METHOD: Record<string, number> = {\n    accountNotifications: 1,\n    blockNotifications: 1,\n    getAccountInfo: 1,\n    getBalance: 1,\n    getBlock: 1,\n    getBlockHeight: 0,\n    getBlockProduction: 0,\n    getBlocks: 2,\n    getBlocksWithLimit: 2,\n    getEpochInfo: 0,\n    getFeeForMessage: 1,\n    getInflationGovernor: 0,\n    getInflationReward: 1,\n    getLargestAccounts: 0,\n    getLatestBlockhash: 0,\n    getLeaderSchedule: 1,\n    getMinimumBalanceForRentExemption: 1,\n    getMultipleAccounts: 1,\n    getProgramAccounts: 1,\n    getSignaturesForAddress: 1,\n    getSlot: 0,\n    getSlotLeader: 0,\n    getStakeMinimumDelegation: 0,\n    getSupply: 0,\n    getTokenAccountBalance: 1,\n    getTokenAccountsByDelegate: 2,\n    getTokenAccountsByOwner: 2,\n    getTokenLargestAccounts: 1,\n    getTokenSupply: 1,\n    getTransaction: 1,\n    getTransactionCount: 0,\n    getVoteAccounts: 0,\n    isBlockhashValid: 1,\n    logsNotifications: 1,\n    programNotifications: 1,\n    requestAirdrop: 2,\n    sendTransaction: 1,\n    signatureNotifications: 1,\n    simulateTransaction: 1,\n};\n"
  },
  {
    "path": "packages/rpc-transformers/src/request-transformer.ts",
    "content": "import { pipe } from '@solana/functional';\nimport { RpcRequest, RpcRequestTransformer } from '@solana/rpc-spec-types';\nimport { Commitment } from '@solana/rpc-types';\n\nimport { getBigIntDowncastRequestTransformer } from './request-transformer-bigint-downcast';\nimport { getDefaultCommitmentRequestTransformer } from './request-transformer-default-commitment';\nimport { getIntegerOverflowRequestTransformer, IntegerOverflowHandler } from './request-transformer-integer-overflow';\nimport { OPTIONS_OBJECT_POSITION_BY_METHOD } from './request-transformer-options-object-position-config';\n\nexport type RequestTransformerConfig = Readonly<{\n    /**\n     * An optional {@link Commitment} value to use as the default when none is supplied by the\n     * caller.\n     */\n    defaultCommitment?: Commitment;\n    /**\n     * An optional function that will be called whenever a `bigint` input exceeds that which can be\n     * expressed using JavaScript numbers.\n     *\n     * This is used in the default {@link SolanaRpcSubscriptionsApi} to throw an exception rather\n     * than to allow truncated values to propagate through a program.\n     */\n    onIntegerOverflow?: IntegerOverflowHandler;\n}>;\n\n/**\n * Returns the default request transformer for the Solana RPC API.\n *\n * Under the hood, this function composes multiple\n * {@link RpcRequestTransformer | RpcRequestTransformers} together such as the\n * {@link getDefaultCommitmentTransformer}, the {@link getIntegerOverflowRequestTransformer} and the\n * {@link getBigIntDowncastRequestTransformer}.\n *\n * @example\n * ```ts\n * import { getDefaultRequestTransformerForSolanaRpc } from '@solana/rpc-transformers';\n *\n * const requestTransformer = getDefaultRequestTransformerForSolanaRpc({\n *     defaultCommitment: 'confirmed',\n *     onIntegerOverflow: (request, keyPath, value) => {\n *         throw new Error(`Integer overflow at ${keyPath.join('.')}: ${value}`);\n *     },\n * });\n * ```\n */\nexport function getDefaultRequestTransformerForSolanaRpc(config?: RequestTransformerConfig): RpcRequestTransformer {\n    const handleIntegerOverflow = config?.onIntegerOverflow;\n    return (request: RpcRequest): RpcRequest => {\n        return pipe(\n            request,\n            handleIntegerOverflow ? getIntegerOverflowRequestTransformer(handleIntegerOverflow) : r => r,\n            getBigIntDowncastRequestTransformer(),\n            getDefaultCommitmentRequestTransformer({\n                defaultCommitment: config?.defaultCommitment,\n                optionsObjectPositionByMethod: OPTIONS_OBJECT_POSITION_BY_METHOD,\n            }),\n        );\n    };\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/response-transformer-allowed-numeric-values.ts",
    "content": "import { KeyPath, KEYPATH_WILDCARD } from './tree-traversal';\n\nexport type AllowedNumericKeypaths<TApi> = Partial<Record<keyof TApi, readonly KeyPath[]>>;\n\n// Numeric values nested in `jsonParsed` accounts\nexport const jsonParsedTokenAccountsConfigs = [\n    // parsed Token/Token22 token account\n    ['data', 'parsed', 'info', 'tokenAmount', 'decimals'],\n    ['data', 'parsed', 'info', 'tokenAmount', 'uiAmount'],\n    ['data', 'parsed', 'info', 'rentExemptReserve', 'decimals'],\n    ['data', 'parsed', 'info', 'rentExemptReserve', 'uiAmount'],\n    ['data', 'parsed', 'info', 'delegatedAmount', 'decimals'],\n    ['data', 'parsed', 'info', 'delegatedAmount', 'uiAmount'],\n    ['data', 'parsed', 'info', 'extensions', KEYPATH_WILDCARD, 'state', 'olderTransferFee', 'transferFeeBasisPoints'],\n    ['data', 'parsed', 'info', 'extensions', KEYPATH_WILDCARD, 'state', 'newerTransferFee', 'transferFeeBasisPoints'],\n    ['data', 'parsed', 'info', 'extensions', KEYPATH_WILDCARD, 'state', 'preUpdateAverageRate'],\n    ['data', 'parsed', 'info', 'extensions', KEYPATH_WILDCARD, 'state', 'currentRate'],\n];\nexport const jsonParsedAccountsConfigs = [\n    ...jsonParsedTokenAccountsConfigs,\n    // parsed AddressTableLookup account\n    ['data', 'parsed', 'info', 'lastExtendedSlotStartIndex'],\n    // parsed Config account\n    ['data', 'parsed', 'info', 'slashPenalty'],\n    ['data', 'parsed', 'info', 'warmupCooldownRate'],\n    // parsed Token/Token22 mint account\n    ['data', 'parsed', 'info', 'decimals'],\n    // parsed Token/Token22 multisig account\n    ['data', 'parsed', 'info', 'numRequiredSigners'],\n    ['data', 'parsed', 'info', 'numValidSigners'],\n    // parsed Stake account\n    ['data', 'parsed', 'info', 'stake', 'delegation', 'warmupCooldownRate'],\n    // parsed Sysvar rent account\n    ['data', 'parsed', 'info', 'exemptionThreshold'],\n    ['data', 'parsed', 'info', 'burnPercent'],\n    // parsed Vote account\n    ['data', 'parsed', 'info', 'commission'],\n    ['data', 'parsed', 'info', 'votes', KEYPATH_WILDCARD, 'confirmationCount'],\n];\nexport const innerInstructionsConfigs = [\n    ['index'],\n    ['instructions', KEYPATH_WILDCARD, 'accounts', KEYPATH_WILDCARD],\n    ['instructions', KEYPATH_WILDCARD, 'programIdIndex'],\n    ['instructions', KEYPATH_WILDCARD, 'stackHeight'],\n];\nexport const messageConfig = [\n    ['addressTableLookups', KEYPATH_WILDCARD, 'writableIndexes', KEYPATH_WILDCARD],\n    ['addressTableLookups', KEYPATH_WILDCARD, 'readonlyIndexes', KEYPATH_WILDCARD],\n    ['header', 'numReadonlySignedAccounts'],\n    ['header', 'numReadonlyUnsignedAccounts'],\n    ['header', 'numRequiredSignatures'],\n    ['instructions', KEYPATH_WILDCARD, 'accounts', KEYPATH_WILDCARD],\n    ['instructions', KEYPATH_WILDCARD, 'programIdIndex'],\n    ['instructions', KEYPATH_WILDCARD, 'stackHeight'],\n] as const;\n"
  },
  {
    "path": "packages/rpc-transformers/src/response-transformer-bigint-upcast-internal.ts",
    "content": "import { KeyPath, KEYPATH_WILDCARD, TraversalState } from './tree-traversal';\n\nexport function getBigIntUpcastVisitor(allowedNumericKeyPaths: readonly KeyPath[]) {\n    return function upcastNodeToBigIntIfNumber(value: unknown, { keyPath }: TraversalState) {\n        const isInteger = (typeof value === 'number' && Number.isInteger(value)) || typeof value === 'bigint';\n        if (!isInteger) return value;\n        if (keyPathIsAllowedToBeNumeric(keyPath, allowedNumericKeyPaths)) {\n            return Number(value);\n        } else {\n            return BigInt(value);\n        }\n    };\n}\n\nfunction keyPathIsAllowedToBeNumeric(keyPath: KeyPath, allowedNumericKeyPaths: readonly KeyPath[]) {\n    return allowedNumericKeyPaths.some(prohibitedKeyPath => {\n        if (prohibitedKeyPath.length !== keyPath.length) {\n            return false;\n        }\n        for (let ii = keyPath.length - 1; ii >= 0; ii--) {\n            const keyPathPart = keyPath[ii];\n            const prohibitedKeyPathPart = prohibitedKeyPath[ii];\n            if (\n                prohibitedKeyPathPart !== keyPathPart &&\n                (prohibitedKeyPathPart !== KEYPATH_WILDCARD || typeof keyPathPart !== 'number')\n            ) {\n                return false;\n            }\n        }\n        return true;\n    });\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/response-transformer-bigint-upcast.ts",
    "content": "import { getBigIntUpcastVisitor } from './response-transformer-bigint-upcast-internal';\nimport { getTreeWalkerResponseTransformer, KeyPath } from './tree-traversal';\n\n/**\n * Returns a transformer that upcasts all `Number` values to `BigInts` unless they match within the\n * provided {@link KeyPath | KeyPaths}. In other words, the provided {@link KeyPath | KeyPaths} will\n * remain as `Number` values, any other numeric value will be upcasted to a `BigInt`.\n *\n * Note that you can use {@link KEYPATH_WILDCARD} to match any key within a {@link KeyPath}.\n *\n * @example\n * ```ts\n * import { getBigIntUpcastResponseTransformer } from '@solana/rpc-transformers';\n *\n * const responseTransformer = getBigIntUpcastResponseTransformer([\n *     ['index'],\n *     ['instructions', KEYPATH_WILDCARD, 'accounts', KEYPATH_WILDCARD],\n *     ['instructions', KEYPATH_WILDCARD, 'programIdIndex'],\n *     ['instructions', KEYPATH_WILDCARD, 'stackHeight'],\n * ]);\n * ```\n */\nexport function getBigIntUpcastResponseTransformer(allowedNumericKeyPaths: readonly KeyPath[]) {\n    return getTreeWalkerResponseTransformer([getBigIntUpcastVisitor(allowedNumericKeyPaths)], { keyPath: [] });\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/response-transformer-result.ts",
    "content": "import { RpcResponseTransformer } from '@solana/rpc-spec-types';\n\ntype JsonRpcResponse = { result: unknown };\n\n/**\n * Returns a transformer that extracts the `result` field from the body of the RPC response.\n *\n * For instance, we go from `{ jsonrpc: '2.0', result: 'foo', id: 1 }` to `'foo'`.\n *\n * @example\n * ```ts\n * import { getResultResponseTransformer } from '@solana/rpc-transformers';\n *\n * const responseTransformer = getResultResponseTransformer();\n * ```\n */\nexport function getResultResponseTransformer(): RpcResponseTransformer {\n    return json => (json as JsonRpcResponse).result;\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/response-transformer-throw-solana-error.ts",
    "content": "import { getSolanaErrorFromJsonRpcError } from '@solana/errors';\nimport { RpcResponseTransformer } from '@solana/rpc-spec-types';\n\nimport { innerInstructionsConfigs, jsonParsedAccountsConfigs } from './response-transformer-allowed-numeric-values';\nimport { getBigIntUpcastVisitor } from './response-transformer-bigint-upcast-internal';\nimport { getTreeWalkerResponseTransformer, KeyPath, KEYPATH_WILDCARD } from './tree-traversal';\n\ntype JsonRpcResponse = { error: Parameters<typeof getSolanaErrorFromJsonRpcError>[0] } | { result: unknown };\n\n// Keypaths for simulateTransaction result that should remain as Number (not BigInt)\n// Note: These are relative to the error.data root, not result.value like in success responses\nfunction getSimulateTransactionAllowedNumericKeypaths(): readonly KeyPath[] {\n    return [\n        ['loadedAccountsDataSize'],\n        ...jsonParsedAccountsConfigs.map(c => ['accounts', KEYPATH_WILDCARD, ...c]),\n        ...innerInstructionsConfigs.map(c => ['innerInstructions', KEYPATH_WILDCARD, ...c]),\n    ];\n}\n\n/**\n * Returns a transformer that throws a {@link SolanaError} with the appropriate RPC error code if\n * the body of the RPC response contains an error.\n *\n * @example\n * ```ts\n * import { getThrowSolanaErrorResponseTransformer } from '@solana/rpc-transformers';\n *\n * const responseTransformer = getThrowSolanaErrorResponseTransformer();\n * ```\n */\nexport function getThrowSolanaErrorResponseTransformer(): RpcResponseTransformer {\n    return (json, request) => {\n        const jsonRpcResponse = json as JsonRpcResponse;\n        if ('error' in jsonRpcResponse) {\n            const { error } = jsonRpcResponse;\n\n            // Check if this is a sendTransaction preflight failure (error code -32002)\n            // These errors contain RpcSimulateTransactionResult in error.data which needs\n            // BigInt values downcast to Number for fields that should be numbers\n            const isSendTransactionPreflightFailure =\n                error &&\n                typeof error === 'object' &&\n                'code' in error &&\n                (error.code === -32002 || error.code === -32002n);\n\n            if (isSendTransactionPreflightFailure && 'data' in error && error.data) {\n                // Apply BigInt downcast transformation to error.data\n                const treeWalker = getTreeWalkerResponseTransformer(\n                    [getBigIntUpcastVisitor(getSimulateTransactionAllowedNumericKeypaths())],\n                    { keyPath: [] },\n                );\n                const transformedData = treeWalker(error.data, request);\n\n                // Reconstruct error with transformed data\n                const transformedError = { ...error, data: transformedData };\n                throw getSolanaErrorFromJsonRpcError(transformedError);\n            }\n\n            throw getSolanaErrorFromJsonRpcError(jsonRpcResponse.error);\n        }\n        return jsonRpcResponse;\n    };\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/response-transformer.ts",
    "content": "import { pipe } from '@solana/functional';\nimport { RpcRequest, RpcResponse, RpcResponseTransformer } from '@solana/rpc-spec-types';\n\nimport { AllowedNumericKeypaths } from './response-transformer-allowed-numeric-values';\nimport { getBigIntUpcastResponseTransformer } from './response-transformer-bigint-upcast';\nimport { getResultResponseTransformer } from './response-transformer-result';\nimport { getThrowSolanaErrorResponseTransformer } from './response-transformer-throw-solana-error';\n\nexport type ResponseTransformerConfig<TApi> = Readonly<{\n    /**\n     * An optional map from the name of an API method to an array of {@link KeyPath | KeyPaths}\n     * pointing to values in the response that should materialize in the application as `Number`\n     * instead of `BigInt`.\n     */\n    allowedNumericKeyPaths?: AllowedNumericKeypaths<TApi>;\n}>;\n\n/**\n * Returns the default response transformer for the Solana RPC API.\n *\n * Under the hood, this function composes multiple\n * {@link RpcResponseTransformer | RpcResponseTransformers} together such as the\n * {@link getThrowSolanaErrorResponseTransformer}, the {@link getResultResponseTransformer} and the\n * {@link getBigIntUpcastResponseTransformer}.\n *\n * @example\n * ```ts\n * import { getDefaultResponseTransformerForSolanaRpc } from '@solana/rpc-transformers';\n *\n * const responseTransformer = getDefaultResponseTransformerForSolanaRpc({\n *     allowedNumericKeyPaths: getAllowedNumericKeypaths(),\n * });\n * ```\n */\nexport function getDefaultResponseTransformerForSolanaRpc<TApi>(\n    config?: ResponseTransformerConfig<TApi>,\n): RpcResponseTransformer {\n    return (response: RpcResponse, request: RpcRequest): RpcResponse => {\n        const methodName = request.methodName as keyof TApi;\n        const keyPaths =\n            config?.allowedNumericKeyPaths && methodName ? config.allowedNumericKeyPaths[methodName] : undefined;\n        return pipe(\n            response,\n            r => getThrowSolanaErrorResponseTransformer()(r, request),\n            r => getResultResponseTransformer()(r, request),\n            r => getBigIntUpcastResponseTransformer(keyPaths ?? [])(r, request),\n        );\n    };\n}\n\n/**\n * Returns the default response transformer for the Solana RPC Subscriptions API.\n *\n * Under the hood, this function composes the {@link getBigIntUpcastResponseTransformer}.\n *\n * @example\n * ```ts\n * import { getDefaultResponseTransformerForSolanaRpcSubscriptions } from '@solana/rpc-transformers';\n *\n * const responseTransformer = getDefaultResponseTransformerForSolanaRpcSubscriptions({\n *     allowedNumericKeyPaths: getAllowedNumericKeypaths(),\n * });\n * ```\n */\nexport function getDefaultResponseTransformerForSolanaRpcSubscriptions<TApi>(\n    config?: ResponseTransformerConfig<TApi>,\n): RpcResponseTransformer {\n    return (response: RpcResponse, request: RpcRequest): RpcResponse => {\n        const methodName = request.methodName as keyof TApi;\n        const keyPaths =\n            config?.allowedNumericKeyPaths && methodName ? config.allowedNumericKeyPaths[methodName] : undefined;\n        return pipe(response, r => getBigIntUpcastResponseTransformer(keyPaths ?? [])(r, request));\n    };\n}\n"
  },
  {
    "path": "packages/rpc-transformers/src/tree-traversal.ts",
    "content": "import { RpcRequest, RpcRequestTransformer, RpcResponseTransformer } from '@solana/rpc-spec-types';\n\nexport type KeyPathWildcard = { readonly ['__keyPathWildcard:@solana/kit']: unique symbol };\nexport type KeyPath = ReadonlyArray<KeyPath | KeyPathWildcard | number | string>;\n\nexport const KEYPATH_WILDCARD = {} as KeyPathWildcard;\n\ntype NodeVisitor = <TState extends TraversalState>(value: unknown, state: TState) => unknown;\nexport type TraversalState = Readonly<{\n    keyPath: KeyPath;\n}>;\n\nfunction getTreeWalker(visitors: NodeVisitor[]) {\n    return function traverse<TState extends TraversalState>(node: unknown, state: TState): unknown {\n        if (Array.isArray(node)) {\n            return node.map((element, ii) => {\n                const nextState = {\n                    ...state,\n                    keyPath: [...state.keyPath, ii],\n                };\n                return traverse(element, nextState);\n            });\n        } else if (typeof node === 'object' && node !== null) {\n            const out: Record<number | string | symbol, unknown> = {};\n            for (const propName in node) {\n                if (!Object.prototype.hasOwnProperty.call(node, propName)) {\n                    continue;\n                }\n                const nextState = {\n                    ...state,\n                    keyPath: [...state.keyPath, propName],\n                };\n                out[propName] = traverse(node[propName as keyof typeof node], nextState);\n            }\n            return out;\n        } else {\n            return visitors.reduce((acc, visitNode) => visitNode(acc, state), node);\n        }\n    };\n}\n\n/**\n * Creates a transformer that traverses the request parameters and executes the provided visitors at\n * each node. A custom initial state can be provided but must at least provide `{ keyPath: [] }`.\n *\n * @example\n * ```ts\n * import { getTreeWalkerRequestTransformer } from '@solana/rpc-transformers';\n *\n * const requestTransformer = getTreeWalkerRequestTransformer(\n *     [\n *         // Replaces foo.bar with \"baz\".\n *         (node, state) => (state.keyPath === ['foo', 'bar'] ? 'baz' : node),\n *         // Increments all numbers by 1.\n *         node => (typeof node === number ? node + 1 : node),\n *     ],\n *     { keyPath: [] },\n * );\n * ```\n */\nexport function getTreeWalkerRequestTransformer<TState extends TraversalState>(\n    visitors: NodeVisitor[],\n    initialState: TState,\n): RpcRequestTransformer {\n    return <TParams>(request: RpcRequest<TParams>): RpcRequest => {\n        const traverse = getTreeWalker(visitors);\n        return Object.freeze({\n            ...request,\n            params: traverse(request.params, initialState),\n        });\n    };\n}\n\nexport function getTreeWalkerResponseTransformer<TState extends TraversalState>(\n    visitors: NodeVisitor[],\n    initialState: TState,\n): RpcResponseTransformer {\n    return json => getTreeWalker(visitors)(json, initialState);\n}\n"
  },
  {
    "path": "packages/rpc-transformers/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-transformers/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-transformers\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-transformers/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-transport-http/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-transport-http/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-transport-http/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-transport-http/CHANGELOG.md",
    "content": "# @solana/rpc-transport-http\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/rpc-spec-types@6.9.0\n    - @solana/rpc-spec@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n    - @solana/rpc-spec@6.8.0\n    - @solana/rpc-spec-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n    - @solana/rpc-spec@6.7.0\n    - @solana/rpc-spec-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/rpc-spec@6.6.0\n    - @solana/rpc-spec-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n    - @solana/rpc-spec@6.5.0\n    - @solana/rpc-spec-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.4.0\n    - @solana/rpc-spec@6.4.0\n    - @solana/rpc-spec-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n    - @solana/rpc-spec@6.3.1\n    - @solana/rpc-spec-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/rpc-spec@6.3.0\n    - @solana/rpc-spec-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/rpc-spec@6.2.0\n    - @solana/rpc-spec-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/rpc-spec@6.1.0\n    - @solana/rpc-spec-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.1\n    - @solana/rpc-spec@6.0.1\n    - @solana/rpc-spec-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.0\n    - @solana/rpc-spec@6.0.0\n    - @solana/rpc-spec-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/rpc-spec@5.5.1\n    - @solana/rpc-spec-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/rpc-spec@5.5.0\n    - @solana/rpc-spec-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/rpc-spec-types@5.4.0\n    - @solana/rpc-spec@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n    - @solana/rpc-spec@5.3.0\n    - @solana/rpc-spec-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n    - @solana/rpc-spec@5.2.0\n    - @solana/rpc-spec-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n    - @solana/rpc-spec@5.1.0\n    - @solana/rpc-spec-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/rpc-spec@5.0.0\n    - @solana/rpc-spec-types@5.0.0\n\n## 4.0.0\n\n### Minor Changes\n\n- [#888](https://github.com/anza-xyz/kit/pull/888) [`05970df`](https://github.com/anza-xyz/kit/commit/05970dfc5706d739083d420b669ccac1266c570f) Thanks [@prashanFOMO](https://github.com/prashanFOMO)! - The React Native and Node builds now permit you to set the `Origin` header. This header continues to be forbidden in the browser build, as it features on the list of forbidden request headers: https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_request_header\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-spec@4.0.0\n    - @solana/rpc-spec-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`81c83b1`](https://github.com/anza-xyz/kit/commit/81c83b12dd0e145bf7d08182e01824f2f14e5ee5)]:\n    - @solana/errors@3.0.0\n    - @solana/rpc-spec-types@3.0.0\n    - @solana/rpc-spec@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`304a44f`](https://github.com/anza-xyz/kit/commit/304a44fc68401001af45b1088eea825d8f437677), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/rpc-spec@2.3.0\n    - @solana/rpc-spec-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.1\n    - @solana/rpc-spec@2.2.1\n    - @solana/rpc-spec-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.0\n    - @solana/rpc-spec@2.2.0\n    - @solana/rpc-spec-types@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-spec-types@2.1.1\n    - @solana/rpc-spec@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Minor Changes\n\n- [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c) Thanks [@steveluscher](https://github.com/steveluscher)! - When the HTTP transport throws an error, you can now access the response headers through `e.context.headers`. This can be useful, for instance, if the HTTP error is a 429 Rate Limit error, and the response contains a `Retry-After` header.\n\n    ```ts\n    try {\n        const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n    } catch (e) {\n        if (isSolanaError(e, SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR)) {\n            if (e.context.code === 429 /* rate limit error */) {\n                const retryAfterHeaderValue = e.context.headers.get('Retry-After');\n                if (retryAfterHeaderValue != null) {\n                    // ...\n                }\n            }\n        }\n    }\n    ```\n\n### Patch Changes\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n    - @solana/rpc-spec@2.1.0\n    - @solana/rpc-spec-types@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3196](https://github.com/solana-labs/solana-web3.js/pull/3196) [`512853e`](https://github.com/solana-labs/solana-web3.js/commit/512853e5d0964075261913f9b2b08137116ce82e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `createHttpTransportForSolanaRpc` function that creates a new HTTP transport specific to the Solana RPC API. This transport uses custom JSON parsing and stringifying strategies on both the request and response of Solana RPC API requests in order to prevents loss of precision for large integers.\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- [#3192](https://github.com/solana-labs/solana-web3.js/pull/3192) [`422f928`](https://github.com/solana-labs/solana-web3.js/commit/422f928086db5897522605243ac09148f9301fa1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `fromJson` and `toJson` options to the HTTP transport\n\n- [#3148](https://github.com/solana-labs/solana-web3.js/pull/3148) [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcTransport` return new `RpcReponse` type instead of parsed JSON data\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69), [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597), [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/errors@2.0.0\n    - @solana/rpc-spec@2.0.0\n    - @solana/rpc-spec-types@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/rpc-spec@2.0.0-rc.4\n    - @solana/rpc-spec-types@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-spec-types@2.0.0-rc.3\n    - @solana/rpc-spec@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3407](https://github.com/solana-labs/solana-web3.js/pull/3407) [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use `RpcRequest`, `RpcResponse` and their transformers in RPC Subscriptions packages\n\n    This change makes the RPC and RPC Subscriptions architecture more consistent by using the same `RpcRequest` and `RpcResponse` types and transformers as the basis for handling user requests (RPC calls or subscriptions) and returning responses to them.\n\n    See the following PRs for more details:\n    - [PR #3393](https://github.com/solana-labs/solana-web3.js/pull/3393)\n    - [PR #3394](https://github.com/solana-labs/solana-web3.js/pull/3394)\n    - [PR #3403](https://github.com/solana-labs/solana-web3.js/pull/3403)\n    - [PR #3404](https://github.com/solana-labs/solana-web3.js/pull/3404)\n    - [PR #3405](https://github.com/solana-labs/solana-web3.js/pull/3405)\n\n- [#3196](https://github.com/solana-labs/solana-web3.js/pull/3196) [`512853e`](https://github.com/solana-labs/solana-web3.js/commit/512853e5d0964075261913f9b2b08137116ce82e) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add new `createHttpTransportForSolanaRpc` function that creates a new HTTP transport specific to the Solana RPC API. This transport uses custom JSON parsing and stringifying strategies on both the request and response of Solana RPC API requests in order to prevents loss of precision for large integers.\n\n- [#3192](https://github.com/solana-labs/solana-web3.js/pull/3192) [`422f928`](https://github.com/solana-labs/solana-web3.js/commit/422f928086db5897522605243ac09148f9301fa1) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `fromJson` and `toJson` options to the HTTP transport\n\n- [#3148](https://github.com/solana-labs/solana-web3.js/pull/3148) [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Make `RpcTransport` return new `RpcReponse` type instead of parsed JSON data\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`6b43588`](https://github.com/solana-labs/solana-web3.js/commit/6b4358864cb328d1b83f11c94b29f75e1b3d635f), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`628177f`](https://github.com/solana-labs/solana-web3.js/commit/628177ffcc1be1c40e0c82d80743b07f695cfe69), [`06dcd86`](https://github.com/solana-labs/solana-web3.js/commit/06dcd86d830e866eb3ee7c47ea1bb99b8205bd1e), [`3c02c35`](https://github.com/solana-labs/solana-web3.js/commit/3c02c3582f5b87151b7ac1d9cd24b9d20f6945ea), [`1c25dd4`](https://github.com/solana-labs/solana-web3.js/commit/1c25dd4069a3a8f5599285c9b0eaeb71a2f897d1), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`4f87d12`](https://github.com/solana-labs/solana-web3.js/commit/4f87d12cf942fbd4f427005d5ac41671ce28a22c), [`a705413`](https://github.com/solana-labs/solana-web3.js/commit/a705413e357fb5c5907c5fc1df17d241bc5c0f76), [`91076ba`](https://github.com/solana-labs/solana-web3.js/commit/91076ba1884eb72880d1ee964b6800d90afb4460), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`f5660d2`](https://github.com/solana-labs/solana-web3.js/commit/f5660d2eb4d2ee5be8c9cd8e8b58a11de1a799bf), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`d198638`](https://github.com/solana-labs/solana-web3.js/commit/d19863844cf28c252e6bedd7070e633692d9e46e), [`db144da`](https://github.com/solana-labs/solana-web3.js/commit/db144da362e3389837b56f97abfb766cc8c847c2)]:\n    - @solana/rpc-spec@2.0.0-rc.2\n    - @solana/rpc-spec-types@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.1\n    - @solana/rpc-spec@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- Updated dependencies [[`29821df`](https://github.com/solana-labs/solana-web3.js/commit/29821df246b14eb41dd4606913f44fac40183957), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/rpc-spec@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`6340744`](https://github.com/solana-labs/solana-web3.js/commit/6340744e5cf0ea91ae677f381d5a187638a19597)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-spec@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/rpc-spec@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/errors@2.0.0-preview.2\n    - @solana/rpc-spec@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-transport-http/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-transport-http/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-transport-http?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-transport-http?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-transport-http\n\n# @solana/rpc-transport-http\n\nThis package allows developers to create custom RPC transports. Using these primitives, developers can create custom transports that perform transforms on messages sent and received, attempt retries, and implement routing strategies between multiple transports.\n\n## Functions\n\n### `createHttpTransport()`\n\nCall this to create a function that conforms to the `RpcTransport` interface (see `@solana/rpc-spec`). You can use that function in your programs to make `POST` requests with headers suitable for sending JSON data to a server.\n\n```ts\nimport { createHttpTransport } from '@solana/rpc-transport-http';\n\nconst transport = createHttpTransport({ url: 'https://api.mainnet-beta.solana.com' });\nconst response = await transport({\n    payload: { id: 1, jsonrpc: '2.0', method: 'getSlot' },\n});\nconst data = await response.json();\n```\n\n#### Config\n\n##### `dispatcher_NODE_ONLY`\n\nIn Node environments you can tune how requests are dispatched to the network. Use this config parameter to install a [`undici.Dispatcher`](https://undici.nodejs.org/#/docs/api/Agent) in your transport.\n\n```ts\nimport { createHttpTransport } from '@solana/rpc-transport-http';\nimport { Agent, BalancedPool } from 'undici';\n\n// Create a dispatcher that, when called with a special URL, creates a round-robin pool of RPCs.\nconst dispatcher = new Agent({\n    factory(origin, opts) {\n        if (origin === 'https://mypool') {\n            const upstreams = [\n                'https://api.mainnet-beta.solana.com',\n                'https://mainnet.helius-rpc.com',\n                'https://several-neat-iguana.quiknode.pro',\n            ];\n            return new BalancedPool(upstreams, {\n                ...opts,\n                bodyTimeout: 60e3,\n                headersTimeout: 5e3,\n                keepAliveTimeout: 19e3,\n            });\n        } else {\n            return new Pool(origin, opts);\n        }\n    },\n});\nconst transport = createHttpTransport({\n    dispatcher_NODE_ONLY: dispatcher,\n    url: 'https://mypool',\n});\nlet id = 0;\nconst balances = await Promise.allSettled(\n    accounts.map(async account => {\n        const response = await transport({\n            payload: {\n                id: ++id,\n                jsonrpc: '2.0',\n                method: 'getBalance',\n                params: [account],\n            },\n        });\n        return await response.json();\n    }),\n);\n```\n\n##### `fromJson`\n\nAn optional function that takes the response as a JSON string and converts it to a JSON value. The request payload is also provided as a second argument. When not provided, the JSON value will be accessed via the `response.json()` method of the fetch API.\n\n##### `headers`\n\nAn object of headers to set on the request. Avoid [forbidden headers](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name). Additionally, the headers `Accept`, `Content-Length`, and `Content-Type` are disallowed.\n\n```ts\nimport { createHttpTransport } from '@solana/rpc-transport-http';\n\nconst transport = createHttpTransport({\n    headers: {\n        // Authorize with the RPC using a bearer token\n        Authorization: `Bearer ${process.env.RPC_AUTH_TOKEN}`,\n    },\n    url: 'https://several-neat-iguana.quiknode.pro',\n});\n```\n\n##### `toJson`\n\nAn optional function that takes the request payload and converts it to a JSON string. When not provided, `JSON.stringify` will be used.\n\n##### `url`\n\nA string representing the target endpoint. In Node, it must be an absolute URL using the `http` or `https` protocol.\n\n### `createHttpTransportForSolanaRpc()`\n\nCreates a `RpcTransport` that uses JSON HTTP requests — much like the `createHttpTransport` function — except that it also uses custom `toJson` and `fromJson` functions in order to allow `bigint` values to be serialized and deserialized correctly over the wire.\n\nSince this is something specific to the Solana RPC API, these custom JSON functions are only triggered when the request is recognized as a Solana RPC request. Normal RPC APIs should aim to wrap their `bigint` values — e.g. `u64` or `i64` — in special value objects that represent the number as a string to avoid numerical values going above `Number.MAX_SAFE_INTEGER`.\n\nIt has the same configuration options as `createHttpTransport`, but without the `fromJson` and `toJson` options.\n\n## Augmenting Transports\n\nUsing this core transport, you can implement specialized functionality for leveraging multiple transports, attempting/handling retries, and more.\n\n### Round Robin\n\nHere’s an example of how someone might implement a “round robin” approach to distribute requests to multiple transports:\n\n```ts\nimport { RpcTransport } from '@solana/rpc-spec';\nimport { RpcResponse } from '@solana/rpc-spec-types';\nimport { createHttpTransport } from '@solana/rpc-transport-http';\n\n// Create a transport for each RPC server\nconst transports = [\n    createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' }),\n    createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),\n    createHttpTransport({ url: 'https://mainnet-beta.my-server-3.com' }),\n];\n\n// Create a wrapper transport that distributes requests to them\nlet nextTransport = 0;\nasync function roundRobinTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {\n    const transport = transports[nextTransport];\n    nextTransport = (nextTransport + 1) % transports.length;\n    return await transport(...args);\n}\n```\n\n### Sharding\n\nAnother example of a possible customization for a transport is to shard requests deterministically among a set of servers. Here’s an example:\n\nPerhaps your application needs to make a large number of requests, or needs to fan request for different methods out to different servers. Here’s an example of an implementation that does the latter:\n\n```ts\nimport { RpcTransport } from '@solana/rpc-spec';\nimport { RpcResponse } from '@solana/rpc-spec-types';\nimport { createHttpTransport } from '@solana/rpc-transport-http';\n\n// Create multiple transports\nconst transportA = createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' });\nconst transportB = createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' });\nconst transportC = createHttpTransport({ url: 'https://mainnet-beta.my-server-3.com' });\nconst transportD = createHttpTransport({ url: 'https://mainnet-beta.my-server-4.com' });\n\n// Function to determine which shard to use based on the request method\nfunction selectShard(method: string): RpcTransport {\n    switch (method) {\n        case 'getAccountInfo':\n        case 'getBalance':\n            return transportA;\n        case 'getLatestBlockhash':\n        case 'getTransaction':\n            return transportB;\n        case 'sendTransaction':\n            return transportC;\n        default:\n            return transportD;\n    }\n}\n\nasync function shardingTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {\n    const payload = args[0].payload as { method: string };\n    const selectedTransport = selectShard(payload.method);\n    return await selectedTransport(...args);\n}\n```\n\n### Retry Logic\n\nThe transport library can also be used to implement custom retry logic on any request:\n\n```ts\nimport { RpcTransport } from '@solana/rpc-spec';\nimport { RpcResponse } from '@solana/rpc-spec-types';\nimport { createHttpTransport } from '@solana/rpc-transport-http';\n\n// Set the maximum number of attempts to retry a request\nconst MAX_ATTEMPTS = 4;\n\n// Create the default transport\nconst defaultTransport = createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' });\n\n// Sleep function to wait for a given number of milliseconds\nfunction sleep(ms: number): Promise<void> {\n    return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// Calculate the delay for a given attempt\nfunction calculateRetryDelay(attempt: number): number {\n    // Exponential backoff with a maximum of 1.5 seconds\n    return Math.min(100 * Math.pow(2, attempt), 1500);\n}\n\n// A retrying transport that will retry up to `MAX_ATTEMPTS` times before failing\nasync function retryingTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {\n    let requestError;\n    for (let attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {\n        try {\n            return await defaultTransport(...args);\n        } catch (err) {\n            requestError = err;\n            // Only sleep if we have more attempts remaining\n            if (attempts < MAX_ATTEMPTS - 1) {\n                const retryDelay = calculateRetryDelay(attempts);\n                await sleep(retryDelay);\n            }\n        }\n    }\n    throw requestError;\n}\n```\n\n### Failover\n\nHere’s an example of some failover logic integrated into a transport:\n\n```ts\nimport { RpcTransport } from '@solana/rpc-spec';\nimport { RpcResponse } from '@solana/rpc-spec-types';\nimport { createHttpTransport } from '@solana/rpc-transport-http';\n\n// Create a transport for each RPC server\nconst transports = [\n    createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' }),\n    createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),\n    createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),\n];\n\n// A failover transport that will try each transport in order until one succeeds before failing\nasync function failoverTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {\n    let requestError;\n\n    for (const transport of transports) {\n        try {\n            return await transport(...args);\n        } catch (err) {\n            requestError = err;\n            console.error(err);\n        }\n    }\n    throw requestError;\n}\n```\n"
  },
  {
    "path": "packages/rpc-transport-http/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-transport-http\",\n    \"version\": \"6.9.0\",\n    \"description\": \"An RPC transport that uses HTTP requests\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-transport-http\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"benchmark\": \"./src/__benchmarks__/run.ts\",\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/rpc-spec\": \"workspace:*\",\n        \"@solana/rpc-spec-types\": \"workspace:*\",\n        \"undici-types\": \"^8.2.0\"\n    },\n    \"devDependencies\": {\n        \"tinybench\": \"^6.0.0\",\n        \"undici\": \"^8.2.0\",\n        \"zx\": \"^8.8.5\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-transport-http/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__benchmarks__/run.ts",
    "content": "#!/usr/bin/env -S pnpm dlx tsx -r ../build-scripts/register-node-globals.cjs\n\nimport { ok } from 'node:assert';\n\nimport { Bench } from 'tinybench';\nimport { Agent, Dispatcher } from 'undici';\nimport { $ } from 'zx';\n\nimport { createHttpTransport } from '../index';\n\nlet VALIDATOR_URL = process.argv[2];\nok(\n    typeof URL === 'undefined' || !!URL,\n    'You must supply the URL of a rate-limit-free Solana JSON-RPC server as the first argument to this script',\n);\nVALIDATOR_URL ??= 'http://127.0.0.1:8899';\n\nconst NUM_CONCURRENT_REQUESTS = 1024;\n\nconst bench = new Bench({\n    throws: true,\n});\n\nlet dispatcher: Dispatcher | undefined;\nfunction createDispatcher(options: Agent.Options) {\n    dispatcher = new Agent({\n        ...options,\n        // One second fewer than the Solana RPC's keepalive timeout.\n        // Read more: https://github.com/solana-labs/solana/issues/27859#issuecomment-1340097889\n        keepAliveTimeout: 19000,\n    });\n}\n\nlet id = 0;\nfunction getTestPayload() {\n    return {\n        id: ++id,\n        jsonrpc: '2.0',\n        method: 'getLatestBlockhash',\n    };\n}\n\nasync function makeConcurrentRequests(num: number = NUM_CONCURRENT_REQUESTS) {\n    await Promise.all(\n        Array.from({ length: num }).map(() =>\n            createHttpTransport({\n                dispatcher_NODE_ONLY: dispatcher,\n                url: VALIDATOR_URL,\n            })({\n                payload: getTestPayload(),\n            }),\n        ),\n    );\n}\n\nbench\n    .add('no dispatcher', () => makeConcurrentRequests(), {\n        beforeEach() {\n            dispatcher = undefined;\n        },\n    })\n    .add('unlimited connections http/2', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { allowH2: true, connections: null }),\n    })\n    .add('unlimited connections', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: null }),\n    })\n    .add('16 connections', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 16 }),\n    })\n    .add('16 connections, http/2', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { allowH2: true, connections: 16 }),\n    })\n    .add('16 connections, pipeline 2 wide', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 16, pipelining: 2 }),\n    })\n    .add('32 connections', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 32 }),\n    })\n    .add('32 connections, http/2', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { allowH2: true, connections: 32 }),\n    })\n    .add('32 connections, pipeline 2 wide', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 32, pipelining: 2 }),\n    })\n    .add('64 connections', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 64 }),\n    })\n    .add('64 connections, http/2', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { allowH2: true, connections: 64 }),\n    })\n    .add('64 connections, pipeline 2 wide', () => makeConcurrentRequests(), {\n        beforeEach: createDispatcher.bind(null, { connections: 64, pipelining: 2 }),\n    });\n\nvoid (async () => {\n    const validatorPromise = $`../../scripts/start-shared-test-validator.sh`;\n    await $`wget --output-document=/dev/null --waitretry=1 --tries=100 --retry-connrefused ${VALIDATOR_URL.replace(\n        /^(\\w+:\\/\\/[^\\\\/]+)\\/.*$/,\n        '$1',\n    )}/health -nv`;\n    await bench.run();\n    console.table(bench.table());\n    await validatorPromise.kill('SIGINT');\n})();\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__tests__/http-transport-abort-test.ts",
    "content": "import { RpcTransport } from '@solana/rpc-spec';\n\nimport { createHttpTransport } from '../http-transport';\n\ndescribe('createHttpTransport and `AbortSignal`', () => {\n    let makeHttpRequest: RpcTransport;\n    beforeEach(() => {\n        makeHttpRequest = createHttpTransport({ url: 'http://localhost' });\n    });\n    describe('when invoked with an already-aborted `AbortSignal`', () => {\n        it('rejects with an `AbortError` when no reason is specified', async () => {\n            expect.assertions(3);\n            const sendPromise = makeHttpRequest({ payload: 123, signal: AbortSignal.abort() });\n            await expect(sendPromise).rejects.toThrow();\n            await expect(sendPromise).rejects.toBeInstanceOf(DOMException);\n            await expect(sendPromise).rejects.toHaveProperty('name', 'AbortError');\n        });\n        // FIXME: https://github.com/JakeChampion/fetch/pull/1436\n        // `whatwg-fetch` handles `reason` incorrectly; it unconditionally throws `AbortError`\n        if (!__BROWSER__) {\n            it(\"rejects with the `AbortSignal's` reason\", async () => {\n                expect.assertions(1);\n                const sendPromise = makeHttpRequest({\n                    payload: 123,\n                    signal: AbortSignal.abort('Already aborted'),\n                });\n                await expect(sendPromise).rejects.toBe('Already aborted');\n            });\n        }\n    });\n    describe('when it receives an abort signal mid-request', () => {\n        let abortController: AbortController;\n        let abortSignal: AbortSignal;\n        beforeEach(() => {\n            abortController = new AbortController();\n            abortSignal = abortController.signal;\n        });\n        it('rejects with an `AbortError` when no reason is specified', async () => {\n            expect.assertions(1);\n            const sendPromise = makeHttpRequest({ payload: 123, signal: abortSignal });\n            abortController.abort();\n            await expect(sendPromise).rejects.toThrow();\n        });\n        // FIXME: https://github.com/JakeChampion/fetch/pull/1436\n        // `whatwg-fetch` handles `reason` incorrectly; it unconditionally throws `AbortError`\n        if (!__BROWSER__) {\n            it(\"rejects with with the `AbortSignal's` reason\", async () => {\n                expect.assertions(1);\n                const sendPromise = makeHttpRequest({ payload: 123, signal: abortSignal });\n                abortController.abort('I got bored waiting');\n                await expect(sendPromise).rejects.toBe('I got bored waiting');\n            });\n        }\n    });\n    describe('when it receives an abort signal after responding', () => {\n        let abortController: AbortController;\n        let abortSignal: AbortSignal;\n        let fetchSpy: jest.SpyInstance;\n        beforeEach(async () => {\n            fetchSpy = jest.spyOn(globalThis, 'fetch');\n            await jest.isolateModulesAsync(async () => {\n                const { createHttpTransport } =\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    // @ts-ignore\n                    await import('../http-transport');\n                makeHttpRequest = createHttpTransport({ url: 'http://localhost' });\n            });\n            abortController = new AbortController();\n            abortSignal = abortController.signal;\n        });\n        it('resolves with the response', async () => {\n            expect.assertions(1);\n            jest.mocked(fetchSpy).mockResolvedValueOnce({\n                json: () => Promise.resolve({ ok: true }),\n                ok: true,\n            } as unknown as Response);\n            const sendPromise = makeHttpRequest({ payload: 123, signal: abortSignal });\n            abortController.abort('I got bored waiting');\n            await expect(sendPromise).resolves.toMatchObject({ ok: true });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__tests__/http-transport-dispatcher-test.browser.ts",
    "content": "import type { Dispatcher } from 'undici';\n\nconst WARNING_MESSAGE =\n    'You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored because ' +\n    'Undici dispatchers only work in Node environments. To eliminate this warning, omit the ' +\n    '`dispatcher_NODE_ONLY` property from your config when running in a non-Node environment.';\n\ndescribe('createHttpTransport()', () => {\n    let createHttpTransport: typeof import('../http-transport').createHttpTransport;\n    beforeEach(async () => {\n        jest.spyOn(console, 'warn').mockImplementation();\n        await jest.isolateModulesAsync(async () => {\n            createHttpTransport =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                (await import('../http-transport')).createHttpTransport;\n        });\n    });\n    describe('in development mode', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/no-explicit-any\n            (globalThis as any).__DEV__ = true;\n        });\n        it('warns when configured with a dispatcher', () => {\n            createHttpTransport({ dispatcher_NODE_ONLY: {} as Dispatcher, url: 'fake://url' });\n            expect(console.warn).toHaveBeenCalledWith(WARNING_MESSAGE);\n        });\n        it('warns when configured with an undefined dispatcher', () => {\n            createHttpTransport({ dispatcher_NODE_ONLY: undefined, url: 'fake://url' });\n            expect(console.warn).toHaveBeenCalledWith(WARNING_MESSAGE);\n        });\n        it('only warns once no matter how many times it is configured with a dispatcher', () => {\n            createHttpTransport({ dispatcher_NODE_ONLY: undefined, url: 'fake://url' });\n            createHttpTransport({ dispatcher_NODE_ONLY: {} as Dispatcher, url: 'fake://url' });\n            createHttpTransport({ dispatcher_NODE_ONLY: null as unknown as Dispatcher, url: 'fake://url' });\n            expect(console.warn).toHaveBeenCalledTimes(1);\n        });\n    });\n    describe('in production mode', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/no-explicit-any\n            (globalThis as any).__DEV__ = false;\n        });\n        it('does not warn when configured with a dispatcher', () => {\n            createHttpTransport({ dispatcher_NODE_ONLY: {} as Dispatcher, url: 'fake://url' });\n            expect(console.warn).not.toHaveBeenCalledWith(WARNING_MESSAGE);\n        });\n        it('does not warn when configured with an undefined dispatcher', () => {\n            createHttpTransport({ dispatcher_NODE_ONLY: undefined, url: 'fake://url' });\n            expect(console.warn).not.toHaveBeenCalledWith(WARNING_MESSAGE);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__tests__/http-transport-for-solana-rpc-test.ts",
    "content": "import { RpcTransport } from '@solana/rpc-spec';\n\nconst MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);\nconst MAX_SAFE_INTEGER_PLUS_ONE = BigInt(Number.MAX_SAFE_INTEGER) + 1n;\n\ndescribe('createHttpTransportForSolanaRpc', () => {\n    let fetchSpy: jest.SpyInstance;\n    let makeHttpRequest: RpcTransport;\n    beforeEach(async () => {\n        await jest.isolateModulesAsync(async () => {\n            fetchSpy = jest.spyOn(globalThis, 'fetch');\n            const { createHttpTransportForSolanaRpc } =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                await import('../http-transport-for-solana-rpc');\n            makeHttpRequest = createHttpTransportForSolanaRpc({ url: 'http://localhost' });\n        });\n    });\n    describe('when the request is from the Solana RPC API', () => {\n        it('passes all bigints as large numerical values in the request body', async () => {\n            expect.assertions(1);\n            fetchSpy.mockResolvedValue({ ok: true, text: () => `{\"ok\":true}` });\n            await makeHttpRequest({\n                payload: {\n                    jsonrpc: '2.0',\n                    method: 'getBalance',\n                    params: {\n                        numbersInString: 'He said: \"1, 2, 3, Soleil!\"',\n                        safeNumber: MAX_SAFE_INTEGER,\n                        unsafeNumber: MAX_SAFE_INTEGER_PLUS_ONE,\n                    },\n                },\n            });\n            expect(fetchSpy).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    body: expect.stringContaining(\n                        `\"params\":{` +\n                            `\"numbersInString\":\"He said: \\\\\"1, 2, 3, Soleil!\\\\\"\",` +\n                            `\"safeNumber\":${MAX_SAFE_INTEGER},` +\n                            `\"unsafeNumber\":${MAX_SAFE_INTEGER_PLUS_ONE}}`,\n                    ),\n                }),\n            );\n        });\n        it('gets all integers as bigints within the response', async () => {\n            expect.assertions(1);\n            fetchSpy.mockResolvedValue({\n                ok: true,\n                text: () =>\n                    `{\"safeNumber\": ${MAX_SAFE_INTEGER}, ` +\n                    `\"unsafeNumber\": ${MAX_SAFE_INTEGER_PLUS_ONE}, ` +\n                    `\"numbersInString\": \"He said: \\\\\"1, 2, 3, Soleil!\\\\\"\"}`,\n            });\n            const requestPromise = makeHttpRequest({\n                payload: {\n                    jsonrpc: '2.0',\n                    method: 'getBalance',\n                    params: ['1234..5678'],\n                },\n            });\n            await expect(requestPromise).resolves.toStrictEqual({\n                numbersInString: 'He said: \"1, 2, 3, Soleil!\"',\n                safeNumber: MAX_SAFE_INTEGER,\n                unsafeNumber: MAX_SAFE_INTEGER_PLUS_ONE,\n            });\n        });\n    });\n    describe('when the request is not from the Solana RPC API', () => {\n        it('fails to stringify bigints in requests', async () => {\n            expect.assertions(1);\n            const promise = makeHttpRequest({\n                payload: {\n                    jsonrpc: '2.0',\n                    method: 'getAssetsByOwner',\n                    params: [MAX_SAFE_INTEGER_PLUS_ONE],\n                },\n            });\n            await expect(promise).rejects.toThrow(new TypeError('Do not know how to serialize a BigInt'));\n        });\n        it('downcasts bigints to numbers in responses', async () => {\n            expect.assertions(1);\n            fetchSpy.mockResolvedValue({\n                ok: true,\n                text: () =>\n                    `{\"safeNumber\": ${MAX_SAFE_INTEGER}, ` +\n                    `\"unsafeNumber\": ${MAX_SAFE_INTEGER_PLUS_ONE}, ` +\n                    `\"numbersInString\": \"He said: \\\\\"1, 2, 3, Soleil!\\\\\"\"}`,\n            });\n            const requestPromise = makeHttpRequest({\n                payload: {\n                    jsonrpc: '2.0',\n                    method: 'getAssetsByOwner',\n                    params: ['1234..5678'],\n                },\n            });\n            await expect(requestPromise).resolves.toStrictEqual({\n                numbersInString: 'He said: \"1, 2, 3, Soleil!\"',\n                safeNumber: Number(MAX_SAFE_INTEGER),\n                unsafeNumber: Number(MAX_SAFE_INTEGER_PLUS_ONE),\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__tests__/http-transport-from-json-test.ts",
    "content": "import { RpcTransport } from '@solana/rpc-spec';\n\ndescribe('createHttpTransport and `fromJson` function', () => {\n    let fromJson: jest.Mock;\n    let fetchSpy: jest.SpyInstance;\n    let makeHttpRequest: RpcTransport;\n    beforeEach(async () => {\n        await jest.isolateModulesAsync(async () => {\n            fromJson = jest.fn();\n            fetchSpy = jest.spyOn(globalThis, 'fetch');\n            fetchSpy.mockResolvedValue({ ok: true, text: () => '{\"ok\":true}' });\n            const { createHttpTransport } =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                await import('../http-transport');\n            makeHttpRequest = createHttpTransport({ fromJson, url: 'http://localhost' });\n        });\n    });\n    it('uses the `fromJson` function to parse the response from a JSON string', async () => {\n        expect.assertions(1);\n        await makeHttpRequest({ payload: { foo: 123 } });\n        expect(fromJson).toHaveBeenCalledWith('{\"ok\":true}', { foo: 123 });\n    });\n    it('returns the value parsed by `fromJson`', async () => {\n        expect.assertions(1);\n        fromJson.mockReturnValueOnce({ result: 456 });\n        await expect(makeHttpRequest({ payload: { foo: 123 } })).resolves.toEqual({ result: 456 });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__tests__/http-transport-headers-test.ts",
    "content": "import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, SolanaError } from '@solana/errors';\nimport { RpcTransport } from '@solana/rpc-spec';\n\nimport { assertIsAllowedHttpRequestHeaders } from '../http-transport-headers';\n\n// HACK: Pierce the veil of `jest.isolateModules` so that the modules inside get the same version of\n//       `@solana/errors` that is imported above.\njest.mock('@solana/errors', () => jest.requireActual('@solana/errors'));\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('assertIsAllowedHttpRequestHeader', () => {\n    [\n        'Accept-Charset',\n        'Accept-charset',\n        'accept-charset',\n        'ACCEPT-CHARSET',\n        'Access-Control-Request-Headers',\n        'Access-Control-Request-Method',\n        'Connection',\n        'Content-Length',\n        'Cookie',\n        'Date',\n        'DNT',\n        'Expect',\n        'Host',\n        'Keep-Alive',\n        'Permissions-Policy',\n        'Proxy-Anything',\n        'Proxy-Authenticate',\n        'Proxy-Authorization',\n        'Sec-Fetch-Dest',\n        'Sec-Fetch-Mode',\n        'Sec-Fetch-Site',\n        'Sec-Fetch-User',\n        'Referer',\n        'TE',\n        'Trailer',\n        'Transfer-Encoding',\n        'Upgrade',\n        'Via',\n    ].forEach(forbiddenHeader => {\n        it('throws when called with the forbidden header `' + forbiddenHeader + '`', () => {\n            expect(() => {\n                assertIsAllowedHttpRequestHeaders({ [forbiddenHeader]: 'value' });\n            }).toThrow(\n                new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n                    headers: [forbiddenHeader],\n                }),\n            );\n        });\n    });\n    if (!__NODEJS__) {\n        it('throws when called with the `Accept-Encoding` header', () => {\n            expect(() => {\n                assertIsAllowedHttpRequestHeaders({ 'Accept-Encoding': 'zstd' });\n            }).toThrow(\n                new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n                    headers: ['Accept-Encoding'],\n                }),\n            );\n        });\n    }\n    if (__BROWSER__) {\n        it('throws when called with the `Origin` header', () => {\n            expect(() => {\n                assertIsAllowedHttpRequestHeaders({ Origin: 'https://spoofed.site' });\n            }).toThrow(\n                new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n                    headers: ['Origin'],\n                }),\n            );\n        });\n    }\n    ['Authorization', 'Content-Language', 'Solana-Client'].forEach(allowedHeader => {\n        it('does not throw when called with the header `' + allowedHeader + '`', () => {\n            expect(() => {\n                assertIsAllowedHttpRequestHeaders({ [allowedHeader]: 'value' });\n            }).not.toThrow();\n        });\n    });\n});\n\ndescribe('createHttpRequest with custom headers', () => {\n    let createHttpTransport: typeof import('../http-transport').createHttpTransport;\n    let fetchSpy: jest.SpyInstance;\n    beforeEach(async () => {\n        await jest.isolateModulesAsync(async () => {\n            fetchSpy = jest.spyOn(globalThis, 'fetch').mockReturnValue(FOREVER_PROMISE as Promise<Response>);\n            const httpTransportModule =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                await import('../http-transport');\n            createHttpTransport = httpTransportModule.createHttpTransport;\n        });\n    });\n    it('is impossible to override the `Accept` header', () => {\n        const makeHttpRequest = createHttpTransport({\n            headers: { aCcEpT: 'text/html' },\n            url: 'http://localhost',\n        });\n        makeHttpRequest({ payload: 123 }).catch(() => {});\n        expect(fetchSpy).toHaveBeenCalledWith(\n            expect.anything(),\n            expect.objectContaining({\n                headers: expect.objectContaining({\n                    accept: 'application/json',\n                }),\n            }),\n        );\n    });\n    it('is impossible to override the `Content-Length` header', () => {\n        const makeHttpRequest = createHttpTransport({\n            headers: { 'cOnTeNt-LeNgTh': '420' },\n            url: 'http://localhost',\n        });\n        makeHttpRequest({ payload: 123 }).catch(() => {});\n        expect(fetchSpy).toHaveBeenCalledWith(\n            expect.anything(),\n            expect.objectContaining({\n                headers: expect.objectContaining({\n                    'content-length': '3',\n                }),\n            }),\n        );\n    });\n    it('is impossible to override the `Content-Type` header', () => {\n        const makeHttpRequest = createHttpTransport({\n            headers: { 'cOnTeNt-TyPe': 'text/html' },\n            url: 'http://localhost',\n        });\n        makeHttpRequest({ payload: 123 }).catch(() => {});\n        expect(fetchSpy).toHaveBeenCalledWith(\n            expect.anything(),\n            expect.objectContaining({\n                headers: expect.objectContaining({\n                    'content-type': 'application/json; charset=utf-8',\n                }),\n            }),\n        );\n    });\n    describe('when configured with a forbidden header', () => {\n        let createTransportWithForbiddenHeaders: () => RpcTransport;\n        beforeEach(() => {\n            createTransportWithForbiddenHeaders = () =>\n                createHttpTransport({\n                    headers: { 'sEc-FeTcH-mOdE': 'no-cors' },\n                    url: 'http://localhost',\n                });\n        });\n        it('throws in dev mode', () => {\n            // eslint-disable-next-line @typescript-eslint/no-explicit-any\n            (globalThis as any).__DEV__ = true;\n            expect(createTransportWithForbiddenHeaders).toThrow(\n                new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n                    headers: ['sEc-FeTcH-mOdE'],\n                }),\n            );\n        });\n        it('does not throw in non-dev mode', () => {\n            // eslint-disable-next-line @typescript-eslint/no-explicit-any\n            (globalThis as any).__DEV__ = false;\n            expect(createTransportWithForbiddenHeaders).not.toThrow();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__tests__/http-transport-test.ts",
    "content": "import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SolanaError } from '@solana/errors';\nimport { RpcTransport } from '@solana/rpc-spec';\n\n// HACK: Pierce the veil of `jest.isolateModules` so that the modules inside get the same version of\n//       `@solana/errors` that is imported above.\njest.mock('@solana/errors', () => jest.requireActual('@solana/errors'));\n\ndescribe('createHttpTransport', () => {\n    let fetchSpy: jest.SpyInstance;\n    let makeHttpRequest: RpcTransport;\n    beforeEach(async () => {\n        await jest.isolateModulesAsync(async () => {\n            fetchSpy = jest.spyOn(globalThis, 'fetch');\n            const { createHttpTransport } =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                await import('../http-transport');\n            makeHttpRequest = createHttpTransport({ url: 'http://localhost' });\n        });\n    });\n    describe('when the endpoint returns a non-200 status code', () => {\n        let expectedHeaders: Headers;\n        beforeEach(() => {\n            expectedHeaders = new Headers([['Sekrit-Response-Header', 'doNotLog']]);\n            fetchSpy.mockResolvedValue({\n                headers: expectedHeaders,\n                ok: false,\n                status: 404,\n                statusText: 'We looked everywhere',\n            });\n        });\n        it('throws HTTP errors', async () => {\n            expect.assertions(1);\n            const requestPromise = makeHttpRequest({ payload: 123 });\n            await expect(requestPromise).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {\n                    headers: expectedHeaders,\n                    message: 'We looked everywhere',\n                    statusCode: 404,\n                }),\n            );\n        });\n        it('exposes the response headers on the error context', async () => {\n            expect.assertions(2);\n            let thrownError!: SolanaError<typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR>;\n            try {\n                await makeHttpRequest({ payload: 123 });\n            } catch (e) {\n                thrownError = e as SolanaError<typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR>;\n            }\n            expect(thrownError).toBeDefined();\n            expect(thrownError.context.headers).toBe(expectedHeaders);\n        });\n        it('does not leak the response header values through the error message', async () => {\n            expect.assertions(2);\n            let thrownError!: SolanaError<typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR>;\n            try {\n                await makeHttpRequest({ payload: 123 });\n            } catch (e) {\n                thrownError = e as SolanaError<typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR>;\n            }\n            expect(thrownError).toBeDefined();\n            expect(thrownError.message).not.toMatch(/doNotLog/);\n        });\n        it('the `Headers` on the error context do not leak the header values when stringified', async () => {\n            expect.assertions(2);\n            let thrownError!: SolanaError<typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR>;\n            try {\n                await makeHttpRequest({ payload: 123 });\n            } catch (e) {\n                thrownError = e as SolanaError<typeof SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR>;\n            }\n            expect(thrownError).toBeDefined();\n            // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n            expect(`${thrownError.context.headers}`).not.toMatch(/doNotLog/);\n        });\n    });\n    describe('when the transport fatals', () => {\n        beforeEach(() => {\n            fetchSpy.mockRejectedValue(new TypeError('Failed to fetch'));\n        });\n        it('passes the exception through', async () => {\n            expect.assertions(1);\n            await expect(makeHttpRequest({ payload: 123 })).rejects.toThrow(new TypeError('Failed to fetch'));\n        });\n    });\n    describe('when the endpoint returns a well-formed JSON response', () => {\n        beforeEach(() => {\n            fetchSpy.mockResolvedValue({\n                json: () => ({ ok: true }),\n                ok: true,\n            });\n        });\n        it('calls fetch with the specified URL', () => {\n            makeHttpRequest({ payload: 123 }).catch(() => {});\n            expect(fetchSpy).toHaveBeenCalledWith('http://localhost', expect.anything());\n        });\n        it('sets the `body` to a stringfied version of the payload', () => {\n            makeHttpRequest({ payload: { ok: true } }).catch(() => {});\n            expect(fetchSpy).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    body: JSON.stringify({ ok: true }),\n                }),\n            );\n        });\n        it('sets the accept header to `application/json`', () => {\n            makeHttpRequest({ payload: 123 }).catch(() => {});\n            expect(fetchSpy).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    headers: expect.objectContaining({\n                        accept: 'application/json',\n                    }),\n                }),\n            );\n        });\n        it('sets the content type header to `application/json; charset=utf-8`', () => {\n            makeHttpRequest({ payload: 123 }).catch(() => {});\n            expect(fetchSpy).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    headers: expect.objectContaining({\n                        'content-type': 'application/json; charset=utf-8',\n                    }),\n                }),\n            );\n        });\n        it('sets the content length header to the length of the JSON-stringified payload', () => {\n            makeHttpRequest({\n                payload:\n                    // Shruggie: https://emojipedia.org/person-shrugging/\n                    '\\xAF\\\\\\x5F\\x28\\u30C4\\x29\\x5F\\x2F\\xAF' +\n                    ' ' +\n                    // https://emojipedia.org/waving-hand-medium-skin-tone/\n                    '\\u{1F44B}\\u{1F3FD}' +\n                    ' ' +\n                    // https://tinyurl.com/bdemuf3r\n                    '\\u{1F469}\\u{1F3FB}\\u200D\\u2764\\uFE0F\\u200D\\u{1F469}\\u{1F3FF}',\n            }).catch(() => {});\n            expect(fetchSpy).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    headers: expect.objectContaining({\n                        'content-length': '30',\n                    }),\n                }),\n            );\n        });\n        it('sets the `method` to `POST`', () => {\n            makeHttpRequest({ payload: 123 }).catch(() => {});\n            expect(fetchSpy).toHaveBeenCalledWith(\n                expect.anything(),\n                expect.objectContaining({\n                    method: 'POST',\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__tests__/http-transport-to-json-test.ts",
    "content": "import { RpcTransport } from '@solana/rpc-spec';\n\ndescribe('createHttpTransport and `toJson` function', () => {\n    let toJson: jest.Mock;\n    let fetchSpy: jest.SpyInstance;\n    let makeHttpRequest: RpcTransport;\n    beforeEach(async () => {\n        await jest.isolateModulesAsync(async () => {\n            toJson = jest.fn(value => JSON.stringify(value));\n            fetchSpy = jest.spyOn(globalThis, 'fetch');\n            fetchSpy.mockResolvedValue({ json: () => ({ ok: true }), ok: true });\n            const { createHttpTransport } =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                await import('../http-transport');\n            makeHttpRequest = createHttpTransport({ toJson, url: 'http://localhost' });\n        });\n    });\n    it('uses the `toJson` function to transform the payload to a JSON string', () => {\n        makeHttpRequest({ payload: { foo: 123 } }).catch(() => {});\n        expect(toJson).toHaveBeenCalledWith({ foo: 123 });\n    });\n    it('uses passes the JSON string to the fetch API', () => {\n        toJson.mockReturnValueOnce('{\"someAugmented\":\"jsonString\"}');\n        makeHttpRequest({ payload: { foo: 123 } }).catch(() => {});\n        expect(fetchSpy).toHaveBeenCalledWith(\n            expect.anything(),\n            expect.objectContaining({\n                body: '{\"someAugmented\":\"jsonString\"}',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__tests__/is-solana-request-test.ts",
    "content": "import { isSolanaRequest } from '../is-solana-request';\n\ndescribe('isSolanaRequest', () => {\n    it('returns true if the method name is from the Solana RPC API', () => {\n        const payload = { jsonrpc: '2.0', method: 'getBalance', params: ['1234..5678'] };\n        expect(isSolanaRequest(payload)).toBe(true);\n    });\n    it('returns false if the method name is not from the Solana RPC API', () => {\n        const payload = { jsonrpc: '2.0', method: 'getAssetsByAuthority', params: ['1234..5678'] };\n        expect(isSolanaRequest(payload)).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/rpc-transport-http/src/__typetests__/http-transport-typetest.ts",
    "content": "import { RpcTransport } from '@solana/rpc-spec';\n\nimport { createHttpTransport } from '../http-transport';\n\nconst url = 'http://localhost:8899';\n\ncreateHttpTransport({ url }) satisfies RpcTransport;\n"
  },
  {
    "path": "packages/rpc-transport-http/src/http-transport-config.ts",
    "content": "import { RpcResponse } from '@solana/rpc-spec-types';\nimport { Dispatcher } from 'undici-types';\n\nimport { AllowedHttpRequestHeaders } from './http-transport-headers';\n\nexport type HttpTransportConfig = Readonly<{\n    /**\n     * In Node environments you can tune how requests are dispatched to the network. Use this config\n     * parameter to install a\n     * [`undici.Dispatcher`](https://undici.nodejs.org/#/docs/api/Agent) in your transport.\n     *\n     * @example\n     * ```ts\n     * import { createHttpTransport } from '@solana/rpc-transport-http';\n     * import { Agent, BalancedPool } from 'undici';\n     *\n     * // Create a dispatcher that, when called with a special URL, creates a round-robin pool of RPCs.\n     * const dispatcher = new Agent({\n     *     factory(origin, opts) {\n     *         if (origin === 'https://mypool') {\n     *             const upstreams = [\n     *                 'https://api.mainnet-beta.solana.com',\n     *                 'https://mainnet.helius-rpc.com',\n     *                 'https://several-neat-iguana.quiknode.pro',\n     *             ];\n     *             return new BalancedPool(upstreams, {\n     *                 ...opts,\n     *                 bodyTimeout: 60e3,\n     *                 headersTimeout: 5e3,\n     *                 keepAliveTimeout: 19e3,\n     *             });\n     *         } else {\n     *             return new Pool(origin, opts);\n     *         }\n     *     },\n     * });\n     * const transport = createHttpTransport({\n     *     dispatcher_NODE_ONLY: dispatcher,\n     *     url: 'https://mypool',\n     * });\n     * let id = 0;\n     * const balances = await Promise.allSettled(\n     *     accounts.map(async account => {\n     *         const response = await transport({\n     *             payload: {\n     *                 id: ++id,\n     *                 jsonrpc: '2.0',\n     *                 method: 'getBalance',\n     *                 params: [account],\n     *             },\n     *         });\n     *         return await response.json();\n     *     }),\n     * );\n     * ```\n     */\n    dispatcher_NODE_ONLY?: Dispatcher;\n    /**\n     * An optional function that takes the response as a JSON string and converts it to a JSON\n     * value.\n     *\n     * The request payload is also provided as a second argument.\n     *\n     * @defaultValue When not provided, the JSON value will be accessed via the `response.json()`\n     * method of the fetch API.\n     */\n    fromJson?: (rawResponse: string, payload: unknown) => RpcResponse;\n    /**\n     * An object of headers to set on the request.\n     *\n     * Avoid\n     * [forbidden headers](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name).\n     * Additionally, the headers `Accept`, `Content-Length`, and `Content-Type` are disallowed.\n     *\n     * @example\n     * ```ts\n     * import { createHttpTransport } from '@solana/rpc-transport-http';\n     *\n     * const transport = createHttpTransport({\n     *     headers: {\n     *         // Authorize with the RPC using a bearer token\n     *         Authorization: `Bearer ${process.env.RPC_AUTH_TOKEN}`,\n     *     },\n     *     url: 'https://several-neat-iguana.quiknode.pro',\n     * });\n     * ```\n     */\n    headers?: AllowedHttpRequestHeaders;\n    /**\n     * An optional function that takes the request payload and converts it to a JSON string.\n     *\n     * @defaultValue When not provided, `JSON.stringify` will be used.\n     */\n    toJson?: (payload: unknown) => string;\n    /**\n     * A string representing the target endpoint.\n     *\n     * In Node, it must be an absolute URL using the `http` or `https` protocol.\n     */\n    url: string;\n}>;\n"
  },
  {
    "path": "packages/rpc-transport-http/src/http-transport-for-solana-rpc.ts",
    "content": "import { RpcTransport } from '@solana/rpc-spec';\nimport { parseJsonWithBigInts, stringifyJsonWithBigInts } from '@solana/rpc-spec-types';\n\nimport { createHttpTransport } from './http-transport';\nimport { HttpTransportConfig } from './http-transport-config';\nimport { isSolanaRequest } from './is-solana-request';\n\ntype Config = Pick<HttpTransportConfig, 'dispatcher_NODE_ONLY' | 'headers' | 'url'>;\n\n/**\n * Creates a {@link RpcTransport} that uses JSON HTTP requests — much like the\n * {@link createHttpTransport} function - except that it also uses custom `toJson` and `fromJson`\n * functions in order to allow `bigint` values to be serialized and deserialized correctly over the\n * wire.\n *\n * Since this is something specific to the Solana RPC API, these custom JSON functions are only\n * triggered when the request is recognized as a Solana RPC request. Normal RPC APIs should aim to\n * wrap their `bigint` values — e.g. `u64` or `i64` — in special value objects that represent the\n * number as a string to avoid numerical values going above `Number.MAX_SAFE_INTEGER`.\n *\n * It has the same configuration options as {@link createHttpTransport}, but without the `fromJson`\n * and `toJson` options.\n */\nexport function createHttpTransportForSolanaRpc(config: Config): RpcTransport {\n    return createHttpTransport({\n        ...config,\n        fromJson: (rawResponse: string, payload: unknown) =>\n            isSolanaRequest(payload) ? parseJsonWithBigInts(rawResponse) : JSON.parse(rawResponse),\n        toJson: (payload: unknown) =>\n            isSolanaRequest(payload) ? stringifyJsonWithBigInts(payload) : JSON.stringify(payload),\n    });\n}\n"
  },
  {
    "path": "packages/rpc-transport-http/src/http-transport-headers.ts",
    "content": "import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, SolanaError } from '@solana/errors';\n\nexport type AllowedHttpRequestHeaders = Readonly<\n    {\n        // Someone can still sneak a forbidden header past Typescript if they do something like\n        // fOo-BaR, but at that point they deserve the runtime failure.\n        [K in DisallowedHeaders | ForbiddenHeaders as\n            | Capitalize<Lowercase<K>> // `Foo-bar`\n            | K // `Foo-Bar`\n            | Lowercase<K> // `foo-bar`\n            | Uncapitalize<K> // `foo-Bar`\n            // `FOO-BAR`\n            | Uppercase<K>]?: never;\n    } & { [headerName: string]: string }\n>;\n// These are headers that we simply don't allow the developer to override because they're\n// fundamental to the operation of the JSON-RPC transport.\ntype DisallowedHeaders = 'Accept' | 'Content-Length' | 'Content-Type' | 'Solana-Client';\ntype ForbiddenHeaders =\n    | 'Accept-Charset'\n    // Though technically forbidden in non-Node environments, we don't have a way to target\n    // TypeScript types depending on which platform you are authoring for. `Accept-Encoding` is\n    // therefore omitted from the forbidden headers type, but is still a runtime error in dev mode\n    // when supplied in a non-Node context.\n    // | 'Accept-Encoding'\n    | 'Access-Control-Request-Headers'\n    | 'Access-Control-Request-Method'\n    | 'Connection'\n    | 'Content-Length'\n    | 'Cookie'\n    | 'Date'\n    | 'DNT'\n    | 'Expect'\n    | 'Host'\n    | 'Keep-Alive'\n    // Similar to `Accept-Encoding`, we don't have a way to target TypeScript types depending on\n    // which platform you are authoring for. `Origin` is therefore omitted from the forbidden\n    // headers type, but is still a runtime error in dev mode when supplied in a browser context.\n    // | 'Origin'\n    | 'Permissions-Policy'\n    | 'Referer'\n    | 'TE'\n    | 'Trailer'\n    | 'Transfer-Encoding'\n    | 'Upgrade'\n    | 'Via'\n    | `Proxy-${string}`\n    | `Sec-${string}`;\n\n// These are headers which are fundamental to the JSON-RPC transport, and must not be modified.\nconst DISALLOWED_HEADERS: Record<string, boolean> = {\n    accept: true,\n    'content-length': true,\n    'content-type': true,\n};\n// https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name\nconst FORBIDDEN_HEADERS: Record<string, boolean> = /* @__PURE__ */ Object.assign(\n    {\n        'accept-charset': true,\n        'access-control-request-headers': true,\n        'access-control-request-method': true,\n        connection: true,\n        'content-length': true,\n        cookie: true,\n        date: true,\n        dnt: true,\n        expect: true,\n        host: true,\n        'keep-alive': true,\n        'permissions-policy': true,\n        // Prefix matching is implemented in code, below.\n        // 'proxy-': true,\n        // 'sec-': true,\n        referer: true,\n        te: true,\n        trailer: true,\n        'transfer-encoding': true,\n        upgrade: true,\n        via: true,\n    },\n    __NODEJS__ ? undefined : { 'accept-encoding': true },\n    __BROWSER__ ? { origin: true } : undefined,\n);\n\nexport function assertIsAllowedHttpRequestHeaders(\n    headers: Record<string, string>,\n): asserts headers is AllowedHttpRequestHeaders {\n    const badHeaders = Object.keys(headers).filter(headerName => {\n        const lowercaseHeaderName = headerName.toLowerCase();\n        return (\n            DISALLOWED_HEADERS[headerName.toLowerCase()] === true ||\n            FORBIDDEN_HEADERS[headerName.toLowerCase()] === true ||\n            lowercaseHeaderName.startsWith('proxy-') ||\n            lowercaseHeaderName.startsWith('sec-')\n        );\n    });\n    if (badHeaders.length > 0) {\n        throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_HEADER_FORBIDDEN, {\n            headers: badHeaders,\n        });\n    }\n}\n\n// Lowercasing header names makes it easier to override user-supplied headers, such as those defined\n// in the `DisallowedHeaders` type.\nexport function normalizeHeaders<T extends Record<string, string>>(\n    headers: T,\n): { [K in string & keyof T as Lowercase<K>]: T[K] } {\n    const out: Record<string, string> = {};\n    for (const headerName in headers) {\n        out[headerName.toLowerCase()] = headers[headerName];\n    }\n    return out as { [K in string & keyof T as Lowercase<K>]: T[K] };\n}\n"
  },
  {
    "path": "packages/rpc-transport-http/src/http-transport.ts",
    "content": "import { SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, SolanaError } from '@solana/errors';\nimport type { RpcTransport } from '@solana/rpc-spec';\nimport type { RpcResponse } from '@solana/rpc-spec-types';\nimport type Dispatcher from 'undici-types/dispatcher';\n\nimport { HttpTransportConfig as Config } from './http-transport-config';\nimport { assertIsAllowedHttpRequestHeaders, normalizeHeaders } from './http-transport-headers';\n\nlet didWarnDispatcherWasSuppliedInNonNodeEnvironment = false;\nfunction warnDispatcherWasSuppliedInNonNodeEnvironment() {\n    if (didWarnDispatcherWasSuppliedInNonNodeEnvironment) {\n        return;\n    }\n    didWarnDispatcherWasSuppliedInNonNodeEnvironment = true;\n    console.warn(\n        'You have supplied a `Dispatcher` to `createHttpTransport()`. It has been ignored ' +\n            'because Undici dispatchers only work in Node environments. To eliminate this ' +\n            'warning, omit the `dispatcher_NODE_ONLY` property from your config when running in ' +\n            'a non-Node environment.',\n    );\n}\n\n/**\n * Creates a function you can use to make `POST` requests with headers suitable for sending JSON\n * data to a server.\n *\n * @example\n * ```ts\n * import { createHttpTransport } from '@solana/rpc-transport-http';\n *\n * const transport = createHttpTransport({ url: 'https://api.mainnet-beta.solana.com' });\n * const response = await transport({\n *     payload: { id: 1, jsonrpc: '2.0', method: 'getSlot' },\n * });\n * const data = await response.json();\n * ```\n */\nexport function createHttpTransport(config: Config): RpcTransport {\n    if (__DEV__ && !__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n        warnDispatcherWasSuppliedInNonNodeEnvironment();\n    }\n    const { fromJson, headers, toJson, url } = config;\n    if (__DEV__ && headers) {\n        assertIsAllowedHttpRequestHeaders(headers);\n    }\n    let dispatcherConfig: { dispatcher: Dispatcher | undefined } | undefined;\n    if (__NODEJS__ && 'dispatcher_NODE_ONLY' in config) {\n        dispatcherConfig = { dispatcher: config.dispatcher_NODE_ONLY };\n    }\n    const customHeaders = headers && normalizeHeaders(headers);\n    return async function makeHttpRequest<TResponse>({\n        payload,\n        signal,\n    }: Parameters<RpcTransport>[0]): Promise<RpcResponse<TResponse>> {\n        const body = toJson ? toJson(payload) : JSON.stringify(payload);\n        const requestInfo = {\n            ...dispatcherConfig,\n            body,\n            headers: {\n                ...customHeaders,\n                // Keep these headers lowercase so they will override any user-supplied headers above.\n                accept: 'application/json',\n                'content-length': body.length.toString(),\n                'content-type': 'application/json; charset=utf-8',\n            },\n            method: 'POST',\n            signal,\n        };\n        const response = await fetch(url, requestInfo);\n        if (!response.ok) {\n            throw new SolanaError(SOLANA_ERROR__RPC__TRANSPORT_HTTP_ERROR, {\n                headers: response.headers,\n                message: response.statusText,\n                statusCode: response.status,\n            });\n        }\n        if (fromJson) {\n            return fromJson(await response.text(), payload) as TResponse;\n        }\n        return await response.json();\n    };\n}\n"
  },
  {
    "path": "packages/rpc-transport-http/src/index.ts",
    "content": "/**\n * This package allows developers to create custom RPC transports. Using these primitives,\n * developers can create custom transports that perform transforms on messages sent and received,\n * attempt retries, and implement routing strategies between multiple transports.\n *\n * ## Augmenting Transports\n *\n * Using this core transport, you can implement specialized functionality for leveraging multiple\n * transports, attempting/handling retries, and more.\n *\n * ### Round Robin\n *\n * Here’s an example of how someone might implement a “round robin” approach to distribute requests\n * to multiple transports:\n *\n * ```ts\n * import { RpcTransport } from '@solana/rpc-spec';\n * import { RpcResponse } from '@solana/rpc-spec-types';\n * import { createHttpTransport } from '@solana/rpc-transport-http';\n *\n * // Create a transport for each RPC server\n * const transports = [\n *     createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' }),\n *     createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),\n *     createHttpTransport({ url: 'https://mainnet-beta.my-server-3.com' }),\n * ];\n *\n * // Create a wrapper transport that distributes requests to them\n * let nextTransport = 0;\n * async function roundRobinTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {\n *     const transport = transports[nextTransport];\n *     nextTransport = (nextTransport + 1) % transports.length;\n *     return await transport(...args);\n * }\n * ```\n *\n * ### Sharding\n *\n * Another example of a possible customization for a transport is to shard requests\n * deterministically among a set of servers. Here’s an example:\n *\n * Perhaps your application needs to make a large number of requests, or needs to fan request for\n * different methods out to different servers. Here’s an example of an implementation that does the\n * latter:\n *\n * ```ts\n * import { RpcTransport } from '@solana/rpc-spec';\n * import { RpcResponse } from '@solana/rpc-spec-types';\n * import { createHttpTransport } from '@solana/rpc-transport-http';\n *\n * // Create multiple transports\n * const transportA = createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' });\n * const transportB = createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' });\n * const transportC = createHttpTransport({ url: 'https://mainnet-beta.my-server-3.com' });\n * const transportD = createHttpTransport({ url: 'https://mainnet-beta.my-server-4.com' });\n *\n * // Function to determine which shard to use based on the request method\n * function selectShard(method: string): RpcTransport {\n *     switch (method) {\n *         case 'getAccountInfo':\n *         case 'getBalance':\n *             return transportA;\n *         case 'getLatestBlockhash':\n *         case 'getTransaction':\n *             return transportB;\n *         case 'sendTransaction':\n *             return transportC;\n *         default:\n *             return transportD;\n *     }\n * }\n *\n * async function shardingTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {\n *     const payload = args[0].payload as { method: string };\n *     const selectedTransport = selectShard(payload.method);\n *     return await selectedTransport(...args);\n * }\n * ```\n *\n * ### Retry Logic\n *\n * The transport library can also be used to implement custom retry logic on any request:\n *\n * ```ts\n * import { RpcTransport } from '@solana/rpc-spec';\n * import { RpcResponse } from '@solana/rpc-spec-types';\n * import { createHttpTransport } from '@solana/rpc-transport-http';\n *\n * // Set the maximum number of attempts to retry a request\n * const MAX_ATTEMPTS = 4;\n *\n * // Create the default transport\n * const defaultTransport = createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' });\n *\n * // Sleep function to wait for a given number of milliseconds\n * function sleep(ms: number): Promise<void> {\n *     return new Promise(resolve => setTimeout(resolve, ms));\n * }\n *\n * // Calculate the delay for a given attempt\n * function calculateRetryDelay(attempt: number): number {\n *     // Exponential backoff with a maximum of 1.5 seconds\n *     return Math.min(100 * Math.pow(2, attempt), 1500);\n * }\n *\n * // A retrying transport that will retry up to `MAX_ATTEMPTS` times before failing\n * async function retryingTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {\n *     let requestError;\n *     for (let attempts = 0; attempts < MAX_ATTEMPTS; attempts++) {\n *         try {\n *             return await defaultTransport(...args);\n *         } catch (err) {\n *             requestError = err;\n *             // Only sleep if we have more attempts remaining\n *             if (attempts < MAX_ATTEMPTS - 1) {\n *                 const retryDelay = calculateRetryDelay(attempts);\n *                 await sleep(retryDelay);\n *             }\n *         }\n *     }\n *     throw requestError;\n * }\n * ```\n *\n * ### Failover\n *\n * Here’s an example of some failover logic integrated into a transport:\n *\n * ```ts\n * import { RpcTransport } from '@solana/rpc-spec';\n * import { RpcResponse } from '@solana/rpc-spec-types';\n * import { createHttpTransport } from '@solana/rpc-transport-http';\n *\n * // Create a transport for each RPC server\n * const transports = [\n *     createHttpTransport({ url: 'https://mainnet-beta.my-server-1.com' }),\n *     createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),\n *     createHttpTransport({ url: 'https://mainnet-beta.my-server-2.com' }),\n * ];\n *\n * // A failover transport that will try each transport in order until one succeeds before failing\n * async function failoverTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {\n *     let requestError;\n *\n *     for (const transport of transports) {\n *         try {\n *             return await transport(...args);\n *         } catch (err) {\n *             requestError = err;\n *             console.error(err);\n *         }\n *     }\n *     throw requestError;\n * }\n * ```\n *\n * @packageDocumentation\n */\nexport * from './http-transport';\nexport * from './http-transport-for-solana-rpc';\n"
  },
  {
    "path": "packages/rpc-transport-http/src/is-solana-request.ts",
    "content": "import { isJsonRpcPayload } from '@solana/rpc-spec';\n\nconst SOLANA_RPC_METHODS = [\n    'getAccountInfo',\n    'getBalance',\n    'getBlock',\n    'getBlockCommitment',\n    'getBlockHeight',\n    'getBlockProduction',\n    'getBlocks',\n    'getBlocksWithLimit',\n    'getBlockTime',\n    'getClusterNodes',\n    'getEpochInfo',\n    'getEpochSchedule',\n    'getFeeForMessage',\n    'getFirstAvailableBlock',\n    'getGenesisHash',\n    'getHealth',\n    'getHighestSnapshotSlot',\n    'getIdentity',\n    'getInflationGovernor',\n    'getInflationRate',\n    'getInflationReward',\n    'getLargestAccounts',\n    'getLatestBlockhash',\n    'getLeaderSchedule',\n    'getMaxRetransmitSlot',\n    'getMaxShredInsertSlot',\n    'getMinimumBalanceForRentExemption',\n    'getMultipleAccounts',\n    'getProgramAccounts',\n    'getRecentPerformanceSamples',\n    'getRecentPrioritizationFees',\n    'getSignaturesForAddress',\n    'getSignatureStatuses',\n    'getSlot',\n    'getSlotLeader',\n    'getSlotLeaders',\n    'getStakeMinimumDelegation',\n    'getSupply',\n    'getTokenAccountBalance',\n    'getTokenAccountsByDelegate',\n    'getTokenAccountsByOwner',\n    'getTokenLargestAccounts',\n    'getTokenSupply',\n    'getTransaction',\n    'getTransactionCount',\n    'getVersion',\n    'getVoteAccounts',\n    'index',\n    'isBlockhashValid',\n    'minimumLedgerSlot',\n    'requestAirdrop',\n    'sendTransaction',\n    'simulateTransaction',\n] as const;\n\n/**\n * Helper function that checks if a given `RpcRequest` comes from the Solana RPC API.\n */\nexport function isSolanaRequest(payload: unknown): payload is Readonly<{\n    jsonrpc: '2.0';\n    method: (typeof SOLANA_RPC_METHODS)[number];\n    params: unknown;\n}> {\n    return isJsonRpcPayload(payload) && (SOLANA_RPC_METHODS as readonly string[]).includes(payload.method);\n}\n"
  },
  {
    "path": "packages/rpc-transport-http/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-transport-http/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-transport-http\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-transport-http/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/rpc-types/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/rpc-types/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/rpc-types/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/rpc-types/CHANGELOG.md",
    "content": "# @solana/rpc-types\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n- [#1578](https://github.com/anza-xyz/kit/pull/1578) [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `Sol`, `sol()`, `solToLamports`, and `lamportsToSol` helpers for converting between SOL amounts expressed as `@solana/fixed-points` values and `Lamports` branded bigints. Also add `getSolEncoder`, `getSolDecoder`, and `getSolCodec` for serializing SOL amounts to bytes (the encoder accepts both `Sol` and `Lamports` inputs; the decoder always returns `Sol`). Finally, update `getLamportsEncoder`/`getDefaultLamportsEncoder` and their codec counterparts to also accept `Sol` as input.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`c5e0e14`](https://github.com/anza-xyz/kit/commit/c5e0e1444ae420390047d5e37a13650edf042954), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/fixed-points@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-numbers@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/nominal-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/nominal-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/nominal-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-numbers@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/nominal-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/nominal-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/nominal-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/nominal-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-numbers@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/nominal-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/nominal-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-numbers@6.1.0\n    - @solana/codecs-strings@6.1.0\n    - @solana/nominal-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-numbers@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/nominal-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-numbers@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/nominal-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-numbers@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/nominal-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-numbers@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/nominal-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-numbers@5.4.0\n    - @solana/codecs-strings@5.4.0\n    - @solana/nominal-types@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-numbers@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/nominal-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-numbers@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/nominal-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/codecs-numbers@5.1.0\n    - @solana/nominal-types@5.1.0\n\n## 5.0.0\n\n### Major Changes\n\n- [#974](https://github.com/anza-xyz/kit/pull/974) [`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389) Thanks [@joncinque](https://github.com/joncinque)! - `BorshIoErrors` from the RPC no longer contain an `encodedData` property. This property used to hold the underlying error from the serialization library used on the server. This message was always subject to changes in the version of that library, or changes in the choice of library itself. New versions of the server no longer throw the underlying error, so for consistency it has been removed everywhere in Kit.\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-numbers@5.0.0\n    - @solana/codecs-strings@5.0.0\n    - @solana/nominal-types@5.0.0\n\n## 4.0.0\n\n### Major Changes\n\n- [#550](https://github.com/anza-xyz/kit/pull/550) [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a) Thanks [@steveluscher](https://github.com/steveluscher)! - Removed `rentEpoch` from the `AccountInfoBase` type. This property is no longer relevant post SIMD-215. Developers whose applications rely on this property being numeric should either eliminate it or hardcode it to `18_446_744_073_709_551_615n`.\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/codecs-numbers@4.0.0\n    - @solana/codecs-strings@4.0.0\n    - @solana/nominal-types@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/errors@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/codecs-numbers@3.0.0\n    - @solana/codecs-strings@3.0.0\n    - @solana/nominal-types@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-numbers@2.3.0\n    - @solana/codecs-strings@2.3.0\n    - @solana/nominal-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-numbers@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/nominal-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893), [`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/nominal-types@2.2.0\n    - @solana/addresses@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-numbers@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#433](https://github.com/anza-xyz/kit/pull/433) [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a) Thanks [@steveluscher](https://github.com/steveluscher)! - Corrected a misspelling of `readonlyIndexes` in the `AddressLookupTable` type. This fixes the return type of the `getTransaction` RPC call.\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-numbers@2.1.1\n    - @solana/codecs-strings@2.1.1\n    - @solana/nominal-types@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add missing `space` attribute to `AccountInfoBase` and `BaseAccount`\n\n- [#153](https://github.com/anza-xyz/kit/pull/153) [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a) Thanks [@steveluscher](https://github.com/steveluscher)! - The values of the `rewardType` property have been corrected. They previously were specified as having a lowercase initial character.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-numbers@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#3467](https://github.com/solana-labs/solana-web3.js/pull/3467) [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove `U64` and `I64` types in favour of `bigint`\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#3456](https://github.com/solana-labs/solana-web3.js/pull/3456) [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove `UnsafeBeyond2Pow53Minus1` type suffixes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#2866](https://github.com/solana-labs/solana-web3.js/pull/2866) [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677) Thanks [@steveluscher](https://github.com/steveluscher)! - The `TransactionInstruction` RPC type now has `stackHeight`\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/codecs-numbers@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-numbers@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-numbers@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3467](https://github.com/solana-labs/solana-web3.js/pull/3467) [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove `U64` and `I64` types in favour of `bigint`\n\n- [#3456](https://github.com/solana-labs/solana-web3.js/pull/3456) [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove `UnsafeBeyond2Pow53Minus1` type suffixes\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-numbers@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-numbers@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-numbers@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2866](https://github.com/solana-labs/solana-web3.js/pull/2866) [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677) Thanks [@steveluscher](https://github.com/steveluscher)! - The `TransactionInstruction` RPC type now has `stackHeight`\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/codecs-numbers@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#2411](https://github.com/solana-labs/solana-web3.js/pull/2411) [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `fixCodec` to `fixCodecSize`\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/codecs-numbers@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/addresses@2.0.0-preview.2\n    - @solana/codecs-numbers@2.0.0-preview.2\n    - @solana/codecs-strings@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/rpc-types/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/rpc-types/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/rpc-types?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/rpc-types?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/rpc-types\n\n# @solana/rpc-types\n\nThis package defines types for values used in the [Solana JSON-RPC](https://docs.solana.com/api/http) and a series of helpers for working with them. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\n## Types\n\n### `Commitment`\n\nA type that enumerates the possible commitment statuses &ndash; each a measure of the network confirmation and stake levels on a particular block. Read more about the statuses themselves, [here](https://docs.solana.com/cluster/commitments).\n\n### `Lamports`\n\nThis type represents an integer value denominated in Lamports (ie. $1 \\times 10^{-9}$ &#x25CE;). It is represented as a `bigint` in client code and an `u64` in server code.\n\n### `StringifiedBigInt`\n\nThis type represents a `bigint` which has been encoded as a string for transit over a transport that does not support `bigint` values natively. The JSON-RPC is such a transport.\n\n### `StringifiedNumber`\n\nThis type represents a number which has been encoded as a string for transit over a transport where loss of precision when using the native number type is a concern. The JSON-RPC is such a transport.\n\n### `UnixTimestamp`\n\nThis type represents a Unix timestamp in _seconds_. It is represented as a `bigint` in client code and an `i64` in server code.\n\n## Functions\n\n### `assertIsLamports()`\n\nLamport values returned from the RPC API conform to the type `Lamports`. You can use a value of that type wherever a quantity of Lamports is expected.\n\nFrom time to time you might acquire a number that you expect to be a quantity of Lamports, from an untrusted network API or user input. To assert that such an arbitrary number is usable as a quantity of Lamports, use the `assertIsLamports` function.\n\n```ts\nimport { assertIsLamports } from '@solana/rpc-types';\n\n// Imagine a function that creates a transfer instruction when a user submits a form.\nfunction handleSubmit() {\n    // We know only that what the user typed conforms to the `number` type.\n    const lamports: number = parseInt(quantityInput.value, 10);\n    try {\n        // If this type assertion function doesn't throw, then\n        // Typescript will upcast `lamports` to `Lamports`.\n        assertIsLamports(lamports);\n        // At this point, `lamports` is a `Lamports` that can be used anywhere Lamports are expected.\n        await transfer(fromAddress, toAddress, lamports);\n    } catch (e) {\n        // `lamports` turned out not to validate as a quantity of Lamports.\n    }\n}\n```\n\n### `assertIsStringifiedBigInt()`\n\nLarge integers returned from the RPC API encoded as strings conform to the type `StringifiedBigInt`.\n\nFrom time to time you might acquire a string that you suspect might validate as a `StringifiedBigInt`, from an untrusted network API or user input. To assert that such an arbitrary string is usable as a `StringifiedBigInt`, use the `assertIsStringifiedBigInt` function.\n\nSee [`assertIsLamports()`](#assertislamports) for an example of how to use an assertion function.\n\n### `assertIsStringifiedNumber()`\n\nLarge numbers returned from the RPC API encoded as strings conform to the type `StringifiedNumber`.\n\nFrom time to time you might acquire a string that you suspect might validate as a `StringifiedNumber`, from an untrusted network API or user input. To assert that such an arbitrary string is usable as a `StringifiedNumber`, use the `assertIsStringifiedNumber` function.\n\nSee [`assertIsLamports()`](#assertislamports) for an example of how to use an assertion function.\n\n### `assertIsUnixTimestamp()`\n\nTimestamps returned from the RPC API conform to the type `UnixTimestamp`.\n\nFrom time to time you might acquire a number that you suspect might validate as a `UnixTimestamp`, from an untrusted network API or user input. To assert that such an arbitrary number is usable as a `UnixTimestamp`, use the `assertIsUnixTimestamp` function.\n\nSee [`assertIsLamports()`](#assertislamports) for an example of how to use an assertion function.\n\n### `commitmentComparator()`\n\nA function that accepts two `Commitments` as input, and returns `-1` if the first is lower than the second, `0` if they are the same, and `1` if the second is higher than the first. You can use this comparator to sort items by commitment, or to determine an upper/lower bound on a level of commitment given two options.\n\n```ts\nimport { commitmentComparator } from '@solana/rpc-types';\n\ntransactions.sort((a, b) => commitmentComparator(a.confirmationStatus, b.confirmationStatus));\n```\n\n### `isLamports()`\n\nThis is a type guard that accepts a `bigint` as input. It will both return `true` if the integer conforms to the `Lamports` type and will refine the type for use in your program.\n\n```ts\nimport { isLamports } from '@solana/rpc-types';\n\nif (isLamports(lamports)) {\n    // At this point, `lamports` has been refined to a\n    // `Lamports` that can be used anywhere Lamports are expected.\n    await transfer(fromAddress, toAddress, lamports);\n} else {\n    setError(`${ownerAddress} is not an address`);\n}\n```\n\n### `isStringifiedBigInt()`\n\nThis is a type guard that accepts a string as input. It will both return `true` if the string can be parsed as a `bigint` and will refine the type for use in your program.\n\nSee [`isLamports()`](#islamports) for an example of how to use a type guard.\n\n### `isStringifiedNumber()`\n\nThis is a type guard that accepts a string as input. It will both return `true` if the string can be parsed as a JavaScript `Number` and will refine the type for use in your program.\n\nSee [`isLamports()`](#islamports) for an example of how to use a type guard.\n\n### `isUnixTimestamp()`\n\nThis is a type guard that accepts a number as input. It will both return `true` if the number is in the Unix timestamp range and will refine the type for use in your program.\n\nSee [`isLamports()`](#islamports) for an example of how to use a type guard.\n\n### `lamports()`\n\nThis helper combines _asserting_ that a number is a possible number of Lamports with _coercing_ it to the `Lamports` type. It's best used with untrusted input.\n\n```ts\nimport { lamports } from '@solana/rpc-types';\n\nawait transfer(address(fromAddress), address(toAddress), lamports(100000n));\n```\n\n### `stringifiedBigInt()`\n\nThis helper combines _asserting_ that a string represents a `bigint` with _coercing_ it to the `StringifiedBigInt` type. It's best used with untrusted input.\n\n### `stringifiedNumber()`\n\nThis helper combines _asserting_ that a string parses as a JavaScript `Number` with _coercing_ it to the `StringifiedNumber` type. It's best used with untrusted input.\n\n### `unixTimestamp()`\n\nThis helper combines _asserting_ that a number is in the Unix timestamp range with _coercing_ it to the `UnixTimestamp` type. It's best used with untrusted input.\n"
  },
  {
    "path": "packages/rpc-types/package.json",
    "content": "{\n    \"name\": \"@solana/rpc-types\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Type definitions for values used in the Solana RPC, and helper functions for working with them\",\n    \"homepage\": \"https://www.solanakit.com/api#solanarpc-types\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/fixed-points\": \"workspace:*\",\n        \"@solana/nominal-types\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/rpc-types/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/rpc-types/src/__tests__/blockhash-test.ts",
    "content": "import type { VariableSizeEncoder } from '@solana/codecs-core';\nimport { getBase58Decoder, getBase58Encoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE,\n    SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH,\n    SolanaError,\n} from '@solana/errors';\n\nimport { Blockhash, getBlockhashCodec, getBlockhashComparator } from '../blockhash';\n\njest.mock('@solana/codecs-strings', () => ({\n    ...jest.requireActual('@solana/codecs-strings'),\n    getBase58Decoder: jest.fn(),\n    getBase58Encoder: jest.fn(),\n}));\n// HACK: Pierce the veil of `jest.isolateModules` so that the modules inside get the same version of\n//       `@solana/errors` that is imported above.\njest.mock('@solana/errors', () => jest.requireActual('@solana/errors'));\n\n// real implementations\nconst originalBase58Module = jest.requireActual('@solana/codecs-strings');\nconst originalGetBase58Encoder = originalBase58Module.getBase58Encoder();\nconst originalGetBase58Decoder = originalBase58Module.getBase58Decoder();\n\ndescribe('assertIsBlockhash()', () => {\n    let assertIsBlockhash: typeof import('../blockhash').assertIsBlockhash;\n    // Reload `assertIsBlockhash` before each test to reset memoized state\n    beforeEach(async () => {\n        await jest.isolateModulesAsync(async () => {\n            const base58ModulePromise =\n                // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                // @ts-ignore\n                import('../blockhash');\n            assertIsBlockhash = (await base58ModulePromise).assertIsBlockhash;\n        });\n    });\n\n    describe('using the real base58 implementation', () => {\n        beforeEach(() => {\n            // use real implementation\n            jest.mocked(getBase58Encoder).mockReturnValue(originalGetBase58Encoder);\n        });\n\n        it('throws when supplied a non-base58 string', () => {\n            const badBlockhash = 'not-a-base-58-encoded-string-but-nice-try';\n            expect(() => {\n                assertIsBlockhash(badBlockhash);\n            }).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_STRING_FOR_BASE, {\n                    alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',\n                    base: 58,\n                    value: badBlockhash,\n                }),\n            );\n        });\n        it.each([31, 45])('throws when the encoded string is of length %s', actualLength => {\n            const badBlockhash = '1'.repeat(actualLength);\n            expect(() => {\n                assertIsBlockhash(badBlockhash);\n            }).toThrow(\n                new SolanaError(SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE, {\n                    actualLength,\n                }),\n            );\n        });\n        it.each([\n            [31, 'tVojvhToWjQ8Xvo4UPx2Xz9eRy7auyYMmZBjc2XfN'],\n            [33, 'JJEfe6DcPM2ziB2vfUWDV6aHVerXRGkv3TcyvJUNGHZz'],\n        ])('throws when the decoded byte array has a length of %s bytes', (actualLength, badBlockhash) => {\n            expect(() => {\n                assertIsBlockhash(badBlockhash);\n            }).toThrow(\n                new SolanaError(SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH, {\n                    actualLength,\n                }),\n            );\n        });\n        it('does not throw when supplied a base-58 encoded hash', () => {\n            expect(() => {\n                assertIsBlockhash('11111111111111111111111111111111');\n            }).not.toThrow();\n        });\n        it('returns undefined when supplied a base-58 encoded hash', () => {\n            expect(assertIsBlockhash('11111111111111111111111111111111')).toBeUndefined();\n        });\n    });\n\n    describe('using a mock base58 implementation', () => {\n        const mockEncode = jest.fn();\n        beforeEach(() => {\n            // use mock implementation\n            mockEncode.mockClear();\n            jest.mocked(getBase58Encoder).mockReturnValue({\n                encode: mockEncode,\n            } as unknown as VariableSizeEncoder<string>);\n        });\n\n        [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44].forEach(len => {\n            it(`attempts to decode input strings of exactly ${len} characters`, () => {\n                try {\n                    assertIsBlockhash('1'.repeat(len));\n                    // eslint-disable-next-line no-empty\n                } catch {}\n                expect(mockEncode).toHaveBeenCalledTimes(1);\n            });\n        });\n        it('does not attempt to decode too-short input strings', () => {\n            try {\n                assertIsBlockhash(\n                    // 31 bytes [0, ..., 0]\n                    '1111111111111111111111111111111', // 31 characters\n                );\n                // eslint-disable-next-line no-empty\n            } catch {}\n            expect(mockEncode).not.toHaveBeenCalled();\n        });\n        it('does not attempt to decode too-long input strings', () => {\n            try {\n                assertIsBlockhash(\n                    // 33 bytes [0, 255, ..., 255]\n                    '1JEKNVnkbo3jma5nREBBJCDoXFVeKkD56V3xKrvRmWxFG', // 45 characters\n                );\n                // eslint-disable-next-line no-empty\n            } catch {}\n            expect(mockEncode).not.toHaveBeenCalled();\n        });\n        it('memoizes getBase58Encoder when called multiple times', () => {\n            try {\n                assertIsBlockhash('1'.repeat(32));\n                // eslint-disable-next-line no-empty\n            } catch {}\n            try {\n                assertIsBlockhash('1'.repeat(32));\n                // eslint-disable-next-line no-empty\n            } catch {}\n            expect(jest.mocked(getBase58Encoder)).toHaveBeenCalledTimes(1);\n        });\n    });\n\n    describe('getBlockhashCodec', () => {\n        let blockhash: ReturnType<typeof getBlockhashCodec>;\n        beforeEach(() => {\n            // use real implementations\n            jest.mocked(getBase58Encoder).mockReturnValue(originalGetBase58Encoder);\n            jest.mocked(getBase58Decoder).mockReturnValue(originalGetBase58Decoder);\n\n            blockhash = getBlockhashCodec();\n        });\n        it('serializes a base58 encoded blockhash into a 32-byte buffer', () => {\n            expect(blockhash.encode('4wBqpZM9xaSheZzJSMawUHDgZ7miWfSsxmfVF5jJpYP' as Blockhash)).toEqual(\n                new Uint8Array([\n                    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n                    0,\n                ]),\n            );\n        });\n        it('deserializes a byte buffer representing an blockhash into a base58 encoded blockhash', () => {\n            expect(\n                blockhash.decode(\n                    new Uint8Array([\n                        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,\n                        27, 28, 29, 30, 31, 32,\n                        // Followed by extra bytes not part of the blockhash\n                        33, 34,\n                    ]),\n                ),\n            ).toBe('4wBqpZM9xaSheZzJSMawUKKwhdpChKbZ5eu5ky4Vigw' as Blockhash);\n        });\n        it('fatals when trying to deserialize a byte buffer shorter than 32-bytes', () => {\n            const tooShortBuffer = new Uint8Array(Array(31).fill(0));\n            expect(() => blockhash.decode(tooShortBuffer)).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n                    bytesLength: 31,\n                    codecDescription: 'fixCodecSize',\n                    expected: 32,\n                }),\n            );\n        });\n        it('memoizes getBase58Encoder and getBase58Decoder when called multiple times', async () => {\n            expect.assertions(2);\n\n            // reload the module to reset memoized state\n            let getBlockhashCodec: typeof import('../blockhash').getBlockhashCodec;\n            await jest.isolateModulesAsync(async () => {\n                const base58ModulePromise =\n                    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n                    // @ts-ignore\n                    import('../blockhash');\n                getBlockhashCodec = (await base58ModulePromise).getBlockhashCodec;\n            });\n\n            blockhash = getBlockhashCodec!();\n            blockhash.encode('4wBqpZM9xaSheZzJSMawUHDgZ7miWfSsxmfVF5jJpYP' as Blockhash);\n\n            blockhash = getBlockhashCodec!();\n            blockhash.encode('4wBqpZM9xaSheZzJSMawUHDgZ7miWfSsxmfVF5jJpYP' as Blockhash);\n\n            expect(jest.mocked(getBase58Encoder)).toHaveBeenCalledTimes(1);\n            expect(jest.mocked(getBase58Decoder)).toHaveBeenCalledTimes(1);\n        });\n    });\n\n    describe('getAddressComparator', () => {\n        it('sorts base 58 blockhashes', () => {\n            expect(\n                // These blockhashes were chosen such that sorting these conventionally (ie. using\n                // the default `Array.sort`) or numerically (ie. on the basis of the underlying\n                // numerical value of the blockhash) would fail to produce the expected output. This\n                // exercises the 'specialness' of the base 58 encoded blockhash comparator.\n                [\n                    'Ht1VrhoyhwMGMpBBi89BPdJp5R39Mu49suKx3A22W9Qs',\n                    'J9ZSLc9qPg3FR8UqfN6ae1QkVReUmnpLgQqFkGEPqmod',\n                    '6JYSQqSHY1E5JDwEfgWMieozqA1KCwiP2cH69to9eWKH',\n                    '7YR1xA7yzFAT4yQCsS4rpowjU1tsh5YUJd9hWMHRppcX',\n                    '7grJ9YUAEHxckLFqCY7fq8cM1UrragNSuPH1dvwJ8EEK',\n                    'AJBPNWCjVLwxff2eJynW56cMRCGmyU4y3vbuvtVdgVgb',\n                    'B8A2zUEDtJjR7nrokNUJYhgUQiwEBzC88rZc6WUE5ZeF',\n                    'BKggsVVp7yLmXtPuBDtC3FXBzvLyyye3Q2tFKUUGCHLj',\n                    'Ds72joawSKQ9nCDAAmGMKFiwiY6HR7PDzYDHDzZom3tj',\n                    'F1zKr4ZUYo5UAnH1fvYaD6R7ne137NYfS1r5HrCb8NpF',\n                ].sort(getBlockhashComparator()),\n            ).toEqual([\n                '6JYSQqSHY1E5JDwEfgWMieozqA1KCwiP2cH69to9eWKH',\n                '7grJ9YUAEHxckLFqCY7fq8cM1UrragNSuPH1dvwJ8EEK',\n                '7YR1xA7yzFAT4yQCsS4rpowjU1tsh5YUJd9hWMHRppcX',\n                'AJBPNWCjVLwxff2eJynW56cMRCGmyU4y3vbuvtVdgVgb',\n                'B8A2zUEDtJjR7nrokNUJYhgUQiwEBzC88rZc6WUE5ZeF',\n                'BKggsVVp7yLmXtPuBDtC3FXBzvLyyye3Q2tFKUUGCHLj',\n                'Ds72joawSKQ9nCDAAmGMKFiwiY6HR7PDzYDHDzZom3tj',\n                'F1zKr4ZUYo5UAnH1fvYaD6R7ne137NYfS1r5HrCb8NpF',\n                'Ht1VrhoyhwMGMpBBi89BPdJp5R39Mu49suKx3A22W9Qs',\n                'J9ZSLc9qPg3FR8UqfN6ae1QkVReUmnpLgQqFkGEPqmod',\n            ]);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-types/src/__tests__/coercions-test.ts",
    "content": "import {\n    SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE,\n    SOLANA_ERROR__MALFORMED_BIGINT_STRING,\n    SOLANA_ERROR__MALFORMED_NUMBER_STRING,\n    SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { Lamports, lamports } from '../lamports';\nimport { StringifiedBigInt, stringifiedBigInt } from '../stringified-bigint';\nimport { StringifiedNumber, stringifiedNumber } from '../stringified-number';\nimport { UnixTimestamp, unixTimestamp } from '../unix-timestamp';\n\ndescribe('coercions', () => {\n    describe('lamports', () => {\n        it('can coerce to `Lamports`', () => {\n            const raw = 1234n as Lamports;\n            const coerced = lamports(1234n);\n            expect(coerced).toBe(raw);\n        });\n        it('throws on invalid `Lamports`', () => {\n            const thisThrows = () => lamports(-5n);\n            expect(thisThrows).toThrow(new SolanaError(SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE));\n        });\n    });\n    describe('stringifiedBigInt', () => {\n        it('can coerce to `StringifiedBigInt`', () => {\n            const raw = '1234' as StringifiedBigInt;\n            const coerced = stringifiedBigInt('1234');\n            expect(coerced).toBe(raw);\n        });\n        it('throws on invalid `StringifiedBigInt`', () => {\n            const thisThrows = () => stringifiedBigInt('test');\n            expect(thisThrows).toThrow(\n                new SolanaError(SOLANA_ERROR__MALFORMED_BIGINT_STRING, {\n                    value: 'test',\n                }),\n            );\n        });\n    });\n    describe('stringifiedNumber', () => {\n        it('can coerce to `StringifiedNumber`', () => {\n            const raw = '1234' as StringifiedNumber;\n            const coerced = stringifiedNumber('1234');\n            expect(coerced).toBe(raw);\n        });\n        it('throws on invalid `StringifiedNumber`', () => {\n            const thisThrows = () => stringifiedNumber('test');\n            expect(thisThrows).toThrow(\n                new SolanaError(SOLANA_ERROR__MALFORMED_NUMBER_STRING, {\n                    value: 'test',\n                }),\n            );\n        });\n    });\n    describe('unixTimestamp', () => {\n        it('can coerce to `UnixTimestamp`', () => {\n            const raw = 1234n as UnixTimestamp;\n            const coerced = unixTimestamp(1234n);\n            expect(coerced).toBe(raw);\n        });\n        it('throws on an out-of-range `UnixTimestamp`', () => {\n            const thisThrows = () => unixTimestamp(BigInt(2n ** 63n));\n            expect(thisThrows).toThrow(\n                new SolanaError(SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE, {\n                    value: BigInt(2n ** 63n),\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/rpc-types/src/__tests__/commitment-test.ts",
    "content": "import { Commitment, commitmentComparator } from '../commitment';\n\ndescribe('commitmentComparator', () => {\n    it('sorts commitments according to their level of finality ascending', () => {\n        expect((['finalized', 'processed', 'confirmed'] as Commitment[]).sort(commitmentComparator)).toEqual([\n            'processed',\n            'confirmed',\n            'finalized',\n        ]);\n    });\n});\n"
  },
  {
    "path": "packages/rpc-types/src/__tests__/lamports-test.ts",
    "content": "import {\n    Endian,\n    getU8Codec,\n    getU8Decoder,\n    getU8Encoder,\n    getU16Codec,\n    getU16Decoder,\n    getU16Encoder,\n    getU64Codec,\n    getU64Decoder,\n    getU64Encoder,\n} from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE, SolanaError } from '@solana/errors';\n\nimport {\n    assertIsLamports,\n    getDefaultLamportsCodec,\n    getDefaultLamportsDecoder,\n    getDefaultLamportsEncoder,\n    getLamportsCodec,\n    getLamportsDecoder,\n    getLamportsEncoder,\n    lamports,\n} from '../lamports';\nimport { sol } from '../sol';\n\ndescribe('assertIsLamports()', () => {\n    it('throws when supplied a negative number', () => {\n        expect(() => {\n            assertIsLamports(-1n);\n        }).toThrow(new SolanaError(SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE));\n        expect(() => {\n            assertIsLamports(-1000n);\n        }).toThrow(new SolanaError(SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE));\n    });\n    it('throws when supplied a too large number', () => {\n        expect(() => {\n            assertIsLamports(2n ** 64n);\n        }).toThrow(new SolanaError(SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE));\n    });\n    it('does not throw when supplied zero lamports', () => {\n        expect(() => {\n            assertIsLamports(0n);\n        }).not.toThrow();\n    });\n    it('does not throw when supplied a valid non-zero number of lamports', () => {\n        expect(() => {\n            assertIsLamports(1_000_000_000n);\n        }).not.toThrow();\n    });\n    it('does not throw when supplied the max valid number of lamports', () => {\n        expect(() => {\n            assertIsLamports(2n ** 64n - 1n);\n        }).not.toThrow();\n    });\n});\n\ndescribe('getDefaultLamportsEncoder', () => {\n    it('encodes a lamports value using the default u64 encoder', () => {\n        const lamportsValue = lamports(1_000_000_000n);\n        const encoder = getDefaultLamportsEncoder();\n        const buffer = encoder.encode(lamportsValue);\n        expect(buffer).toStrictEqual(new Uint8Array([0, 202, 154, 59, 0, 0, 0, 0]));\n    });\n\n    it('has a fixed size of 8', () => {\n        const encoder = getDefaultLamportsEncoder();\n        expect(encoder.fixedSize).toBe(8);\n    });\n    it('also accepts a Sol value as input', () => {\n        const encoder = getDefaultLamportsEncoder();\n        // 1 SOL = 1_000_000_000 lamports.\n        expect(encoder.encode(sol('1'))).toStrictEqual(new Uint8Array([0, 202, 154, 59, 0, 0, 0, 0]));\n    });\n});\n\ndescribe('getLamportsEncoder', () => {\n    it('encodes a lamports value using a passed u8 encoder', () => {\n        const lamportsValue = lamports(100n);\n        const encoder = getLamportsEncoder(getU8Encoder());\n        const buffer = encoder.encode(lamportsValue);\n        expect(buffer).toStrictEqual(new Uint8Array([100]));\n    });\n    it('also accepts a Sol value as input', () => {\n        // Smallest Sol = 1 lamport = u8 100... we'll use a real one: sol('0.0000001') = 100 lamports.\n        const encoder = getLamportsEncoder(getU8Encoder());\n        expect(encoder.encode(sol('0.0000001'))).toStrictEqual(new Uint8Array([100]));\n    });\n    it('encodes a lamports value using a passed big-endian u16 encoder', () => {\n        const lamportsValue = lamports(100n);\n        const encoder = getLamportsEncoder(getU16Encoder({ endian: Endian.Big }));\n        const buffer = encoder.encode(lamportsValue);\n        expect(buffer).toStrictEqual(new Uint8Array([0, 100]));\n    });\n    it('encodes a lamports value using a passed u64 encoder', () => {\n        const lamportsValue = lamports(BigInt('0xffffffffffffffff'));\n        const encoder = getLamportsEncoder(getU64Encoder());\n        const buffer = encoder.encode(lamportsValue);\n        expect(buffer).toStrictEqual(new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]));\n    });\n    it('has a fixed size of 1 for a passed u8 encoder', () => {\n        const encoder = getLamportsEncoder(getU8Encoder());\n        expect(encoder.fixedSize).toBe(1);\n    });\n});\n\ndescribe('getDefaultLamportsDecoder', () => {\n    it('decodes an 8-byte buffer into a lamports value using the default u64 decoder', () => {\n        const buffer = new Uint8Array([0, 29, 50, 247, 69, 0, 0, 0]);\n        const decoder = getDefaultLamportsDecoder();\n        const lamportsValue = decoder.decode(buffer);\n        expect(lamportsValue).toStrictEqual(lamports(300_500_000_000n));\n    });\n    it('has a fixed size of 8', () => {\n        const decoder = getDefaultLamportsDecoder();\n        expect(decoder.fixedSize).toBe(8);\n    });\n});\n\ndescribe('getLamportsDecoder', () => {\n    it('decodes a 1-byte buffer into a lamports value using a passed u8 decoder', () => {\n        const buffer = new Uint8Array([100]);\n        const decoder = getLamportsDecoder(getU8Decoder());\n        const lamportsValue = decoder.decode(buffer);\n        expect(lamportsValue).toStrictEqual(lamports(100n));\n    });\n    it('decodes a 2-byte buffer into a lamports value using a passed big-endian u16 decoder', () => {\n        const buffer = new Uint8Array([0, 100]);\n        const decoder = getLamportsDecoder(getU16Decoder({ endian: Endian.Big }));\n        const lamportsValue = decoder.decode(buffer);\n        expect(lamportsValue).toStrictEqual(lamports(100n));\n    });\n    it('decodes an 8-byte buffer into a lamports value using a passed u64 decoder', () => {\n        const buffer = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]);\n        const decoder = getLamportsDecoder(getU64Decoder());\n        const lamportsValue = decoder.decode(buffer);\n        expect(lamportsValue).toStrictEqual(lamports(BigInt('0xffffffffffffffff')));\n    });\n    it('has a fixed size of 1 for a passed u8 decoder', () => {\n        const decoder = getLamportsDecoder(getU8Decoder());\n        expect(decoder.fixedSize).toBe(1);\n    });\n});\n\ndescribe('getDefaultLamportsCodec', () => {\n    it('encodes a lamports value using the default u64 encoder', () => {\n        const lamportsValue = lamports(1_000_000_000n);\n        const codec = getDefaultLamportsCodec();\n        const buffer = codec.encode(lamportsValue);\n        expect(buffer).toStrictEqual(new Uint8Array([0, 202, 154, 59, 0, 0, 0, 0]));\n    });\n    it('decodes an 8-byte buffer into a lamports value using the default u64 decoder', () => {\n        const buffer = new Uint8Array([0, 29, 50, 247, 69, 0, 0, 0]);\n        const codec = getDefaultLamportsCodec();\n        const lamportsValue = codec.decode(buffer);\n        expect(lamportsValue).toStrictEqual(lamports(300_500_000_000n));\n    });\n    it('has a fixed size of 8', () => {\n        const codec = getDefaultLamportsCodec();\n        expect(codec.fixedSize).toBe(8);\n    });\n});\n\ndescribe('getLamportsCodec', () => {\n    it('encodes a lamports value using a passed u8 codec', () => {\n        const lamportsValue = lamports(100n);\n        const codec = getLamportsCodec(getU8Codec());\n        const buffer = codec.encode(lamportsValue);\n        expect(buffer).toStrictEqual(new Uint8Array([100]));\n    });\n    it('encodes a lamports value using a passed big-endian u16 codec', () => {\n        const lamportsValue = lamports(100n);\n        const codec = getLamportsCodec(getU16Codec({ endian: Endian.Big }));\n        const buffer = codec.encode(lamportsValue);\n        expect(buffer).toStrictEqual(new Uint8Array([0, 100]));\n    });\n    it('encodes a lamports value using a passed u64 codec', () => {\n        const lamportsValue = lamports(BigInt('0xffffffffffffffff'));\n        const codec = getLamportsCodec(getU64Codec());\n        const buffer = codec.encode(lamportsValue);\n        expect(buffer).toStrictEqual(new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]));\n    });\n\n    it('decodes a 1-byte buffer into a lamports value using a passed u8 codec', () => {\n        const buffer = new Uint8Array([100]);\n        const codec = getLamportsCodec(getU8Codec());\n        const lamportsValue = codec.decode(buffer);\n        expect(lamportsValue).toStrictEqual(lamports(100n));\n    });\n    it('decodes a 2-byte buffer into a lamports value using a passed big-endian u16 codec', () => {\n        const buffer = new Uint8Array([0, 100]);\n        const codec = getLamportsCodec(getU16Codec({ endian: Endian.Big }));\n        const lamportsValue = codec.decode(buffer);\n        expect(lamportsValue).toStrictEqual(lamports(100n));\n    });\n    it('decodes an 8-byte buffer into a lamports value using a passed u64 codec', () => {\n        const buffer = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]);\n        const codec = getLamportsCodec(getU64Codec());\n        const lamportsValue = codec.decode(buffer);\n        expect(lamportsValue).toStrictEqual(lamports(BigInt('0xffffffffffffffff')));\n    });\n    it('has a fixed size of 1 for a passed u8 codec', () => {\n        const decoder = getLamportsCodec(getU8Codec());\n        expect(decoder.fixedSize).toBe(1);\n    });\n});\n"
  },
  {
    "path": "packages/rpc-types/src/__tests__/sol-test.ts",
    "content": "import {\n    SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS,\n    SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { lamports } from '../lamports';\nimport { getSolCodec, getSolDecoder, getSolEncoder, lamportsToSol, sol, solToLamports } from '../sol';\n\ndescribe('sol', () => {\n    it('parses whole numbers of SOL', () => {\n        expect(sol('1').raw).toBe(1_000_000_000n);\n    });\n\n    it('parses fractional SOL amounts', () => {\n        expect(sol('1.5').raw).toBe(1_500_000_000n);\n    });\n\n    it('parses zero', () => {\n        expect(sol('0').raw).toBe(0n);\n    });\n\n    it('parses the smallest representable amount (one Lamport)', () => {\n        expect(sol('0.000000001').raw).toBe(1n);\n    });\n\n    it('throws STRICT_MODE_PRECISION_LOSS by default when more than 9 decimals are supplied', () => {\n        expect(() => sol('1.1234567891')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS, {\n                kind: 'decimalFixedPoint',\n                operation: 'fromString',\n            }),\n        );\n    });\n\n    it('rounds when a rounding mode is supplied', () => {\n        expect(sol('1.1234567891', 'round').raw).toBe(1_123_456_789n);\n        expect(sol('1.1234567899', 'floor').raw).toBe(1_123_456_789n);\n        expect(sol('1.1234567891', 'ceil').raw).toBe(1_123_456_790n);\n    });\n\n    it('throws VALUE_OUT_OF_RANGE when the amount exceeds u64', () => {\n        // u64 max / 10^9 = ~18.45 billion SOL; just above that overflows.\n        expect(() => sol('18446744074')).toThrow(\n            new SolanaError(SOLANA_ERROR__FIXED_POINTS__VALUE_OUT_OF_RANGE, {\n                kind: 'decimalFixedPoint',\n                max: 18_446_744_073_709_551_615n,\n                min: 0n,\n                raw: 18_446_744_074_000_000_000n,\n                signedness: 'unsigned',\n                totalBits: 64,\n            }),\n        );\n    });\n});\n\ndescribe('solToLamports', () => {\n    it('returns the raw bigint as a Lamports-branded value', () => {\n        expect(solToLamports(sol('1'))).toBe(1_000_000_000n);\n    });\n\n    it('converts zero SOL to zero Lamports', () => {\n        expect(solToLamports(sol('0'))).toBe(0n);\n    });\n\n    it('converts fractional SOL to the correct Lamports', () => {\n        expect(solToLamports(sol('1.5'))).toBe(1_500_000_000n);\n    });\n\n    it('handles the smallest amount (1 Lamport)', () => {\n        expect(solToLamports(sol('0.000000001'))).toBe(1n);\n    });\n});\n\ndescribe('lamportsToSol', () => {\n    it('converts zero Lamports to a Sol value of zero', () => {\n        expect(lamportsToSol(lamports(0n)).raw).toBe(0n);\n    });\n\n    it('converts one billion Lamports to one SOL', () => {\n        expect(lamportsToSol(lamports(1_000_000_000n)).raw).toBe(1_000_000_000n);\n    });\n\n    it('preserves the Sol shape metadata', () => {\n        const value = lamportsToSol(lamports(1_500_000_000n));\n        expect(value.kind).toBe('decimalFixedPoint');\n        expect(value.signedness).toBe('unsigned');\n        expect(value.totalBits).toBe(64);\n        expect(value.decimals).toBe(9);\n    });\n\n    it('accepts the maximum Lamports value', () => {\n        const maxU64 = 18_446_744_073_709_551_615n;\n        expect(lamportsToSol(lamports(maxU64)).raw).toBe(maxU64);\n    });\n});\n\ndescribe('round-tripping Sol and Lamports', () => {\n    it.each([0n, 1n, 1_000_000_000n, 1_500_000_000n, 18_446_744_073_709_551_615n])(\n        'round-trips %s Lamports through Sol',\n        raw => {\n            expect(solToLamports(lamportsToSol(lamports(raw)))).toBe(raw);\n        },\n    );\n});\n\ndescribe('getSolEncoder', () => {\n    it('encodes a Sol value to 8 little-endian bytes', () => {\n        // 1.5 SOL = 1_500_000_000 lamports = 0x59682F00 in u64 LE.\n        expect(getSolEncoder().encode(sol('1.5'))).toEqual(\n            new Uint8Array([0x00, 0x2f, 0x68, 0x59, 0x00, 0x00, 0x00, 0x00]),\n        );\n    });\n\n    it('also accepts a Lamports value', () => {\n        expect(getSolEncoder().encode(lamports(1_500_000_000n))).toEqual(\n            new Uint8Array([0x00, 0x2f, 0x68, 0x59, 0x00, 0x00, 0x00, 0x00]),\n        );\n    });\n\n    it('produces identical bytes for equivalent Sol and Lamports inputs', () => {\n        const fromSol = getSolEncoder().encode(sol('1.5'));\n        const fromLamports = getSolEncoder().encode(lamports(1_500_000_000n));\n        expect(fromSol).toEqual(fromLamports);\n    });\n\n    it('reports a fixed size of 8', () => {\n        expect(getSolEncoder().fixedSize).toBe(8);\n    });\n});\n\ndescribe('getSolDecoder', () => {\n    it('decodes 8 little-endian bytes into a Sol value', () => {\n        const value = getSolDecoder().decode(new Uint8Array([0x00, 0x2f, 0x68, 0x59, 0x00, 0x00, 0x00, 0x00]));\n        expect(value.raw).toBe(1_500_000_000n);\n    });\n\n    it('returns a Sol with the correct shape metadata', () => {\n        const value = getSolDecoder().decode(new Uint8Array([0x00, 0x2f, 0x68, 0x59, 0x00, 0x00, 0x00, 0x00]));\n        expect(value.kind).toBe('decimalFixedPoint');\n        expect(value.signedness).toBe('unsigned');\n        expect(value.totalBits).toBe(64);\n        expect(value.decimals).toBe(9);\n    });\n\n    it('reports a fixed size of 8', () => {\n        expect(getSolDecoder().fixedSize).toBe(8);\n    });\n});\n\ndescribe('getSolCodec', () => {\n    it('round-trips a Sol value', () => {\n        const codec = getSolCodec();\n        const input = sol('42.5');\n        expect(codec.decode(codec.encode(input))).toEqual(input);\n    });\n\n    it('round-trips a Lamports value as Sol', () => {\n        const codec = getSolCodec();\n        expect(codec.decode(codec.encode(lamports(1_500_000_000n)))).toEqual(sol('1.5'));\n    });\n});\n"
  },
  {
    "path": "packages/rpc-types/src/__tests__/stringified-bigint-test.ts",
    "content": "import { SOLANA_ERROR__MALFORMED_BIGINT_STRING, SolanaError } from '@solana/errors';\n\nimport { assertIsStringifiedBigInt } from '../stringified-bigint';\n\ndescribe('assertIsStringifiedBigInt()', () => {\n    it(\"throws when supplied a string that can't parse as a number\", () => {\n        expect(() => {\n            assertIsStringifiedBigInt('abc');\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__MALFORMED_BIGINT_STRING, {\n                value: 'abc',\n            }),\n        );\n        expect(() => {\n            assertIsStringifiedBigInt('123a');\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__MALFORMED_BIGINT_STRING, {\n                value: '123a',\n            }),\n        );\n    });\n    it(\"throws when supplied a string that can't parse as an integer\", () => {\n        expect(() => {\n            assertIsStringifiedBigInt('123.0');\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__MALFORMED_BIGINT_STRING, {\n                value: '123.0',\n            }),\n        );\n        expect(() => {\n            assertIsStringifiedBigInt('123.5');\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__MALFORMED_BIGINT_STRING, {\n                value: '123.5',\n            }),\n        );\n    });\n    it('does not throw when supplied a string that parses as an integer', () => {\n        expect(() => {\n            assertIsStringifiedBigInt('-123');\n        }).not.toThrow();\n        expect(() => {\n            assertIsStringifiedBigInt('0');\n        }).not.toThrow();\n        expect(() => {\n            assertIsStringifiedBigInt('123');\n        }).not.toThrow();\n    });\n});\n"
  },
  {
    "path": "packages/rpc-types/src/__tests__/stringified-number-test.ts",
    "content": "import { SOLANA_ERROR__MALFORMED_NUMBER_STRING, SolanaError } from '@solana/errors';\n\nimport { assertIsStringifiedNumber } from '../stringified-number';\n\ndescribe('assertIsStringifiedNumber()', () => {\n    it(\"throws when supplied a string that can't parse as a number\", () => {\n        expect(() => {\n            assertIsStringifiedNumber('abc');\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__MALFORMED_NUMBER_STRING, {\n                value: 'abc',\n            }),\n        );\n        expect(() => {\n            assertIsStringifiedNumber('123a');\n        }).toThrow(\n            new SolanaError(SOLANA_ERROR__MALFORMED_NUMBER_STRING, {\n                value: '123a',\n            }),\n        );\n    });\n    it('does not throw when supplied a string that parses as a float', () => {\n        expect(() => {\n            assertIsStringifiedNumber('123.0');\n        }).not.toThrow();\n        expect(() => {\n            assertIsStringifiedNumber('123.5');\n        }).not.toThrow();\n    });\n    it('does not throw when supplied a string that parses as an integer', () => {\n        expect(() => {\n            assertIsStringifiedNumber('-123');\n        }).not.toThrow();\n        expect(() => {\n            assertIsStringifiedNumber('0');\n        }).not.toThrow();\n        expect(() => {\n            assertIsStringifiedNumber('123');\n        }).not.toThrow();\n    });\n});\n"
  },
  {
    "path": "packages/rpc-types/src/__tests__/unix-timestamp-test.ts",
    "content": "import { assertIsUnixTimestamp } from '../unix-timestamp';\n\ndescribe('assertIsUnixTimestamp()', () => {\n    it('throws when supplied a too large number', () => {\n        expect(() => {\n            assertIsUnixTimestamp(BigInt(2n ** 63n));\n        }).toThrow();\n        expect(() => {\n            assertIsUnixTimestamp(BigInt('9223372036854775808'));\n        }).toThrow();\n    });\n    it('throws when supplied a too small number', () => {\n        expect(() => {\n            assertIsUnixTimestamp(BigInt(BigInt(-(2n ** 63n)) - 1n));\n        }).toThrow();\n        expect(() => {\n            assertIsUnixTimestamp(BigInt('-9223372036854775809'));\n        }).toThrow();\n    });\n    it('does not throw when supplied a zero timestamp', () => {\n        expect(() => {\n            assertIsUnixTimestamp(0n);\n        }).not.toThrow();\n    });\n    it('does not throw when supplied a valid non-zero timestamp', () => {\n        expect(() => {\n            assertIsUnixTimestamp(1_000_000_000n);\n        }).not.toThrow();\n    });\n    it('does not throw when supplied the max valid timestamp', () => {\n        expect(() => {\n            assertIsUnixTimestamp(BigInt(BigInt(2n ** 63n) - 1n));\n        }).not.toThrow();\n        expect(() => {\n            assertIsUnixTimestamp(BigInt('9223372036854775807'));\n        }).not.toThrow();\n    });\n});\n"
  },
  {
    "path": "packages/rpc-types/src/__typetests__/blockhash-typetests.ts",
    "content": "import { EncodedString } from '@solana/nominal-types';\n\nimport { Blockhash } from '../blockhash';\n\n// [DESCRIBE] Blockhash\n{\n    // It satisfies the base58 encoded string brand\n    {\n        const blockhash = null as unknown as Blockhash;\n        blockhash satisfies EncodedString<string, 'base58'>;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-types/src/__typetests__/coercions-typetest.ts",
    "content": "import { Lamports, lamports } from '../lamports';\nimport { StringifiedBigInt, stringifiedBigInt } from '../stringified-bigint';\nimport { StringifiedNumber, stringifiedNumber } from '../stringified-number';\nimport { UnixTimestamp, unixTimestamp } from '../unix-timestamp';\n\nlamports(50_000_000_000_000n) satisfies Lamports;\nstringifiedBigInt('50_000_000_000_000') satisfies StringifiedBigInt;\nstringifiedNumber('50_000_000_000_000') satisfies StringifiedNumber;\nunixTimestamp(0n) satisfies UnixTimestamp;\n"
  },
  {
    "path": "packages/rpc-types/src/__typetests__/encoded-bytes-typetests.ts",
    "content": "import { CompressedData, EncodedString } from '@solana/nominal-types';\n\nimport { Base58EncodedBytes, Base64EncodedBytes, Base64EncodedZStdCompressedBytes } from '../encoded-bytes';\n\n// [DESCRIBE] Base58EncodedBytes\n{\n    // It satisfies the base58 encoded string brand\n    {\n        const encodedBytes = null as unknown as Base58EncodedBytes;\n        encodedBytes satisfies EncodedString<string, 'base58'>;\n    }\n}\n\n// [DESCRIBE] Base64EncodedBytes\n{\n    // It satisfies the base64 encoded string brand\n    {\n        const encodedBytes = null as unknown as Base64EncodedBytes;\n        encodedBytes satisfies EncodedString<string, 'base64'>;\n    }\n}\n\n// [DESCRIBE] Base64EncodedZStdCompressedBytes\n{\n    // It satisfies the base64 encoded string brand\n    {\n        const encodedBytes = null as unknown as Base64EncodedZStdCompressedBytes;\n        encodedBytes satisfies EncodedString<string, 'base64'>;\n    }\n    // It satisfies the ztd compressed data type\n    {\n        const encodedBytes = null as unknown as Base64EncodedZStdCompressedBytes;\n        encodedBytes satisfies CompressedData<string, 'zstd'>;\n    }\n}\n"
  },
  {
    "path": "packages/rpc-types/src/__typetests__/lamports-typetest.ts",
    "content": "import {\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    ReadonlyUint8Array,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\n\nimport {\n    getDefaultLamportsCodec,\n    getDefaultLamportsDecoder,\n    getDefaultLamportsEncoder,\n    getLamportsCodec,\n    getLamportsDecoder,\n    getLamportsEncoder,\n    Lamports,\n} from '../lamports';\nimport { Sol } from '../sol';\n\n// Default encoder\n{\n    const encoder = getDefaultLamportsEncoder();\n    encoder satisfies FixedSizeEncoder<Lamports | Sol, 8>;\n    encoder.fixedSize satisfies 8;\n    encoder.encode(1n as Lamports) satisfies ReadonlyUint8Array;\n    encoder.encode({} as Sol) satisfies ReadonlyUint8Array;\n}\n\n// Fixed size inner encoder\n{\n    const innerEncoder = {} as FixedSizeEncoder<bigint | number, 42>;\n    const encoder = getLamportsEncoder(innerEncoder);\n    encoder satisfies FixedSizeEncoder<Lamports | Sol, 42>;\n    encoder.fixedSize satisfies 42;\n    encoder.encode(1n as Lamports) satisfies ReadonlyUint8Array;\n    encoder.encode({} as Sol) satisfies ReadonlyUint8Array;\n}\n\n// Variable size inner encoder\n{\n    const innerEncoder = {} as VariableSizeEncoder<bigint | number>;\n    const encoder = getLamportsEncoder(innerEncoder);\n    // Note: `getSizeFromValue` retains the inner encoder's signature via `ExtractAdditionalProps`\n    // so we assert against the narrower `VariableSizeEncoder<Lamports>` rather than the widened\n    // `VariableSizeEncoder<Lamports | Sol>` here.\n    encoder satisfies VariableSizeEncoder<Lamports>;\n    encoder.getSizeFromValue satisfies (value: bigint | number) => number;\n    encoder.maxSize satisfies number | undefined;\n    encoder.encode(1n as Lamports) satisfies ReadonlyUint8Array;\n    encoder.encode({} as Sol) satisfies ReadonlyUint8Array;\n}\n\n// Default decoder\n{\n    const decoder = getDefaultLamportsDecoder();\n    decoder satisfies FixedSizeDecoder<Lamports, 8>;\n    decoder.fixedSize satisfies 8;\n    decoder.decode(null as unknown as ReadonlyUint8Array) satisfies Lamports;\n}\n\n// Fixed size inner decoder\n{\n    const innerDecoder = {} as FixedSizeDecoder<bigint, 42> | FixedSizeDecoder<number, 42>;\n    const decoder = getLamportsDecoder(innerDecoder);\n    decoder satisfies FixedSizeDecoder<Lamports, 42>;\n    decoder.fixedSize satisfies 42;\n    decoder.decode(null as unknown as ReadonlyUint8Array) satisfies Lamports;\n}\n\n// Variable size inner decoder\n{\n    const innerDecoder = {} as VariableSizeDecoder<bigint> | VariableSizeDecoder<number>;\n    const decoder = getLamportsDecoder(innerDecoder);\n    decoder satisfies VariableSizeDecoder<Lamports>;\n    decoder.maxSize satisfies number | undefined;\n    decoder.decode(null as unknown as ReadonlyUint8Array) satisfies Lamports;\n}\n\n// Default codec\n{\n    const codec = getDefaultLamportsCodec();\n    codec satisfies FixedSizeCodec<Lamports | Sol, Lamports, 8>;\n    codec satisfies FixedSizeEncoder<Lamports | Sol, 8>;\n    codec satisfies FixedSizeDecoder<Lamports, 8>;\n    codec.fixedSize satisfies 8;\n    codec.encode(1n as Lamports) satisfies ReadonlyUint8Array;\n    codec.encode({} as Sol) satisfies ReadonlyUint8Array;\n    codec.decode(null as unknown as ReadonlyUint8Array) satisfies Lamports;\n}\n\n// Fixed size inner codec\n{\n    const innerCodec = {} as FixedSizeCodec<bigint | number, bigint, 42> | FixedSizeCodec<bigint | number, number, 42>;\n    const codec = getLamportsCodec(innerCodec);\n    codec satisfies FixedSizeCodec<Lamports | Sol, Lamports, 42>;\n    codec satisfies FixedSizeEncoder<Lamports | Sol, 42>;\n    codec satisfies FixedSizeDecoder<Lamports, 42>;\n    codec.fixedSize satisfies 42;\n    codec.encode(1n as Lamports) satisfies ReadonlyUint8Array;\n    codec.encode({} as Sol) satisfies ReadonlyUint8Array;\n    codec.decode(null as unknown as ReadonlyUint8Array) satisfies Lamports;\n}\n\n// Variable size codec\n{\n    const innerCodec = {} as VariableSizeCodec<bigint | number, bigint> | VariableSizeCodec<bigint | number, number>;\n    const codec = getLamportsCodec(innerCodec);\n    // Note: `getSizeFromValue` retains the inner codec's signature via `ExtractAdditionalProps`\n    // so we assert against the narrower `VariableSizeCodec<Lamports, Lamports>` here.\n    codec satisfies VariableSizeCodec<Lamports, Lamports>;\n    codec.maxSize satisfies number | undefined;\n    codec.encode(1n as Lamports) satisfies ReadonlyUint8Array;\n    codec.encode({} as Sol) satisfies ReadonlyUint8Array;\n    codec.decode(null as unknown as ReadonlyUint8Array) satisfies Lamports;\n}\n"
  },
  {
    "path": "packages/rpc-types/src/__typetests__/sol-typetest.ts",
    "content": "import { FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder, ReadonlyUint8Array } from '@solana/codecs-core';\nimport { type DecimalFixedPoint } from '@solana/fixed-points';\n\nimport { type Lamports } from '../lamports';\nimport { getSolCodec, getSolDecoder, getSolEncoder, lamportsToSol, type Sol, sol, solToLamports } from '../sol';\n\n// Sol is the canonical unsigned 64-bit decimal fixed-point with 9 decimals.\n{\n    const value = {} as Sol;\n    value satisfies DecimalFixedPoint<'unsigned', 64, 9>;\n}\n\n// sol() returns a Sol.\n{\n    sol('1') satisfies Sol;\n    sol('1', 'round') satisfies Sol;\n}\n\n// solToLamports returns a Lamports.\n{\n    solToLamports({} as Sol) satisfies Lamports;\n}\n\n// lamportsToSol returns a Sol.\n{\n    lamportsToSol({} as Lamports) satisfies Sol;\n}\n\n// getSolEncoder accepts both Sol and Lamports.\n{\n    const encoder = getSolEncoder();\n    encoder satisfies FixedSizeEncoder<Lamports | Sol, 8>;\n    encoder.fixedSize satisfies 8;\n    encoder.encode({} as Sol) satisfies ReadonlyUint8Array;\n    encoder.encode({} as Lamports) satisfies ReadonlyUint8Array;\n}\n\n// getSolDecoder always returns Sol.\n{\n    const decoder = getSolDecoder();\n    decoder satisfies FixedSizeDecoder<Sol, 8>;\n    decoder.fixedSize satisfies 8;\n    decoder.decode(null as unknown as ReadonlyUint8Array) satisfies Sol;\n}\n\n// getSolCodec encodes from Sol | Lamports, decodes to Sol.\n{\n    const codec = getSolCodec();\n    codec satisfies FixedSizeCodec<Lamports | Sol, Sol, 8>;\n    codec.fixedSize satisfies 8;\n    codec.encode({} as Sol) satisfies ReadonlyUint8Array;\n    codec.encode({} as Lamports) satisfies ReadonlyUint8Array;\n    codec.decode(null as unknown as ReadonlyUint8Array) satisfies Sol;\n}\n"
  },
  {
    "path": "packages/rpc-types/src/account-filters.ts",
    "content": "import { Base58EncodedBytes, Base64EncodedBytes } from './encoded-bytes';\n\nexport type DataSlice = Readonly<{\n    /** The number of bytes to return */\n    length: number;\n    /** The byte offset from which to start reading */\n    offset: number;\n}>;\n\ntype ProgramNotificationsMemcmpFilterBase58 = Readonly<{\n    /**\n     * The bytes to match, as a base-58 encoded string.\n     *\n     * Data is limited to a maximum of 128 decoded bytes.\n     */\n    bytes: Base58EncodedBytes;\n    /** The encoding to use when decoding the supplied byte string */\n    encoding: 'base58';\n    /** The byte offset into the account data from which to start the comparison */\n    offset: bigint;\n}>;\n\ntype ProgramNotificationsMemcmpFilterBase64 = Readonly<{\n    /**\n     * The bytes to match, as a base-64 encoded string.\n     *\n     * Data is limited to a maximum of 128 decoded bytes.\n     */\n    bytes: Base64EncodedBytes;\n    /** The encoding to use when decoding the supplied byte string */\n    encoding: 'base64';\n    /** The byte offset into the account data from which to start the comparison */\n    offset: bigint;\n}>;\n\nexport type GetProgramAccountsMemcmpFilter = Readonly<{\n    /**\n     * This filter matches when the bytes supplied are equal to the account data at the given offset\n     */\n    memcmp: ProgramNotificationsMemcmpFilterBase58 | ProgramNotificationsMemcmpFilterBase64;\n}>;\n\nexport type GetProgramAccountsDatasizeFilter = Readonly<{\n    /** This filter matches when the account data length is equal to this */\n    dataSize: bigint;\n}>;\n"
  },
  {
    "path": "packages/rpc-types/src/account-info.ts",
    "content": "import type { Address } from '@solana/addresses';\n\nimport type {\n    Base58EncodedBytes,\n    Base58EncodedDataResponse,\n    Base64EncodedDataResponse,\n    Base64EncodedZStdCompressedDataResponse,\n} from './encoded-bytes';\nimport type { Lamports } from './lamports';\n\nexport type AccountInfoBase = Readonly<{\n    /** Indicates if the account contains a program (and is strictly read-only) */\n    executable: boolean;\n    /** Number of {@link Lamports} assigned to this account */\n    lamports: Lamports;\n    /** Address of the program this account has been assigned to */\n    owner: Address;\n    /** The size of the account data in bytes (excluding the 128 bytes of header) */\n    space: bigint;\n}>;\n\n/** @deprecated */\nexport type AccountInfoWithBase58Bytes = Readonly<{\n    data: Base58EncodedBytes;\n}>;\n\n/** @deprecated */\nexport type AccountInfoWithBase58EncodedData = Readonly<{\n    data: Base58EncodedDataResponse;\n}>;\n\nexport type AccountInfoWithBase64EncodedData = Readonly<{\n    data: Base64EncodedDataResponse;\n}>;\n\nexport type AccountInfoWithBase64EncodedZStdCompressedData = Readonly<{\n    data: Base64EncodedZStdCompressedDataResponse;\n}>;\n\nexport type AccountInfoWithJsonData = Readonly<{\n    data:\n        | Base64EncodedDataResponse // If `jsonParsed` encoding is requested but a parser cannot be found for the given account the `data` field falls back to `base64`.\n        | Readonly<{\n              parsed: {\n                  info?: object;\n                  type: string;\n              };\n              // Name of the program that owns this account.\n              program: string;\n              space: bigint;\n          }>;\n}>;\n\nexport type AccountInfoWithPubkey<TAccount extends AccountInfoBase> = Readonly<{\n    account: TAccount;\n    pubkey: Address;\n}>;\n"
  },
  {
    "path": "packages/rpc-types/src/blockhash.ts",
    "content": "import { Address, assertIsAddress, getAddressDecoder, getAddressEncoder, isAddress } from '@solana/addresses';\nimport { combineCodec, createEncoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\nimport {\n    isSolanaError,\n    SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE,\n    SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH,\n    SolanaError,\n} from '@solana/errors';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nexport type Blockhash = Brand<EncodedString<string, 'base58'>, 'Blockhash'>;\n\n/**\n * A type guard that returns `true` if the input string conforms to the {@link Blockhash} type, and\n * refines its type for use in your program.\n *\n * @example\n * ```ts\n * import { isBlockhash } from '@solana/rpc-types';\n *\n * if (isBlockhash(blockhash)) {\n *     // At this point, `blockhash` has been refined to a\n *     // `Blockhash` that can be used with the RPC.\n *     const { value: isValid } = await rpc.isBlockhashValid(blockhash).send();\n *     setBlockhashIsFresh(isValid);\n * } else {\n *     setError(`${blockhash} is not a blockhash`);\n * }\n * ```\n */\nexport function isBlockhash(putativeBlockhash: string): putativeBlockhash is Blockhash {\n    return isAddress(putativeBlockhash);\n}\n\n/**\n * From time to time you might acquire a string, that you expect to validate as a blockhash, from an\n * untrusted network API or user input. Use this function to assert that such an arbitrary string is\n * a base58-encoded blockhash.\n *\n * @example\n * ```ts\n * import { assertIsBlockhash } from '@solana/rpc-types';\n *\n * // Imagine a function that determines whether a blockhash is fresh when a user submits a form.\n * function handleSubmit() {\n *     // We know only that what the user typed conforms to the `string` type.\n *     const blockhash: string = blockhashInput.value;\n *     try {\n *         // If this type assertion function doesn't throw, then\n *         // Typescript will upcast `blockhash` to `Blockhash`.\n *         assertIsBlockhash(blockhash);\n *         // At this point, `blockhash` is a `Blockhash` that can be used with the RPC.\n *         const { value: isValid } = await rpc.isBlockhashValid(blockhash).send();\n *     } catch (e) {\n *         // `blockhash` turned out not to be a base58-encoded blockhash\n *     }\n * }\n * ```\n */\nexport function assertIsBlockhash(putativeBlockhash: string): asserts putativeBlockhash is Blockhash {\n    try {\n        assertIsAddress(putativeBlockhash);\n    } catch (error) {\n        if (isSolanaError(error, SOLANA_ERROR__ADDRESSES__STRING_LENGTH_OUT_OF_RANGE)) {\n            throw new SolanaError(SOLANA_ERROR__BLOCKHASH_STRING_LENGTH_OUT_OF_RANGE, error.context);\n        }\n        if (isSolanaError(error, SOLANA_ERROR__ADDRESSES__INVALID_BYTE_LENGTH)) {\n            throw new SolanaError(SOLANA_ERROR__INVALID_BLOCKHASH_BYTE_LENGTH, error.context);\n        }\n        throw error;\n    }\n}\n\n/**\n * Combines _asserting_ that a string is a blockhash with _coercing_ it to the {@link Blockhash}\n * type. It's most useful with untrusted input.\n *\n * @example\n * ```ts\n * import { blockhash } from '@solana/rpc-types';\n *\n * const { value: isValid } = await rpc.isBlockhashValid(blockhash(blockhashFromUserInput)).send();\n * ```\n *\n * > [!TIP]\n * > When starting from a known-good blockhash as a string, it's more efficient to typecast it\n * rather than to use the {@link blockhash} helper, because the helper unconditionally performs\n * validation on its input.\n * >\n * > ```ts\n * > import { Blockhash } from '@solana/rpc-types';\n * >\n * > const blockhash = 'ABmPH5KDXX99u6woqFS5vfBGSNyKG42SzpvBMWWqAy48' as Blockhash;\n * > ```\n */\nexport function blockhash(putativeBlockhash: string): Blockhash {\n    assertIsBlockhash(putativeBlockhash);\n    return putativeBlockhash;\n}\n\n/**\n * Returns an encoder that you can use to encode a base58-encoded blockhash to a byte array.\n *\n * @example\n * ```ts\n * import { getBlockhashEncoder } from '@solana/rpc-types';\n *\n * const blockhash = 'ABmPH5KDXX99u6woqFS5vfBGSNyKG42SzpvBMWWqAy48' as Blockhash;\n * const blockhashEncoder = getBlockhashEncoder();\n * const blockhashBytes = blockhashEncoder.encode(blockhash);\n * // Uint8Array(32) [\n * //   136, 123,  44, 249,  43,  19,  60,  14,\n * //   144,  16, 168, 241, 121, 111,  70, 232,\n * //   186,  26, 140, 202, 213,  64, 231,  82,\n * //   179,  66, 103, 237,  52, 117, 217,  93\n * // ]\n * ```\n */\nexport function getBlockhashEncoder(): FixedSizeEncoder<Blockhash, 32> {\n    const addressEncoder = getAddressEncoder();\n    return createEncoder({\n        fixedSize: 32,\n        write: (value: string, bytes, offset) => {\n            assertIsBlockhash(value);\n            return addressEncoder.write(value as string as Address, bytes, offset);\n        },\n    });\n}\n\n/**\n * Returns a decoder that you can use to convert an array of 32 bytes representing a blockhash to\n * the base58-encoded representation of that blockhash.\n *\n * @example\n * ```ts\n * import { getBlockhashDecoder } from '@solana/rpc-types';\n *\n * const blockhashBytes = new Uint8Array([\n *     136, 123,  44, 249,  43,  19,  60,  14,\n *     144,  16, 168, 241, 121, 111,  70, 232,\n *     186,  26, 140, 202, 213,  64, 231,  82,\n *     179,  66, 103, 237,  52, 117, 217,  93\n * ]);\n * const blockhashDecoder = getBlockhashDecoder();\n * const blockhash = blockhashDecoder.decode(blockhashBytes); // ABmPH5KDXX99u6woqFS5vfBGSNyKG42SzpvBMWWqAy48\n * ```\n */\nexport function getBlockhashDecoder(): FixedSizeDecoder<Blockhash, 32> {\n    return getAddressDecoder() as FixedSizeDecoder<string, 32> as FixedSizeDecoder<Blockhash, 32>;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a base-58 encoded blockhash.\n *\n * @see {@link getBlockhashDecoder}\n * @see {@link getBlockhashEncoder}\n */\nexport function getBlockhashCodec(): FixedSizeCodec<Blockhash, Blockhash, 32> {\n    return combineCodec(getBlockhashEncoder(), getBlockhashDecoder());\n}\n\nexport function getBlockhashComparator(): (x: string, y: string) => number {\n    return new Intl.Collator('en', {\n        caseFirst: 'lower',\n        ignorePunctuation: false,\n        localeMatcher: 'best fit',\n        numeric: false,\n        sensitivity: 'variant',\n        usage: 'sort',\n    }).compare;\n}\n"
  },
  {
    "path": "packages/rpc-types/src/cluster-url.ts",
    "content": "export type MainnetUrl = string & { '~cluster': 'mainnet' };\nexport type DevnetUrl = string & { '~cluster': 'devnet' };\nexport type TestnetUrl = string & { '~cluster': 'testnet' };\nexport type ClusterUrl = DevnetUrl | MainnetUrl | TestnetUrl | string;\n\n/** Given a URL casts it to a type that is only accepted where mainnet URLs are expected. */\nexport function mainnet(putativeString: string): MainnetUrl {\n    return putativeString as MainnetUrl;\n}\n/** Given a URL casts it to a type that is only accepted where devnet URLs are expected. */\nexport function devnet(putativeString: string): DevnetUrl {\n    return putativeString as DevnetUrl;\n}\n/** Given a URL casts it to a type that is only accepted where testnet URLs are expected. */\nexport function testnet(putativeString: string): TestnetUrl {\n    return putativeString as TestnetUrl;\n}\n"
  },
  {
    "path": "packages/rpc-types/src/commitment.ts",
    "content": "import { SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, SolanaError } from '@solana/errors';\n\n/**\n * A union of all possible commitment statuses -- each a measure of the network confirmation and\n * stake levels on a particular block.\n *\n * Read more about the statuses themselves, [here](https://docs.solana.com/cluster/commitments).\n */\nexport type Commitment = 'confirmed' | 'finalized' | 'processed';\n\nfunction getCommitmentScore(commitment: Commitment): number {\n    switch (commitment) {\n        case 'finalized':\n            return 2;\n        case 'confirmed':\n            return 1;\n        case 'processed':\n            return 0;\n        default:\n            throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SWITCH_MUST_BE_EXHAUSTIVE, {\n                unexpectedValue: commitment satisfies never,\n            });\n    }\n}\n\nexport function commitmentComparator(a: Commitment, b: Commitment): -1 | 0 | 1 {\n    if (a === b) {\n        return 0;\n    }\n    return getCommitmentScore(a) < getCommitmentScore(b) ? -1 : 1;\n}\n"
  },
  {
    "path": "packages/rpc-types/src/encoded-bytes.ts",
    "content": "import { Brand, CompressedData, EncodedString } from '@solana/nominal-types';\n\nexport type Base58EncodedBytes = Brand<EncodedString<string, 'base58'>, 'Base58EncodedBytes'>;\nexport type Base64EncodedBytes = Brand<EncodedString<string, 'base64'>, 'Base64EncodedBytes'>;\nexport type Base64EncodedZStdCompressedBytes = Brand<\n    EncodedString<CompressedData<string, 'zstd'>, 'base64'>,\n    'Base64EncodedZStdCompressedBytes'\n>;\n\nexport type Base58EncodedDataResponse = [Base58EncodedBytes, 'base58'];\nexport type Base64EncodedDataResponse = [Base64EncodedBytes, 'base64'];\nexport type Base64EncodedZStdCompressedDataResponse = [Base64EncodedZStdCompressedBytes, 'base64+zstd'];\n"
  },
  {
    "path": "packages/rpc-types/src/index.ts",
    "content": "/**\n * This package defines types for values used in the\n * [Solana JSON-RPC](https://docs.solana.com/api/http) and a series of helpers for working with\n * them. It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @packageDocumentation\n */\nexport * from './account-filters';\nexport * from './account-info';\nexport * from './blockhash';\nexport * from './cluster-url';\nexport * from './commitment';\nexport * from './encoded-bytes';\nexport * from './lamports';\nexport * from './rpc-api';\nexport * from './sol';\nexport * from './stringified-bigint';\nexport * from './stringified-number';\nexport * from './token-amount';\nexport * from './token-balance';\nexport * from './transaction';\nexport * from './transaction-error';\nexport * from './typed-numbers';\nexport * from './unix-timestamp';\n"
  },
  {
    "path": "packages/rpc-types/src/lamports.ts",
    "content": "import {\n    Codec,\n    combineCodec,\n    Decoder,\n    Encoder,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n} from '@solana/codecs-core';\nimport { getU64Decoder, getU64Encoder, NumberCodec, NumberDecoder, NumberEncoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE, SolanaError } from '@solana/errors';\nimport { Brand } from '@solana/nominal-types';\n\nimport type { Sol } from './sol';\n\n/**\n * Represents an integer value denominated in Lamports (ie. $1 \\times 10^{-9}$ ◎).\n *\n * It is represented as a `bigint` in client code and an `u64` in server code.\n */\nexport type Lamports = Brand<bigint, 'Lamports'>;\n\n// Largest possible value to be represented by a u64\nconst maxU64Value = 18446744073709551615n; // 2n ** 64n - 1n\n\nlet memoizedU64Encoder: FixedSizeEncoder<bigint | number, 8> | undefined;\nlet memoizedU64Decoder: FixedSizeDecoder<bigint, 8> | undefined;\n\nfunction getMemoizedU64Encoder(): FixedSizeEncoder<bigint | number, 8> {\n    if (!memoizedU64Encoder) memoizedU64Encoder = getU64Encoder();\n    return memoizedU64Encoder;\n}\n\nfunction getMemoizedU64Decoder(): FixedSizeDecoder<bigint, 8> {\n    if (!memoizedU64Decoder) memoizedU64Decoder = getU64Decoder();\n    return memoizedU64Decoder;\n}\n\n/**\n * This is a type guard that accepts a `bigint` as input. It will both return `true` if the integer\n * conforms to the {@link Lamports} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isLamports } from '@solana/rpc-types';\n *\n * if (isLamports(lamports)) {\n *     // At this point, `lamports` has been refined to a\n *     // `Lamports` that can be used anywhere Lamports are expected.\n *     await transfer(fromAddress, toAddress, lamports);\n * } else {\n *     setError(`${lamports} is not a quantity of Lamports`);\n * }\n * ```\n */\nexport function isLamports(putativeLamports: bigint): putativeLamports is Lamports {\n    return putativeLamports >= 0 && putativeLamports <= maxU64Value;\n}\n\n/**\n * Lamport values returned from the RPC API conform to the type {@link Lamports}. You can use a\n * value of that type wherever a quantity of Lamports is expected.\n *\n * @example\n * From time to time you might acquire a number that you expect to be a quantity of Lamports, from\n * an untrusted network API or user input. To assert that such an arbitrary number is usable as a\n * quantity of Lamports, use this function.\n *\n * ```ts\n * import { assertIsLamports } from '@solana/rpc-types';\n *\n * // Imagine a function that creates a transfer instruction when a user submits a form.\n * function handleSubmit() {\n *     // We know only that what the user typed conforms to the `number` type.\n *     const lamports: number = parseInt(quantityInput.value, 10);\n *     try {\n *         // If this type assertion function doesn't throw, then\n *         // Typescript will upcast `lamports` to `Lamports`.\n *         assertIsLamports(lamports);\n *         // At this point, `lamports` is a `Lamports` that can be used anywhere Lamports are expected.\n *         await transfer(fromAddress, toAddress, lamports);\n *     } catch (e) {\n *         // `lamports` turned out not to validate as a quantity of Lamports.\n *     }\n * }\n * ```\n */\nexport function assertIsLamports(putativeLamports: bigint): asserts putativeLamports is Lamports {\n    if (putativeLamports < 0 || putativeLamports > maxU64Value) {\n        throw new SolanaError(SOLANA_ERROR__LAMPORTS_OUT_OF_RANGE);\n    }\n}\n\n/**\n * This helper combines _asserting_ that a number is a possible number of {@link Lamports} with\n * _coercing_ it to the {@link Lamports} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { lamports } from '@solana/rpc-types';\n *\n * await transfer(address(fromAddress), address(toAddress), lamports(100000n));\n * ```\n */\nexport function lamports(putativeLamports: bigint): Lamports {\n    assertIsLamports(putativeLamports);\n    return putativeLamports;\n}\n\ntype ExtractAdditionalProps<T, U> = Omit<T, keyof U>;\n\n/**\n * Returns an encoder that you can use to encode a 64-bit {@link Lamports} value to 8 bytes in\n * little endian order. The encoder also accepts a {@link Sol} fixed-point value.\n */\nexport function getDefaultLamportsEncoder(): FixedSizeEncoder<Lamports | Sol, 8> {\n    return getLamportsEncoder(getMemoizedU64Encoder());\n}\n\n/**\n * Returns an encoder that you can use to encode a {@link Lamports} value to a byte array. The\n * encoder also accepts a {@link Sol} fixed-point value, whose `raw` bigint is written as if it\n * were a Lamports value.\n *\n * You must supply a number decoder that will determine how encode the numeric value.\n *\n * @example\n * ```ts\n * import { getLamportsEncoder } from '@solana/rpc-types';\n * import { getU16Encoder } from '@solana/codecs-numbers';\n *\n * const lamports = lamports(256n);\n * const lamportsEncoder = getLamportsEncoder(getU16Encoder());\n * const lamportsBytes = lamportsEncoder.encode(lamports);\n * // Uint8Array(2) [ 0, 1 ]\n * ```\n */\nexport function getLamportsEncoder<TEncoder extends NumberEncoder>(\n    innerEncoder: TEncoder,\n): Encoder<Lamports | Sol> & ExtractAdditionalProps<TEncoder, NumberEncoder> {\n    return transformEncoder<bigint | number, Lamports | Sol>(innerEncoder, value =>\n        typeof value === 'bigint' ? value : value.raw,\n    ) as Encoder<Lamports | Sol> & ExtractAdditionalProps<TEncoder, NumberEncoder>;\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing a 64-bit little endian\n * number to a {@link Lamports} value.\n */\nexport function getDefaultLamportsDecoder(): FixedSizeDecoder<Lamports, 8> {\n    return getLamportsDecoder(getMemoizedU64Decoder());\n}\n\n/**\n * Returns a decoder that you can use to convert an array of bytes representing a number to a\n * {@link Lamports} value.\n *\n * You must supply a number decoder that will determine how many bits to use to decode the numeric\n * value.\n *\n * @example\n * ```ts\n * import { getLamportsDecoder } from '@solana/rpc-types';\n * import { getU16Decoder } from '@solana/codecs-numbers';\n *\n * const lamportsBytes = new Uint8Array([ 0, 1 ]);\n * const lamportsDecoder = getLamportsDecoder(getU16Decoder());\n * const lamports = lamportsDecoder.decode(lamportsBytes); // lamports(256n)\n * ```\n */\nexport function getLamportsDecoder<TDecoder extends NumberDecoder>(\n    innerDecoder: TDecoder,\n): Decoder<Lamports> & ExtractAdditionalProps<TDecoder, NumberDecoder> {\n    return transformDecoder<bigint | number, Lamports>(innerDecoder, value =>\n        lamports(typeof value === 'bigint' ? value : BigInt(value)),\n    ) as Decoder<Lamports> & ExtractAdditionalProps<TDecoder, NumberDecoder>;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a 64-bit {@link Lamports} value.\n * The encoder also accepts a {@link Sol} fixed-point value; the decoder always returns\n * {@link Lamports}.\n *\n * @see {@link getDefaultLamportsDecoder}\n * @see {@link getDefaultLamportsEncoder}\n */\nexport function getDefaultLamportsCodec(): FixedSizeCodec<Lamports | Sol, Lamports, 8> {\n    return combineCodec(getDefaultLamportsEncoder(), getDefaultLamportsDecoder());\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a {@link Lamports} value. The\n * encoder also accepts a {@link Sol} fixed-point value; the decoder always returns\n * {@link Lamports}.\n *\n * @see {@link getLamportsDecoder}\n * @see {@link getLamportsEncoder}\n */\nexport function getLamportsCodec<TCodec extends NumberCodec>(\n    innerCodec: TCodec,\n): Codec<Lamports | Sol, Lamports> & ExtractAdditionalProps<TCodec, NumberCodec> {\n    return combineCodec(getLamportsEncoder(innerCodec), getLamportsDecoder(innerCodec)) as Codec<\n        Lamports | Sol,\n        Lamports\n    > &\n        ExtractAdditionalProps<TCodec, NumberCodec>;\n}\n"
  },
  {
    "path": "packages/rpc-types/src/rpc-api.ts",
    "content": "import type { Slot } from './typed-numbers';\n\nexport type SolanaRpcResponse<TValue> = Readonly<{\n    context: Readonly<{ slot: Slot }>;\n    value: TValue;\n}>;\n"
  },
  {
    "path": "packages/rpc-types/src/sol.ts",
    "content": "import {\n    combineCodec,\n    type FixedSizeCodec,\n    type FixedSizeDecoder,\n    type FixedSizeEncoder,\n    transformDecoder,\n    transformEncoder,\n} from '@solana/codecs-core';\nimport { getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\nimport {\n    type DecimalFixedPoint,\n    decimalFixedPoint,\n    rawDecimalFixedPoint,\n    type RoundingMode,\n} from '@solana/fixed-points';\n\nimport { type Lamports, lamports } from './lamports';\n\n/**\n * The canonical fixed-point shape for SOL amounts: unsigned 64-bit with 9\n * decimals. Since 1 SOL equals `10 ** 9` Lamports, a `Sol` value's `raw`\n * bigint is exactly the corresponding Lamports count.\n */\nexport type Sol = DecimalFixedPoint<'unsigned', 64, 9>;\n\nlet memoizedSolFactory: ReturnType<typeof decimalFixedPoint<'unsigned', 64, 9>> | undefined;\nlet memoizedRawSolFactory: ReturnType<typeof rawDecimalFixedPoint<'unsigned', 64, 9>> | undefined;\n\nfunction solFactory(value: string, rounding?: RoundingMode): Sol {\n    if (!memoizedSolFactory) memoizedSolFactory = decimalFixedPoint('unsigned', 64, 9);\n    return memoizedSolFactory(value, rounding);\n}\n\nfunction rawSolFactory(value: bigint): Sol {\n    if (!memoizedRawSolFactory) memoizedRawSolFactory = rawDecimalFixedPoint('unsigned', 64, 9);\n    return memoizedRawSolFactory(value);\n}\n\nlet memoizedU64Encoder: FixedSizeEncoder<bigint | number, 8> | undefined;\nlet memoizedU64Decoder: FixedSizeDecoder<bigint, 8> | undefined;\n\nfunction getMemoizedU64Encoder(): FixedSizeEncoder<bigint | number, 8> {\n    if (!memoizedU64Encoder) memoizedU64Encoder = getU64Encoder();\n    return memoizedU64Encoder;\n}\n\nfunction getMemoizedU64Decoder(): FixedSizeDecoder<bigint, 8> {\n    if (!memoizedU64Decoder) memoizedU64Decoder = getU64Decoder();\n    return memoizedU64Decoder;\n}\n\n/**\n * Parses a decimal string as a {@link Sol} fixed-point value.\n *\n * The default rounding mode is `'strict'`, which throws\n * `SOLANA_ERROR__FIXED_POINTS__STRICT_MODE_PRECISION_LOSS` when the input\n * has more than 9 fractional digits. Pass another `RoundingMode` to accept\n * a rounded result.\n *\n * @example\n * ```ts\n * sol('1.5');            // represents 1.5 SOL (raw === 1_500_000_000n)\n * sol('0.000000001');    // the smallest representable amount: 1 Lamport\n * sol('1.1234567891', 'round'); // rounded to 9 decimals\n * ```\n *\n * @see {@link solToLamports}\n * @see {@link lamportsToSol}\n */\nexport function sol(value: string, rounding?: RoundingMode): Sol {\n    return solFactory(value, rounding);\n}\n\n/**\n * Converts a {@link Sol} fixed-point value to its equivalent {@link Lamports}\n * bigint. This conversion is exact — a `Sol` value's raw bigint is exactly\n * the Lamports count.\n *\n * @example\n * ```ts\n * solToLamports(sol('1.5')); // lamports(1_500_000_000n)\n * ```\n *\n * @see {@link lamportsToSol}\n * @see {@link sol}\n */\nexport function solToLamports(value: Sol): Lamports {\n    return lamports(value.raw);\n}\n\n/**\n * Converts a {@link Lamports} bigint to its equivalent {@link Sol}\n * fixed-point value. This conversion is exact.\n *\n * @example\n * ```ts\n * lamportsToSol(lamports(1_500_000_000n)); // represents 1.5 SOL\n * ```\n *\n * @see {@link solToLamports}\n * @see {@link sol}\n */\nexport function lamportsToSol(value: Lamports): Sol {\n    return rawSolFactory(value);\n}\n\n/**\n * Returns an encoder that writes a {@link Sol} or {@link Lamports} value to\n * 8 bytes in little-endian order. Since Sol and Lamports share the same\n * u64 wire format, either can be passed as input.\n *\n * @see {@link getSolDecoder}\n * @see {@link getSolCodec}\n */\nexport function getSolEncoder(): FixedSizeEncoder<Lamports | Sol, 8> {\n    return transformEncoder<bigint | number, Lamports | Sol, 8>(getMemoizedU64Encoder(), value =>\n        typeof value === 'bigint' ? value : value.raw,\n    );\n}\n\n/**\n * Returns a decoder that reads 8 bytes in little-endian order into a\n * {@link Sol} value.\n *\n * @see {@link getSolEncoder}\n * @see {@link getSolCodec}\n */\nexport function getSolDecoder(): FixedSizeDecoder<Sol, 8> {\n    return transformDecoder<bigint, Sol, 8>(getMemoizedU64Decoder(), value => rawSolFactory(value));\n}\n\n/**\n * Returns a codec combining {@link getSolEncoder} and {@link getSolDecoder}.\n * The encoder accepts either {@link Sol} or {@link Lamports}; the decoder\n * always returns {@link Sol}.\n *\n * @see {@link getSolEncoder}\n * @see {@link getSolDecoder}\n */\nexport function getSolCodec(): FixedSizeCodec<Lamports | Sol, Sol, 8> {\n    return combineCodec(getSolEncoder(), getSolDecoder());\n}\n"
  },
  {
    "path": "packages/rpc-types/src/stringified-bigint.ts",
    "content": "import { SOLANA_ERROR__MALFORMED_BIGINT_STRING, SolanaError } from '@solana/errors';\nimport { Brand } from '@solana/nominal-types';\n\n/**\n * This type represents a `bigint` which has been encoded as a string for transit over a transport\n * that does not support `bigint` values natively. The JSON-RPC is such a transport.\n */\nexport type StringifiedBigInt = Brand<string, 'StringifiedBigInt'>;\n\n/**\n * A type guard that returns `true` if the input string parses as a `BigInt`, and refines its type\n * for use in your program.\n *\n * @example\n * ```ts\n * import { isStringifiedBigInt } from '@solana/rpc-types';\n *\n * if (isStringifiedBigInt(bigintString)) {\n *     // At this point, `bigintString` has been refined to a `StringifiedBigInt`\n *     bigintString satisfies StringifiedBigInt; // OK\n * } else {\n *     setError(`${bigintString} does not represent a BigInt`);\n * }\n * ```\n */\nexport function isStringifiedBigInt(putativeBigInt: string): putativeBigInt is StringifiedBigInt {\n    try {\n        BigInt(putativeBigInt);\n        return true;\n    } catch {\n        return false;\n    }\n}\n\n/**\n * From time to time you might acquire a string, that you expect to parse as a `BigInt`, from an\n * untrusted network API or user input. Use this function to assert that such an arbitrary string\n * will in fact parse as a `BigInt`.\n *\n * @example\n * ```ts\n * import { assertIsStringifiedBigInt } from '@solana/rpc-types';\n *\n * // Imagine having received a value that you presume represents the supply of some token.\n * // At this point we know only that it conforms to the `string` type.\n * try {\n *     // If this type assertion function doesn't throw, then\n *     // Typescript will upcast `supplyString` to `StringifiedBigInt`.\n *     assertIsStringifiedBigInt(supplyString);\n *     // At this point, `supplyString` is a `StringifiedBigInt`.\n *     supplyString satisfies StringifiedBigInt;\n * } catch (e) {\n *     // `supplyString` turned out not to parse as a `BigInt`\n * }\n * ```\n */\nexport function assertIsStringifiedBigInt(putativeBigInt: string): asserts putativeBigInt is StringifiedBigInt {\n    try {\n        BigInt(putativeBigInt);\n    } catch {\n        throw new SolanaError(SOLANA_ERROR__MALFORMED_BIGINT_STRING, {\n            value: putativeBigInt,\n        });\n    }\n}\n\n/**\n * This helper combines _asserting_ that a string will parse as a `BigInt` with _coercing_ it to the\n * {@link StringifiedBigInt} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { stringifiedBigInt } from '@solana/rpc-types';\n *\n * const supplyString = stringifiedBigInt('1000000000');\n * ```\n */\nexport function stringifiedBigInt(putativeBigInt: string): StringifiedBigInt {\n    assertIsStringifiedBigInt(putativeBigInt);\n    return putativeBigInt;\n}\n"
  },
  {
    "path": "packages/rpc-types/src/stringified-number.ts",
    "content": "import { SOLANA_ERROR__MALFORMED_NUMBER_STRING, SolanaError } from '@solana/errors';\nimport { Brand } from '@solana/nominal-types';\n\n/**\n * This type represents a number which has been encoded as a string for transit over a transport\n * where loss of precision when using the native number type is a concern. The JSON-RPC is such a\n * transport.\n */\nexport type StringifiedNumber = Brand<string, 'StringifiedNumber'>;\n\n/**\n * A type guard that returns `true` if the input string parses as a `Number`, and refines its type\n * for use in your program.\n *\n * @example\n * ```ts\n * import { isStringifiedNumber } from '@solana/rpc-types';\n *\n * if (isStringifiedNumber(numericString)) {\n *     // At this point, `numericString` has been refined to a `StringifiedNumber`\n *     numericString satisfies StringifiedNumber; // OK\n * } else {\n *     setError(`${numericString} does not represent a number`);\n * }\n * ```\n */\nexport function isStringifiedNumber(putativeNumber: string): putativeNumber is StringifiedNumber {\n    return !Number.isNaN(Number(putativeNumber));\n}\n\n/**\n * From time to time you might acquire a string, that you expect to parse as a `Number`, from an\n * untrusted network API or user input. Use this function to assert that such an arbitrary string\n * will in fact parse as a `Number`.\n *\n * @example\n * ```ts\n * import { assertIsStringifiedNumber } from '@solana/rpc-types';\n *\n * // Imagine having received a value that you presume represents some decimal number.\n * // At this point we know only that it conforms to the `string` type.\n * try {\n *     // If this type assertion function doesn't throw, then\n *     // Typescript will upcast `decimalNumberString` to `StringifiedNumber`.\n *     assertIsStringifiedNumber(decimalNumberString);\n *     // At this point, `decimalNumberString` is a `StringifiedNumber`.\n *     decimalNumberString satisfies StringifiedNumber;\n * } catch (e) {\n *     // `decimalNumberString` turned out not to parse as a number.\n * }\n * ```\n */\nexport function assertIsStringifiedNumber(putativeNumber: string): asserts putativeNumber is StringifiedNumber {\n    if (Number.isNaN(Number(putativeNumber))) {\n        throw new SolanaError(SOLANA_ERROR__MALFORMED_NUMBER_STRING, {\n            value: putativeNumber,\n        });\n    }\n}\n\n/**\n * This helper combines _asserting_ that a string will parse as a `Number` with _coercing_ it to the\n * {@link StringifiedNumber} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { stringifiedNumber } from '@solana/rpc-types';\n *\n * const decimalNumberString = stringifiedNumber('-42.1');\n * ```\n */\nexport function stringifiedNumber(putativeNumber: string): StringifiedNumber {\n    assertIsStringifiedNumber(putativeNumber);\n    return putativeNumber;\n}\n"
  },
  {
    "path": "packages/rpc-types/src/token-amount.ts",
    "content": "import { StringifiedBigInt } from './stringified-bigint';\nimport { StringifiedNumber } from './stringified-number';\n\nexport type TokenAmount = Readonly<{\n    /**\n     * The quantity, in fractional units.\n     *\n     * @example\n     * If the token in question is configured to have 6 decimal places, the value `1_000_000n` would\n     * indicate a balance of one whole token.\n     */\n    amount: StringifiedBigInt;\n    /**\n     * A power of ten, the inverse of which defines the smallest fractional unit of this token.\n     *\n     * @example\n     * A token configured to have 6 decimals is made up of fractional units each representing\n     * 10^(-6) tokens.\n     */\n    decimals: number;\n    /** @deprecated */\n    uiAmount: number | null;\n    /**\n     * The balance of whole tokens, as a string.\n     *\n     * The string representation will use a decimal when necessary, but will never contain trailing\n     * zeros to the right of the decimal place.\n     *\n     * @example\n     * A token configured to have 6 decimals, with an amount of `1_000_500n`, will produce the\n     * string `\"1.0005\"`.\n     */\n    uiAmountString: StringifiedNumber;\n}>;\n"
  },
  {
    "path": "packages/rpc-types/src/token-balance.ts",
    "content": "import type { Address } from '@solana/addresses';\n\nimport type { TokenAmount } from './token-amount';\n\nexport type TokenBalance = Readonly<{\n    /** Index of the account in which the token balance is provided for. */\n    accountIndex: number;\n    /** Address of the token's mint. */\n    mint: Address;\n    /** Address of token balance's owner. */\n    owner?: Address;\n    /** Address of the Token program that owns the account. */\n    programId?: Address;\n    uiTokenAmount: TokenAmount;\n}>;\n"
  },
  {
    "path": "packages/rpc-types/src/transaction-error.ts",
    "content": "type CustomProgramError = number;\n\n// Keep synced with RPC source: https://github.com/anza-xyz/solana-sdk/blob/master/instruction-error/src/lib.rs\ntype InstructionError =\n    | 'AccountAlreadyInitialized'\n    | 'AccountBorrowFailed'\n    | 'AccountBorrowOutstanding'\n    | 'AccountDataSizeChanged'\n    | 'AccountDataTooSmall'\n    | 'AccountNotExecutable'\n    | 'AccountNotRentExempt'\n    | 'ArithmeticOverflow'\n    | 'BorshIoError' // SDKv3 has a fieldless `BorshIoError`\n    | 'BuiltinProgramsMustConsumeComputeUnits'\n    | 'CallDepth'\n    | 'ComputationalBudgetExceeded'\n    | 'DuplicateAccountIndex'\n    | 'DuplicateAccountOutOfSync'\n    | 'ExecutableAccountNotRentExempt'\n    | 'ExecutableDataModified'\n    | 'ExecutableLamportChange'\n    | 'ExecutableModified'\n    | 'ExternalAccountDataModified'\n    | 'ExternalAccountLamportSpend'\n    | 'GenericError'\n    | 'IllegalOwner'\n    | 'Immutable'\n    | 'IncorrectAuthority'\n    | 'IncorrectProgramId'\n    | 'InsufficientFunds'\n    | 'InvalidAccountData'\n    | 'InvalidAccountOwner'\n    | 'InvalidArgument'\n    | 'InvalidError'\n    | 'InvalidInstructionData'\n    | 'InvalidRealloc'\n    | 'InvalidSeeds'\n    | 'MaxAccountsDataAllocationsExceeded'\n    | 'MaxAccountsExceeded'\n    | 'MaxInstructionTraceLengthExceeded'\n    | 'MaxSeedLengthExceeded'\n    | 'MissingAccount'\n    | 'MissingRequiredSignature'\n    | 'ModifiedProgramId'\n    | 'NotEnoughAccountKeys'\n    | 'PrivilegeEscalation'\n    | 'ProgramEnvironmentSetupFailure'\n    | 'ProgramFailedToCompile'\n    | 'ProgramFailedToComplete'\n    | 'ReadonlyDataModified'\n    | 'ReadonlyLamportChange'\n    | 'ReentrancyNotAllowed'\n    | 'RentEpochModified'\n    | 'UnbalancedInstruction'\n    | 'UninitializedAccount'\n    | 'UnsupportedProgramId'\n    | 'UnsupportedSysvar'\n    | { Custom: CustomProgramError };\n\ntype InstructionIndex = number;\ntype AccountIndex = number;\n\n// Keep synced with RPC source: https://github.com/anza-xyz/agave/blob/master/sdk/src/transaction/error.rs\nexport type TransactionError =\n    | 'AccountBorrowOutstanding'\n    | 'AccountInUse'\n    | 'AccountLoadedTwice'\n    | 'AccountNotFound'\n    | 'AddressLookupTableNotFound'\n    | 'AlreadyProcessed'\n    | 'BlockhashNotFound'\n    | 'CallChainTooDeep'\n    | 'ClusterMaintenance'\n    | 'InsufficientFundsForFee'\n    | 'InvalidAccountForFee'\n    | 'InvalidAccountIndex'\n    | 'InvalidAddressLookupTableData'\n    | 'InvalidAddressLookupTableIndex'\n    | 'InvalidAddressLookupTableOwner'\n    | 'InvalidLoadedAccountsDataSizeLimit'\n    | 'InvalidProgramForExecution'\n    | 'InvalidRentPayingAccount'\n    | 'InvalidWritableAccount'\n    | 'MaxLoadedAccountsDataSizeExceeded'\n    | 'MissingSignatureForFee'\n    | 'ProgramAccountNotFound'\n    | 'ResanitizationNeeded'\n    | 'SanitizeFailure'\n    | 'SignatureFailure'\n    | 'TooManyAccountLocks'\n    | 'UnbalancedTransaction'\n    | 'UnsupportedVersion'\n    | 'WouldExceedAccountDataBlockLimit'\n    | 'WouldExceedAccountDataTotalLimit'\n    | 'WouldExceedMaxAccountCostLimit'\n    | 'WouldExceedMaxBlockCostLimit'\n    | 'WouldExceedMaxVoteCostLimit'\n    | { DuplicateInstruction: InstructionIndex }\n    | { InstructionError: [InstructionIndex, InstructionError] }\n    | { InsufficientFundsForRent: { account_index: AccountIndex } }\n    | { ProgramExecutionTemporarilyRestricted: { account_index: AccountIndex } };\n"
  },
  {
    "path": "packages/rpc-types/src/transaction.ts",
    "content": "import type { Address } from '@solana/addresses';\n\nimport type { Blockhash } from './blockhash';\nimport type { Base58EncodedBytes, Base58EncodedDataResponse, Base64EncodedDataResponse } from './encoded-bytes';\nimport type { Lamports } from './lamports';\nimport type { TokenBalance } from './token-balance';\nimport type { TransactionError } from './transaction-error';\nimport type { SignedLamports } from './typed-numbers';\n\ntype TransactionVersion = 'legacy' | 0 | 1;\n\ntype AddressTableLookup = Readonly<{\n    /** Address of the address lookup table account. */\n    accountKey: Address;\n    /** Indexes of accounts in a lookup table to load as read-only. */\n    readonlyIndexes: readonly number[];\n    /** Indexes of accounts in a lookup table to load as writable. */\n    writableIndexes: readonly number[];\n}>;\n\ntype InstructionWithStackHeight = Readonly<{\n    /**\n     * A number indicating the height at which this instruction was called with respect to the\n     * bottom of the call stack denoted by `1` or `null`.\n     *\n     * For instance, an instruction explicitly declared in the transaction message will have a `1`\n     * or `null` height, the first instruction that it calls using a cross-program invocation (CPI)\n     * will have a height of 2, an instruction called by that instruction using a CPI will have a\n     * depth of 3, and so on.\n     */\n    stackHeight: number; // FIXME(https://github.com/anza-xyz/agave/issues/5732) Should be `1` instead of `null` at base of stack\n}>;\n\ntype InstructionWithData = Readonly<{\n    /** The input to the invoked program */\n    data: Base58EncodedBytes;\n}>;\n\ntype ParsedTransactionInstruction = Partial<InstructionWithStackHeight> &\n    Readonly<{\n        /** The output of the program's instruction parser */\n        parsed: {\n            /** The instruction, as interpreted the program's instruction parser. */\n            info?: object;\n            /**\n             * A label that indicates the type of the instruction, as determined by the program's\n             * instruction parser.\n             */\n            type: string;\n        };\n        /** The name of the program. */\n        program: string;\n        /** The address of the program */\n        programId: Address;\n    }>;\n\ntype PartiallyDecodedTransactionInstruction = InstructionWithData &\n    Partial<InstructionWithStackHeight> &\n    Readonly<{\n        /** An ordered list of addresses belonging to the accounts loaded by this instruction */\n        accounts: readonly Address[];\n        /** The address of the program to invoke */\n        programId: Address;\n    }>;\n\ntype ReturnData = {\n    /** A tuple whose first element is the bytes of the return data as a base64-encoded string. */\n    data: Base64EncodedDataResponse;\n    /** The address of the program that generated the return data */\n    programId: Address;\n};\n\ntype TransactionInstruction = InstructionWithData &\n    Partial<InstructionWithStackHeight> &\n    Readonly<{\n        /**\n         * An ordered list of indices that indicate which accounts in the transaction message's\n         * accounts list are loaded by this instruction.\n         */\n        accounts: readonly number[];\n        /**\n         * The index of the address in the transaction message's accounts list associated with the\n         * program to invoke.\n         */\n        programIdIndex: number;\n    }>;\n\ntype TransactionMessageBase = Readonly<{\n    header: {\n        /**\n         * The number of read-only accounts in the static accounts list that must sign this\n         * transaction.\n         *\n         * Subtracting this number from `numRequiredSignatures` yields the index of the first\n         * read-only signer account in the static accounts list.\n         */\n        numReadonlySignedAccounts: number;\n        /**\n         * The number of accounts in the static accounts list that are neither writable nor signers.\n         *\n         * Adding this number to `numRequiredSignatures` yields the index of the first read-only\n         * non-signer account in the static accounts list.\n         */\n        numReadonlyUnsignedAccounts: number;\n        /**\n         * The number of accounts in the static accounts list that must sign this transaction.\n         *\n         * Subtracting `numReadonlySignedAccounts` from this number yields the number of writable\n         * signer accounts in the static accounts list. Writable signer accounts always begin at\n         * index zero in the static accounts list.\n         *\n         * This number itself is the index of the first non-signer account in the static accounts\n         * list.\n         */\n        numRequiredSignatures: number;\n    };\n    /**\n     * For transactions whose lifetime is specified by a recent blockhash, this is that blockhash,\n     * and for transactions whose lifetime is specified by a durable nonce, this is the nonce value.\n     */\n    recentBlockhash: Blockhash;\n}>;\n\ntype TransactionParsedAccountBase = Readonly<{\n    /** The address of the account */\n    pubkey: Address;\n    /** Whether this account is required to sign the transaction that it's a part of */\n    signer: boolean;\n    /** Whether this account must be loaded with a write-lock */\n    writable: boolean;\n}>;\n\ntype TransactionParsedAccountLegacy = Readonly<{\n    /** Indicates that the account was statically declared in the transaction message */\n    source: 'transaction';\n}> &\n    TransactionParsedAccountBase;\n\ntype TransactionParsedAccountVersioned = Readonly<{\n    /**\n     * Indicates whether the account was statically declared in the transaction message or loaded\n     * from an address lookup table.\n     */\n    source: 'lookupTable' | 'transaction';\n}> &\n    TransactionParsedAccountBase;\n\n// Types for `accounts` transactionDetails\n\n// Only a partial version of the `TransactionMetaBase` type for when\n// `transactionDetails: 'accounts'` is provided.\ntype TransactionForAccountsMetaBase = Readonly<{\n    /** Error if transaction failed, `null` if transaction succeeded. */\n    err: TransactionError | null;\n    /** The fee this transaction was charged, in {@link Lamports} */\n    fee: Lamports;\n    /** Account balances after the transaction was processed */\n    postBalances: readonly Lamports[];\n    /**\n     * List of token balances from after the transaction was processed or omitted if token balance\n     * recording was not yet enabled during this transaction\n     */\n    postTokenBalances?: readonly TokenBalance[];\n    /** Account balances from before the transaction was processed */\n    preBalances: readonly Lamports[];\n    /**\n     * List of token balances from before the transaction was processed or omitted if token balance\n     * recording was not yet enabled during this transaction\n     */\n    preTokenBalances?: readonly TokenBalance[];\n    /** @deprecated */\n    status: TransactionStatus;\n}>;\n\ntype TransactionWithSignatures = Readonly<{\n    /**\n     * An ordered list of signatures belonging to the accounts required to sign this transaction.\n     *\n     * Each signature is an Ed25519 signature of the transaction message using the private key\n     * associated with the account required to sign the transaction.\n     */\n    signatures: readonly Base58EncodedBytes[];\n}>;\n\n// Accounts\n\nexport type TransactionForAccounts<TMaxSupportedTransactionVersion extends TransactionVersion | void> =\n    TMaxSupportedTransactionVersion extends void\n        ? Readonly<{\n              /** Transaction partial meta */\n              meta: TransactionForAccountsMetaBase | null;\n              /** Partial transactions */\n              transaction: Readonly<{\n                  /** Parsed accounts */\n                  accountKeys: readonly TransactionParsedAccountLegacy[];\n              }> &\n                  TransactionWithSignatures;\n          }>\n        : Readonly<{\n              /** Transaction partial meta */\n              meta: TransactionForAccountsMetaBase | null;\n              /** Partial transactions */\n              transaction: Readonly<{\n                  /** Parsed accounts */\n                  accountKeys: readonly TransactionParsedAccountVersioned[];\n              }> &\n                  TransactionWithSignatures;\n              /** The transaction version */\n              version: TransactionVersion;\n          }>;\n\n// Types for `full` transactionDetails\n\ntype TransactionForFullMetaBase = Readonly<{\n    /** Number of compute units consumed by the transaction */\n    computeUnitsConsumed?: bigint;\n    /** String log messages or `null` if log message recording was not enabled during this transaction */\n    logMessages: readonly string[] | null;\n    /** The most-recent return data generated by an instruction in the transaction */\n    returnData?: ReturnData;\n    /** Transaction-level rewards */\n    rewards: readonly Reward[] | null;\n}> &\n    TransactionForAccountsMetaBase;\n\nexport type TransactionForFullMetaInnerInstructionsUnparsed = Readonly<{\n    /** A list of instructions called by programs via cross-program invocation (CPI) */\n    innerInstructions: readonly Readonly<{\n        /** The index of the instruction in the transaction */\n        index: number;\n        /** The instructions */\n        instructions: readonly TransactionInstruction[];\n    }>[];\n}>;\n\nexport type TransactionForFullMetaInnerInstructionsParsed = Readonly<{\n    /** A list of instructions called by programs via cross-program invocation (CPI) */\n    innerInstructions: readonly Readonly<{\n        /** The index of the instruction in the transaction */\n        index: number;\n        /** The instructions */\n        instructions: readonly (ParsedTransactionInstruction | PartiallyDecodedTransactionInstruction)[];\n    }>[];\n}>;\n\n// According to the RPC docs: \"Transaction addresses loaded from address lookup tables.\n// Undefined if maxSupportedTransactionVersion is not set in request params, or if jsonParsed\n// encoding is set in request params.\"\ntype TransactionForFullMetaLoadedAddresses = Readonly<{\n    /** Addresses loaded from lookup tables */\n    loadedAddresses: {\n        /** Ordered list of base-58 encoded addresses for read-only accounts */\n        readonly: readonly Address[];\n        /** Ordered list of base-58 encoded addresses for writable accounts */\n        writable: readonly Address[];\n    };\n}>;\n\ntype TransactionForFullTransactionAddressTableLookups = Readonly<{\n    message: {\n        /** A list of address tables and the accounts that this transaction loads from them */\n        addressTableLookups?: readonly AddressTableLookup[] | null;\n    };\n}>;\n\n// Base58\n\nexport type TransactionForFullBase58<TMaxSupportedTransactionVersion extends TransactionVersion | void> =\n    TMaxSupportedTransactionVersion extends void\n        ? Readonly<{\n              /** Transaction meta */\n              meta: (TransactionForFullMetaBase & TransactionForFullMetaInnerInstructionsUnparsed) | null;\n              /** Partial transactions */\n              transaction: Base58EncodedDataResponse;\n          }>\n        : Readonly<{\n              /** Transaction meta */\n              meta:\n                  | (TransactionForFullMetaBase &\n                        TransactionForFullMetaInnerInstructionsUnparsed &\n                        TransactionForFullMetaLoadedAddresses)\n                  | null;\n              /** Partial transactions */\n              transaction: Base58EncodedDataResponse;\n              /** The transaction version */\n              version: TransactionVersion;\n          }>;\n\n// Base64\n\nexport type TransactionForFullBase64<TMaxSupportedTransactionVersion extends TransactionVersion | void> =\n    TMaxSupportedTransactionVersion extends void\n        ? Readonly<{\n              /** Transaction meta */\n              meta: (TransactionForFullMetaBase & TransactionForFullMetaInnerInstructionsUnparsed) | null;\n              /** Partial transactions */\n              transaction: Base64EncodedDataResponse;\n          }>\n        : Readonly<{\n              /** Transaction meta */\n              meta:\n                  | (TransactionForFullMetaBase &\n                        TransactionForFullMetaInnerInstructionsUnparsed &\n                        TransactionForFullMetaLoadedAddresses)\n                  | null;\n              /** Partial transactions */\n              transaction: Base64EncodedDataResponse;\n              /** The transaction version */\n              version: TransactionVersion;\n          }>;\n\n// JsonParsed\n\ntype TransactionForFullTransactionJsonParsedBase = Readonly<{\n    message: Readonly<{\n        instructions: readonly (ParsedTransactionInstruction | PartiallyDecodedTransactionInstruction)[];\n    }> &\n        TransactionMessageBase;\n}> &\n    TransactionWithSignatures;\n\nexport type TransactionForFullJsonParsed<TMaxSupportedTransactionVersion extends TransactionVersion | void> =\n    TMaxSupportedTransactionVersion extends void\n        ? Readonly<{\n              meta: (TransactionForFullMetaBase & TransactionForFullMetaInnerInstructionsParsed) | null;\n              transaction: TransactionForFullTransactionJsonParsedBase & {\n                  message: Readonly<{\n                      /** Parsed accounts */\n                      accountKeys: readonly TransactionParsedAccountLegacy[];\n                  }>;\n              };\n          }>\n        : Readonly<{\n              meta:\n                  | (TransactionForFullMetaBase &\n                        TransactionForFullMetaInnerInstructionsParsed &\n                        TransactionForFullMetaLoadedAddresses)\n                  | null;\n              transaction: TransactionForFullTransactionJsonParsedBase & {\n                  message: Readonly<{\n                      /** Parsed accounts */\n                      accountKeys: readonly TransactionParsedAccountLegacy[];\n                  }>;\n              };\n              version: TransactionVersion;\n          }>;\n\n// Json\n\ntype TransactionForFullTransactionJsonBase = Readonly<{\n    message: Readonly<{\n        /** An ordered list of addresses belonging to the accounts loaded by this transaction */\n        accountKeys: readonly Address[];\n        instructions: readonly TransactionInstruction[];\n    }> &\n        TransactionMessageBase;\n}> &\n    TransactionWithSignatures;\n\nexport type TransactionForFullJson<TMaxSupportedTransactionVersion extends TransactionVersion | void> =\n    TMaxSupportedTransactionVersion extends void\n        ? Readonly<{\n              meta: (TransactionForFullMetaBase & TransactionForFullMetaInnerInstructionsUnparsed) | null;\n              transaction: TransactionForFullTransactionJsonBase;\n          }>\n        : Readonly<{\n              meta:\n                  | (TransactionForFullMetaBase &\n                        TransactionForFullMetaInnerInstructionsUnparsed &\n                        TransactionForFullMetaLoadedAddresses)\n                  | null;\n              transaction: TransactionForFullTransactionAddressTableLookups & TransactionForFullTransactionJsonBase;\n              version: TransactionVersion;\n          }>;\n\ntype RewardBase = Readonly<{\n    /** The number of reward {@link Lamports} credited or debited to the account */\n    lamports: SignedLamports;\n    /** The account balance in {@link Lamports} after the reward was applied */\n    postBalance: Lamports;\n    /** The address of the account that received the reward */\n    pubkey: Address;\n}>;\n\nexport type Reward =\n    | (Readonly<{\n          /** The type of reward */\n          rewardType: 'Fee' | 'Rent';\n      }> &\n          RewardBase)\n    // Commission is present only for voting and staking rewards\n    | (Readonly<{\n          /** The vote account commission when the reward was credited */\n          commission: number;\n          /** The type of reward */\n          rewardType: 'Staking' | 'Voting';\n      }> &\n          RewardBase);\n\n/** @deprecated */\nexport type TransactionStatus = { Err: TransactionError } | { Ok: null };\n"
  },
  {
    "path": "packages/rpc-types/src/typed-numbers.ts",
    "content": "import { Brand } from '@solana/nominal-types';\n\nexport type Slot = bigint;\nexport type Epoch = bigint;\n\n// Specifically being used to denote micro-lamports, which are 0.000001 lamports.\nexport type MicroLamports = Brand<bigint, 'MicroLamports'>;\nexport type SignedLamports = bigint;\n\n// FIXME(solana-labs/solana/issues/30341)\n// <https://stackoverflow.com/questions/45929493/node-js-maximum-safe-floating-point-number/57225494#57225494>\n// Beware that floating-point value precision can vary widely:\n// - For precision of 1 decimal place, anything above 562949953421311\n// - For precision of 2 decimal places, anything above 70368744177663\n// can be truncated or rounded because of a downcast to JavaScript `number` between your calling\n// code and the JSON-RPC transport.\nexport type F64UnsafeSeeDocumentation = number;\n"
  },
  {
    "path": "packages/rpc-types/src/unix-timestamp.ts",
    "content": "import { SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE, SolanaError } from '@solana/errors';\nimport { Brand } from '@solana/nominal-types';\n\n/**\n * This type represents a Unix timestamp in _seconds_.\n *\n * It is represented as a `bigint` in client code and an `i64` in server code.\n */\nexport type UnixTimestamp = Brand<bigint, 'UnixTimestamp'>;\n\n// Largest possible value to be represented by an i64\nconst maxI64Value = 9223372036854775807n; // 2n ** 63n - 1n\nconst minI64Value = -9223372036854775808n; // -(2n ** 63n)\n\n/**\n * This is a type guard that accepts a `bigint` as input. It will both return `true` if the integer\n * conforms to the {@link UnixTimestamp} type and will refine the type for use in your program.\n *\n * @example\n * ```ts\n * import { isUnixTimestamp } from '@solana/rpc-types';\n *\n * if (isUnixTimestamp(timestamp)) {\n *     // At this point, `timestamp` has been refined to a\n *     // `UnixTimestamp` that can be used anywhere timestamps are expected.\n *     timestamp satisfies UnixTimestamp;\n * } else {\n *     setError(`${timestamp} is not a Unix timestamp`);\n * }\n * ```\n */\n\nexport function isUnixTimestamp(putativeTimestamp: bigint): putativeTimestamp is UnixTimestamp {\n    return putativeTimestamp >= minI64Value && putativeTimestamp <= maxI64Value;\n}\n\n/**\n * Timestamp values returned from the RPC API conform to the type {@link UnixTimestamp}. You can use\n * a value of that type wherever a timestamp is expected.\n *\n * @example\n * From time to time you might acquire a number that you expect to be a timestamp, from an untrusted\n * network API or user input. To assert that such an arbitrary number is usable as a Unix timestamp,\n * use this function.\n *\n * ```ts\n * import { assertIsUnixTimestamp } from '@solana/rpc-types';\n *\n * // Imagine having received a value that you presume represents a timestamp.\n * // At this point we know only that it conforms to the `bigint` type.\n * try {\n *     // If this type assertion function doesn't throw, then\n *     // Typescript will upcast `timestamp` to `UnixTimestamp`.\n *     assertIsUnixTimestamp(timestamp);\n *     // At this point, `timestamp` is a `UnixTimestamp`.\n *     timestamp satisfies UnixTimestamp;\n * } catch (e) {\n *     // `timestamp` turned out not to be a valid Unix timestamp\n * }\n * ```\n */\nexport function assertIsUnixTimestamp(putativeTimestamp: bigint): asserts putativeTimestamp is UnixTimestamp {\n    if (putativeTimestamp < minI64Value || putativeTimestamp > maxI64Value) {\n        throw new SolanaError(SOLANA_ERROR__TIMESTAMP_OUT_OF_RANGE, {\n            value: putativeTimestamp,\n        });\n    }\n}\n\n/**\n * This helper combines _asserting_ that a `bigint` represents a Unix timestamp with _coercing_ it\n * to the {@link UnixTimestamp} type. It's best used with untrusted input.\n *\n * @example\n * ```ts\n * import { unixTimestamp } from '@solana/rpc-types';\n *\n * const timestamp = unixTimestamp(-42n); // Wednesday, December 31, 1969 3:59:18 PM GMT-08:00\n * ```\n */\nexport function unixTimestamp(putativeTimestamp: bigint): UnixTimestamp {\n    assertIsUnixTimestamp(putativeTimestamp);\n    return putativeTimestamp;\n}\n"
  },
  {
    "path": "packages/rpc-types/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/rpc-types/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2018\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/rpc-types\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/rpc-types/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/signers/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/signers/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/signers/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/signers/CHANGELOG.md",
    "content": "# @solana/signers\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/instructions@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/nominal-types@6.9.0\n    - @solana/offchain-messages@6.9.0\n    - @solana/transaction-messages@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Minor Changes\n\n- [#1531](https://github.com/anza-xyz/kit/pull/1531) [`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add an optional `extractable` argument to `generateKeyPair` and `generateKeyPairSigner`. It defaults to `false`, preserving the existing secure-by-default behavior, but can be set to `true` when you need to export the generated private key bytes via `crypto.subtle.exportKey()`.\n\n- [#1537](https://github.com/anza-xyz/kit/pull/1537) [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `writeKeyPair` and `writeKeyPairSigner` helpers for persisting an extractable key pair to disk as a JSON byte array, matching the format produced by `solana-keygen`. Missing parent directories are created automatically, and written files use mode `0600`. These helpers are Node-only and refuse to overwrite an existing file unless the caller sets `unsafelyOverwriteExistingKeyPair: true`.\n\n- [#1534](https://github.com/anza-xyz/kit/pull/1534) [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `grindKeyPair`, `grindKeyPairs`, `grindKeyPairSigner`, and `grindKeyPairSigners` for mining vanity key pairs whose base58-encoded public key matches a `RegExp` or a custom predicate. Supports `amount` for mining multiple key pairs, `extractable` for forwarding to the underlying `generateKeyPair` call, `concurrency` (defaulting to `32`) for batched parallel key generation, and `abortSignal` for cancellation. Regex matchers are statically checked for base58-alphabet violations at runtime (after stripping escapes, character classes, quantifiers, and groups) to catch common typos like `/^sol0/`.\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/instructions@6.8.0\n    - @solana/nominal-types@6.8.0\n    - @solana/offchain-messages@6.8.0\n    - @solana/transaction-messages@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/instructions@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/nominal-types@6.7.0\n    - @solana/offchain-messages@6.7.0\n    - @solana/transaction-messages@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- [#1492](https://github.com/anza-xyz/kit/pull/1492) [`0fa54a4`](https://github.com/anza-xyz/kit/commit/0fa54a469937db3989f42afc4248882736f719f5) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Allow `deduplicateSigners` to handle structurally equivalent signers (e.g. two `createNoopSigner` calls with the same address) instead of throwing.\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/transactions@6.6.0\n    - @solana/errors@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/instructions@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/offchain-messages@6.6.0\n    - @solana/nominal-types@6.6.0\n\n## 6.5.0\n\n### Minor Changes\n\n- [#1487](https://github.com/anza-xyz/kit/pull/1487) [`9e05736`](https://github.com/anza-xyz/kit/commit/9e057365a1a4e350f8a0ccc233b262e09b0134fa) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add `partiallySignTransactionWithSigners`, `signTransactionWithSigners`, and `signAndSendTransactionWithSigners` functions that accept a set of signers and a compiled `Transaction` directly, without requiring signers to be embedded in a transaction message. Also add `assertContainsResolvableTransactionSendingSigner` to validate that a set of signers contains an unambiguously resolvable sending signer. The existing transaction message helpers now delegate to these new functions internally.\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/instructions@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/nominal-types@6.5.0\n    - @solana/offchain-messages@6.5.0\n    - @solana/transaction-messages@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c), [`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/transaction-messages@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/instructions@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/offchain-messages@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/nominal-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/instructions@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/nominal-types@6.3.1\n    - @solana/offchain-messages@6.3.1\n    - @solana/transaction-messages@6.3.1\n    - @solana/transactions@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/instructions@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/offchain-messages@6.3.0\n    - @solana/transaction-messages@6.3.0\n    - @solana/transactions@6.3.0\n    - @solana/nominal-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/instructions@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/offchain-messages@6.2.0\n    - @solana/transaction-messages@6.2.0\n    - @solana/transactions@6.2.0\n    - @solana/nominal-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/offchain-messages@6.1.0\n    - @solana/transaction-messages@6.1.0\n    - @solana/transactions@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/instructions@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/nominal-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- [#1321](https://github.com/anza-xyz/kit/pull/1321) [`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix a bug in the type of `TransactionMessageWithSigners`\n\n- Updated dependencies [[`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492), [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462)]:\n    - @solana/transaction-messages@6.0.1\n    - @solana/transactions@6.0.1\n    - @solana/addresses@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/instructions@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/nominal-types@6.0.1\n    - @solana/offchain-messages@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926), [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a), [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db)]:\n    - @solana/transaction-messages@6.0.0\n    - @solana/transactions@6.0.0\n    - @solana/addresses@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/instructions@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/nominal-types@6.0.0\n    - @solana/offchain-messages@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/instructions@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/offchain-messages@5.5.1\n    - @solana/transaction-messages@5.5.1\n    - @solana/transactions@5.5.1\n    - @solana/nominal-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/instructions@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/offchain-messages@5.5.0\n    - @solana/transaction-messages@5.5.0\n    - @solana/transactions@5.5.0\n    - @solana/nominal-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/transaction-messages@5.4.0\n    - @solana/offchain-messages@5.4.0\n    - @solana/nominal-types@5.4.0\n    - @solana/instructions@5.4.0\n    - @solana/transactions@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/instructions@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/nominal-types@5.3.0\n    - @solana/offchain-messages@5.3.0\n    - @solana/transaction-messages@5.3.0\n    - @solana/transactions@5.3.0\n\n## 5.2.0\n\n### Minor Changes\n\n- [#1139](https://github.com/anza-xyz/kit/pull/1139) [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Return more precise types from transaction message functions\n\n    Deprecate `BaseTransactionMessage` in favour of `TransactionMessage`\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/transaction-messages@5.2.0\n    - @solana/transactions@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/instructions@5.2.0\n    - @solana/offchain-messages@5.2.0\n    - @solana/nominal-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951), [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd)]:\n    - @solana/offchain-messages@5.1.0\n    - @solana/errors@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/transactions@5.1.0\n    - @solana/transaction-messages@5.1.0\n    - @solana/instructions@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/nominal-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n    - @solana/transaction-messages@5.0.0\n    - @solana/transactions@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/instructions@5.0.0\n    - @solana/keys@5.0.0\n    - @solana/nominal-types@5.0.0\n\n## 4.0.0\n\n### Major Changes\n\n- [#927](https://github.com/anza-xyz/kit/pull/927) [`c035ab8`](https://github.com/anza-xyz/kit/commit/c035ab8a488486d160ca0361408493115cd09383) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the signer API to return Transaction & TransactionWithLifetime\n\n    The `modifyAndSignTransactions` function for a `TransactionModifyingSigner` must now return a `Transaction & TransactionWithLifetime & TransactionWithinSizeLimit`. Previously it technically needed to return a type derived from the input `TransactionMessage`, but this wasn't checked.\n\n    If you have written a `TransactionModifyingSigner` then you should review the changes to `useWalletAccountTransactionSigner` in the React package for guidance. You may need to use the new `getTransactionLifetimeConstraintFromCompiledTransactionMessage` function to obtain a lifetime for the transaction being returned.\n\n    If you are using a `TransactionModifyingSigner` such as `useWalletAccountTransactionSigner`, then you will now receive a transaction with `TransactionWithLifetime` when you would previously have received a type with a lifetime matching the input transaction message. This was never guaranteed to match at runtime, but we incorrectly returned a stronger type than can be guaranteed. You may need to use the new `isTransactionWithBlockhashLifetime` or `isTransactionWithDurableNonceLifetime` functions to check the lifetime type of the returned transaction. For example, if you want to pass it to a function returned by `sendAndConfirmTransactionFactory` then you must use `isTransactionWithBlockhashLifetime` or `assertIsTransactionWithBlockhashLifetime` to check its lifetime first.\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df), [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013)]:\n    - @solana/transactions@4.0.0\n    - @solana/errors@4.0.0\n    - @solana/keys@4.0.0\n    - @solana/transaction-messages@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/instructions@4.0.0\n    - @solana/nominal-types@4.0.0\n\n## 3.0.0\n\n### Major Changes\n\n- [#574](https://github.com/anza-xyz/kit/pull/574) [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add the `TransactionWithLifetime` requirement when signing transactions. This is because, whilst a lifetime may not always be required before compile a transaction message, it is always required when signing a transaction. Otherwise, the transaction signatures will be invalid when one is added later.\n\n- [#462](https://github.com/anza-xyz/kit/pull/462) [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: The `FullySignedTransaction` no longer extends the `Transaction` type so it can be composed with other flags that also narrow transaction types. This means, whenever `FullySignedTransaction` is used on its own, it will need to be replaced with `FullySignedTransaction & Transaction`.\n\n- [#691](https://github.com/anza-xyz/kit/pull/691) [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: Removes the following deprecated types: `ITransactionMessageWithSigners`, `ITransactionMessageWithFeePayerSigner`, `ITransactionMessageWithSingleSendingSigner`, `IAccountSignerMeta` and `IInstructionWithSigners`.\n\n### Minor Changes\n\n- [#582](https://github.com/anza-xyz/kit/pull/582) [`93ae6f9`](https://github.com/anza-xyz/kit/commit/93ae6f96859019b6c7ea9a596ffb9b1be7a35e64) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Allow transaction messages with no lifetime constraints to be signed using the Signer API helpers such as `signTransactionMessageWithSigners` and `partiallySignTransactionMessageWithSigners`. This is because some `TransactionSigners` such as `TransactionModifyingSigners` have the ability to update the transaction before signing it, meaning that the lifetime constraint may not be known until the transaction is signed.\n\n- [#581](https://github.com/anza-xyz/kit/pull/581) [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Allow transaction messages with no lifetime constraints to be compiled. Renames `TransactionFromCompilableTransactionMessage` and `SetTransactionLifetimeFromCompilableTransactionMessage` type helpers to `TransactionFromTransactionMessage` and `SetTransactionLifetimeFromTransactionMessage` respectively, to reflect that they can now be used with transaction messages that do not have a lifetime constraint.\n\n### Patch Changes\n\n- [#584](https://github.com/anza-xyz/kit/pull/584) [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate `CompilableTransactionMessage` in favour of `TransactionMessage & TransactionMessageWithFeePayer`\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6), [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0), [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845), [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf)]:\n    - @solana/transaction-messages@3.0.0\n    - @solana/instructions@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/transactions@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/keys@3.0.0\n    - @solana/nominal-types@3.0.0\n\n## 2.3.0\n\n### Minor Changes\n\n- [#468](https://github.com/anza-xyz/kit/pull/468) [`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add, remove and forward the `TransactionMessageWithinSizeLimit` and `TransactionWithinSizeLimit` types in all helpers that may affect the size of a transaction or transaction message.\n\n- [#426](https://github.com/anza-xyz/kit/pull/426) [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate the `I` prefix of four transaction message types to stay consistent with the rest of them. Namely, the following types are renamed and their old names are marked as deprecated:\n    - `ITransactionMessageWithFeePayer` -> `TransactionMessageWithFeePayer`\n    - `ITransactionMessageWithFeePayerSigner` -> `TransactionMessageWithFeePayerSigner`\n    - `ITransactionMessageWithSigners` -> `TransactionMessageWithSigners`\n    - `ITransactionMessageWithSingleSendingSigner` -> `TransactionMessageWithSingleSendingSigner`\n\n- [#488](https://github.com/anza-xyz/kit/pull/488) [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove the `I` prefix on the following types: `IInstruction`, `IInstructionWithAccounts`, `IInstructionWithData`, `IInstructionWithSigners`, `IAccountMeta`, `IAccountLookupMeta` and `IAccountSignerMeta`. The old names are kept as aliases but marked as deprecated.\n\n### Patch Changes\n\n- Updated dependencies [[`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a), [`53e1336`](https://github.com/anza-xyz/kit/commit/53e1336149878c84048e0fde5c7e7ace6cc1e97f), [`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eb61d94`](https://github.com/anza-xyz/kit/commit/eb61d94786e212fc23778d445a94b86d2b1b024f), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`bbcb913`](https://github.com/anza-xyz/kit/commit/bbcb913839d33abc746f38d6e65e7bfd30cd2ac6), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`e6c0568`](https://github.com/anza-xyz/kit/commit/e6c0568ef34fdc04075af27eb102851123a02be0), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/transaction-messages@2.3.0\n    - @solana/transactions@2.3.0\n    - @solana/errors@2.3.0\n    - @solana/instructions@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/keys@2.3.0\n    - @solana/nominal-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/instructions@2.2.1\n    - @solana/keys@2.2.1\n    - @solana/nominal-types@2.2.1\n    - @solana/transaction-messages@2.2.1\n    - @solana/transactions@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893), [`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/nominal-types@2.2.0\n    - @solana/addresses@2.2.0\n    - @solana/keys@2.2.0\n    - @solana/transaction-messages@2.2.0\n    - @solana/transactions@2.2.0\n    - @solana/instructions@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`776e18d`](https://github.com/anza-xyz/kit/commit/776e18d75c759a839608069c61da3f70b775540b), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/transaction-messages@2.1.1\n    - @solana/nominal-types@2.1.1\n    - @solana/instructions@2.1.1\n    - @solana/transactions@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/errors@2.1.1\n    - @solana/keys@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [#151](https://github.com/anza-xyz/kit/pull/151) [`a1e45a1`](https://github.com/anza-xyz/kit/commit/a1e45a1d91ba1ac530eea0986b2ffeafb9713aec) Thanks [@lorisleiva](https://github.com/lorisleiva)! - `addSignersToTransactionMessage` now upgrades `feePayer` to a signer when applicable\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/keys@2.1.0\n    - @solana/transaction-messages@2.1.0\n    - @solana/instructions@2.1.0\n    - @solana/transactions@2.1.0\n\n## 2.0.0\n\n### Minor Changes\n\n- [#2858](https://github.com/solana-labs/solana-web3.js/pull/2858) [`22a34aa`](https://github.com/solana-labs/solana-web3.js/commit/22a34aa08d1be7e9b43ccfea94a99eaa2694e491) Thanks [@steveluscher](https://github.com/steveluscher)! - Transaction signers' methods now take `minContextSlot` as an option. This is important for signers that simulate transactions, like wallets. They might be interested in knowing the slot at which the transaction was prepared, lest they run simulation at too early a slot.\n\n### Patch Changes\n\n- [#3051](https://github.com/solana-labs/solana-web3.js/pull/3051) [`1ad523d`](https://github.com/solana-labs/solana-web3.js/commit/1ad523dc5792d9152a66e9dc2b83294e3eba4db0) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a `createKeyPairSignerFromPrivateKeyBytes` helper that compose `createKeyPairFromPrivateKeyBytes` and `createSignerFromKeyPair`.\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2852](https://github.com/solana-labs/solana-web3.js/pull/2852) [`cec9048`](https://github.com/solana-labs/solana-web3.js/commit/cec9048b2f83535df7e499db5488c336981dfb5a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - The `signAndSendTransactionMessageWithSigners` function now automatically asserts that the provided transaction message contains a single sending signer and fails otherwise.\n\n- [#2707](https://github.com/solana-labs/solana-web3.js/pull/2707) [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow creating keypairs and keys from ReadonlyUint8Array\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3481](https://github.com/solana-labs/solana-web3.js/pull/3481) [`4decebb`](https://github.com/solana-labs/solana-web3.js/commit/4decebb9b619972f49c740323b59cf470696e105) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove the `feePayerSigner` attribute of transaction messages in favour of the existing `feePayer` attribute. This ensures fee payers are defined in a single place — whether they are using signers or not.\n\n- [#3482](https://github.com/solana-labs/solana-web3.js/pull/3482) [`d4965ec`](https://github.com/solana-labs/solana-web3.js/commit/d4965ece9abaf81e3006442db15f3f77d89a622c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Override `feePayer` signer when the address matches the existing one. This is because users may want to provide a different wallet from the same address.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/transactions@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/keys@2.0.0\n    - @solana/transaction-messages@2.0.0\n    - @solana/instructions@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/instructions@2.0.0-rc.4\n    - @solana/keys@2.0.0-rc.4\n    - @solana/transaction-messages@2.0.0-rc.4\n    - @solana/transactions@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/instructions@2.0.0-rc.3\n    - @solana/keys@2.0.0-rc.3\n    - @solana/transaction-messages@2.0.0-rc.3\n    - @solana/transactions@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- [#3481](https://github.com/solana-labs/solana-web3.js/pull/3481) [`4decebb`](https://github.com/solana-labs/solana-web3.js/commit/4decebb9b619972f49c740323b59cf470696e105) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove the `feePayerSigner` attribute of transaction messages in favour of the existing `feePayer` attribute. This ensures fee payers are defined in a single place — whether they are using signers or not.\n\n- [#3482](https://github.com/solana-labs/solana-web3.js/pull/3482) [`d4965ec`](https://github.com/solana-labs/solana-web3.js/commit/d4965ece9abaf81e3006442db15f3f77d89a622c) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Override `feePayer` signer when the address matches the existing one. This is because users may want to provide a different wallet from the same address.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/transaction-messages@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/instructions@2.0.0-rc.2\n    - @solana/transactions@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n    - @solana/keys@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- [#3051](https://github.com/solana-labs/solana-web3.js/pull/3051) [`1ad523d`](https://github.com/solana-labs/solana-web3.js/commit/1ad523dc5792d9152a66e9dc2b83294e3eba4db0) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a `createKeyPairSignerFromPrivateKeyBytes` helper that compose `createKeyPairFromPrivateKeyBytes` and `createSignerFromKeyPair`.\n\n- Updated dependencies [[`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302)]:\n    - @solana/keys@2.0.0-rc.1\n    - @solana/transactions@2.0.0-rc.1\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/instructions@2.0.0-rc.1\n    - @solana/transaction-messages@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/transaction-messages@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/transactions@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/instructions@2.0.0-rc.0\n    - @solana/keys@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Minor Changes\n\n- [#2858](https://github.com/solana-labs/solana-web3.js/pull/2858) [`22a34aa`](https://github.com/solana-labs/solana-web3.js/commit/22a34aa08d1be7e9b43ccfea94a99eaa2694e491) Thanks [@steveluscher](https://github.com/steveluscher)! - Transaction signers' methods now take `minContextSlot` as an option. This is important for signers that simulate transactions, like wallets. They might be interested in knowing the slot at which the transaction was prepared, lest they run simulation at too early a slot.\n\n### Patch Changes\n\n- [#2852](https://github.com/solana-labs/solana-web3.js/pull/2852) [`cec9048`](https://github.com/solana-labs/solana-web3.js/commit/cec9048b2f83535df7e499db5488c336981dfb5a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - The `signAndSendTransactionMessageWithSigners` function now automatically asserts that the provided transaction message contains a single sending signer and fails otherwise.\n\n- [#2707](https://github.com/solana-labs/solana-web3.js/pull/2707) [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Allow creating keypairs and keys from ReadonlyUint8Array\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/errors@2.0.0-preview.4\n    - @solana/keys@2.0.0-preview.4\n    - @solana/transaction-messages@2.0.0-preview.4\n    - @solana/instructions@2.0.0-preview.4\n    - @solana/transactions@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/transactions@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/transaction-messages@2.0.0-preview.3\n    - @solana/keys@2.0.0-preview.3\n    - @solana/instructions@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/addresses@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n    - @solana/instructions@2.0.0-preview.2\n    - @solana/keys@2.0.0-preview.2\n    - @solana/transactions@2.0.0-preview.2\n"
  },
  {
    "path": "packages/signers/LICENSE",
    "content": "Copyright (c) 2018 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/signers/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/signers?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/signers?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/signers\n\n# @solana/signers\n\nThis package provides an abstraction layer over signing messages and transactions in Solana. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nYou can think of signers as an abstract way to sign messages and transactions. This could be using a Crypto KeyPair, a wallet adapter in the browser, a Noop signer for testing purposes, or anything you want. Here's an example using a `CryptoKeyPair` signer:\n\n```ts\nimport { pipe } from '@solana/functional';\nimport { generateKeyPairSigner } from '@solana/signers';\nimport { createTransactionMessage } from '@solana/transaction-messages';\nimport { compileTransaction } from '@solana/transactions';\n\n// Generate a key pair signer.\nconst mySigner = await generateKeyPairSigner();\nmySigner.address; // Address;\n\n// Sign one or multiple messages.\nconst myMessage = createSignableMessage('Hello world!');\nconst [messageSignatures] = await mySigner.signMessages([myMessage]);\n\n// Sign one or multiple transaction messages.\nconst myTransactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    // Add instructions, fee payer, lifetime, etc.\n);\nconst myTransaction = compileTransaction(myTransactionMessage);\nconst [transactionSignatures] = await mySigner.signTransactions([myTransaction]);\n```\n\nAs you can see, this provides a consistent API regardless of how things are being signed behind the scenes. If tomorrow we need to use a browser wallet instead, we'd simply need to swap the `generateKeyPairSigner` function with the signer factory of our choice.\n\nThis package offers a total of five different types of signers that may be used in combination when applicable. Three of them allow us to sign transactions whereas the other two are used for regular message signing.\n\nThey are separated into three categories:\n\n- **Partial signers**: Given a message or transaction, provide one or more signatures for it. These signers are not able to modify the given data which allows us to run many of them in parallel.\n- **Modifying signers**: Can choose to modify a message or transaction before signing it with zero or more private keys. Because modifying a message or transaction invalidates any pre-existing signatures over it, modifying signers must do their work before any other signer.\n- **Sending signers**: Given a transaction, signs it and sends it immediately to the blockchain. When applicable, the signer may also decide to modify the provided transaction before signing it. This interface accommodates wallets that simply cannot sign a transaction without sending it at the same time. This category of signers does not apply to regular messages.\n\nThus, we end up with the following interfaces.\n\n|                     | Partial signers            | Modifying signers            | Sending signers            |\n| ------------------- | -------------------------- | ---------------------------- | -------------------------- |\n| `TransactionSigner` | `TransactionPartialSigner` | `TransactionModifyingSigner` | `TransactionSendingSigner` |\n| `MessageSigner`     | `MessagePartialSigner`     | `MessageModifyingSigner`     | N/A                        |\n\nWe will go through each of these five signer interfaces and their respective characteristics in the documentation below.\n\nThis package also provides the following concrete signer implementations:\n\n- The `KeyPairSigner` which uses a `CryptoKeyPair` to sign messages and transactions.\n- The Noop signer which does not sign anything and is mostly useful for testing purposes or for indicating that an account will be signed in a different environment (e.g. sending a transaction to your server so it can sign it).\n\nAdditionally, this package allows transaction signers to be stored inside the account meta of an instruction. This allows us to create instructions by passing around signers instead of addresses when applicable which, in turn, allows us to sign an entire transaction automatically without having to scan through its instructions to find the required signers.\n\nIn the sections below, we'll go through all the provided signers in more detail before diving into storing signers inside instruction account metas and how to benefit from it.\n\n## Signing messages\n\n### Types\n\n#### `SignableMessage`\n\nDefines a message with any of the signatures that might have already been provided by other signers. This interface allows modifying signers to decide on whether or not they should modify the provided message depending on whether or not signatures already exist for such message. It also helps create a more consistent API by providing a structure analogous to transactions which also keep track of their signature dictionary.\n\n```ts\ntype SignableMessage = {\n    content: Uint8Array;\n    signatures: SignatureDictionary; // Record<Address, SignatureBytes>\n};\n```\n\n#### `MessagePartialSigner<TAddress>`\n\nAn interface that signs an array of `SignableMessages` without modifying their content. It defines a `signMessages` function that returns a `SignatureDictionary` for each provided message. Such signature dictionaries are expected to be merged with the existing ones if any.\n\n```ts\nconst myMessagePartialSigner: MessagePartialSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    signMessages: async (messages: SignableMessage[]): Promise<SignatureDictionary[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Parallel**. When multiple signers sign the same message, we can perform this operation in parallel to obtain all their signatures.\n- **Flexible order**. The order in which we use these signers for a given message doesn’t matter.\n\n#### `MessageModifyingSigner<TAddress>`\n\nAn interface that potentially modifies the content of the provided `SignableMessages` before signing them. E.g. this enables wallets to prefix or suffix nonces to the messages they sign. For each message, instead of returning a `SignatureDictionary`, its `modifyAndSignMessages` function returns its updated `SignableMessage` with a potentially modified content and signature dictionary.\n\n```ts\nconst myMessageModifyingSigner: MessageModifyingSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    modifyAndSignMessages: async (messages: SignableMessage[]): Promise<SignableMessage[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Sequential**. Contrary to partial signers, these cannot be executed in parallel as each call can modify the content of the message.\n- **First signers**. For a given message, a modifying signer must always be used before a partial signer as the former will likely modify the message and thus impact the outcome of the latter.\n- **Potential conflicts**. If more than one modifying signer is provided, the second signer may invalidate the signature of the first one. However, modifying signers may decide not to modify a message based on the existence of signatures for that message.\n\n#### `MessageSigner<TAddress>`\n\nUnion interface that uses any of the available message signers.\n\n```ts\ntype MessageSigner<TAddress extends string = string> =\n    | MessagePartialSigner<TAddress>\n    | MessageModifyingSigner<TAddress>;\n```\n\n### Functions\n\n#### `createSignableMessage(content, signatures?)`\n\nCreates a `SignableMessage` from a `Uint8Array` or a UTF-8 string. It optionally accepts a signature dictionary if the message already contains signatures.\n\n```ts\nconst myMessage = createSignableMessage(new Uint8Array([1, 2, 3]));\nconst myMessageFromText = createSignableMessage('Hello world!');\nconst myMessageWithSignatures = createSignableMessage('Hello world!', {\n    [address('1234..5678')]: new Uint8Array([1, 2, 3]) as SignatureBytes,\n});\n```\n\n#### Type guards\n\nEach of the message interfaces described above comes with two type guards that allow us to check whether or not a given value is a message signer of the requested type. One that returns a boolean and one that asserts by throwing an error if the provided value is not of the expected interface.\n\n```ts\nconst myAddress = address('1234..5678');\n\nisMessagePartialSigner({ address: myAddress, signMessages: async () => {} }); // ✅ true\nisMessagePartialSigner({ address: myAddress }); // ❌ false\nassertIsMessagePartialSigner({ address: myAddress, signMessages: async () => {} }); // ✅ void\nassertIsMessagePartialSigner({ address: myAddress }); // ❌ Throws an error.\n\nisMessageModifyingSigner({ address: myAddress, modifyAndSignMessages: async () => {} }); // ✅ true\nisMessageModifyingSigner({ address: myAddress }); // ❌ false\nassertIsMessageModifyingSigner({ address: myAddress, modifyAndSignMessages: async () => {} }); // ✅ void\nassertIsMessageModifyingSigner({ address: myAddress }); // ❌ Throws an error.\n\nisMessageSigner({ address: myAddress, signMessages: async () => {} }); // ✅ true\nisMessageSigner({ address: myAddress, modifyAndSignMessages: async () => {} }); // ✅ true\nassertIsMessageSigner({ address: myAddress, signMessages: async () => {} }); // ✅ void\nassertIsMessageSigner({ address: myAddress, modifyAndSignMessages: async () => {} }); // ✅ void\n```\n\n## Signing transactions\n\n### Types\n\n#### `TransactionPartialSigner<TAddress>`\n\nAn interface that signs an array of `Transactions` without modifying their content. It defines a `signTransactions` function that returns a `SignatureDictionary` for each provided transaction. Such signature dictionaries are expected to be merged with the existing ones if any.\n\n```ts\nconst myTransactionPartialSigner: TransactionPartialSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    signTransactions: async (transactions: Transaction[]): Promise<SignatureDictionary[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Parallel**. It returns a signature dictionary for each provided transaction without modifying them, making it possible for multiple partial signers to sign the same transaction in parallel.\n- **Flexible order**. The order in which we use these signers for a given transaction doesn’t matter.\n\n#### `TransactionModifyingSigner<TAddress>`\n\nAn interface that potentially modifies the provided `Transactions` before signing them. E.g. this enables wallets to inject additional instructions into the transaction before signing them. For each transaction, instead of returning a `SignatureDictionary`, its `modifyAndSignTransactions` function returns an updated `Transaction` with a potentially modified set of instructions and signature dictionary.\n\n```ts\nconst myTransactionModifyingSigner: TransactionModifyingSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    modifyAndSignTransactions: async <T extends Transaction>(transactions: T[]): Promise<T[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Sequential**. Contrary to partial signers, these cannot be executed in parallel as each call can modify the provided transactions.\n- **First signers**. For a given transaction, a modifying signer must always be used before a partial signer as the former will likely modify the transaction and thus impact the outcome of the latter.\n- **Potential conflicts**. If more than one modifying signer is provided, the second signer may invalidate the signature of the first one. However, modifying signers may decide not to modify a transaction based on the existence of signatures for that transaction.\n\n#### `TransactionSendingSigner<TAddress>`\n\nAn interface that signs one or multiple transactions before sending them immediately to the blockchain. It defines a `signAndSendTransactions` function that returns the transaction signature (i.e. its identifier) for each provided `Transaction`. This interface is required for PDA wallets and other types of wallets that don't provide an interface for signing transactions without sending them.\n\nNote that it is also possible for such signers to modify the provided transactions before signing and sending them. This enables use cases where the modified transactions cannot be shared with the app and thus must be sent directly.\n\n```ts\nconst myTransactionSendingSigner: TransactionSendingSigner<'1234..5678'> = {\n    address: address('1234..5678'),\n    signAndSendTransactions: async (transactions: Transaction[]): Promise<SignatureBytes[]> => {\n        // My custom signing logic.\n    },\n};\n```\n\n**Characteristics**:\n\n- **Single signer**. Since this signer also sends the provided transactions, we can only use a single `TransactionSendingSigner` for a given set of transactions.\n- **Last signer**. Trivially, that signer must also be the last one used.\n- **Potential conflicts**. Since signers may decide to modify the given transactions before sending them, they may invalidate previous signatures. However, signers may decide not to modify a transaction based on the existence of signatures for that transaction.\n- **Potential confirmation**. Whilst this is not required by this interface, it is also worth noting that most wallets will also wait for the transaction to be confirmed (typically with a `confirmed` commitment) before notifying the app that they are done.\n\n#### `TransactionSigner<TAddress>`\n\nUnion interface that uses any of the available transaction signers.\n\n```ts\ntype TransactionSigner<TAddress extends string = string> =\n    | TransactionPartialSigner<TAddress>\n    | TransactionModifyingSigner<TAddress>\n    | TransactionSendingSigner<TAddress>;\n```\n\n### Functions\n\n#### Type guards\n\nEach of the transaction interfaces described above comes with two type guards that allow us to check whether or not a given value is a transaction signer of the requested type. One that returns a boolean and one that asserts by throwing an error if the provided value is not of the expected interface.\n\n```ts\nconst myAddress = address('1234..5678');\n\nisTransactionPartialSigner({ address: myAddress, signTransactions: async () => {} }); // ✅ true\nisTransactionPartialSigner({ address: myAddress }); // ❌ false\nassertIsTransactionPartialSigner({ address: myAddress, signTransactions: async () => {} }); // ✅ void\nassertIsTransactionPartialSigner({ address: myAddress }); // ❌ Throws an error.\n\nisTransactionModifyingSigner({ address: myAddress, modifyAndSignTransactions: async () => {} }); // ✅ true\nisTransactionModifyingSigner({ address: myAddress }); // ❌ false\nassertIsTransactionModifyingSigner({ address: myAddress, modifyAndSignTransactions: async () => {} }); // ✅ void\nassertIsTransactionModifyingSigner({ address: myAddress }); // ❌ Throws an error.\n\nisTransactionSendingSigner({ address: myAddress, signAndSignTransaction: async () => {} }); // ✅ true\nisTransactionSendingSigner({ address: myAddress }); // ❌ false\nassertIsTransactionSendingSigner({ address: myAddress, signAndSignTransaction: async () => {} }); // ✅ void\nassertIsTransactionSendingSigner({ address: myAddress }); // ❌ Throws an error.\n\nisTransactionSigner({ address: myAddress, signTransactions: async () => {} }); // ✅ true\nisTransactionSigner({ address: myAddress, modifyAndSignTransactions: async () => {} }); // ✅ true\nisTransactionSigner({ address: myAddress, signAndSignTransaction: async () => {} }); // ✅ true\nassertIsTransactionSigner({ address: myAddress, signTransactions: async () => {} }); // ✅ void\nassertIsTransactionSigner({ address: myAddress, modifyAndSignTransactions: async () => {} }); // ✅ void\nassertIsTransactionSigner({ address: myAddress, signAndSignTransaction: async () => {} }); // ✅ void\n```\n\n## Creating and generating KeyPair signers\n\n### Types\n\n#### `KeyPairSigner<TAddress>`\n\nDefines a signer that uses a `CryptoKeyPair` to sign messages and transactions. It implements both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces and keeps track of the `CryptoKeyPair` instance used to sign messages and transactions.\n\n```ts\nimport { generateKeyPairSigner } from '@solana/signers';\n\nconst myKeyPairSigner = generateKeyPairSigner();\nmyKeyPairSigner.address; // Address;\nmyKeyPairSigner.keyPair; // CryptoKeyPair;\nconst [myMessageSignatures] = await myKeyPairSigner.signMessages([myMessage]);\nconst [myTransactionSignatures] = await myKeyPairSigner.signTransactions([myTransaction]);\n```\n\n### Functions\n\n#### `createSignerFromKeyPair()`\n\nCreates a `KeyPairSigner` from a provided Crypto KeyPair. The `signMessages` and `signTransactions` functions of the returned signer will use the private key of the provided key pair to sign messages and transactions. Note that both the `signMessages` and `signTransactions` implementations are parallelized, meaning that they will sign all provided messages and transactions in parallel.\n\n```ts\nimport { generateKeyPair } from '@solana/keys';\nimport { createSignerFromKeyPair, KeyPairSigner } from '@solana/signers';\n\nconst myKeyPair: CryptoKeyPair = await generateKeyPair();\nconst myKeyPairSigner: KeyPairSigner = await createSignerFromKeyPair(myKeyPair);\n```\n\n#### `generateKeyPairSigner()`\n\nA convenience function that generates a new Crypto KeyPair and immediately creates a `KeyPairSigner` from it.\n\n```ts\nimport { generateKeyPairSigner } from '@solana/signers';\n\nconst myKeyPairSigner = await generateKeyPairSigner();\n```\n\n#### `createKeyPairSignerFromBytes()`\n\nA convenience function that creates a new KeyPair from a 64-bytes `Uint8Array` secret key and immediately creates a `KeyPairSigner` from it.\n\n```ts\nimport fs from 'fs';\nimport { createKeyPairSignerFromBytes } from '@solana/signers';\n\n// Get bytes from local keypair file.\nconst keypairFile = fs.readFileSync('~/.config/solana/id.json');\nconst keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n\n// Create a KeyPairSigner from the bytes.\nconst signer = await createKeyPairSignerFromBytes(keypairBytes);\n```\n\n#### `createKeyPairSignerFromPrivateKeyBytes()`\n\nA convenience function that creates a new KeyPair from a 32-bytes `Uint8Array` private key and immediately creates a `KeyPairSigner` from it.\n\n```ts\nimport { getUtf8Encoder } from '@solana/codecs-strings';\nimport { createKeyPairSignerFromPrivateKeyBytes } from '@solana/signers';\n\nconst message = getUtf8Encoder().encode('Hello, World!');\nconst seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n\nconst derivedSigner = await createKeyPairSignerFromPrivateKeyBytes(seed);\n```\n\n#### `grindKeyPairSigner()`\n\nMines a vanity `KeyPairSigner` whose address satisfies the provided `matches` criterion. The matcher may be a `RegExp` or a predicate function that receives the candidate address as a string. This is a thin wrapper around `grindKeyPair()` from `@solana/keys` that immediately wraps the resulting key pair in a `KeyPairSigner`.\n\n```ts\nimport { grindKeyPairSigner } from '@solana/signers';\n\nconst signer = await grindKeyPairSigner({ matches: /^anza/ });\n```\n\nThe config is identical to `grindKeyPair()`'s and also accepts an `extractable` flag, a `concurrency` setting for the batch size (defaulting to `32`), and an `abortSignal` to cancel long-running grinds.\n\n#### `grindKeyPairSigners()`\n\nMines multiple vanity `KeyPairSigners` whose addresses all satisfy the provided `matches` criterion. This is the batch variant of `grindKeyPairSigner()` and accepts the same configuration plus an `amount` field.\n\n```ts\nimport { grindKeyPairSigners } from '@solana/signers';\n\nconst signers = await grindKeyPairSigners({ matches: /^anza/, amount: 4 });\n```\n\n#### `writeKeyPairSigner()`\n\nPersists the `CryptoKeyPair` backing a `KeyPairSigner` to disk in the format produced by `solana-keygen`. This is a thin wrapper around `writeKeyPair()` from `@solana/keys` and requires that the signer's underlying key pair was created as extractable (e.g. via `generateKeyPairSigner(true)` or `createKeyPairSignerFromBytes(bytes, true)`).\n\n```ts\nimport { generateKeyPairSigner, writeKeyPairSigner } from '@solana/signers';\n\n// Generate an extractable signer so its bytes can be persisted.\nconst signer = await generateKeyPairSigner(true);\nawait writeKeyPairSigner(signer, './my-keypair.json');\n```\n\nLike `writeKeyPair()`, this helper requires a writable filesystem, creates missing parent directories, writes the file with mode `0600`, and refuses to overwrite an existing file unless the caller passes `{ unsafelyOverwriteExistingKeyPair: true }` — which permanently destroys the previous key and any funds controlled by it.\n\n#### `isKeyPairSigner()`\n\nA type guard that returns `true` if the provided value is a `KeyPairSigner`.\n\n```ts\nconst myKeyPairSigner = await generateKeyPairSigner();\nisKeyPairSigner(myKeyPairSigner); // ✅ true\nisKeyPairSigner({ address: address('1234..5678') }); // ❌ false\n```\n\n#### `assertIsKeyPairSigner()`\n\nA type guard that throws an error if the provided value is not a `KeyPairSigner`.\n\n```ts\nconst myKeyPairSigner = await generateKeyPairSigner();\nassertIsKeyPairSigner(myKeyPairSigner); // ✅ void\nassertIsKeyPairSigner({ address: address('1234..5678') }); // ❌ Throws an error.\n```\n\n## Creating Noop signers\n\nFor a given address, a Noop (No-Operation) signer can be created to offer an implementation of both the `MessagePartialSigner` and `TransactionPartialSigner` interfaces such that they do not sign anything. Namely, signing a transaction or a message with a `NoopSigner` will return an empty `SignatureDictionary`.\n\nThis signer may be useful:\n\n- For testing purposes.\n- For indicating that a given account is a signer and taking the responsibility to provide the signature for that account ourselves. For instance, if we need to send the transaction to a server that will sign it and send it for us.\n\n### Types\n\n#### `NoopSigner<TAddress>`\n\nDefines a Noop (No-Operation) signer.\n\n```ts\nconst myNoopSigner: NoopSigner;\nmyNoopSigner satisfies MessagePartialSigner;\nmyNoopSigner satisfies TransactionPartialSigner;\n```\n\n### Functions\n\n#### `createNoopSigner()`\n\nCreates a Noop (No-Operation) signer from a given address.\n\n```ts\nimport { createNoopSigner } from '@solana/signers';\n\nconst myNoopSigner = createNoopSigner(address('1234..5678'));\nconst [myMessageSignatures] = await myNoopSigner.signMessages([myMessage]); // <- Empty signature dictionary.\nconst [myTransactionSignatures] = await myNoopSigner.signTransactions([myTransaction]); // <- Empty signature dictionary.\n```\n\n## Storing transaction signers inside instruction account metas\n\nThis package defines an alternative definition for account metas that allows us to store `TransactionSigners` inside them. This means each instruction can keep track of its own set of signers and, by extension, so can transactions.\n\nIt also provides helper functions that deduplicate and extract signers from instructions and transactions which makes it possible to sign an entire transaction automatically as we will see in the next section.\n\n### Types\n\n#### `AccountSignerMeta`\n\nAlternative `AccountMeta` definition for signer accounts that allows us to store `TransactionSigners` inside it.\n\n```ts\nconst mySignerMeta: AccountSignerMeta = {\n    address: myTransactionSigner.address,\n    role: AccountRole.READONLY_SIGNER,\n    signer: myTransactionSigner,\n};\n```\n\n#### `InstructionWithSigners`\n\nComposable type that allows `AccountSignerMetas` to be used inside the instruction's `accounts` array.\n\n```ts\nconst myInstructionWithSigners: Instruction & InstructionWithSigners = {\n    programAddress: address('1234..5678'),\n    accounts: [\n        {\n            address: myTransactionSigner.address,\n            role: AccountRole.READONLY_SIGNER,\n            signer: myTransactionSigner,\n        },\n    ],\n};\n```\n\n#### `TransactionMessageWithSigners`\n\nComposable type that allows `AccountSignerMetas` to be used inside all of the transaction message's account metas.\n\n```ts\nconst myTransactionMessageWithSigners: TransactionMessage & TransactionMessageWithSigners = {\n    instructions: [\n        myInstructionA as Instruction & InstructionWithSigners,\n        myInstructionB as Instruction & InstructionWithSigners,\n        myInstructionC as Instruction,\n    ],\n    version: 0,\n};\n```\n\n### Functions\n\n#### `getSignersFromInstruction()`\n\nExtracts and deduplicates all signers stored inside the account metas of an instruction.\n\n```ts\nconst mySignerA = { address: address('1111..1111'), signTransactions: async () => {} };\nconst mySignerB = { address: address('2222..2222'), signTransactions: async () => {} };\nconst myInstructionWithSigners: InstructionWithSigners = {\n    programAddress: address('1234..5678'),\n    accounts: [\n        { address: mySignerA.address, role: AccountRole.READONLY_SIGNER, signer: mySignerA },\n        { address: mySignerB.address, role: AccountRole.WRITABLE_SIGNER, signer: mySignerB },\n        { address: mySignerA.address, role: AccountRole.WRITABLE_SIGNER, signer: mySignerA },\n    ],\n};\n\nconst instructionSigners = getSignersFromInstruction(myInstructionWithSigners);\n// ^ [mySignerA, mySignerB]\n```\n\n#### `getSignersFromTransactionMessage()`\n\nSimilarly to `getSignersFromInstruction`, this function extracts and deduplicates all signers stored inside the account metas of all the instructions inside a transaction message.\n\n```ts\nconst transactionSigners = getSignersFromTransactionMessage(myTransactionMessageWithSigners);\n```\n\n#### `addSignersToInstruction()`\n\nHelper function that adds the provided signers to any of the applicable account metas. For an account meta to match a provided signer it:\n\n- Must have a signer role (`AccountRole.READONLY_SIGNER` or `AccountRole.WRITABLE_SIGNER`).\n- Must have the same address as the provided signer.\n- Must not have an attached signer already.\n\n```ts\nconst myInstruction: Instruction = {\n    accounts: [\n        { address: '1111' as Address, role: AccountRole.READONLY_SIGNER },\n        { address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER },\n    ],\n    // ...\n};\n\nconst mySignerA: TransactionSigner<'1111'>;\nconst mySignerB: TransactionSigner<'2222'>;\nconst myInstructionWithSigners = addSignersToInstruction([mySignerA, mySignerB], myInstruction);\n\n// myInstructionWithSigners.accounts[0].signer === mySignerA\n// myInstructionWithSigners.accounts[1].signer === mySignerB\n```\n\n#### `addSignersToTransactionMessage()`\n\nSimilarly to `addSignersToInstruction`, this function adds signer to all the applicable account metas of all the instructions inside a transaction message. Note that it also updates the fee payer if necessary.\n\n```ts\nconst myTransactionMessageWithSigners = addSignersToTransactionMessage(mySigners, myTransactionMessage);\n```\n\n## Signing transactions with signers\n\nAs we've seen in the previous section, we can store and extract `TransactionSigners` from instructions and transaction messages. This allows us to provide helper methods that sign and send transactions.\n\nThere are two sets of signing functions:\n\n- **Transaction message helpers** extract signers from a `TransactionMessage` with embedded `TransactionSigners` in its account metas, compile it to a `Transaction`, and sign it.\n- **Transaction helpers** take a set of signers and an already-compiled `Transaction` directly, giving you full control over compilation and signer selection.\n\n### Signing transaction messages\n\nThese functions extract all `TransactionSigners` from the provided transaction message and use them to sign the compiled transaction.\n\n#### `partiallySignTransactionMessageWithSigners()`\n\nExtracts all signers inside the provided transaction message and uses them to sign it. It first uses all `TransactionModifyingSigners` sequentially before using all `TransactionPartialSigners` in parallel.\n\nIf a composite signer implements both interfaces, it will be used as a modifying signer if no other signer implements that interface. Otherwise, it will be used as a partial signer.\n\n```ts\nconst mySignedTransaction = await partiallySignTransactionMessageWithSigners(myTransactionMessage);\n```\n\nIt also accepts an optional `AbortSignal` that will be propagated to all signers.\n\n```ts\nconst mySignedTransaction = await partiallySignTransactionMessageWithSigners(myTransactionMessage, {\n    abortSignal: myAbortController.signal,\n});\n```\n\nFinally, note that this function ignores `TransactionSendingSigners` as it does not send the transaction. See the `signAndSendTransactionMessageWithSigners` function below for more details on how to use sending signers.\n\n#### `signTransactionMessageWithSigners()`\n\nThis function works the same as the `partiallySignTransactionMessageWithSigners` function described above except that it also ensures the transaction is fully signed before returning it. An error will be thrown if that's not the case.\n\n```ts\nconst mySignedTransaction = await signTransactionMessageWithSigners(myTransactionMessage);\n\n// With additional config.\nconst mySignedTransaction = await signTransactionMessageWithSigners(myTransactionMessage, {\n    abortSignal: myAbortController.signal,\n});\n\n// We now know the transaction is fully signed.\nmySignedTransaction satisfies FullySignedTransaction;\n```\n\n#### `signAndSendTransactionMessageWithSigners()`\n\nExtracts all signers inside the provided transaction and uses them to sign it before sending it immediately to the blockchain. It returns the signature of the sent transaction (i.e. its identifier).\n\n```ts\nconst transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n\n// With additional config.\nconst transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage, {\n    abortSignal: myAbortController.signal,\n});\n```\n\nSimilarly to the `partiallySignTransactionMessageWithSigners` function, it first uses all `TransactionModifyingSigners` sequentially before using all `TransactionPartialSigners` in parallel. It then sends the transaction using the `TransactionSendingSigner` it identified.\n\nHere as well, composite transaction signers are treated such that at least one sending signer is used if any. When a `TransactionSigner` implements more than one interface, use it as a:\n\n- `TransactionSendingSigner`, if no other `TransactionSendingSigner` exists.\n- `TransactionModifyingSigner`, if no other `TransactionModifyingSigner` exists.\n- `TransactionPartialSigner`, otherwise.\n\nThe provided transaction must contain exactly one `TransactionSendingSigner` inside its account metas. If more than one composite signers implement the `TransactionSendingSigner` interface, one of them will be selected as the sending signer. Otherwise, if multiple `TransactionSendingSigners` must be selected, the function will throw an error.\n\nIf you'd like to assert that a transaction makes use of exactly one `TransactionSendingSigner` _before_ calling this function, you may use the `assertIsTransactionMessageWithSingleSendingSigner` function.\n\n```ts\nassertIsTransactionMessageWithSingleSendingSigner(transactionMessage);\nconst transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n```\n\nAlternatively, you may use the `isTransactionWithSingleSendingSigner()` function to provide a fallback in case the transaction does not contain any sending signer.\n\n```ts\nlet transactionSignature: SignatureBytes;\nif (isTransactionWithSingleSendingSigner(transactionMessage)) {\n    transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n} else {\n    const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n    const encodedTransaction = getBase64EncodedWireTransaction(signedTransaction);\n    transactionSignature = await rpc.sendTransaction(encodedTransaction).send();\n}\n```\n\n### Signing compiled transactions\n\nThese functions accept a set of signers and an already-compiled `Transaction` directly. Use them when you have already compiled a transaction (e.g. via `compileTransaction`) and want to sign it with a specific set of signers.\n\n#### `partiallySignTransactionWithSigners()`\n\nSigns a compiled transaction using the provided `TransactionModifyingSigners` and `TransactionPartialSigners`. It first uses all modifying signers sequentially before using all partial signers in parallel.\n\nIf a composite signer implements both interfaces, it will be used as a modifying signer if no other signer implements that interface. Otherwise, it will be used as a partial signer.\n\n```ts\nimport { partiallySignTransactionWithSigners } from '@solana/signers';\n\nconst signedTransaction = await partiallySignTransactionWithSigners(mySigners, compiledTransaction);\n\n// With additional config.\nconst signedTransaction = await partiallySignTransactionWithSigners(mySigners, compiledTransaction, {\n    abortSignal: myAbortController.signal,\n});\n```\n\nNote that only `TransactionModifyingSigner` and `TransactionPartialSigner` interfaces are accepted. If you need to use a `TransactionSendingSigner`, see `signAndSendTransactionWithSigners` below.\n\n#### `signTransactionWithSigners()`\n\nThis function works the same as `partiallySignTransactionWithSigners` except that it also ensures the transaction is fully signed before returning it. An error will be thrown if that's not the case.\n\n```ts\nimport { signTransactionWithSigners } from '@solana/signers';\n\nconst signedTransaction = await signTransactionWithSigners(mySigners, compiledTransaction);\n\n// We now know the transaction is fully signed.\nsignedTransaction satisfies FullySignedTransaction;\n```\n\n#### `signAndSendTransactionWithSigners()`\n\nSigns a compiled transaction using the provided signers and sends it immediately to the blockchain. It returns the signature of the sent transaction (i.e. its identifier) as bytes.\n\n```ts\nimport { signAndSendTransactionWithSigners } from '@solana/signers';\n\nconst transactionSignature = await signAndSendTransactionWithSigners(mySigners, compiledTransaction);\n```\n\nSimilarly to `partiallySignTransactionWithSigners`, it first uses all modifying signers sequentially before using all partial signers in parallel. It then sends the transaction using the resolved `TransactionSendingSigner`.\n\nThe provided signers must contain at least one `TransactionSendingSigner` that can be unambiguously resolved. This is checked internally and will throw an error if the condition is not met.\n"
  },
  {
    "path": "packages/signers/package.json",
    "content": "{\n    \"name\": \"@solana/signers\",\n    \"version\": \"6.9.0\",\n    \"description\": \"An abstraction layer over signing messages and transactions in Solana\",\n    \"homepage\": \"https://www.solanakit.com/api#solanasigners\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/instructions\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/nominal-types\": \"workspace:*\",\n        \"@solana/offchain-messages\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/text-encoding-impl\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/signers/src/__tests__/__setup__.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountRole, Instruction } from '@solana/instructions';\nimport {\n    OffchainMessage,\n    OffchainMessageApplicationDomain,\n    OffchainMessageContentFormat,\n    OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n    OffchainMessageSignatory,\n    OffchainMessageWithRequiredSignatories,\n} from '@solana/offchain-messages';\nimport type { Blockhash } from '@solana/rpc-types';\nimport {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithLifetime,\n} from '@solana/transaction-messages';\nimport {\n    appendTransactionMessageInstruction,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n} from '@solana/transaction-messages';\n\nimport { AccountSignerMeta, InstructionWithSigners, TransactionMessageWithSigners } from '../account-signer-meta';\nimport { MessageModifyingSigner } from '../message-modifying-signer';\nimport { MessagePartialSigner } from '../message-partial-signer';\nimport { OffchainMessageSignatorySigner } from '../offchain-message-signer';\nimport { TransactionModifyingSigner } from '../transaction-modifying-signer';\nimport { TransactionPartialSigner } from '../transaction-partial-signer';\nimport { TransactionSendingSigner } from '../transaction-sending-signer';\nimport { TransactionSigner } from '../transaction-signer';\n\nconst APPLICATION_DOMAIN_BYTES = new Uint8Array([\n    0x0d, 0x3b, 0x73, 0x0b, 0x9e, 0x88, 0x9b, 0x4b, 0x66, 0x1e, 0xd2, 0xa3, 0xce, 0x19, 0x1f, 0x68, 0xd3, 0x7d, 0xa7,\n    0x44, 0x32, 0x06, 0xa1, 0x82, 0xb9, 0x46, 0x89, 0x1e, 0x00, 0x00, 0x00, 0x00,\n]);\n\nexport function createMockInstructionWithSigners(signers: TransactionSigner[]): Instruction & InstructionWithSigners {\n    return {\n        accounts: signers.map(\n            (signer): AccountSignerMeta => ({ address: signer.address, role: AccountRole.READONLY_SIGNER, signer }),\n        ),\n        data: new Uint8Array([]),\n        programAddress: '11111111111111111111111111111111' as Address,\n    };\n}\n\nexport function createMockOffchainMessageWithSigners(\n    signers: OffchainMessageSignatorySigner[],\n): OffchainMessageWithRequiredSignatories<OffchainMessageSignatory | OffchainMessageSignatorySigner> &\n    Omit<OffchainMessage, 'requiredSignatories'> {\n    return Object.freeze({\n        applicationDomain: APPLICATION_DOMAIN_BYTES as unknown as OffchainMessageApplicationDomain,\n        content: {\n            format: OffchainMessageContentFormat.RESTRICTED_ASCII_1232_BYTES_MAX,\n            text: 'Hello world',\n        } as OffchainMessageContentRestrictedAsciiOf1232BytesMax,\n        requiredSignatories: [...signers],\n        version: 0,\n    });\n}\n\nexport function createMockTransactionMessageWithSigners(\n    signers: TransactionSigner[],\n): TransactionMessage &\n    TransactionMessageWithFeePayer &\n    TransactionMessageWithLifetime &\n    TransactionMessageWithSigners {\n    const transaction = createTransactionMessage({ version: 0 });\n    const transactionWithFeePayer = setTransactionMessageFeePayer(signers[0]?.address ?? '1111', transaction);\n    const compilableTransaction = setTransactionMessageLifetimeUsingBlockhash(\n        { blockhash: 'dummy_blockhash' as Blockhash, lastValidBlockHeight: 42n },\n        transactionWithFeePayer,\n    );\n    return appendTransactionMessageInstruction(createMockInstructionWithSigners(signers), compilableTransaction);\n}\n\nexport function createMockMessagePartialSigner(address: Address): MessagePartialSigner & { signMessages: jest.Mock } {\n    return { address, signMessages: jest.fn() };\n}\n\nexport function createMockMessageModifyingSigner(\n    address: Address,\n): MessageModifyingSigner & { modifyAndSignMessages: jest.Mock } {\n    return { address, modifyAndSignMessages: jest.fn() };\n}\n\nexport function createMockTransactionPartialSigner(\n    address: Address,\n): TransactionPartialSigner & { signTransactions: jest.Mock } {\n    return { address, signTransactions: jest.fn() };\n}\n\nexport function createMockTransactionModifyingSigner(\n    address: Address,\n): TransactionModifyingSigner & { modifyAndSignTransactions: jest.Mock } {\n    return { address, modifyAndSignTransactions: jest.fn() };\n}\n\nexport function createMockTransactionSendingSigner(\n    address: Address,\n): TransactionSendingSigner & { signAndSendTransactions: jest.Mock } {\n    return { address, signAndSendTransactions: jest.fn() };\n}\n\nexport function createMockTransactionCompositeSigner(address: Address) {\n    return {\n        ...createMockTransactionPartialSigner(address),\n        ...createMockTransactionModifyingSigner(address),\n        ...createMockTransactionSendingSigner(address),\n    };\n}\n"
  },
  {
    "path": "packages/signers/src/__tests__/account-signer-meta-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { createTransactionMessage } from '@solana/transaction-messages';\n\nimport { getSignersFromInstruction, getSignersFromTransactionMessage } from '../account-signer-meta';\nimport { setTransactionMessageFeePayerSigner } from '../fee-payer-signer';\nimport {\n    createMockInstructionWithSigners,\n    createMockTransactionMessageWithSigners,\n    createMockTransactionModifyingSigner,\n    createMockTransactionPartialSigner,\n} from './__setup__';\n\ndescribe('getSignersFromInstruction', () => {\n    it('extracts signers from the account meta of the provided instruction', () => {\n        // Given an instruction with two signers A and B.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n        const instruction = createMockInstructionWithSigners([signerA, signerB]);\n\n        // When we extract the signers from the instruction's account metas.\n        const extractedSigners = getSignersFromInstruction(instruction);\n\n        // Then we expect signer A and B to be part of the extracted signers.\n        expect(extractedSigners).toHaveLength(2);\n        expect(extractedSigners[0]).toBe(signerA);\n        expect(extractedSigners[1]).toBe(signerB);\n    });\n\n    it('removes duplicated signers by reference', () => {\n        // Given an instruction with duplicated signers using the same reference.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n        const instruction = createMockInstructionWithSigners([signerA, signerB, signerA, signerA]);\n\n        // When we extract the signers from the instruction's account metas.\n        const extractedSigners = getSignersFromInstruction(instruction);\n\n        // Then we expect the extracted signers to be deduplicated.\n        expect(extractedSigners).toHaveLength(2);\n        expect(extractedSigners.map(signer => signer.address).sort()).toStrictEqual(['1111', '2222']);\n    });\n});\n\ndescribe('getSignersFromTransactionMessage', () => {\n    it('extracts signers from the account meta of the provided transaction', () => {\n        // Given a transaction with two signers A and B.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB]);\n\n        // When we extract the signers from the transaction's account metas.\n        const extractedSigners = getSignersFromTransactionMessage(transaction);\n\n        // Then we expect signer A and B to be part of the extracted signers.\n        expect(extractedSigners).toHaveLength(2);\n        expect(extractedSigners[0]).toBe(signerA);\n        expect(extractedSigners[1]).toBe(signerB);\n    });\n\n    it('extracts the fee payer signer of the provided transaction', () => {\n        // Given a transaction with a signer fee payer.\n        const feePayer = createMockTransactionPartialSigner('1111' as Address);\n        const transaction = setTransactionMessageFeePayerSigner(feePayer, createTransactionMessage({ version: 0 }));\n\n        // When we extract the signers from the transaction.\n        const extractedSigners = getSignersFromTransactionMessage(transaction);\n\n        // Then we expect the extracted signers to contain the fee payer signer.\n        expect(extractedSigners).toHaveLength(1);\n        expect(extractedSigners[0]).toBe(feePayer);\n    });\n\n    it('removes duplicated signers', () => {\n        // Given a transaction with duplicated signers using the same reference.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB, signerA, signerA]);\n\n        // When we extract the signers from the transaction's account metas.\n        const extractedSigners = getSignersFromTransactionMessage(transaction);\n\n        // Then we expect the extracted signers to be deduplicated.\n        expect(extractedSigners).toHaveLength(2);\n        expect(extractedSigners.map(signer => signer.address).sort()).toStrictEqual(['1111', '2222']);\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/add-signers-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS, SolanaError } from '@solana/errors';\nimport { AccountRole, Instruction } from '@solana/instructions';\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport { AccountSignerMeta, InstructionWithSigners } from '../account-signer-meta';\nimport { addSignersToInstruction, addSignersToTransactionMessage } from '../add-signers';\nimport { TransactionMessageWithFeePayerSigner } from '../fee-payer-signer';\nimport { createMockTransactionModifyingSigner, createMockTransactionPartialSigner } from './__setup__';\n\ndescribe('addSignersToInstruction', () => {\n    it('adds signers to the account metas of the instruction', () => {\n        // Given an instruction with signer account metas.\n        const instruction: Instruction = {\n            accounts: [\n                { address: '1111' as Address, role: AccountRole.READONLY_SIGNER },\n                { address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER },\n            ],\n            data: new Uint8Array([]),\n            programAddress: '9999' as Address,\n        };\n\n        // And two associated signers.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n\n        // When we add the signers to the instruction.\n        const instructionWithSigners = addSignersToInstruction([signerA, signerB], instruction);\n\n        // Then the instruction's account metas now store the provided signers.\n        expect(instructionWithSigners.accounts).toStrictEqual([\n            { address: '1111' as Address, role: AccountRole.READONLY_SIGNER, signer: signerA },\n            { address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER, signer: signerB },\n        ]);\n    });\n\n    it('ignores account metas that already have a signer', () => {\n        // Given an instruction with a signer account metas that already has a signer A attached to it.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const instruction: Instruction & InstructionWithSigners = {\n            accounts: [\n                {\n                    address: '1111' as Address,\n                    role: AccountRole.READONLY_SIGNER,\n                    signer: signerA,\n                } as AccountSignerMeta,\n            ],\n            data: new Uint8Array([]),\n            programAddress: '9999' as Address,\n        };\n\n        // When we try to add a signer B to the instruction matching the signer A's address.\n        const signerB = createMockTransactionPartialSigner('1111' as Address);\n        const instructionWithSigners = addSignersToInstruction([signerB], instruction);\n\n        // Then the instruction's account meta still stores the signer A.\n        expect(instructionWithSigners.accounts).toStrictEqual([\n            { address: '1111' as Address, role: AccountRole.READONLY_SIGNER, signer: signerA },\n        ]);\n    });\n\n    it('ignores account metas that do not have a signer role', () => {\n        // Given an instruction with a non-signer account metas.\n        const instruction: Instruction = {\n            accounts: [{ address: '1111' as Address, role: AccountRole.WRITABLE }],\n            data: new Uint8Array([]),\n            programAddress: '9999' as Address,\n        };\n\n        // When we try to add a signer to the instruction matching the non-signer account metas's address.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        const instructionWithSigners = addSignersToInstruction([signer], instruction);\n\n        // Then the instruction's account meta still doesn't store the signer.\n        expect(instructionWithSigners.accounts).toStrictEqual([\n            { address: '1111' as Address, role: AccountRole.WRITABLE },\n        ]);\n    });\n\n    it('can add the same signer to multiple account metas', () => {\n        // Given an instruction with two signer account metas that share the same address.\n        const instruction: Instruction = {\n            accounts: [\n                { address: '1111' as Address, role: AccountRole.READONLY_SIGNER },\n                { address: '1111' as Address, role: AccountRole.WRITABLE_SIGNER },\n            ],\n            data: new Uint8Array([]),\n            programAddress: '9999' as Address,\n        };\n\n        // When we add a signer matching this address to the instruction.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        const instructionWithSigners = addSignersToInstruction([signer], instruction);\n\n        // Then the instruction's account metas now store the provided signer on both account metas.\n        expect(instructionWithSigners.accounts).toStrictEqual([\n            { address: '1111' as Address, role: AccountRole.READONLY_SIGNER, signer },\n            { address: '1111' as Address, role: AccountRole.WRITABLE_SIGNER, signer },\n        ]);\n    });\n\n    it('fails if two distincts signers are provided for the same address', () => {\n        // Given an instruction with a signer account meta.\n        const instruction: Instruction = {\n            accounts: [{ address: '1111' as Address, role: AccountRole.READONLY_SIGNER }],\n            data: new Uint8Array([]),\n            programAddress: '9999' as Address,\n        };\n\n        // And two distinct signers for the same address.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('1111' as Address);\n\n        // When we try to add the signers to the instruction.\n        const fn = () => addSignersToInstruction([signerA, signerB], instruction);\n\n        // Then we expect an error to be thrown.\n        expect(fn).toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS, {\n                address: '1111',\n            }),\n        );\n    });\n\n    it('freezes the returned instruction', () => {\n        // Given an instruction with a signer account metas.\n        const instruction: Instruction = {\n            accounts: [{ address: '1111' as Address, role: AccountRole.READONLY_SIGNER }],\n            data: new Uint8Array([]),\n            programAddress: '9999' as Address,\n        };\n\n        // When we add a signer to the instruction.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        const instructionWithSigners = addSignersToInstruction([signer], instruction);\n\n        // Then the returned instruction is frozen and so are its updated account metas.\n        expect(instructionWithSigners).toBeFrozenObject();\n        expect(instructionWithSigners.accounts![0]).toBeFrozenObject();\n    });\n\n    it('returns the instruction as-is if it has no account metas', () => {\n        // Given an instruction with no account metas.\n        const instruction: Instruction = {\n            accounts: [],\n            data: new Uint8Array([]),\n            programAddress: '9999' as Address,\n        };\n\n        // When we try to add signers to the instruction.\n        const instructionWithSigners = addSignersToInstruction([], instruction);\n\n        // Then the returned instruction is the same as the original.\n        expect(instructionWithSigners).toBe(instruction);\n    });\n});\n\ndescribe('addSignersToTransactionMessage', () => {\n    it('adds signers to the account metas of the transaction', () => {\n        // Given a transaction with two instructions with signer account metas.\n        const instructionA: Instruction = {\n            accounts: [{ address: '1111' as Address, role: AccountRole.READONLY_SIGNER }],\n            data: new Uint8Array([]),\n            programAddress: '8888' as Address,\n        };\n        const instructionB: Instruction = {\n            accounts: [{ address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER }],\n            data: new Uint8Array([]),\n            programAddress: '9999' as Address,\n        };\n        const transaction: TransactionMessage = {\n            instructions: [instructionA, instructionB],\n            version: 0,\n        };\n\n        // And two associated signers.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n\n        // When we add the signers to the transaction.\n        const transactionWithSigners = addSignersToTransactionMessage([signerA, signerB], transaction);\n\n        // Then the transaction's account metas now store the provided signers.\n        expect(transactionWithSigners.instructions[0].accounts).toStrictEqual([\n            { address: '1111' as Address, role: AccountRole.READONLY_SIGNER, signer: signerA },\n        ]);\n        expect(transactionWithSigners.instructions[1].accounts).toStrictEqual([\n            { address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER, signer: signerB },\n        ]);\n    });\n\n    it('updates the fee payer if a matching signer is provided', () => {\n        // Given a transaction with a fee payer address.\n        const transaction: TransactionMessage & TransactionMessageWithFeePayer = {\n            feePayer: { address: '1111' as Address },\n            instructions: [],\n            version: 0,\n        };\n\n        // And a signer matching the fee payer address.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n\n        // When we add the signers to the transaction.\n        const transactionWithSigners = addSignersToTransactionMessage([signer], transaction);\n\n        // Then the transaction's fee payer now stores the provided signer.\n        expect(transactionWithSigners.feePayer).toBe(signer);\n    });\n\n    it('does not update the fee payer if it is already a signer', () => {\n        // Given two signers A and B with the same address.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('1111' as Address);\n\n        // And a transaction using fee payer signer A.\n        const transaction: TransactionMessage & TransactionMessageWithFeePayerSigner = {\n            feePayer: signerA,\n            instructions: [],\n            version: 0,\n        };\n\n        // When we try to add signer B to the transaction.\n        const transactionWithSigners = addSignersToTransactionMessage([signerB], transaction);\n\n        // Then the transaction did not update its fee payer and remains unchanged.\n        expect(transactionWithSigners).toBe(transaction);\n    });\n\n    it('freezes the returned transaction', () => {\n        // Given a one-instruction transaction with signer account metas.\n        const transaction: TransactionMessage = {\n            instructions: [\n                {\n                    accounts: [{ address: '1111' as Address, role: AccountRole.READONLY_SIGNER }],\n                    data: new Uint8Array([]),\n                    programAddress: '8888' as Address,\n                },\n            ],\n            version: 0,\n        };\n\n        // When we add signers to the transaction.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        const transactionWithSigners = addSignersToTransactionMessage([signer], transaction);\n\n        // Then the returned transaction is frozen and so are its updated instructions and account metas.\n        expect(transactionWithSigners).toBeFrozenObject();\n        expect(transactionWithSigners.instructions[0]).toBeFrozenObject();\n        expect(transactionWithSigners.instructions[0].accounts![0]).toBeFrozenObject();\n    });\n\n    it('returns the transaction as-is if it has no instructions or fee payer to update', () => {\n        // Given transaction with no instructions or fee payer.\n        const transaction: TransactionMessage = { instructions: [], version: 0 };\n\n        // When we try to add signers to the transaction.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        const transactionWithSigners = addSignersToTransactionMessage([signer], transaction);\n\n        // Then the returned transaction is the same as the original.\n        expect(transactionWithSigners).toBe(transaction);\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/deduplicate-signers-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS, SolanaError } from '@solana/errors';\n\nimport { deduplicateSigners } from '../deduplicate-signers';\nimport { createNoopSigner } from '../noop-signer';\nimport {\n    createMockMessagePartialSigner,\n    createMockTransactionModifyingSigner,\n    createMockTransactionPartialSigner,\n    createMockTransactionSendingSigner,\n} from './__setup__';\n\ndescribe('deduplicateSigners', () => {\n    it('removes duplicated signers by address', () => {\n        // Given two signers A and B.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockMessagePartialSigner('2222' as Address);\n\n        // And an array of them with some duplicates.\n        const signers = [signerA, signerB, signerA, signerA, signerB, signerB];\n\n        // When we deduplicate them.\n        const deduplicatedSigners = deduplicateSigners(signers);\n\n        // Then we expect only two signers to remain: one for Signer A and one for Signer B.\n        expect(deduplicatedSigners).toHaveLength(2);\n        expect(deduplicatedSigners.map(signer => signer.address).sort()).toStrictEqual(['1111', '2222']);\n    });\n\n    it('fails to duplicated disctint signers for the same address', () => {\n        // Given a list of signers with some distinct duplicates for the same address.\n        const addressA = '1111' as Address;\n        const addressB = '2222' as Address;\n        const signers = [\n            createMockTransactionPartialSigner(addressA),\n            createMockMessagePartialSigner(addressB),\n            createMockTransactionModifyingSigner(addressA),\n            createMockTransactionSendingSigner(addressA),\n        ];\n\n        // When we try deduplicate them.\n        const fn = () => deduplicateSigners(signers);\n\n        // Then we expect an error to be thrown.\n        expect(fn).toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS, {\n                address: addressA,\n            }),\n        );\n    });\n\n    it('deduplicates equivalent noop signers with the same address', () => {\n        // Given two separately created noop signers for the same address.\n        const addressA = '1111' as Address;\n        const noopSignerA = createNoopSigner(addressA);\n        const noopSignerB = createNoopSigner(addressA);\n\n        // When we deduplicate them.\n        const deduplicatedSigners = deduplicateSigners([noopSignerA, noopSignerB]);\n\n        // Then we expect only one signer to remain and it should be the first one.\n        expect(deduplicatedSigners).toHaveLength(1);\n        expect(deduplicatedSigners[0]).toBe(noopSignerA);\n    });\n\n    it('fails when a noop signer and a real signer share the same address', () => {\n        // Given a noop signer and a real signer for the same address.\n        const addressA = '1111' as Address;\n        const signers = [createNoopSigner(addressA), createMockTransactionPartialSigner(addressA)];\n\n        // When we try deduplicate them.\n        const fn = () => deduplicateSigners(signers);\n\n        // Then we expect an error to be thrown.\n        expect(fn).toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS, {\n                address: addressA,\n            }),\n        );\n    });\n\n    it('filters signers without cloning them', () => {\n        // Given a list of signers with no duplicates.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockMessagePartialSigner('2222' as Address);\n        const signers = [signerA, signerB];\n\n        // When we deduplicate them.\n        const deduplicatedSigners = deduplicateSigners(signers);\n\n        // Then we expect the exact same signer objects to remain.\n        expect(deduplicatedSigners).toHaveLength(2);\n        expect(deduplicatedSigners[0]).toBe(signerA);\n        expect(deduplicatedSigners[1]).toBe(signerB);\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/fee-payer-signer-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport { setTransactionMessageFeePayerSigner, TransactionMessageWithFeePayerSigner } from '../fee-payer-signer';\nimport { TransactionSigner } from '../transaction-signer';\nimport { createMockTransactionPartialSigner } from './__setup__';\n\ndescribe('setTransactionMessageFeePayerSigner', () => {\n    let feePayerA: TransactionSigner;\n    let feePayerB: TransactionSigner;\n    let baseTx: TransactionMessage;\n    beforeEach(() => {\n        baseTx = { instructions: [], version: 0 };\n        feePayerA = createMockTransactionPartialSigner('1111' as Address);\n        feePayerB = createMockTransactionPartialSigner('2222' as Address);\n    });\n    it('sets the fee payer signer on the transaction', () => {\n        const txWithFeePayerA = setTransactionMessageFeePayerSigner(feePayerA, baseTx);\n        expect(txWithFeePayerA).toHaveProperty('feePayer', feePayerA);\n    });\n    describe('given a transaction with a fee payer signer already set', () => {\n        let txWithFeePayerA: TransactionMessage & TransactionMessageWithFeePayerSigner;\n        beforeEach(() => {\n            txWithFeePayerA = { ...baseTx, feePayer: feePayerA };\n        });\n        it('overrides the fee payer signer when it differs from the existing one', () => {\n            const txWithFeePayerB = setTransactionMessageFeePayerSigner(feePayerB, txWithFeePayerA);\n            expect(txWithFeePayerB).toHaveProperty('feePayer', feePayerB);\n        });\n        it('overrides the fee payer signer even when the existing fee payer address is the same', () => {\n            const txWithSameFeePayer = setTransactionMessageFeePayerSigner(feePayerA, txWithFeePayerA);\n            expect(txWithSameFeePayer).toHaveProperty('feePayer', feePayerA);\n            expect(txWithSameFeePayer).not.toBe(txWithFeePayerA);\n        });\n    });\n    describe('given a transaction with a non-signer fee payer already set', () => {\n        let txWithFeePayerA: TransactionMessage & TransactionMessageWithFeePayer;\n        beforeEach(() => {\n            txWithFeePayerA = { ...baseTx, feePayer: { address: feePayerA.address } };\n        });\n        it('overrides the fee payer when it differs from the existing one', () => {\n            const txWithFeePayerB = setTransactionMessageFeePayerSigner(feePayerB, txWithFeePayerA);\n            expect(txWithFeePayerB).toHaveProperty('feePayer', feePayerB);\n        });\n        it('overrides the fee payer even when the existing fee payer address is the same', () => {\n            const txWithSameFeePayer = setTransactionMessageFeePayerSigner(feePayerA, txWithFeePayerA);\n            expect(txWithSameFeePayer).toHaveProperty('feePayer', feePayerA);\n            expect(txWithFeePayerA).not.toBe(txWithSameFeePayer);\n        });\n    });\n    it('freezes the object', () => {\n        const txWithFeePayer = setTransactionMessageFeePayerSigner(feePayerA, baseTx);\n        expect(txWithFeePayer).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/grind-keypair-signer-test.ts",
    "content": "import { address, getAddressFromPublicKey } from '@solana/addresses';\nimport { grindKeyPairs } from '@solana/keys';\n\nimport { grindKeyPairSigner, grindKeyPairSigners } from '../grind-keypair-signer';\nimport { KeyPairSigner } from '../keypair-signer';\n\n// Partial mocks.\njest.mock('@solana/addresses', () => ({\n    ...jest.requireActual('@solana/addresses'),\n    getAddressFromPublicKey: jest.fn(),\n}));\njest.mock('@solana/keys', () => ({\n    ...jest.requireActual('@solana/keys'),\n    grindKeyPairs: jest.fn(),\n}));\n\nconst getMockCryptoKeyPair = () => ({ privateKey: {}, publicKey: {} }) as CryptoKeyPair;\n\ndescribe('grindKeyPairSigner', () => {\n    it('returns a single `KeyPairSigner` whose `keyPair` comes from `grindKeyPairs`', async () => {\n        expect.assertions(3);\n\n        const mockKeyPair = getMockCryptoKeyPair();\n        const mockAddress = address('soidJbjQLKFQvcXLTT3AbddEPupBw5LsQv5w6mZqgxT');\n        jest.mocked(grindKeyPairs).mockResolvedValueOnce([mockKeyPair]);\n        jest.mocked(getAddressFromPublicKey).mockResolvedValueOnce(mockAddress);\n\n        const signer = await grindKeyPairSigner({ matches: /^so/ });\n        signer satisfies KeyPairSigner;\n\n        expect(signer.keyPair).toBe(mockKeyPair);\n        expect(signer.address).toBe(mockAddress);\n        expect(jest.mocked(grindKeyPairs)).toHaveBeenCalledTimes(1);\n    });\n\n    it('forwards config fields to `grindKeyPairs` with `amount: 1`', async () => {\n        expect.assertions(1);\n\n        const mockKeyPair = getMockCryptoKeyPair();\n        jest.mocked(grindKeyPairs).mockResolvedValueOnce([mockKeyPair]);\n        jest.mocked(getAddressFromPublicKey).mockResolvedValueOnce(\n            address('soidJbjQLKFQvcXLTT3AbddEPupBw5LsQv5w6mZqgxT'),\n        );\n\n        const abortController = new AbortController();\n        const matches = /^so/;\n        await grindKeyPairSigner({\n            abortSignal: abortController.signal,\n            concurrency: 8,\n            extractable: true,\n            matches,\n        });\n\n        expect(jest.mocked(grindKeyPairs)).toHaveBeenCalledWith({\n            abortSignal: abortController.signal,\n            amount: 1,\n            concurrency: 8,\n            extractable: true,\n            matches,\n        });\n    });\n\n    it('propagates errors from `grindKeyPairs`', async () => {\n        expect.assertions(1);\n        const error = new Error('Cancelled');\n        jest.mocked(grindKeyPairs).mockRejectedValueOnce(error);\n        await expect(grindKeyPairSigner({ matches: () => true })).rejects.toThrow('Cancelled');\n    });\n});\n\ndescribe('grindKeyPairSigners', () => {\n    it('returns one `KeyPairSigner` per key pair returned by `grindKeyPairs`', async () => {\n        expect.assertions(4);\n\n        const mockKeyPairs = [getMockCryptoKeyPair(), getMockCryptoKeyPair(), getMockCryptoKeyPair()];\n        const mockAddresses = [\n            address('soidJbjQLKFQvcXLTT3AbddEPupBw5LsQv5w6mZqgxT'),\n            address('soTEku193tpVTyiqVFyyS4iUnrCH3WByTaarHmRvtVV'),\n            address('so5Rqdrtb31G2cDDgdDyBmEWk2C4K2ryfwASZPQAcYw'),\n        ];\n        jest.mocked(grindKeyPairs).mockResolvedValueOnce(mockKeyPairs);\n        jest.mocked(getAddressFromPublicKey)\n            .mockResolvedValueOnce(mockAddresses[0])\n            .mockResolvedValueOnce(mockAddresses[1])\n            .mockResolvedValueOnce(mockAddresses[2]);\n\n        const signers = await grindKeyPairSigners({ amount: 3, matches: /^so/ });\n\n        expect(signers).toHaveLength(3);\n        for (let i = 0; i < 3; i++) {\n            expect(signers[i]).toMatchObject({\n                address: mockAddresses[i],\n                keyPair: mockKeyPairs[i],\n            });\n        }\n    });\n\n    it('forwards config directly to `grindKeyPairs`', async () => {\n        expect.assertions(1);\n\n        jest.mocked(grindKeyPairs).mockResolvedValueOnce([]);\n\n        const abortController = new AbortController();\n        const matches = (addr: string) => addr.startsWith('so');\n        await grindKeyPairSigners({\n            abortSignal: abortController.signal,\n            amount: 5,\n            concurrency: 16,\n            extractable: true,\n            matches,\n        });\n\n        expect(jest.mocked(grindKeyPairs)).toHaveBeenCalledWith({\n            abortSignal: abortController.signal,\n            amount: 5,\n            concurrency: 16,\n            extractable: true,\n            matches,\n        });\n    });\n\n    it('returns an empty array when `grindKeyPairs` returns an empty array', async () => {\n        expect.assertions(1);\n        jest.mocked(grindKeyPairs).mockResolvedValueOnce([]);\n        const signers = await grindKeyPairSigners({ amount: 0, matches: () => true });\n        expect(signers).toEqual([]);\n    });\n\n    it('propagates errors from `grindKeyPairs`', async () => {\n        expect.assertions(1);\n        const error = new Error('Cancelled');\n        jest.mocked(grindKeyPairs).mockRejectedValueOnce(error);\n        await expect(grindKeyPairSigners({ amount: 3, matches: () => true })).rejects.toThrow('Cancelled');\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/keypair-signer-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { address, getAddressFromPublicKey } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER, SolanaError } from '@solana/errors';\nimport { generateKeyPair, SignatureBytes, signBytes } from '@solana/keys';\nimport {\n    partiallySignTransaction,\n    Transaction,\n    TransactionWithinSizeLimit,\n    TransactionWithLifetime,\n} from '@solana/transactions';\n\nimport {\n    assertIsKeyPairSigner,\n    createSignerFromKeyPair,\n    generateKeyPairSigner,\n    isKeyPairSigner,\n    KeyPairSigner,\n} from '../keypair-signer';\nimport { createSignableMessage } from '../signable-message';\n\nconst getMockCryptoKeyPair = () => ({ privateKey: {}, publicKey: {} }) as CryptoKeyPair;\n\n// Partial mocks.\njest.mock('@solana/addresses', () => ({\n    ...jest.requireActual('@solana/addresses'),\n    getAddressFromPublicKey: jest.fn(),\n}));\njest.mock('@solana/keys', () => ({\n    ...jest.requireActual('@solana/keys'),\n    generateKeyPair: jest.fn(),\n    signBytes: jest.fn(),\n}));\njest.mock('@solana/transactions', () => ({\n    ...jest.requireActual('@solana/transactions'),\n    partiallySignTransaction: jest.fn(),\n}));\n\ndescribe('isKeyPairSigner', () => {\n    it('checks whether a given value is a KeyPairSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            keyPair: getMockCryptoKeyPair(),\n            signMessages: () => Promise.resolve([]),\n            signTransactions: () => Promise.resolve([]),\n        } satisfies KeyPairSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        expect(isKeyPairSigner(mySigner)).toBe(true);\n        expect(isKeyPairSigner({ address: myAddress })).toBe(false);\n        expect(isKeyPairSigner({ ...mySigner, signMessages: 42 })).toBe(false);\n        expect(isKeyPairSigner({ ...mySigner, signTransactions: 42 })).toBe(false);\n        expect(isKeyPairSigner({ ...mySigner, keyPair: 42 })).toBe(false);\n    });\n});\n\ndescribe('assertIsKeyPairSigner', () => {\n    it('asserts that a given value is a KeyPairSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            keyPair: getMockCryptoKeyPair(),\n            signMessages: () => Promise.resolve([]),\n            signTransactions: () => Promise.resolve([]),\n        } satisfies KeyPairSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER, {\n            address: myAddress,\n        });\n        expect(() => assertIsKeyPairSigner(mySigner)).not.toThrow();\n        expect(() => assertIsKeyPairSigner({ address: myAddress })).toThrow(expectedError);\n        expect(() => assertIsKeyPairSigner({ ...mySigner, signMessages: 42 })).toThrow(expectedError);\n        expect(() => assertIsKeyPairSigner({ ...mySigner, signTransactions: 42 })).toThrow(expectedError);\n        expect(() => assertIsKeyPairSigner({ ...mySigner, keyPair: 42 })).toThrow(expectedError);\n    });\n});\n\ndescribe('createSignerFromKeyPair', () => {\n    it('creates a KeyPairSigner from a given CryptoKeypair', async () => {\n        expect.assertions(5);\n\n        // Given a mock CryptoKeyPair returning a mock address.\n        const myKeyPair = getMockCryptoKeyPair();\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        jest.mocked(getAddressFromPublicKey).mockResolvedValueOnce(myAddress);\n\n        // When we create a Signer from that CryptoKeyPair.\n        const mySigner = await createSignerFromKeyPair(myKeyPair);\n        mySigner satisfies KeyPairSigner;\n\n        // Then the created signer kept track of the address and key pair.\n        expect(jest.mocked(getAddressFromPublicKey)).toHaveBeenCalledTimes(1);\n        expect(mySigner.address).toBe(myAddress);\n        expect(mySigner.keyPair).toBe(myKeyPair);\n\n        // And provided functions to sign messages and transactions.\n        expect(typeof mySigner.signMessages).toBe('function');\n        expect(typeof mySigner.signTransactions).toBe('function');\n    });\n\n    it('freezes the created signer', async () => {\n        expect.assertions(1);\n        const mySigner = await createSignerFromKeyPair(getMockCryptoKeyPair());\n        expect(mySigner).toBeFrozenObject();\n    });\n\n    it('signs messages using the signBytes function', async () => {\n        expect.assertions(7);\n\n        // Given a KeyPairSigner created from a mock CryptoKeyPair.\n        const myKeyPair = getMockCryptoKeyPair();\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        jest.mocked(getAddressFromPublicKey).mockResolvedValueOnce(myAddress);\n        const mySigner = await createSignerFromKeyPair(myKeyPair);\n\n        // And given we mock the next two signatures of the signBytes function.\n        const mockSignatures = [new Uint8Array([101, 101, 101]), new Uint8Array([201, 201, 201])] as SignatureBytes[];\n        jest.mocked(signBytes).mockResolvedValueOnce(mockSignatures[0]);\n        jest.mocked(signBytes).mockResolvedValueOnce(mockSignatures[1]);\n\n        // When we sign two messages using that signer.\n        const messages = [\n            createSignableMessage(new Uint8Array([1, 1, 1])),\n            createSignableMessage(new Uint8Array([2, 2, 2])),\n        ];\n        const signatureDictionaries = await mySigner.signMessages(messages);\n\n        // Then the signature directories contain the expected signatures.\n        expect(signatureDictionaries[0]).toStrictEqual({ [myAddress]: mockSignatures[0] });\n        expect(signatureDictionaries[1]).toStrictEqual({ [myAddress]: mockSignatures[1] });\n\n        // And the signature directories are frozen.\n        expect(signatureDictionaries[0]).toBeFrozenObject();\n        expect(signatureDictionaries[1]).toBeFrozenObject();\n\n        // And signBytes was called twice with the expected parameters.\n        expect(jest.mocked(signBytes)).toHaveBeenCalledTimes(2);\n        expect(jest.mocked(signBytes)).toHaveBeenNthCalledWith(1, myKeyPair.privateKey, messages[0].content);\n        expect(jest.mocked(signBytes)).toHaveBeenNthCalledWith(2, myKeyPair.privateKey, messages[1].content);\n    });\n\n    it('signs transactions using the signTransactions function', async () => {\n        expect.assertions(7);\n\n        // Given a KeyPairSigner created from a mock CryptoKeyPair.\n        const myKeyPair = getMockCryptoKeyPair();\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        jest.mocked(getAddressFromPublicKey).mockResolvedValueOnce(myAddress);\n        const mySigner = await createSignerFromKeyPair(myKeyPair);\n\n        // And given we have a couple of mock transactions to sign.\n        const mockTransactions = [\n            {} as Transaction & TransactionWithinSizeLimit & TransactionWithLifetime,\n            {} as Transaction & TransactionWithinSizeLimit & TransactionWithLifetime,\n        ];\n\n        // And given we mock the next two calls of the partiallySignTransaction function.\n        const mockSignatures = [new Uint8Array([101, 101, 101]), new Uint8Array([201, 201, 201])] as SignatureBytes[];\n        jest.mocked(partiallySignTransaction).mockResolvedValueOnce({\n            ...mockTransactions[0],\n            signatures: { [myAddress]: mockSignatures[0] },\n        });\n        jest.mocked(partiallySignTransaction).mockResolvedValueOnce({\n            ...mockTransactions[1],\n            signatures: { [myAddress]: mockSignatures[1] },\n        });\n\n        // When we sign both transactions using that signer.\n        const signatureDictionaries = await mySigner.signTransactions(mockTransactions);\n\n        // Then the signature directories contain the expected signatures.\n        expect(signatureDictionaries[0]).toStrictEqual({ [myAddress]: mockSignatures[0] });\n        expect(signatureDictionaries[1]).toStrictEqual({ [myAddress]: mockSignatures[1] });\n\n        // And the signature directories are frozen.\n        expect(signatureDictionaries[0]).toBeFrozenObject();\n        expect(signatureDictionaries[1]).toBeFrozenObject();\n\n        // And partiallySignTransaction was called twice with the expected parameters.\n        expect(jest.mocked(partiallySignTransaction)).toHaveBeenCalledTimes(2);\n        expect(jest.mocked(partiallySignTransaction)).toHaveBeenNthCalledWith(1, [myKeyPair], mockTransactions[0]);\n        expect(jest.mocked(partiallySignTransaction)).toHaveBeenNthCalledWith(2, [myKeyPair], mockTransactions[1]);\n    });\n});\n\ndescribe('generateKeyPairSigner', () => {\n    it('generates a new KeyPairSigner using the generateKeyPair function', async () => {\n        expect.assertions(4);\n\n        // Given we mock the return value of generateKeyPair.\n        const mockKeypair = getMockCryptoKeyPair();\n        jest.mocked(generateKeyPair).mockResolvedValueOnce(mockKeypair);\n\n        // And we mock the return value of getAddressFromPublicKey.\n        const mockAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        jest.mocked(getAddressFromPublicKey).mockResolvedValueOnce(mockAddress);\n\n        // When we generate a new KeyPairSigner from scratch.\n        const mySigner = await generateKeyPairSigner();\n        mySigner satisfies KeyPairSigner;\n\n        // Then the signer was created using the generated key pair and the mock address.\n        expect(mySigner.keyPair).toBe(mockKeypair);\n        expect(mySigner.address).toBe(mockAddress);\n\n        // And generateKeyPair was called once with the default `extractable` value.\n        expect(jest.mocked(generateKeyPair)).toHaveBeenCalledTimes(1);\n        expect(jest.mocked(generateKeyPair)).toHaveBeenCalledWith(false);\n    });\n\n    it('forwards the `extractable` argument to `generateKeyPair`', async () => {\n        expect.assertions(2);\n\n        // Given we mock the return value of generateKeyPair.\n        const mockKeypair = getMockCryptoKeyPair();\n        jest.mocked(generateKeyPair).mockResolvedValueOnce(mockKeypair);\n        jest.mocked(getAddressFromPublicKey).mockResolvedValueOnce(\n            address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'),\n        );\n\n        // When we generate a new KeyPairSigner requesting an extractable key pair.\n        await generateKeyPairSigner(true);\n\n        // Then generateKeyPair was called with `extractable` set to `true`.\n        expect(jest.mocked(generateKeyPair)).toHaveBeenCalledTimes(1);\n        expect(jest.mocked(generateKeyPair)).toHaveBeenCalledWith(true);\n    });\n\n    it('freezes the generated signer', async () => {\n        expect.assertions(1);\n\n        // Given we mock the return value of generateKeyPair.\n        const mockKeypair = getMockCryptoKeyPair();\n        jest.mocked(generateKeyPair).mockResolvedValueOnce(mockKeypair);\n\n        // Then the generated signer is frozen.\n        const mySigner = await generateKeyPairSigner();\n        expect(mySigner).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/message-modifying-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER, SolanaError } from '@solana/errors';\n\nimport {\n    assertIsMessageModifyingSigner,\n    isMessageModifyingSigner,\n    MessageModifyingSigner,\n} from '../message-modifying-signer';\n\ndescribe('isMessageModifyingSigner', () => {\n    it('checks whether a given value is a MessageModifyingSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            modifyAndSignMessages: () => Promise.resolve([]),\n        } satisfies MessageModifyingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        expect(isMessageModifyingSigner(mySigner)).toBe(true);\n        expect(isMessageModifyingSigner({ address: myAddress })).toBe(false);\n        expect(isMessageModifyingSigner({ address: myAddress, modifyAndSignMessages: 42 })).toBe(false);\n    });\n});\n\ndescribe('assertIsMessageModifyingSigner', () => {\n    it('asserts that a given value is a MessageModifyingSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            modifyAndSignMessages: () => Promise.resolve([]),\n        } satisfies MessageModifyingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER, {\n            address: myAddress,\n        });\n        expect(() => assertIsMessageModifyingSigner(mySigner)).not.toThrow();\n        expect(() => assertIsMessageModifyingSigner({ address: myAddress })).toThrow(expectedError);\n        expect(() => assertIsMessageModifyingSigner({ address: myAddress, modifyAndSignMessages: 42 })).toThrow(\n            expectedError,\n        );\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/message-partial-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER, SolanaError } from '@solana/errors';\n\nimport { assertIsMessagePartialSigner, isMessagePartialSigner, MessagePartialSigner } from '../message-partial-signer';\n\ndescribe('isMessagePartialSigner', () => {\n    it('checks whether a given value is a MessagePartialSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            signMessages: () => Promise.resolve([]),\n        } satisfies MessagePartialSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        expect(isMessagePartialSigner(mySigner)).toBe(true);\n        expect(isMessagePartialSigner({ address: myAddress })).toBe(false);\n        expect(isMessagePartialSigner({ address: myAddress, signMessages: 42 })).toBe(false);\n    });\n});\n\ndescribe('assertIsMessagePartialSigner', () => {\n    it('asserts that a given value is a MessagePartialSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            signMessages: () => Promise.resolve([]),\n        } satisfies MessagePartialSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER, {\n            address: myAddress,\n        });\n        expect(() => assertIsMessagePartialSigner(mySigner)).not.toThrow();\n        expect(() => assertIsMessagePartialSigner({ address: myAddress })).toThrow(expectedError);\n        expect(() => assertIsMessagePartialSigner({ address: myAddress, signMessages: 42 })).toThrow(expectedError);\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/message-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER, SolanaError } from '@solana/errors';\n\nimport { assertIsMessageSigner, isMessageSigner, MessageSigner } from '../message-signer';\n\ndescribe('isMessageSigner', () => {\n    it('checks whether a given value is a MessageSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const myPartialSigner = {\n            address: myAddress,\n            signMessages: () => Promise.resolve([]),\n        } satisfies MessageSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n        const myModifyingSigner = {\n            address: myAddress,\n            modifyAndSignMessages: () => Promise.resolve([]),\n        } satisfies MessageSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        expect(isMessageSigner(myPartialSigner)).toBe(true);\n        expect(isMessageSigner(myModifyingSigner)).toBe(true);\n        expect(isMessageSigner({ ...myPartialSigner, ...myModifyingSigner })).toBe(true);\n        expect(isMessageSigner({ address: myAddress })).toBe(false);\n        expect(isMessageSigner({ address: myAddress, signMessages: 42 })).toBe(false);\n        expect(isMessageSigner({ address: myAddress, modifyAndSignMessages: 42 })).toBe(false);\n    });\n});\n\ndescribe('assertIsMessageSigner', () => {\n    it('asserts that a given value is a MessageSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const myPartialSigner = {\n            address: myAddress,\n            signMessages: () => Promise.resolve([]),\n        } satisfies MessageSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n        const myModifyingSigner = {\n            address: myAddress,\n            modifyAndSignMessages: () => Promise.resolve([]),\n        } satisfies MessageSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER, {\n            address: myAddress,\n        });\n        expect(() => assertIsMessageSigner(myPartialSigner)).not.toThrow();\n        expect(() => assertIsMessageSigner(myModifyingSigner)).not.toThrow();\n        expect(() => assertIsMessageSigner({ ...myPartialSigner, ...myModifyingSigner })).not.toThrow();\n        expect(() => assertIsMessageSigner({ address: myAddress })).toThrow(expectedError);\n        expect(() => assertIsMessageSigner({ address: myAddress, signMessages: 42 })).toThrow(expectedError);\n        expect(() => assertIsMessageSigner({ address: myAddress, modifyAndSignMessages: 42 })).toThrow(expectedError);\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/noop-signer-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { address } from '@solana/addresses';\nimport { Transaction, TransactionWithinSizeLimit, TransactionWithLifetime } from '@solana/transactions';\n\nimport { createNoopSigner, NoopSigner } from '../noop-signer';\nimport { createSignableMessage } from '../signable-message';\n\ndescribe('createNoopSigner', () => {\n    it('creates a NoopSigner from a given address', () => {\n        // Given a base58 encoded address.\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n\n        // When we create a NoopSigner from that address.\n        const mySigner = createNoopSigner(myAddress);\n        mySigner satisfies NoopSigner;\n\n        // Then the created signer kept track of the address.\n        expect(mySigner.address).toBe(myAddress);\n\n        // And provided functions to sign messages and transactions.\n        expect(typeof mySigner.signMessages).toBe('function');\n        expect(typeof mySigner.signTransactions).toBe('function');\n    });\n\n    it('freezes the created signer', () => {\n        const mySigner = createNoopSigner(address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'));\n        expect(mySigner).toBeFrozenObject();\n    });\n\n    it('returns an empty signature dictionary when signing messages', async () => {\n        expect.assertions(4);\n\n        // Given a NoopSigner.\n        const mySigner = createNoopSigner(address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'));\n\n        // When we sign two messages using that signer.\n        const messages = [createSignableMessage('hello'), createSignableMessage('world')];\n        const signatureDictionaries = await mySigner.signMessages(messages);\n\n        // Then the signature directories are empty and frozen.\n        expect(signatureDictionaries[0]).toStrictEqual({});\n        expect(signatureDictionaries[1]).toStrictEqual({});\n        expect(signatureDictionaries[0]).toBeFrozenObject();\n        expect(signatureDictionaries[1]).toBeFrozenObject();\n    });\n\n    it('returns an empty signature dictionary when signing new transactions', async () => {\n        expect.assertions(4);\n\n        // Given a NoopSigner.\n        const mySigner = createNoopSigner(address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'));\n\n        // And given we have a couple of mock transactions to sign.\n        const mockTransactions = [\n            {} as Transaction & TransactionWithinSizeLimit & TransactionWithLifetime,\n            {} as Transaction & TransactionWithinSizeLimit & TransactionWithLifetime,\n        ];\n\n        // When we sign both transactions using that signer.\n        const signatureDictionaries = await mySigner.signTransactions(mockTransactions);\n\n        // Then the signature directories are empty and frozen.\n        expect(signatureDictionaries[0]).toStrictEqual({});\n        expect(signatureDictionaries[1]).toStrictEqual({});\n        expect(signatureDictionaries[0]).toBeFrozenObject();\n        expect(signatureDictionaries[1]).toBeFrozenObject();\n    });\n\n    it('returns an empty signature dictionary when signing transactions', async () => {\n        expect.assertions(4);\n\n        // Given a NoopSigner.\n        const mySigner = createNoopSigner(address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'));\n\n        // And given we have a couple of mock transactions to sign.\n        const mockTransactions = [\n            {} as Transaction & TransactionWithinSizeLimit & TransactionWithLifetime,\n            {} as Transaction & TransactionWithinSizeLimit & TransactionWithLifetime,\n        ];\n\n        // When we sign both transactions using that signer.\n        const signatureDictionaries = await mySigner.signTransactions(mockTransactions);\n\n        // Then the signature directories are empty and frozen.\n        expect(signatureDictionaries[0]).toStrictEqual({});\n        expect(signatureDictionaries[1]).toStrictEqual({});\n        expect(signatureDictionaries[0]).toBeFrozenObject();\n        expect(signatureDictionaries[1]).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/offchain-message-signer-test.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { getSignersFromOffchainMessage } from '../offchain-message-signer';\nimport { createMockMessageModifyingSigner, createMockMessagePartialSigner } from './__setup__';\n\ndescribe('getSignersFromOffchainMessage', () => {\n    it('extracts signers from the required signatories of the provided message', () => {\n        const signerA = createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const signerB = createMockMessageModifyingSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n        const extractedSigners = getSignersFromOffchainMessage({\n            requiredSignatories: [signerA, signerB],\n        });\n\n        expect(extractedSigners).toHaveLength(2);\n        expect(extractedSigners[0]).toBe(signerA);\n        expect(extractedSigners[1]).toBe(signerB);\n    });\n\n    it('removes duplicated signers by reference', () => {\n        const signerA = createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const signerB = createMockMessageModifyingSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n        const extractedSigners = getSignersFromOffchainMessage({\n            requiredSignatories: [signerA, signerB, signerA, { address: signerA.address }],\n        });\n\n        expect(extractedSigners).toHaveLength(2);\n        expect(extractedSigners.map(signer => signer.address).sort()).toStrictEqual([\n            'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\n            'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',\n        ]);\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/sign-offchain-message-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING, SolanaError } from '@solana/errors';\nimport {\n    compileOffchainMessageEnvelope,\n    FullySignedOffchainMessageEnvelope,\n    OffchainMessageBytes,\n    OffchainMessageEnvelope,\n} from '@solana/offchain-messages';\n\nimport { partiallySignOffchainMessageWithSigners, signOffchainMessageWithSigners } from '../sign-offchain-message';\nimport {\n    createMockMessageModifyingSigner,\n    createMockMessagePartialSigner,\n    createMockOffchainMessageWithSigners,\n} from './__setup__';\n\njest.mock('@solana/offchain-messages', () => ({\n    ...jest.requireActual('@solana/offchain-messages'),\n    compileOffchainMessageEnvelope: jest.fn(),\n}));\n\ndescribe('partiallySignOffchainMessageWithSigners', () => {\n    it('signs the message with its extracted signers', async () => {\n        expect.assertions(3);\n\n        // Given an offchain message with two signers A and B in its list of required signatories.\n        const signerA = createMockMessageModifyingSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const signerB = createMockMessagePartialSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n        const offchainMessage = createMockOffchainMessageWithSigners([signerA, signerB]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // And given signer A and B are mocked to provide the following signatures.\n        const modifiedOffchainMessage = {\n            ...unsignedOffchainMessageEnvelope,\n            signatures: {\n                signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n                signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: null,\n            },\n        };\n        signerA.modifyAndSignMessages.mockResolvedValueOnce([modifiedOffchainMessage]);\n        signerB.signMessages.mockResolvedValueOnce([\n            { signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature' },\n        ]);\n\n        // When we partially sign this message.\n        const mockOptions = {\n            abortSignal: AbortSignal.timeout(1_000_000),\n        };\n        const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(\n            offchainMessage,\n            mockOptions,\n        );\n\n        // Then it contains the expected signatures.\n        expect(signedOffchainMessageEnvelope.signatures).toStrictEqual({\n            signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n        });\n\n        // And the signers were called with the expected parameters.\n        expect(signerA.modifyAndSignMessages).toHaveBeenCalledWith([unsignedOffchainMessageEnvelope], mockOptions);\n        expect(signerB.signMessages).toHaveBeenCalledWith([modifiedOffchainMessage], mockOptions);\n    });\n\n    it('signs modifying signers before partial signers', async () => {\n        expect.assertions(2);\n\n        // Given a modifying signer A and a partial signer B.\n        const signerA = createMockMessageModifyingSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const signerB = createMockMessagePartialSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        signerA.modifyAndSignMessages.mockImplementation((messages: OffchainMessageEnvelope[]) => {\n            events.push('signerA');\n            return messages.map(message => ({\n                ...message,\n                signatures: {\n                    signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:\n                        'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n                },\n            }));\n        });\n        signerB.signMessages.mockImplementation((messages: OffchainMessageEnvelope[]) => {\n            events.push('signerB');\n            return messages.map(() => ({\n                signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n            }));\n        });\n\n        // And given an offchain message that contains these signers in its list of required signatories (in any order).\n        const offchainMessage = createMockOffchainMessageWithSigners([signerB, signerA]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // When we partially sign this message.\n        const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage);\n\n        // Then the modifying signer was called before the partial signer.\n        expect(events).toStrictEqual(['signerA', 'signerB']);\n\n        // And it contains the expected signatures.\n        expect(signedOffchainMessageEnvelope.signatures).toStrictEqual({\n            signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n        });\n    });\n\n    it('signs modifying signers sequentially', async () => {\n        expect.assertions(2);\n\n        // Given two modifying signers A and B.\n        const signerA = createMockMessageModifyingSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const signerB = createMockMessageModifyingSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        const mockImplementation =\n            (signerId: string, address: string) => async (messages: OffchainMessageEnvelope[]) => {\n                events.push(`${signerId} starts`);\n                await new Promise(r => setTimeout(r, 500));\n                events.push(`${signerId} ends`);\n                return messages.map(message => ({\n                    ...message,\n                    signatures: { ...message.signatures, [address]: `${address}_signature` },\n                }));\n            };\n        signerA.modifyAndSignMessages.mockImplementation(\n            mockImplementation('signerA', 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'),\n        );\n        signerB.modifyAndSignMessages.mockImplementation(\n            mockImplementation('signerB', 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'),\n        );\n\n        // And given an offchain message that contains these two signers in its list of required signatories.\n        const offchainMessage = createMockOffchainMessageWithSigners([signerA, signerB]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // When we partially sign this message.\n        const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage);\n\n        // Then the first modifying signer finished signing before the second one started.\n        expect(events).toStrictEqual(['signerA starts', 'signerA ends', 'signerB starts', 'signerB ends']);\n\n        // And it contains the expected signatures.\n        expect(signedOffchainMessageEnvelope.signatures).toStrictEqual({\n            signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n        });\n    });\n\n    it('signs partial signers in parallel', async () => {\n        expect.assertions(2);\n\n        // Given two partial signers A and B.\n        const signerA = createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const signerB = createMockMessagePartialSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        const mockImplementation =\n            (signerId: string, address: string, timeout: number) => async (messages: OffchainMessageEnvelope[]) => {\n                events.push(`${signerId} starts`);\n                await new Promise(r => setTimeout(r, timeout));\n                events.push(`${signerId} ends`);\n                return messages.map(() => ({ [address]: `${address}_signature` }));\n            };\n        signerA.signMessages.mockImplementation(\n            mockImplementation('signerA', 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', 500),\n        );\n        signerB.signMessages.mockImplementation(\n            mockImplementation('signerB', 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', 600),\n        );\n\n        // And given an offchain message that contains these two signers in its list of required signatories.\n        const offchainMessage = createMockOffchainMessageWithSigners([signerA, signerB]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // When we partially sign this message.\n        const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage);\n\n        // Then the second partial signer started signing before the first one finished.\n        expect(events).toStrictEqual(['signerA starts', 'signerB starts', 'signerA ends', 'signerB ends']);\n\n        // And it contains the expected signatures.\n        expect(signedOffchainMessageEnvelope.signatures).toStrictEqual({\n            signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n        });\n    });\n\n    it('uses a composite signer as a modifying signer when there are no other modifying signers', async () => {\n        expect.assertions(4);\n\n        // Given an offchain message with a composite (partial & modifying) signer A and a partial signer B.\n        const signerA = {\n            ...createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address),\n            ...createMockMessageModifyingSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address),\n        };\n        const signerB = createMockMessagePartialSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n        const offchainMessage = createMockOffchainMessageWithSigners([signerA, signerB]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // And given the following mocked signatures.\n        const modifiedOffchainMessage = {\n            ...unsignedOffchainMessageEnvelope,\n            signatures: {\n                signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            },\n        };\n        signerA.modifyAndSignMessages.mockResolvedValueOnce([modifiedOffchainMessage]);\n        signerB.signMessages.mockResolvedValueOnce([\n            { signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature' },\n        ]);\n\n        // When we partially sign this message.\n        const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage);\n\n        // Then signer A was used as a modifying signer.\n        expect(signerA.signMessages).not.toHaveBeenCalled();\n        expect(signerA.modifyAndSignMessages).toHaveBeenCalledWith(\n            [unsignedOffchainMessageEnvelope],\n            undefined /* config */,\n        );\n        expect(signerB.signMessages).toHaveBeenCalledWith([modifiedOffchainMessage], undefined /* config */);\n\n        // And it contains the expected signatures.\n        expect(signedOffchainMessageEnvelope.signatures).toStrictEqual({\n            signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n        });\n    });\n\n    it('uses a composite signer as a partial signer when other modifying signers exist', async () => {\n        expect.assertions(4);\n\n        // Given an offchain message with a composite (partial & modifying) signer A and a modifying signer B.\n        const signerA = {\n            ...createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address),\n            ...createMockMessageModifyingSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address),\n        };\n        const signerB = createMockMessageModifyingSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n        const offchainMessage = createMockOffchainMessageWithSigners([signerA, signerB]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // And given the following mocked signatures.\n        const modifiedOffchainMessage = {\n            ...unsignedOffchainMessageEnvelope,\n            signatures: {\n                signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n            },\n        };\n        signerA.signMessages.mockResolvedValueOnce([\n            { signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature' },\n        ]);\n        signerB.modifyAndSignMessages.mockResolvedValueOnce([modifiedOffchainMessage]);\n\n        // When we partially sign this message.\n        const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage);\n\n        // Then signer A was used as a partial signer.\n        expect(signerA.signMessages).toHaveBeenCalledWith([modifiedOffchainMessage], undefined /* config */);\n        expect(signerA.modifyAndSignMessages).not.toHaveBeenCalled();\n        expect(signerB.modifyAndSignMessages).toHaveBeenCalledWith(\n            [unsignedOffchainMessageEnvelope],\n            undefined /* config */,\n        );\n\n        // And it contains the expected signatures.\n        expect(signedOffchainMessageEnvelope.signatures).toStrictEqual({\n            signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n        });\n    });\n\n    it('freezes the signed message and its signature dictionary', async () => {\n        expect.assertions(2);\n\n        // Given an offchain message with a mocked partial signer.\n        const signer = createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const offchainMessage = createMockOffchainMessageWithSigners([signer]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        signer.signMessages.mockResolvedValueOnce([\n            { signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature' },\n        ]);\n\n        // When we partially sign this message.\n        const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage);\n\n        // Then the signed message and its signature dictionary are frozen.\n        expect(signedOffchainMessageEnvelope).toBeFrozenObject();\n        expect(signedOffchainMessageEnvelope.signatures).toBeFrozenObject();\n    });\n\n    it('can be cancelled using an AbortSignal', async () => {\n        expect.assertions(1);\n\n        // Given an offchain message with a mocked partial signer.\n        const signer = createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        signer.signMessages.mockResolvedValueOnce([\n            { signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature' },\n        ]);\n        const offchainMessage = createMockOffchainMessageWithSigners([signer]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // And given we've started partially signing this message whilst providing an abort signal.\n        const abortController = new AbortController();\n        const promise = partiallySignOffchainMessageWithSigners(offchainMessage, {\n            abortSignal: abortController.signal,\n        });\n\n        // When we cancel the operation via the abort controller.\n        abortController.abort();\n\n        // Then we expect the partially signing promise to fail.\n        await expect(promise).rejects.toThrow(/(The|This) operation was aborted/);\n    });\n\n    it('compiles the input offchain message', async () => {\n        expect.assertions(1);\n\n        // Given a message\n        const offchainMessage = createMockOffchainMessageWithSigners([]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {},\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // When we partially sign it\n        await partiallySignOffchainMessageWithSigners(offchainMessage);\n\n        // Then we expect the compile function to have been called\n        expect(compileOffchainMessageEnvelope).toHaveBeenCalled();\n    });\n});\n\ndescribe('signOffchainMessageWithSigners', () => {\n    it('signs the message with its extracted signers', async () => {\n        expect.assertions(3);\n\n        // Given an offchain message with two signers A and B in its list of required signatories.\n        const signerA = createMockMessageModifyingSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const signerB = createMockMessagePartialSigner('signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address);\n        const offchainMessage = createMockOffchainMessageWithSigners([signerA, signerB]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // And given signer A and B are mocked to provide the following signatures.\n        const modifiedOffchainMessage = {\n            ...unsignedOffchainMessageEnvelope,\n            signatures: {\n                signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            },\n        };\n        signerA.modifyAndSignMessages.mockResolvedValueOnce([modifiedOffchainMessage]);\n        signerB.signMessages.mockResolvedValueOnce([\n            { signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature' },\n        ]);\n\n        // When we sign this message.\n        const mockOptions = {\n            abortSignal: AbortSignal.timeout(1_000_000),\n        };\n        const signedOffchainMessageEnvelope = await signOffchainMessageWithSigners(offchainMessage, mockOptions);\n\n        // Then it contains the expected signatures.\n        expect(signedOffchainMessageEnvelope.signatures).toStrictEqual({\n            signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature',\n            signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB_signature',\n        });\n\n        // And the message is fully signed.\n        signedOffchainMessageEnvelope satisfies FullySignedOffchainMessageEnvelope & OffchainMessageEnvelope;\n\n        // And the signers were called with the expected parameters.\n        expect(signerA.modifyAndSignMessages).toHaveBeenCalledWith([unsignedOffchainMessageEnvelope], mockOptions);\n        expect(signerB.signMessages).toHaveBeenCalledWith([modifiedOffchainMessage], mockOptions);\n    });\n\n    it('asserts the message is fully signed', async () => {\n        expect.assertions(1);\n\n        // Given an offchain message with a partial signer A and a non-Signer address B\n        const signerA = createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        const signerB = { address: 'signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address };\n        const offchainMessageWithSignerA = createMockOffchainMessageWithSigners([signerA]);\n        const offchainMessage = {\n            ...offchainMessageWithSignerA,\n            requiredSignatories: [...offchainMessageWithSignerA.requiredSignatories, signerB],\n        } as typeof offchainMessageWithSignerA;\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // And given signer A is mocked to provide the following signatures.\n        signerA.signMessages.mockResolvedValueOnce([\n            { signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature' },\n        ]);\n\n        // When we try to sign this message.\n        const promise = signOffchainMessageWithSigners(offchainMessage);\n\n        // Then we expect an error letting us know the message is not fully signed.\n        // This is because non Signers are ignored by signOffchainMessageWithSigners.\n        await expect(promise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__OFFCHAIN_MESSAGE__SIGNATURES_MISSING, {\n                addresses: ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address],\n            }),\n        );\n    });\n\n    it('can be cancelled using an AbortSignal', async () => {\n        expect.assertions(1);\n\n        // Given an offchain message with a mocked partial signer.\n        const signer = createMockMessagePartialSigner('signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address);\n        signer.signMessages.mockResolvedValueOnce([\n            { signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: 'signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_signature' },\n        ]);\n        const offchainMessage = createMockOffchainMessageWithSigners([signer]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {\n                ['signerAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address]: null,\n                ['signerBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address]: null,\n            },\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // And given we've started signing this message whilst providing an abort signal.\n        const abortController = new AbortController();\n        const promise = signOffchainMessageWithSigners(offchainMessage, {\n            abortSignal: abortController.signal,\n        });\n\n        // When we cancel the operation via the abort controller.\n        abortController.abort();\n\n        // Then we expect the signing promise to fail.\n        await expect(promise).rejects.toThrow(/(The|This) operation was aborted/);\n    });\n\n    it('compiles the input offchain message', async () => {\n        expect.assertions(1);\n\n        // Given an offchain message\n        const offchainMessage = createMockOffchainMessageWithSigners([]);\n        const unsignedOffchainMessageEnvelope: OffchainMessageEnvelope = {\n            content: new Uint8Array() as unknown as OffchainMessageBytes,\n            signatures: {},\n        };\n        jest.mocked(compileOffchainMessageEnvelope).mockReturnValue(unsignedOffchainMessageEnvelope);\n\n        // When we partially sign it\n        await signOffchainMessageWithSigners(offchainMessage);\n\n        // Then we expect the compile function to have been called\n        expect(compileOffchainMessageEnvelope).toHaveBeenCalled();\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/sign-transaction-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING,\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n    SolanaError,\n} from '@solana/errors';\nimport { Blockhash } from '@solana/rpc-types';\nimport {\n    compileTransaction,\n    FullySignedTransaction,\n    Transaction,\n    TransactionMessageBytes,\n    TransactionWithLifetime,\n} from '@solana/transactions';\n\nimport {\n    partiallySignTransactionMessageWithSigners,\n    partiallySignTransactionWithSigners,\n    signAndSendTransactionMessageWithSigners,\n    signAndSendTransactionWithSigners,\n    signTransactionMessageWithSigners,\n    signTransactionWithSigners,\n} from '../sign-transaction';\nimport {\n    assertIsTransactionMessageWithSingleSendingSigner,\n    TransactionMessageWithSingleSendingSigner,\n} from '../transaction-with-single-sending-signer';\nimport {\n    createMockTransactionCompositeSigner,\n    createMockTransactionMessageWithSigners,\n    createMockTransactionModifyingSigner,\n    createMockTransactionPartialSigner,\n    createMockTransactionSendingSigner,\n} from './__setup__';\n\njest.mock('@solana/transactions', () => ({\n    ...jest.requireActual('@solana/transactions'),\n    compileTransaction: jest.fn(),\n}));\n\ndescribe('partiallySignTransactionMessageWithSigners', () => {\n    it('signs the transaction with its extracted signers', async () => {\n        expect.assertions(3);\n\n        // Given a transaction with two signers A and B in its account metas.\n        const signerA = createMockTransactionModifyingSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given signer A and B are mocked to provide the following signatures.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } };\n        signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we partially sign this transaction.\n        const mockOptions = {\n            abortSignal: AbortSignal.timeout(1_000_000),\n            minContextSlot: 123n,\n        };\n        const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage, mockOptions);\n\n        // Then it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n\n        // And the signers were called with the expected parameters.\n        expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], mockOptions);\n        expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], mockOptions);\n    });\n\n    it('signs modifying signers before partial signers', async () => {\n        expect.assertions(2);\n\n        // Given a modifying signer A and a partial signer B.\n        const signerA = createMockTransactionModifyingSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        signerA.modifyAndSignTransactions.mockImplementation((transactions: Transaction[]) => {\n            events.push('signerA');\n            return transactions.map(tx => ({ ...tx, signatures: { '1111': '1111_signature' } }));\n        });\n        signerB.signTransactions.mockImplementation((transactions: Transaction[]) => {\n            events.push('signerB');\n            return transactions.map(() => ({ '2222': '2222_signature' }));\n        });\n\n        // And given a transaction that contains theses signers in its account metas (in any order).\n        const transactionMessage = createMockTransactionMessageWithSigners([signerB, signerA]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n\n        // Then the modifying signer was called before the partial signer.\n        expect(events).toStrictEqual(['signerA', 'signerB']);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('signs modifying signers sequentially', async () => {\n        expect.assertions(2);\n\n        // Given two modifying signers A and B.\n        const signerA = createMockTransactionModifyingSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        const mockImplementation = (signerId: string, address: string) => async (transactions: Transaction[]) => {\n            events.push(`${signerId} starts`);\n            await new Promise(r => setTimeout(r, 500));\n            events.push(`${signerId} ends`);\n            return transactions.map(tx => ({\n                ...tx,\n                signatures: { ...tx.signatures, [address]: `${address}_signature` },\n            }));\n        };\n        signerA.modifyAndSignTransactions.mockImplementation(mockImplementation('signerA', '1111'));\n        signerB.modifyAndSignTransactions.mockImplementation(mockImplementation('signerB', '2222'));\n\n        // And given a transaction that contains theses two signers in its account metas.\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n\n        // Then the first modifying signer finished signing before the second one started.\n        expect(events).toStrictEqual(['signerA starts', 'signerA ends', 'signerB starts', 'signerB ends']);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('signs partial signers in parallel', async () => {\n        expect.assertions(2);\n\n        // Given two partial signers A and B.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        const mockImplementation =\n            (signerId: string, address: string, timeout: number) => async (transactions: Transaction[]) => {\n                events.push(`${signerId} starts`);\n                await new Promise(r => setTimeout(r, timeout));\n                events.push(`${signerId} ends`);\n                return transactions.map(() => ({ [address]: `${address}_signature` }));\n            };\n        signerA.signTransactions.mockImplementation(mockImplementation('signerA', '1111', 500));\n        signerB.signTransactions.mockImplementation(mockImplementation('signerB', '2222', 600));\n\n        // And given a transaction that contains theses two signers in its account metas.\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n\n        // Then the second partial signer started signing before the first one finished.\n        expect(events).toStrictEqual(['signerA starts', 'signerB starts', 'signerA ends', 'signerB ends']);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('ignores sending signers', async () => {\n        expect.assertions(4);\n\n        // Given a transaction with a sending signer A and a composite signer B\n        // which is both a sending signer and a partial signer.\n        const signerA = createMockTransactionSendingSigner('1111' as Address);\n        const signerB = {\n            ...createMockTransactionSendingSigner('2222' as Address),\n            ...createMockTransactionPartialSigner('2222' as Address),\n        };\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given signer B's partial interface is mocked to provide the following signatures.\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n\n        // Then it only contains signer B's signature.\n        expect(signedTransaction.signatures).toStrictEqual({ '1111': null, '2222': '2222_signature' });\n\n        // And only the partial signer function was called.\n        expect(signerB.signTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n        expect(signerA.signAndSendTransactions).not.toHaveBeenCalled();\n        expect(signerB.signAndSendTransactions).not.toHaveBeenCalled();\n    });\n\n    it('uses a composite signer as a modifying signer when there are no other modifying signers', async () => {\n        expect.assertions(4);\n\n        // Given a transaction with a composite (partial & modifying) signer A and a partial signer B.\n        const signerA = {\n            ...createMockTransactionPartialSigner('1111' as Address),\n            ...createMockTransactionModifyingSigner('1111' as Address),\n        };\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given the following mocked signatures.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature' } };\n        signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n\n        // Then signer A was used as a modifying signer.\n        expect(signerA.signTransactions).not.toHaveBeenCalled();\n        expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n        expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], undefined /* config */);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('uses a composite signer as a partial signer when other modifying signers exist', async () => {\n        expect.assertions(4);\n\n        // Given a transaction with a composite (partial & modifying) signer A and a modifying signer B.\n        const signerA = {\n            ...createMockTransactionPartialSigner('1111' as Address),\n            ...createMockTransactionModifyingSigner('1111' as Address),\n        };\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given the following mocked signatures.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '2222': '2222_signature' } };\n        signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        signerB.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n\n        // Then signer A was used as a partial signer.\n        expect(signerA.signTransactions).toHaveBeenCalledWith([modifiedTransaction], undefined /* config */);\n        expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled();\n        expect(signerB.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('freezes the signed transaction and its signature dictionary', async () => {\n        expect.assertions(2);\n\n        // Given a transaction with a mocked partial signer.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        const transactionMessage = createMockTransactionMessageWithSigners([signer]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n\n        // Then the signed transaction and its signature dictionary are frozen.\n        expect(signedTransaction).toBeFrozenObject();\n        expect(signedTransaction.signatures).toBeFrozenObject();\n    });\n\n    it('can be cancelled using an AbortSignal', async () => {\n        expect.assertions(1);\n\n        // Given a transaction with a mocked partial signer.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        const transactionMessage = createMockTransactionMessageWithSigners([signer]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given we've started partially signing this transaction whilst providing an abort signal.\n        const abortController = new AbortController();\n        const promise = partiallySignTransactionMessageWithSigners(transactionMessage, {\n            abortSignal: abortController.signal,\n        });\n\n        // When we cancel the operation via the abort controller.\n        abortController.abort();\n\n        // Then we expect the partially signing promise to fail.\n        await expect(promise).rejects.toThrow(/(The|This) operation was aborted/);\n    });\n\n    it('compiles the input transaction message', async () => {\n        expect.assertions(1);\n\n        // Given a transaction\n        const transactionMessage = createMockTransactionMessageWithSigners([]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // When we partially sign it\n        await partiallySignTransactionMessageWithSigners(transactionMessage);\n\n        // Then we expect the compile function to have been called\n        expect(compileTransaction).toHaveBeenCalled();\n    });\n});\n\ndescribe('signTransactionMessageWithSigners', () => {\n    it('signs the transaction with its extracted signers', async () => {\n        expect.assertions(3);\n\n        // Given a transaction with two signers A and B in its account metas.\n        const signerA = createMockTransactionModifyingSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given signer A and B are mocked to provide the following signatures.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature' } };\n        signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we sign this transaction.\n        const mockOptions = {\n            abortSignal: AbortSignal.timeout(1_000_000),\n            minContextSlot: 123n,\n        };\n        const signedTransaction = await signTransactionMessageWithSigners(transactionMessage, mockOptions);\n\n        // Then it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n\n        // And the transaction is fully signed.\n        signedTransaction satisfies FullySignedTransaction & Transaction;\n\n        // And the signers were called with the expected parameters.\n        expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], mockOptions);\n        expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], mockOptions);\n    });\n\n    it('asserts the transaction is fully signed', async () => {\n        expect.assertions(1);\n\n        // Given a transaction with a partial signer A and a sending signer B.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given signer A is mocked to provide the following signatures.\n        signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n\n        // When we try to sign this transaction.\n        const promise = signTransactionMessageWithSigners(transactionMessage);\n\n        // Then we expect an error letting us know the transaction is not fully signed.\n        // This is because sending signers are ignored by signTransactionMessageWithSigners.\n        await expect(promise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n                addresses: ['2222' as Address],\n            }),\n        );\n    });\n\n    it('can be cancelled using an AbortSignal', async () => {\n        expect.assertions(1);\n\n        // Given a transaction with a mocked partial signer.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        const transactionMessage = createMockTransactionMessageWithSigners([signer]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given we've started signing this transaction whilst providing an abort signal.\n        const abortController = new AbortController();\n        const promise = signTransactionMessageWithSigners(transactionMessage, {\n            abortSignal: abortController.signal,\n        });\n\n        // When we cancel the operation via the abort controller.\n        abortController.abort();\n\n        // Then we expect the signing promise to fail.\n        await expect(promise).rejects.toThrow(/(The|This) operation was aborted/);\n    });\n\n    it('compiles the input transaction message', async () => {\n        expect.assertions(1);\n\n        // Given a transaction\n        const transactionMessage = createMockTransactionMessageWithSigners([]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // When we partially sign it\n        await signTransactionMessageWithSigners(transactionMessage);\n\n        // Then we expect the compile function to have been called\n        expect(compileTransaction).toHaveBeenCalled();\n    });\n});\n\ndescribe('signAndSendTransactionMessageWithSigners', () => {\n    it('signs and sends the transaction with the provided signers', async () => {\n        expect.assertions(3);\n\n        // Given a transaction with a partial signer A and a sending signer B.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given signer A and B are mocked to provide the following return values.\n        signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n\n        // When we sign and send this transaction.\n        assertIsTransactionMessageWithSingleSendingSigner(transactionMessage);\n        const mockOptions = {\n            abortSignal: AbortSignal.timeout(1_000_000),\n            minContextSlot: 123n,\n        };\n        const transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage, mockOptions);\n\n        // Then the sending signer was used to send the transaction.\n        expect(signerA.signTransactions).toHaveBeenCalledWith([unsignedTransaction], mockOptions);\n        expect(signerB.signAndSendTransactions).toHaveBeenCalledWith(\n            [{ ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } }],\n            mockOptions,\n        );\n\n        // And the returned signature matches the one returned by the sending signer.\n        expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3]));\n    });\n\n    it('fails if no sending signer exists on the transaction', async () => {\n        expect.assertions(1);\n\n        // Given a transaction with a mocked partial signer but no sending signer.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        const transactionMessage = createMockTransactionMessageWithSigners([signer]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // When we try to force sign and send this transaction.\n        const promise = signAndSendTransactionMessageWithSigners(\n            transactionMessage as TransactionMessageWithSingleSendingSigner & typeof transactionMessage,\n        );\n\n        // Then we expect an error letting us know no sending mechanism was provided.\n        await expect(promise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING),\n        );\n    });\n\n    it('uses a composite signer as a sending signer when there are no other sending signers', async () => {\n        expect.assertions(4);\n\n        // Given a transaction with a composite (partial, modifying & sending) signer A and a partial signer B.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n        const transactionMessage = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        signerA.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we sign and send this transaction.\n        assertIsTransactionMessageWithSingleSendingSigner(transactionMessage);\n        const transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n\n        // Then the composite signer was used as a sending signer.\n        expect(signerA.signAndSendTransactions).toHaveBeenCalledWith(\n            [{ ...unsignedTransaction, signatures: { '1111': null, '2222': '2222_signature' } }],\n            undefined /* config */,\n        );\n        expect(signerA.signTransactions).not.toHaveBeenCalled();\n        expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled();\n\n        // And the returned signature matches the one returned by that sending signer.\n        expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3]));\n    });\n\n    it('uses a composite signer as a modifying signer when there are no other modifying signers', async () => {\n        expect.assertions(5);\n\n        // Given a transaction with a composite (partial, modifying & sending) signer A and a sending signer B.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given the following mocked signatures for these signers.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } };\n        signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n        signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n\n        // When we sign and send this transaction.\n        assertIsTransactionMessageWithSingleSendingSigner(transaction);\n        const transactionSignature = await signAndSendTransactionMessageWithSigners(transaction);\n\n        // Then the composite signer was used as a modifying signer.\n        expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n        expect(signerA.signTransactions).not.toHaveBeenCalled();\n        expect(signerA.signAndSendTransactions).not.toHaveBeenCalled();\n\n        // And the sending only signer was used to send the transaction.\n        expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3]));\n        expect(signerB.signAndSendTransactions).toHaveBeenCalledWith([modifiedTransaction], undefined /* config */);\n    });\n\n    it('uses a composite signer as a partial signer when other sending and modifying signers exist', async () => {\n        expect.assertions(6);\n\n        // Given a transaction with a composite (partial, modifying & sending) signer A,\n        // a sending signer B and a modifying signer C.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n        const signerC = createMockTransactionModifyingSigner('3333' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB, signerC]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n                ['3333' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given the following mocked signatures for these signers.\n        signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n        const modifiedTransaction = {\n            ...unsignedTransaction,\n            signatures: { '1111': null, '2222': null, '3333': '3333_signature' },\n        };\n        signerC.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n\n        // When we sign and send this transaction.\n        assertIsTransactionMessageWithSingleSendingSigner(transaction);\n        const transactionSignature = await signAndSendTransactionMessageWithSigners(transaction);\n\n        // Then the composite signer was used as a partial signer.\n        expect(signerA.signTransactions).toHaveBeenCalledWith([modifiedTransaction], undefined /* config */);\n        expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled();\n        expect(signerA.signAndSendTransactions).not.toHaveBeenCalled();\n\n        // And the other signers were used as expected.\n        expect(signerC.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n        expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3]));\n        expect(signerB.signAndSendTransactions).toHaveBeenCalledWith(\n            [\n                {\n                    ...unsignedTransaction,\n                    signatures: { '1111': '1111_signature', '2222': null, '3333': '3333_signature' },\n                },\n            ],\n            undefined /* config */,\n        );\n    });\n\n    it('can be cancelled using an AbortSignal', async () => {\n        expect.assertions(1);\n\n        // Given a transaction with a mocked sending signer.\n        const signer = createMockTransactionSendingSigner('1111' as Address);\n        signer.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n        const transactionMessage = createMockTransactionMessageWithSigners([signer]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // And given we've started signing this transaction whilst providing an abort signal.\n        const abortController = new AbortController();\n        assertIsTransactionMessageWithSingleSendingSigner(transactionMessage);\n        const promise = signAndSendTransactionMessageWithSigners(transactionMessage, {\n            abortSignal: abortController.signal,\n        });\n\n        // When we cancel the operation via the abort controller.\n        abortController.abort();\n\n        // Then we expect the signing promise to fail.\n        await expect(promise).rejects.toThrow(/(The|This) operation was aborted/);\n    });\n\n    it('compiles the input transaction message', async () => {\n        expect.assertions(1);\n\n        // Given a transaction with a mocked sending signer.\n        const signer = createMockTransactionSendingSigner('1111' as Address);\n        signer.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n        const transactionMessage = createMockTransactionMessageWithSigners([signer]);\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n            },\n        };\n        jest.mocked(compileTransaction).mockReturnValue(unsignedTransaction);\n\n        // When we sign and send it\n        assertIsTransactionMessageWithSingleSendingSigner(transactionMessage);\n        await signAndSendTransactionMessageWithSigners(transactionMessage);\n\n        // Then we expect the compile function to have been called\n        expect(compileTransaction).toHaveBeenCalled();\n    });\n});\n\ndescribe('partiallySignTransactionWithSigners', () => {\n    it('signs the transaction with the provided signers', async () => {\n        expect.assertions(3);\n\n        // Given a modifying signer A and a partial signer B.\n        const signerA = createMockTransactionModifyingSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given signer A and B are mocked to provide the following signatures.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } };\n        signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we partially sign this transaction.\n        const mockOptions = {\n            abortSignal: AbortSignal.timeout(1_000_000),\n            minContextSlot: 123n,\n        };\n        const signedTransaction = await partiallySignTransactionWithSigners(\n            [signerA, signerB],\n            unsignedTransaction,\n            mockOptions,\n        );\n\n        // Then it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n\n        // And the signers were called with the expected parameters.\n        expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], mockOptions);\n        expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], mockOptions);\n    });\n\n    it('signs modifying signers before partial signers', async () => {\n        expect.assertions(2);\n\n        // Given a modifying signer A and a partial signer B.\n        const signerA = createMockTransactionModifyingSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        signerA.modifyAndSignTransactions.mockImplementation((transactions: Transaction[]) => {\n            events.push('signerA');\n            return transactions.map(tx => ({ ...tx, signatures: { '1111': '1111_signature' } }));\n        });\n        signerB.signTransactions.mockImplementation((transactions: Transaction[]) => {\n            events.push('signerB');\n            return transactions.map(() => ({ '2222': '2222_signature' }));\n        });\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // When we partially sign this transaction (passing signers in any order).\n        const signedTransaction = await partiallySignTransactionWithSigners([signerB, signerA], unsignedTransaction);\n\n        // Then the modifying signer was called before the partial signer.\n        expect(events).toStrictEqual(['signerA', 'signerB']);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('signs modifying signers sequentially', async () => {\n        expect.assertions(2);\n\n        // Given two modifying signers A and B.\n        const signerA = createMockTransactionModifyingSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        const mockImplementation = (signerId: string, address: string) => async (transactions: Transaction[]) => {\n            events.push(`${signerId} starts`);\n            await new Promise(r => setTimeout(r, 500));\n            events.push(`${signerId} ends`);\n            return transactions.map(tx => ({\n                ...tx,\n                signatures: { ...tx.signatures, [address]: `${address}_signature` },\n            }));\n        };\n        signerA.modifyAndSignTransactions.mockImplementation(mockImplementation('signerA', '1111'));\n        signerB.modifyAndSignTransactions.mockImplementation(mockImplementation('signerB', '2222'));\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionWithSigners([signerA, signerB], unsignedTransaction);\n\n        // Then the first modifying signer finished signing before the second one started.\n        expect(events).toStrictEqual(['signerA starts', 'signerA ends', 'signerB starts', 'signerB ends']);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('signs partial signers in parallel', async () => {\n        expect.assertions(2);\n\n        // Given two partial signers A and B.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n\n        // And mock implementations for both signers such that they append events to an array.\n        const events: string[] = [];\n        const mockImplementation =\n            (signerId: string, address: string, timeout: number) => async (transactions: Transaction[]) => {\n                events.push(`${signerId} starts`);\n                await new Promise(r => setTimeout(r, timeout));\n                events.push(`${signerId} ends`);\n                return transactions.map(() => ({ [address]: `${address}_signature` }));\n            };\n        signerA.signTransactions.mockImplementation(mockImplementation('signerA', '1111', 500));\n        signerB.signTransactions.mockImplementation(mockImplementation('signerB', '2222', 600));\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionWithSigners([signerA, signerB], unsignedTransaction);\n\n        // Then the second partial signer started signing before the first one finished.\n        expect(events).toStrictEqual(['signerA starts', 'signerB starts', 'signerA ends', 'signerB ends']);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('uses a composite signer as a modifying signer when there are no other modifying signers', async () => {\n        expect.assertions(4);\n\n        // Given a composite (partial & modifying) signer A and a partial signer B.\n        const signerA = {\n            ...createMockTransactionPartialSigner('1111' as Address),\n            ...createMockTransactionModifyingSigner('1111' as Address),\n        };\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given the following mocked signatures.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature' } };\n        signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionWithSigners([signerA, signerB], unsignedTransaction);\n\n        // Then signer A was used as a modifying signer.\n        expect(signerA.signTransactions).not.toHaveBeenCalled();\n        expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n        expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], undefined /* config */);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('uses a composite signer as a partial signer when other modifying signers exist', async () => {\n        expect.assertions(4);\n\n        // Given a composite (partial & modifying) signer A and a modifying signer B.\n        const signerA = {\n            ...createMockTransactionPartialSigner('1111' as Address),\n            ...createMockTransactionModifyingSigner('1111' as Address),\n        };\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given the following mocked signatures.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '2222': '2222_signature' } };\n        signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        signerB.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionWithSigners([signerA, signerB], unsignedTransaction);\n\n        // Then signer A was used as a partial signer.\n        expect(signerA.signTransactions).toHaveBeenCalledWith([modifiedTransaction], undefined /* config */);\n        expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled();\n        expect(signerB.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n\n        // And it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n    });\n\n    it('freezes the signed transaction and its signature dictionary', async () => {\n        expect.assertions(2);\n\n        // Given a partial signer.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n\n        // When we partially sign this transaction.\n        const signedTransaction = await partiallySignTransactionWithSigners([signer], unsignedTransaction);\n\n        // Then the signed transaction and its signature dictionary are frozen.\n        expect(signedTransaction).toBeFrozenObject();\n        expect(signedTransaction.signatures).toBeFrozenObject();\n    });\n\n    it('can be cancelled using an AbortSignal', async () => {\n        expect.assertions(1);\n\n        // Given a partial signer.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given we've started partially signing whilst providing an abort signal.\n        const abortController = new AbortController();\n        const promise = partiallySignTransactionWithSigners([signer], unsignedTransaction, {\n            abortSignal: abortController.signal,\n        });\n\n        // When we cancel the operation via the abort controller.\n        abortController.abort();\n\n        // Then we expect the partially signing promise to fail.\n        await expect(promise).rejects.toThrow(/(The|This) operation was aborted/);\n    });\n});\n\ndescribe('signTransactionWithSigners', () => {\n    it('signs the transaction with the provided signers', async () => {\n        expect.assertions(3);\n\n        // Given a modifying signer A and a partial signer B.\n        const signerA = createMockTransactionModifyingSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given signer A and B are mocked to provide the following signatures.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature' } };\n        signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we sign this transaction.\n        const mockOptions = {\n            abortSignal: AbortSignal.timeout(1_000_000),\n            minContextSlot: 123n,\n        };\n        const signedTransaction = await signTransactionWithSigners(\n            [signerA, signerB],\n            unsignedTransaction,\n            mockOptions,\n        );\n\n        // Then it contains the expected signatures.\n        expect(signedTransaction.signatures).toStrictEqual({\n            '1111': '1111_signature',\n            '2222': '2222_signature',\n        });\n\n        // And the transaction is fully signed.\n        signedTransaction satisfies FullySignedTransaction & Transaction;\n\n        // And the signers were called with the expected parameters.\n        expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], mockOptions);\n        expect(signerB.signTransactions).toHaveBeenCalledWith([modifiedTransaction], mockOptions);\n    });\n\n    it('asserts the transaction is fully signed', async () => {\n        expect.assertions(1);\n\n        // Given a partial signer A that only signs for address 1111.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n\n        // And a compiled transaction that expects signatures from both 1111 and 2222.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given signer A is mocked to provide a signature for 1111 only.\n        signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n\n        // When we try to sign this transaction.\n        const promise = signTransactionWithSigners([signerA], unsignedTransaction);\n\n        // Then we expect an error letting us know the transaction is not fully signed.\n        await expect(promise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n                addresses: ['2222' as Address],\n            }),\n        );\n    });\n\n    it('can be cancelled using an AbortSignal', async () => {\n        expect.assertions(1);\n\n        // Given a partial signer.\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n        signer.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given we've started signing whilst providing an abort signal.\n        const abortController = new AbortController();\n        const promise = signTransactionWithSigners([signer], unsignedTransaction, {\n            abortSignal: abortController.signal,\n        });\n\n        // When we cancel the operation via the abort controller.\n        abortController.abort();\n\n        // Then we expect the signing promise to fail.\n        await expect(promise).rejects.toThrow(/(The|This) operation was aborted/);\n    });\n});\n\ndescribe('signAndSendTransactionWithSigners', () => {\n    it('signs and sends the transaction with the provided signers', async () => {\n        expect.assertions(3);\n\n        // Given a partial signer A and a sending signer B.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given signer A and B are mocked to provide the following return values.\n        signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n\n        // When we sign and send this transaction.\n        const mockOptions = {\n            abortSignal: AbortSignal.timeout(1_000_000),\n            minContextSlot: 123n,\n        };\n        const transactionSignature = await signAndSendTransactionWithSigners(\n            [signerA, signerB],\n            unsignedTransaction,\n            mockOptions,\n        );\n\n        // Then the sending signer was used to send the transaction.\n        expect(signerA.signTransactions).toHaveBeenCalledWith([unsignedTransaction], mockOptions);\n        expect(signerB.signAndSendTransactions).toHaveBeenCalledWith(\n            [{ ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } }],\n            mockOptions,\n        );\n\n        // And the returned signature matches the one returned by the sending signer.\n        expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3]));\n    });\n\n    it('fails if no sending signer exists in the provided signers', async () => {\n        expect.assertions(1);\n\n        // Given only a partial signer (no sending signer).\n        const signer = createMockTransactionPartialSigner('1111' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // When we try to sign and send this transaction.\n        const promise = signAndSendTransactionWithSigners([signer], unsignedTransaction);\n\n        // Then we expect an error letting us know no sending mechanism was provided.\n        await expect(promise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING),\n        );\n    });\n\n    it('uses a composite signer as a sending signer when there are no other sending signers', async () => {\n        expect.assertions(4);\n\n        // Given a composite (partial, modifying & sending) signer A and a partial signer B.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionPartialSigner('2222' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        signerA.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n        signerB.signTransactions.mockResolvedValueOnce([{ '2222': '2222_signature' }]);\n\n        // When we sign and send this transaction.\n        const transactionSignature = await signAndSendTransactionWithSigners([signerA, signerB], unsignedTransaction);\n\n        // Then the composite signer was used as a sending signer.\n        expect(signerA.signAndSendTransactions).toHaveBeenCalledWith(\n            [{ ...unsignedTransaction, signatures: { '1111': null, '2222': '2222_signature' } }],\n            undefined /* config */,\n        );\n        expect(signerA.signTransactions).not.toHaveBeenCalled();\n        expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled();\n\n        // And the returned signature matches the one returned by that sending signer.\n        expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3]));\n    });\n\n    it('uses a composite signer as a modifying signer when there are no other modifying signers', async () => {\n        expect.assertions(5);\n\n        // Given a composite (partial, modifying & sending) signer A and a sending signer B.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n            },\n        };\n\n        // And given the following mocked signatures for these signers.\n        const modifiedTransaction = { ...unsignedTransaction, signatures: { '1111': '1111_signature', '2222': null } };\n        signerA.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n        signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n\n        // When we sign and send this transaction.\n        const transactionSignature = await signAndSendTransactionWithSigners([signerA, signerB], unsignedTransaction);\n\n        // Then the composite signer was used as a modifying signer.\n        expect(signerA.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n        expect(signerA.signTransactions).not.toHaveBeenCalled();\n        expect(signerA.signAndSendTransactions).not.toHaveBeenCalled();\n\n        // And the sending only signer was used to send the transaction.\n        expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3]));\n        expect(signerB.signAndSendTransactions).toHaveBeenCalledWith([modifiedTransaction], undefined /* config */);\n    });\n\n    it('uses a composite signer as a partial signer when other sending and modifying signers exist', async () => {\n        expect.assertions(6);\n\n        // Given a composite (partial, modifying & sending) signer A,\n        // a sending signer B and a modifying signer C.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n        const signerC = createMockTransactionModifyingSigner('3333' as Address);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n                ['2222' as Address]: null,\n                ['3333' as Address]: null,\n            },\n        };\n\n        // And given the following mocked signatures for these signers.\n        signerA.signTransactions.mockResolvedValueOnce([{ '1111': '1111_signature' }]);\n        signerB.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n        const modifiedTransaction = {\n            ...unsignedTransaction,\n            signatures: { '1111': null, '2222': null, '3333': '3333_signature' },\n        };\n        signerC.modifyAndSignTransactions.mockResolvedValueOnce([modifiedTransaction]);\n\n        // When we sign and send this transaction.\n        const transactionSignature = await signAndSendTransactionWithSigners(\n            [signerA, signerB, signerC],\n            unsignedTransaction,\n        );\n\n        // Then the composite signer was used as a partial signer.\n        expect(signerA.signTransactions).toHaveBeenCalledWith([modifiedTransaction], undefined /* config */);\n        expect(signerA.modifyAndSignTransactions).not.toHaveBeenCalled();\n        expect(signerA.signAndSendTransactions).not.toHaveBeenCalled();\n\n        // And the other signers were used as expected.\n        expect(signerC.modifyAndSignTransactions).toHaveBeenCalledWith([unsignedTransaction], undefined /* config */);\n        expect(transactionSignature).toStrictEqual(new Uint8Array([1, 2, 3]));\n        expect(signerB.signAndSendTransactions).toHaveBeenCalledWith(\n            [\n                {\n                    ...unsignedTransaction,\n                    signatures: { '1111': '1111_signature', '2222': null, '3333': '3333_signature' },\n                },\n            ],\n            undefined /* config */,\n        );\n    });\n\n    it('can be cancelled using an AbortSignal', async () => {\n        expect.assertions(1);\n\n        // Given a sending signer.\n        const signer = createMockTransactionSendingSigner('1111' as Address);\n        signer.signAndSendTransactions.mockResolvedValueOnce([new Uint8Array([1, 2, 3])]);\n\n        // And a compiled transaction.\n        const unsignedTransaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: { blockhash: 'a' as Blockhash, lastValidBlockHeight: 1n },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['1111' as Address]: null,\n            },\n        };\n\n        // And given we've started signing whilst providing an abort signal.\n        const abortController = new AbortController();\n        const promise = signAndSendTransactionWithSigners([signer], unsignedTransaction, {\n            abortSignal: abortController.signal,\n        });\n\n        // When we cancel the operation via the abort controller.\n        abortController.abort();\n\n        // Then we expect the signing promise to fail.\n        await expect(promise).rejects.toThrow(/(The|This) operation was aborted/);\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/signable-message-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { TextEncoder } from '@solana/text-encoding-impl';\n\nimport { createSignableMessage } from '../signable-message';\n\ndescribe('createSignableMessage', () => {\n    it('creates a SignableMessage from a byte array', () => {\n        // Given a byte array.\n        const content = new Uint8Array([1, 2, 3]);\n\n        // When we use it to create a new SignableMessage.\n        const message = createSignableMessage(content);\n\n        // Then we expect a message with the same content and no signatures.\n        expect(message.content).toBe(content);\n        expect(message.signatures).toStrictEqual({});\n    });\n\n    it('creates a SignableMessage with signatures', () => {\n        // Given a byte array content and some signatures.\n        const content = new Uint8Array([1, 2, 3]);\n        const signatures = {\n            '1111': new Uint8Array([1, 1, 1, 1]),\n            '2222': new Uint8Array([2, 2, 2, 2]),\n        };\n\n        // When we create a SignableMessage using both the content and the existing signatures.\n        const message = createSignableMessage(content, signatures);\n\n        // Then we expect the message to store the provided content as-is.\n        expect(message.content).toBe(content);\n\n        // And the signatures to be copied shallowly.\n        expect(message.signatures).toStrictEqual(signatures);\n    });\n\n    it('creates a SignableMessage from a UTF-8 string', () => {\n        // When we create a SignableMessage by providing a string.\n        const message = createSignableMessage('Hello world!');\n\n        // Then we expect this string to be UTF-8 encoded.\n        expect(message.content).toStrictEqual(new TextEncoder().encode('Hello world!'));\n        expect(message.signatures).toStrictEqual({});\n    });\n\n    it('freezes the created signable message', () => {\n        const message = createSignableMessage('Hello world!');\n        expect(message).toBeFrozenObject();\n    });\n\n    it('freezes the empty signature dictionary when none is provided', () => {\n        const message = createSignableMessage('Hello world!');\n        expect(message.signatures).toStrictEqual({});\n        expect(message.signatures).toBeFrozenObject();\n    });\n\n    it('shallow copies and freezes the provided signature dictionary', () => {\n        // Given an existing signature dictionary.\n        const signatures = {\n            '1111': new Uint8Array([1, 1, 1, 1]),\n            '2222': new Uint8Array([2, 2, 2, 2]),\n        };\n\n        // When we create a new SignableMessage using this signature dictionary.\n        const message = createSignableMessage('Hello world!', signatures);\n\n        // Then the signature dictionary is copied and frozen.\n        expect(message.signatures).not.toBe(signatures);\n        expect(message.signatures).toStrictEqual(signatures);\n        expect(message.signatures).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/transaction-modifying-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER, SolanaError } from '@solana/errors';\n\nimport {\n    assertIsTransactionModifyingSigner,\n    isTransactionModifyingSigner,\n    TransactionModifyingSigner,\n} from '../transaction-modifying-signer';\n\ndescribe('isTransactionModifyingSigner', () => {\n    it('checks whether a given value is a TransactionModifyingSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            modifyAndSignTransactions: () => Promise.resolve([]),\n        } satisfies TransactionModifyingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        expect(isTransactionModifyingSigner(mySigner)).toBe(true);\n        expect(isTransactionModifyingSigner({ address: myAddress })).toBe(false);\n        expect(isTransactionModifyingSigner({ address: myAddress, modifyAndSignTransactions: 42 })).toBe(false);\n    });\n});\n\ndescribe('assertIsTransactionModifyingSigner', () => {\n    it('asserts that a given value is a TransactionModifyingSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            modifyAndSignTransactions: () => Promise.resolve([]),\n        } satisfies TransactionModifyingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER, {\n            address: myAddress,\n        });\n        expect(() => assertIsTransactionModifyingSigner(mySigner)).not.toThrow();\n        expect(() => assertIsTransactionModifyingSigner({ address: myAddress })).toThrow(expectedError);\n        expect(() => assertIsTransactionModifyingSigner({ address: myAddress, modifyAndSignTransactions: 42 })).toThrow(\n            expectedError,\n        );\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/transaction-partial-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER, SolanaError } from '@solana/errors';\n\nimport {\n    assertIsTransactionPartialSigner,\n    isTransactionPartialSigner,\n    TransactionPartialSigner,\n} from '../transaction-partial-signer';\n\ndescribe('isTransactionPartialSigner', () => {\n    it('checks whether a given value is a TransactionPartialSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            signTransactions: () => Promise.resolve([]),\n        } satisfies TransactionPartialSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        expect(isTransactionPartialSigner(mySigner)).toBe(true);\n        expect(isTransactionPartialSigner({ address: myAddress })).toBe(false);\n        expect(isTransactionPartialSigner({ address: myAddress, signTransactions: 42 })).toBe(false);\n    });\n});\n\ndescribe('assertIsTransactionPartialSigner', () => {\n    it('asserts that a given value is a TransactionPartialSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            signTransactions: () => Promise.resolve([]),\n        } satisfies TransactionPartialSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER, {\n            address: myAddress,\n        });\n        expect(() => assertIsTransactionPartialSigner(mySigner)).not.toThrow();\n        expect(() => assertIsTransactionPartialSigner({ address: myAddress })).toThrow(expectedError);\n        expect(() => assertIsTransactionPartialSigner({ address: myAddress, signTransactions: 42 })).toThrow(\n            expectedError,\n        );\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/transaction-sending-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER, SolanaError } from '@solana/errors';\n\nimport {\n    assertIsTransactionSendingSigner,\n    isTransactionSendingSigner,\n    TransactionSendingSigner,\n} from '../transaction-sending-signer';\n\ndescribe('isTransactionSendingSigner', () => {\n    it('checks whether a given value is a TransactionSendingSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            signAndSendTransactions: () => Promise.resolve([]),\n        } satisfies TransactionSendingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        expect(isTransactionSendingSigner(mySigner)).toBe(true);\n        expect(isTransactionSendingSigner({ address: myAddress })).toBe(false);\n        expect(isTransactionSendingSigner({ address: myAddress, signAndSendTransactions: 42 })).toBe(false);\n    });\n});\n\ndescribe('assertIsTransactionSendingSigner', () => {\n    it('asserts that a given value is a TransactionSendingSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const mySigner = {\n            address: myAddress,\n            signAndSendTransactions: () => Promise.resolve([]),\n        } satisfies TransactionSendingSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER, {\n            address: myAddress,\n        });\n        expect(() => assertIsTransactionSendingSigner(mySigner)).not.toThrow();\n        expect(() => assertIsTransactionSendingSigner({ address: myAddress })).toThrow(expectedError);\n        expect(() => assertIsTransactionSendingSigner({ address: myAddress, signAndSendTransactions: 42 })).toThrow(\n            expectedError,\n        );\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/transaction-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER, SolanaError } from '@solana/errors';\n\nimport { assertIsTransactionSigner, isTransactionSigner, TransactionSigner } from '../transaction-signer';\n\ndescribe('isTransactionSigner', () => {\n    it('checks whether a given value is a TransactionSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const myPartialSigner = {\n            address: myAddress,\n            signTransactions: () => Promise.resolve([]),\n        } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n        const myModifyingSigner = {\n            address: myAddress,\n            modifyAndSignTransactions: () => Promise.resolve([]),\n        } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n        const mySendingSigner = {\n            address: myAddress,\n            signAndSendTransactions: () => Promise.resolve([]),\n        } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        expect(isTransactionSigner(myPartialSigner)).toBe(true);\n        expect(isTransactionSigner(myModifyingSigner)).toBe(true);\n        expect(isTransactionSigner(mySendingSigner)).toBe(true);\n        expect(isTransactionSigner({ ...myPartialSigner, ...myModifyingSigner })).toBe(true);\n        expect(isTransactionSigner({ ...myPartialSigner, ...mySendingSigner })).toBe(true);\n        expect(isTransactionSigner({ ...myModifyingSigner, ...mySendingSigner })).toBe(true);\n        expect(isTransactionSigner({ ...myPartialSigner, ...myModifyingSigner, ...mySendingSigner })).toBe(true);\n        expect(isTransactionSigner({ address: myAddress })).toBe(false);\n        expect(isTransactionSigner({ address: myAddress, signTransactions: 42 })).toBe(false);\n        expect(isTransactionSigner({ address: myAddress, modifyAndSignTransactions: 42 })).toBe(false);\n        expect(isTransactionSigner({ address: myAddress, signAndSendTransactions: 42 })).toBe(false);\n    });\n});\n\ndescribe('assertIsTransactionSigner', () => {\n    it('asserts that a given value is a TransactionSigner', () => {\n        const myAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n        const myPartialSigner = {\n            address: myAddress,\n            signTransactions: () => Promise.resolve([]),\n        } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n        const myModifyingSigner = {\n            address: myAddress,\n            modifyAndSignTransactions: () => Promise.resolve([]),\n        } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n        const mySendingSigner = {\n            address: myAddress,\n            signAndSendTransactions: () => Promise.resolve([]),\n        } satisfies TransactionSigner<'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy'>;\n\n        const expectedError = new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER, {\n            address: myAddress,\n        });\n        expect(() => assertIsTransactionSigner(myPartialSigner)).not.toThrow();\n        expect(() => assertIsTransactionSigner(myModifyingSigner)).not.toThrow();\n        expect(() => assertIsTransactionSigner(mySendingSigner)).not.toThrow();\n        expect(() => assertIsTransactionSigner({ ...myPartialSigner, ...myModifyingSigner })).not.toThrow();\n        expect(() => assertIsTransactionSigner({ ...myPartialSigner, ...mySendingSigner })).not.toThrow();\n        expect(() => assertIsTransactionSigner({ ...myModifyingSigner, ...mySendingSigner })).not.toThrow();\n        expect(() =>\n            assertIsTransactionSigner({ ...myPartialSigner, ...myModifyingSigner, ...mySendingSigner }),\n        ).not.toThrow();\n        expect(() => assertIsTransactionSigner({ address: myAddress })).toThrow(expectedError);\n        expect(() => assertIsTransactionSigner({ address: myAddress, signTransactions: 42 })).toThrow(expectedError);\n        expect(() => assertIsTransactionSigner({ address: myAddress, modifyAndSignTransactions: 42 })).toThrow(\n            expectedError,\n        );\n        expect(() => assertIsTransactionSigner({ address: myAddress, signAndSendTransactions: 42 })).toThrow(\n            expectedError,\n        );\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/transaction-with-single-sending-signer.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS,\n    SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING,\n    SolanaError,\n} from '@solana/errors';\n\nimport {\n    assertContainsResolvableTransactionSendingSigner,\n    assertIsTransactionMessageWithSingleSendingSigner,\n    isTransactionMessageWithSingleSendingSigner,\n} from '../transaction-with-single-sending-signer';\nimport {\n    createMockTransactionCompositeSigner,\n    createMockTransactionMessageWithSigners,\n    createMockTransactionModifyingSigner,\n    createMockTransactionPartialSigner,\n    createMockTransactionSendingSigner,\n} from './__setup__';\n\ndescribe('isTransactionMessageWithSingleSendingSigner', () => {\n    it('returns true if a transaction message contains a single sending only signer', () => {\n        // Given a transaction message with a single sending signer.\n        const signer = createMockTransactionSendingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signer]);\n\n        // Then we expect it to be a valid `TransactionWithSingleSendingSigner`.\n        expect(isTransactionMessageWithSingleSendingSigner(transaction)).toBe(true);\n    });\n\n    it('returns true if a transaction message contains multiple sending signer composites', () => {\n        // Given a transaction message with two sending signers that can also be used as other signer interfaces.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionCompositeSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB]);\n\n        // Then we expect it to be a valid `TransactionMessageWithSingleSendingSigner` because we can use\n        // one of them as a sending signer and the other as a modifying or partial signer.\n        expect(isTransactionMessageWithSingleSendingSigner(transaction)).toBe(true);\n    });\n\n    it('returns false if a transaction message contains multiple sending only signers', () => {\n        // Given a transaction message with two sending only signers.\n        const signerA = createMockTransactionSendingSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB]);\n\n        // Then we expect it not to be a valid `TransactionMessageWithSingleSendingSigner`.\n        expect(isTransactionMessageWithSingleSendingSigner(transaction)).toBe(false);\n    });\n\n    it('returns false if a transaction message contains no sending signer at all', () => {\n        // Given a transaction message with no sending signer.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB]);\n\n        // Then we expect it not to be a valid `TransactionMessageWithSingleSendingSigner`.\n        expect(isTransactionMessageWithSingleSendingSigner(transaction)).toBe(false);\n    });\n});\n\ndescribe('assertIsTransactionMessageWithSingleSendingSigner', () => {\n    it('succeeds if a transaction message contains a single sending only signer', () => {\n        // Given a transaction message with a single sending signer.\n        const signer = createMockTransactionSendingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signer]);\n\n        // Then we expect the assertion to succeed.\n        expect(() => assertIsTransactionMessageWithSingleSendingSigner(transaction)).not.toThrow();\n    });\n\n    it('succeeds if a transaction contains multiple sending signer composites', () => {\n        // Given a transaction message with two sending signers that can also be used as other signer interfaces.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionCompositeSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB]);\n\n        // Then we expect the assertion to succeed because we can use one of them\n        // as a sending signer and the other as a modifying or partial signer.\n        expect(() => assertIsTransactionMessageWithSingleSendingSigner(transaction)).not.toThrow();\n    });\n\n    it('fails if a transaction message contains multiple sending only signers', () => {\n        // Given a transaction message with a two sending only signers.\n        const signerA = createMockTransactionSendingSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB]);\n\n        // Then we expect the assertion to fail.\n        expect(() => assertIsTransactionMessageWithSingleSendingSigner(transaction)).toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS),\n        );\n    });\n\n    it('fails if a transaction message contains no sending signer at all', () => {\n        // Given a transaction message with no sending signer.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n        const transaction = createMockTransactionMessageWithSigners([signerA, signerB]);\n\n        // Then we expect the assertion to fail.\n        expect(() => assertIsTransactionMessageWithSingleSendingSigner(transaction)).toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING),\n        );\n    });\n});\n\ndescribe('assertContainsResolvableTransactionSendingSigner', () => {\n    it('succeeds if the signers contain a single sending only signer', () => {\n        // Given a single sending signer.\n        const signer = createMockTransactionSendingSigner('1111' as Address);\n\n        // Then we expect the assertion to succeed.\n        expect(() => assertContainsResolvableTransactionSendingSigner([signer])).not.toThrow();\n    });\n\n    it('succeeds if the signers contain multiple sending signer composites', () => {\n        // Given two sending signers that can also be used as other signer interfaces.\n        const signerA = createMockTransactionCompositeSigner('1111' as Address);\n        const signerB = createMockTransactionCompositeSigner('2222' as Address);\n\n        // Then we expect the assertion to succeed because we can use one of them\n        // as a sending signer and the other as a modifying or partial signer.\n        expect(() => assertContainsResolvableTransactionSendingSigner([signerA, signerB])).not.toThrow();\n    });\n\n    it('fails if the signers contain multiple sending only signers', () => {\n        // Given two sending only signers.\n        const signerA = createMockTransactionSendingSigner('1111' as Address);\n        const signerB = createMockTransactionSendingSigner('2222' as Address);\n\n        // Then we expect the assertion to fail.\n        expect(() => assertContainsResolvableTransactionSendingSigner([signerA, signerB])).toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS),\n        );\n    });\n\n    it('fails if the signers contain no sending signer at all', () => {\n        // Given only partial and modifying signers.\n        const signerA = createMockTransactionPartialSigner('1111' as Address);\n        const signerB = createMockTransactionModifyingSigner('2222' as Address);\n\n        // Then we expect the assertion to fail.\n        expect(() => assertContainsResolvableTransactionSendingSigner([signerA, signerB])).toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/write-keypair-signer-test.browser.ts",
    "content": "import { SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT, SolanaError } from '@solana/errors';\n\nimport { generateKeyPairSigner } from '../keypair-signer';\nimport { writeKeyPairSigner } from '../write-keypair-signer';\n\ndescribe('writeKeyPairSigner', () => {\n    it('throws with `SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT` when called outside Node', async () => {\n        expect.assertions(1);\n        const signer = await generateKeyPairSigner(/* extractable */ true);\n        await expect(writeKeyPairSigner(signer, '/fake/path/keypair.json')).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__tests__/write-keypair-signer-test.node.ts",
    "content": "import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\n\nimport { SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, SolanaError } from '@solana/errors';\nimport { generateKeyPair, writeKeyPair } from '@solana/keys';\n\nimport { createSignerFromKeyPair, generateKeyPairSigner, KeyPairSigner } from '../keypair-signer';\nimport { writeKeyPairSigner } from '../write-keypair-signer';\n\ndescribe('writeKeyPairSigner', () => {\n    let tmpDir: string;\n    let signer: KeyPairSigner;\n    beforeEach(async () => {\n        tmpDir = await mkdtemp(join(tmpdir(), 'kit-write-keypair-signer-'));\n        signer = await generateKeyPairSigner(/* extractable */ true);\n    });\n    afterEach(async () => {\n        await rm(tmpDir, { force: true, recursive: true });\n    });\n    it(\"produces the same file contents as `writeKeyPair` called with the signer's underlying key pair\", async () => {\n        expect.assertions(1);\n        const signerPath = join(tmpDir, 'signer.json');\n        const keyPairPath = join(tmpDir, 'keypair.json');\n        await writeKeyPairSigner(signer, signerPath);\n        await writeKeyPair(signer.keyPair, keyPairPath);\n        const [signerContents, keyPairContents] = await Promise.all([\n            readFile(signerPath, 'utf8'),\n            readFile(keyPairPath, 'utf8'),\n        ]);\n        expect(signerContents).toBe(keyPairContents);\n    });\n    it('refuses to overwrite an existing file by default', async () => {\n        expect.assertions(2);\n        const path = join(tmpDir, 'signer.json');\n        await writeFile(path, 'pre-existing contents');\n        await expect(writeKeyPairSigner(signer, path)).rejects.toThrow(expect.objectContaining({ code: 'EEXIST' }));\n        await expect(readFile(path, 'utf8')).resolves.toBe('pre-existing contents');\n    });\n    it('overwrites an existing file when `unsafelyOverwriteExistingKeyPair` is set', async () => {\n        expect.assertions(1);\n        const path = join(tmpDir, 'signer.json');\n        await writeFile(path, 'pre-existing contents');\n        await writeKeyPairSigner(signer, path, { unsafelyOverwriteExistingKeyPair: true });\n        const contents = await readFile(path, 'utf8');\n        expect(JSON.parse(contents)).toHaveLength(64);\n    });\n    it(\"throws when the signer's key pair is not extractable\", async () => {\n        expect.assertions(1);\n        const nonExtractableKeyPair = await generateKeyPair(/* extractable */ false);\n        const nonExtractableSigner = await createSignerFromKeyPair(nonExtractableKeyPair);\n        await expect(writeKeyPairSigner(nonExtractableSigner, join(tmpDir, 'signer.json'))).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY, {\n                key: nonExtractableKeyPair.privateKey,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/signers/src/__typetests__/account-signer-meta-typetest.ts",
    "content": "import { address } from '@solana/addresses';\nimport { AccountRole } from '@solana/instructions';\n\nimport { AccountSignerMeta } from '../account-signer-meta';\nimport { TransactionSigner } from '../transaction-signer';\n\n{\n    // [AccountSignerMeta]: It adds a transaction signer to a valid account meta.\n    ({\n        address: address('1'),\n        role: AccountRole.READONLY_SIGNER,\n        signer: {} as TransactionSigner,\n    }) satisfies AccountSignerMeta;\n}\n\n{\n    // [AccountSignerMeta]: It fails if the signer is not a transaction signer.\n    ({\n        address: address('1'),\n        role: AccountRole.READONLY_SIGNER,\n        // @ts-expect-error Signer is not a transaction signer.\n        signer: {} as MessageSigner,\n    }) satisfies AccountSignerMeta;\n}\n\n{\n    // [AccountSignerMeta]: It fails if the account meta is not a signer.\n    ({\n        address: address('1'),\n        // @ts-expect-error Role is not a signer role.\n        role: AccountRole.READONLY,\n        signer: {} as TransactionSigner,\n    }) satisfies AccountSignerMeta;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/add-signers-typetest.ts",
    "content": "import { Instruction } from '@solana/instructions';\nimport { TransactionMessage } from '@solana/transaction-messages';\n\nimport { InstructionWithSigners, TransactionMessageWithSigners } from '../account-signer-meta';\nimport { addSignersToInstruction, addSignersToTransactionMessage } from '../add-signers';\nimport { TransactionSigner } from '../transaction-signer';\n\nconst aliceSigner = null as unknown as TransactionSigner<'alice'>;\nconst bobSigner = null as unknown as TransactionSigner<'bob'>;\n\nconst instruction = null as unknown as Instruction;\nconst message = null as unknown as TransactionMessage;\n\n// [DESCRIBE] addSignersToInstruction\n{\n    // It adds the `WithSigners` type expansion to the instruction\n    {\n        const instructionWithSigners = addSignersToInstruction([aliceSigner, bobSigner], instruction);\n        instructionWithSigners satisfies InstructionWithSigners;\n    }\n}\n\n// [DESCRIBE] addSignersToTransactionMessage\n{\n    // It adds the `WithSigners` type expansion to the transaction message\n    {\n        const messageWithSigners = addSignersToTransactionMessage([aliceSigner, bobSigner], message);\n        messageWithSigners satisfies TransactionMessageWithSigners;\n    }\n\n    // It preserves the instruction type of the transaction message\n    {\n        type InstructionA = Instruction & { id: 'A' };\n        type InstructionB = Instruction & { id: 'B' };\n\n        const message = null as unknown as TransactionMessage & {\n            instructions: [InstructionA, InstructionB];\n        };\n\n        message.instructions satisfies [InstructionA, InstructionB];\n        const messageWithSigners = addSignersToTransactionMessage([aliceSigner, bobSigner], message);\n        messageWithSigners satisfies TransactionMessageWithSigners;\n        messageWithSigners.instructions satisfies [InstructionA, InstructionB];\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/fee-payer-typetest.ts",
    "content": "import { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport { setTransactionMessageFeePayerSigner, TransactionMessageWithFeePayerSigner } from '../fee-payer-signer';\nimport { TransactionSigner } from '../transaction-signer';\n\nconst aliceSigner = null as unknown as TransactionSigner<'alice'>;\nconst bobSigner = null as unknown as TransactionSigner<'bob'>;\n\nconst message = null as unknown as TransactionMessage;\n\n// [DESCRIBE] setTransactionFeePayerSigner\n{\n    // It adds the fee payer signer to the new message\n    {\n        const messageWithFeePayer = setTransactionMessageFeePayerSigner(aliceSigner, message);\n        messageWithFeePayer satisfies TransactionMessageWithFeePayerSigner<'alice'>;\n    }\n\n    // It *replaces* an existing fee payer signer with the new one\n    {\n        const messageWithAliceFeePayerSigner = null as unknown as TransactionMessage &\n            TransactionMessageWithFeePayerSigner<'alice'>;\n        const messageWithBobFeePayerSigner = setTransactionMessageFeePayerSigner(\n            bobSigner,\n            messageWithAliceFeePayerSigner,\n        );\n        // @ts-expect-error Alice should no longer be a payer.\n        messageWithBobFeePayerSigner satisfies TransactionMessageWithFeePayerSigner<'alice'>;\n        messageWithBobFeePayerSigner satisfies TransactionMessageWithFeePayerSigner<'bob'>;\n    }\n\n    // It *replaces* an existing fee payer address with the new signer\n    {\n        const messageWithMalloryFeePayer = null as unknown as TransactionMessage &\n            TransactionMessageWithFeePayer<'mallory'>;\n        const messageWithBobFeePayerSigner = setTransactionMessageFeePayerSigner(bobSigner, messageWithMalloryFeePayer);\n        // @ts-expect-error Mallory should no longer be a payer.\n        messageWithBobFeePayerSigner satisfies TransactionMessageWithFeePayer<'mallory'>;\n        messageWithBobFeePayerSigner satisfies TransactionMessageWithFeePayerSigner<'bob'>;\n    }\n\n    // It can narrow the result by transaction version\n    {\n        type TransactionMessageNotLegacy = Exclude<TransactionMessage, { version: 'legacy' }>;\n        const message = null as unknown as TransactionMessage;\n        const messageWithFeePayer = setTransactionMessageFeePayerSigner(aliceSigner, message);\n        // @ts-expect-error Could be legacy\n        messageWithFeePayer satisfies TransactionMessageNotLegacy;\n        if (messageWithFeePayer.version === 0) {\n            messageWithFeePayer satisfies TransactionMessageNotLegacy;\n        }\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/keypair-signer-typetest.ts",
    "content": "import { address } from '@solana/addresses';\n\nimport { assertIsKeyPairSigner, isKeyPairSigner, KeyPairSigner } from '../keypair-signer';\n\nconst keyPair = {} as CryptoKeyPair;\nconst signMessages = () => {};\nconst signTransactions = () => {};\n\n{\n    // [isKeyPairSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), keyPair, signMessages, signTransactions };\n    if (isKeyPairSigner(potentialSigner)) {\n        potentialSigner satisfies KeyPairSigner<'1'>;\n    }\n}\n\n{\n    // [assertIsKeyPairSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), keyPair, signMessages, signTransactions };\n    assertIsKeyPairSigner(potentialSigner);\n    potentialSigner satisfies KeyPairSigner<'1'>;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/message-modifying-signer-typetest.ts",
    "content": "import { address } from '@solana/addresses';\n\nimport {\n    assertIsMessageModifyingSigner,\n    isMessageModifyingSigner,\n    MessageModifyingSigner,\n} from '../message-modifying-signer';\n\nconst modifyAndSignMessages = () => {};\n\n{\n    // [isMessageModifyingSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), modifyAndSignMessages };\n    if (isMessageModifyingSigner(potentialSigner)) {\n        potentialSigner satisfies MessageModifyingSigner<'1'>;\n    }\n}\n\n{\n    // [assertIsMessageModifyingSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), modifyAndSignMessages };\n    assertIsMessageModifyingSigner(potentialSigner);\n    potentialSigner satisfies MessageModifyingSigner<'1'>;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/message-partial-signer-typetest.ts",
    "content": "import { address } from '@solana/addresses';\n\nimport { assertIsMessagePartialSigner, isMessagePartialSigner, MessagePartialSigner } from '../message-partial-signer';\n\nconst signMessages = () => {};\n\n{\n    // [isMessagePartialSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signMessages };\n    if (isMessagePartialSigner(potentialSigner)) {\n        potentialSigner satisfies MessagePartialSigner<'1'>;\n    }\n}\n\n{\n    // [assertIsMessagePartialSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signMessages };\n    assertIsMessagePartialSigner(potentialSigner);\n    potentialSigner satisfies MessagePartialSigner<'1'>;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/message-signer-typetest.ts",
    "content": "import { address } from '@solana/addresses';\n\nimport { assertIsMessageSigner, isMessageSigner, MessageSigner } from '../message-signer';\n\nconst signMessages = () => {};\n\n{\n    // [isMessageSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signMessages };\n    if (isMessageSigner(potentialSigner)) {\n        potentialSigner satisfies MessageSigner<'1'>;\n    }\n}\n\n{\n    // [assertIsMessageSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signMessages };\n    assertIsMessageSigner(potentialSigner);\n    potentialSigner satisfies MessageSigner<'1'>;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/offchain-message-signer-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { MessageModifyingSigner } from '../message-modifying-signer';\nimport { MessagePartialSigner } from '../message-partial-signer';\nimport { MessageSigner } from '../message-signer';\nimport { getSignersFromOffchainMessage, OffchainMessageSignatorySigner } from '../offchain-message-signer';\nimport { TransactionModifyingSigner } from '../transaction-modifying-signer';\nimport { TransactionPartialSigner } from '../transaction-partial-signer';\nimport { TransactionSendingSigner } from '../transaction-sending-signer';\nimport { TransactionSigner } from '../transaction-signer';\n\n// [DESCRIBE] `OffchainMessageSignatorySigner`.\n{\n    // It accepts a `MessageSigner` as a signatory\n    {\n        ({}) as MessageSigner satisfies OffchainMessageSignatorySigner;\n        ({}) as MessageModifyingSigner satisfies OffchainMessageSignatorySigner;\n        ({}) as MessagePartialSigner satisfies OffchainMessageSignatorySigner;\n    }\n    // It does not accept a `TransactionSigner` as a signatory\n    {\n        // @ts-expect-error You can not use a transaction signer here\n        ({}) as TransactionSigner satisfies OffchainMessageSignatorySigner;\n        // @ts-expect-error You can not use a transaction signer here\n        ({}) as TransactionModifyingSigner satisfies OffchainMessageSignatorySigner;\n        // @ts-expect-error You can not use a transaction signer here\n        ({}) as TransactionPartialSigner satisfies OffchainMessageSignatorySigner;\n        // @ts-expect-error You can not use a transaction signer here\n        ({}) as TransactionSendingSigner satisfies OffchainMessageSignatorySigner;\n    }\n}\n\n// [DESCRIBE] `getSignersFromOffchainMessage`.\n{\n    // It accepts `MessageSigners` among the `requiredSignatories`\n    {\n        getSignersFromOffchainMessage({\n            requiredSignatories: [null as unknown as MessageSigner],\n        });\n    }\n\n    // It accepts `MessagePartialSigners` among the `requiredSignatories`\n    {\n        getSignersFromOffchainMessage({\n            requiredSignatories: [null as unknown as MessagePartialSigner],\n        });\n    }\n\n    // It accepts `MessageModifyingSigners` among the `requiredSignatories`\n    {\n        getSignersFromOffchainMessage({\n            requiredSignatories: [null as unknown as MessageModifyingSigner],\n        });\n    }\n\n    // It accepts non signers among the `requiredSignatories`\n    {\n        getSignersFromOffchainMessage({\n            requiredSignatories: [{ address: 'non-signer' as Address }],\n        });\n    }\n\n    // It accepts a mix of signers and non signers among the `requiredSignatories`\n    {\n        getSignersFromOffchainMessage({\n            requiredSignatories: [\n                { address: 'non-signer' as Address },\n                null as unknown as MessageModifyingSigner,\n                null as unknown as MessagePartialSigner,\n                null as unknown as MessageSigner,\n            ],\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/sign-offchain-message-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { Address } from '@solana/addresses';\nimport {\n    FullySignedOffchainMessageEnvelope,\n    OffchainMessage,\n    OffchainMessageEnvelope,\n} from '@solana/offchain-messages';\n\nimport { MessageModifyingSigner } from '../message-modifying-signer';\nimport { MessagePartialSigner } from '../message-partial-signer';\nimport { MessageSigner } from '../message-signer';\nimport { partiallySignOffchainMessageWithSigners, signOffchainMessageWithSigners } from '../sign-offchain-message';\n\n// [DESCRIBE] `partiallySignOffchainMessageWithSigners`\n{\n    // It returns an offchain message envelope\n    {\n        const offchainMessage = null as unknown as OffchainMessage;\n        partiallySignOffchainMessageWithSigners(offchainMessage) satisfies Promise<Readonly<OffchainMessageEnvelope>>;\n    }\n\n    // It accepts an offchain message with only non-signers\n    {\n        const offchainMessage = null as unknown as Omit<OffchainMessage, 'requiredSignatories'>;\n        partiallySignOffchainMessageWithSigners({\n            ...offchainMessage,\n            requiredSignatories: [{ address: '123' as Address<'123'> }],\n        });\n    }\n\n    // It accepts an offchain message with a mix of signers and non-signers\n    {\n        const offchainMessage = null as unknown as Omit<OffchainMessage, 'requiredSignatories'>;\n        partiallySignOffchainMessageWithSigners({\n            ...offchainMessage,\n            requiredSignatories: [\n                { address: '123' as Address<'123'> },\n                {} as MessageModifyingSigner,\n                {} as MessagePartialSigner,\n                {} as MessageSigner,\n            ],\n        });\n    }\n\n    // It accepts an offchain message with only signers\n    {\n        const offchainMessage = null as unknown as Omit<OffchainMessage, 'requiredSignatories'>;\n        partiallySignOffchainMessageWithSigners({\n            ...offchainMessage,\n            requiredSignatories: [{} as MessageModifyingSigner, {} as MessagePartialSigner, {} as MessageSigner],\n        });\n    }\n}\n\n// [DESCRIBE] `signOffchainMessageWithSigners`\n{\n    // It returns a fully signed offchain-message envelope\n    {\n        const offchainMessage = null as unknown as OffchainMessage;\n        signOffchainMessageWithSigners(offchainMessage) satisfies Promise<\n            Readonly<FullySignedOffchainMessageEnvelope & OffchainMessageEnvelope>\n        >;\n    }\n\n    // It accepts an offchain message with only non-signers\n    {\n        const offchainMessage = null as unknown as Omit<OffchainMessage, 'requiredSignatories'>;\n        signOffchainMessageWithSigners({\n            ...offchainMessage,\n            requiredSignatories: [{ address: '123' as Address<'123'> }],\n        });\n    }\n\n    // It accepts an offchain message with a mix of signers and non-signers\n    {\n        const offchainMessage = null as unknown as Omit<OffchainMessage, 'requiredSignatories'>;\n        signOffchainMessageWithSigners({\n            ...offchainMessage,\n            requiredSignatories: [\n                { address: '123' as Address<'123'> },\n                {} as MessageModifyingSigner,\n                {} as MessagePartialSigner,\n                {} as MessageSigner,\n            ],\n        });\n    }\n\n    // It accepts an offchain message with only signers\n    {\n        const offchainMessage = null as unknown as Omit<OffchainMessage, 'requiredSignatories'>;\n        signOffchainMessageWithSigners({\n            ...offchainMessage,\n            requiredSignatories: [{} as MessageModifyingSigner, {} as MessagePartialSigner, {} as MessageSigner],\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/sign-transaction-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { SignatureBytes } from '@solana/keys';\nimport {\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithDurableNonceLifetime,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithinSizeLimit,\n    TransactionMessageWithLifetime,\n} from '@solana/transaction-messages';\nimport {\n    FullySignedTransaction,\n    Transaction,\n    TransactionWithinSizeLimit,\n    TransactionWithLifetime,\n} from '@solana/transactions';\n\nimport { TransactionMessageWithSigners } from '../account-signer-meta';\nimport {\n    partiallySignTransactionMessageWithSigners,\n    partiallySignTransactionWithSigners,\n    signAndSendTransactionMessageWithSigners,\n    signAndSendTransactionWithSigners,\n    signTransactionMessageWithSigners,\n    signTransactionWithSigners,\n} from '../sign-transaction';\nimport { TransactionModifyingSigner } from '../transaction-modifying-signer';\nimport { TransactionPartialSigner } from '../transaction-partial-signer';\nimport { TransactionSendingSigner } from '../transaction-sending-signer';\nimport { TransactionSigner } from '../transaction-signer';\nimport { TransactionMessageWithSingleSendingSigner } from '../transaction-with-single-sending-signer';\n\n{\n    // [partiallySignTransactionMessageWithSigners]: returns a transaction with a lifetime when the input message has a blockhash lifetime\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithBlockhashLifetime &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithSigners;\n    partiallySignTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [partiallySignTransactionMessageWithSigners]: returns a transaction with a lifetime when the input message has a durable nonce lifetime\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithDurableNonceLifetime &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithSigners;\n    partiallySignTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [partiallySignTransactionMessageWithSigners]: returns a transaction with an unknown lifetime when the input message has an unknown lifetime\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithLifetime &\n        TransactionMessageWithSigners;\n    partiallySignTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [partiallySignTransactionMessageWithSigners]: returns a transaction with a lifetime when the input message has no lifetime\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithSigners;\n    partiallySignTransactionMessageWithSigners(transactionMessage) satisfies Promise<Readonly<Transaction>>;\n    partiallySignTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [partiallySignTransactionMessageWithSigners]: returns a transaction with a `TransactionWithinSizeLimit` flag\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithinSizeLimit &\n        TransactionMessageWithLifetime &\n        TransactionMessageWithSigners;\n    partiallySignTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<Transaction & TransactionWithinSizeLimit>\n    >;\n}\n\n{\n    // [signTransactionMessageWithSigners]: returns a fully signed transaction with a lifetime when the input message has a blockhash lifetime\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithBlockhashLifetime &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithSigners;\n    signTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<FullySignedTransaction & Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [signTransactionMessageWithSigners]: returns a fully signed transaction with a lifetime when the input message has a durable nonce lifetime\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithDurableNonceLifetime &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithSigners;\n    signTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<FullySignedTransaction & Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [signTransactionMessageWithSigners]: returns a fully signed transaction with an unknown lifetime when the input message has an unknown lifetime\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithLifetime &\n        TransactionMessageWithSigners;\n    signTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<FullySignedTransaction & Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [signTransactionMessageWithSigners]: returns a transaction with a lifetime when the input message has no lifetime\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithSigners;\n    signTransactionMessageWithSigners(transactionMessage) satisfies Promise<Readonly<Transaction>>;\n    signTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [signTransactionMessageWithSigners]: returns a transaction with a `TransactionWithinSizeLimit` flag\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithinSizeLimit &\n        TransactionMessageWithLifetime &\n        TransactionMessageWithSigners;\n    signTransactionMessageWithSigners(transactionMessage) satisfies Promise<\n        Readonly<FullySignedTransaction & Transaction & TransactionWithinSizeLimit>\n    >;\n}\n\n{\n    // [signAndSendTransactionMessageWithSigners]: returns a signature\n    const transactionMessage = null as unknown as TransactionMessage &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithLifetime &\n        TransactionMessageWithSigners &\n        TransactionMessageWithSingleSendingSigner;\n    signAndSendTransactionMessageWithSigners(transactionMessage) satisfies Promise<SignatureBytes>;\n}\n\n{\n    // [partiallySignTransactionWithSigners]: returns a Transaction & TransactionWithinSizeLimit & TransactionWithLifetime\n    const signers = null as unknown as readonly (TransactionModifyingSigner | TransactionPartialSigner)[];\n    const transaction = null as unknown as Transaction;\n    partiallySignTransactionWithSigners(signers, transaction) satisfies Promise<\n        Readonly<Transaction & TransactionWithinSizeLimit & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [partiallySignTransactionWithSigners]: accepts a composite signer that is both a TransactionSendingSigner and a TransactionPartialSigner\n    const signers = null as unknown as readonly (TransactionPartialSigner & TransactionSendingSigner)[];\n    const transaction = null as unknown as Transaction;\n    partiallySignTransactionWithSigners(signers, transaction);\n}\n\n{\n    // [partiallySignTransactionWithSigners]: does not accept a TransactionSendingSigner on its own\n    const signers = null as unknown as readonly TransactionSendingSigner[];\n    const transaction = null as unknown as Transaction;\n    // @ts-expect-error TransactionSendingSigner is not assignable to TransactionModifyingSigner | TransactionPartialSigner\n    partiallySignTransactionWithSigners(signers, transaction);\n}\n\n{\n    // [signTransactionWithSigners]: returns a FullySignedTransaction & Transaction & TransactionWithLifetime\n    const signers = null as unknown as readonly (TransactionModifyingSigner | TransactionPartialSigner)[];\n    const transaction = null as unknown as Transaction;\n    signTransactionWithSigners(signers, transaction) satisfies Promise<\n        Readonly<FullySignedTransaction & Transaction & TransactionWithLifetime>\n    >;\n}\n\n{\n    // [signTransactionWithSigners]: accepts a composite signer that is both a TransactionSendingSigner and a TransactionPartialSigner\n    const signers = null as unknown as readonly (TransactionPartialSigner & TransactionSendingSigner)[];\n    const transaction = null as unknown as Transaction;\n    signTransactionWithSigners(signers, transaction);\n}\n\n{\n    // [signTransactionWithSigners]: does not accept a TransactionSendingSigner on its own\n    const signers = null as unknown as readonly TransactionSendingSigner[];\n    const transaction = null as unknown as Transaction;\n    // @ts-expect-error TransactionSendingSigner is not assignable to TransactionModifyingSigner | TransactionPartialSigner\n    signTransactionWithSigners(signers, transaction);\n}\n\n{\n    // [signAndSendTransactionWithSigners]: returns SignatureBytes\n    const signers = null as unknown as readonly TransactionSigner[];\n    const transaction = null as unknown as Transaction;\n    signAndSendTransactionWithSigners(signers, transaction) satisfies Promise<SignatureBytes>;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/transaction-modifying-signer-typetest.ts",
    "content": "import { address } from '@solana/addresses';\n\nimport {\n    assertIsTransactionModifyingSigner,\n    isTransactionModifyingSigner,\n    TransactionModifyingSigner,\n} from '../transaction-modifying-signer';\n\nconst modifyAndSignTransactions = () => {};\n\n{\n    // [isTransactionModifyingSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), modifyAndSignTransactions };\n    if (isTransactionModifyingSigner(potentialSigner)) {\n        potentialSigner satisfies TransactionModifyingSigner<'1'>;\n    }\n}\n\n{\n    // [assertIsTransactionModifyingSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), modifyAndSignTransactions };\n    assertIsTransactionModifyingSigner(potentialSigner);\n    potentialSigner satisfies TransactionModifyingSigner<'1'>;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/transaction-partial-signer-typetest.ts",
    "content": "import { address } from '@solana/addresses';\n\nimport {\n    assertIsTransactionPartialSigner,\n    isTransactionPartialSigner,\n    TransactionPartialSigner,\n} from '../transaction-partial-signer';\n\nconst signTransactions = () => {};\n\n{\n    // [isTransactionPartialSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signTransactions };\n    if (isTransactionPartialSigner(potentialSigner)) {\n        potentialSigner satisfies TransactionPartialSigner<'1'>;\n    }\n}\n\n{\n    // [assertIsTransactionPartialSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signTransactions };\n    assertIsTransactionPartialSigner(potentialSigner);\n    potentialSigner satisfies TransactionPartialSigner<'1'>;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/transaction-sending-signer-typetest.ts",
    "content": "import { address } from '@solana/addresses';\n\nimport {\n    assertIsTransactionSendingSigner,\n    isTransactionSendingSigner,\n    TransactionSendingSigner,\n} from '../transaction-sending-signer';\n\nconst signAndSendTransactions = () => {};\n\n{\n    // [isTransactionSendingSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signAndSendTransactions };\n    if (isTransactionSendingSigner(potentialSigner)) {\n        potentialSigner satisfies TransactionSendingSigner<'1'>;\n    }\n}\n\n{\n    // [assertIsTransactionSendingSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signAndSendTransactions };\n    assertIsTransactionSendingSigner(potentialSigner);\n    potentialSigner satisfies TransactionSendingSigner<'1'>;\n}\n"
  },
  {
    "path": "packages/signers/src/__typetests__/transaction-signer-typetest.ts",
    "content": "import { address } from '@solana/addresses';\n\nimport { assertIsTransactionSigner, isTransactionSigner, TransactionSigner } from '../transaction-signer';\n\nconst signTransactions = () => {};\n\n{\n    // [isTransactionSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signTransactions };\n    if (isTransactionSigner(potentialSigner)) {\n        potentialSigner satisfies TransactionSigner<'1'>;\n    }\n}\n\n{\n    // [assertIsTransactionSigner]: It keeps track of the address type parameter when the address is a valid Address.\n    const potentialSigner = { address: address('1'), signTransactions };\n    assertIsTransactionSigner(potentialSigner);\n    potentialSigner satisfies TransactionSigner<'1'>;\n}\n"
  },
  {
    "path": "packages/signers/src/account-signer-meta.ts",
    "content": "import { AccountLookupMeta, AccountMeta, AccountRole, Instruction } from '@solana/instructions';\nimport { TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport { deduplicateSigners } from './deduplicate-signers';\nimport { TransactionMessageWithFeePayerSigner } from './fee-payer-signer';\nimport { isTransactionSigner, TransactionSigner } from './transaction-signer';\n\n/**\n * An extension of the {@link AccountMeta} type that allows us to store {@link TransactionSigner | TransactionSigners} inside it.\n *\n * Note that, because this type represents a signer, it must use one the following two roles:\n * - {@link AccountRole.READONLY_SIGNER}\n * - {@link AccountRole.WRITABLE_SIGNER}\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TSigner - Optionally provide a narrower type for the {@link TransactionSigner} to use within the account meta.\n *\n * @interface\n *\n * @example\n * ```ts\n * import { AccountRole } from '@solana/instructions';\n * import { generateKeyPairSigner, AccountSignerMeta } from '@solana/signers';\n *\n * const signer = await generateKeyPairSigner();\n * const account: AccountSignerMeta = {\n *     address: signer.address,\n *     role: AccountRole.READONLY_SIGNER,\n *     signer,\n * };\n * ```\n */\nexport interface AccountSignerMeta<\n    TAddress extends string = string,\n    TSigner extends TransactionSigner<TAddress> = TransactionSigner<TAddress>,\n> extends AccountMeta<TAddress> {\n    readonly role: AccountRole.READONLY_SIGNER | AccountRole.WRITABLE_SIGNER;\n    readonly signer: TSigner;\n}\n\n/**\n * A union type that supports base account metas as well as {@link AccountSignerMeta | signer account metas}.\n */\ntype AccountMetaWithSigner<TSigner extends TransactionSigner = TransactionSigner> =\n    | AccountLookupMeta\n    | AccountMeta\n    | AccountSignerMeta<string, TSigner>;\n\n/**\n * Composable type that allows {@link AccountSignerMeta | AccountSignerMetas} to be used inside the instruction's `accounts` array\n *\n * @typeParam TSigner - Optionally provide a narrower type for {@link TransactionSigner | TransactionSigners}.\n * @typeParam TAccounts - Optionally provide a narrower type for the account metas.\n *\n * @interface\n *\n * @example\n * ```ts\n * import { AccountRole, Instruction } from '@solana/instructions';\n * import { generateKeyPairSigner, InstructionWithSigners } from '@solana/signers';\n *\n * const [authority, buffer] = await Promise.all([\n *     generateKeyPairSigner(),\n *     generateKeyPairSigner(),\n * ]);\n * const instruction: Instruction & InstructionWithSigners = {\n *     programAddress: address('1234..5678'),\n *     accounts: [\n *         // The authority is a signer account.\n *         {\n *             address: authority.address,\n *             role: AccountRole.READONLY_SIGNER,\n *             signer: authority,\n *         },\n *         // The buffer is a writable account.\n *         { address: buffer.address, role: AccountRole.WRITABLE },\n *     ],\n * };\n * ```\n */\nexport type InstructionWithSigners<\n    TSigner extends TransactionSigner = TransactionSigner,\n    TAccounts extends readonly AccountMetaWithSigner<TSigner>[] = readonly AccountMetaWithSigner<TSigner>[],\n> = Pick<Instruction<string, TAccounts>, 'accounts'>;\n\n/**\n * A {@link TransactionMessage} type extension that accept {@link TransactionSigner | TransactionSigners}.\n *\n * Namely, it allows:\n * - a {@link TransactionSigner} to be used as the fee payer and\n * - {@link InstructionWithSigners} to be used in its instructions.\n *\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TSigner - Optionally provide a narrower type for {@link TransactionSigner | TransactionSigners}.\n * @typeParam TAccounts - Optionally provide a narrower type for the account metas.\n *\n * @example\n * ```ts\n * import { Instruction } from '@solana/instructions';\n * import { TransactionMessage } from '@solana/transaction-messages';\n * import { generateKeyPairSigner, InstructionWithSigners, TransactionMessageWithSigners } from '@solana/signers';\n *\n * const signer = await generateKeyPairSigner();\n * const firstInstruction: Instruction = { ... };\n * const secondInstruction: InstructionWithSigners = { ... };\n * const transactionMessage: TransactionMessage & TransactionMessageWithSigners = {\n *     feePayer: signer,\n *     instructions: [firstInstruction, secondInstruction],\n * }\n * ```\n */\nexport type TransactionMessageWithSigners<\n    TAddress extends string = string,\n    TSigner extends TransactionSigner<TAddress> = TransactionSigner<TAddress>,\n    TAccounts extends readonly AccountMetaWithSigner<TSigner>[] = readonly AccountMetaWithSigner<TSigner>[],\n> = Partial<\n    Pick<TransactionMessageWithFeePayer<TAddress> | TransactionMessageWithFeePayerSigner<TAddress, TSigner>, 'feePayer'>\n> &\n    Readonly<{ instructions: readonly (Instruction & InstructionWithSigners<TSigner, TAccounts>)[] }>;\n\n/**\n * Extracts and deduplicates all {@link TransactionSigner | TransactionSigners} stored\n * inside the account metas of an {@link InstructionWithSigners | instruction}.\n *\n * Any extracted signers that share the same {@link Address} will be de-duplicated.\n *\n * @typeParam TSigner - Optionally provide a narrower type for {@link TransactionSigner | TransactionSigners}.\n *\n * @example\n * ```ts\n * import { InstructionWithSigners, getSignersFromInstruction } from '@solana/signers';\n *\n * const signerA = { address: address('1111..1111'), signTransactions: async () => {} };\n * const signerB = { address: address('2222..2222'), signTransactions: async () => {} };\n * const instructionWithSigners: InstructionWithSigners = {\n *     accounts: [\n *         { address: signerA.address, signer: signerA, ... },\n *         { address: signerB.address, signer: signerB, ... },\n *         { address: signerA.address, signer: signerA, ... },\n *     ],\n * };\n *\n * const instructionSigners = getSignersFromInstruction(instructionWithSigners);\n * // ^ [signerA, signerB]\n * ```\n */\nexport function getSignersFromInstruction<TSigner extends TransactionSigner = TransactionSigner>(\n    instruction: InstructionWithSigners<TSigner>,\n): readonly TSigner[] {\n    return deduplicateSigners(\n        (instruction.accounts ?? []).flatMap(account => ('signer' in account ? account.signer : [])),\n    );\n}\n\n/**\n * Extracts and deduplicates all {@link TransactionSigner | TransactionSigners} stored\n * inside a given {@link TransactionMessageWithSigners | transaction message}.\n *\n * This includes any {@link TransactionSigner | TransactionSigners} stored\n * as the fee payer or in the instructions of the transaction message.\n *\n * Any extracted signers that share the same {@link Address} will be de-duplicated.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TSigner - Optionally provide a narrower type for {@link TransactionSigner | TransactionSigners}.\n * @typeParam TTransactionMessage - The inferred type of the transaction message provided.\n *\n * @example\n * ```ts\n * import { Instruction } from '@solana/instructions';\n * import { InstructionWithSigners, TransactionMessageWithSigners, getSignersFromTransactionMessage } from '@solana/signers';\n *\n * const signerA = { address: address('1111..1111'), signTransactions: async () => {} };\n * const signerB = { address: address('2222..2222'), signTransactions: async () => {} };\n * const firstInstruction: Instruction & InstructionWithSigners = {\n *     programAddress: address('1234..5678'),\n *     accounts: [{ address: signerA.address, signer: signerA, ... }],\n * };\n * const secondInstruction: Instruction & InstructionWithSigners = {\n *     programAddress: address('1234..5678'),\n *     accounts: [{ address: signerB.address, signer: signerB, ... }],\n * };\n * const transactionMessage: TransactionMessageWithSigners = {\n *     feePayer: signerA,\n *     instructions: [firstInstruction, secondInstruction],\n * }\n *\n * const transactionSigners = getSignersFromTransactionMessage(transactionMessage);\n * // ^ [signerA, signerB]\n * ```\n */\nexport function getSignersFromTransactionMessage<\n    TAddress extends string = string,\n    TSigner extends TransactionSigner<TAddress> = TransactionSigner<TAddress>,\n    TTransactionMessage extends TransactionMessageWithSigners<TAddress, TSigner> = TransactionMessageWithSigners<\n        TAddress,\n        TSigner\n    >,\n>(transaction: TTransactionMessage): readonly TSigner[] {\n    return deduplicateSigners([\n        ...(transaction.feePayer && isTransactionSigner(transaction.feePayer) ? [transaction.feePayer as TSigner] : []),\n        ...transaction.instructions.flatMap(getSignersFromInstruction),\n    ]);\n}\n"
  },
  {
    "path": "packages/signers/src/add-signers.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Instruction, isSignerRole } from '@solana/instructions';\nimport { TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport { AccountSignerMeta, InstructionWithSigners, TransactionMessageWithSigners } from './account-signer-meta';\nimport { deduplicateSigners } from './deduplicate-signers';\nimport { isTransactionSigner, TransactionSigner } from './transaction-signer';\n\n/**\n * Attaches the provided {@link TransactionSigner | TransactionSigners} to the\n * account metas of an instruction when applicable.\n *\n * For an account meta to match a provided signer it:\n * - Must have a signer role ({@link AccountRole.READONLY_SIGNER} or {@link AccountRole.WRITABLE_SIGNER}).\n * - Must have the same address as the provided signer.\n * - Must not have an attached signer already.\n *\n * @typeParam TInstruction - The inferred type of the instruction provided.\n *\n * @example\n * ```ts\n * import { AccountRole, Instruction } from '@solana/instructions';\n * import { addSignersToInstruction, TransactionSigner } from '@solana/signers';\n *\n * const instruction: Instruction = {\n *     accounts: [\n *         { address: '1111' as Address, role: AccountRole.READONLY_SIGNER },\n *         { address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER },\n *     ],\n *     // ...\n * };\n *\n * const signerA: TransactionSigner<'1111'>;\n * const signerB: TransactionSigner<'2222'>;\n * const instructionWithSigners = addSignersToInstruction(\n *     [signerA, signerB],\n *     instruction\n * );\n *\n * // instructionWithSigners.accounts[0].signer === signerA\n * // instructionWithSigners.accounts[1].signer === signerB\n * ```\n */\nexport function addSignersToInstruction<TInstruction extends Instruction>(\n    signers: TransactionSigner[],\n    instruction: TInstruction | (InstructionWithSigners & TInstruction),\n): InstructionWithSigners & TInstruction {\n    if (!instruction.accounts || instruction.accounts.length === 0) {\n        return instruction as InstructionWithSigners & TInstruction;\n    }\n\n    const signerByAddress = new Map(deduplicateSigners(signers).map(signer => [signer.address, signer]));\n    return Object.freeze({\n        ...instruction,\n        accounts: instruction.accounts.map(account => {\n            const signer = signerByAddress.get(account.address);\n            if (!isSignerRole(account.role) || 'signer' in account || !signer) {\n                return account;\n            }\n            return Object.freeze({ ...account, signer } as AccountSignerMeta);\n        }),\n    });\n}\n\n/**\n * Attaches the provided {@link TransactionSigner | TransactionSigners} to the\n * account metas of all instructions inside a transaction message and/or\n * the transaction message fee payer, when applicable.\n *\n * For an account meta to match a provided signer it:\n * - Must have a signer role ({@link AccountRole.READONLY_SIGNER} or {@link AccountRole.WRITABLE_SIGNER}).\n * - Must have the same address as the provided signer.\n * - Must not have an attached signer already.\n *\n * @typeParam TTransactionMessage - The inferred type of the transaction message provided.\n *\n * @example\n * ```ts\n * import { AccountRole, Instruction } from '@solana/instructions';\n * import { TransactionMessage } from '@solana/transaction-messages';\n * import { addSignersToTransactionMessage, TransactionSigner } from '@solana/signers';\n *\n * const instructionA: Instruction = {\n *     accounts: [{ address: '1111' as Address, role: AccountRole.READONLY_SIGNER }],\n *     // ...\n * };\n * const instructionB: Instruction = {\n *     accounts: [{ address: '2222' as Address, role: AccountRole.WRITABLE_SIGNER }],\n *     // ...\n * };\n * const transactionMessage: TransactionMessage = {\n *     instructions: [instructionA, instructionB],\n *     // ...\n * }\n *\n * const signerA: TransactionSigner<'1111'>;\n * const signerB: TransactionSigner<'2222'>;\n * const transactionMessageWithSigners = addSignersToTransactionMessage(\n *     [signerA, signerB],\n *     transactionMessage\n * );\n *\n * // transactionMessageWithSigners.instructions[0].accounts[0].signer === signerA\n * // transactionMessageWithSigners.instructions[1].accounts[0].signer === signerB\n * ```\n */\nexport function addSignersToTransactionMessage<\n    TTransactionMessage extends Readonly<{ instructions: readonly Instruction[] }>,\n>(\n    signers: TransactionSigner[],\n    transactionMessage: TTransactionMessage,\n): TransactionMessageWithSigners & TTransactionMessage {\n    const feePayerSigner = hasAddressOnlyFeePayer(transactionMessage)\n        ? signers.find(signer => signer.address === transactionMessage.feePayer.address)\n        : undefined;\n\n    if (!feePayerSigner && transactionMessage.instructions.length === 0) {\n        return transactionMessage as TransactionMessageWithSigners & TTransactionMessage;\n    }\n\n    return Object.freeze({\n        ...transactionMessage,\n        ...(feePayerSigner ? { feePayer: feePayerSigner } : null),\n        instructions: transactionMessage.instructions.map(instruction => addSignersToInstruction(signers, instruction)),\n    }) as TransactionMessageWithSigners & TTransactionMessage;\n}\n\nfunction hasAddressOnlyFeePayer(\n    message: Partial<TransactionMessageWithFeePayer> & Readonly<{ instructions: readonly Instruction[] }>,\n): message is Readonly<{ instructions: readonly Instruction[] }> & { feePayer: { address: Address } } {\n    return (\n        !!message &&\n        'feePayer' in message &&\n        !!message.feePayer &&\n        typeof message.feePayer.address === 'string' &&\n        !isTransactionSigner(message.feePayer)\n    );\n}\n"
  },
  {
    "path": "packages/signers/src/deduplicate-signers.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS, SolanaError } from '@solana/errors';\n\nimport { MessageSigner } from './message-signer';\nimport { TransactionSigner } from './transaction-signer';\n\n/**\n * Removes all duplicated {@link MessageSigner | MessageSigners} and\n * {@link TransactionSigner | TransactionSigners} from a provided array\n * by comparing their {@link Address | addresses}.\n *\n * @internal\n */\nexport function deduplicateSigners<TSigner extends MessageSigner | TransactionSigner>(\n    signers: readonly TSigner[],\n): readonly TSigner[] {\n    const deduplicated: Record<Address, TSigner> = {};\n    signers.forEach(signer => {\n        if (!deduplicated[signer.address]) {\n            deduplicated[signer.address] = signer;\n        } else if (!signersAreEquivalent(deduplicated[signer.address], signer)) {\n            throw new SolanaError(SOLANA_ERROR__SIGNER__ADDRESS_CANNOT_HAVE_MULTIPLE_SIGNERS, {\n                address: signer.address,\n            });\n        }\n    });\n    return Object.values(deduplicated);\n}\n\nfunction signersAreEquivalent(a: MessageSigner | TransactionSigner, b: MessageSigner | TransactionSigner): boolean {\n    if (a === b) return true;\n    const aKeys = Object.getOwnPropertyNames(a);\n    const bKeys = Object.getOwnPropertyNames(b);\n    if (aKeys.length !== bKeys.length) return false;\n    return aKeys.every(key => {\n        if (!(key in b)) return false;\n        const aVal = (a as Record<string, unknown>)[key];\n        const bVal = (b as Record<string, unknown>)[key];\n        if (typeof aVal === 'function' && typeof bVal === 'function') {\n            return aVal.toString() === bVal.toString();\n        }\n        return aVal === bVal;\n    });\n}\n"
  },
  {
    "path": "packages/signers/src/fee-payer-signer.ts",
    "content": "import { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport { TransactionSigner } from './transaction-signer';\n\n/**\n * Alternative to {@link TransactionMessageWithFeePayer} that uses a {@link TransactionSigner} for the fee payer.\n *\n * @typeParam TAddress - Supply a string literal to define a fee payer having a particular address.\n * @typeParam TSigner - Optionally provide a narrower type for the {@link TransactionSigner}.\n *\n * @example\n * ```ts\n * import { TransactionMessage } from '@solana/transaction-messages';\n * import { generateKeyPairSigner, TransactionMessageWithFeePayerSigner } from '@solana/signers';\n *\n * const transactionMessage: TransactionMessage & TransactionMessageWithFeePayerSigner = {\n *     feePayer: await generateKeyPairSigner(),\n *     instructions: [],\n *     version: 0,\n * };\n * ```\n */\nexport interface TransactionMessageWithFeePayerSigner<\n    TAddress extends string = string,\n    TSigner extends TransactionSigner<TAddress> = TransactionSigner<TAddress>,\n> {\n    readonly feePayer: TSigner;\n}\n\n/**\n * A helper type to exclude the fee payer from a transaction message.\n */\ntype ExcludeTransactionMessageFeePayer<TTransactionMessage extends TransactionMessage> =\n    TTransactionMessage extends unknown ? Omit<TTransactionMessage, 'feePayer'> : never;\n\n/**\n * Sets the fee payer of a {@link TransactionMessage | transaction message}\n * using a {@link TransactionSigner}.\n *\n * @typeParam TFeePayerAddress - Supply a string literal to define a fee payer having a particular address.\n * @typeParam TTransactionMessage - The inferred type of the transaction message provided.\n *\n * @example\n * ```ts\n * import { pipe } from '@solana/functional';\n * import { generateKeyPairSigner, setTransactionMessageFeePayerSigner } from '@solana/signers';\n * import { createTransactionMessage } from '@solana/transaction-messages';\n *\n * const feePayer = await generateKeyPairSigner();\n * const transactionMessage = pipe(\n *     createTransactionMessage({ version: 0 }),\n *     message => setTransactionMessageFeePayerSigner(signer, message),\n * );\n * ```\n */\nexport function setTransactionMessageFeePayerSigner<\n    TFeePayerAddress extends string,\n    TTransactionMessage extends Partial<TransactionMessageWithFeePayer | TransactionMessageWithFeePayerSigner> &\n        TransactionMessage,\n>(\n    feePayer: TransactionSigner<TFeePayerAddress>,\n    transactionMessage: TTransactionMessage,\n): ExcludeTransactionMessageFeePayer<TTransactionMessage> & TransactionMessageWithFeePayerSigner<TFeePayerAddress> {\n    Object.freeze(feePayer);\n    const out = { ...transactionMessage, feePayer };\n    Object.freeze(out);\n    return out as ExcludeTransactionMessageFeePayer<TTransactionMessage> &\n        TransactionMessageWithFeePayerSigner<TFeePayerAddress>;\n}\n"
  },
  {
    "path": "packages/signers/src/grind-keypair-signer.ts",
    "content": "import { grindKeyPairs, GrindKeyPairsConfig } from '@solana/keys';\n\nimport { createSignerFromKeyPair, KeyPairSigner } from './keypair-signer';\n\n/**\n * Generates multiple {@link KeyPairSigner | KeyPairSigners} whose addresses satisfy the\n * provided `matches` criterion. Internally, this calls\n * {@link grindKeyPairs} from `@solana/keys` and wraps each resulting\n * {@link CryptoKeyPair} in a {@link KeyPairSigner}.\n *\n * @param config - See {@link GrindKeyPairsConfig}.\n *\n * @example\n * Find four signers whose address starts with `anza`:\n * ```ts\n * import { grindKeyPairSigners } from '@solana/signers';\n *\n * const signers = await grindKeyPairSigners({ matches: /^anza/, amount: 4 });\n * ```\n *\n * @see {@link grindKeyPairSigner}\n * @see {@link grindKeyPairs}\n */\nexport async function grindKeyPairSigners(config: GrindKeyPairsConfig): Promise<KeyPairSigner[]> {\n    const keyPairs = await grindKeyPairs(config);\n    return await Promise.all(keyPairs.map(createSignerFromKeyPair));\n}\n\n/**\n * Generates a single {@link KeyPairSigner} whose address satisfies the\n * provided `matches` criterion. This is the main entry point for mining\n * vanity signers: the function keeps generating fresh key pairs in parallel\n * batches until one of them matches, and then wraps the result in a\n * {@link KeyPairSigner}.\n *\n * When `matches` is a {@link RegExp}, its literal characters (outside of\n * escape sequences, character classes, quantifiers, and groups) are\n * validated against the base58 alphabet up front. This catches common typos\n * such as `/^ab0/` (`0` is not in the base58 alphabet) before any key is\n * generated, preventing a guaranteed infinite loop.\n *\n * When `matches` is a function, it is used as-is with no validation — use\n * this form when you need arbitrary matching logic that cannot be expressed\n * as a regex. Be mindful that if the function can never return `true`, the\n * grind loop will never terminate unless you supply an {@link AbortSignal}.\n *\n * @param config - See {@link GrindKeyPairsConfig}. The `amount` field is\n * omitted because this function always returns a single signer.\n *\n * @returns A promise that resolves to a {@link KeyPairSigner} whose\n * base58-encoded address satisfies the matcher.\n *\n * @throws {@link SOLANA_ERROR__KEYS__INVALID_BASE58_IN_GRIND_REGEX} when the\n * provided regex contains a literal character that is not in the base58\n * alphabet.\n *\n * @throws The `AbortSignal`'s reason when the supplied `abortSignal` is\n * fired (either before the function is called or during the grind loop).\n *\n * @example\n * Mine a vanity signer whose address starts with `anza`:\n * ```ts\n * import { grindKeyPairSigner } from '@solana/signers';\n *\n * const signer = await grindKeyPairSigner({ matches: /^anza/ });\n * ```\n *\n * @example\n * Use the `i` flag for case-insensitive matching:\n * ```ts\n * import { grindKeyPairSigner } from '@solana/signers';\n *\n * const signer = await grindKeyPairSigner({ matches: /^anza/i });\n * ```\n *\n * @example\n * Use a predicate function for arbitrary matching logic:\n * ```ts\n * import { grindKeyPairSigner } from '@solana/signers';\n *\n * const signer = await grindKeyPairSigner({\n *     matches: address => address.startsWith('anza') && address.length === 44,\n * });\n * ```\n *\n * @example\n * Cap the grind at 60 seconds using\n * [`AbortSignal.timeout()`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static):\n * ```ts\n * import { grindKeyPairSigner } from '@solana/signers';\n *\n * const signer = await grindKeyPairSigner({\n *     matches: /^anza/,\n *     abortSignal: AbortSignal.timeout(60_000),\n * });\n * ```\n *\n * @see {@link grindKeyPairSigners}\n * @see {@link GrindKeyPairsConfig}\n */\nexport async function grindKeyPairSigner(config: Omit<GrindKeyPairsConfig, 'amount'>): Promise<KeyPairSigner> {\n    const [signer] = await grindKeyPairSigners({ ...config, amount: 1 });\n    return signer;\n}\n"
  },
  {
    "path": "packages/signers/src/index.ts",
    "content": "/**\n * This package provides an abstraction layer over signing messages and transactions in Solana.\n * It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * You can think of signers as an abstract way to sign messages and transactions.\n * This could be using a {@link CryptoKeyPair}, a wallet adapter in the browser,\n * a Noop signer for testing purposes, or anything you want.\n * Here's an example using a {@link CryptoKeyPair} signer:\n *\n * @example\n * ```ts\n * import { pipe } from '@solana/functional';\n * import { generateKeyPairSigner } from '@solana/signers';\n * import { createTransactionMessage } from '@solana/transaction-messages';\n * import { compileTransaction } from '@solana/transactions';\n *\n * // Generate a key pair signer.\n * const mySigner = await generateKeyPairSigner();\n * mySigner.address; // Address;\n *\n * // Sign one or multiple messages.\n * const myMessage = createSignableMessage('Hello world!');\n * const [messageSignatures] = await mySigner.signMessages([myMessage]);\n *\n * // Sign one or multiple transaction messages.\n * const myTransactionMessage = pipe(\n *     createTransactionMessage({ version: 0 }),\n *     // Add instructions, fee payer, lifetime, etc.\n * );\n * const myTransaction = compileTransaction(myTransactionMessage);\n * const [transactionSignatures] = await mySigner.signTransactions([myTransaction]);\n * ```\n *\n * As you can see, this provides a consistent API regardless of how things are being signed\n * behind the scenes. If tomorrow we need to use a browser wallet instead, we'd simply\n * need to swap the {@link generateKeyPairSigner} function with the signer factory of our choice.\n *\n * @remarks\n * This package offers a total of five different types of signers that may be used in combination when applicable.\n * Three of them allow us to sign transactions whereas the other two are used for regular message signing.\n *\n * They are separated into three categories:\n *\n * - **Partial signers**: Given a message or transaction, provide one or more signatures for it.\n *   These signers are not able to modify the given data which allows us to run many of them in parallel.\n * - **Modifying signers**: Can choose to modify a message or transaction before signing it with zero\n *   or more private keys. Because modifying a message or transaction invalidates any pre-existing\n *   signatures over it, modifying signers must do their work before any other signer.\n * - **Sending signers**: Given a transaction, signs it and sends it immediately to the blockchain.\n *   When applicable, the signer may also decide to modify the provided transaction before signing it.\n *   This interface accommodates wallets that simply cannot sign a transaction without sending it at the same time.\n *   This category of signers does not apply to regular messages.\n *\n * Thus, we end up with the following interfaces.\n *\n * |                     | Partial signers            | Modifying signers            | Sending signers            |\n * | ------------------- | -------------------------- | ---------------------------- | -------------------------- |\n * | {@link TransactionSigner} | {@link TransactionPartialSigner} | {@link TransactionModifyingSigner} | {@link TransactionSendingSigner} |\n * | {@link MessageSigner}     | {@link MessagePartialSigner}     | {@link MessageModifyingSigner}     | N/A                        |\n *\n * This package also provides the following concrete signer implementations:\n *\n * - The {@link KeyPairSigner} which uses a {@link CryptoKeyPair} to sign messages and transactions.\n * - The {@link NoopSigner} which does not sign anything and is mostly useful for testing purposes\n *   or for indicating that an account will be signed in a different environment (e.g. sending a\n *   transaction to your server so it can sign it).\n *\n * Additionally, this package allows {@link TransactionSigner | TransactionSigners} to be stored\n * inside the account meta of an instruction. This allows us to create instructions by passing\n * around signers instead of addresses when applicable which, in turn, allows us to\n * {@link signTransactionMessageWithSigners | sign an entire transaction automatically}\n * without having to scan through its instructions to find the required signers.\n *\n * @packageDocumentation\n */\nexport * from './account-signer-meta';\nexport * from './add-signers';\nexport * from './fee-payer-signer';\nexport * from './grind-keypair-signer';\nexport * from './keypair-signer';\nexport * from './message-modifying-signer';\nexport * from './message-partial-signer';\nexport * from './message-signer';\nexport * from './noop-signer';\nexport * from './offchain-message-signer';\nexport * from './sign-offchain-message';\nexport * from './sign-transaction';\nexport * from './signable-message';\nexport * from './transaction-modifying-signer';\nexport * from './transaction-partial-signer';\nexport * from './transaction-sending-signer';\nexport * from './transaction-signer';\nexport * from './transaction-with-single-sending-signer';\nexport * from './types';\nexport * from './write-keypair-signer';\n"
  },
  {
    "path": "packages/signers/src/keypair-signer.ts",
    "content": "import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER, SolanaError } from '@solana/errors';\nimport { createKeyPairFromBytes, createKeyPairFromPrivateKeyBytes, generateKeyPair, signBytes } from '@solana/keys';\nimport { partiallySignTransaction } from '@solana/transactions';\n\nimport { isMessagePartialSigner, MessagePartialSigner } from './message-partial-signer';\nimport { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer';\n\n/**\n * Defines a signer that uses a {@link CryptoKeyPair} to sign messages and transactions.\n *\n * It implements both the {@link MessagePartialSigner} and {@link TransactionPartialSigner}\n * interfaces and keeps track of the {@link CryptoKeyPair} instance used\n * to sign messages and transactions.\n *\n * @typeParam TAddress - Supply a string literal to define a signer having a particular address.\n *\n * @example\n * ```ts\n * import { generateKeyPairSigner } from '@solana/signers';\n *\n * const signer = generateKeyPairSigner();\n * signer.address; // Address;\n * signer.keyPair; // CryptoKeyPair;\n * const [messageSignatures] = await signer.signMessages([message]);\n * const [transactionSignatures] = await signer.signTransactions([transaction]);\n * ```\n *\n * @see {@link generateKeyPairSigner}\n * @see {@link createSignerFromKeyPair}\n * @see {@link createKeyPairSignerFromBytes}\n * @see {@link createKeyPairSignerFromPrivateKeyBytes}\n * @see {@link isKeyPairSigner}\n * @see {@link assertIsKeyPairSigner}\n */\nexport type KeyPairSigner<TAddress extends string = string> = MessagePartialSigner<TAddress> &\n    TransactionPartialSigner<TAddress> & { keyPair: CryptoKeyPair };\n\n/**\n * Checks whether the provided value implements the {@link KeyPairSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { generateKeyPairSigner, isKeyPairSigner } from '@solana/signers';\n *\n * const signer = await generateKeyPairSigner();\n * isKeyPairSigner(signer); // true\n * isKeyPairSigner({ address: address('1234..5678') }); // false\n * ```\n */\nexport function isKeyPairSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): value is KeyPairSigner<TAddress> {\n    return (\n        'keyPair' in value &&\n        typeof value.keyPair === 'object' &&\n        isMessagePartialSigner(value) &&\n        isTransactionPartialSigner(value)\n    );\n}\n\n/**\n * Asserts that the provided value implements the {@link KeyPairSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { generateKeyPairSigner, assertIsKeyPairSigner } from '@solana/signers';\n *\n * const signer = await generateKeyPairSigner();\n * assertIsKeyPairSigner(signer); // void\n * assertIsKeyPairSigner({ address: address('1234..5678') }); // Throws an error.\n * ```\n */\nexport function assertIsKeyPairSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): asserts value is KeyPairSigner<TAddress> {\n    if (!isKeyPairSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_KEY_PAIR_SIGNER, {\n            address: value.address,\n        });\n    }\n}\n\n/**\n * Creates a {@link KeyPairSigner} from a provided {@link CryptoKeyPair}.\n *\n * The {@link MessagePartialSigner#signMessages | signMessages} and\n * {@link TransactionPartialSigner#signTransactions | signTransactions}\n * functions of the returned signer will use the private key of the provided\n * key pair to sign messages and transactions.\n *\n * Note that both the {@link MessagePartialSigner#signMessages | signMessages} and\n * {@link TransactionPartialSigner#signTransactions | signTransactions} implementations\n * are parallelized, meaning that they will sign all provided messages and transactions in parallel.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { createSignerFromKeyPair, KeyPairSigner } from '@solana/signers';\n *\n * const keyPair: CryptoKeyPair = await generateKeyPair();\n * const signer: KeyPairSigner = await createSignerFromKeyPair(keyPair);\n * ```\n */\nexport async function createSignerFromKeyPair(keyPair: CryptoKeyPair): Promise<KeyPairSigner> {\n    const address = await getAddressFromPublicKey(keyPair.publicKey);\n    const out: KeyPairSigner = {\n        address,\n        keyPair,\n        signMessages: messages =>\n            Promise.all(\n                messages.map(async message =>\n                    Object.freeze({ [address]: await signBytes(keyPair.privateKey, message.content) }),\n                ),\n            ),\n        signTransactions: transactions =>\n            Promise.all(\n                transactions.map(async transaction => {\n                    const signedTransaction = await partiallySignTransaction([keyPair], transaction);\n                    // we know that the address has signed `signedTransaction` because it comes from the keypair\n                    return Object.freeze({ [address]: signedTransaction.signatures[address]! });\n                }),\n            ),\n    };\n\n    return Object.freeze(out);\n}\n\n/**\n * Generates a signer capable of signing messages and transactions by generating\n * a {@link CryptoKeyPair} and creating a {@link KeyPairSigner} from it.\n *\n * @param extractable Setting this to `true` makes it possible to extract the bytes of the private\n * key using the [`crypto.subtle.exportKey()`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)\n * API. Defaults to `false`, which prevents the bytes of the private key from being visible to JS.\n *\n * @example\n * ```ts\n * import { generateKeyPairSigner } from '@solana/signers';\n *\n * const signer = await generateKeyPairSigner();\n * ```\n *\n * @see {@link createSignerFromKeyPair}\n */\nexport async function generateKeyPairSigner(extractable: boolean = false): Promise<KeyPairSigner> {\n    return await createSignerFromKeyPair(await generateKeyPair(extractable));\n}\n\n/**\n * Creates a new {@link KeyPairSigner} from a 64-bytes `Uint8Array` secret key (private key and public key).\n *\n * @example\n * ```ts\n * import fs from 'fs';\n * import { createKeyPairSignerFromBytes } from '@solana/signers';\n *\n * // Get bytes from local keypair file.\n * const keypairFile = fs.readFileSync('~/.config/solana/id.json');\n * const keypairBytes = new Uint8Array(JSON.parse(keypairFile.toString()));\n *\n * // Create a KeyPairSigner from the bytes.\n * const signer = await createKeyPairSignerFromBytes(keypairBytes);\n * ```\n *\n * @see {@link createKeyPairSignerFromPrivateKeyBytes} if you only have the 32-bytes private key instead.\n * @see {@link writeKeyPairSigner} — the inverse helper that persists a signer's key pair to\n * disk in the same format.\n */\nexport async function createKeyPairSignerFromBytes(\n    bytes: ReadonlyUint8Array,\n    extractable?: boolean,\n): Promise<KeyPairSigner> {\n    return await createSignerFromKeyPair(await createKeyPairFromBytes(bytes, extractable));\n}\n\n/**\n * Creates a new {@link KeyPairSigner} from a 32-bytes `Uint8Array` private key.\n *\n * @example\n * ```ts\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { createKeyPairSignerFromPrivateKeyBytes } from '@solana/signers';\n *\n * const message = getUtf8Encoder().encode('Hello, World!');\n * const seed = new Uint8Array(await crypto.subtle.digest('SHA-256', message));\n *\n * const derivedSigner = await createKeyPairSignerFromPrivateKeyBytes(seed);\n * ```\n *\n * @see {@link createKeyPairSignerFromBytes} if you have the 64-bytes secret key instead (private key and public key).\n */\nexport async function createKeyPairSignerFromPrivateKeyBytes(\n    bytes: ReadonlyUint8Array,\n    extractable?: boolean,\n): Promise<KeyPairSigner> {\n    return await createSignerFromKeyPair(await createKeyPairFromPrivateKeyBytes(bytes, extractable));\n}\n"
  },
  {
    "path": "packages/signers/src/message-modifying-signer.ts",
    "content": "import { Address, isAddress } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER, SolanaError } from '@solana/errors';\n\nimport { SignableMessage } from './signable-message';\nimport { BaseSignerConfig } from './types';\n\n/**\n * The configuration to optionally provide when calling the\n * {@link MessageModifyingSigner#modifyAndSignMessages | modifyAndSignMessages} method.\n *\n * @see {@link BaseSignerConfig}\n */\nexport type MessageModifyingSignerConfig = BaseSignerConfig;\n\n/**\n * A signer interface that _potentially_ modifies the content\n * of the provided {@link SignableMessage | SignableMessages} before signing them.\n *\n * For instance, this enables wallets to prefix or suffix nonces to the messages they sign.\n * For each message, instead of returning a {@link SignatureDictionary}, the\n * {@link MessageModifyingSigner#modifyAndSignMessages | modifyAndSignMessages} function\n * returns an updated {@link SignableMessage} with a potentially modified content and signature dictionary.\n *\n * @typeParam TAddress - Supply a string literal to define a signer having a particular address.\n *\n * @example\n * ```ts\n * const signer: MessageModifyingSigner<'1234..5678'> = {\n *     address: address('1234..5678'),\n *     modifyAndSignMessages: async (\n *         messages: SignableMessage[]\n *     ): Promise<SignableMessage[]> => {\n *         // My custom signing logic.\n *     },\n * };\n * ```\n *\n * @remarks\n * Here are the main characteristics of this signer interface:\n *\n * - **Sequential**. Contrary to partial signers, these cannot be executed in\n *   parallel as each call can modify the content of the message.\n * - **First signers**. For a given message, a modifying signer must always be used\n *   before a partial signer as the former will likely modify the message and\n *   thus impact the outcome of the latter.\n * - **Potential conflicts**. If more than one modifying signer is provided, the second\n *   signer may invalidate the signature of the first one. However, modifying signers\n *   may decide not to modify a message based on the existence of signatures for that message.\n *\n * @see {@link SignableMessage}\n * @see {@link createSignableMessage}\n * @see {@link isMessageModifyingSigner}\n * @see {@link assertIsMessageModifyingSigner}\n */\nexport type MessageModifyingSigner<TAddress extends string = string> = Readonly<{\n    address: Address<TAddress>;\n    modifyAndSignMessages(\n        messages: readonly SignableMessage[],\n        config?: MessageModifyingSignerConfig,\n    ): Promise<readonly SignableMessage[]>;\n}>;\n\n/**\n * Checks whether the provided value implements the {@link MessageModifyingSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { isMessageModifyingSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * isMessageModifyingSigner({ address, modifyAndSignMessages: async () => {} }); // true\n * isMessageModifyingSigner({ address }); // false\n * ```\n *\n * @see {@link assertIsMessageModifyingSigner}\n */\nexport function isMessageModifyingSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): value is MessageModifyingSigner<TAddress> {\n    return (\n        isAddress(value.address) &&\n        'modifyAndSignMessages' in value &&\n        typeof value.modifyAndSignMessages === 'function'\n    );\n}\n\n/**\n * Asserts that the provided value implements the {@link MessageModifyingSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { assertIsMessageModifyingSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * assertIsMessageModifyingSigner({ address, modifyAndSignMessages: async () => {} }); // void\n * assertIsMessageModifyingSigner({ address }); // Throws an error.\n * ```\n *\n * @see {@link isMessageModifyingSigner}\n */\nexport function assertIsMessageModifyingSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): asserts value is MessageModifyingSigner<TAddress> {\n    if (!isMessageModifyingSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_MODIFYING_SIGNER, {\n            address: value.address,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/message-partial-signer.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER, SolanaError } from '@solana/errors';\n\nimport { SignableMessage } from './signable-message';\nimport { BaseSignerConfig, SignatureDictionary } from './types';\n\n/**\n * The configuration to optionally provide when calling the\n * {@link MessagePartialSigner#signMessages | signMessages} method.\n *\n * @see {@link BaseSignerConfig}\n */\nexport type MessagePartialSignerConfig = BaseSignerConfig;\n\n/**\n * A signer interface that signs an array of {@link SignableMessage | SignableMessages}\n * without modifying their content.\n *\n * It defines a {@link MessagePartialSigner#signMessages | signMessages} function\n * that returns a {@link SignatureDictionary} for each provided message.\n * Such signature dictionaries are expected to be merged with the existing ones if any.\n *\n * @typeParam TAddress - Supply a string literal to define a signer having a particular address.\n *\n * @example\n * ```ts\n * const signer: MessagePartialSigner<'1234..5678'> = {\n *     address: address('1234..5678'),\n *     signMessages: async (\n *         messages: SignableMessage[]\n *     ): Promise<SignatureDictionary[]> => {\n *         // My custom signing logic.\n *     },\n * };\n * ```\n *\n * @remarks\n * Here are the main characteristics of this signer interface:\n *\n * - **Parallel**. When multiple signers sign the same message, we can\n *   perform this operation in parallel to obtain all their signatures.\n * - **Flexible order**. The order in which we use these signers\n *   for a given message doesn’t matter.\n *\n * @see {@link SignableMessage}\n * @see {@link createSignableMessage}\n * @see {@link isMessagePartialSigner}\n * @see {@link assertIsMessagePartialSigner}\n */\nexport type MessagePartialSigner<TAddress extends string = string> = Readonly<{\n    address: Address<TAddress>;\n    signMessages(\n        messages: readonly SignableMessage[],\n        config?: MessagePartialSignerConfig,\n    ): Promise<readonly SignatureDictionary[]>;\n}>;\n\n/**\n * Checks whether the provided value implements the {@link MessagePartialSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { isMessagePartialSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * isMessagePartialSigner({ address, signMessages: async () => {} }); // true\n * isMessagePartialSigner({ address }); // false\n * ```\n *\n * @see {@link assertIsMessagePartialSigner}\n */\nexport function isMessagePartialSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): value is MessagePartialSigner<TAddress> {\n    return 'signMessages' in value && typeof value.signMessages === 'function';\n}\n\n/**\n * Asserts that the provided value implements the {@link MessagePartialSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { assertIsMessagePartialSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * assertIsMessagePartialSigner({ address, signMessages: async () => {} }); // void\n * assertIsMessagePartialSigner({ address }); // Throws an error.\n * ```\n *\n * @see {@link isMessagePartialSigner}\n */\nexport function assertIsMessagePartialSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): asserts value is MessagePartialSigner<TAddress> {\n    if (!isMessagePartialSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_PARTIAL_SIGNER, {\n            address: value.address,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/message-signer.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER, SolanaError } from '@solana/errors';\n\nimport { isMessageModifyingSigner, MessageModifyingSigner } from './message-modifying-signer';\nimport { isMessagePartialSigner, MessagePartialSigner } from './message-partial-signer';\n\n/**\n * Defines a signer capable of signing messages.\n *\n * @see {@link MessageModifyingSigner} For signers that can modify messages before signing them.\n * @see {@link MessagePartialSigner} For signers that can be used in parallel.\n * @see {@link isMessageSigner}\n * @see {@link assertIsMessageSigner}\n */\nexport type MessageSigner<TAddress extends string = string> =\n    | MessageModifyingSigner<TAddress>\n    | MessagePartialSigner<TAddress>;\n\n/**\n * Checks whether the provided value implements the {@link MessageSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { isMessageSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * isMessageSigner({ address, signMessages: async () => {} }); // true\n * isMessageSigner({ address, modifyAndSignMessages: async () => {} }); // true\n * isMessageSigner({ address }); // false\n * ```\n *\n * @see {@link assertIsMessageSigner}\n */\nexport function isMessageSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): value is MessageSigner<TAddress> {\n    return isMessagePartialSigner(value) || isMessageModifyingSigner(value);\n}\n\n/**\n * Asserts that the provided value implements the {@link MessageSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { assertIsMessageSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * assertIsMessageSigner({ address, signMessages: async () => {} }); // void\n * assertIsMessageSigner({ address, modifyAndSignMessages: async () => {} }); // void\n * assertIsMessageSigner({ address }); // Throws an error.\n * ```\n *\n * @see {@link isMessageSigner}\n */\nexport function assertIsMessageSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): asserts value is MessageSigner<TAddress> {\n    if (!isMessageSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_MESSAGE_SIGNER, {\n            address: value.address,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/noop-signer.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { MessagePartialSigner } from './message-partial-signer';\nimport { TransactionPartialSigner } from './transaction-partial-signer';\n\n/**\n * Defines a Noop (No-Operation) signer that pretends to partially sign messages and transactions.\n *\n * For a given {@link Address}, a Noop Signer can be created to offer an implementation of both\n * the {@link MessagePartialSigner} and {@link TransactionPartialSigner} interfaces such that\n * they do not sign anything. Namely, signing a transaction or a message with a `NoopSigner`\n * will return an empty `SignatureDictionary`.\n *\n * @typeParam TAddress - Supply a string literal to define a Noop signer having a particular address.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n * import { createNoopSigner } from '@solana/signers';\n *\n * const signer = createNoopSigner(address('1234..5678'));\n * const [messageSignatures] = await signer.signMessages([message]);\n * const [transactionSignatures] = await signer.signTransactions([transaction]);\n * // ^ Both messageSignatures and transactionSignatures are empty.\n * ```\n *\n * @remarks\n * This signer may be useful:\n *\n * - For testing purposes.\n * - For indicating that a given account is a signer and taking the responsibility to provide\n *   the signature for that account ourselves. For instance, if we need to send the transaction\n *   to a server that will sign it and send it for us.\n *\n * @see {@link createNoopSigner}\n */\nexport type NoopSigner<TAddress extends string = string> = MessagePartialSigner<TAddress> &\n    TransactionPartialSigner<TAddress>;\n\n/**\n * Creates a {@link NoopSigner} from the provided {@link Address}.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n * import { createNoopSigner } from '@solana/signers';\n *\n * const signer = createNoopSigner(address('1234..5678'));\n * ```\n */\nexport function createNoopSigner<TAddress extends string = string>(address: Address<TAddress>): NoopSigner<TAddress> {\n    const out: NoopSigner<TAddress> = {\n        address,\n        signMessages: messages => Promise.resolve(messages.map(() => Object.freeze({}))),\n        signTransactions: transactions => Promise.resolve(transactions.map(() => Object.freeze({}))),\n    };\n\n    return Object.freeze(out);\n}\n"
  },
  {
    "path": "packages/signers/src/offchain-message-signer.ts",
    "content": "import { OffchainMessageWithRequiredSignatories } from '@solana/offchain-messages';\n\nimport { deduplicateSigners } from './deduplicate-signers';\nimport { isMessageSigner, MessageSigner } from './message-signer';\n\n/**\n * Represents a {@link Signer} that is required to sign an offchain message for it to be valid.\n */\nexport type OffchainMessageSignatorySigner<TAddress extends string = string> = MessageSigner<TAddress>;\n\n/**\n * Extracts and deduplicates all {@link MessageSigner | MessageSigners} stored inside a given\n * {@link OffchainMessageWithSigners | offchain message}.\n *\n * Any extracted signers that share the same {@link Address} will be de-duplicated.\n *\n * @typeParam TAddress - Supply a string literal to define an account having a particular address.\n * @typeParam TSigner - Optionally provide a narrower type for {@link MessageSigner | MessageSigners}.\n * @typeParam TOffchainMessage - The inferred type of the offchain message provided.\n *\n * @example\n * ```ts\n * import { OffchainMessageWithSigners, getSignersFromOffchainMessage } from '@solana/signers';\n *\n * const signerA = { address: address('1111..1111'), signMessages: async () => {} };\n * const signerB = { address: address('2222..2222'), modifyAndSignMessages: async () => {} };\n * const OffchainMessage: OffchainMessageWithSigners = {\n *     /* ... *\\/\n *     requiredSignatories: [signerA, signerB],\n * };\n *\n * const messageSigners = getSignersFromOffchainMessage(offchainMessage);\n * // ^ [signerA, signerB]\n * ```\n */\nexport function getSignersFromOffchainMessage({\n    requiredSignatories,\n}: OffchainMessageWithRequiredSignatories): readonly MessageSigner[] {\n    const messageSigners = requiredSignatories.filter(isMessageSigner);\n    return deduplicateSigners(messageSigners);\n}\n"
  },
  {
    "path": "packages/signers/src/sign-offchain-message.ts",
    "content": "import {\n    assertIsFullySignedOffchainMessageEnvelope,\n    compileOffchainMessageEnvelope,\n    FullySignedOffchainMessageEnvelope,\n    OffchainMessage,\n    OffchainMessageEnvelope,\n    OffchainMessageSignatory,\n    OffchainMessageWithRequiredSignatories,\n} from '@solana/offchain-messages';\n\nimport {\n    isMessageModifyingSigner,\n    MessageModifyingSigner,\n    MessageModifyingSignerConfig,\n} from './message-modifying-signer';\nimport { isMessagePartialSigner, MessagePartialSigner, MessagePartialSignerConfig } from './message-partial-signer';\nimport { MessageSigner } from './message-signer';\nimport { getSignersFromOffchainMessage, OffchainMessageSignatorySigner } from './offchain-message-signer';\nimport { SignableMessage } from './signable-message';\n\n/**\n * Extracts all {@link MessageSigner | MessageSigners} inside the provided offchain message and uses\n * them to return a signed offchain message envelope.\n *\n * It first uses all {@link MessageModifyingSigner | MessageModifyingSigners} sequentially before\n * using all {@link MessagePartialSigner | MessagePartialSigners} in parallel.\n *\n * If a composite signer implements both interfaces, it will be used as a\n * {@link MessageModifyingSigner} if no other signer implements that interface. Otherwise, it will\n * be used as a {@link MessagePartialSigner}.\n *\n * @example\n * ```ts\n * const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage);\n * ```\n *\n * It also accepts an optional {@link AbortSignal} that will be propagated to all signers.\n *\n * ```ts\n * const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage, {\n *     abortSignal: myAbortController.signal,\n * });\n * ```\n *\n * @see {@link signOffchainMessageWithSigners}\n */\nexport async function partiallySignOffchainMessageWithSigners(\n    offchainMessage: OffchainMessageWithRequiredSignatories<OffchainMessageSignatory | OffchainMessageSignatorySigner> &\n        Omit<OffchainMessage, 'requiredSignatories'>,\n    config?: MessagePartialSignerConfig,\n): Promise<OffchainMessageEnvelope> {\n    const { partialSigners, modifyingSigners } = categorizeMessageSigners(\n        getSignersFromOffchainMessage(offchainMessage),\n    );\n    return await signModifyingAndPartialMessageSigners(offchainMessage, modifyingSigners, partialSigners, config);\n}\n\n/**\n * Extracts all {@link MessageSigner | MessageSigners} inside the provided offchain message and uses\n * them to return a signed offchain message envelope before asserting that all signatures required\n * by the message are present.\n *\n * This function delegates to the {@link partiallySignOffchainMessageWithSigners} function\n * in order to extract signers from the offchain message and sign it.\n *\n * @example\n * ```ts\n * const mySignedOffchainMessageEnvelope = await signOffchainMessageWithSigners(myOffchainMessage);\n *\n * // With additional config.\n * const mySignedOffchainMessageEnvelope = await signOffchainMessageWithSigners(myOffchainMessage, {\n *     abortSignal: myAbortController.signal,\n * });\n *\n * // We now know the offchain message is fully signed.\n * mySignedOffchainMessageEnvelope satisfies FullySignedOffchainMessageEnvelope;\n * ```\n *\n * @see {@link partiallySignOffchainMessageWithSigners}\n */\nexport async function signOffchainMessageWithSigners(\n    offchainMessage: OffchainMessageWithRequiredSignatories<OffchainMessageSignatory | OffchainMessageSignatorySigner> &\n        Omit<OffchainMessage, 'requiredSignatories'>,\n    config?: MessagePartialSignerConfig,\n): Promise<FullySignedOffchainMessageEnvelope & OffchainMessageEnvelope> {\n    const signedOffchainMessageEnvelope = await partiallySignOffchainMessageWithSigners(offchainMessage, config);\n    assertIsFullySignedOffchainMessageEnvelope(signedOffchainMessageEnvelope);\n    return signedOffchainMessageEnvelope;\n}\n\n/**\n * Identifies each provided {@link MessageSigner} and categorizes them into their respective types.\n * When a signer implements multiple interfaces, it will try to used to most powerful interface but\n * fall back to the least powerful interface when necessary.\n *\n * For instance, if a signer implements {@link MessageSigner} and {@link MessageModifyingSigner},\n * it will be categorized as a `MessageModifyingSigner`.\n */\nfunction categorizeMessageSigners(signers: readonly MessageSigner[]): Readonly<{\n    modifyingSigners: readonly MessageModifyingSigner[];\n    partialSigners: readonly MessagePartialSigner[];\n}> {\n    // Identify the modifying signers from the other signers.\n    const modifyingSigners = identifyMessageModifyingSigners(signers);\n\n    // Use any remaining signers as partial signers.\n    const partialSigners = signers\n        .filter(isMessagePartialSigner)\n        .filter(signer => !(modifyingSigners as typeof signers).includes(signer));\n\n    return Object.freeze({ modifyingSigners, partialSigners });\n}\n\n/** Identifies the best signers to use as MessageModifyingSigners, if any */\nfunction identifyMessageModifyingSigners(\n    signers: readonly (MessageModifyingSigner | MessagePartialSigner)[],\n): readonly MessageModifyingSigner[] {\n    // Ensure there are any MessageModifyingSigner in the first place.\n    const modifyingSigners = signers.filter(isMessageModifyingSigner);\n    if (modifyingSigners.length === 0) return [];\n\n    // Prefer modifying signers that do not offer partial signing.\n    const nonPartialSigners = modifyingSigners.filter(signer => !isMessagePartialSigner(signer));\n    if (nonPartialSigners.length > 0) return nonPartialSigners;\n\n    // Otherwise, choose only one modifying signer (whichever).\n    return [modifyingSigners[0]];\n}\n\n/**\n * Signs an offchain message using the provided\n * {@link MessageModifyingSigner | MessageModifyingSigners} sequentially followed by the\n * {@link MessagePartialSigner | MessagePartialSigners} in parallel.\n */\nasync function signModifyingAndPartialMessageSigners(\n    offchainMessage: OffchainMessageWithRequiredSignatories<OffchainMessageSignatory | OffchainMessageSignatorySigner> &\n        Omit<OffchainMessage, 'requiredSignatories'>,\n    modifyingSigners: readonly MessageModifyingSigner[] = [],\n    partialSigners: readonly MessagePartialSigner[] = [],\n    config?: MessageModifyingSignerConfig,\n): Promise<OffchainMessageEnvelope> {\n    // @ts-expect-error SignableMessage should probably specify `ReadonlyUint8Array` here.\n    const offchainMessageEnvelope: SignableMessage = compileOffchainMessageEnvelope(offchainMessage);\n\n    // Handle modifying signers sequentially.\n    const modifiedOffchainMessage = await modifyingSigners.reduce(async (offchainMessageEnvelope, modifyingSigner) => {\n        config?.abortSignal?.throwIfAborted();\n        const [message] = await modifyingSigner.modifyAndSignMessages([await offchainMessageEnvelope], config);\n        return Object.freeze(message);\n    }, Promise.resolve(offchainMessageEnvelope));\n\n    // Handle partial signers in parallel.\n    config?.abortSignal?.throwIfAborted();\n    const signatureDictionaries = await Promise.all(\n        partialSigners.map(async partialSigner => {\n            const [signatures] = await partialSigner.signMessages([modifiedOffchainMessage], config);\n            return signatures;\n        }),\n    );\n\n    // @ts-expect-error SignableMessage should probably specify `ReadonlyUint8Array` here.\n    return Object.freeze({\n        ...modifiedOffchainMessage,\n        signatures: Object.freeze(\n            signatureDictionaries.reduce((signatures, signatureDictionary) => {\n                return { ...signatures, ...signatureDictionary };\n            }, modifiedOffchainMessage.signatures ?? {}),\n        ),\n    } as OffchainMessageEnvelope);\n}\n"
  },
  {
    "path": "packages/signers/src/sign-transaction.ts",
    "content": "import { SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\nimport {\n    assertIsFullySignedTransaction,\n    compileTransaction,\n    SendableTransaction,\n    Transaction,\n    TransactionWithinSizeLimit,\n    TransactionWithLifetime,\n} from '@solana/transactions';\n\nimport { getSignersFromTransactionMessage, TransactionMessageWithSigners } from './account-signer-meta';\nimport { deduplicateSigners } from './deduplicate-signers';\nimport {\n    isTransactionModifyingSigner,\n    TransactionModifyingSigner,\n    TransactionModifyingSignerConfig,\n} from './transaction-modifying-signer';\nimport {\n    isTransactionPartialSigner,\n    TransactionPartialSigner,\n    TransactionPartialSignerConfig,\n} from './transaction-partial-signer';\nimport {\n    isTransactionSendingSigner,\n    TransactionSendingSigner,\n    TransactionSendingSignerConfig,\n} from './transaction-sending-signer';\nimport { isTransactionSigner, TransactionSigner } from './transaction-signer';\nimport { assertContainsResolvableTransactionSendingSigner } from './transaction-with-single-sending-signer';\n\n/**\n * Extracts all {@link TransactionSigner | TransactionSigners} inside the provided\n * transaction message and uses them to return a signed transaction.\n *\n * It first uses all {@link TransactionModifyingSigner | TransactionModifyingSigners} sequentially before\n * using all {@link TransactionPartialSigner | TransactionPartialSigners} in parallel.\n *\n * If a composite signer implements both interfaces, it will be used as a\n * {@link TransactionModifyingSigner} if no other signer implements that interface.\n * Otherwise, it will be used as a {@link TransactionPartialSigner}.\n *\n * @example\n * ```ts\n * const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage);\n * ```\n *\n * It also accepts an optional {@link AbortSignal} that will be propagated to all signers.\n *\n * ```ts\n * const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage, {\n *     abortSignal: myAbortController.signal,\n * });\n * ```\n *\n * @remarks\n * Finally, note that this function ignores {@link TransactionSendingSigner | TransactionSendingSigners}\n * as it does not send the transaction. Check out the {@link signAndSendTransactionMessageWithSigners}\n * function for more details on how to use sending signers.\n *\n * @see {@link partiallySignTransactionWithSigners}\n * @see {@link signTransactionMessageWithSigners}\n * @see {@link signAndSendTransactionMessageWithSigners}\n */\nexport async function partiallySignTransactionMessageWithSigners(\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners,\n    config?: TransactionPartialSignerConfig,\n): Promise<Transaction & TransactionWithinSizeLimit & TransactionWithLifetime> {\n    return await partiallySignTransactionWithSigners(\n        getSignersFromTransactionMessage(transactionMessage).filter(\n            signer => isTransactionModifyingSigner(signer) || isTransactionPartialSigner(signer),\n        ),\n        compileTransaction(transactionMessage),\n        config,\n    );\n}\n\n/**\n * Extracts all {@link TransactionSigner | TransactionSigners} inside the provided\n * transaction message and uses them to return a signed transaction before asserting\n * that all signatures required by the transaction are present.\n *\n * This function delegates to the {@link partiallySignTransactionMessageWithSigners} function\n * in order to extract signers from the transaction message and sign the transaction.\n *\n * @example\n * ```ts\n * const mySignedTransaction = await signTransactionMessageWithSigners(myTransactionMessage);\n *\n * // With additional config.\n * const mySignedTransaction = await signTransactionMessageWithSigners(myTransactionMessage, {\n *     abortSignal: myAbortController.signal,\n * });\n *\n * // We now know the transaction is fully signed.\n * mySignedTransaction satisfies FullySignedTransaction;\n * ```\n *\n * @see {@link signTransactionWithSigners}\n * @see {@link partiallySignTransactionMessageWithSigners}\n * @see {@link signAndSendTransactionMessageWithSigners}\n */\nexport async function signTransactionMessageWithSigners(\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners,\n    config?: TransactionPartialSignerConfig,\n): Promise<SendableTransaction & Transaction & TransactionWithLifetime> {\n    const signedTransaction = await partiallySignTransactionMessageWithSigners(transactionMessage, config);\n    assertIsFullySignedTransaction(signedTransaction);\n    return signedTransaction;\n}\n\n/**\n * Extracts all {@link TransactionSigner | TransactionSigners} inside the provided\n * transaction message and uses them to sign it before sending it immediately to the blockchain.\n *\n * It returns the signature of the sent transaction (i.e. its identifier) as bytes.\n *\n * @example\n * ```ts\n * import { signAndSendTransactionMessageWithSigners } from '@solana/signers';\n *\n * const transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n *\n * // With additional config.\n * const transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage, {\n *     abortSignal: myAbortController.signal,\n * });\n * ```\n *\n * @remarks\n * Similarly to the {@link partiallySignTransactionMessageWithSigners} function, it first uses all\n * {@link TransactionModifyingSigner | TransactionModifyingSigners} sequentially before using all\n * {@link TransactionPartialSigner | TransactionPartialSigners} in parallel.\n * It then sends the transaction using the {@link TransactionSendingSigner} it identified.\n *\n * Composite transaction signers are treated such that at least one sending signer is used if any.\n * When a {@link TransactionSigner} implements more than one interface, we use it as a:\n *\n * - {@link TransactionSendingSigner}, if no other {@link TransactionSendingSigner} exists.\n * - {@link TransactionModifyingSigner}, if no other {@link TransactionModifyingSigner} exists.\n * - {@link TransactionPartialSigner}, otherwise.\n *\n * The provided transaction must contain exactly one {@link TransactionSendingSigner} inside its account metas.\n * If more than one composite signers implement the {@link TransactionSendingSigner} interface,\n * one of them will be selected as the sending signer. Otherwise, if multiple\n * {@link TransactionSendingSigner | TransactionSendingSigners} must be selected, the function will throw an error.\n *\n * If you'd like to assert that a transaction makes use of exactly one {@link TransactionSendingSigner}\n * _before_ calling this function, you may use the {@link assertIsTransactionMessageWithSingleSendingSigner} function.\n *\n * Alternatively, you may use the {@link isTransactionMessageWithSingleSendingSigner} function to provide a\n * fallback in case the transaction does not contain any sending signer.\n *\n * @see {@link signAndSendTransactionWithSigners}\n * @see {@link assertIsTransactionMessageWithSingleSendingSigner}\n * @see {@link isTransactionMessageWithSingleSendingSigner}\n * @see {@link partiallySignTransactionMessageWithSigners}\n * @see {@link signTransactionMessageWithSigners}\n *\n */\nexport async function signAndSendTransactionMessageWithSigners(\n    transaction: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithSigners,\n    config?: TransactionSendingSignerConfig,\n): Promise<SignatureBytes> {\n    return await signAndSendTransactionWithSigners(\n        getSignersFromTransactionMessage(transaction).filter(isTransactionSigner),\n        compileTransaction(transaction),\n        config,\n    );\n}\n\n/**\n * Signs a transaction using the provided {@link TransactionModifyingSigner | TransactionModifyingSigners}\n * and {@link TransactionPartialSigner | TransactionPartialSigners}.\n *\n * It first uses all {@link TransactionModifyingSigner | TransactionModifyingSigners} sequentially before\n * using all {@link TransactionPartialSigner | TransactionPartialSigners} in parallel.\n *\n * If a composite signer implements both interfaces, it will be used as a\n * {@link TransactionModifyingSigner} if no other signer implements that interface.\n * Otherwise, it will be used as a {@link TransactionPartialSigner}.\n *\n * @param signers - The signers to use. Only {@link TransactionModifyingSigner} and\n * {@link TransactionPartialSigner} interfaces are accepted.\n * @param transaction - The compiled transaction to sign.\n * @param config - Optional configuration including an {@link AbortSignal}.\n * @returns The signed transaction.\n *\n * @example\n * ```ts\n * const signedTransaction = await partiallySignTransactionWithSigners(mySigners, compiledTransaction);\n * ```\n *\n * It also accepts an optional {@link AbortSignal} that will be propagated to all signers.\n *\n * ```ts\n * const signedTransaction = await partiallySignTransactionWithSigners(mySigners, compiledTransaction, {\n *     abortSignal: myAbortController.signal,\n * });\n * ```\n *\n * @see {@link signTransactionWithSigners}\n * @see {@link signAndSendTransactionWithSigners}\n * @see {@link partiallySignTransactionMessageWithSigners}\n */\nexport async function partiallySignTransactionWithSigners(\n    signers: readonly (TransactionModifyingSigner | TransactionPartialSigner)[],\n    transaction: Transaction,\n    config?: TransactionPartialSignerConfig,\n): Promise<Transaction & TransactionWithinSizeLimit & TransactionWithLifetime> {\n    const { partialSigners, modifyingSigners } = categorizeTransactionSigners(deduplicateSigners(signers), {\n        identifySendingSigner: false,\n    });\n\n    return await signModifyingAndPartialTransactionSigners(transaction, modifyingSigners, partialSigners, config);\n}\n\n/**\n * Signs a transaction using the provided signers and asserts that all\n * signatures required by the transaction are present.\n *\n * This function delegates to {@link partiallySignTransactionWithSigners} to sign\n * the transaction, then asserts it is fully signed before returning.\n *\n * @param signers - The signers to use. Only {@link TransactionModifyingSigner} and\n * {@link TransactionPartialSigner} interfaces are accepted.\n * @param transaction - The compiled transaction to sign.\n * @param config - Optional configuration including an {@link AbortSignal}.\n * @returns The fully signed transaction.\n *\n * @example\n * ```ts\n * const mySignedTransaction = await signTransactionWithSigners(mySigners, compiledTransaction);\n *\n * // With additional config.\n * const mySignedTransaction = await signTransactionWithSigners(mySigners, compiledTransaction, {\n *     abortSignal: myAbortController.signal,\n * });\n *\n * // We now know the transaction is fully signed.\n * mySignedTransaction satisfies FullySignedTransaction;\n * ```\n *\n * @see {@link partiallySignTransactionWithSigners}\n * @see {@link signAndSendTransactionWithSigners}\n * @see {@link signTransactionMessageWithSigners}\n */\nexport async function signTransactionWithSigners(\n    signers: readonly (TransactionModifyingSigner | TransactionPartialSigner)[],\n    transaction: Transaction,\n    config?: TransactionPartialSignerConfig,\n): Promise<SendableTransaction & Transaction & TransactionWithLifetime> {\n    const signedTransaction = await partiallySignTransactionWithSigners(signers, transaction, config);\n    assertIsFullySignedTransaction(signedTransaction);\n    return signedTransaction;\n}\n\n/**\n * Signs a transaction using the provided signers and sends it immediately to the blockchain.\n *\n * It returns the signature of the sent transaction (i.e. its identifier) as bytes.\n *\n * Similarly to {@link partiallySignTransactionWithSigners}, it first uses all\n * {@link TransactionModifyingSigner | TransactionModifyingSigners} sequentially before using all\n * {@link TransactionPartialSigner | TransactionPartialSigners} in parallel.\n * It then sends the transaction using the {@link TransactionSendingSigner} it identified.\n *\n * Composite transaction signers are treated such that at least one sending signer is used if any.\n * When a {@link TransactionSigner} implements more than one interface, we use it as a:\n *\n * - {@link TransactionSendingSigner}, if no other {@link TransactionSendingSigner} exists.\n * - {@link TransactionModifyingSigner}, if no other {@link TransactionModifyingSigner} exists.\n * - {@link TransactionPartialSigner}, otherwise.\n *\n * The provided signers must contain exactly one {@link TransactionSendingSigner} that can be\n * unambiguously resolved. If more than one composite signers implement the\n * {@link TransactionSendingSigner} interface, one of them will be selected as the sending signer.\n * Otherwise, if multiple {@link TransactionSendingSigner | TransactionSendingSigners} must be\n * selected, the function will throw an error.\n *\n * @param signers - The signers to use. Must contain at least one resolvable\n * {@link TransactionSendingSigner}.\n * @param transaction - The compiled transaction to sign and send.\n * @param config - Optional configuration including an {@link AbortSignal}.\n * @returns The signature of the sent transaction as bytes.\n *\n * @example\n * ```ts\n * const transactionSignature = await signAndSendTransactionWithSigners(mySigners, compiledTransaction);\n *\n * // With additional config.\n * const transactionSignature = await signAndSendTransactionWithSigners(mySigners, compiledTransaction, {\n *     abortSignal: myAbortController.signal,\n * });\n * ```\n *\n * @see {@link assertContainsResolvableTransactionSendingSigner}\n * @see {@link partiallySignTransactionWithSigners}\n * @see {@link signTransactionWithSigners}\n * @see {@link signAndSendTransactionMessageWithSigners}\n */\nexport async function signAndSendTransactionWithSigners(\n    signers: readonly TransactionSigner[],\n    transaction: Transaction,\n    config?: TransactionSendingSignerConfig,\n): Promise<SignatureBytes> {\n    assertContainsResolvableTransactionSendingSigner(signers);\n\n    const abortSignal = config?.abortSignal;\n    const { partialSigners, modifyingSigners, sendingSigner } = categorizeTransactionSigners(\n        deduplicateSigners(signers),\n    );\n\n    abortSignal?.throwIfAborted();\n    const signedTransaction = await signModifyingAndPartialTransactionSigners(\n        transaction,\n        modifyingSigners,\n        partialSigners,\n        config,\n    );\n\n    if (!sendingSigner) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING);\n    }\n\n    abortSignal?.throwIfAborted();\n    const [signature] = await sendingSigner.signAndSendTransactions([signedTransaction], config);\n    abortSignal?.throwIfAborted();\n\n    return signature;\n}\n\n/**\n * Identifies each provided TransactionSigner and categorizes them into their respective types.\n * When a signer implements multiple interface, it will try to used to most powerful interface\n * but fallback to the least powerful interface when necessary.\n * For instance, if a signer implements TransactionSendingSigner and TransactionModifyingSigner,\n * it will be categorized as a TransactionSendingSigner if and only if no other signers implement\n * the TransactionSendingSigner interface.\n */\nfunction categorizeTransactionSigners(\n    signers: readonly TransactionSigner[],\n    config: { identifySendingSigner?: boolean } = {},\n): Readonly<{\n    modifyingSigners: readonly TransactionModifyingSigner[];\n    partialSigners: readonly TransactionPartialSigner[];\n    sendingSigner: TransactionSendingSigner | null;\n}> {\n    // Identify the unique sending signer that should be used.\n    const identifySendingSigner = config.identifySendingSigner ?? true;\n    const sendingSigner = identifySendingSigner ? identifyTransactionSendingSigner(signers) : null;\n\n    // Now, focus on the other signers.\n    // I.e. the modifying or partial signers that are not the identified sending signer.\n    // Note that any other sending only signers will be discarded.\n    const otherSigners = signers.filter(\n        (signer): signer is TransactionModifyingSigner | TransactionPartialSigner =>\n            signer !== sendingSigner && (isTransactionModifyingSigner(signer) || isTransactionPartialSigner(signer)),\n    );\n\n    // Identify the modifying signers from the other signers.\n    const modifyingSigners = identifyTransactionModifyingSigners(otherSigners);\n\n    // Use any remaining signers as partial signers.\n    const partialSigners = otherSigners\n        .filter(isTransactionPartialSigner)\n        .filter(signer => !(modifyingSigners as typeof otherSigners).includes(signer));\n\n    return Object.freeze({ modifyingSigners, partialSigners, sendingSigner });\n}\n\n/** Identifies the best signer to use as a TransactionSendingSigner, if any */\nfunction identifyTransactionSendingSigner(signers: readonly TransactionSigner[]): TransactionSendingSigner | null {\n    // Ensure there are any TransactionSendingSigners in the first place.\n    const sendingSigners = signers.filter(isTransactionSendingSigner);\n    if (sendingSigners.length === 0) return null;\n\n    // Prefer sending signers that do not offer other interfaces.\n    const sendingOnlySigners = sendingSigners.filter(\n        signer => !isTransactionModifyingSigner(signer) && !isTransactionPartialSigner(signer),\n    );\n    if (sendingOnlySigners.length > 0) {\n        return sendingOnlySigners[0];\n    }\n\n    // Otherwise, choose any sending signer.\n    return sendingSigners[0];\n}\n\n/** Identifies the best signers to use as TransactionModifyingSigners, if any */\nfunction identifyTransactionModifyingSigners(\n    signers: readonly (TransactionModifyingSigner | TransactionPartialSigner)[],\n): readonly TransactionModifyingSigner[] {\n    // Ensure there are any TransactionModifyingSigner in the first place.\n    const modifyingSigners = signers.filter(isTransactionModifyingSigner);\n    if (modifyingSigners.length === 0) return [];\n\n    // Prefer modifying signers that do not offer partial signing.\n    const nonPartialSigners = modifyingSigners.filter(signer => !isTransactionPartialSigner(signer));\n    if (nonPartialSigners.length > 0) return nonPartialSigners;\n\n    // Otherwise, choose only one modifying signer (whichever).\n    return [modifyingSigners[0]];\n}\n\n/**\n * Signs a transaction using the provided TransactionModifyingSigners\n * sequentially followed by the TransactionPartialSigners in parallel.\n */\nasync function signModifyingAndPartialTransactionSigners(\n    transaction: Transaction,\n    modifyingSigners: readonly TransactionModifyingSigner[] = [],\n    partialSigners: readonly TransactionPartialSigner[] = [],\n    config?: TransactionModifyingSignerConfig,\n): Promise<Transaction & TransactionWithinSizeLimit & TransactionWithLifetime> {\n    // Handle modifying signers sequentially.\n    const modifiedTransaction = (await modifyingSigners.reduce(\n        async (transaction, modifyingSigner) => {\n            config?.abortSignal?.throwIfAborted();\n            const [tx] = await modifyingSigner.modifyAndSignTransactions([await transaction], config);\n            return Object.freeze(tx);\n        },\n        Promise.resolve(transaction) as Promise<Readonly<Transaction & TransactionWithLifetime>>,\n    )) as Transaction & TransactionWithinSizeLimit & TransactionWithLifetime;\n\n    // Handle partial signers in parallel.\n    config?.abortSignal?.throwIfAborted();\n    const signatureDictionaries = await Promise.all(\n        partialSigners.map(async partialSigner => {\n            const [signatures] = await partialSigner.signTransactions([modifiedTransaction], config);\n            return signatures;\n        }),\n    );\n\n    return Object.freeze({\n        ...modifiedTransaction,\n        signatures: Object.freeze(\n            signatureDictionaries.reduce((signatures, signatureDictionary) => {\n                return { ...signatures, ...signatureDictionary };\n            }, modifiedTransaction.signatures ?? {}),\n        ),\n    });\n}\n"
  },
  {
    "path": "packages/signers/src/signable-message.ts",
    "content": "import { TextEncoder } from '@solana/text-encoding-impl';\n\nimport { SignatureDictionary } from './types';\n\n/**\n * Defines a message that needs signing and its current set of signatures if any.\n *\n * This interface allows {@link MessageModifyingSigner | MessageModifyingSigners}\n * to decide on whether or not they should modify the provided message depending\n * on whether or not signatures already exist for such message.\n *\n * It also helps create a more consistent API by providing a structure analogous\n * to transactions which also keep track of their {@link SignatureDictionary}.\n *\n * @example\n * ```ts\n * import { createSignableMessage } from '@solana/signers';\n *\n * const message = createSignableMessage(new Uint8Array([1, 2, 3]));\n * message.content; // The content of the message as bytes.\n * message.signatures; // The current set of signatures for this message.\n * ```\n *\n * @see {@link createSignableMessage}\n */\nexport type SignableMessage = Readonly<{\n    content: Uint8Array;\n    signatures: SignatureDictionary;\n}>;\n\n/**\n * Creates a {@link SignableMessage} from a `Uint8Array` or a UTF-8 string.\n *\n * It optionally accepts a signature dictionary if the message already contains signatures.\n *\n * @example\n * ```ts\n * const message = createSignableMessage(new Uint8Array([1, 2, 3]));\n * const messageFromText = createSignableMessage('Hello world!');\n * const messageWithSignatures = createSignableMessage('Hello world!', {\n *     [address('1234..5678')]: new Uint8Array([1, 2, 3]) as SignatureBytes,\n * });\n * ```\n */\nexport function createSignableMessage(\n    content: Uint8Array | string,\n    signatures: SignatureDictionary = {},\n): SignableMessage {\n    return Object.freeze({\n        content: typeof content === 'string' ? new TextEncoder().encode(content) : content,\n        signatures: Object.freeze({ ...signatures }),\n    });\n}\n"
  },
  {
    "path": "packages/signers/src/transaction-modifying-signer.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER, SolanaError } from '@solana/errors';\nimport { Transaction, TransactionWithinSizeLimit, TransactionWithLifetime } from '@solana/transactions';\n\nimport { BaseTransactionSignerConfig } from './types';\n\n/**\n * The configuration to optionally provide when calling the\n * {@link TransactionModifyingSigner#modifyAndSignTransactions | modifyAndSignTransactions} method.\n *\n * @see {@link BaseTransactionSignerConfig}\n */\nexport type TransactionModifyingSignerConfig = BaseTransactionSignerConfig;\n\n/**\n * A signer interface that potentially modifies the provided {@link Transaction | Transactions}\n * before signing them.\n *\n * For instance, this enables wallets to inject additional instructions into the\n * transaction before signing them. For each transaction, instead of returning a\n * {@link SignatureDictionary}, its\n * {@link TransactionModifyingSigner#modifyAndSignTransactions | modifyAndSignTransactions} function\n * returns an updated {@link Transaction} with a potentially modified set of instructions and\n * signature dictionary. The returned transaction must be within the transaction size limit,\n * and include a `lifetimeConstraint`.\n *\n * @typeParam TAddress - Supply a string literal to define a signer having a particular address.\n *\n * @example\n * ```ts\n * const signer: TransactionModifyingSigner<'1234..5678'> = {\n *     address: address('1234..5678'),\n *     modifyAndSignTransactions: async (\n *         transactions: Transaction[]\n *     ): Promise<(Transaction & TransactionWithinSizeLimit & TransactionWithLifetime)[]> => {\n *         // My custom signing logic.\n *     },\n * };\n * ```\n *\n * @remarks\n * Here are the main characteristics of this signer interface:\n *\n * - **Sequential**. Contrary to partial signers, these cannot be executed in\n *   parallel as each call can modify the provided transactions.\n * - **First signers**. For a given transaction, a modifying signer must always\n *   be used before a partial signer as the former will likely modify the\n *   transaction and thus impact the outcome of the latter.\n * - **Potential conflicts**. If more than one modifying signer is provided,\n *   the second signer may invalidate the signature of the first one. However,\n *   modifying signers may decide not to modify a transaction based on the\n *   existence of signatures for that transaction.\n *\n * @see {@link isTransactionModifyingSigner}\n * @see {@link assertIsTransactionModifyingSigner}\n */\nexport type TransactionModifyingSigner<TAddress extends string = string> = Readonly<{\n    address: Address<TAddress>;\n    modifyAndSignTransactions(\n        transactions: readonly (Transaction | (Transaction & TransactionWithLifetime))[],\n        config?: TransactionModifyingSignerConfig,\n    ): Promise<readonly (Transaction & TransactionWithinSizeLimit & TransactionWithLifetime)[]>;\n}>;\n\n/**\n * Checks whether the provided value implements the {@link TransactionModifyingSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { isTransactionModifyingSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * isTransactionModifyingSigner({ address, modifyAndSignTransactions: async () => {} }); // true\n * isTransactionModifyingSigner({ address }); // false\n * ```\n *\n * @see {@link assertIsTransactionModifyingSigner}\n */\nexport function isTransactionModifyingSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): value is TransactionModifyingSigner<TAddress> {\n    return 'modifyAndSignTransactions' in value && typeof value.modifyAndSignTransactions === 'function';\n}\n\n/**\n * Asserts that the provided value implements the {@link TransactionModifyingSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { assertIsTransactionModifyingSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * assertIsTransactionModifyingSigner({ address, modifyAndSignTransactions: async () => {} }); // void\n * assertIsTransactionModifyingSigner({ address }); // Throws an error.\n * ```\n *\n * @see {@link isTransactionModifyingSigner}\n */\nexport function assertIsTransactionModifyingSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): asserts value is TransactionModifyingSigner<TAddress> {\n    if (!isTransactionModifyingSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_MODIFYING_SIGNER, {\n            address: value.address,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/transaction-partial-signer.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER, SolanaError } from '@solana/errors';\nimport { Transaction, TransactionWithinSizeLimit, TransactionWithLifetime } from '@solana/transactions';\n\nimport { BaseTransactionSignerConfig, SignatureDictionary } from './types';\n\n/**\n * The configuration to optionally provide when calling the\n * {@link TransactionPartialSigner#signTransactions | signTransactions} method.\n *\n * @see {@link BaseTransactionSignerConfig}\n */\nexport type TransactionPartialSignerConfig = BaseTransactionSignerConfig;\n\n/**\n * A signer interface that signs an array of {@link Transaction | Transactions}\n *  without modifying their content. It defines a\n * {@link TransactionPartialSigner#signTransactions | signTransactions}\n * function that returns a {@link SignatureDictionary} for each provided transaction.\n *\n * Such signature dictionaries are expected to be merged with the existing ones if any.\n *\n * @typeParam TAddress - Supply a string literal to define a signer having a particular address.\n *\n * @example\n * ```ts\n * const signer: TransactionPartialSigner<'1234..5678'> = {\n *     address: address('1234..5678'),\n *     signTransactions: async (\n *         transactions: Transaction[]\n *     ): Promise<SignatureDictionary[]> => {\n *         // My custom signing logic.\n *     },\n * };\n * ```\n *\n * @remarks\n * Here are the main characteristics of this signer interface:\n *\n * - **Parallel**. It returns a signature dictionary for each provided\n *   transaction without modifying them, making it possible for multiple\n *   partial signers to sign the same transaction in parallel.\n * - **Flexible order**. The order in which we use these signers for\n *   a given transaction doesn’t matter.\n *\n * @see {@link isTransactionPartialSigner}\n * @see {@link assertIsTransactionPartialSigner}\n */\nexport type TransactionPartialSigner<TAddress extends string = string> = Readonly<{\n    address: Address<TAddress>;\n    signTransactions(\n        transactions: readonly (Transaction & TransactionWithinSizeLimit & TransactionWithLifetime)[],\n        config?: TransactionPartialSignerConfig,\n    ): Promise<readonly SignatureDictionary[]>;\n}>;\n\n/**\n * Checks whether the provided value implements the {@link TransactionPartialSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { isTransactionPartialSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * isTransactionPartialSigner({ address, signTransactions: async () => {} }); // true\n * isTransactionPartialSigner({ address }); // false\n * ```\n *\n * @see {@link assertIsTransactionPartialSigner}\n */\nexport function isTransactionPartialSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): value is TransactionPartialSigner<TAddress> {\n    return 'signTransactions' in value && typeof value.signTransactions === 'function';\n}\n\n/**\n * Asserts that the provided value implements the {@link TransactionPartialSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { assertIsTransactionPartialSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * assertIsTransactionPartialSigner({ address, signTransactions: async () => {} }); // void\n * assertIsTransactionPartialSigner({ address }); // Throws an error.\n * ```\n *\n * @see {@link isTransactionPartialSigner}\n */\nexport function assertIsTransactionPartialSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): asserts value is TransactionPartialSigner<TAddress> {\n    if (!isTransactionPartialSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_PARTIAL_SIGNER, {\n            address: value.address,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/transaction-sending-signer.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { Transaction, TransactionWithLifetime } from '@solana/transactions';\n\nimport { BaseTransactionSignerConfig } from './types';\n\n/**\n * The configuration to optionally provide when calling the\n * {@link TransactionSendingSignerConfig#signAndSendTransactions | signAndSendTransactions} method.\n *\n * @see {@link BaseTransactionSignerConfig}\n */\nexport type TransactionSendingSignerConfig = BaseTransactionSignerConfig;\n\n/**\n * A signer interface that signs one or multiple transactions\n * before sending them immediately to the blockchain.\n *\n * It defines a {@link TransactionSendingSignerConfig#signAndSendTransactions | signAndSendTransactions}\n * function that returns the transaction signature (i.e. its identifier) for each provided\n * {@link Transaction}.\n *\n * This interface is required for PDA wallets and other types of wallets that don't provide an\n * interface for signing transactions without sending them.\n *\n * Note that it is also possible for such signers to modify the provided transactions\n * before signing and sending them. This enables use cases where the modified transactions\n * cannot be shared with the app and thus must be sent directly.\n *\n * @typeParam TAddress - Supply a string literal to define a signer having a particular address.\n *\n * @example\n * ```ts\n * const myTransactionSendingSigner: TransactionSendingSigner<'1234..5678'> = {\n *     address: address('1234..5678'),\n *     signAndSendTransactions: async (transactions: Transaction[]): Promise<SignatureBytes[]> => {\n *         // My custom signing logic.\n *     },\n * };\n * ```\n *\n * @remarks\n * Here are the main characteristics of this signer interface:\n *\n * - **Single signer**. Since this signer also sends the provided transactions,\n *   we can only use a single {@link TransactionSendingSigner} for a given set of transactions.\n * - **Last signer**. Trivially, that signer must also be the last one used.\n * - **Potential conflicts**. Since signers may decide to modify the given\n *   transactions before sending them, they may invalidate previous signatures.\n *   However, signers may decide not to modify a transaction based\n *   on the existence of signatures for that transaction.\n * - **Potential confirmation**. Whilst this is not required by this interface,\n *   it is also worth noting that most wallets will also wait for the transaction\n *   to be confirmed (typically with a `confirmed` commitment)\n *   before notifying the app that they are done.\n *\n * @see {@link isTransactionSendingSigner}\n * @see {@link assertIsTransactionSendingSigner}\n */\nexport type TransactionSendingSigner<TAddress extends string = string> = Readonly<{\n    address: Address<TAddress>;\n    signAndSendTransactions(\n        transactions: readonly (Transaction | (Transaction & TransactionWithLifetime))[],\n        config?: TransactionSendingSignerConfig,\n    ): Promise<readonly SignatureBytes[]>;\n}>;\n\n/**\n * Checks whether the provided value implements the {@link TransactionSendingSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { isTransactionSendingSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * isTransactionSendingSigner({ address, signAndSendTransactions: async () => {} }); // true\n * isTransactionSendingSigner({ address }); // false\n * ```\n *\n * @see {@link assertIsTransactionSendingSigner}\n */\nexport function isTransactionSendingSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): value is TransactionSendingSigner<TAddress> {\n    return 'signAndSendTransactions' in value && typeof value.signAndSendTransactions === 'function';\n}\n\n/**\n * Asserts that the provided value implements the {@link TransactionSendingSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { assertIsTransactionSendingSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * assertIsTransactionSendingSigner({ address, signAndSendTransactions: async () => {} }); // void\n * assertIsTransactionSendingSigner({ address }); // Throws an error.\n * ```\n *\n * @see {@link isTransactionSendingSigner}\n */\nexport function assertIsTransactionSendingSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): asserts value is TransactionSendingSigner<TAddress> {\n    if (!isTransactionSendingSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SENDING_SIGNER, {\n            address: value.address,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/transaction-signer.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER, SolanaError } from '@solana/errors';\n\nimport { isTransactionModifyingSigner, TransactionModifyingSigner } from './transaction-modifying-signer';\nimport { isTransactionPartialSigner, TransactionPartialSigner } from './transaction-partial-signer';\nimport { isTransactionSendingSigner, TransactionSendingSigner } from './transaction-sending-signer';\n\n/**\n * Defines a signer capable of signing transactions.\n *\n * @see {@link TransactionModifyingSigner} For signers that can modify transactions before signing them.\n * @see {@link TransactionPartialSigner} For signers that can be used in parallel.\n * @see {@link TransactionSendingSigner} For signers that send transactions after signing them.\n * @see {@link isTransactionSigner}\n * @see {@link assertIsTransactionSigner}\n */\nexport type TransactionSigner<TAddress extends string = string> =\n    | TransactionModifyingSigner<TAddress>\n    | TransactionPartialSigner<TAddress>\n    | TransactionSendingSigner<TAddress>;\n\n/**\n * Checks whether the provided value implements the {@link TransactionSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { isTransactionSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * isTransactionSigner({ address, signTransactions: async () => {} }); // true\n * isTransactionSigner({ address, modifyAndSignTransactions: async () => {} }); // true\n * isTransactionSigner({ address, signAndSendTransactions: async () => {} }); // true\n * isTransactionSigner({ address }); // false\n * ```\n *\n * @see {@link assertIsTransactionSigner}\n */\nexport function isTransactionSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): value is TransactionSigner<TAddress> {\n    return (\n        isTransactionPartialSigner(value) || isTransactionModifyingSigner(value) || isTransactionSendingSigner(value)\n    );\n}\n\n/**\n * Asserts that the provided value implements the {@link TransactionSigner} interface.\n *\n * @typeParam TAddress - The inferred type of the address provided.\n *\n * @example\n * ```ts\n * import { Address } from '@solana/addresses';\n * import { assertIsTransactionSigner } from '@solana/signers';\n *\n * const address = '1234..5678' as Address<'1234..5678'>;\n * assertIsTransactionSigner({ address, signTransactions: async () => {} }); // void\n * assertIsTransactionSigner({ address, modifyAndSignTransactions: async () => {} }); // void\n * assertIsTransactionSigner({ address, signAndSendTransactions: async () => {} }); // void\n * assertIsTransactionSigner({ address }); // Throws an error.\n * ```\n *\n * @see {@link isTransactionSigner}\n */\nexport function assertIsTransactionSigner<TAddress extends string>(value: {\n    [key: string]: unknown;\n    address: Address<TAddress>;\n}): asserts value is TransactionSigner<TAddress> {\n    if (!isTransactionSigner(value)) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__EXPECTED_TRANSACTION_SIGNER, {\n            address: value.address,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/transaction-with-single-sending-signer.ts",
    "content": "import {\n    SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS,\n    SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING,\n    SolanaError,\n} from '@solana/errors';\nimport { Brand } from '@solana/nominal-types';\nimport { TransactionMessage, TransactionMessageWithFeePayer } from '@solana/transaction-messages';\n\nimport { getSignersFromTransactionMessage, TransactionMessageWithSigners } from './account-signer-meta';\nimport { isTransactionModifyingSigner } from './transaction-modifying-signer';\nimport { isTransactionPartialSigner } from './transaction-partial-signer';\nimport { isTransactionSendingSigner } from './transaction-sending-signer';\nimport { TransactionSigner } from './transaction-signer';\n\n/**\n * Defines a transaction message with exactly one {@link TransactionSendingSigner}.\n *\n * This type is used to narrow the type of transaction messages that have been\n * checked to have exactly one sending signer.\n *\n * @example\n * ```ts\n * import { assertIsTransactionMessageWithSingleSendingSigner } from '@solana/signers';\n *\n * assertIsTransactionMessageWithSingleSendingSigner(transactionMessage);\n * transactionMessage satisfies TransactionMessageWithSingleSendingSigner;\n * ```\n *\n * @see {@link isTransactionMessageWithSingleSendingSigner}\n * @see {@link assertIsTransactionMessageWithSingleSendingSigner}\n */\nexport type TransactionMessageWithSingleSendingSigner = Brand<\n    TransactionMessageWithSigners,\n    'TransactionMessageWithSingleSendingSigner'\n>;\n\n/**\n * Checks whether the provided transaction has exactly one {@link TransactionSendingSigner}.\n *\n * This can be useful when using {@link signAndSendTransactionMessageWithSigners} to provide\n * a fallback strategy in case the transaction message cannot be send using this function.\n *\n * @typeParam TTransactionMessage - The inferred type of the transaction message provided.\n *\n * @example\n * ```ts\n * import {\n *     isTransactionMessageWithSingleSendingSigner,\n *     signAndSendTransactionMessageWithSigners,\n *     signTransactionMessageWithSigners,\n * } from '@solana/signers';\n * import { getBase64EncodedWireTransaction } from '@solana/transactions';\n *\n * let transactionSignature: SignatureBytes;\n * if (isTransactionMessageWithSingleSendingSigner(transactionMessage)) {\n *     transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n * } else {\n *     const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);\n *     const encodedTransaction = getBase64EncodedWireTransaction(signedTransaction);\n *     transactionSignature = await rpc.sendTransaction(encodedTransaction).send();\n * }\n * ```\n *\n * @see {@link signAndSendTransactionMessageWithSigners}\n * @see {@link assertIsTransactionMessageWithSingleSendingSigner}\n */\nexport function isTransactionMessageWithSingleSendingSigner<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer,\n>(transaction: TTransactionMessage): transaction is TransactionMessageWithSingleSendingSigner & TTransactionMessage {\n    try {\n        assertIsTransactionMessageWithSingleSendingSigner(transaction);\n        return true;\n    } catch {\n        return false;\n    }\n}\n\n/**\n * Asserts that the provided transaction message has exactly one {@link TransactionSendingSigner}.\n *\n * This can be useful when using the {@link signAndSendTransactionMessageWithSigners} function\n * to ensure it will be able to select the correct signer to send the transaction.\n *\n * @typeParam TTransactionMessage - The inferred type of the transaction message provided.\n *\n * @example\n * ```ts\n * import {\n *     assertIsTransactionMessageWithSingleSendingSigner,\n *     signAndSendTransactionMessageWithSigners\n * } from '@solana/signers';\n *\n * assertIsTransactionMessageWithSingleSendingSigner(transactionMessage);\n * const transactionSignature = await signAndSendTransactionMessageWithSigners(transactionMessage);\n * ```\n *\n * @see {@link signAndSendTransactionMessageWithSigners}\n * @see {@link isTransactionMessageWithSingleSendingSigner}\n */\nexport function assertIsTransactionMessageWithSingleSendingSigner<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer,\n>(\n    transaction: TTransactionMessage,\n): asserts transaction is TransactionMessageWithSingleSendingSigner & TTransactionMessage {\n    assertContainsResolvableTransactionSendingSigner(getSignersFromTransactionMessage(transaction));\n}\n\n/**\n * Asserts that the provided signers contain at least one {@link TransactionSendingSigner}\n * that can be unambiguously resolved.\n *\n * This means the signers must contain at least one sending signer, and at most one\n * sending-only signer (i.e. a signer that implements {@link TransactionSendingSigner}\n * but not {@link TransactionPartialSigner} or {@link TransactionModifyingSigner}).\n * Composite signers that also implement other interfaces can be demoted to non-sending\n * roles, so multiple composite sending signers are allowed.\n *\n * @param signers - The signers to check.\n * @throws {@link SolanaError} with code {@link SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING}\n * if no sending signer is found.\n * @throws {@link SolanaError} with code {@link SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS}\n * if more than one sending-only signer is found.\n *\n * @example\n * ```ts\n * assertContainsResolvableTransactionSendingSigner(mySigners);\n * const signature = await signAndSendTransactionWithSigners(mySigners, compiledTransaction);\n * ```\n *\n * @see {@link signAndSendTransactionWithSigners}\n * @see {@link assertIsTransactionMessageWithSingleSendingSigner}\n */\nexport function assertContainsResolvableTransactionSendingSigner(signers: readonly TransactionSigner[]) {\n    const sendingSigners = signers.filter(isTransactionSendingSigner);\n\n    if (sendingSigners.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_SENDING_SIGNER_MISSING);\n    }\n\n    // When identifying if there are multiple sending signers, we only need to check for\n    // sending signers that do not implement other transaction signer interfaces as\n    // they will be used as these other signer interfaces in case of a conflict.\n    const sendingOnlySigners = sendingSigners.filter(\n        signer => !isTransactionPartialSigner(signer) && !isTransactionModifyingSigner(signer),\n    );\n\n    if (sendingOnlySigners.length > 1) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__TRANSACTION_CANNOT_HAVE_MULTIPLE_SENDING_SIGNERS);\n    }\n}\n"
  },
  {
    "path": "packages/signers/src/types.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SignatureBytes } from '@solana/keys';\nimport { Slot } from '@solana/rpc-types';\n\nexport type SignatureDictionary = Readonly<Record<Address, SignatureBytes>>;\n\n/**\n * The base configuration object for all signers — including transaction and message signers.\n */\nexport type BaseSignerConfig = Readonly<{\n    /**\n     * An optional `AbortSignal` that can be used to cancel the signing process.\n     *\n     * @example\n     * ```ts\n     * import { generateKeyPairSigner } from '@solana/signers';\n     *\n     * const abortController = new AbortController();\n     * const signer = await generateKeyPairSigner();\n     * signer.signMessages([message], { abortSignal: abortController.signal });\n     * abortController.abort();\n     * ```\n     */\n    abortSignal?: AbortSignal;\n}>;\n\n/**\n * The base configuration object for transaction signers only.\n */\nexport interface BaseTransactionSignerConfig extends BaseSignerConfig {\n    /**\n     * Signers that simulate transactions (eg. wallets) might be interested in knowing which slot\n     * was current when the transaction was prepared. They can use this information to ensure that\n     * they don't run the simulation at too early a slot.\n     */\n    minContextSlot?: Slot;\n}\n"
  },
  {
    "path": "packages/signers/src/write-keypair-signer.ts",
    "content": "import { writeKeyPair, WriteKeyPairConfig } from '@solana/keys';\n\nimport { KeyPairSigner } from './keypair-signer';\n\nexport type { WriteKeyPairConfig };\n\n/**\n * Writes the {@link CryptoKeyPair} backing a {@link KeyPairSigner} to disk as a JSON array\n * of 64 bytes, matching the format produced by `solana-keygen`. The first 32 bytes are the\n * raw Ed25519 seed (private key) and the last 32 bytes are the raw public key.\n *\n * Any missing parent directories are created automatically. The written file uses mode\n * `0600` (owner read/write only) to match `solana-keygen`.\n *\n * This helper requires a writable filesystem and will throw in environments that don't\n * provide one (such as browsers or React Native).\n *\n * @param signer - A {@link KeyPairSigner} whose underlying {@link CryptoKeyPair} is\n * extractable (i.e. created via `generateKeyPairSigner(true)` or\n * `createKeyPairSignerFromBytes(bytes, true)`).\n * @param path - The destination path on disk.\n * @param config - See {@link WriteKeyPairConfig}.\n *\n * @throws A {@link SolanaError} of code\n * `SOLANA_ERROR__KEYS__WRITE_KEY_PAIR_UNSUPPORTED_ENVIRONMENT` when called in an\n * environment without a writable filesystem.\n * @throws A {@link SolanaError} of code\n * `SOLANA_ERROR__SUBTLE_CRYPTO__CANNOT_EXPORT_NON_EXTRACTABLE_KEY` when the signer's\n * underlying key pair is not extractable.\n *\n * @example\n * ```ts\n * import { generateKeyPairSigner, writeKeyPairSigner } from '@solana/signers';\n *\n * // Generate an extractable signer so its bytes can be persisted.\n * const signer = await generateKeyPairSigner(true);\n * await writeKeyPairSigner(signer, './my-keypair.json');\n * ```\n *\n * @example\n * Overwriting an existing file requires an explicit opt-in, because doing so permanently\n * destroys the previous key and any funds controlled by it:\n * ```ts\n * import { writeKeyPairSigner } from '@solana/signers';\n *\n * await writeKeyPairSigner(signer, './my-keypair.json', {\n *     unsafelyOverwriteExistingKeyPair: true,\n * });\n * ```\n *\n * @see {@link writeKeyPair} — the lower-level helper from `@solana/keys` that operates on\n * a raw {@link CryptoKeyPair}.\n * @see {@link createKeyPairSignerFromBytes} — the inverse helper that loads a signer from\n * a 64-byte buffer.\n */\nexport async function writeKeyPairSigner(\n    signer: KeyPairSigner,\n    path: string,\n    config?: WriteKeyPairConfig,\n): Promise<void> {\n    return await writeKeyPair(signer.keyPair, path, config);\n}\n"
  },
  {
    "path": "packages/signers/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/signers/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2017\", \"ES2019.Array\"]\n    },\n    \"display\": \"@solana/signers\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/signers/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\",\n    \"readme\": \"none\"\n}\n"
  },
  {
    "path": "packages/subscribable/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/subscribable/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/subscribable/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/subscribable/CHANGELOG.md",
    "content": "# @solana/subscribable\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/errors@6.9.0\n\n## 6.8.0\n\n### Minor Changes\n\n- [#1524](https://github.com/anza-xyz/kit/pull/1524) [`f53ce07`](https://github.com/anza-xyz/kit/commit/f53ce0796c782e79490e1cf11a55e28fb62b8c8f) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add `ReactiveStore` type and `createReactiveStoreFromDataPublisher()` to `@solana/subscribable`, and a `reactive()` method to pending subscriptions in `@solana/rpc-subscriptions-spec` that returns a reactive store compatible with `useSyncExternalStore`, Svelte stores, and other reactive primitives.\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/errors@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/errors@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f)]:\n    - @solana/errors@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065) Thanks [@steveluscher](https://github.com/steveluscher)! - Disabled the `MaxListenersExceededWarning` in Node when creating event targets for internal use\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3301](https://github.com/solana-labs/solana-web3.js/pull/3301) [`8c2cb9f`](https://github.com/solana-labs/solana-web3.js/commit/8c2cb9f44a52b3c27bc15c2c972bea1aae1622e7) Thanks [@steveluscher](https://github.com/steveluscher)! - Creates a package for working with subscribable data sources like event targets. From an `EventTarget` or object which conforms to the `EventEmitter` interface you can now create a more ergonomic `DataPublisher` (object with an `on` method that vends an unsubscribe function) or an abortable `AsyncIterable`.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/errors@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3301](https://github.com/solana-labs/solana-web3.js/pull/3301) [`8c2cb9f`](https://github.com/solana-labs/solana-web3.js/commit/8c2cb9f44a52b3c27bc15c2c972bea1aae1622e7) Thanks [@steveluscher](https://github.com/steveluscher)! - Creates a package for working with subscribable data sources like event targets. From an `EventTarget` or object which conforms to the `EventEmitter` interface you can now create a more ergonomic `DataPublisher` (object with an `on` method that vends an unsubscribe function) or an abortable `AsyncIterable`.\n\n- Updated dependencies [[`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0-rc.2\n"
  },
  {
    "path": "packages/subscribable/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/subscribable/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/subscribable?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/subscribable?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/subscribable\n\n# @solana/subscribable\n\nThis package contains utilities for creating subscription-based event targets. These differ from the `EventTarget` interface in that the method you use to add a listener returns an unsubscribe function. It is primarily intended for internal use &ndash; particularly for those building `RpcSubscriptionChannels` and associated infrastructure.\n\n## Types\n\n### `DataPublisher<TDataByChannelName>`\n\nThis type represents an object with an `on` function that you can call to subscribe to certain data over a named channel.\n\n```ts\nlet dataPublisher: DataPublisher<{ error: SolanaError }>;\ndataPublisher.on('data', handleData); // ERROR. `data` is not a known channel name.\ndataPublisher.on('error', e => {\n    console.error(e);\n}); // OK.\n```\n\n### `ReactiveStreamStore<T>`\n\nThis type represents a reactive store that holds the latest value published to a data channel. It exposes a `{ getUnifiedState, retry, subscribe }` contract compatible with `useSyncExternalStore`, Svelte stores, and other reactive primitives.\n\n`getUnifiedState()` returns a discriminated snapshot of the store's lifecycle:\n\n```ts\ntype ReactiveState<T> =\n    | { data: undefined; error: undefined; status: 'loading' }\n    | { data: T; error: undefined; status: 'loaded' }\n    | { data: T | undefined; error: unknown; status: 'error' }\n    | { data: T | undefined; error: undefined; status: 'retrying' };\n```\n\n> Also exported as `ReactiveStore<T>` for backwards compatibility. That alias is deprecated and will be removed in a future major release.\n\n```ts\nconst store: ReactiveStreamStore<AccountInfo> = /* ... */;\n\n// React — snapshot identity is stable between updates, so it can be passed directly.\nconst state = useSyncExternalStore(store.subscribe, store.getUnifiedState);\nif (state.status === 'error') return <ErrorMessage error={state.error} onRetry={store.retry} />;\nif (state.status === 'loading') return <Spinner />;\nreturn <View data={state.data} />;\n\n// Vue\nconst snapshot = shallowRef(store.getUnifiedState());\nstore.subscribe(() => {\n    snapshot.value = store.getUnifiedState();\n});\n```\n\n`retry()` re-opens the stream after an error. When the underlying store supports restart (see [`createReactiveStoreFromDataPublisherFactory`](#createreactivestorefromdatapublisherfactory-abortsignal-createdatapublisher-datachannelname-errorchannelname-)), the store transitions to `status: 'retrying'` and reconnects. Stores that cannot be restarted throw a `SolanaError` with code `SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED` instead.\n\nThe individual `getState()` and `getError()` getters on `ReactiveStreamStore<T>` are `@deprecated` &mdash; prefer `getUnifiedState()`, which exposes the same information with a stable snapshot identity and `status` discriminator.\n\n### `ReactiveActionStore<TArgs, TResult>`\n\nA framework-agnostic state machine for wrapping an async action (a function you dispatch on demand — like a form submission, a mutation, or an on-click fetch). It exposes a `{ dispatch, getState, subscribe, reset }` contract that bridges trivially into `useSyncExternalStore`, Svelte stores, Vue's `shallowRef`, and similar reactive primitives.\n\nThe snapshot is a discriminated union:\n\n```ts\ntype ReactiveActionState<TResult> =\n    | { status: 'idle'; data: undefined; error: undefined }\n    | { status: 'running'; data: TResult | undefined; error: undefined }\n    | { status: 'success'; data: TResult; error: undefined }\n    | { status: 'error'; data: TResult | undefined; error: unknown };\n```\n\n`data` is the last successful result and survives across transitions — a `running` or `error` snapshot still carries the last value so UIs can render stale content while a retry is in flight. Only `reset()` clears it.\n\nUnlike `ReactiveStreamStore<T>` (which models a stream of values with a separate error channel), `ReactiveActionStore` models a one-shot-per-dispatch lifecycle where errors are part of the snapshot.\n\n### `TypedEventEmitter<TEventMap>`\n\nThis type allows you to type `addEventListener` and `removeEventListener` so that the call signature of the listener matches the event type given.\n\n```ts\nconst emitter: TypedEventEmitter<{ message: MessageEvent }> = new WebSocket('wss://api.devnet.solana.com');\nemitter.addEventListener('data', handleData); // ERROR. `data` is not a known event type.\nemitter.addEventListener('message', message => {\n    console.log(message.origin); // OK. `message` is a `MessageEvent` so it has an `origin` property.\n});\n```\n\n### `TypedEventTarget<TEventMap>`\n\nThis type is a superset of `TypedEventEmitter` that allows you to constrain calls to `dispatchEvent`.\n\n```ts\nconst target: TypedEventTarget<{ candyVended: CustomEvent<{ flavour: string }> }> = new EventTarget();\ntarget.dispatchEvent(new CustomEvent('candyVended', { detail: { flavour: 'raspberry' } })); // OK.\ntarget.dispatchEvent(new CustomEvent('candyVended', { detail: { flavor: 'raspberry' } })); // ERROR. Misspelling in detail.\n```\n\n## Functions\n\n### `createReactiveActionStore(fn)`\n\nWraps an async function in a `ReactiveActionStore`. Each `dispatch` creates a fresh `AbortController` and aborts the previous one, so a rapid succession of dispatches only produces one final state transition — the outcome of the most recent call. The wrapped function receives the `AbortSignal` as its first argument, followed by the arguments passed to `dispatch`.\n\n```tsx\nconst store = createReactiveActionStore(async (signal: AbortSignal, accountId: Address) => {\n    const response = await fetch(`/api/accounts/${accountId}`, { signal });\n    return response.json();\n});\n\n// React — stale-while-revalidate: keep showing the card during retries.\nconst { data, error, status } = useSyncExternalStore(store.subscribe, store.getState);\nreturn (\n    <>\n        {data !== undefined && <AccountCard account={data} />}\n        {status === 'running' && <InlineSpinner />}\n        {status === 'error' && <RetryBanner error={error} onRetry={() => store.dispatch(someAccountId)} />}\n        {status === 'idle' && data === undefined && <button onClick={() => store.dispatch(someAccountId)}>Load</button>}\n    </>\n);\n```\n\nThings to note:\n\n- Starts at `{ status: 'idle' }`. `getState()` always returns a defined snapshot.\n- `dispatch` is a stable reference — safe to pass into memoized callbacks without re-renders.\n- Two ways to trigger the action:\n    - `dispatch(...)` — fire-and-forget. Returns `undefined` synchronously and never throws; safe to call from UI event handlers without a `.catch`. Failures surface on state as `{ status: 'error' }`.\n    - `dispatchAsync(...)` — returns a promise that resolves to the wrapped function's result. Rejects on failure and with an `AbortError` when superseded or `reset()`. Use from imperative code that needs the resolved value; pair with [`isAbortError`](../promises#isaborterrorerr) from `@solana/promises` to filter abort rejections.\n- Calling either dispatch while one is in flight aborts the previous call; its outcome is dropped from state regardless of which variant started it.\n- `data` survives across transitions: a fresh `running` or `error` snapshot carries the last successful result so call sites can keep rendering stale content while a retry is in flight. Only `reset()` clears it.\n- `reset()` aborts the in-flight dispatch and restores the idle snapshot, clearing both `data` and `error`.\n- Subscribers are notified only when the snapshot's `status`, `data`, or `error` actually changes, so redundant transitions (`dispatch` while already `running` with the same `data`, `reset` while already `idle`) are silent.\n- `fn` is captured at construction, so the store holds a closure over whatever `fn` referenced at that moment. In React, create the store once (`useState(() => createReactiveActionStore(...))` or `useRef`) and read the latest closure through a ref if you need it to change between renders — don't call `createReactiveActionStore` directly in a render body.\n- The store holds strong references to its subscribers. Non-framework consumers that subscribe without unsubscribing will keep their listeners (and anything the listeners close over) alive for the lifetime of the store.\n\n### `createAsyncIterableFromDataPublisher({ abortSignal, dataChannelName, dataPublisher, errorChannelName })`\n\nReturns an `AsyncIterable` given a data publisher. The iterable will produce iterators that vend messages published to `dataChannelName` and will throw the first time a message is published to `errorChannelName`. Triggering the abort signal will cause all iterators spawned from this iterator to return once they have published all queued messages.\n\n```ts\nconst iterable = createAsyncIterableFromDataPublisher({\n    abortSignal: AbortSignal.timeout(10_000),\n    dataChannelName: 'message',\n    dataPublisher,\n    errorChannelName: 'error',\n});\ntry {\n    for await (const message of iterable) {\n        console.log('Got message', message);\n    }\n} catch (e) {\n    console.error('An error was published to the error channel', e);\n} finally {\n    console.log(\"It's been 10 seconds; that's enough for now.\");\n}\n```\n\nThings to note:\n\n- If a message is published over a channel before the `AsyncIterator` attached to it has polled for the next result, the message will be queued in memory.\n- Messages only begin to be queued after the first time an iterator begins to poll. Channel messages published before that time will be dropped.\n- If there are messages in the queue and an error occurs, all queued messages will be vended to the iterator before the error is thrown.\n- If there are messages in the queue and the abort signal fires, all queued messages will be vended to the iterator after which it will return.\n- Any new iterators created after the first error is encountered will reject with that error when polled.\n\n### `createReactiveStoreFromDataPublisher({ abortSignal, dataChannelName, dataPublisher, errorChannelName })`\n\n> **Deprecated.** Prefer [`createReactiveStoreFromDataPublisherFactory`](#createreactivestorefromdatapublisherfactory-abortsignal-createdatapublisher-datachannelname-errorchannelname-) &mdash; it supports `retry()`. Because this function accepts a ready-made `DataPublisher` rather than a factory, it cannot restart the underlying source, and calling `retry()` on the returned store throws a `SolanaError` with code `SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED`.\n\nReturns a `ReactiveStreamStore` given a data publisher. The store holds the most recent message published to `dataChannelName` and notifies subscribers on each update. When a message is published to `errorChannelName`, the store transitions to `status: 'error'` preserving the last known value. Triggering the abort signal disconnects the store from the data publisher.\n\n```ts\nconst store = createReactiveStoreFromDataPublisher({\n    abortSignal: AbortSignal.timeout(10_000),\n    dataChannelName: 'notification',\n    dataPublisher,\n    errorChannelName: 'error',\n});\nconst unsubscribe = store.subscribe(() => {\n    console.log('State updated:', store.getUnifiedState());\n});\n```\n\nThings to note:\n\n- `getUnifiedState()` starts in `status: 'loading'` until the first notification arrives.\n- On error, `status` becomes `'error'` with the last known value preserved on `data`. Only the first error is captured.\n- The function returned by `subscribe` is idempotent &mdash; calling it multiple times is safe.\n\n### `createReactiveStoreFromDataPublisherFactory({ abortSignal, createDataPublisher, dataChannelName, errorChannelName })`\n\nReturns a `ReactiveStreamStore` that wires itself to a fresh `DataPublisher` on construction and on every `retry()`. Unlike `createReactiveStoreFromDataPublisher`, this variant accepts an async factory so the store can tear down a broken stream and open a new one without losing subscribers or the last known value.\n\n```ts\nconst store = createReactiveStoreFromDataPublisherFactory({\n    abortSignal: AbortSignal.timeout(60_000),\n    async createDataPublisher() {\n        return await openMyConnection();\n    },\n    dataChannelName: 'notification',\n    errorChannelName: 'error',\n});\nstore.subscribe(() => {\n    const snapshot = store.getUnifiedState();\n    if (snapshot.status === 'error') store.retry();\n});\n```\n\nThings to note:\n\n- `createDataPublisher` is called once on construction and again on every `retry()`.\n- `retry()` is a no-op unless the store is in `status: 'error'`; otherwise the store transitions to `status: 'retrying'` (preserving stale data) and reconnects.\n- If `createDataPublisher` rejects, the store transitions to `status: 'error'` with the rejection as the error. Call `retry()` to try again.\n- Triggering the caller's `abortSignal` disconnects the store permanently; subsequent `retry()` calls are no-ops.\n\n### `demultiplexDataPublisher(publisher, sourceChannelName, messageTransformer)`\n\nGiven a channel that carries messages for multiple subscribers on a single channel name, this function returns a new `DataPublisher` that splits them into multiple channel names.\n\nImagine a channel that carries multiple notifications whose destination is contained within the message itself.\n\n```ts\nconst demuxedDataPublisher = demultiplexDataPublisher(channel, 'message', message => {\n    const destinationChannelName = `notification-for:${message.subscriberId}`;\n    return [destinationChannelName, message];\n});\n```\n\nNow you can subscribe to _only_ the messages you are interested in, without having to subscribe to the entire `'message'` channel and filter out the messages that are not for you.\n\n```ts\ndemuxedDataPublisher.on(\n    'notification-for:123',\n    message => {\n        console.log('Got a message for subscriber 123', message);\n    },\n    { signal: AbortSignal.timeout(5_000) },\n);\n```\n\n### `getDataPublisherFromEventEmitter(emitter)`\n\nReturns an object with an `on` function that you can call to subscribe to certain data over a named channel. The `on` function returns an unsubscribe function.\n\n```ts\nconst socketDataPublisher = getDataPublisherFromEventEmitter(new WebSocket('wss://api.devnet.solana.com'));\nconst unsubscribe = socketDataPublisher.on('message', message => {\n    if (JSON.parse(message.data).id === 42) {\n        console.log('Got response 42');\n        unsubscribe();\n    }\n});\n```\n"
  },
  {
    "path": "packages/subscribable/package.json",
    "content": "{\n    \"name\": \"@solana/subscribable\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for creating subscription-based event emitters\",\n    \"homepage\": \"https://www.solanakit.com/api#solanasubscribable\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/promises\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/event-target-impl\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/subscribable/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/subscribable/src/__tests__/async-iterable-test.ts",
    "content": "import { createAsyncIterableFromDataPublisher } from '../async-iterable';\nimport { DataPublisher } from '../data-publisher';\n\ndescribe('createAsyncIterableFromDataPublisher', () => {\n    let mockDataPublisher: DataPublisher;\n    let mockOn: jest.Mock;\n    function publish(type: string, payload: unknown) {\n        mockOn.mock.calls.filter(([actualType]) => actualType === type).forEach(([_, listener]) => listener(payload));\n    }\n    beforeEach(() => {\n        mockOn = jest.fn().mockReturnValue(function unsubscribe() {});\n        mockDataPublisher = {\n            on: mockOn,\n        };\n    });\n    it('returns from the iterator when the abort signal starts aborted', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        abortController.abort();\n        const iterable = createAsyncIterableFromDataPublisher({\n            abortSignal: abortController.signal,\n            dataChannelName: 'data',\n            dataPublisher: mockDataPublisher,\n            errorChannelName: 'error',\n        });\n        const iterator = iterable[Symbol.asyncIterator]();\n        const nextDataPromise = iterator.next();\n        await expect(nextDataPromise).resolves.toMatchObject({\n            done: true,\n            value: undefined,\n        });\n    });\n    it('returns from the iterator when the abort signal fires', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        const iterable = createAsyncIterableFromDataPublisher({\n            abortSignal: abortController.signal,\n            dataChannelName: 'data',\n            dataPublisher: mockDataPublisher,\n            errorChannelName: 'error',\n        });\n        const iterator = iterable[Symbol.asyncIterator]();\n        const nextDataPromise = iterator.next();\n        abortController.abort();\n        await expect(nextDataPromise).resolves.toMatchObject({\n            done: true,\n            value: undefined,\n        });\n    });\n    it('throws the first published error through newly created iterators', async () => {\n        expect.assertions(1);\n        const iterable = createAsyncIterableFromDataPublisher({\n            abortSignal: new AbortController().signal,\n            dataChannelName: 'data',\n            dataPublisher: mockDataPublisher,\n            errorChannelName: 'error',\n        });\n        publish('error', new Error('o no'));\n        publish('error', new Error('also o no'));\n        const iterator = iterable[Symbol.asyncIterator]();\n        const nextDataPromise = iterator.next();\n        await expect(nextDataPromise).rejects.toThrow(new Error('o no'));\n    });\n    it('returns from the iterator on the next poll after an error', async () => {\n        expect.assertions(1);\n        const iterable = createAsyncIterableFromDataPublisher({\n            abortSignal: new AbortController().signal,\n            dataChannelName: 'data',\n            dataPublisher: mockDataPublisher,\n            errorChannelName: 'error',\n        });\n        publish('error', new Error('o no'));\n        const iterator = iterable[Symbol.asyncIterator]();\n        iterator.next().catch(() => {});\n        const dataPromiseAfterError = iterator.next();\n        await expect(dataPromiseAfterError).resolves.toStrictEqual({\n            done: true,\n            value: undefined,\n        });\n    });\n    describe('given that no iterator has yet been polled', () => {\n        let abortController: AbortController;\n        let iterable: AsyncIterable<unknown>;\n        let iterator: AsyncIterator<unknown>;\n        beforeEach(() => {\n            abortController = new AbortController();\n            iterable = createAsyncIterableFromDataPublisher({\n                abortSignal: abortController.signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            iterator = iterable[Symbol.asyncIterator]();\n        });\n        it('drops data published before polling begins', async () => {\n            expect.assertions(1);\n            publish('data', 'lost message');\n            const nextDataPromise = iterator.next();\n            publish('data', 'hi');\n            await expect(nextDataPromise).resolves.toStrictEqual({\n                done: false,\n                value: 'hi',\n            });\n        });\n        it('vends the first error received when the iterator is eventually polled', async () => {\n            expect.assertions(1);\n            publish('error', new Error('o no'));\n            publish('error', new Error('also o no'));\n            const nextDataPromise = iterator.next();\n            await expect(nextDataPromise).rejects.toThrow(new Error('o no'));\n        });\n        it('returns when the iterator is eventually polled, the iterator having already been aborted', async () => {\n            expect.assertions(1);\n            abortController.abort();\n            const nextDataPromise = iterator.next();\n            await expect(nextDataPromise).resolves.toStrictEqual({\n                done: true,\n                value: undefined,\n            });\n        });\n    });\n    describe('given that multiple consumers have begun to poll', () => {\n        let abortController: AbortController;\n        let iteratorA: AsyncIterator<unknown>;\n        let iteratorB: AsyncIterator<unknown>;\n        let nextDataPromiseA: Promise<unknown>;\n        let nextDataPromiseB: Promise<unknown>;\n        beforeEach(() => {\n            abortController = new AbortController();\n            const iterable = createAsyncIterableFromDataPublisher({\n                abortSignal: abortController.signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            iteratorA = iterable[Symbol.asyncIterator]();\n            iteratorB = iterable[Symbol.asyncIterator]();\n            nextDataPromiseA = iteratorA.next();\n            nextDataPromiseB = iteratorB.next();\n        });\n        it('throws from all iterators when an error is published', async () => {\n            expect.assertions(2);\n            publish('error', new Error('o no'));\n            await expect(nextDataPromiseA).rejects.toThrow(new Error('o no'));\n            await expect(nextDataPromiseB).rejects.toThrow(new Error('o no'));\n        });\n        it('vends a message to all iterators who have already polled for a result', async () => {\n            expect.assertions(2);\n            publish('data', 'hi');\n            await expect(nextDataPromiseA).resolves.toStrictEqual({\n                done: false,\n                value: 'hi',\n            });\n            await expect(nextDataPromiseB).resolves.toStrictEqual({\n                done: false,\n                value: 'hi',\n            });\n        });\n        it('queues messages for all iterators', async () => {\n            expect.assertions(4);\n            publish('data', 'consumed message');\n            publish('data', 'queued message 1');\n            publish('data', 'queued message 2');\n            await expect(iteratorA.next()).resolves.toStrictEqual({\n                done: false,\n                value: 'queued message 1',\n            });\n            await expect(iteratorB.next()).resolves.toStrictEqual({\n                done: false,\n                value: 'queued message 1',\n            });\n            await expect(iteratorA.next()).resolves.toStrictEqual({\n                done: false,\n                value: 'queued message 2',\n            });\n            await expect(iteratorB.next()).resolves.toStrictEqual({\n                done: false,\n                value: 'queued message 2',\n            });\n        });\n        it('flushes the queue before vending errors', async () => {\n            expect.assertions(4);\n            publish('data', 'consumed message');\n            publish('data', 'queued message 1');\n            publish('error', new Error('o no'));\n            await expect(iteratorA.next()).resolves.toStrictEqual({\n                done: false,\n                value: 'queued message 1',\n            });\n            await expect(iteratorB.next()).resolves.toStrictEqual({\n                done: false,\n                value: 'queued message 1',\n            });\n            await expect(iteratorA.next()).rejects.toThrow(new Error('o no'));\n            await expect(iteratorB.next()).rejects.toThrow(new Error('o no'));\n        });\n        it('flushes the queue before an abort finalizes it', async () => {\n            expect.assertions(4);\n            publish('data', 'consumed message');\n            publish('data', 'queued message 1');\n            abortController.abort();\n            await expect(iteratorA.next()).resolves.toStrictEqual({\n                done: false,\n                value: 'queued message 1',\n            });\n            await expect(iteratorB.next()).resolves.toStrictEqual({\n                done: false,\n                value: 'queued message 1',\n            });\n            await expect(iteratorA.next()).resolves.toStrictEqual({\n                done: true,\n                value: undefined,\n            });\n            await expect(iteratorB.next()).resolves.toStrictEqual({\n                done: true,\n                value: undefined,\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/subscribable/src/__tests__/data-publisher-test.ts",
    "content": "import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from '../data-publisher';\n\ndescribe('a data publisher', () => {\n    let dataPublisher: DataPublisher;\n    let eventTarget: EventTarget;\n    beforeEach(() => {\n        eventTarget = new EventTarget();\n        dataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n    });\n    it('calls a subscriber with no arguments when the event is an `Event`', () => {\n        const subscriber = jest.fn();\n        dataPublisher.on('someEvent', subscriber);\n        eventTarget.dispatchEvent(new Event('someEvent'));\n        expect(subscriber).toHaveBeenCalledWith();\n    });\n    it('calls a subscriber with `null` when the event is a `CustomEvent` with no `detail`', () => {\n        const subscriber = jest.fn();\n        dataPublisher.on('someEvent', subscriber);\n        eventTarget.dispatchEvent(new CustomEvent('someEvent'));\n        expect(subscriber).toHaveBeenCalledWith(null);\n    });\n    it('calls a subscriber with the `detail` of a `CustomEvent`', () => {\n        const subscriber = jest.fn();\n        dataPublisher.on('someEvent', subscriber);\n        eventTarget.dispatchEvent(new CustomEvent('someEvent', { detail: 123 }));\n        expect(subscriber).toHaveBeenCalledWith(123);\n    });\n    it('does not call a subscriber after the unsubscribe function is called', () => {\n        const subscriber = jest.fn();\n        const unsubscribe = dataPublisher.on('someEvent', subscriber);\n        unsubscribe();\n        eventTarget.dispatchEvent(new Event('someEvent'));\n        expect(subscriber).not.toHaveBeenCalled();\n    });\n    it('does not call a subscriber after its abort signal fires', () => {\n        const subscriber = jest.fn();\n        const abortController = new AbortController();\n        dataPublisher.on('someEvent', subscriber, { signal: abortController.signal });\n        abortController.abort();\n        eventTarget.dispatchEvent(new Event('someEvent'));\n        expect(subscriber).not.toHaveBeenCalled();\n    });\n    it('does not fatal when the unsubscribe method is called more than once', () => {\n        const subscriber = jest.fn();\n        const unsubscribe = dataPublisher.on('someEvent', subscriber);\n        unsubscribe();\n        expect(() => {\n            unsubscribe();\n        }).not.toThrow();\n    });\n    it('keeps other subscribers subscribed when unsubcribing from others', () => {\n        const subscriberA = jest.fn();\n        const subscriberB = jest.fn();\n        dataPublisher.on('someEvent', subscriberA);\n        const unsubscribeB = dataPublisher.on('someEvent', subscriberB);\n        unsubscribeB();\n        eventTarget.dispatchEvent(new Event('someEvent'));\n        expect(subscriberA).toHaveBeenCalled();\n    });\n    it('keeps other subscribers subscribed when the abort signal of another fires', () => {\n        const subscriberA = jest.fn();\n        const subscriberB = jest.fn();\n        const abortController = new AbortController();\n        dataPublisher.on('someEvent', subscriberA);\n        dataPublisher.on('someEvent', subscriberB, { signal: abortController.signal });\n        abortController.abort();\n        eventTarget.dispatchEvent(new Event('someEvent'));\n        expect(subscriberA).toHaveBeenCalled();\n    });\n    it('does not notify a subscriber about an event with a type different than the one it is interested in', () => {\n        const subscriber = jest.fn();\n        dataPublisher.on('someEvent', subscriber);\n        eventTarget.dispatchEvent(new Event('someOtherEvent'));\n        expect(subscriber).not.toHaveBeenCalled();\n    });\n});\n"
  },
  {
    "path": "packages/subscribable/src/__tests__/demultiplex-test.ts",
    "content": "import { demultiplexDataPublisher } from '../demultiplex';\n\ndescribe('demultiplexDataPublisher', () => {\n    let mockDataPublisher: { on: jest.Mock };\n    function publishMessage(channelName: string, message: unknown) {\n        mockDataPublisher.on.mock.calls\n            .filter(([actualChannelName]) => actualChannelName === channelName)\n            .forEach(([_, listener]) => listener(message));\n    }\n    beforeEach(() => {\n        mockDataPublisher = {\n            on: jest.fn(),\n        };\n    });\n    it('does not listen to the publisher when there are no subscribers', () => {\n        demultiplexDataPublisher(mockDataPublisher, 'channelName', jest.fn() /* messageTransformer */);\n        expect(mockDataPublisher.on).not.toHaveBeenCalled();\n    });\n    it('starts to listen to the publisher when a subscriber appears', () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        demuxedDataPublisher.on('someChannelName', () => {});\n        expect(mockDataPublisher.on).toHaveBeenCalledTimes(1);\n    });\n    it('only listens to the publisher once despite multiple subscriptions', () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        demuxedDataPublisher.on('someChannelName', () => {});\n        demuxedDataPublisher.on('someOtherChannelName', () => {});\n        expect(mockDataPublisher.on).toHaveBeenCalledTimes(1);\n    });\n    it('unsubscribes from the publisher once the last subscriber unsubscribes', () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        const mockUnsubscribe = jest.fn();\n        mockDataPublisher.on.mockReturnValue(mockUnsubscribe);\n        const unsubscribe = demuxedDataPublisher.on('someChannelName', () => {});\n        unsubscribe();\n        expect(mockUnsubscribe).toHaveBeenCalledTimes(1);\n    });\n    it('does not unsubscribe from the publisher if there are still subscribers after some having unsubscribed', () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        const mockUnsubscribe = jest.fn();\n        mockDataPublisher.on.mockReturnValue(mockUnsubscribe);\n        const unsubscribe = demuxedDataPublisher.on('someChannelName', () => {});\n        demuxedDataPublisher.on('someChannelName', () => {});\n        unsubscribe();\n        expect(mockUnsubscribe).not.toHaveBeenCalled();\n    });\n    it(\"does not unsubscribe from the publisher when one subscriber's unsubscribe function is called as many times as there are subscriptions\", () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        const mockUnsubscribe = jest.fn();\n        mockDataPublisher.on.mockReturnValue(mockUnsubscribe);\n        const unsubscribeA = demuxedDataPublisher.on('someChannelName', () => {});\n        demuxedDataPublisher.on('someOtherChannelName', () => {});\n        // No matter how many times the unsubscribe function is called, it only decrements the\n        // subscriber count once, for its own subscription.\n        unsubscribeA();\n        unsubscribeA();\n        expect(mockUnsubscribe).not.toHaveBeenCalled();\n    });\n    it('unsubscribes from the publisher once the last subscriber aborts', () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        const mockUnsubscribe = jest.fn();\n        mockDataPublisher.on.mockReturnValue(mockUnsubscribe);\n        const abortController = new AbortController();\n        demuxedDataPublisher.on('someChannelName', () => {}, { signal: abortController.signal });\n        abortController.abort();\n        expect(mockUnsubscribe).toHaveBeenCalledTimes(1);\n    });\n    it('does not unsubscribe from the publisher if there are still subscribers after some having aborted', () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        const mockUnsubscribe = jest.fn();\n        mockDataPublisher.on.mockReturnValue(mockUnsubscribe);\n        const abortController = new AbortController();\n        demuxedDataPublisher.on('someChannelName', () => {}, { signal: abortController.signal });\n        demuxedDataPublisher.on('someChannelName', () => {});\n        abortController.abort();\n        expect(mockUnsubscribe).not.toHaveBeenCalled();\n    });\n    it(\"does not unsubscribe from the publisher when one subscriber's abort signal is fired as many times as there are subscriptions\", () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        const mockUnsubscribe = jest.fn();\n        mockDataPublisher.on.mockReturnValue(mockUnsubscribe);\n        const abortController = new AbortController();\n        demuxedDataPublisher.on('someChannelName', () => {}, { signal: abortController.signal });\n        demuxedDataPublisher.on('someOtherChannelName', () => {});\n        // No matter how many times the abort signal is fired, it only decrements the subscriber\n        // count once, for its own subscription.\n        abortController.abort();\n        abortController.abort();\n        expect(mockUnsubscribe).not.toHaveBeenCalled();\n    });\n    it(\"does not unsubscribe from the publisher when one subscriber's unsubscribe function is called and its abort signal fires for a total of as many cancellations as there are subscriptions\", () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(\n            mockDataPublisher,\n            'channelName',\n            jest.fn() /* messageTransformer */,\n        );\n        const mockUnsubscribe = jest.fn();\n        mockDataPublisher.on.mockReturnValue(mockUnsubscribe);\n        const abortControllerA = new AbortController();\n        const unsubscribeA = demuxedDataPublisher.on('someChannelName', () => {}, { signal: abortControllerA.signal });\n        demuxedDataPublisher.on('someOtherChannelName', () => {});\n        // No matter how many times the unsubscribe function is called, it only decrements the\n        // subscriber count once, for its own subscription.\n        unsubscribeA();\n        abortControllerA.abort();\n        expect(mockUnsubscribe).not.toHaveBeenCalled();\n    });\n    it('does not call the transform function when there are no subscribers yet', () => {\n        const mockMessageTransformer = jest.fn().mockReturnValue([]);\n        demultiplexDataPublisher(mockDataPublisher, 'channelName', mockMessageTransformer);\n        publishMessage('channelName', 'hi');\n        expect(mockMessageTransformer).not.toHaveBeenCalled();\n    });\n    it('calls the transform function for every event that matches the source channel name when there is at least one subscriber', () => {\n        const mockMessageTransformer = jest.fn().mockReturnValue([]);\n        const demuxedDataPublisher = demultiplexDataPublisher(mockDataPublisher, 'channelName', mockMessageTransformer);\n        demuxedDataPublisher.on('channelName', () => {});\n        publishMessage('channelName', 'hi');\n        expect(mockMessageTransformer).toHaveBeenCalledWith('hi');\n    });\n    it('does not call the transform function when the event does not match the source channel name', () => {\n        const mockMessageTransformer = jest.fn().mockReturnValue([]);\n        demultiplexDataPublisher(mockDataPublisher, 'channelName', mockMessageTransformer);\n        publishMessage('otherChannelName', 'o no');\n        expect(mockMessageTransformer).not.toHaveBeenCalled();\n    });\n    it('publishes a message on the demuxed channel with the name returned by the transformer', () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(mockDataPublisher, 'channelName', () => [\n            'transformedChannelName',\n            'HI',\n        ]);\n        const transformedChannelListener = jest.fn();\n        demuxedDataPublisher.on('transformedChannelName', transformedChannelListener);\n        publishMessage('channelName', 'hi');\n        expect(transformedChannelListener).toHaveBeenCalledWith('HI');\n    });\n    it('publishes no message on the demuxed channel if the transformer returns `undefined`', () => {\n        const demuxedDataPublisher = demultiplexDataPublisher(mockDataPublisher, 'channelName', () => {});\n        const transformedChannelListener = jest.fn();\n        demuxedDataPublisher.on('transformedChannelName', transformedChannelListener);\n        publishMessage('channelName', 'hi');\n        expect(transformedChannelListener).not.toHaveBeenCalled();\n    });\n});\n"
  },
  {
    "path": "packages/subscribable/src/__tests__/reactive-action-store-test.ts",
    "content": "import { createReactiveActionStore } from '../reactive-action-store';\n\ndescribe('createReactiveActionStore', () => {\n    it('starts in the `idle` state', () => {\n        const store = createReactiveActionStore(() => Promise.resolve('never'));\n        expect(store.getState()).toStrictEqual({\n            data: undefined,\n            error: undefined,\n            status: 'idle',\n        });\n    });\n\n    it('transitions `idle` → `running` → `success` on a successful dispatch', async () => {\n        expect.assertions(2);\n        const { promise, resolve } = Promise.withResolvers<number>();\n        const store = createReactiveActionStore(() => promise);\n        const dispatched = store.dispatchAsync();\n        expect(store.getState()).toStrictEqual({\n            data: undefined,\n            error: undefined,\n            status: 'running',\n        });\n        resolve(42);\n        await dispatched;\n        expect(store.getState()).toStrictEqual({\n            data: 42,\n            error: undefined,\n            status: 'success',\n        });\n    });\n\n    it('transitions `idle` → `running` → `error` when the dispatch rejects', async () => {\n        expect.assertions(2);\n        const { promise, reject } = Promise.withResolvers<number>();\n        const store = createReactiveActionStore(() => promise);\n        const dispatched = store.dispatchAsync();\n        expect(store.getState()).toStrictEqual({\n            data: undefined,\n            error: undefined,\n            status: 'running',\n        });\n        const failure = new Error('boom');\n        reject(failure);\n        await dispatched.catch(() => {});\n        expect(store.getState()).toStrictEqual({\n            data: undefined,\n            error: failure,\n            status: 'error',\n        });\n    });\n\n    it('returns `undefined` synchronously from `dispatch`', () => {\n        const store = createReactiveActionStore(() => Promise.reject(new Error('boom')));\n        expect(store.dispatch()).toBeUndefined();\n    });\n\n    it('rejects `dispatchAsync` on failure so callers can `try/catch`', async () => {\n        expect.assertions(1);\n        const store = createReactiveActionStore(() => Promise.reject(new Error('boom')));\n        await expect(store.dispatchAsync()).rejects.toThrow('boom');\n    });\n\n    it('resolves `dispatchAsync` with the wrapped function result on success', async () => {\n        expect.assertions(1);\n        const store = createReactiveActionStore(() => Promise.resolve(42));\n        await expect(store.dispatchAsync()).resolves.toBe(42);\n    });\n\n    it('forwards the `AbortSignal` as the first argument of the wrapped function', async () => {\n        expect.assertions(1);\n        const fn = jest.fn<Promise<string>, [AbortSignal, string, number]>(() => Promise.resolve('ok'));\n        const store = createReactiveActionStore(fn);\n        await store.dispatchAsync('hello', 7);\n        expect(fn.mock.calls).toStrictEqual([[expect.any(AbortSignal), 'hello', 7]]);\n    });\n\n    it('aborts an in-flight dispatch when a new dispatch supersedes it', () => {\n        const signals: AbortSignal[] = [];\n        const store = createReactiveActionStore((signal: AbortSignal) => {\n            signals.push(signal);\n            return new Promise<string>(() => {});\n        });\n        store.dispatch();\n        store.dispatch();\n        expect(signals[0].aborted).toBe(true);\n    });\n\n    it('rejects a superseded `dispatchAsync` with an `AbortError`', async () => {\n        expect.assertions(1);\n        const store = createReactiveActionStore(() => new Promise<string>(() => {}));\n        const first = store.dispatchAsync();\n        store.dispatch();\n        await expect(first).rejects.toMatchObject({ name: 'AbortError' });\n    });\n\n    it('rejects `dispatchAsync` with an `AbortError` if superseded after `fn` resolves but before the continuation runs', async () => {\n        expect.assertions(1);\n        const { promise, resolve } = Promise.withResolvers<string>();\n        const store = createReactiveActionStore(() => promise);\n        const first = store.dispatchAsync();\n        resolve('stale');\n        // Let the wrapper promise resolve, then synchronously supersede before\n        // `dispatchAsync`'s await continuation runs.\n        await Promise.resolve();\n        store.dispatch();\n        await expect(first).rejects.toMatchObject({ name: 'AbortError' });\n    });\n\n    it('rejects `dispatchAsync` with an `AbortError` if superseded after `fn` rejects but before the continuation runs', async () => {\n        expect.assertions(1);\n        const { promise, reject } = Promise.withResolvers<string>();\n        const store = createReactiveActionStore(() => promise);\n        const first = store.dispatchAsync();\n        reject(new Error('nope'));\n        // Let the wrapper promise reject, then synchronously supersede before\n        // `dispatchAsync`'s catch continuation runs — caller should see AbortError,\n        // not the masked real error.\n        await Promise.resolve();\n        store.dispatch();\n        await expect(first).rejects.toMatchObject({ name: 'AbortError' });\n    });\n\n    it('reflects only the most recent dispatch when two dispatches run in quick succession', async () => {\n        expect.assertions(1);\n        const { promise: firstPromise, resolve: resolveFirst } = Promise.withResolvers<string>();\n        const { promise: secondPromise, resolve: resolveSecond } = Promise.withResolvers<string>();\n        const results = [firstPromise, secondPromise];\n        const store = createReactiveActionStore(() => results.shift()!);\n        store.dispatch();\n        const second = store.dispatchAsync();\n        resolveSecond('second');\n        await second;\n        expect(store.getState()).toStrictEqual({\n            data: 'second',\n            error: undefined,\n            status: 'success',\n        });\n        resolveFirst('first');\n    });\n\n    it('does not overwrite the superseding call when a superseded call rejects later', async () => {\n        expect.assertions(1);\n        const { promise: firstPromise, reject: rejectFirst } = Promise.withResolvers<string>();\n        const { promise: secondPromise, resolve: resolveSecond } = Promise.withResolvers<string>();\n        const results = [firstPromise, secondPromise];\n        const store = createReactiveActionStore(() => results.shift()!);\n        store.dispatch();\n        const second = store.dispatchAsync();\n        resolveSecond('winner');\n        await second;\n        rejectFirst(new Error('late loser'));\n        await Promise.resolve();\n        await Promise.resolve();\n        expect(store.getState()).toStrictEqual({\n            data: 'winner',\n            error: undefined,\n            status: 'success',\n        });\n    });\n\n    it('does not overwrite the idle state when a superseded call resolves after `reset`', async () => {\n        expect.assertions(1);\n        const { promise, resolve } = Promise.withResolvers<string>();\n        const store = createReactiveActionStore(() => promise);\n        store.dispatch();\n        store.reset();\n        resolve('stale');\n        await Promise.resolve();\n        await Promise.resolve();\n        expect(store.getState()).toStrictEqual({\n            data: undefined,\n            error: undefined,\n            status: 'idle',\n        });\n    });\n\n    describe('reset()', () => {\n        it('returns the store to idle from a success state', async () => {\n            expect.assertions(1);\n            const store = createReactiveActionStore(() => Promise.resolve('ok'));\n            await store.dispatchAsync();\n            store.reset();\n            expect(store.getState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'idle',\n            });\n        });\n\n        it('returns the store to idle from an error state', async () => {\n            expect.assertions(1);\n            const store = createReactiveActionStore(() => Promise.reject(new Error('boom')));\n            await store.dispatchAsync().catch(() => {});\n            store.reset();\n            expect(store.getState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'idle',\n            });\n        });\n\n        it('aborts an in-flight dispatch', () => {\n            const signals: AbortSignal[] = [];\n            const store = createReactiveActionStore((signal: AbortSignal) => {\n                signals.push(signal);\n                return new Promise<string>(() => {});\n            });\n            store.dispatch();\n            store.reset();\n            expect(signals[0].aborted).toBe(true);\n        });\n\n        it('rejects an in-flight `dispatchAsync` with an `AbortError`', async () => {\n            expect.assertions(1);\n            const store = createReactiveActionStore(() => new Promise<string>(() => {}));\n            const dispatched = store.dispatchAsync();\n            store.reset();\n            await expect(dispatched).rejects.toMatchObject({ name: 'AbortError' });\n        });\n    });\n\n    describe('subscribe()', () => {\n        it('notifies listeners on transition to `running`', () => {\n            const store = createReactiveActionStore(() => new Promise<string>(() => {}));\n            const listener = jest.fn();\n            store.subscribe(listener);\n            store.dispatch();\n            expect(listener).toHaveBeenCalledTimes(1);\n        });\n\n        it('notifies listeners on transition to `success`', async () => {\n            expect.assertions(1);\n            const { promise, resolve } = Promise.withResolvers<string>();\n            const store = createReactiveActionStore(() => promise);\n            const dispatched = store.dispatchAsync();\n            const listener = jest.fn();\n            store.subscribe(listener);\n            resolve('ok');\n            await dispatched;\n            expect(listener).toHaveBeenCalledTimes(1);\n        });\n\n        it('notifies listeners on transition to `error`', async () => {\n            expect.assertions(1);\n            const { promise, reject } = Promise.withResolvers<string>();\n            const store = createReactiveActionStore(() => promise);\n            const dispatched = store.dispatchAsync();\n            const listener = jest.fn();\n            store.subscribe(listener);\n            reject(new Error('boom'));\n            await dispatched.catch(() => {});\n            expect(listener).toHaveBeenCalledTimes(1);\n        });\n\n        it('does not notify listeners that unsubscribed before the transition', async () => {\n            expect.assertions(1);\n            const store = createReactiveActionStore(() => Promise.resolve('ok'));\n            const listener = jest.fn();\n            const unsubscribe = store.subscribe(listener);\n            unsubscribe();\n            await store.dispatchAsync();\n            expect(listener).not.toHaveBeenCalled();\n        });\n\n        it('notifies multiple listeners independently', async () => {\n            expect.assertions(2);\n            const store = createReactiveActionStore(() => Promise.resolve('ok'));\n            const listenerA = jest.fn();\n            const listenerB = jest.fn();\n            store.subscribe(listenerA);\n            store.subscribe(listenerB);\n            await store.dispatchAsync();\n            expect(listenerA).toHaveBeenCalledTimes(2);\n            expect(listenerB).toHaveBeenCalledTimes(2);\n        });\n\n        it('the unsubscribe function is idempotent', () => {\n            const store = createReactiveActionStore(() => Promise.resolve('ok'));\n            const unsubscribe = store.subscribe(jest.fn());\n            expect(() => {\n                unsubscribe();\n                unsubscribe();\n            }).not.toThrow();\n        });\n\n        it('notifies on reset() from a non-idle state', async () => {\n            expect.assertions(1);\n            const store = createReactiveActionStore(() => Promise.resolve('ok'));\n            await store.dispatchAsync();\n            const listener = jest.fn();\n            store.subscribe(listener);\n            store.reset();\n            expect(listener).toHaveBeenCalledTimes(1);\n        });\n\n        it('does not notify on reset() when already idle', () => {\n            const store = createReactiveActionStore(() => Promise.resolve('ok'));\n            const listener = jest.fn();\n            store.subscribe(listener);\n            store.reset();\n            expect(listener).not.toHaveBeenCalled();\n        });\n\n        it('does not notify on a superseding dispatch when the state is already `running`', () => {\n            const store = createReactiveActionStore(() => new Promise<string>(() => {}));\n            store.dispatch();\n            const listener = jest.fn();\n            store.subscribe(listener);\n            store.dispatch();\n            expect(listener).not.toHaveBeenCalled();\n        });\n    });\n\n    it('has a stable `dispatch` reference across state changes', async () => {\n        expect.assertions(1);\n        const store = createReactiveActionStore(() => Promise.resolve('ok'));\n        const initial = store.dispatch;\n        await store.dispatchAsync();\n        store.reset();\n        expect(store.dispatch).toBe(initial);\n    });\n\n    it('returns a stable snapshot reference for the `idle` state across resets', async () => {\n        expect.assertions(1);\n        const store = createReactiveActionStore(() => Promise.resolve('ok'));\n        const idleBefore = store.getState();\n        await store.dispatchAsync();\n        store.reset();\n        expect(store.getState()).toBe(idleBefore);\n    });\n\n    describe('stale-while-revalidate', () => {\n        it('preserves the last successful `data` across a subsequent `running` state', async () => {\n            expect.assertions(1);\n            const { promise: second, resolve: resolveSecond } = Promise.withResolvers<string>();\n            const results = [Promise.resolve('first'), second];\n            const store = createReactiveActionStore(() => results.shift()!);\n            await store.dispatchAsync();\n            store.dispatch();\n            expect(store.getState()).toStrictEqual({\n                data: 'first',\n                error: undefined,\n                status: 'running',\n            });\n            resolveSecond('second');\n        });\n\n        it('preserves the last successful `data` across a subsequent `error` state', async () => {\n            expect.assertions(1);\n            const failure = new Error('boom');\n            const results = [Promise.resolve('first'), Promise.reject(failure)];\n            const store = createReactiveActionStore(() => results.shift()!);\n            await store.dispatchAsync();\n            await store.dispatchAsync().catch(() => {});\n            expect(store.getState()).toStrictEqual({\n                data: 'first',\n                error: failure,\n                status: 'error',\n            });\n        });\n\n        it('replaces stale `data` when a subsequent dispatch succeeds with a new value', async () => {\n            expect.assertions(1);\n            const results = [Promise.resolve('first'), Promise.resolve('second')];\n            const store = createReactiveActionStore(() => results.shift()!);\n            await store.dispatchAsync();\n            await store.dispatchAsync();\n            expect(store.getState()).toStrictEqual({\n                data: 'second',\n                error: undefined,\n                status: 'success',\n            });\n        });\n\n        it('clears a previous error once a subsequent dispatch succeeds', async () => {\n            expect.assertions(1);\n            const results = [Promise.reject(new Error('boom')), Promise.resolve('ok')];\n            const store = createReactiveActionStore(() => results.shift()!);\n            await store.dispatchAsync().catch(() => {});\n            await store.dispatchAsync();\n            expect(store.getState()).toStrictEqual({\n                data: 'ok',\n                error: undefined,\n                status: 'success',\n            });\n        });\n\n        it('clears `data` on reset()', async () => {\n            expect.assertions(1);\n            const store = createReactiveActionStore(() => Promise.resolve('ok'));\n            await store.dispatchAsync();\n            store.reset();\n            expect(store.getState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'idle',\n            });\n        });\n\n        it('does not restore stale `data` after reset() when a new dispatch runs', () => {\n            const { promise } = Promise.withResolvers<string>();\n            const results = [Promise.resolve('first'), promise];\n            const store = createReactiveActionStore(() => results.shift()!);\n            store.dispatch();\n            store.reset();\n            store.dispatch();\n            expect(store.getState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'running',\n            });\n        });\n\n        it('keeps `data` undefined in the error state when no prior success occurred', async () => {\n            expect.assertions(1);\n            const failure = new Error('boom');\n            const store = createReactiveActionStore(() => Promise.reject(failure));\n            await store.dispatchAsync().catch(() => {});\n            expect(store.getState()).toStrictEqual({\n                data: undefined,\n                error: failure,\n                status: 'error',\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/subscribable/src/__tests__/reactive-stream-store-test.ts",
    "content": "import { SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport { DataPublisher } from '../data-publisher';\nimport {\n    createReactiveStoreFromDataPublisher,\n    createReactiveStoreFromDataPublisherFactory,\n} from '../reactive-stream-store';\n\njest.useFakeTimers();\n\ndescribe('createReactiveStoreFromDataPublisher', () => {\n    let mockDataPublisher: DataPublisher;\n    let mockOn: jest.Mock;\n    function publish(type: string, payload: unknown) {\n        mockOn.mock.calls.filter(([actualType]) => actualType === type).forEach(([_, listener]) => listener(payload));\n    }\n    beforeEach(() => {\n        mockOn = jest.fn().mockReturnValue(function unsubscribe() {});\n        mockDataPublisher = {\n            on: mockOn,\n        };\n    });\n\n    describe('getState()', () => {\n        it('returns `undefined` before any notification arrives', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            expect(store.getState()).toBeUndefined();\n        });\n        it('returns the latest notification after one arrives', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            publish('data', { value: 42 });\n            expect(store.getState()).toStrictEqual({ value: 42 });\n        });\n        it('returns the most recent notification when multiple arrive', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            publish('data', { value: 1 });\n            publish('data', { value: 2 });\n            publish('data', { value: 3 });\n            expect(store.getState()).toStrictEqual({ value: 3 });\n        });\n        it('preserves the last known value after an error', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            publish('data', { value: 42 });\n            publish('error', new Error('o no'));\n            expect(store.getState()).toStrictEqual({ value: 42 });\n        });\n        it('returns `undefined` after an error when no notification has arrived', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            publish('error', new Error('o no'));\n            expect(store.getState()).toBeUndefined();\n        });\n    });\n\n    describe('getError()', () => {\n        it('returns `undefined` before any error', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            expect(store.getError()).toBeUndefined();\n        });\n        it('returns the error after one arrives', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const error = new Error('o no');\n            publish('error', error);\n            expect(store.getError()).toBe(error);\n        });\n        it('preserves the first error when multiple errors arrive', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const firstError = new Error('first');\n            const secondError = new Error('second');\n            publish('error', firstError);\n            publish('error', secondError);\n            expect(store.getError()).toBe(firstError);\n        });\n        it('remains `undefined` when only data notifications arrive', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            publish('data', { value: 1 });\n            publish('data', { value: 2 });\n            expect(store.getError()).toBeUndefined();\n        });\n    });\n\n    describe('getUnifiedState()', () => {\n        it('starts in `loading` status with no data or error', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'loading',\n            });\n        });\n        it('transitions to `loaded` with the value when a notification arrives', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            publish('data', { value: 42 });\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { value: 42 },\n                error: undefined,\n                status: 'loaded',\n            });\n        });\n        it('transitions to `error` preserving the last known value', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const error = new Error('o no');\n            publish('data', { value: 42 });\n            publish('error', error);\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { value: 42 },\n                error,\n                status: 'error',\n            });\n        });\n        it('transitions to `error` with undefined data when no value arrived first', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const error = new Error('o no');\n            publish('error', error);\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error,\n                status: 'error',\n            });\n        });\n    });\n\n    describe('retry()', () => {\n        it('throws a SolanaError because a raw DataPublisher cannot be restarted', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            expect(() => store.retry()).toThrow(new SolanaError(SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED));\n        });\n    });\n\n    describe('subscribe()', () => {\n        it('calls the subscriber when a notification arrives', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            publish('data', { value: 1 });\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('calls the subscriber on each new notification', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            publish('data', { value: 1 });\n            publish('data', { value: 2 });\n            publish('data', { value: 3 });\n            expect(subscriber).toHaveBeenCalledTimes(3);\n        });\n        it('calls the subscriber when an error arrives', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            publish('error', new Error('o no'));\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('does not notify subscribers on subsequent errors', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            publish('error', new Error('first'));\n            publish('error', new Error('second'));\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('calls multiple concurrent subscribers on each notification', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const subscriberA = jest.fn();\n            const subscriberB = jest.fn();\n            store.subscribe(subscriberA);\n            store.subscribe(subscriberB);\n            publish('data', { value: 1 });\n            expect(subscriberA).toHaveBeenCalledTimes(1);\n            expect(subscriberB).toHaveBeenCalledTimes(1);\n        });\n        it('stops calling the subscriber after the returned unsubscribe is called', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const subscriber = jest.fn();\n            const unsubscribe = store.subscribe(subscriber);\n            unsubscribe();\n            publish('data', { value: 1 });\n            expect(subscriber).not.toHaveBeenCalled();\n        });\n        it('only unsubscribes the subscriber whose unsubscribe function was called', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const subscriberA = jest.fn();\n            const subscriberB = jest.fn();\n            const unsubscribeA = store.subscribe(subscriberA);\n            store.subscribe(subscriberB);\n            unsubscribeA();\n            publish('data', { value: 1 });\n            expect(subscriberA).not.toHaveBeenCalled();\n            expect(subscriberB).toHaveBeenCalledTimes(1);\n        });\n        it('the unsubscribe function is idempotent', () => {\n            const store = createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const unsubscribe = store.subscribe(jest.fn());\n            expect(() => {\n                unsubscribe();\n                unsubscribe();\n            }).not.toThrow();\n        });\n    });\n\n    describe('abort signal', () => {\n        it('aborts the signals forwarded to dataPublisher.on() when the caller aborts', () => {\n            const abortController = new AbortController();\n            createReactiveStoreFromDataPublisher({\n                abortSignal: abortController.signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const dataChannelSignal = mockOn.mock.calls.find(([type]: [string]) => type === 'data')![2].signal;\n            const errorChannelSignal = mockOn.mock.calls.find(([type]: [string]) => type === 'error')![2].signal;\n            expect(dataChannelSignal.aborted).toBe(false);\n            expect(errorChannelSignal.aborted).toBe(false);\n            const reason = new Error('go away');\n            abortController.abort(reason);\n            expect(dataChannelSignal.aborted).toBe(true);\n            expect(dataChannelSignal.reason).toBe(reason);\n            expect(errorChannelSignal.aborted).toBe(true);\n            expect(errorChannelSignal.reason).toBe(reason);\n        });\n        it('aborts the signals forwarded to dataPublisher.on() when an error arrives', () => {\n            createReactiveStoreFromDataPublisher({\n                abortSignal: new AbortController().signal,\n                dataChannelName: 'data',\n                dataPublisher: mockDataPublisher,\n                errorChannelName: 'error',\n            });\n            const dataChannelSignal = mockOn.mock.calls.find(([type]: [string]) => type === 'data')![2].signal;\n            const errorChannelSignal = mockOn.mock.calls.find(([type]: [string]) => type === 'error')![2].signal;\n            expect(dataChannelSignal.aborted).toBe(false);\n            expect(errorChannelSignal.aborted).toBe(false);\n            const error = new Error('o no');\n            publish('error', error);\n            expect(dataChannelSignal.aborted).toBe(true);\n            expect(dataChannelSignal.reason).toBe(error);\n            expect(errorChannelSignal.aborted).toBe(true);\n            expect(errorChannelSignal.reason).toBe(error);\n        });\n    });\n});\n\ndescribe('createReactiveStoreFromDataPublisherFactory', () => {\n    function createMockDataPublisher(): {\n        mockOn: jest.Mock;\n        publish(channel: string, payload: unknown): void;\n        publisher: DataPublisher;\n    } {\n        const mockOn = jest.fn().mockReturnValue(function unsubscribe() {});\n        return {\n            mockOn,\n            publish(channel: string, payload: unknown) {\n                mockOn.mock.calls\n                    .filter(\n                        ([actualChannel, , options]: [string, unknown, { signal?: AbortSignal } | undefined]) =>\n                            actualChannel === channel && !options?.signal?.aborted,\n                    )\n                    .forEach(([_, listener]) => listener(payload));\n            },\n            publisher: { on: mockOn },\n        };\n    }\n\n    // Helper: returns a factory that hands out a fresh mock DataPublisher per invocation, plus\n    // a parallel array of those publishers for test assertions.\n    function createFactory() {\n        const publishers: ReturnType<typeof createMockDataPublisher>[] = [];\n        const mockRequest = jest.fn().mockImplementation(() => {\n            const p = createMockDataPublisher();\n            publishers.push(p);\n            return Promise.resolve(p.publisher);\n        });\n        return { mockRequest, publishers };\n    }\n\n    describe('initial connection', () => {\n        it('starts in `loading` before the factory resolves', () => {\n            const { mockRequest } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: undefined,\n                status: 'loading',\n            });\n        });\n        it('transitions to `loaded` once the factory resolves and data arrives', async () => {\n            expect.assertions(1);\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            publishers[0].publish('data', { value: 42 });\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { value: 42 },\n                error: undefined,\n                status: 'loaded',\n            });\n        });\n        it('transitions to `error` when the factory rejects', async () => {\n            expect.assertions(1);\n            const failure = new Error('connection refused');\n            const mockRequest = jest.fn().mockRejectedValue(failure);\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: failure,\n                status: 'error',\n            });\n        });\n        it('transitions to `error` on an error channel message, preserving the last known value', async () => {\n            expect.assertions(1);\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            publishers[0].publish('data', { value: 42 });\n            const failure = new Error('stream died');\n            publishers[0].publish('error', failure);\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { value: 42 },\n                error: failure,\n                status: 'error',\n            });\n        });\n    });\n\n    describe('retry()', () => {\n        it('is a no-op when the store is not in `error` state', async () => {\n            expect.assertions(2);\n            const { mockRequest } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            const callsBefore = mockRequest.mock.calls.length;\n            store.retry();\n            expect(mockRequest).toHaveBeenCalledTimes(callsBefore);\n            expect(store.getUnifiedState().status).toBe('loading');\n        });\n        it('transitions to `retrying` and preserves stale data', async () => {\n            expect.assertions(1);\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            publishers[0].publish('data', { value: 42 });\n            publishers[0].publish('error', new Error('fail'));\n            store.retry();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { value: 42 },\n                error: undefined,\n                status: 'retrying',\n            });\n        });\n        it('invokes the factory a second time', async () => {\n            expect.assertions(1);\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            publishers[0].publish('error', new Error('fail'));\n            store.retry();\n            expect(mockRequest).toHaveBeenCalledTimes(2);\n        });\n        it('transitions back to `loaded` when the retried stream publishes a value', async () => {\n            expect.assertions(1);\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            publishers[0].publish('error', new Error('fail'));\n            store.retry();\n            await jest.runAllTimersAsync();\n            publishers[1].publish('data', { value: 'recovered' });\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { value: 'recovered' },\n                error: undefined,\n                status: 'loaded',\n            });\n        });\n        it('notifies subscribers on the retrying transition', async () => {\n            expect.assertions(1);\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            publishers[0].publish('error', new Error('fail'));\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            store.retry();\n            expect(subscriber).toHaveBeenCalledTimes(1);\n        });\n        it('can recover from a factory-rejection error by retrying', async () => {\n            expect.assertions(2);\n            const publisher = createMockDataPublisher();\n            const mockRequest = jest\n                .fn()\n                .mockRejectedValueOnce(new Error('transient'))\n                .mockResolvedValue(publisher.publisher);\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState().status).toBe('error');\n            store.retry();\n            await jest.runAllTimersAsync();\n            publisher.publish('data', { value: 99 });\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: { value: 99 },\n                error: undefined,\n                status: 'loaded',\n            });\n        });\n        it('transitions back to `error` when the retried factory rejects again', async () => {\n            expect.assertions(1);\n            const firstFailure = new Error('first');\n            const secondFailure = new Error('second');\n            const mockRequest = jest.fn().mockRejectedValueOnce(firstFailure).mockRejectedValue(secondFailure);\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: new AbortController().signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            store.retry();\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: secondFailure,\n                status: 'error',\n            });\n        });\n    });\n\n    describe('abort signal', () => {\n        it('prevents further state updates once the caller aborts', async () => {\n            expect.assertions(1);\n            const abortController = new AbortController();\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: abortController.signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            abortController.abort();\n            publishers[0].publish('data', { value: 'late' });\n            expect(store.getUnifiedState().status).toBe('loading');\n        });\n        it('aborts the signal forwarded to the inner DataPublisher listeners', async () => {\n            expect.assertions(2);\n            const abortController = new AbortController();\n            const { mockRequest, publishers } = createFactory();\n            createReactiveStoreFromDataPublisherFactory({\n                abortSignal: abortController.signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            const dataSignal = publishers[0].mockOn.mock.calls.find(([channel]: [string]) => channel === 'data')![2]\n                .signal;\n            expect(dataSignal.aborted).toBe(false);\n            abortController.abort();\n            expect(dataSignal.aborted).toBe(true);\n        });\n        it('retry() after abort does not re-invoke the factory', async () => {\n            expect.assertions(1);\n            const abortController = new AbortController();\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: abortController.signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            publishers[0].publish('error', new Error('fail'));\n            abortController.abort();\n            const callsBefore = mockRequest.mock.calls.length;\n            store.retry();\n            await jest.runAllTimersAsync();\n            expect(mockRequest).toHaveBeenCalledTimes(callsBefore);\n        });\n        it('retry() after abort leaves the store in `error` state', async () => {\n            expect.assertions(1);\n            const abortController = new AbortController();\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: abortController.signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            const failure = new Error('fail');\n            publishers[0].publish('error', failure);\n            abortController.abort();\n            store.retry();\n            await jest.runAllTimersAsync();\n            expect(store.getUnifiedState()).toStrictEqual({\n                data: undefined,\n                error: failure,\n                status: 'error',\n            });\n        });\n        it('retry() after abort does not notify subscribers', async () => {\n            expect.assertions(1);\n            const abortController = new AbortController();\n            const { mockRequest, publishers } = createFactory();\n            const store = createReactiveStoreFromDataPublisherFactory({\n                abortSignal: abortController.signal,\n                createDataPublisher: mockRequest,\n                dataChannelName: 'data',\n                errorChannelName: 'error',\n            });\n            await jest.runAllTimersAsync();\n            publishers[0].publish('error', new Error('fail'));\n            abortController.abort();\n            const subscriber = jest.fn();\n            store.subscribe(subscriber);\n            store.retry();\n            await jest.runAllTimersAsync();\n            expect(subscriber).not.toHaveBeenCalled();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/subscribable/src/__typetests__/data-publisher-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-ts-comment */\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from '../data-publisher';\nimport { TypedEventEmitter, TypedEventTarget } from '../event-emitter';\n\ntype ChannelMap = {\n    fall: null;\n    jump: { height: number };\n    run: { velocity: number };\n};\nconst publisher = null as unknown as DataPublisher<ChannelMap>;\n\n// [DESCRIBE] getDataPublisherFromEventEmitter\n{\n    // It materializes listener signatures based on the events of an event emitter\n    {\n        const eventEmitter = null as unknown as TypedEventEmitter<{\n            baz: Event;\n            foo: CustomEvent<'bar'>;\n        }>;\n        const publisher = getDataPublisherFromEventEmitter(eventEmitter);\n        publisher.on('foo', data => {\n            data satisfies 'bar';\n        });\n        publisher.on('baz', (...args) => {\n            // @ts-ignore FIXME: The actual implementation supplies no arguments, not `null`\n            args satisfies [];\n        });\n    }\n    // It materializes listener signatures based on the events of an event target\n    {\n        const eventTarget = null as unknown as TypedEventTarget<{\n            baz: Event;\n            foo: CustomEvent<'bar'>;\n        }>;\n        const publisher = getDataPublisherFromEventEmitter(eventTarget);\n        publisher.on('foo', data => {\n            data satisfies 'bar';\n        });\n        publisher.on('baz', (...args) => {\n            // @ts-ignore FIXME: The actual implementation supplies no arguments, not `null`\n            args satisfies [];\n        });\n    }\n}\n\n// [DESCRIBE] DataPublisher\n{\n    // It adds listeners for known types\n    {\n        publisher.on('fall', () => {});\n        publisher.on('jump', () => {});\n        publisher.on('run', () => {});\n    }\n    // It rejects adding listeners for unknown types\n    {\n        publisher.on(\n            // @ts-expect-error\n            'roll',\n            () => {},\n        );\n    }\n    // It accepts adding listeners with the appropriate signature\n    {\n        publisher.on('fall', data => {\n            data satisfies null;\n        });\n        publisher.on('jump', data => {\n            data satisfies { height: number };\n        });\n        publisher.on('run', data => {\n            data satisfies { velocity: number };\n        });\n    }\n    // It rejects adding listeners with inappropriate signatures\n    {\n        publisher.on('fall', data => {\n            // @ts-expect-error\n            data satisfies { style: string };\n        });\n    }\n}\n"
  },
  {
    "path": "packages/subscribable/src/__typetests__/event-emitter-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-ts-comment */\n\nimport { TypedEventEmitter, TypedEventTarget } from '../event-emitter';\n\ntype EventMap = {\n    fall: Event;\n    jump: CustomEvent<{ height: number }>;\n    run: CustomEvent<{ velocity: number }>;\n};\nconst emitter = null as unknown as TypedEventEmitter<EventMap>;\n\n// [DESCRIBE] TypedEventEmitter\n{\n    // It adds listeners for known types\n    {\n        emitter.addEventListener('fall', () => {});\n        emitter.addEventListener('jump', () => {});\n        emitter.addEventListener('run', () => {});\n    }\n    // It removes listeners for known types\n    {\n        emitter.removeEventListener('fall', () => {});\n        emitter.removeEventListener('jump', () => {});\n        emitter.removeEventListener('run', () => {});\n    }\n    // It rejects adding listeners for unknown types\n    {\n        emitter.addEventListener(\n            // @ts-expect-error\n            'roll',\n            () => {},\n        );\n    }\n    // It rejects removing listeners for unknown types\n    {\n        emitter.removeEventListener(\n            // @ts-expect-error\n            'roll',\n            () => {},\n        );\n    }\n    // It accepts adding listeners with the appropriate signature\n    {\n        emitter.addEventListener('fall', ev => {\n            ev satisfies Event;\n        });\n        emitter.addEventListener('jump', ev => {\n            ev satisfies CustomEvent<{ height: number }>;\n        });\n        emitter.addEventListener('run', ev => {\n            ev satisfies CustomEvent<{ velocity: number }>;\n        });\n    }\n    // It accepts removing listeners with the appropriate signature\n    {\n        emitter.removeEventListener('fall', ev => {\n            ev satisfies Event;\n        });\n        emitter.removeEventListener('jump', ev => {\n            ev satisfies CustomEvent<{ height: number }>;\n        });\n        emitter.removeEventListener('run', ev => {\n            ev satisfies CustomEvent<{ velocity: number }>;\n        });\n    }\n    // It rejects adding listeners with inappropriate signatures\n    {\n        emitter.addEventListener('fall', ev => {\n            // @ts-expect-error\n            ev satisfies CustomEvent<{ style: string }>;\n        });\n    }\n    // It rejects removing listeners with inappropriate signatures\n    {\n        emitter.removeEventListener('fall', ev => {\n            // @ts-expect-error\n            ev satisfies CustomEvent<{ style: string }>;\n        });\n    }\n}\n\n// [DESCRIBE] TypedEventTarget\n{\n    // It is a TypedEventEmitter\n    {\n        const eventTarget = null as unknown as TypedEventTarget<{ foo: CustomEvent<'bar'> }>;\n        eventTarget satisfies TypedEventEmitter<{ foo: CustomEvent<'bar'> }>;\n    }\n}\n"
  },
  {
    "path": "packages/subscribable/src/async-iterable.ts",
    "content": "import {\n    SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n    SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING,\n    SolanaError,\n} from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n    /**\n     * Triggering this abort signal will cause all iterators spawned from this iterator to return\n     * once they have published all queued messages.\n     */\n    abortSignal: AbortSignal;\n    /**\n     * Messages from this channel of `dataPublisher` will be the ones yielded through the iterators.\n     *\n     * Messages only begin to be queued after the first time an iterator begins to poll. Channel\n     * messages published before that time will be dropped.\n     */\n    dataChannelName: string;\n    // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n    //        definitely supports the `dataChannelName` and `errorChannelName` channels, and\n    //        furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n    //        than it should be: https://tsplay.dev/NlZelW\n    dataPublisher: DataPublisher;\n    /**\n     * Messages from this channel of `dataPublisher` will be the ones thrown through the iterators.\n     *\n     * Any new iterators created after the first error is encountered will reject with that error\n     * when polled.\n     */\n    errorChannelName: string;\n}>;\n\nconst enum PublishType {\n    DATA,\n    ERROR,\n}\n\ntype IteratorKey = symbol;\ntype IteratorState<TData> =\n    | {\n          __hasPolled: false;\n          publishQueue: (\n              | {\n                    __type: PublishType.DATA;\n                    data: TData;\n                }\n              | {\n                    __type: PublishType.ERROR;\n                    err: unknown;\n                }\n          )[];\n      }\n    | {\n          __hasPolled: true;\n          onData: (data: TData) => void;\n          onError: Parameters<ConstructorParameters<typeof Promise>[0]>[1];\n      };\n\nlet EXPLICIT_ABORT_TOKEN: symbol;\nfunction createExplicitAbortToken() {\n    // This function is an annoying workaround to prevent `process.env.NODE_ENV` from appearing at\n    // the top level of this module and thwarting an optimizing compiler's attempt to tree-shake.\n    return Symbol(\n        __DEV__\n            ? \"This symbol is thrown from a socket's iterator when the connection is explicitly \" +\n                  'aborted by the user'\n            : undefined,\n    );\n}\n\nconst UNINITIALIZED = Symbol();\n\n/**\n * Returns an `AsyncIterable` given a data publisher.\n *\n * The iterable will produce iterators that vend messages published to `dataChannelName` and will\n * throw the first time a message is published to `errorChannelName`. Triggering the abort signal\n * will cause all iterators spawned from this iterator to return once they have published all queued\n * messages.\n *\n * Things to note:\n *\n * - If a message is published over a channel before the `AsyncIterator` attached to it has polled\n *   for the next result, the message will be queued in memory.\n * - Messages only begin to be queued after the first time an iterator begins to poll. Channel\n *   messages published before that time will be dropped.\n * - If there are messages in the queue and an error occurs, all queued messages will be vended to\n *   the iterator before the error is thrown.\n * - If there are messages in the queue and the abort signal fires, all queued messages will be\n *   vended to the iterator after which it will return.\n * - Any new iterators created after the first error is encountered will reject with that error when\n *   polled.\n *\n * @param config\n *\n * @example\n * ```ts\n * const iterable = createAsyncIterableFromDataPublisher({\n *     abortSignal: AbortSignal.timeout(10_000),\n *     dataChannelName: 'message',\n *     dataPublisher,\n *     errorChannelName: 'error',\n * });\n * try {\n *     for await (const message of iterable) {\n *         console.log('Got message', message);\n *     }\n * } catch (e) {\n *     console.error('An error was published to the error channel', e);\n * } finally {\n *     console.log(\"It's been 10 seconds; that's enough for now.\");\n * }\n * ```\n */\nexport function createAsyncIterableFromDataPublisher<TData>({\n    abortSignal,\n    dataChannelName,\n    dataPublisher,\n    errorChannelName,\n}: Config): AsyncIterable<TData> {\n    const iteratorState: Map<IteratorKey, IteratorState<TData>> = new Map();\n    function publishErrorToAllIterators(reason: unknown) {\n        for (const [iteratorKey, state] of iteratorState.entries()) {\n            if (state.__hasPolled) {\n                iteratorState.delete(iteratorKey);\n                state.onError(reason);\n            } else {\n                state.publishQueue.push({\n                    __type: PublishType.ERROR,\n                    err: reason,\n                });\n            }\n        }\n    }\n    const abortController = new AbortController();\n    abortSignal.addEventListener('abort', () => {\n        abortController.abort();\n        publishErrorToAllIterators((EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken()));\n    });\n    const options = { signal: abortController.signal } as const;\n    let firstError: unknown = UNINITIALIZED;\n    dataPublisher.on(\n        errorChannelName,\n        err => {\n            if (firstError === UNINITIALIZED) {\n                firstError = err;\n                abortController.abort();\n                publishErrorToAllIterators(err);\n            }\n        },\n        options,\n    );\n    dataPublisher.on(\n        dataChannelName,\n        data => {\n            iteratorState.forEach((state, iteratorKey) => {\n                if (state.__hasPolled) {\n                    const { onData } = state;\n                    iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n                    onData(data as TData);\n                } else {\n                    state.publishQueue.push({\n                        __type: PublishType.DATA,\n                        data: data as TData,\n                    });\n                }\n            });\n        },\n        options,\n    );\n    return {\n        async *[Symbol.asyncIterator]() {\n            if (abortSignal.aborted) {\n                return;\n            }\n            if (firstError !== UNINITIALIZED) {\n                throw firstError;\n            }\n            const iteratorKey = Symbol();\n            iteratorState.set(iteratorKey, { __hasPolled: false, publishQueue: [] });\n            try {\n                while (true) {\n                    const state = iteratorState.get(iteratorKey);\n                    if (!state) {\n                        // There should always be state by now.\n                        throw new SolanaError(SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_STATE_MISSING);\n                    }\n                    if (state.__hasPolled) {\n                        // You should never be able to poll twice in a row.\n                        throw new SolanaError(\n                            SOLANA_ERROR__INVARIANT_VIOLATION__SUBSCRIPTION_ITERATOR_MUST_NOT_POLL_BEFORE_RESOLVING_EXISTING_MESSAGE_PROMISE,\n                        );\n                    }\n                    const publishQueue = state.publishQueue;\n                    try {\n                        if (publishQueue.length) {\n                            state.publishQueue = [];\n                            for (const item of publishQueue) {\n                                if (item.__type === PublishType.DATA) {\n                                    yield item.data;\n                                } else {\n                                    throw item.err;\n                                }\n                            }\n                        } else {\n                            yield await new Promise<TData>((resolve, reject) => {\n                                iteratorState.set(iteratorKey, {\n                                    __hasPolled: true,\n                                    onData: resolve,\n                                    onError: reject,\n                                });\n                            });\n                        }\n                    } catch (e) {\n                        if (e === (EXPLICIT_ABORT_TOKEN ||= createExplicitAbortToken())) {\n                            return;\n                        } else {\n                            throw e;\n                        }\n                    }\n                }\n            } finally {\n                iteratorState.delete(iteratorKey);\n            }\n        },\n    };\n}\n"
  },
  {
    "path": "packages/subscribable/src/data-publisher.ts",
    "content": "import { TypedEventEmitter, TypedEventTarget } from './event-emitter';\n\ntype UnsubscribeFn = () => void;\n\n/**\n * Represents an object with an `on` function that you can call to subscribe to certain data over a\n * named channel.\n *\n * @example\n * ```ts\n * let dataPublisher: DataPublisher<{ error: SolanaError }>;\n * dataPublisher.on('data', handleData); // ERROR. `data` is not a known channel name.\n * dataPublisher.on('error', e => {\n *     console.error(e);\n * }); // OK.\n * ```\n */\nexport interface DataPublisher<TDataByChannelName extends Record<string, unknown> = Record<string, unknown>> {\n    /**\n     * Call this to subscribe to data over a named channel.\n     *\n     * @param channelName The name of the channel on which to subscribe for messages\n     * @param subscriber The function to call when a message becomes available\n     * @param options.signal An abort signal you can fire to unsubscribe\n     *\n     * @returns A function that you can call to unsubscribe\n     */\n    on<const TChannelName extends keyof TDataByChannelName>(\n        channelName: TChannelName,\n        subscriber: (data: TDataByChannelName[TChannelName]) => void,\n        options?: { signal: AbortSignal },\n    ): UnsubscribeFn;\n}\n\n/**\n * Returns an object with an `on` function that you can call to subscribe to certain data over a\n * named channel.\n *\n * The `on` function returns an unsubscribe function.\n *\n * @example\n * ```ts\n * const socketDataPublisher = getDataPublisherFromEventEmitter(new WebSocket('wss://api.devnet.solana.com'));\n * const unsubscribe = socketDataPublisher.on('message', message => {\n *     if (JSON.parse(message.data).id === 42) {\n *         console.log('Got response 42');\n *         unsubscribe();\n *     }\n * });\n * ```\n */\nexport function getDataPublisherFromEventEmitter<TEventMap extends Record<string, Event>>(\n    eventEmitter: TypedEventEmitter<TEventMap> | TypedEventTarget<TEventMap>,\n): DataPublisher<{\n    [TEventType in keyof TEventMap]: TEventMap[TEventType] extends CustomEvent ? TEventMap[TEventType]['detail'] : null;\n}> {\n    return {\n        on(channelName, subscriber, options) {\n            function innerListener(ev: Event) {\n                if (ev instanceof CustomEvent) {\n                    const data = (ev as CustomEvent<TEventMap[typeof channelName]>).detail;\n                    (subscriber as unknown as (data: TEventMap[typeof channelName]) => void)(data);\n                } else {\n                    (subscriber as () => void)();\n                }\n            }\n            eventEmitter.addEventListener(channelName, innerListener, options);\n            return () => {\n                eventEmitter.removeEventListener(channelName, innerListener);\n            };\n        },\n    };\n}\n"
  },
  {
    "path": "packages/subscribable/src/demultiplex.ts",
    "content": "import { EventTarget } from '@solana/event-target-impl';\n\nimport { DataPublisher, getDataPublisherFromEventEmitter } from './data-publisher';\n\n/**\n * Given a channel that carries messages for multiple subscribers on a single channel name, this\n * function returns a new {@link DataPublisher} that splits them into multiple channel names.\n *\n * @param messageTransformer A function that receives the message as the first argument, and returns\n * a tuple of the derived channel name and the message.\n *\n * @example\n * Imagine a channel that carries multiple notifications whose destination is contained within the\n * message itself.\n *\n * ```ts\n * const demuxedDataPublisher = demultiplexDataPublisher(channel, 'message', message => {\n *     const destinationChannelName = `notification-for:${message.subscriberId}`;\n *     return [destinationChannelName, message];\n * });\n * ```\n *\n * Now you can subscribe to _only_ the messages you are interested in, without having to subscribe\n * to the entire `'message'` channel and filter out the messages that are not for you.\n *\n * ```ts\n * demuxedDataPublisher.on(\n *     'notification-for:123',\n *     message => {\n *         console.log('Got a message for subscriber 123', message);\n *     },\n *     { signal: AbortSignal.timeout(5_000) },\n * );\n * ```\n */\nexport function demultiplexDataPublisher<\n    TDataPublisher extends DataPublisher,\n    const TChannelName extends Parameters<TDataPublisher['on']>[0],\n>(\n    publisher: TDataPublisher,\n    sourceChannelName: TChannelName,\n    messageTransformer: (\n        // FIXME: Deriving the type of the message from `TDataPublisher` and `TChannelName` would\n        //        help callers to constrain their transform functions.\n        message: unknown,\n    ) => [destinationChannelName: string, message: unknown] | void,\n): DataPublisher {\n    let innerPublisherState:\n        | {\n              readonly dispose: () => void;\n              numSubscribers: number;\n          }\n        | undefined;\n    const eventTarget = new EventTarget();\n    const demultiplexedDataPublisher = getDataPublisherFromEventEmitter(eventTarget);\n    return {\n        ...demultiplexedDataPublisher,\n        on(channelName, subscriber, options) {\n            if (!innerPublisherState) {\n                const innerPublisherUnsubscribe = publisher.on(sourceChannelName, sourceMessage => {\n                    const transformResult = messageTransformer(sourceMessage);\n                    if (!transformResult) {\n                        return;\n                    }\n                    const [destinationChannelName, message] = transformResult;\n                    eventTarget.dispatchEvent(\n                        new CustomEvent(destinationChannelName, {\n                            detail: message,\n                        }),\n                    );\n                });\n                innerPublisherState = {\n                    dispose: innerPublisherUnsubscribe,\n                    numSubscribers: 0,\n                };\n            }\n            innerPublisherState.numSubscribers++;\n            const unsubscribe = demultiplexedDataPublisher.on(channelName, subscriber, options);\n            let isActive = true;\n            function handleUnsubscribe() {\n                if (!isActive) {\n                    return;\n                }\n                isActive = false;\n                options?.signal.removeEventListener('abort', handleUnsubscribe);\n                innerPublisherState!.numSubscribers--;\n                if (innerPublisherState!.numSubscribers === 0) {\n                    innerPublisherState!.dispose();\n                    innerPublisherState = undefined;\n                }\n                unsubscribe();\n            }\n            options?.signal.addEventListener('abort', handleUnsubscribe);\n            return handleUnsubscribe;\n        },\n    };\n}\n"
  },
  {
    "path": "packages/subscribable/src/event-emitter.ts",
    "content": "type EventMap = Record<string, Event>;\ntype Listener<TEvent extends Event> = ((evt: TEvent) => void) | { handleEvent(object: TEvent): void };\n\n/**\n * This type allows you to type `addEventListener` and `removeEventListener` so that the call\n * signature of the listener matches the event type given.\n *\n * @example\n * ```ts\n * const emitter: TypedEventEmitter<{ message: MessageEvent }> = new WebSocket('wss://api.devnet.solana.com');\n * emitter.addEventListener('data', handleData); // ERROR. `data` is not a known event type.\n * emitter.addEventListener('message', message => {\n *     console.log(message.origin); // OK. `message` is a `MessageEvent` so it has an `origin` property.\n * });\n * ```\n */\nexport interface TypedEventEmitter<TEventMap extends EventMap> {\n    addEventListener<const TEventType extends keyof TEventMap>(\n        type: TEventType,\n        listener: Listener<TEventMap[TEventType]>,\n        options?: AddEventListenerOptions | boolean,\n    ): void;\n    removeEventListener<const TEventType extends keyof TEventMap>(\n        type: TEventType,\n        listener: Listener<TEventMap[TEventType]>,\n        options?: EventListenerOptions | boolean,\n    ): void;\n}\n\n// Why not just extend the interface above, rather than to copy/paste it?\n// See https://github.com/microsoft/TypeScript/issues/60008\n/**\n * This type is a superset of `TypedEventEmitter` that allows you to constrain calls to\n * `dispatchEvent`.\n *\n * @example\n * ```ts\n * const target: TypedEventTarget<{ candyVended: CustomEvent<{ flavour: string }> }> = new EventTarget();\n * target.dispatchEvent(new CustomEvent('candyVended', { detail: { flavour: 'raspberry' } })); // OK.\n * target.dispatchEvent(new CustomEvent('candyVended', { detail: { flavor: 'raspberry' } })); // ERROR. Misspelling in detail.\n * ```\n */\nexport interface TypedEventTarget<TEventMap extends EventMap> {\n    addEventListener<const TEventType extends keyof TEventMap>(\n        type: TEventType,\n        listener: Listener<TEventMap[TEventType]>,\n        options?: AddEventListenerOptions | boolean,\n    ): void;\n    dispatchEvent<TEventType extends keyof TEventMap>(ev: TEventMap[TEventType]): void;\n    removeEventListener<const TEventType extends keyof TEventMap>(\n        type: TEventType,\n        listener: Listener<TEventMap[TEventType]>,\n        options?: EventListenerOptions | boolean,\n    ): void;\n}\n"
  },
  {
    "path": "packages/subscribable/src/index.ts",
    "content": "/**\n * This package contains utilities for creating subscription-based event targets. These differ from\n * the `EventTarget` interface in that the method you use to add a listener returns an unsubscribe\n * function. It is primarily intended for internal use -- particularly for those building\n * {@link RpcSubscriptionChannel | RpcSubscriptionChannels} and associated infrastructure.\n *\n * @packageDocumentation\n */\nexport * from './reactive-action-store';\nexport * from './async-iterable';\nexport * from './data-publisher';\nexport * from './demultiplex';\nexport * from './event-emitter';\nexport * from './reactive-stream-store';\n"
  },
  {
    "path": "packages/subscribable/src/reactive-action-store.ts",
    "content": "import { AbortController } from '@solana/event-target-impl';\nimport { getAbortablePromise } from '@solana/promises';\n\n/** Lifecycle status of a {@link ReactiveActionStore}. */\nexport type ReactiveActionStatus = 'error' | 'idle' | 'running' | 'success';\n\n/**\n * Discriminated state of a {@link ReactiveActionStore}, keyed by {@link ReactiveActionStatus}.\n *\n * `data` holds the most recent successful result and persists through subsequent `running` and\n * `error` states so call sites can keep rendering stale content while a retry is in flight. Only\n * `reset()` clears it.\n */\nexport type ReactiveActionState<TResult> =\n    | { readonly data: TResult | undefined; readonly error: undefined; readonly status: 'running' }\n    | { readonly data: TResult | undefined; readonly error: unknown; readonly status: 'error' }\n    | { readonly data: TResult; readonly error: undefined; readonly status: 'success' }\n    | { readonly data: undefined; readonly error: undefined; readonly status: 'idle' };\n\n/**\n * A framework-agnostic state machine that wraps an async function and exposes a\n * `{ dispatch, getState, subscribe, reset }` contract. Bridges trivially into\n * `useSyncExternalStore`, Svelte stores, Vue's `shallowRef`, and similar reactive primitives.\n *\n * @see {@link createReactiveActionStore}\n */\nexport type ReactiveActionStore<TArgs extends readonly unknown[], TResult> = {\n    /**\n     * Fire-and-forget dispatch. Returns `undefined` synchronously and never throws — failures\n     * surface on state as `{ status: 'error' }`, and superseded or `reset()`-aborted calls produce\n     * no state update. Use from UI event handlers; there's no promise to handle or `.catch`.\n     *\n     * @see {@link ReactiveActionStore.dispatchAsync} when you need the resolved value or propagated errors.\n     */\n    readonly dispatch: (...args: TArgs) => void;\n    /**\n     * Promise-returning dispatch for imperative callers. Resolves with the wrapped function's\n     * result on success. Rejects with the thrown error on failure, and with an `AbortError` when\n     * the call is superseded or `reset()` is invoked — filter those with `isAbortError` from\n     * `@solana/promises`.\n     */\n    readonly dispatchAsync: (...args: TArgs) => Promise<TResult>;\n    /** Returns the current state. */\n    readonly getState: () => ReactiveActionState<TResult>;\n    /** Aborts any in-flight dispatch and resets the state to `{ status: 'idle' }`. */\n    readonly reset: () => void;\n    /** Registers a listener called on every state change. Returns an unsubscribe function. */\n    readonly subscribe: (listener: () => void) => () => void;\n};\n\nconst IDLE_STATE: ReactiveActionState<never> = Object.freeze({\n    data: undefined,\n    error: undefined,\n    status: 'idle',\n});\n\n/**\n * Wraps an async function in a {@link ReactiveActionStore}. Each `dispatch` creates a fresh\n * {@link AbortController} and aborts the previous one; the superseded call's outcome is dropped,\n * so only the most recent dispatch can mutate state.\n *\n * The wrapped function receives the `AbortSignal` as its first argument, followed by whatever\n * arguments were passed to `dispatch`.\n *\n * @typeParam TArgs - Argument tuple forwarded from `dispatch` to `fn`.\n * @typeParam TResult - Resolved value type of `fn`.\n * @param fn - Async function to wrap. Receives an {@link AbortSignal} plus the dispatch arguments.\n * @return A {@link ReactiveActionStore} exposing `dispatch`, `dispatchAsync`, `getState`, `subscribe`,\n * and `reset`.\n *\n * @example\n * ```ts\n * const store = createReactiveActionStore(async (signal, accountId: Address) => {\n *     const response = await fetch(`/api/accounts/${accountId}`, { signal });\n *     return response.json();\n * });\n *\n * store.subscribe(() => console.log(store.getState()));\n * store.dispatch(someAccountId); // fire-and-forget; state is the source of truth\n *\n * // Or, when you need the resolved value imperatively:\n * const account = await store.dispatchAsync(someAccountId);\n * ```\n *\n * @see {@link ReactiveActionStore}\n */\nexport function createReactiveActionStore<TArgs extends readonly unknown[], TResult>(\n    fn: (signal: AbortSignal, ...args: TArgs) => Promise<TResult>,\n): ReactiveActionStore<TArgs, TResult> {\n    let state: ReactiveActionState<TResult> = IDLE_STATE;\n    let currentController: AbortController | undefined;\n    const listeners = new Set<() => void>();\n\n    function setState(next: ReactiveActionState<TResult>) {\n        if (state.status === next.status && state.data === next.data && state.error === next.error) {\n            return;\n        }\n        state = next;\n        listeners.forEach(listener => listener());\n    }\n\n    const dispatchAsync = async (...args: TArgs): Promise<TResult> => {\n        currentController?.abort();\n        const controller = new AbortController();\n        currentController = controller;\n        const { signal } = controller;\n        const previousData = state.data;\n        setState({ data: previousData, error: undefined, status: 'running' });\n        try {\n            const result = await getAbortablePromise(fn(signal, ...args), signal);\n            if (signal.aborted) {\n                throw signal.reason;\n            }\n            setState({ data: result, error: undefined, status: 'success' });\n            return result;\n        } catch (error) {\n            if (signal.aborted) {\n                throw signal.reason;\n            }\n            setState({ data: previousData, error, status: 'error' });\n            throw error;\n        }\n    };\n\n    const dispatch = (...args: TArgs): void => {\n        dispatchAsync(...args).catch(() => {});\n    };\n\n    return {\n        dispatch,\n        dispatchAsync,\n        getState: () => state,\n        reset: () => {\n            currentController?.abort();\n            currentController = undefined;\n            setState(IDLE_STATE);\n        },\n        subscribe: listener => {\n            listeners.add(listener);\n            return () => {\n                listeners.delete(listener);\n            };\n        },\n    };\n}\n"
  },
  {
    "path": "packages/subscribable/src/reactive-stream-store.ts",
    "content": "import { SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED, SolanaError } from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\n\nimport { DataPublisher } from './data-publisher';\n\ntype Config = Readonly<{\n    /**\n     * Triggering this abort signal will cause the store to stop updating and will disconnect it from\n     * the underlying data publisher.\n     */\n    abortSignal: AbortSignal;\n    /**\n     * Messages from this channel of `dataPublisher` will be used to update the store's state.\n     */\n    dataChannelName: string;\n    // FIXME: It would be nice to be able to constrain the type of `dataPublisher` to one that\n    //        definitely supports the `dataChannelName` and `errorChannelName` channels, and\n    //        furthermore publishes `TData` on the `dataChannelName` channel. This is more difficult\n    //        than it should be: https://tsplay.dev/NlZelW\n    dataPublisher: DataPublisher;\n    /**\n     * Messages from this channel of `dataPublisher` will cause subscribers to be notified without\n     * updating the state, so that they can respond to the error condition.\n     */\n    errorChannelName: string;\n}>;\n\ntype FactoryConfig = Readonly<{\n    /**\n     * Triggering this abort signal will cause the store to stop updating and will disconnect it from\n     * any active {@link DataPublisher}. Subsequent calls to {@link ReactiveStreamStore.retry | `retry()`}\n     * are no-ops once this signal has fired.\n     */\n    abortSignal: AbortSignal;\n    /**\n     * An async factory that produces a fresh {@link DataPublisher} each time it is invoked. Called\n     * once on construction and again on every {@link ReactiveStreamStore.retry | `retry()`}. Rejections\n     * surface as a store error.\n     */\n    createDataPublisher: () => Promise<DataPublisher>;\n    /**\n     * Messages from this channel of the produced `DataPublisher` will be used to update the store's\n     * state.\n     */\n    dataChannelName: string;\n    /**\n     * Messages from this channel of the produced `DataPublisher` will transition the store to an\n     * error state, preserving the last known value.\n     */\n    errorChannelName: string;\n}>;\n\n/**\n * The lifecycle state of a {@link ReactiveStreamStore} as a single snapshot.\n *\n * - `loading`: the store is waiting for its first value. `data` is `undefined`.\n * - `loaded`: a value has been received and no error is active. `data` is defined.\n * - `error`: the stream failed. `data` is the last known value (or `undefined` if no value ever\n *   arrived), and `error` holds the failure.\n * - `retrying`: a {@link ReactiveStreamStore.retry | `retry()`} is in progress after a previous error.\n *   `error` is cleared; `data` is preserved from before the failure if present.\n */\nexport type ReactiveState<T> =\n    | { readonly data: T | undefined; readonly error: undefined; readonly status: 'retrying' }\n    | { readonly data: T | undefined; readonly error: unknown; readonly status: 'error' }\n    | { readonly data: T; readonly error: undefined; readonly status: 'loaded' }\n    | { readonly data: undefined; readonly error: undefined; readonly status: 'loading' };\n\nconst LOADING_STATE: ReactiveState<never> = Object.freeze({\n    data: undefined,\n    error: undefined,\n    status: 'loading',\n});\n\n/**\n * A reactive store that holds the latest value published to a data channel and allows external\n * systems to subscribe to changes. Compatible with `useSyncExternalStore`, Svelte stores, Solid's\n * `from()`, and other reactive primitives that expect a `{ subscribe, getUnifiedState }` contract.\n *\n * @example\n * ```ts\n * // React — the unified state snapshot has stable identity per update, making it suitable as\n * // the second argument to `useSyncExternalStore`.\n * const state = useSyncExternalStore(store.subscribe, store.getUnifiedState);\n * if (state.status === 'error') return <ErrorMessage error={state.error} onRetry={store.retry} />;\n * if (state.status === 'loading') return <Spinner />;\n * return <View data={state.data} />;\n * ```\n *\n * @see {@link createReactiveStoreFromDataPublisherFactory}\n */\nexport type ReactiveStreamStore<T> = {\n    /**\n     * Returns the error published to the error channel, or `undefined` if no error has occurred.\n     *\n     * @deprecated Use {@link ReactiveStreamStore.getUnifiedState | `getUnifiedState()`} instead. This\n     * getter returns only the error field and cannot narrow the relationship between the current\n     * value, error, and status.\n     */\n    getError(): unknown;\n    /**\n     * Returns the most recent value published to the data channel, or `undefined` if no\n     * notification has arrived yet. On error, continues to return the last known value.\n     *\n     * @deprecated Use {@link ReactiveStreamStore.getUnifiedState | `getUnifiedState()`} instead. This\n     * getter returns only the value field and does not surface lifecycle status (e.g. `retrying`).\n     */\n    getState(): T | undefined;\n    /**\n     * Returns the current lifecycle snapshot: `{ data, error, status }`. The returned object has\n     * stable identity between state changes, making it safe to pass directly as the\n     * `getSnapshot` argument to React's `useSyncExternalStore`.\n     *\n     * @see {@link ReactiveState}\n     */\n    getUnifiedState(): ReactiveState<T>;\n    /**\n     * Re-opens the stream after an error. No-op when the store is not in the `error` state.\n     */\n    retry(): void;\n    /**\n     * Registers a callback to be called whenever the state changes or an error is received.\n     * Returns an unsubscribe function. Safe to call multiple times.\n     */\n    subscribe(callback: () => void): () => void;\n};\n\n/**\n * @deprecated Use {@link ReactiveStreamStore} instead. This alias will be removed in a future\n * major release.\n */\nexport type ReactiveStore<T> = ReactiveStreamStore<T>;\n\n/**\n * Returns a {@link ReactiveStreamStore} given a data publisher.\n *\n * The store will update its state with each message published to `dataChannelName` and notify all\n * subscribers. When a message is published to `errorChannelName`, subscribers are notified so they\n * can react to the error condition, but the last-known state is preserved. Triggering the abort\n * signal disconnects the store from the data publisher.\n *\n * Things to note:\n *\n * - `getUnifiedState()` starts in `status: 'loading'` until the first notification arrives.\n * - On error, `getUnifiedState().data` continues to return the last known value and `error` holds\n *   the failure. Only the first error is captured.\n * - The function returned by `subscribe` is idempotent — calling it multiple times is safe.\n * - Because a `DataPublisher` instance cannot be restarted, {@link ReactiveStreamStore.retry | `retry()`}\n *   on the returned store throws a\n *   {@link SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED | `SolanaError`}.\n *\n * @param config\n *\n * @deprecated Use {@link createReactiveStoreFromDataPublisherFactory} instead. That variant accepts\n * a factory function for the underlying {@link DataPublisher} and can therefore support\n * {@link ReactiveStreamStore.retry | `retry()`}.\n */\nexport function createReactiveStoreFromDataPublisher<TData>({\n    abortSignal,\n    dataChannelName,\n    dataPublisher,\n    errorChannelName,\n}: Config): ReactiveStreamStore<TData> {\n    let currentState: ReactiveState<TData> = LOADING_STATE;\n    const subscribers = new Set<() => void>();\n\n    const abortController = new AbortController();\n    abortSignal.addEventListener('abort', () => abortController.abort(abortSignal.reason));\n\n    function notify() {\n        subscribers.forEach(cb => cb());\n    }\n\n    dataPublisher.on(\n        dataChannelName,\n        data => {\n            currentState = { data: data as TData, error: undefined, status: 'loaded' };\n            notify();\n        },\n        { signal: abortController.signal },\n    );\n    dataPublisher.on(\n        errorChannelName,\n        err => {\n            if (currentState.status === 'error') return;\n            currentState = { data: currentState.data, error: err, status: 'error' };\n            abortController.abort(err);\n            notify();\n        },\n        { signal: abortController.signal },\n    );\n\n    return {\n        getError(): unknown {\n            return currentState.error;\n        },\n        getState(): TData | undefined {\n            return currentState.data;\n        },\n        getUnifiedState(): ReactiveState<TData> {\n            return currentState;\n        },\n        retry(): void {\n            throw new SolanaError(SOLANA_ERROR__SUBSCRIBABLE__RETRY_NOT_SUPPORTED);\n        },\n        subscribe(callback: () => void): () => void {\n            subscribers.add(callback);\n            return () => {\n                subscribers.delete(callback);\n            };\n        },\n    };\n}\n\n/**\n * Returns a {@link ReactiveStreamStore} that wires itself to a fresh {@link DataPublisher} on\n * construction and on every {@link ReactiveStreamStore.retry | `retry()`}.\n *\n * Unlike {@link createReactiveStoreFromDataPublisher}, this variant accepts a `createDataPublisher`\n * factory rather than a ready-made publisher. That lets the store tear down a broken stream and\n * open a new one without losing subscribers or the last known value.\n *\n * Things to note:\n *\n * - `getUnifiedState()` starts in `status: 'loading'` until the first notification arrives.\n * - On error, the store transitions to `status: 'error'` preserving the last known value. Only the\n *   first error per connection window is captured — a subsequent `retry()` resets that window.\n * - `retry()` is a no-op unless the store is currently in `status: 'error'`. When it fires, the\n *   store transitions to `status: 'retrying'` (preserving stale data), invokes\n *   `createDataPublisher()`, and wires up a fresh connection. If the factory rejects, the store\n *   transitions to `status: 'error'` with the rejection reason.\n * - Triggering the caller's `abortSignal` disconnects the store permanently; subsequent `retry()`\n *   calls are no-ops.\n *\n * @param config\n *\n * @example\n * ```ts\n * const store = createReactiveStoreFromDataPublisherFactory({\n *     abortSignal,\n *     async createDataPublisher() {\n *         return getDataPublisherFromEventEmitter(new WebSocket(url));\n *     },\n *     dataChannelName: 'message',\n *     errorChannelName: 'error',\n * });\n * const unsubscribe = store.subscribe(() => {\n *     const snapshot = store.getUnifiedState();\n *     if (snapshot.status === 'error') console.error('Connection failed:', snapshot.error);\n *     else if (snapshot.status === 'loaded') console.log('Latest:', snapshot.data);\n * });\n * // Call `store.retry()` to recover after an error — e.g. from a user-triggered \"Retry\" button.\n * ```\n */\nexport function createReactiveStoreFromDataPublisherFactory<TData>({\n    abortSignal,\n    createDataPublisher,\n    dataChannelName,\n    errorChannelName,\n}: FactoryConfig): ReactiveStreamStore<TData> {\n    let currentState: ReactiveState<TData> = LOADING_STATE;\n    const subscribers = new Set<() => void>();\n\n    const outerController = new AbortController();\n    abortSignal.addEventListener('abort', () => outerController.abort(abortSignal.reason));\n\n    function notify() {\n        subscribers.forEach(cb => cb());\n    }\n\n    function connect() {\n        if (outerController.signal.aborted) return;\n        // Inner signal is passed to data publisher\n        const innerController = new AbortController();\n        // Forward an abort from the outer signal to the inner one, so that when the caller aborts, we disconnect\n        // Scope this forwarder to the inner signal so it's removed on reconnection\n        // and we don't accumulate listeners on the outer signal across retries.\n        const forwardAbort = () => innerController.abort(outerController.signal.reason);\n        outerController.signal.addEventListener('abort', forwardAbort, { signal: innerController.signal });\n        createDataPublisher().then(\n            publisher => {\n                if (innerController.signal.aborted) return;\n                publisher.on(\n                    dataChannelName,\n                    data => {\n                        currentState = { data: data as TData, error: undefined, status: 'loaded' };\n                        notify();\n                    },\n                    { signal: innerController.signal },\n                );\n                publisher.on(\n                    errorChannelName,\n                    err => {\n                        if (currentState.status === 'error') return;\n                        currentState = { data: currentState.data, error: err, status: 'error' };\n                        innerController.abort(err);\n                        notify();\n                    },\n                    { signal: innerController.signal },\n                );\n            },\n            err => {\n                if (innerController.signal.aborted) return;\n                currentState = { data: currentState.data, error: err, status: 'error' };\n                innerController.abort(err);\n                notify();\n            },\n        );\n    }\n\n    connect();\n\n    return {\n        getError(): unknown {\n            return currentState.error;\n        },\n        getState(): TData | undefined {\n            return currentState.data;\n        },\n        getUnifiedState(): ReactiveState<TData> {\n            return currentState;\n        },\n        retry(): void {\n            if (outerController.signal.aborted) return;\n            if (currentState.status !== 'error') return;\n            currentState = { data: currentState.data, error: undefined, status: 'retrying' };\n            notify();\n            connect();\n        },\n        subscribe(callback: () => void): () => void {\n            subscribers.add(callback);\n            return () => {\n                subscribers.delete(callback);\n            };\n        },\n    };\n}\n"
  },
  {
    "path": "packages/subscribable/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/subscribable/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"@solana/subscribable\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"],\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2024.Promise\"]\n    }\n}\n"
  },
  {
    "path": "packages/subscribable/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/sysvars/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/sysvars/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/sysvars/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/sysvars/CHANGELOG.md",
    "content": "# @solana/sysvars\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/errors@6.9.0\n    - @solana/accounts@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-data-structures@6.9.0\n    - @solana/codecs-numbers@6.9.0\n    - @solana/rpc-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/accounts@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-data-structures@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/rpc-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-data-structures@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/rpc-types@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/accounts@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-data-structures@6.6.0\n    - @solana/codecs-numbers@6.6.0\n    - @solana/rpc-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-data-structures@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/rpc-types@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/accounts@6.4.0\n    - @solana/codecs-data-structures@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/errors@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-data-structures@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/rpc-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/accounts@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-data-structures@6.3.0\n    - @solana/codecs-numbers@6.3.0\n    - @solana/rpc-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- [#1428](https://github.com/anza-xyz/kit/pull/1428) [`b28b843`](https://github.com/anza-xyz/kit/commit/b28b8439b1f62aefd9c35c4bea733816975033e5) Thanks [@datasalaryman](https://github.com/datasalaryman)! - use internals codecs dependencies\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`5390602`](https://github.com/anza-xyz/kit/commit/53906024cffc3facb7259ab65ab974b6b1038f56), [`3f4c5f0`](https://github.com/anza-xyz/kit/commit/3f4c5f003e343c21a785e8f339f84c8d6bd3a3b1), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-data-structures@6.2.0\n    - @solana/accounts@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n    - @solana/rpc-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/codecs@6.1.0\n    - @solana/accounts@6.1.0\n    - @solana/rpc-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@6.0.1\n    - @solana/codecs@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@6.0.0\n    - @solana/codecs@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/accounts@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/codecs@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/accounts@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/codecs@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`fb1c576`](https://github.com/anza-xyz/kit/commit/fb1c5761122bebc9955179a911a79a33a391e032), [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/accounts@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/codecs@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@5.3.0\n    - @solana/codecs@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/rpc-types@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5)]:\n    - @solana/errors@5.2.0\n    - @solana/accounts@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/codecs@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df)]:\n    - @solana/errors@5.1.0\n    - @solana/accounts@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/codecs@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/accounts@5.0.0\n    - @solana/codecs@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/accounts@4.0.0\n    - @solana/codecs@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f)]:\n    - @solana/errors@3.0.0\n    - @solana/accounts@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/codecs@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639)]:\n    - @solana/errors@2.3.0\n    - @solana/accounts@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/codecs@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@2.2.1\n    - @solana/codecs@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/rpc-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-types@2.2.0\n    - @solana/accounts@2.2.0\n    - @solana/codecs@2.2.0\n    - @solana/errors@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#374](https://github.com/anza-xyz/kit/pull/374) [`2fb1fbc`](https://github.com/anza-xyz/kit/commit/2fb1fbcf06b12f3f892776e89d2ee32797d032a3) Thanks [@steveluscher](https://github.com/steveluscher)! - The `SysvarEpochRewards` encoder/decoder no longer produces malformed data\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#379](https://github.com/anza-xyz/kit/pull/379) [`e143797`](https://github.com/anza-xyz/kit/commit/e1437975c60b9fe1beaabb45d513a840000b25a3) Thanks [@steveluscher](https://github.com/steveluscher)! - The `SysvarStakeHistory` encoder/decoder no longer produces malformed data\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/rpc-types@2.1.1\n    - @solana/accounts@2.1.1\n    - @solana/codecs@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Minor Changes\n\n- [`c880687`](https://github.com/anza-xyz/kit/commit/c880687184239a2b2908e85b460bc0b97c07f371) Thanks [@steveluscher](https://github.com/steveluscher)! - Removed the fees sysvar which has been disabled on the network for a year, and has now been removed from the test validator in Agave 2.0\n\n    ```\n    % solana feature status JAN1trEUEtZjgXYzNBYHU9DYd7GnThhXfFP7SzPXkPsG\n    Feature                                      | Status                  | Activation Slot | Description\n    JAN1trEUEtZjgXYzNBYHU9DYd7GnThhXfFP7SzPXkPsG | active since epoch 483  | 208656004       | disable fees sysvar\n    ```\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/errors@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/accounts@2.1.0\n    - @solana/codecs@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/errors@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/accounts@2.0.0\n    - @solana/codecs@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/accounts@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/codecs@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@2.0.0-rc.3\n    - @solana/codecs@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3134](https://github.com/solana-labs/solana-web3.js/pull/3134) [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Change unix timestamp type to bigint with an unsafe label\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`3fc388f`](https://github.com/solana-labs/solana-web3.js/commit/3fc388f0b40243436a3ecbcd2af27ea8efa683e4), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/accounts@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/accounts@2.0.0-rc.1\n    - @solana/codecs@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/accounts@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n    - @solana/codecs@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/accounts@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/codecs@2.0.0-preview.3\n    - @solana/accounts@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/accounts@2.0.0-preview.2\n    - @solana/codecs@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n"
  },
  {
    "path": "packages/sysvars/LICENSE",
    "content": "Copyright (c) 2018 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/sysvars/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/sysvars?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/sysvars?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/sysvars\n\n# @solana/sysvars\n\nThis package contains types and helpers for fetching and decoding Solana sysvars. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nMore information about the available sysvars on Solana can be found in the docs\nat <https://docs.solanalabs.com/runtime/sysvars>.\n\nAll currently available sysvars can be retrieved and/or decoded using this\nlibrary.\n\n## Sysvar API\n\nThis package offers a simple API for working with sysvars.\n\nOne can fetch an encoded sysvar account using an RPC client.\n\n```ts\nconst maybeEncodedClock = await fetchEncodedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS);\nmaybeEncodedClock satisfies MaybeEncodedAccount<'SysvarC1ock11111111111111111111111111111111'>;\n```\n\nOne can also attempt to fetch a JSON-parsed sysvar account.\n\n```ts\nconst maybeJsonParsedClock = await fetchJsonParsedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS);\nmaybeJsonParsedClock satisfies\n    | MaybeAccount<JsonParsedSysvarAccount, 'SysvarC1ock11111111111111111111111111111111'>\n    | MaybeEncodedAccount<'SysvarC1ock11111111111111111111111111111111'>;\n```\n\nEach sysvar within the library ships with its own\n[codec](https://github.com/anza-xyz/kit/tree/main/packages/codecs)\nfor deserializing the account data.\n\nYou can pair this codec with the helpers from\n[`@solana/accounts`](https://github.com/anza-xyz/kit/tree/main/packages/accounts)\nto assert and decode sysvar account data.\n\n```ts\n// Fetch.\nconst clock = await fetchEncodedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS);\nclock satisfies MaybeEncodedAccount<'SysvarC1ock11111111111111111111111111111111'>;\n\n// Assert.\nassertAccountExists(clock);\nclock satisfies EncodedAccount<'SysvarC1ock11111111111111111111111111111111'>;\n\n// Decode.\nconst decodedClock = decodeAccount(clock, getSysvarClockDecoder());\ndecodedClock satisfies Account<SysvarClock, 'SysvarC1ock11111111111111111111111111111111'>;\n```\n\nEach supported sysvar also ships with its own fetch-and-decode function to\nperform the steps above and return the decoded sysvar data.\n\n```ts\nconst clock: SysvarClock = await fetchSysvarClock(rpc);\n```\n\n## Supported Sysvars:\n\nThis package supports the following Solana sysvars:\n\n- [`Clock`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/clock.ts)\n- [`EpochRewards`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/epoch-rewards.ts)\n- [`EpochSchedule`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/epoch-schedule.ts)\n- [`Fees`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/fees.ts)\n- [`LastRestartSlot`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/last-restart-slot.ts)\n- [`RecentBlockhashes`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/recent-blockhashes.ts)\n- [`Rent`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/rent.ts)\n- [`SlotHashes`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/slot-hashes.ts)\n- [`SlotHistory`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/slot-history.ts)\n- [`StakeHistory`](https://github.com/anza-xyz/kit/tree/main/packages/sysvars/src/stake-history.ts)\n\nThe `Instructions` sysvar is also supported but does not exist on-chain,\ntherefore has no corresponding module or codec.\n"
  },
  {
    "path": "packages/sysvars/package.json",
    "content": "{\n    \"name\": \"@solana/sysvars\",\n    \"version\": \"6.9.0\",\n    \"description\": \"An abstraction layer over signing messages and transactions in Solana\",\n    \"homepage\": \"https://www.solanakit.com/api#solanasysvars\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --globalSetup @solana/test-config/test-validator-setup.js --globalTeardown @solana/test-config/test-validator-teardown.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/accounts\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-data-structures\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/rpc-api\": \"workspace:*\",\n        \"@solana/rpc-parsed-types\": \"workspace:*\",\n        \"@solana/rpc-spec\": \"workspace:*\",\n        \"@solana/rpc-transport-http\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/sysvars/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/__setup__.ts",
    "content": "import { createSolanaRpcApi, type SolanaRpcApi } from '@solana/rpc-api';\nimport { createRpc, type Rpc } from '@solana/rpc-spec';\nimport { createHttpTransport } from '@solana/rpc-transport-http';\n\nexport function createLocalhostSolanaRpc(): Rpc<SolanaRpcApi> {\n    return createRpc({\n        api: createSolanaRpcApi(),\n        transport: createHttpTransport({ url: 'http://127.0.0.1:8899' }),\n    });\n}\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/clock-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { fetchSysvarClock, getSysvarClockCodec } from '../clock';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('clock', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    it('decode', () => {\n        // prettier-ignore\n        const clockState = new Uint8Array([\n            119, 233, 246, 16, 0, 0, 0, 0,          // slot\n            246, 255, 255, 255, 255, 255, 255, 255, // epochStartTimestamp\n            4, 0, 0, 0, 0, 0, 0, 0,                 // epoch\n            0, 0, 0, 0, 0, 0, 0, 0,                 // leaderScheduleEpoch\n            224, 177, 255, 255, 255, 255, 255, 255, // unixTimestamp\n        ]);\n        expect(getSysvarClockCodec().decode(clockState)).toMatchObject({\n            epoch: 4n,\n            epochStartTimestamp: -10n,\n            leaderScheduleEpoch: 0n,\n            slot: 284_617_079n,\n            unixTimestamp: -20_000n,\n        });\n    });\n    it('fetch', async () => {\n        expect.assertions(1);\n        const clock = await fetchSysvarClock(rpc);\n        expect(clock).toMatchObject({\n            epoch: expect.any(BigInt),\n            epochStartTimestamp: expect.any(BigInt),\n            leaderScheduleEpoch: expect.any(BigInt),\n            slot: expect.any(BigInt),\n            unixTimestamp: expect.any(BigInt),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/epoch-rewards-test.ts",
    "content": "import { getSysvarEpochRewardsCodec } from '../epoch-rewards';\n\ndescribe('epoch rewards', () => {\n    it('decode', () => {\n        // prettier-ignore\n        const epochRewardsState = new Uint8Array([\n            // distributionStartingBlockHeight\n            0xab, 0xa8, 0x87, 0x12, 0x00, 0x00, 0x00, 0x00,\n            // numPartitions\n            0x3a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n            // parentBlockhash\n            0x67, 0x8b, 0xd4, 0xe4, 0xc8, 0x5c, 0x10, 0x87, 0xa8, 0x0a, 0xfb, 0x2f, 0x0d, 0xbb, 0x13, 0x27, 0x16, 0x11, 0x3a, 0xc7, 0xc7, 0xb0, 0xc7, 0xe4, 0x99, 0x51, 0x4d, 0x42, 0xdb, 0x43, 0xd7, 0x1c,\n            // totalPoints\n            0x10, 0xbe, 0x90, 0x99, 0x7a, 0x16, 0x9e, 0xa5, 0xc2, 0x2d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, \n            // totalRewards\n            0x00, 0xb3, 0x04, 0x4e, 0xd0, 0x20, 0x89, 0x00,\n            // distributedRewards\n            0x00, 0xb8, 0xea, 0x37, 0xd0, 0x20, 0x89, 0x00,\n            // active\n            0x00,\n        ]);\n        expect(getSysvarEpochRewardsCodec().decode(epochRewardsState)).toStrictEqual({\n            active: false,\n            distributedRewards: 38598150472775680n,\n            distributionStartingBlockHeight: 310880427n,\n            numPartitions: 314n,\n            parentBlockhash: '7yCfKTaamnrmkAfefSgsonQ6rtwCfVaxQJircWb9K4Qj',\n            totalPoints: 2633948733309470433656336n,\n            totalRewards: 38598150843577088n,\n        });\n    });\n    // TODO: This account does not seem to exist on-chain yet.\n    it.todo('fetch');\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/epoch-schedule-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { fetchSysvarEpochSchedule, getSysvarEpochScheduleCodec } from '../epoch-schedule';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('epoch rewards', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    it('decode', () => {\n        // prettier-ignore\n        const epochScheduleState = new Uint8Array([\n            16, 39, 0, 0, 0, 0, 0, 0,       // slotsPerEpoch\n            134, 74, 2, 0, 0, 0, 0, 0,      // leaderScheduleSlotOffset\n            1,                              // warmup\n            38, 2, 0, 0, 0, 0, 0, 0,        // firstNormalEpoch\n            128, 147, 220, 20, 0, 0, 0, 0,  // firstNormalSlot\n        ]);\n        expect(getSysvarEpochScheduleCodec().decode(epochScheduleState)).toMatchObject({\n            firstNormalEpoch: 550n,\n            firstNormalSlot: 350_000_000n,\n            leaderScheduleSlotOffset: 150_150n,\n            slotsPerEpoch: 10_000n,\n            warmup: true,\n        });\n    });\n    it('fetch', async () => {\n        expect.assertions(1);\n        const epochSchedule = await fetchSysvarEpochSchedule(rpc);\n        expect(epochSchedule).toMatchObject({\n            firstNormalEpoch: expect.any(BigInt),\n            firstNormalSlot: expect.any(BigInt),\n            leaderScheduleSlotOffset: expect.any(BigInt),\n            slotsPerEpoch: expect.any(BigInt),\n            warmup: expect.any(Boolean),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/last-restart-slot-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { fetchSysvarLastRestartSlot, getSysvarLastRestartSlotCodec } from '../last-restart-slot';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('last restart slot', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    it('decode', () => {\n        const lastRestartSlotState = new Uint8Array([119, 233, 246, 16, 0, 0, 0, 0]);\n        expect(getSysvarLastRestartSlotCodec().decode(lastRestartSlotState)).toMatchObject({\n            lastRestartSlot: 284_617_079n,\n        });\n    });\n    it('fetch', async () => {\n        expect.assertions(1);\n        const lastRestartSlot = await fetchSysvarLastRestartSlot(rpc);\n        expect(lastRestartSlot).toMatchObject({\n            lastRestartSlot: expect.any(BigInt),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/recent-blockhashes-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { fetchSysvarRecentBlockhashes, getSysvarRecentBlockhashesCodec } from '../recent-blockhashes';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('recent blockhashes', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    it('decode', () => {\n        // prettier-ignore\n        const recentBlockhashesState = new Uint8Array([\n            2, 0, 0, 0,                 // array length \n            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n            134, 74, 2, 0, 0, 0, 0, 0,  // lamportsPerSignature\n            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n            134, 74, 2, 0, 0, 0, 0, 0,  // lamportsPerSignature\n        ]);\n        expect(getSysvarRecentBlockhashesCodec().decode(recentBlockhashesState)).toMatchObject([\n            {\n                blockhash: '4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLKi',\n                feeCalculator: {\n                    lamportsPerSignature: 150_150n,\n                },\n            },\n            {\n                blockhash: '8qbHbw2BbbTHBW1sbeqakYXVKRQM8Ne7pLK7m6CVfeR',\n                feeCalculator: {\n                    lamportsPerSignature: 150_150n,\n                },\n            },\n        ]);\n    });\n    it('fetch', async () => {\n        expect.assertions(1);\n        const recentBlockhashes = await fetchSysvarRecentBlockhashes(rpc);\n        expect(recentBlockhashes).toMatchObject(\n            expect.arrayContaining([\n                {\n                    blockhash: expect.any(String),\n                    feeCalculator: {\n                        lamportsPerSignature: expect.any(BigInt),\n                    },\n                },\n            ]),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/rent-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { fetchSysvarRent, getSysvarRentCodec } from '../rent';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('rent', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    it('decode', () => {\n        // prettier-ignore\n        const rentState = new Uint8Array([\n            0, 225, 245, 5, 0, 0, 0, 0, // lamportsPerByteYear\n            0, 225, 245, 5, 0, 0, 0, 0, // exemptionThreshold\n            8,                          // burnPercent\n        ]);\n        expect(getSysvarRentCodec().decode(rentState)).toMatchObject({\n            burnPercent: 8,\n            exemptionThreshold: 4.94065646e-316,\n            lamportsPerByteYear: 100_000_000n,\n        });\n    });\n    it('fetch', async () => {\n        expect.assertions(1);\n        const rent = await fetchSysvarRent(rpc);\n        expect(rent).toMatchObject({\n            burnPercent: expect.any(Number),\n            exemptionThreshold: expect.any(Number),\n            lamportsPerByteYear: expect.any(BigInt),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/slot-hashes-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { fetchSysvarSlotHashes, getSysvarSlotHashesCodec } from '../slot-hashes';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('slot hashes', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    it('decode', () => {\n        // prettier-ignore\n        const slotHashesState = new Uint8Array([\n            2, 0, 0, 0,                 // array length \n            134, 74, 2, 0, 0, 0, 0, 0,  // slot\n            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n            134, 74, 2, 0, 0, 0, 0, 0,  // slot\n            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,\n        ]);\n        expect(getSysvarSlotHashesCodec().decode(slotHashesState)).toMatchObject(\n            expect.arrayContaining([\n                {\n                    hash: '4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLKi',\n                    slot: 150_150n,\n                },\n                {\n                    hash: '8qbHbw2BbbTHBW1sbeqakYXVKRQM8Ne7pLK7m6CVfeR',\n                    slot: 150_150n,\n                },\n            ]),\n        );\n    });\n    it('fetch', async () => {\n        expect.assertions(1);\n        const slotHashes = await fetchSysvarSlotHashes(rpc);\n        expect(slotHashes).toMatchObject(\n            expect.arrayContaining([\n                {\n                    hash: expect.any(String),\n                    slot: expect.any(BigInt),\n                },\n            ]),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/slot-history-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { fetchSysvarSlotHistory, getSysvarSlotHistoryCodec } from '../slot-history';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\nconst BITVEC_DISCRIMINATOR = 1;\nconst BITVEC_NUM_BITS = 1024 * 1024;\nconst BITVEC_LENGTH = BITVEC_NUM_BITS / 64;\n\ndescribe('slot history', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    it('decode', () => {\n        const codec = getSysvarSlotHistoryCodec();\n        const slotHistoryState = new Uint8Array(codec.fixedSize);\n        slotHistoryState.fill(1);\n        let offset = 0;\n        slotHistoryState.set([BITVEC_DISCRIMINATOR], offset);\n        offset += 1;\n        slotHistoryState.set([0, 64, 0, 0, 0, 0, 0, 0], offset);\n        offset += 8;\n        // Let the 1s represent the bits.\n        offset += BITVEC_LENGTH * 8;\n        slotHistoryState.set([0, 0, 16, 0, 0, 0, 0, 0], offset);\n        offset += 8;\n        slotHistoryState.set([134, 74, 2, 0, 0, 0, 0, 0], offset);\n        expect(codec.decode(slotHistoryState)).toMatchObject({\n            bits: expect.arrayContaining([72_340_172_838_076_673n]), // [1, 1, 1, 1, 1, 1, 1, 1]\n            nextSlot: 150_150n,\n        });\n    });\n    it('fetch', async () => {\n        expect.assertions(1);\n        const slotHashes = await fetchSysvarSlotHistory(rpc);\n        expect(slotHashes).toMatchObject({\n            bits: expect.any(Array),\n            nextSlot: expect.any(BigInt),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/stake-history-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport { fetchSysvarStakeHistory, getSysvarStakeHistoryCodec } from '../stake-history';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('stake history', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    it('decode', () => {\n        // prettier-ignore\n        const stakeHistoryState = new Uint8Array([\n            2, 0, 0, 0, 0, 0, 0, 0,         // array length \n            1, 0, 0, 0, 0, 0, 0, 0,         // epoch\n            0, 208, 237, 144, 46, 0, 0, 0,  // effective\n            0, 160, 219, 33, 93, 0, 0, 0,   // activating\n            0, 112, 201, 178, 139, 0, 0, 0, // deactivating\n            2, 0, 0, 0, 0, 0, 0, 0,         // epoch\n            0, 160, 219, 33, 93, 0, 0, 0,   // effective\n            0, 112, 201, 178, 139, 0, 0, 0, // activating\n            0, 64, 183, 67, 186, 0, 0, 0,   // deactivating\n        ]);\n        expect(getSysvarStakeHistoryCodec().decode(stakeHistoryState)).toMatchObject(\n            expect.arrayContaining([\n                {\n                    epoch: 1n,\n                    stakeHistory: {\n                        activating: 400_000_000_000n,\n                        deactivating: 600_000_000_000n,\n                        effective: 200_000_000_000n,\n                    },\n                },\n                {\n                    epoch: 2n,\n                    stakeHistory: {\n                        activating: 600_000_000_000n,\n                        deactivating: 800_000_000_000n,\n                        effective: 400_000_000_000n,\n                    },\n                },\n            ]),\n        );\n    });\n    it('fetch', async () => {\n        expect.assertions(1);\n        const stakeHistory = await fetchSysvarStakeHistory(rpc);\n        expect(stakeHistory).toMatchObject(expect.any(Array)); // Not always populated on test validator\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__tests__/sysvar-test.ts",
    "content": "import type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\n\nimport {\n    fetchEncodedSysvarAccount,\n    fetchJsonParsedSysvarAccount,\n    SYSVAR_CLOCK_ADDRESS,\n    SYSVAR_EPOCH_SCHEDULE_ADDRESS,\n    SYSVAR_LAST_RESTART_SLOT_ADDRESS,\n    SYSVAR_RECENT_BLOCKHASHES_ADDRESS,\n    SYSVAR_RENT_ADDRESS,\n    SYSVAR_SLOT_HASHES_ADDRESS,\n    SYSVAR_SLOT_HISTORY_ADDRESS,\n    SYSVAR_STAKE_HISTORY_ADDRESS,\n} from '../sysvar';\nimport { createLocalhostSolanaRpc } from './__setup__';\n\ndescribe('sysvar account', () => {\n    let rpc: Rpc<GetAccountInfoApi>;\n    beforeEach(() => {\n        rpc = createLocalhostSolanaRpc();\n    });\n    const assertValidEncodedSysvarAccount = async (address: Parameters<typeof fetchEncodedSysvarAccount>[1]) => {\n        const account = await fetchEncodedSysvarAccount(rpc, address);\n        expect(account.address).toEqual(address);\n        expect(account.exists).toBe(true);\n        expect(account).toMatchObject({\n            data: expect.any(Uint8Array),\n        });\n    };\n    const assertValidJsonParsedSysvarAccount = async (\n        address: Parameters<typeof fetchEncodedSysvarAccount>[1],\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        data: any,\n    ) => {\n        const account = await fetchJsonParsedSysvarAccount(rpc, address);\n        expect(account.address).toEqual(address);\n        expect(account.exists).toBe(true);\n        expect(account).toMatchObject(data);\n    };\n    describe('clock', () => {\n        it('fetch encoded', async () => {\n            expect.assertions(3);\n            await assertValidEncodedSysvarAccount(SYSVAR_CLOCK_ADDRESS);\n        });\n        it('fetch JSON-parsed', async () => {\n            expect.assertions(3);\n            await assertValidJsonParsedSysvarAccount(SYSVAR_CLOCK_ADDRESS, {\n                data: {\n                    epoch: expect.any(BigInt),\n                    epochStartTimestamp: expect.any(BigInt),\n                    leaderScheduleEpoch: expect.any(BigInt),\n                    slot: expect.any(BigInt),\n                    unixTimestamp: expect.any(BigInt),\n                },\n            });\n        });\n    });\n    // `EpochRewards` will only appear at the start of an epoch, after epoch 0 concludes.\n    // See https://github.com/anza-xyz/agave/blob/e0203f22dc83cb792fa97f91dbe6e924cbd08af1/docs/src/runtime/sysvars.md?plain=1#L155-L168\n    describe('epoch schedule', () => {\n        it('fetch encoded', async () => {\n            expect.assertions(3);\n            await assertValidEncodedSysvarAccount(SYSVAR_EPOCH_SCHEDULE_ADDRESS);\n        });\n        it('fetch JSON-parsed', async () => {\n            expect.assertions(3);\n            await assertValidJsonParsedSysvarAccount(SYSVAR_EPOCH_SCHEDULE_ADDRESS, {\n                data: {\n                    firstNormalEpoch: expect.any(BigInt),\n                    firstNormalSlot: expect.any(BigInt),\n                    leaderScheduleSlotOffset: expect.any(BigInt),\n                    slotsPerEpoch: expect.any(BigInt),\n                    warmup: expect.any(Boolean),\n                },\n            });\n        });\n    });\n    // `Instructions` does not exist on-chain.\n    describe('last restart slot', () => {\n        it('fetch encoded', async () => {\n            expect.assertions(3);\n            await assertValidEncodedSysvarAccount(SYSVAR_LAST_RESTART_SLOT_ADDRESS);\n        });\n        it('fetch JSON-parsed', async () => {\n            expect.assertions(3);\n            await assertValidJsonParsedSysvarAccount(SYSVAR_LAST_RESTART_SLOT_ADDRESS, {\n                data: {\n                    lastRestartSlot: expect.any(BigInt),\n                },\n            });\n        });\n    });\n    describe('recent blockhashes', () => {\n        it('fetch encoded', async () => {\n            expect.assertions(3);\n            await assertValidEncodedSysvarAccount(SYSVAR_RECENT_BLOCKHASHES_ADDRESS);\n        });\n        it('fetch JSON-parsed', async () => {\n            expect.assertions(3);\n            await assertValidJsonParsedSysvarAccount(SYSVAR_RECENT_BLOCKHASHES_ADDRESS, {\n                data: expect.arrayContaining([\n                    {\n                        blockhash: expect.any(String),\n                        feeCalculator: {\n                            lamportsPerSignature: expect.any(String), // JsonParsed converts to string\n                        },\n                    },\n                ]),\n            });\n        });\n    });\n    describe('rent', () => {\n        it('fetch encoded', async () => {\n            expect.assertions(3);\n            await assertValidEncodedSysvarAccount(SYSVAR_RENT_ADDRESS);\n        });\n        it('fetch JSON-parsed', async () => {\n            expect.assertions(3);\n            await assertValidJsonParsedSysvarAccount(SYSVAR_RENT_ADDRESS, {\n                data: {\n                    burnPercent: expect.any(Number),\n                    exemptionThreshold: expect.any(Number),\n                    lamportsPerByteYear: expect.any(String), // JsonParsed converts to string\n                },\n            });\n        });\n    });\n    describe('slot hashes', () => {\n        it('fetch encoded', async () => {\n            expect.assertions(3);\n            await assertValidEncodedSysvarAccount(SYSVAR_SLOT_HASHES_ADDRESS);\n        });\n        it('fetch JSON-parsed', async () => {\n            expect.assertions(3);\n            await assertValidJsonParsedSysvarAccount(SYSVAR_SLOT_HASHES_ADDRESS, {\n                data: expect.arrayContaining([\n                    {\n                        hash: expect.any(String),\n                        slot: expect.any(BigInt),\n                    },\n                ]),\n            });\n        });\n    });\n    describe('slot history', () => {\n        it('fetch encoded', async () => {\n            expect.assertions(3);\n            await assertValidEncodedSysvarAccount(SYSVAR_SLOT_HISTORY_ADDRESS);\n        });\n        it('fetch JSON-parsed', async () => {\n            expect.assertions(3);\n            await assertValidJsonParsedSysvarAccount(SYSVAR_SLOT_HISTORY_ADDRESS, {\n                data: {\n                    bits: expect.any(String), // JsonParsed converts to string\n                    nextSlot: expect.any(BigInt),\n                },\n            });\n        });\n    });\n    describe('stake history', () => {\n        it('fetch encoded', async () => {\n            expect.assertions(3);\n            await assertValidEncodedSysvarAccount(SYSVAR_STAKE_HISTORY_ADDRESS);\n        });\n        it('fetch JSON-parsed', async () => {\n            expect.assertions(3);\n            await assertValidJsonParsedSysvarAccount(SYSVAR_STAKE_HISTORY_ADDRESS, {\n                data: expect.any(Array), // Not always populated on test validator\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/sysvars/src/__typetests__/sysvar-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport type { MaybeAccount, MaybeEncodedAccount } from '@solana/accounts';\nimport type { Address } from '@solana/addresses';\nimport type { JsonParsedSysvarAccount } from '@solana/rpc-parsed-types';\n\nimport { fetchSysvarClock, type SysvarClock } from '../clock';\nimport { fetchSysvarEpochRewards, type SysvarEpochRewards } from '../epoch-rewards';\nimport { fetchSysvarEpochSchedule, type SysvarEpochSchedule } from '../epoch-schedule';\nimport { fetchSysvarLastRestartSlot, type SysvarLastRestartSlot } from '../last-restart-slot';\nimport { fetchSysvarRecentBlockhashes, type SysvarRecentBlockhashes } from '../recent-blockhashes';\nimport { fetchSysvarRent, type SysvarRent } from '../rent';\nimport { fetchSysvarSlotHashes, type SysvarSlotHashes } from '../slot-hashes';\nimport { fetchSysvarSlotHistory, type SysvarSlotHistory } from '../slot-history';\nimport { fetchSysvarStakeHistory, type SysvarStakeHistory } from '../stake-history';\nimport { fetchEncodedSysvarAccount, fetchJsonParsedSysvarAccount, SYSVAR_CLOCK_ADDRESS } from '../sysvar';\n\nconst rpc = null as unknown as Parameters<typeof fetchEncodedSysvarAccount>[0];\n\n// `fetchEncodedSysvarAccount`\n{\n    // Only accepts a valid sysvar address.\n    fetchEncodedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS);\n    // @ts-expect-error Only accepts a valid sysvar address.\n    fetchEncodedSysvarAccount(rpc, 'Foo1111' as Address<'Foo1111'>);\n\n    // Returns a `MaybeEncodedAccount` with the provided sysvar address.\n    fetchEncodedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS) satisfies Promise<\n        MaybeEncodedAccount<typeof SYSVAR_CLOCK_ADDRESS>\n    >;\n    // @ts-expect-error Returns a `MaybeEncodedAccount` with the provided sysvar address.\n    fetchEncodedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS) satisfies Promise<MaybeEncodedAccount<Address<'Foo1111'>>>;\n}\n\n// `fetchJsonParsedSysvarAccount`\n{\n    // Only accepts a valid sysvar address.\n    fetchJsonParsedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS);\n    // @ts-expect-error Only accepts a valid sysvar address.\n    fetchJsonParsedSysvarAccount(rpc, 'Foo1111' as Address<'Foo1111'>);\n\n    // Returns an `MaybeAccount or MaybeEncodedAccount` with the provided sysvar address,\n    // as well as the `JsonParsedSysvarAccount` data.\n    fetchJsonParsedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS) satisfies Promise<\n        | MaybeAccount<JsonParsedSysvarAccount, typeof SYSVAR_CLOCK_ADDRESS>\n        | MaybeEncodedAccount<typeof SYSVAR_CLOCK_ADDRESS>\n    >;\n    // @ts-expect-error Returns an `MaybeAccount or MaybeEncodedAccount` with the provided address.\n    fetchJsonParsedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS) satisfies Promise<\n        MaybeAccount<JsonParsedSysvarAccount, Address<'Foo1111'>> | MaybeEncodedAccount<Address<'Foo1111'>>\n    >;\n    // @ts-expect-error Returns an `MaybeAccount or MaybeEncodedAccount` with `JsonParsedSysvarAccount` data.\n    fetchJsonParsedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS) satisfies Promise<\n        MaybeAccount<{ foo: string }, typeof SYSVAR_CLOCK_ADDRESS> | MaybeEncodedAccount<typeof SYSVAR_CLOCK_ADDRESS>\n    >;\n}\n\n// `fetchSysvarClock`\n{\n    // Returns a `SysvarClock`.\n    fetchSysvarClock(rpc) satisfies Promise<SysvarClock>;\n    // @ts-expect-error Returns a `SysvarClock`.\n    fetchSysvarClock(rpc) satisfies Promise<{ foo: string }>;\n}\n\n// `fetchSysvarEpochRewards`\n{\n    // Returns a `SysvarEpochRewards`.\n    fetchSysvarEpochRewards(rpc) satisfies Promise<SysvarEpochRewards>;\n    // @ts-expect-error Returns a `SysvarEpochRewards`.\n    fetchSysvarEpochRewards(rpc) satisfies Promise<{ foo: string }>;\n}\n\n// `fetchSysvarEpochSchedule`\n{\n    // Returns a `SysvarEpochSchedule`.\n    fetchSysvarEpochSchedule(rpc) satisfies Promise<SysvarEpochSchedule>;\n    // @ts-expect-error Returns a `SysvarEpochSchedule`.\n    fetchSysvarEpochSchedule(rpc) satisfies Promise<{ foo: string }>;\n}\n\n// `fetchSysvarLastRestartSlot`\n{\n    // Returns a `SysvarLastRestartSlot`.\n    fetchSysvarLastRestartSlot(rpc) satisfies Promise<SysvarLastRestartSlot>;\n    // @ts-expect-error Returns a `SysvarLastRestartSlot`.\n    fetchSysvarLastRestartSlot(rpc) satisfies Promise<{ foo: string }>;\n}\n\n// `fetchSysvarRecentBlockhashes`\n{\n    // Returns a `SysvarRecentBlockhashes`.\n    fetchSysvarRecentBlockhashes(rpc) satisfies Promise<SysvarRecentBlockhashes>;\n    // @ts-expect-error Returns a `SysvarRecentBlockhashes`.\n    fetchSysvarRecentBlockhashes(rpc) satisfies Promise<{ foo: string }>;\n}\n\n// `fetchSysvarRent`\n{\n    // Returns a `SysvarRent`.\n    fetchSysvarRent(rpc) satisfies Promise<SysvarRent>;\n    // @ts-expect-error Returns a `SysvarRent`.\n    fetchSysvarRent(rpc) satisfies Promise<{ foo: string }>;\n}\n\n// `fetchSysvarSlotHashes`\n{\n    // Returns a `SysvarSlotHashes`.\n    fetchSysvarSlotHashes(rpc) satisfies Promise<SysvarSlotHashes>;\n    // @ts-expect-error Returns a `SysvarSlotHashes`.\n    fetchSysvarSlotHashes(rpc) satisfies Promise<{ foo: string }>;\n}\n\n// `fetchSysvarSlotHistory`\n{\n    // Returns a `SysvarSlotHistory`.\n    fetchSysvarSlotHistory(rpc) satisfies Promise<SysvarSlotHistory>;\n    // @ts-expect-error Returns a `SysvarSlotHistory`.\n    fetchSysvarSlotHistory(rpc) satisfies Promise<{ foo: string }>;\n}\n\n// `fetchSysvarStakeHistory`\n{\n    // Returns a `SysvarStakeHistory`.\n    fetchSysvarStakeHistory(rpc) satisfies Promise<SysvarStakeHistory>;\n    // @ts-expect-error Returns a `SysvarStakeHistory`.\n    fetchSysvarStakeHistory(rpc) satisfies Promise<{ foo: string }>;\n}\n"
  },
  {
    "path": "packages/sysvars/src/clock.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport { combineCodec, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder } from '@solana/codecs-core';\nimport { getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getI64Decoder, getI64Encoder, getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Epoch, Slot, UnixTimestamp } from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_CLOCK_ADDRESS } from './sysvar';\n\ntype SysvarClockSize = 40;\n\n/**\n * Contains data on cluster time, including the current slot, epoch, and estimated wall-clock Unix\n * timestamp. It is updated every slot.\n */\nexport type SysvarClock = Readonly<{\n    /** The current epoch */\n    epoch: Epoch;\n    /**\n     * The Unix timestamp of the first slot in this epoch.\n     *\n     * In the first slot of an epoch, this timestamp is identical to the `unixTimestamp`.\n     */\n    epochStartTimestamp: UnixTimestamp;\n    /** The most recent epoch for which the leader schedule has already been generated */\n    leaderScheduleEpoch: Epoch;\n    /** The current slot */\n    slot: Slot;\n    /** The Unix timestamp of this slot */\n    unixTimestamp: UnixTimestamp;\n}>;\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarClock} to a byte array representing\n * the `Clock` sysvar's account data.\n */\nexport function getSysvarClockEncoder(): FixedSizeEncoder<SysvarClock, SysvarClockSize> {\n    return getStructEncoder([\n        ['slot', getU64Encoder()],\n        ['epochStartTimestamp', getI64Encoder()],\n        ['epoch', getU64Encoder()],\n        ['leaderScheduleEpoch', getU64Encoder()],\n        ['unixTimestamp', getI64Encoder()],\n    ]) as FixedSizeEncoder<SysvarClock, SysvarClockSize>;\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `Clock` sysvar's\n * account data to a {@link SysvarClock}.\n */\nexport function getSysvarClockDecoder(): FixedSizeDecoder<SysvarClock, SysvarClockSize> {\n    return getStructDecoder([\n        ['slot', getU64Decoder()],\n        ['epochStartTimestamp', getI64Decoder()],\n        ['epoch', getU64Decoder()],\n        ['leaderScheduleEpoch', getU64Decoder()],\n        ['unixTimestamp', getI64Decoder()],\n    ]) as FixedSizeDecoder<SysvarClock, SysvarClockSize>;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarClock}\n *\n * @see {@link getSysvarClockDecoder}\n * @see {@link getSysvarClockEncoder}\n */\nexport function getSysvarClockCodec(): FixedSizeCodec<SysvarClock, SysvarClock, SysvarClockSize> {\n    return combineCodec(getSysvarClockEncoder(), getSysvarClockDecoder());\n}\n\n/**\n * Fetches the `Clock` sysvar account using any RPC that supports the {@link GetAccountInfoApi}.\n */\nexport async function fetchSysvarClock(rpc: Rpc<GetAccountInfoApi>, config?: FetchAccountConfig): Promise<SysvarClock> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarClockDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/epoch-rewards.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport { combineCodec, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder } from '@solana/codecs-core';\nimport {\n    getBooleanDecoder,\n    getBooleanEncoder,\n    getStructDecoder,\n    getStructEncoder,\n} from '@solana/codecs-data-structures';\nimport { getU64Decoder, getU64Encoder, getU128Decoder, getU128Encoder } from '@solana/codecs-numbers';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport {\n    Blockhash,\n    getBlockhashDecoder,\n    getBlockhashEncoder,\n    getDefaultLamportsDecoder,\n    getDefaultLamportsEncoder,\n    Lamports,\n} from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_EPOCH_REWARDS_ADDRESS } from './sysvar';\n\ntype SysvarEpochRewardsSize = 81;\n\n/**\n * Tracks whether the rewards period (including calculation and distribution) is in progress, as\n * well as the details needed to resume distribution when starting from a snapshot during the\n * rewards period.\n *\n * The sysvar is repopulated at the start of the first block of each epoch. Therefore, the sysvar\n * contains data about the current epoch until a new epoch begins.\n */\nexport type SysvarEpochRewards = Readonly<{\n    /** Whether the rewards period (including calculation and distribution) is active */\n    active: boolean;\n    /** The rewards currently distributed for the current epoch, in {@link Lamports} */\n    distributedRewards: Lamports;\n    /** The starting block height of the rewards distribution in the current epoch */\n    distributionStartingBlockHeight: bigint;\n    /**\n     * Number of partitions in the rewards distribution in the current epoch, used to generate an\n     * `EpochRewardsHasher`\n     */\n    numPartitions: bigint;\n    /**\n     * The {@link Blockhash} of the parent block of the first block in the epoch, used to seed an\n     * `EpochRewardsHasher`\n     */\n    parentBlockhash: Blockhash;\n    /**\n     * The total rewards points calculated for the current epoch, where points equals the sum of\n     * (delegated stake * credits observed) for all  delegations\n     */\n    totalPoints: bigint;\n    /** The total rewards for the current epoch, in {@link Lamports} */\n    totalRewards: Lamports;\n}>;\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarEpochRewards} to a byte array\n * representing the `EpochRewards` sysvar's account data.\n */\nexport function getSysvarEpochRewardsEncoder(): FixedSizeEncoder<SysvarEpochRewards, SysvarEpochRewardsSize> {\n    return getStructEncoder([\n        ['distributionStartingBlockHeight', getU64Encoder()],\n        ['numPartitions', getU64Encoder()],\n        ['parentBlockhash', getBlockhashEncoder()],\n        ['totalPoints', getU128Encoder()],\n        ['totalRewards', getDefaultLamportsEncoder()],\n        ['distributedRewards', getDefaultLamportsEncoder()],\n        ['active', getBooleanEncoder()],\n    ]) as FixedSizeEncoder<SysvarEpochRewards, SysvarEpochRewardsSize>;\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `EpochRewards`\n * sysvar's account data to a {@link SysvarEpochRewards}.\n */\nexport function getSysvarEpochRewardsDecoder(): FixedSizeDecoder<SysvarEpochRewards, SysvarEpochRewardsSize> {\n    return getStructDecoder([\n        ['distributionStartingBlockHeight', getU64Decoder()],\n        ['numPartitions', getU64Decoder()],\n        ['parentBlockhash', getBlockhashDecoder()],\n        ['totalPoints', getU128Decoder()],\n        ['totalRewards', getDefaultLamportsDecoder()],\n        ['distributedRewards', getDefaultLamportsDecoder()],\n        ['active', getBooleanDecoder()],\n    ]) as FixedSizeDecoder<SysvarEpochRewards, SysvarEpochRewardsSize>;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarEpochRewards}\n *\n * @see {@link getSysvarEpochRewardsDecoder}\n * @see {@link getSysvarEpochRewardsEncoder}\n */\nexport function getSysvarEpochRewardsCodec(): FixedSizeCodec<\n    SysvarEpochRewards,\n    SysvarEpochRewards,\n    SysvarEpochRewardsSize\n> {\n    return combineCodec(getSysvarEpochRewardsEncoder(), getSysvarEpochRewardsDecoder());\n}\n\n/**\n * Fetch the `EpochRewards` sysvar account using any RPC that supports the\n * {@link GetAccountInfoApi}.\n */\nexport async function fetchSysvarEpochRewards(\n    rpc: Rpc<GetAccountInfoApi>,\n    config?: FetchAccountConfig,\n): Promise<SysvarEpochRewards> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_EPOCH_REWARDS_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarEpochRewardsDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/epoch-schedule.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport { combineCodec, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder } from '@solana/codecs-core';\nimport {\n    getBooleanDecoder,\n    getBooleanEncoder,\n    getStructDecoder,\n    getStructEncoder,\n} from '@solana/codecs-data-structures';\nimport { getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Epoch, Slot } from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_EPOCH_SCHEDULE_ADDRESS } from './sysvar';\n\ntype SysvarEpochScheduleSize = 33;\n\n/**\n * Includes the number of slots per epoch, timing of leader schedule selection, and information\n * about epoch warm-up time.\n */\nexport type SysvarEpochSchedule = Readonly<{\n    /**\n     * First normal-length epoch after the warmup period,\n     * log2(slotsPerEpoch) - log2(MINIMUM_SLOTS_PER_EPOCH)\n     */\n    firstNormalEpoch: Epoch;\n    /**\n     * The first slot after the warmup period, MINIMUM_SLOTS_PER_EPOCH * (2^(firstNormalEpoch) - 1)\n     */\n    firstNormalSlot: Slot;\n    /**\n     * A number of slots before beginning of an epoch to calculate a leader schedule for that\n     * epoch.\n     */\n    leaderScheduleSlotOffset: bigint;\n    /** The maximum number of slots in each epoch */\n    slotsPerEpoch: bigint;\n    /** Whether epochs start short and grow */\n    warmup: boolean;\n}>;\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarEpochSchedule} to a byte array\n * representing the `EpochSchedule` sysvar's account data.\n */\nexport function getSysvarEpochScheduleEncoder(): FixedSizeEncoder<SysvarEpochSchedule, SysvarEpochScheduleSize> {\n    return getStructEncoder([\n        ['slotsPerEpoch', getU64Encoder()],\n        ['leaderScheduleSlotOffset', getU64Encoder()],\n        ['warmup', getBooleanEncoder()],\n        ['firstNormalEpoch', getU64Encoder()],\n        ['firstNormalSlot', getU64Encoder()],\n    ]) as FixedSizeEncoder<SysvarEpochSchedule, SysvarEpochScheduleSize>;\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `EpochSchedule`\n * sysvar's account data to a {@link SysvarEpochSchedule}.\n */\nexport function getSysvarEpochScheduleDecoder(): FixedSizeDecoder<SysvarEpochSchedule, SysvarEpochScheduleSize> {\n    return getStructDecoder([\n        ['slotsPerEpoch', getU64Decoder()],\n        ['leaderScheduleSlotOffset', getU64Decoder()],\n        ['warmup', getBooleanDecoder()],\n        ['firstNormalEpoch', getU64Decoder()],\n        ['firstNormalSlot', getU64Decoder()],\n    ]) as FixedSizeDecoder<SysvarEpochSchedule, SysvarEpochScheduleSize>;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarEpochSchedule}\n *\n * @see {@link getSysvarEpochScheduleDecoder}\n * @see {@link getSysvarEpochScheduleEncoder}\n */\nexport function getSysvarEpochScheduleCodec(): FixedSizeCodec<\n    SysvarEpochSchedule,\n    SysvarEpochSchedule,\n    SysvarEpochScheduleSize\n> {\n    return combineCodec(getSysvarEpochScheduleEncoder(), getSysvarEpochScheduleDecoder());\n}\n\n/**\n * Fetches the `EpochSchedule` sysvar account using any RPC that supports the\n * {@link GetAccountInfoApi}.\n */\nexport async function fetchSysvarEpochSchedule(\n    rpc: Rpc<GetAccountInfoApi>,\n    config?: FetchAccountConfig,\n): Promise<SysvarEpochSchedule> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_EPOCH_SCHEDULE_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarEpochScheduleDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/index.ts",
    "content": "/**\n * This package contains types and helpers for fetching and decoding Solana sysvars.\n * It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * More information about the available sysvars on Solana can be found in the docs at\n * https://docs.solanalabs.com/runtime/sysvars.\n *\n * All currently available sysvars can be retrieved and/or decoded using this library.\n *\n * - `Clock`\n * - `EpochRewards`\n * - `EpochSchedule`\n * - `Fees`\n * - `LastRestartSlot`\n * - `RecentBlockhashes`\n * - `Rent`\n * - `SlotHashes`\n * - `SlotHistory`\n * - `StakeHistory`\n *\n * The `Instructions` sysvar is also supported but does not exist on-chain, therefore has no\n * corresponding module or codec.\n *\n * @example Fetch and decode a sysvar account.\n * ```ts\n * const clock: SysvarClock = await fetchSysvarClock(rpc);\n * ```\n *\n * @example Fetch and decode a sysvar account manually.\n * ```ts\n * // Fetch.\n * const clock = await fetchEncodedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS);\n * clock satisfies MaybeEncodedAccount<'SysvarC1ock11111111111111111111111111111111'>;\n *\n * // Assert.\n * assertAccountExists(clock);\n * clock satisfies EncodedAccount<'SysvarC1ock11111111111111111111111111111111'>;\n *\n * // Decode.\n * const decodedClock = decodeAccount(clock, getSysvarClockDecoder());\n * decodedClock satisfies Account<SysvarClock, 'SysvarC1ock11111111111111111111111111111111'>;\n * ```\n *\n * @example Fetch a JSON-parsed sysvar account.\n * ```ts\n * const maybeJsonParsedClock = await fetchJsonParsedSysvarAccount(rpc, SYSVAR_CLOCK_ADDRESS);\n * maybeJsonParsedClock satisfies\n *     | MaybeAccount<JsonParsedSysvarAccount, 'SysvarC1ock11111111111111111111111111111111'>\n *     | MaybeEncodedAccount<'SysvarC1ock11111111111111111111111111111111'>;\n * ```\n *\n * @packageDocumentation\n */\nexport * from './clock';\nexport * from './epoch-rewards';\nexport * from './epoch-schedule';\nexport * from './last-restart-slot';\nexport * from './recent-blockhashes';\nexport * from './rent';\nexport * from './slot-hashes';\nexport * from './slot-history';\nexport * from './stake-history';\nexport * from './sysvar';\n"
  },
  {
    "path": "packages/sysvars/src/last-restart-slot.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport { combineCodec, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder } from '@solana/codecs-core';\nimport { getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Slot } from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_LAST_RESTART_SLOT_ADDRESS } from './sysvar';\n\ntype SysvarLastRestartSlotSize = 8;\n\n/**\n * Information about the last restart slot (hard fork).\n *\n * The `LastRestartSlot` sysvar provides access to the last restart slot kept in the bank fork for\n * the slot on the fork that executes the current transaction. In case there was no fork it returns\n * `0`.\n */\nexport type SysvarLastRestartSlot = Readonly<{\n    /** The last restart {@link Slot} */\n    lastRestartSlot: Slot;\n}>;\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarLastRestartSlot} to a byte array\n * representing the `LastRestartSlot` sysvar's account data.\n */\nexport function getSysvarLastRestartSlotEncoder(): FixedSizeEncoder<SysvarLastRestartSlot, SysvarLastRestartSlotSize> {\n    return getStructEncoder([['lastRestartSlot', getU64Encoder()]]) as FixedSizeEncoder<\n        SysvarLastRestartSlot,\n        SysvarLastRestartSlotSize\n    >;\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `LastRestartSlot`\n * sysvar's account data to a {@link SysvarLastRestartSlot}.\n */\nexport function getSysvarLastRestartSlotDecoder(): FixedSizeDecoder<SysvarLastRestartSlot, SysvarLastRestartSlotSize> {\n    return getStructDecoder([['lastRestartSlot', getU64Decoder()]]) as FixedSizeDecoder<\n        SysvarLastRestartSlot,\n        SysvarLastRestartSlotSize\n    >;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarLastRestartSlot}\n *\n * @see {@link getSysvarLastRestartSlotDecoder}\n * @see {@link getSysvarLastRestartSlotEncoder}\n */\nexport function getSysvarLastRestartSlotCodec(): FixedSizeCodec<\n    SysvarLastRestartSlot,\n    SysvarLastRestartSlot,\n    SysvarLastRestartSlotSize\n> {\n    return combineCodec(getSysvarLastRestartSlotEncoder(), getSysvarLastRestartSlotDecoder());\n}\n\n/**\n * Fetches the `LastRestartSlot` sysvar account using any RPC that supports the\n * {@link GetAccountInfoApi}.\n */\nexport async function fetchSysvarLastRestartSlot(\n    rpc: Rpc<GetAccountInfoApi>,\n    config?: FetchAccountConfig,\n): Promise<SysvarLastRestartSlot> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_LAST_RESTART_SLOT_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarLastRestartSlotDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/recent-blockhashes.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport {\n    combineCodec,\n    type VariableSizeCodec,\n    type VariableSizeDecoder,\n    type VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder, getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport {\n    type Blockhash,\n    getBlockhashDecoder,\n    getBlockhashEncoder,\n    getDefaultLamportsDecoder,\n    getDefaultLamportsEncoder,\n    type Lamports,\n} from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_RECENT_BLOCKHASHES_ADDRESS } from './sysvar';\n\ntype FeeCalculator = Readonly<{\n    /**\n     * The current cost of a signature.\n     *\n     * This amount may increase/decrease over time based on cluster processing load\n     */\n    lamportsPerSignature: Lamports;\n}>;\ntype Entry = Readonly<{\n    blockhash: Blockhash;\n    feeCalculator: FeeCalculator;\n}>;\n\n/**\n * Information about recent blocks and their fee calculators.\n *\n * @deprecated Transaction fees should be determined with the\n * {@link GetFeeForMessageApi.getFeeForMessage} RPC method. For additional context see the\n * [Comprehensive Compute Fees proposal](https://docs.anza.xyz/proposals/comprehensive-compute-fees/).\n */\nexport type SysvarRecentBlockhashes = Entry[];\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarRecentBlockhashes} to a byte array\n * representing the `RecentBlockhashes` sysvar's account data.\n *\n * @deprecated Transaction fees should be determined with the\n * {@link GetFeeForMessageApi.getFeeForMessage} RPC method. For additional context see the\n * [Comprehensive Compute Fees proposal](https://docs.anza.xyz/proposals/comprehensive-compute-fees/).\n */\nexport function getSysvarRecentBlockhashesEncoder(): VariableSizeEncoder<SysvarRecentBlockhashes> {\n    return getArrayEncoder(\n        getStructEncoder([\n            ['blockhash', getBlockhashEncoder()],\n            ['feeCalculator', getStructEncoder([['lamportsPerSignature', getDefaultLamportsEncoder()]])],\n        ]),\n    );\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `RecentBlockhashes`\n * sysvar's account data to a {@link SysvarRecentBlockhashes}.\n *\n * @deprecated Transaction fees should be determined with the\n * {@link GetFeeForMessageApi.getFeeForMessage} RPC method. For additional context see the\n * [Comprehensive Compute Fees proposal](https://docs.anza.xyz/proposals/comprehensive-compute-fees/).\n */\nexport function getSysvarRecentBlockhashesDecoder(): VariableSizeDecoder<SysvarRecentBlockhashes> {\n    return getArrayDecoder(\n        getStructDecoder([\n            ['blockhash', getBlockhashDecoder()],\n            ['feeCalculator', getStructDecoder([['lamportsPerSignature', getDefaultLamportsDecoder()]])],\n        ]),\n    );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarRecentBlockhashes}\n *\n * @deprecated Transaction fees should be determined with the\n * {@link GetFeeForMessageApi.getFeeForMessage} RPC method. For additional context see the\n * [Comprehensive Compute Fees proposal](https://docs.anza.xyz/proposals/comprehensive-compute-fees/).\n *\n * @see {@link getSysvarRecentBlockhashesDecoder}\n * @see {@link getSysvarRecentBlockhashesEncoder}\n */\nexport function getSysvarRecentBlockhashesCodec(): VariableSizeCodec<SysvarRecentBlockhashes> {\n    return combineCodec(getSysvarRecentBlockhashesEncoder(), getSysvarRecentBlockhashesDecoder());\n}\n\n/**\n * Fetches the `RecentBlockhashes` sysvar account using any RPC that supports the\n * {@link GetAccountInfoApi}.\n *\n * @deprecated Transaction fees should be determined with the\n * {@link GetFeeForMessageApi.getFeeForMessage} RPC method. For additional context see the\n * [Comprehensive Compute Fees proposal](https://docs.anza.xyz/proposals/comprehensive-compute-fees/).\n */\nexport async function fetchSysvarRecentBlockhashes(\n    rpc: Rpc<GetAccountInfoApi>,\n    config?: FetchAccountConfig,\n): Promise<SysvarRecentBlockhashes> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_RECENT_BLOCKHASHES_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarRecentBlockhashesDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/rent.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport { combineCodec, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder } from '@solana/codecs-core';\nimport { getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getF64Decoder, getF64Encoder, getU8Decoder, getU8Encoder } from '@solana/codecs-numbers';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport {\n    F64UnsafeSeeDocumentation,\n    getDefaultLamportsDecoder,\n    getDefaultLamportsEncoder,\n    type Lamports,\n} from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_RENT_ADDRESS } from './sysvar';\n\ntype SysvarRentSize = 17;\n\n/**\n * Configuration for network rent.\n */\nexport type SysvarRent = Readonly<{\n    /**\n     * The percentage of collected rent that is burned.\n     *\n     * Valid values are in the range [0, 100]. The remaining percentage is distributed to\n     * validators.\n     */\n    burnPercent: number;\n    /** Amount of time (in years) a balance must include rent for the account to be rent exempt */\n    exemptionThreshold: F64UnsafeSeeDocumentation;\n    /** Rental rate in {@link Lamports}/byte-year. */\n    lamportsPerByteYear: Lamports;\n}>;\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarRent} to a byte array representing\n * the `Rent` sysvar's account data.\n */\nexport function getSysvarRentEncoder(): FixedSizeEncoder<SysvarRent, SysvarRentSize> {\n    return getStructEncoder([\n        ['lamportsPerByteYear', getDefaultLamportsEncoder()],\n        ['exemptionThreshold', getF64Encoder()],\n        ['burnPercent', getU8Encoder()],\n    ]) as FixedSizeEncoder<SysvarRent, SysvarRentSize>;\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `Rent` sysvar's\n * account data to a {@link SysvarRent}.\n */\nexport function getSysvarRentDecoder(): FixedSizeDecoder<SysvarRent, SysvarRentSize> {\n    return getStructDecoder([\n        ['lamportsPerByteYear', getDefaultLamportsDecoder()],\n        ['exemptionThreshold', getF64Decoder()],\n        ['burnPercent', getU8Decoder()],\n    ]) as FixedSizeDecoder<SysvarRent, SysvarRentSize>;\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarRent}\n *\n * @see {@link getSysvarRentDecoder}\n * @see {@link getSysvarRentEncoder}\n */\nexport function getSysvarRentCodec(): FixedSizeCodec<SysvarRent, SysvarRent, SysvarRentSize> {\n    return combineCodec(getSysvarRentEncoder(), getSysvarRentDecoder());\n}\n\n/**\n * Fetches the `Rent` sysvar account using any RPC that supports the {@link GetAccountInfoApi}.\n */\nexport async function fetchSysvarRent(rpc: Rpc<GetAccountInfoApi>, config?: FetchAccountConfig): Promise<SysvarRent> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_RENT_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarRentDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/slot-hashes.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport {\n    combineCodec,\n    type VariableSizeCodec,\n    type VariableSizeDecoder,\n    type VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder, getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport { type Blockhash, getBlockhashDecoder, getBlockhashEncoder, type Slot } from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_SLOT_HASHES_ADDRESS } from './sysvar';\n\ntype Entry = Readonly<{\n    hash: Blockhash;\n    slot: Slot;\n}>;\n\n/** The most recent hashes of a slot's parent banks. */\nexport type SysvarSlotHashes = Entry[];\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarSlotHashes} to a byte array\n * representing the `SlotHashes` sysvar's account data.\n */\nexport function getSysvarSlotHashesEncoder(): VariableSizeEncoder<SysvarSlotHashes> {\n    return getArrayEncoder(\n        getStructEncoder([\n            ['slot', getU64Encoder()],\n            ['hash', getBlockhashEncoder()],\n        ]),\n    );\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `SlotHashes` sysvar's\n * account data to a {@link SysvarSlotHashes}.\n */\nexport function getSysvarSlotHashesDecoder(): VariableSizeDecoder<SysvarSlotHashes> {\n    return getArrayDecoder(\n        getStructDecoder([\n            ['slot', getU64Decoder()],\n            ['hash', getBlockhashDecoder()],\n        ]),\n    );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarSlotHashes}\n *\n * @see {@link getSysvarSlotHashesDecoder}\n * @see {@link getSysvarSlotHashesEncoder}\n */\nexport function getSysvarSlotHashesCodec(): VariableSizeCodec<SysvarSlotHashes> {\n    return combineCodec(getSysvarSlotHashesEncoder(), getSysvarSlotHashesDecoder());\n}\n\n/**\n * Fetches the `SlotHashes` sysvar account using any RPC that supports the {@link GetAccountInfoApi}.\n */\nexport async function fetchSysvarSlotHashes(\n    rpc: Rpc<GetAccountInfoApi>,\n    config?: FetchAccountConfig,\n): Promise<SysvarSlotHashes> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_SLOT_HASHES_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarSlotHashesDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/slot-history.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    type FixedSizeCodec,\n    type FixedSizeDecoder,\n    type FixedSizeEncoder,\n    ReadonlyUint8Array,\n} from '@solana/codecs-core';\nimport { getArrayCodec } from '@solana/codecs-data-structures';\nimport { getU64Codec, getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE,\n    SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH,\n    SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS,\n    SolanaError,\n} from '@solana/errors';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport type { Slot } from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_SLOT_HISTORY_ADDRESS } from './sysvar';\n\nconst BITVEC_DISCRIMINATOR = 1;\n// Max number of bits in the bitvector.\n// The Solana SDK defines a constant `MAX_ENTRIES` representing the maximum\n// number of bits that can be represented by the bitvector in the `SlotHistory`\n// sysvar. This value is 1024 * 1024 = 1_048_576.\n// See https://github.com/anza-xyz/agave/blob/e0203f22dc83cb792fa97f91dbe6e924cbd08af1/sdk/program/src/slot_history.rs#L43\nconst BITVEC_NUM_BITS = 1024 * 1024;\n// The length of the bitvector in blocks.\n// At 64 bits per block, this is 1024 * 1024 / 64 = 16_384.\nconst BITVEC_LENGTH = BITVEC_NUM_BITS / 64;\n\nconst SLOT_HISTORY_ACCOUNT_DATA_STATIC_SIZE =\n    1 + // Discriminator\n    8 + // bitvector length (u64)\n    BITVEC_LENGTH * 8 +\n    8 + // Number of bits (u64)\n    8; // Next slot (u64)\n\nlet memoizedU64Encoder: FixedSizeEncoder<bigint, 8> | undefined;\nlet memoizedU64Decoder: FixedSizeDecoder<bigint, 8> | undefined;\nlet memoizedU64ArrayEncoder: FixedSizeEncoder<bigint[]> | undefined;\nlet memoizedU64ArrayDecoder: FixedSizeDecoder<bigint[]> | undefined;\n\nfunction getMemoizedU64Encoder(): FixedSizeEncoder<bigint, 8> {\n    if (!memoizedU64Encoder) memoizedU64Encoder = getU64Encoder();\n    return memoizedU64Encoder;\n}\nfunction getMemoizedU64Decoder(): FixedSizeDecoder<bigint, 8> {\n    if (!memoizedU64Decoder) memoizedU64Decoder = getU64Decoder();\n    return memoizedU64Decoder;\n}\nfunction getMemoizedU64ArrayEncoder(): FixedSizeEncoder<bigint[], typeof BITVEC_LENGTH> {\n    if (!memoizedU64ArrayEncoder) memoizedU64ArrayEncoder = getArrayCodec(getU64Codec(), { size: BITVEC_LENGTH });\n    return memoizedU64ArrayEncoder;\n}\nfunction getMemoizedU64ArrayDecoder(): FixedSizeDecoder<bigint[], typeof BITVEC_LENGTH> {\n    if (!memoizedU64ArrayDecoder) memoizedU64ArrayDecoder = getArrayCodec(getU64Codec(), { size: BITVEC_LENGTH });\n    return memoizedU64ArrayDecoder;\n}\n\ntype SysvarSlotHistorySize = typeof SLOT_HISTORY_ACCOUNT_DATA_STATIC_SIZE;\n\n/** A bitvector of slots present over the last epoch. */\nexport type SysvarSlotHistory = {\n    /**\n     * A vector of 64-bit numbers which, when their bits are strung together, represent a record of\n     * non-skipped slots.\n     *\n     * The bit in position (slot % MAX_ENTRIES) is 0 if the slot was skipped and 1 otherwise, valid\n     * only when the candidate slot is less than `nextSlot` and greater than or equal to\n     * `MAX_ENTRIES - nextSlot`.\n     */\n    bits: bigint[];\n    /** The number of the slot one newer than tracked by the bitvector */\n    nextSlot: Slot;\n};\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarSlotHistory} to a byte array\n * representing the `SlotHistory` sysvar's account data.\n */\nexport function getSysvarSlotHistoryEncoder(): FixedSizeEncoder<SysvarSlotHistory, SysvarSlotHistorySize> {\n    return createEncoder({\n        fixedSize: SLOT_HISTORY_ACCOUNT_DATA_STATIC_SIZE,\n        write: (value: SysvarSlotHistory, bytes, offset) => {\n            // First byte is the bitvector discriminator.\n            bytes.set([BITVEC_DISCRIMINATOR], offset);\n            offset += 1;\n            // Next 8 bytes are the bitvector length.\n            getMemoizedU64Encoder().write(BigInt(BITVEC_LENGTH), bytes, offset);\n            offset += 8;\n            // Next `BITVEC_LENGTH` bytes are the bitvector.\n            // Any missing bits are assumed to be 0.\n            getMemoizedU64ArrayEncoder().write(value.bits, bytes, offset);\n            offset += BITVEC_LENGTH * 8;\n            // Next 8 bytes are the number of bits.\n            getMemoizedU64Encoder().write(BigInt(BITVEC_NUM_BITS), bytes, offset);\n            offset += 8;\n            // Next 8 bytes are the next slot.\n            getMemoizedU64Encoder().write(value.nextSlot, bytes, offset);\n            offset += 8;\n            return offset;\n        },\n    });\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `SlotHistory` sysvar's\n * account data to a {@link SysvarSlotHistory}.\n */\nexport function getSysvarSlotHistoryDecoder(): FixedSizeDecoder<SysvarSlotHistory, SysvarSlotHistorySize> {\n    return createDecoder({\n        fixedSize: SLOT_HISTORY_ACCOUNT_DATA_STATIC_SIZE,\n        read: (bytes: ReadonlyUint8Array | Uint8Array, offset) => {\n            // Byte length should be exact.\n            if (bytes.length != SLOT_HISTORY_ACCOUNT_DATA_STATIC_SIZE) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_BYTE_LENGTH, {\n                    actual: bytes.length,\n                    expected: SLOT_HISTORY_ACCOUNT_DATA_STATIC_SIZE,\n                });\n            }\n            // First byte is the bitvector discriminator.\n            const discriminator = bytes[offset];\n            offset += 1;\n            if (discriminator !== BITVEC_DISCRIMINATOR) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__ENUM_DISCRIMINATOR_OUT_OF_RANGE, {\n                    actual: discriminator,\n                    expected: BITVEC_DISCRIMINATOR,\n                });\n            }\n            // Next 8 bytes are the bitvector length.\n            const bitVecLength = getMemoizedU64Decoder().read(bytes, offset)[0];\n            offset += 8;\n            if (bitVecLength !== BigInt(BITVEC_LENGTH)) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                    actual: bitVecLength,\n                    codecDescription: 'SysvarSlotHistoryCodec',\n                    expected: BITVEC_LENGTH,\n                });\n            }\n            // Next `BITVEC_LENGTH` bytes are the bitvector.\n            const bits = getMemoizedU64ArrayDecoder().read(bytes, offset)[0];\n            offset += BITVEC_LENGTH * 8;\n            // Next 8 bytes are the number of bits.\n            const numBits = getMemoizedU64Decoder().read(bytes, offset)[0];\n            offset += 8;\n            if (numBits !== BigInt(BITVEC_NUM_BITS)) {\n                throw new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                    actual: numBits,\n                    codecDescription: 'SysvarSlotHistoryCodec',\n                    expected: BITVEC_NUM_BITS,\n                });\n            }\n            // Next 8 bytes are the next slot.\n            const nextSlot = getMemoizedU64Decoder().read(bytes, offset)[0];\n            offset += 8;\n            return [\n                {\n                    bits,\n                    nextSlot,\n                },\n                offset,\n            ];\n        },\n    });\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarSlotHistory}\n *\n * @see {@link getSysvarSlotHistoryDecoder}\n * @see {@link getSysvarSlotHistoryEncoder}\n */\nexport function getSysvarSlotHistoryCodec(): FixedSizeCodec<\n    SysvarSlotHistory,\n    SysvarSlotHistory,\n    SysvarSlotHistorySize\n> {\n    return combineCodec(getSysvarSlotHistoryEncoder(), getSysvarSlotHistoryDecoder());\n}\n\n/**\n * Fetches the `SlotHistory` sysvar account using any RPC that supports the\n * {@link GetAccountInfoApi}.\n */\nexport async function fetchSysvarSlotHistory(\n    rpc: Rpc<GetAccountInfoApi>,\n    config?: FetchAccountConfig,\n): Promise<SysvarSlotHistory> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_SLOT_HISTORY_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarSlotHistoryDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/stake-history.ts",
    "content": "import { assertAccountExists, decodeAccount, type FetchAccountConfig } from '@solana/accounts';\nimport {\n    combineCodec,\n    type VariableSizeCodec,\n    type VariableSizeDecoder,\n    type VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder, getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { Rpc } from '@solana/rpc-spec';\nimport { Epoch, getDefaultLamportsDecoder, getDefaultLamportsEncoder, type Lamports } from '@solana/rpc-types';\n\nimport { fetchEncodedSysvarAccount, SYSVAR_STAKE_HISTORY_ADDRESS } from './sysvar';\n\ntype Entry = Readonly<{\n    /** The epoch to which this stake history entry pertains */\n    epoch: Epoch;\n    stakeHistory: Readonly<{\n        /**\n         * Sum of portion of stakes requested to be warmed up, but not fully activated yet, in\n         * {@link Lamports}\n         */\n        activating: Lamports;\n        /**\n         * Sum of portion of stakes requested to be cooled down, but not fully deactivated yet, in\n         * {@link Lamports}\n         */\n        deactivating: Lamports;\n        /** Effective stake at this epoch, in {@link Lamports} */\n        effective: Lamports;\n    }>;\n}>;\n\n/** History of stake activations and de-activations. */\nexport type SysvarStakeHistory = Entry[];\n\n/**\n * Returns an encoder that you can use to encode a {@link SysvarStakeHistory} to a byte array\n * representing the `StakeHistory` sysvar's account data.\n */\nexport function getSysvarStakeHistoryEncoder(): VariableSizeEncoder<SysvarStakeHistory> {\n    return getArrayEncoder(\n        getStructEncoder([\n            ['epoch', getU64Encoder()],\n            [\n                'stakeHistory',\n                getStructEncoder([\n                    ['effective', getDefaultLamportsEncoder()],\n                    ['activating', getDefaultLamportsEncoder()],\n                    ['deactivating', getDefaultLamportsEncoder()],\n                ]),\n            ],\n        ]),\n        { size: getU64Encoder() },\n    );\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing the `StakeHistory`\n * sysvar's account data to a {@link SysvarStakeHistory}.\n */\nexport function getSysvarStakeHistoryDecoder(): VariableSizeDecoder<SysvarStakeHistory> {\n    return getArrayDecoder(\n        getStructDecoder([\n            ['epoch', getU64Decoder()],\n            [\n                'stakeHistory',\n                getStructDecoder([\n                    ['effective', getDefaultLamportsDecoder()],\n                    ['activating', getDefaultLamportsDecoder()],\n                    ['deactivating', getDefaultLamportsDecoder()],\n                ]),\n            ],\n        ]),\n        { size: getU64Decoder() },\n    );\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link SysvarStakeHistory}\n *\n * @see {@link getSysvarStakeHistoryDecoder}\n * @see {@link getSysvarStakeHistoryEncoder}\n */\nexport function getSysvarStakeHistoryCodec(): VariableSizeCodec<SysvarStakeHistory> {\n    return combineCodec(getSysvarStakeHistoryEncoder(), getSysvarStakeHistoryDecoder());\n}\n\n/**\n * Fetches the `StakeHistory` sysvar account using any RPC that supports the\n * {@link GetAccountInfoApi}.\n */\nexport async function fetchSysvarStakeHistory(\n    rpc: Rpc<GetAccountInfoApi>,\n    config?: FetchAccountConfig,\n): Promise<SysvarStakeHistory> {\n    const account = await fetchEncodedSysvarAccount(rpc, SYSVAR_STAKE_HISTORY_ADDRESS, config);\n    assertAccountExists(account);\n    const decoded = decodeAccount(account, getSysvarStakeHistoryDecoder());\n    return decoded.data;\n}\n"
  },
  {
    "path": "packages/sysvars/src/sysvar.ts",
    "content": "import {\n    type FetchAccountConfig,\n    fetchEncodedAccount,\n    fetchJsonParsedAccount,\n    type MaybeAccount,\n    type MaybeEncodedAccount,\n} from '@solana/accounts';\nimport type { Address } from '@solana/addresses';\nimport type { GetAccountInfoApi } from '@solana/rpc-api';\nimport type { JsonParsedSysvarAccount } from '@solana/rpc-parsed-types';\nimport type { Rpc } from '@solana/rpc-spec';\n\nexport const SYSVAR_CLOCK_ADDRESS =\n    'SysvarC1ock11111111111111111111111111111111' as Address<'SysvarC1ock11111111111111111111111111111111'>;\nexport const SYSVAR_EPOCH_REWARDS_ADDRESS =\n    'SysvarEpochRewards1111111111111111111111111' as Address<'SysvarEpochRewards1111111111111111111111111'>;\nexport const SYSVAR_EPOCH_SCHEDULE_ADDRESS =\n    'SysvarEpochSchedu1e111111111111111111111111' as Address<'SysvarEpochSchedu1e111111111111111111111111'>;\nexport const SYSVAR_INSTRUCTIONS_ADDRESS =\n    'Sysvar1nstructions1111111111111111111111111' as Address<'Sysvar1nstructions1111111111111111111111111'>;\nexport const SYSVAR_LAST_RESTART_SLOT_ADDRESS =\n    'SysvarLastRestartS1ot1111111111111111111111' as Address<'SysvarLastRestartS1ot1111111111111111111111'>;\nexport const SYSVAR_RECENT_BLOCKHASHES_ADDRESS =\n    'SysvarRecentB1ockHashes11111111111111111111' as Address<'SysvarRecentB1ockHashes11111111111111111111'>;\nexport const SYSVAR_RENT_ADDRESS =\n    'SysvarRent111111111111111111111111111111111' as Address<'SysvarRent111111111111111111111111111111111'>;\nexport const SYSVAR_SLOT_HASHES_ADDRESS =\n    'SysvarS1otHashes111111111111111111111111111' as Address<'SysvarS1otHashes111111111111111111111111111'>;\nexport const SYSVAR_SLOT_HISTORY_ADDRESS =\n    'SysvarS1otHistory11111111111111111111111111' as Address<'SysvarS1otHistory11111111111111111111111111'>;\nexport const SYSVAR_STAKE_HISTORY_ADDRESS =\n    'SysvarStakeHistory1111111111111111111111111' as Address<'SysvarStakeHistory1111111111111111111111111'>;\n\ntype SysvarAddress =\n    | typeof SYSVAR_CLOCK_ADDRESS\n    | typeof SYSVAR_EPOCH_REWARDS_ADDRESS\n    | typeof SYSVAR_EPOCH_SCHEDULE_ADDRESS\n    | typeof SYSVAR_INSTRUCTIONS_ADDRESS\n    | typeof SYSVAR_LAST_RESTART_SLOT_ADDRESS\n    | typeof SYSVAR_RECENT_BLOCKHASHES_ADDRESS\n    | typeof SYSVAR_RENT_ADDRESS\n    | typeof SYSVAR_SLOT_HASHES_ADDRESS\n    | typeof SYSVAR_SLOT_HISTORY_ADDRESS\n    | typeof SYSVAR_STAKE_HISTORY_ADDRESS;\n\n/**\n * Fetch an encoded sysvar account.\n *\n * Sysvars are special accounts that contain dynamically-updated data about the network cluster, the\n * blockchain history, and the executing transaction.\n */\nexport async function fetchEncodedSysvarAccount<TAddress extends SysvarAddress>(\n    rpc: Rpc<GetAccountInfoApi>,\n    address: TAddress,\n    config?: FetchAccountConfig,\n): Promise<MaybeEncodedAccount<TAddress>> {\n    return await fetchEncodedAccount<TAddress>(rpc, address, config);\n}\n\n/**\n * Fetch a JSON-parsed sysvar account.\n *\n * Sysvars are special accounts that contain dynamically-updated data about the network cluster, the\n * blockchain history, and the executing transaction.\n */\nexport async function fetchJsonParsedSysvarAccount<TAddress extends SysvarAddress>(\n    rpc: Rpc<GetAccountInfoApi>,\n    address: TAddress,\n    config?: FetchAccountConfig,\n): Promise<MaybeAccount<JsonParsedSysvarAccount, TAddress> | MaybeEncodedAccount<TAddress>> {\n    return await fetchJsonParsedAccount<JsonParsedSysvarAccount, TAddress>(rpc, address, config);\n}\n"
  },
  {
    "path": "packages/sysvars/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/sysvars/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2017\", \"ES2019.Array\"]\n    },\n    \"display\": \"@solana/sysvars\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/sysvars/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/test-config/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/test-config/browser-environment.ts",
    "content": "import { TestEnvironment } from 'jest-environment-jsdom';\n\nexport default class BrowserEnvironment extends TestEnvironment {\n    async setup() {\n        await super.setup();\n        /**\n         * Here we inject Node's binary array types as globals so that - among other things -\n         * `instanceof` checks inside `SubtleCrypto.digest()` work with `Uint8Array#buffer`. Read\n         * more here: https://github.com/jestjs/jest/issues/7780#issuecomment-615890410\n         */\n        this.global.ArrayBuffer = globalThis.ArrayBuffer;\n        this.global.Uint8Array = globalThis.Uint8Array;\n    }\n}\n"
  },
  {
    "path": "packages/test-config/global.d.ts",
    "content": "declare namespace globalThis {\n    // eslint-disable-next-line no-var\n    var __DEV__: boolean;\n    // eslint-disable-next-line no-var\n    var __VERSION__: string;\n}\n"
  },
  {
    "path": "packages/test-config/jest-dev.config.js",
    "content": "import path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nconst config = {\n    projects: [\n        path.resolve(__dirname, 'jest-lint.config.js'),\n        path.resolve(__dirname, 'jest-prettier.config.js'),\n        path.resolve(__dirname, 'jest-unit.config.browser.js'),\n        path.resolve(__dirname, 'jest-unit.config.node.js'),\n    ],\n    watchPlugins: [\n        'jest-watch-master',\n        'jest-watch-select-projects',\n        'jest-watch-typeahead/filename',\n        'jest-watch-typeahead/testname',\n    ],\n    workerThreads: true,\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/jest-dev.config.ts",
    "content": "import type { Config } from 'jest';\nimport path from 'path';\n\nconst config: Config = {\n    projects: [\n        path.resolve(__dirname, 'jest-lint.config.ts'),\n        path.resolve(__dirname, 'jest-prettier.config.ts'),\n        path.resolve(__dirname, 'jest-unit.config.browser.js'),\n        path.resolve(__dirname, 'jest-unit.config.node.js'),\n    ],\n    watchPlugins: [\n        'jest-watch-master',\n        'jest-watch-select-projects',\n        'jest-watch-typeahead/filename',\n        'jest-watch-typeahead/testname',\n    ],\n    workerThreads: true,\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/jest-lint.config.js",
    "content": "const config = {\n    displayName: {\n        color: 'cyanBright',\n        name: 'ESLint',\n    },\n    runner: 'eslint',\n    testMatch: ['<rootDir>src/**/*.ts'],\n    testPathIgnorePatterns: ['README.md'],\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/jest-lint.config.ts",
    "content": "import type { Config } from '@jest/types';\n\nconst config: Partial<Config.InitialProjectOptions> = {\n    displayName: {\n        color: 'cyanBright',\n        name: 'ESLint',\n    },\n    runner: 'eslint',\n    testMatch: ['<rootDir>src/**/*.ts'],\n    testPathIgnorePatterns: ['README.md'],\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/jest-prettier.config.js",
    "content": "const config = {\n    displayName: {\n        color: 'magentaBright',\n        name: 'Prettier',\n    },\n    moduleFileExtensions: ['js', 'ts', 'json', 'md'],\n    runner: 'prettier',\n    testMatch: ['<rootDir>/src/**', '<rootDir>*'],\n    testPathIgnorePatterns: ['CHANGELOG.md'],\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/jest-prettier.config.ts",
    "content": "import type { Config } from '@jest/types';\n\nconst config: Partial<Config.InitialProjectOptions> = {\n    displayName: {\n        color: 'magentaBright',\n        name: 'Prettier',\n    },\n    moduleFileExtensions: ['js', 'ts', 'json', 'md'],\n    runner: 'prettier',\n    testMatch: ['<rootDir>/src/**', '<rootDir>*'],\n    testPathIgnorePatterns: ['CHANGELOG.md'],\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/jest-unit.config.browser.js",
    "content": "import { createRequire } from 'module';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nimport commonConfig from './jest-unit.config.common.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst require = createRequire(import.meta.url);\n\nconst config = {\n    ...commonConfig,\n    displayName: {\n        color: 'grey',\n        name: 'Unit Test (Browser)',\n    },\n    globals: {\n        ...commonConfig.globals,\n        __BROWSER__: true,\n        __NODEJS__: false,\n        __REACTNATIVE__: false,\n    },\n    // From https://stackoverflow.com/a/73203803/1375972\n    // this is required for @solana/compat, which uses the legacy web3js\n    moduleNameMapper: {\n        // Force module uuid to resolve with the CJS entry point, because Jest does not support package.json.exports. See https://github.com/uuidjs/uuid/issues/451\n        \"uuid\": require.resolve('uuid'),\n    },\n    setupFilesAfterEnv: [\n        ...(commonConfig.setupFilesAfterEnv ?? []),\n        path.resolve(__dirname, 'setup-secure-context.ts'),\n        path.resolve(__dirname, 'setup-text-encoder.ts'),\n        path.resolve(__dirname, 'setup-web-buffer-global.ts'),\n        path.resolve(__dirname, 'setup-whatwg-fetch.ts'),\n    ],\n    testEnvironment: path.resolve(__dirname, 'browser-environment.ts'),\n    testEnvironmentOptions: {},\n    testPathIgnorePatterns: [...(commonConfig.testPathIgnorePatterns ?? []), '-test.node.ts$'],\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/jest-unit.config.common.js",
    "content": "import path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nconst config = {\n    resetMocks: true,\n    restoreMocks: true,\n    roots: ['<rootDir>/src/'],\n    setupFilesAfterEnv: [\n        path.resolve(__dirname, 'setup-dev-mode.ts'),\n        path.resolve(__dirname, 'setup-define-version-constant.ts'),\n        path.resolve(__dirname, 'setup-webcrypto.ts'),\n    ],\n    testPathIgnorePatterns: ['__setup__.ts'],\n    transform: {\n        '^.+\\\\.(ts|js)x?$': [\n            '@swc/jest',\n            {\n                jsc: {\n                    target: 'es2020',\n                },\n            },\n        ],\n    },\n    transformIgnorePatterns: ['/node_modules/(?!.*\\\\@noble/ed25519/)', '\\\\.pnp\\\\.[^\\\\/]+$'],\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/jest-unit.config.node.js",
    "content": "import path from 'node:path';\nimport { fileURLToPath } from 'url';\n\nimport commonConfig from './jest-unit.config.common.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nconst config = {\n    ...commonConfig,\n    displayName: {\n        color: 'grey',\n        name: 'Unit Test (Node)',\n    },\n    globals: {\n        ...commonConfig.globals,\n        __BROWSER__: false,\n        __NODEJS__: true,\n        __REACTNATIVE__: false,\n    },\n    setupFilesAfterEnv: [...(commonConfig.setupFilesAfterEnv ?? []), path.resolve(__dirname, 'setup-undici-fetch.ts')],\n    testPathIgnorePatterns: [...(commonConfig.testPathIgnorePatterns ?? []), '-test.browser.tsx?$'],\n};\n\nexport default config;\n"
  },
  {
    "path": "packages/test-config/package.json",
    "content": "{\n    \"name\": \"@solana/test-config\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"type\": \"module\",\n    \"files\": [\n        \"test-validator-setup.js\",\n        \"test-validator-teardown.js\"\n    ],\n    \"peerDependencies\": {\n        \"jest-dev-server\": \"^10.0.0\",\n        \"undici\": \"^8.2.0\",\n        \"whatwg-fetch\": \"^3.6.20\"\n    },\n    \"devDependencies\": {\n        \"@jest/types\": \"^29.6.3\",\n        \"undici\": \"^8.2.0\",\n        \"whatwg-fetch\": \"^3.6.20\"\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/test-config/setup-define-version-constant.ts",
    "content": "beforeEach(() => {\n    globalThis.__VERSION__ = '0.0.0-test';\n});\n"
  },
  {
    "path": "packages/test-config/setup-dev-mode.ts",
    "content": "globalThis.__DEV__ = false;\nbeforeEach(() => {\n    globalThis.__DEV__ = false;\n});\n"
  },
  {
    "path": "packages/test-config/setup-secure-context.ts",
    "content": "globalThis.isSecureContext = true;\nbeforeEach(() => {\n    globalThis.isSecureContext = true;\n});\n"
  },
  {
    "path": "packages/test-config/setup-text-encoder.ts",
    "content": "import { TextDecoder, TextEncoder } from 'util';\n\nif (typeof globalThis.TextEncoder === 'undefined') {\n    globalThis.TextEncoder = TextEncoder;\n}\n\nif (typeof globalThis.TextDecoder === 'undefined') {\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    globalThis.TextDecoder = TextDecoder;\n}\n"
  },
  {
    "path": "packages/test-config/setup-undici-fetch.ts",
    "content": "import { fetch as undiciFetch } from 'undici';\n\nglobalThis.fetch = undiciFetch as unknown as typeof globalThis.fetch;\n"
  },
  {
    "path": "packages/test-config/setup-web-buffer-global.ts",
    "content": "/**\n * Browsers don't have a `Buffer` global, so delete it now.\n */\nbeforeEach(() => {\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    delete globalThis.Buffer;\n});\n"
  },
  {
    "path": "packages/test-config/setup-webcrypto.ts",
    "content": "import crypto from 'node:crypto';\n\nif (typeof globalThis.crypto === 'undefined') {\n    Object.defineProperty(globalThis, 'crypto', {\n        value: crypto.webcrypto,\n        writable: true, // Allow tests to delete it.\n    });\n}\nif (typeof globalThis.crypto.subtle === 'undefined') {\n    Object.defineProperty(globalThis.crypto, 'subtle', {\n        value: crypto.webcrypto.subtle,\n    });\n}\n"
  },
  {
    "path": "packages/test-config/setup-whatwg-fetch.ts",
    "content": "import 'whatwg-fetch';\n"
  },
  {
    "path": "packages/test-config/test-validator-setup.js",
    "content": "/* eslint-disable */\nconst { setup } = require('jest-dev-server');\n\nmodule.exports = async function globalSetup() {\n    globalThis.servers = await setup([\n        // Unconditionally obtain a lease on the test validator.\n        { command: '../../scripts/start-shared-test-validator.sh' },\n        // This 'server' is a noop; we only use it to run the 'wait for server' logic.\n        {\n            command: 'while true; do sleep 86400000; done',\n            host: '127.0.0.1',\n            launchTimeout: 50000,\n            path: 'health',\n            port: 8899,\n            protocol: 'http',\n            usedPortAction: 'ignore',\n        },\n    ]);\n};\n"
  },
  {
    "path": "packages/test-config/test-validator-teardown.js",
    "content": "/* eslint-disable */\nconst { teardown } = require('jest-dev-server');\n\nmodule.exports = async function globalTeardown() {\n    await teardown(globalThis.servers);\n};\n"
  },
  {
    "path": "packages/test-config/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"Test Config\",\n    \"extends\": \"../tsconfig/base.json\"\n}\n"
  },
  {
    "path": "packages/test-matchers/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/test-matchers/package.json",
    "content": "{\n    \"name\": \"@solana/test-matchers\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"files\": [\n        \"toBeFrozenObject.ts\"\n    ],\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/test-matchers/toBeFrozenObject.ts",
    "content": "expect.extend({\n    toBeFrozenObject(actual: object) {\n        return {\n            message: () => `Expected object ${this.isNot ? 'not ' : ''}to be frozen`,\n            pass: Object.isFrozen(actual),\n        };\n    },\n});\n\ndeclare global {\n    // eslint-disable-next-line @typescript-eslint/no-namespace\n    namespace jest {\n        interface AsymmetricMatchers {\n            toBeFrozenObject(): void;\n        }\n        interface Matchers<R> {\n            toBeFrozenObject(): R;\n        }\n    }\n}\n\nexport {};\n"
  },
  {
    "path": "packages/test-matchers/toEqualArrayBuffer.ts",
    "content": "expect.extend({\n    toEqualArrayBuffer(received: ArrayBuffer, expected: ArrayBuffer) {\n        if (!(received instanceof ArrayBuffer) || !(expected instanceof ArrayBuffer)) {\n            return {\n                message: () => 'Expected to compare two `ArrayBuffers`',\n                pass: false,\n            };\n        }\n        let pass = false;\n        if (received.byteLength === expected.byteLength) {\n            const receivedView = new Uint8Array(received);\n            const expectedView = new Uint8Array(expected);\n            pass = expectedView.every((b, ii) => b === receivedView[ii]);\n        }\n        return {\n            message: () =>\n                this.isNot\n                    ? 'Expected `ArrayBuffers` to differ'\n                    : `${this.utils.diff(expected, received, { expand: true })}`,\n            pass,\n        };\n    },\n});\n\ndeclare global {\n    // eslint-disable-next-line @typescript-eslint/no-namespace\n    namespace jest {\n        interface AsymmetricMatchers {\n            toEqualArrayBuffer(expected: ArrayBuffer): void;\n        }\n        interface Matchers<R> {\n            toEqualArrayBuffer(expected: ArrayBuffer): R;\n        }\n    }\n}\n\nexport {};\n"
  },
  {
    "path": "packages/test-matchers/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"Default\",\n    \"compilerOptions\": {\n        \"composite\": false,\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"esModuleInterop\": true,\n        \"forceConsistentCasingInFileNames\": true,\n        \"inlineSources\": false,\n        \"isolatedModules\": true,\n        \"moduleResolution\": \"node\",\n        \"noFallthroughCasesInSwitch\": true,\n        \"noUnusedLocals\": true,\n        \"noUnusedParameters\": true,\n        \"preserveWatchOutput\": true,\n        \"skipLibCheck\": true,\n        \"strict\": true,\n        \"target\": \"ESNext\"\n    },\n    \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "packages/text-encoding-impl/.gitignore",
    "content": "dist/\n"
  },
  {
    "path": "packages/text-encoding-impl/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/text-encoding-impl/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/text-encoding-impl/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/text-encoding-impl/package.json",
    "content": "{\n    \"name\": \"@solana/text-encoding-impl\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.browser.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.browser.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\"\n    ],\n    \"sideEffects\": false,\n    \"scripts\": {\n        \"compile:js\": \"tsup\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"devDependencies\": {\n        \"@types/fastestsmallesttextencoderdecoder\": \"^1.0.2\"\n    },\n    \"peerDependencies\": {\n        \"fastestsmallesttextencoderdecoder\": \"^1.0.22\"\n    },\n    \"peerDependenciesMeta\": {\n        \"fastestsmallesttextencoderdecoder\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/text-encoding-impl/src/index.browser.ts",
    "content": "export const TextDecoder = globalThis.TextDecoder;\nexport const TextEncoder = globalThis.TextEncoder;\n"
  },
  {
    "path": "packages/text-encoding-impl/src/index.native.ts",
    "content": "// When building the browser and node bundles, this import gets replaced by `globalThis.TextEncoder` and `globalThis.TextDecoder`.\nimport {\n    TextDecoder as TextDecoderPolyfill,\n    TextEncoder as TextEncoderPolyfill,\n} from 'fastestsmallesttextencoderdecoder';\n\nexport const TextDecoder = TextDecoderPolyfill;\nexport const TextEncoder = TextEncoderPolyfill;\n"
  },
  {
    "path": "packages/text-encoding-impl/src/index.node.ts",
    "content": "export const TextDecoder = globalThis.TextDecoder;\nexport const TextEncoder = globalThis.TextEncoder;\n"
  },
  {
    "path": "packages/text-encoding-impl/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"isolatedModules\": false,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.browser.ts\"]\n}\n"
  },
  {
    "path": "packages/text-encoding-impl/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2016\"]\n    },\n    \"display\": \"TextEncoder and TextDecoder Implementation\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/text-encoding-impl/tsup.config.ts",
    "content": "import { defineConfig } from 'tsup';\n\nexport default defineConfig(_options =>\n    (['browser', 'node', 'native'] as const).map(platform => ({\n        entry: [`./src/index.${platform}.ts`],\n        format: platform === 'native' ? ['esm'] : ['cjs', 'esm'],\n        minify: true,\n        name: platform,\n        outExtension({ format }) {\n            return { js: `.${format === 'cjs' ? 'cjs' : 'mjs'}` };\n        },\n        platform: platform === 'node' ? 'node' : 'browser',\n        sourcemap: true,\n        treeshake: true,\n    })),\n);\n"
  },
  {
    "path": "packages/transaction-confirmation/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/transaction-confirmation/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/transaction-confirmation/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/transaction-confirmation/CHANGELOG.md",
    "content": "# @solana/transaction-confirmation\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`8d73de5`](https://github.com/anza-xyz/kit/commit/8d73de5241d709946431f2fdda74f2a0df5e9529), [`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/promises@6.9.0\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/rpc-subscriptions@6.9.0\n    - @solana/rpc-types@6.9.0\n    - @solana/rpc@6.9.0\n    - @solana/transaction-messages@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/promises@6.8.0\n    - @solana/rpc@6.8.0\n    - @solana/rpc-subscriptions@6.8.0\n    - @solana/rpc-types@6.8.0\n    - @solana/transaction-messages@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/promises@6.7.0\n    - @solana/rpc@6.7.0\n    - @solana/rpc-subscriptions@6.7.0\n    - @solana/rpc-types@6.7.0\n    - @solana/transaction-messages@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/transactions@6.6.0\n    - @solana/errors@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/rpc@6.6.0\n    - @solana/rpc-subscriptions@6.6.0\n    - @solana/rpc-types@6.6.0\n    - @solana/promises@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/promises@6.5.0\n    - @solana/rpc@6.5.0\n    - @solana/rpc-subscriptions@6.5.0\n    - @solana/rpc-types@6.5.0\n    - @solana/transaction-messages@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c), [`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888)]:\n    - @solana/codecs-strings@6.4.0\n    - @solana/transaction-messages@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/rpc-subscriptions@6.4.0\n    - @solana/rpc@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/promises@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/promises@6.3.1\n    - @solana/rpc@6.3.1\n    - @solana/rpc-subscriptions@6.3.1\n    - @solana/rpc-types@6.3.1\n    - @solana/transaction-messages@6.3.1\n    - @solana/transactions@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/rpc@6.3.0\n    - @solana/rpc-subscriptions@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/transaction-messages@6.3.0\n    - @solana/transactions@6.3.0\n    - @solana/promises@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/rpc@6.2.0\n    - @solana/rpc-subscriptions@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/transaction-messages@6.2.0\n    - @solana/transactions@6.2.0\n    - @solana/promises@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75)]:\n    - @solana/errors@6.1.0\n    - @solana/transaction-messages@6.1.0\n    - @solana/transactions@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-strings@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/rpc@6.1.0\n    - @solana/rpc-subscriptions@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/promises@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies [[`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492), [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462)]:\n    - @solana/transaction-messages@6.0.1\n    - @solana/transactions@6.0.1\n    - @solana/rpc@6.0.1\n    - @solana/rpc-subscriptions@6.0.1\n    - @solana/addresses@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/promises@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926), [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a), [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db)]:\n    - @solana/transaction-messages@6.0.0\n    - @solana/transactions@6.0.0\n    - @solana/rpc@6.0.0\n    - @solana/rpc-subscriptions@6.0.0\n    - @solana/addresses@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/promises@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/rpc@5.5.1\n    - @solana/rpc-subscriptions@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/transaction-messages@5.5.1\n    - @solana/transactions@5.5.1\n    - @solana/promises@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/rpc@5.5.0\n    - @solana/rpc-subscriptions@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/transaction-messages@5.5.0\n    - @solana/transactions@5.5.0\n    - @solana/promises@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/transaction-messages@5.4.0\n    - @solana/rpc-subscriptions@5.4.0\n    - @solana/codecs-strings@5.4.0\n    - @solana/transactions@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/promises@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n    - @solana/rpc@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/promises@5.3.0\n    - @solana/rpc@5.3.0\n    - @solana/rpc-subscriptions@5.3.0\n    - @solana/rpc-types@5.3.0\n    - @solana/transaction-messages@5.3.0\n    - @solana/transactions@5.3.0\n\n## 5.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/transaction-messages@5.2.0\n    - @solana/transactions@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/rpc@5.2.0\n    - @solana/rpc-subscriptions@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/promises@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#1003](https://github.com/anza-xyz/kit/pull/1003) [`18e7e2c`](https://github.com/anza-xyz/kit/commit/18e7e2c9d9013be6223932398f40cbc276c4a0e9) Thanks [@damianac](https://github.com/damianac)! - Actually fixed a bug where transaction errors discovered during recent transaction confirmation might not be thrown. The fix in #793 was insufficient.\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951), [`eb49ed7`](https://github.com/anza-xyz/kit/commit/eb49ed7dd45f2a5a0098b3de5ef482a813f8ad47), [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/transactions@5.1.0\n    - @solana/rpc@5.1.0\n    - @solana/transaction-messages@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/rpc-subscriptions@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/promises@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/rpc@5.0.0\n    - @solana/rpc-subscriptions@5.0.0\n    - @solana/transaction-messages@5.0.0\n    - @solana/transactions@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/codecs-strings@5.0.0\n    - @solana/keys@5.0.0\n    - @solana/promises@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#793](https://github.com/anza-xyz/kit/pull/793) [`cfc1d92`](https://github.com/anza-xyz/kit/commit/cfc1d9249e55c79d27ac840806f198a5c5895e56) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug where transaction errors discovered during recent transaction confirmation might not be thrown\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df), [`9e8bfe4`](https://github.com/anza-xyz/kit/commit/9e8bfe460886124d1d12e444e7452db631c0ac6f), [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013)]:\n    - @solana/transactions@4.0.0\n    - @solana/errors@4.0.0\n    - @solana/keys@4.0.0\n    - @solana/transaction-messages@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/rpc-subscriptions@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/codecs-strings@4.0.0\n    - @solana/rpc@4.0.0\n    - @solana/promises@4.0.0\n\n## 3.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6), [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845), [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf)]:\n    - @solana/transaction-messages@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/transactions@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/codecs-strings@3.0.0\n    - @solana/keys@3.0.0\n    - @solana/rpc@3.0.0\n    - @solana/rpc-subscriptions@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/promises@3.0.0\n\n## 2.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a), [`53e1336`](https://github.com/anza-xyz/kit/commit/53e1336149878c84048e0fde5c7e7ace6cc1e97f), [`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eb61d94`](https://github.com/anza-xyz/kit/commit/eb61d94786e212fc23778d445a94b86d2b1b024f), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`bbcb913`](https://github.com/anza-xyz/kit/commit/bbcb913839d33abc746f38d6e65e7bfd30cd2ac6), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`e6c0568`](https://github.com/anza-xyz/kit/commit/e6c0568ef34fdc04075af27eb102851123a02be0), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/transaction-messages@2.3.0\n    - @solana/transactions@2.3.0\n    - @solana/errors@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/codecs-strings@2.3.0\n    - @solana/keys@2.3.0\n    - @solana/rpc@2.3.0\n    - @solana/rpc-subscriptions@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/promises@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/rpc-subscriptions@2.2.1\n    - @solana/addresses@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/keys@2.2.1\n    - @solana/promises@2.2.1\n    - @solana/rpc@2.2.1\n    - @solana/rpc-types@2.2.1\n    - @solana/transaction-messages@2.2.1\n    - @solana/transactions@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/addresses@2.2.0\n    - @solana/keys@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/transaction-messages@2.2.0\n    - @solana/transactions@2.2.0\n    - @solana/rpc-subscriptions@2.2.0\n    - @solana/rpc@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/promises@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#409](https://github.com/anza-xyz/kit/pull/409) [`24a329d`](https://github.com/anza-xyz/kit/commit/24a329dda1434aaf450d1d35b022ee77556ac415) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Loosen lifetime constraint on sendAndConfirmTransaction to only require lastValidBlockHeight\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`776e18d`](https://github.com/anza-xyz/kit/commit/776e18d75c759a839608069c61da3f70b775540b), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/transaction-messages@2.1.1\n    - @solana/rpc-subscriptions@2.1.1\n    - @solana/codecs-strings@2.1.1\n    - @solana/transactions@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/promises@2.1.1\n    - @solana/errors@2.1.1\n    - @solana/keys@2.1.1\n    - @solana/rpc@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065) Thanks [@steveluscher](https://github.com/steveluscher)! - Disabled the `MaxListenersExceededWarning` in Node when creating event targets for internal use\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`29d1e28`](https://github.com/anza-xyz/kit/commit/29d1e282f7ae53db008515980f13d54c40760065), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`70eb596`](https://github.com/anza-xyz/kit/commit/70eb596bdff9d95d607a937615190a0d8111ad3c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/keys@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/rpc-subscriptions@2.1.0\n    - @solana/rpc@2.1.0\n    - @solana/transaction-messages@2.1.0\n    - @solana/transactions@2.1.0\n    - @solana/promises@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3353](https://github.com/solana-labs/solana-web3.js/pull/3353) [`696c72c`](https://github.com/solana-labs/solana-web3.js/commit/696c72ce25c96f06442785bddffbc890ceb802f3) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug that could result in the transaction confirmer claiming that the blockheight had been exceeded, when the fact of the matter was that the confirmation was aborted by an `AbortSignal`\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2553](https://github.com/solana-labs/solana-web3.js/pull/2553) [`af9fa3b`](https://github.com/solana-labs/solana-web3.js/commit/af9fa3b7e83220d69eab67b37d3a36beac0e848c) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Changes `createRecentSignatureConfirmationPromiseFactory` to enforce `rpc` and `rpcSubscriptions` to have matching clusters, changing the function signature to accept an object rather than two parameters.\n\n- [#3072](https://github.com/solana-labs/solana-web3.js/pull/3072) [`c122c75`](https://github.com/solana-labs/solana-web3.js/commit/c122c75936e8fa5364edf114a5182cf119b26922) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a memory leak with transaction confirmation and subscriptions\n\n- [#2554](https://github.com/solana-labs/solana-web3.js/pull/2554) [`0b02de1`](https://github.com/solana-labs/solana-web3.js/commit/0b02de140887654f19f8eda374f40c6f5a8f5e92) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Changes `createNonceInvalidationPromiseFactory` to enforce `rpc` and `rpcSubscriptions` to have matching clusters, changing the function signature to accept an object rather than two parameters.\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`42a70f4`](https://github.com/solana-labs/solana-web3.js/commit/42a70f4c3004e55fe6ce5a8e500f5610765ec66f), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`7ee47ae`](https://github.com/solana-labs/solana-web3.js/commit/7ee47ae24ad73b429ee863342f300a6f6c49e3d2), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`500a991`](https://github.com/solana-labs/solana-web3.js/commit/500a991d292638eaee1fa48a7b94acfe2ff83cb7), [`c122c75`](https://github.com/solana-labs/solana-web3.js/commit/c122c75936e8fa5364edf114a5182cf119b26922), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`8f94a9e`](https://github.com/solana-labs/solana-web3.js/commit/8f94a9ede71b32662bff991e6def68bc9e8bc921), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`44c8772`](https://github.com/solana-labs/solana-web3.js/commit/44c8772c8711b99e68dce3348e17bfc5b1d2a833), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/transactions@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/rpc@2.0.0\n    - @solana/rpc-subscriptions@2.0.0\n    - @solana/keys@2.0.0\n    - @solana/transaction-messages@2.0.0\n    - @solana/promises@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n    - @solana/keys@2.0.0-rc.4\n    - @solana/rpc@2.0.0-rc.4\n    - @solana/rpc-subscriptions@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/transaction-messages@2.0.0-rc.4\n    - @solana/transactions@2.0.0-rc.4\n    - @solana/promises@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies [[`45df702`](https://github.com/solana-labs/solana-web3.js/commit/45df7028d872e65759dad86b97cd9d4a9a3a545e)]:\n    - @solana/rpc-subscriptions@2.0.0-rc.3\n    - @solana/rpc@2.0.0-rc.3\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/keys@2.0.0-rc.3\n    - @solana/promises@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n    - @solana/transaction-messages@2.0.0-rc.3\n    - @solana/transactions@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3353](https://github.com/solana-labs/solana-web3.js/pull/3353) [`696c72c`](https://github.com/solana-labs/solana-web3.js/commit/696c72ce25c96f06442785bddffbc890ceb802f3) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug that could result in the transaction confirmer claiming that the blockheight had been exceeded, when the fact of the matter was that the confirmation was aborted by an `AbortSignal`\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`10b08ac`](https://github.com/solana-labs/solana-web3.js/commit/10b08ac8cdb61aa1412475426cfcaf0eefe32722), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`9dfca45`](https://github.com/solana-labs/solana-web3.js/commit/9dfca454355819444bad29e48602886428ba4cac), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`500a991`](https://github.com/solana-labs/solana-web3.js/commit/500a991d292638eaee1fa48a7b94acfe2ff83cb7), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`8f94a9e`](https://github.com/solana-labs/solana-web3.js/commit/8f94a9ede71b32662bff991e6def68bc9e8bc921), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`4c7224d`](https://github.com/solana-labs/solana-web3.js/commit/4c7224d0a884b0dc91ea536ce5fbdcd0a0d7e011), [`44c8772`](https://github.com/solana-labs/solana-web3.js/commit/44c8772c8711b99e68dce3348e17bfc5b1d2a833), [`e1cb697`](https://github.com/solana-labs/solana-web3.js/commit/e1cb697d66dc906aa2433965452417e03cf86e13), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`c8e6e71`](https://github.com/solana-labs/solana-web3.js/commit/c8e6e71529f219caf83ed444e53f5a1e757129dc)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/rpc-subscriptions@2.0.0-rc.2\n    - @solana/rpc@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/transaction-messages@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/transactions@2.0.0-rc.2\n    - @solana/promises@2.0.0-rc.2\n    - @solana/keys@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- [#3072](https://github.com/solana-labs/solana-web3.js/pull/3072) [`c122c75`](https://github.com/solana-labs/solana-web3.js/commit/c122c75936e8fa5364edf114a5182cf119b26922) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a memory leak with transaction confirmation and subscriptions\n\n- Updated dependencies [[`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`c122c75`](https://github.com/solana-labs/solana-web3.js/commit/c122c75936e8fa5364edf114a5182cf119b26922), [`b4bf318`](https://github.com/solana-labs/solana-web3.js/commit/b4bf318d7d4bdd639e4c126c70350993a8540fe8), [`f2bb4e8`](https://github.com/solana-labs/solana-web3.js/commit/f2bb4e8c7f7efd049cb1c3810291c99e9293c25d), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302)]:\n    - @solana/keys@2.0.0-rc.1\n    - @solana/rpc-subscriptions@2.0.0-rc.1\n    - @solana/promises@2.0.0-rc.1\n    - @solana/transactions@2.0.0-rc.1\n    - @solana/rpc@2.0.0-rc.1\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n    - @solana/transaction-messages@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`42a70f4`](https://github.com/solana-labs/solana-web3.js/commit/42a70f4c3004e55fe6ce5a8e500f5610765ec66f), [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/rpc@2.0.0-rc.0\n    - @solana/transaction-messages@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/rpc-subscriptions@2.0.0-rc.0\n    - @solana/transactions@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n    - @solana/keys@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`7ee47ae`](https://github.com/solana-labs/solana-web3.js/commit/7ee47ae24ad73b429ee863342f300a6f6c49e3d2), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/rpc@2.0.0-preview.4\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/keys@2.0.0-preview.4\n    - @solana/transaction-messages@2.0.0-preview.4\n    - @solana/rpc-subscriptions@2.0.0-preview.4\n    - @solana/transactions@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2553](https://github.com/solana-labs/solana-web3.js/pull/2553) [`af9fa3b`](https://github.com/solana-labs/solana-web3.js/commit/af9fa3b7e83220d69eab67b37d3a36beac0e848c) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Changes `createRecentSignatureConfirmationPromiseFactory` to enforce `rpc` and `rpcSubscriptions` to have matching clusters, changing the function signature to accept an object rather than two parameters.\n\n- [#2554](https://github.com/solana-labs/solana-web3.js/pull/2554) [`0b02de1`](https://github.com/solana-labs/solana-web3.js/commit/0b02de140887654f19f8eda374f40c6f5a8f5e92) Thanks [@buffalojoec](https://github.com/buffalojoec)! - Changes `createNonceInvalidationPromiseFactory` to enforce `rpc` and `rpcSubscriptions` to have matching clusters, changing the function signature to accept an object rather than two parameters.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`18d6b56`](https://github.com/solana-labs/solana-web3.js/commit/18d6b56a69509e4c98de8f3de51abe2623b46763), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/transactions@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/transaction-messages@2.0.0-preview.3\n    - @solana/rpc-subscriptions@2.0.0-preview.3\n    - @solana/rpc@2.0.0-preview.3\n    - @solana/keys@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/addresses@2.0.0-preview.2\n    - @solana/codecs-strings@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n    - @solana/keys@2.0.0-preview.2\n    - @solana/rpc@2.0.0-preview.2\n    - @solana/rpc-subscriptions@2.0.0-preview.2\n    - @solana/rpc-types@2.0.0-preview.2\n    - @solana/transactions@2.0.0-preview.2\n"
  },
  {
    "path": "packages/transaction-confirmation/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/transaction-confirmation/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/transaction-confirmation?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/transaction-confirmation?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/transaction-confirmation\n\n# @solana/transaction-confirmation\n\nThis package contains utilities for confirming transactions and for building your own transaction confirmation strategies.\n\n## Functions\n\n### `createBlockHeightExceedencePromiseFactory()`\n\nWhen a transaction's lifetime is tied to a blockhash, that transaction can be landed on the network until that blockhash expires. All blockhashes have a block height after which they are considered to have expired. A block height exceedence promise throws when the network progresses past that block height.\n\n```ts\nimport { isSolanaError, SolanaError } from '@solana/errors';\nimport { createBlockHeightExceedencePromiseFactory } from '@solana/transaction-confirmation';\n\nconst getBlockHeightExceedencePromise = createBlockHeightExceedencePromiseFactory({\n    rpc,\n    rpcSubscriptions,\n});\ntry {\n    await getBlockHeightExceedencePromise({ lastValidBlockHeight });\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {\n        console.error(\n            `The block height of the network has exceeded ${e.context.lastValidBlockHeight}. ` +\n                `It is now ${e.context.currentBlockHeight}`,\n        );\n        // Re-sign and retry the transaction.\n        return;\n    }\n    throw e;\n}\n```\n\n### `createNonceInvalidationPromiseFactory()`\n\nWhen a transaction's lifetime is tied to the value stored in a nonce account, that transaction can be landed on the network until the nonce is advanced to a new value. A nonce invalidation promise throws when the value stored in a nonce account is not the expected one.\n\n```ts\nimport { isSolanaError, SolanaError } from '@solana/errors';\nimport { createNonceInvalidationPromiseFactory } from '@solana/transaction-confirmation';\n\nconst getNonceInvalidationPromise = createNonceInvalidationPromiseFactory({\n    rpc,\n    rpcSubscriptions,\n});\ntry {\n    await getNonceInvalidationPromise({\n        currentNonceValue,\n        nonceAccountAddress,\n    });\n} catch (e) {\n    if (isSolanaError(e, SOLANA_ERROR__NONCE_INVALID)) {\n        console.error(`The nonce has advanced to ${e.context.actualNonceValue}`);\n        // Re-sign and retry the transaction.\n        return;\n    } else if (isSolanaError(e, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND)) {\n        console.error(`No nonce account was found at ${nonceAccountAddress}`);\n    }\n    throw e;\n}\n```\n\n### `createRecentSignatureConfirmationPromiseFactory()`\n\nThe status of recently-landed transactions is available in the network's status cache. A recent signature confirmation promise resolves when a transaction achieves the target confirmation commitment, and throws when the transaction fails with an error.\n\n```ts\nimport { createRecentSignatureConfirmationPromiseFactory } from '@solana/transaction-confirmation';\n\nconst getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({\n    rpc,\n    rpcSubscriptions,\n});\ntry {\n    await getRecentSignatureConfirmationPromise({\n        commitment,\n        signature,\n    });\n    console.log(`The transaction with signature \\`${signature}\\` has achieved a commitment level of \\`${commitment}\\``);\n} catch (e) {\n    console.error(`The transaction with signature \\`${signature}\\` failed`, e.cause);\n    throw e;\n}\n```\n\n### `getTimeoutPromise()`\n\nWhen no other heuristic exists to infer that a transaction has expired, you can use this promise factory with a commitment level. It throws after 30 seconds when the commitment is `processed`, and 60 seconds otherwise. You would typically race this with another confirmation strategy.\n\n```ts\nimport { safeRace } from '@solana/promises';\nimport { getTimeoutPromise } from '@solana/transaction-confirmation';\n\ntry {\n    await safeRace([getCustomTransactionConfirmationPromise(/* ... */), getTimeoutPromise({ commitment })]);\n} catch (e) {\n    if (e instanceof DOMException && e.name === 'TimeoutError') {\n        console.log('Could not confirm transaction after a timeout');\n    }\n    throw e;\n}\n```\n\n### `waitForDurableNonceTransactionConfirmation()`\n\nSupply your own confirmation implementations to this function to create a custom nonce transaction confirmation strategy.\n\n```ts\nimport { waitForDurableNonceTransactionConfirmation } from '@solana/transaction-confirmation';\n\ntry {\n    await waitForDurableNonceTransactionConfirmation({\n        getNonceInvalidationPromise({ abortSignal, commitment, currentNonceValue, nonceAccountAddress }) {\n            // Return a promise that rejects when a nonce becomes invalid.\n        },\n        getRecentSignatureConfirmationPromise({ abortSignal, commitment, signature }) {\n            // Return a promise that resolves when a transaction achieves confirmation\n        },\n    });\n} catch (e) {\n    // Handle errors.\n}\n```\n\n### `waitForRecentTransactionConfirmation()`\n\nSupply your own confirmation implementations to this function to create a custom confirmation strategy for recently-landed transactions.\n\n```ts\nimport { waitForRecentTransactionConfirmation } from '@solana/transaction-confirmation';\n\ntry {\n    await waitForRecentTransactionConfirmation({\n        getBlockHeightExceedencePromise({ abortSignal, commitment, lastValidBlockHeight }) {\n            // Return a promise that rejects when the blockhash's block height has been exceeded\n        },\n        getRecentSignatureConfirmationPromise({ abortSignal, commitment, signature }) {\n            // Return a promise that resolves when a transaction achieves confirmation\n        },\n    });\n} catch (e) {\n    // Handle errors.\n}\n```\n\n### `waitForRecentTransactionConfirmationUntilTimeout()`\n\nSupply your own confirmation implementations to this function to create a custom nonce transaction confirmation strategy.\n\n```ts\nimport { waitForRecentTransactionConfirmationUntilTimeout } from '@solana/transaction-confirmation';\n\ntry {\n    await waitForRecentTransactionConfirmationUntilTimeout({\n        getTimeoutPromise({ abortSignal, commitment }) {\n            // Return a promise that rejects after your chosen timeout\n        },\n        getRecentSignatureConfirmationPromise({ abortSignal, commitment, signature }) {\n            // Return a promise that resolves when a transaction achieves confirmation\n        },\n    });\n} catch (e) {\n    // Handle errors.\n}\n```\n"
  },
  {
    "path": "packages/transaction-confirmation/package.json",
    "content": "{\n    \"name\": \"@solana/transaction-confirmation\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for confirming Solana transactions\",\n    \"homepage\": \"https://www.solanakit.com/api#solanatransaction-confirmation\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-packages\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && pnpm dist-tag add $npm_package_name@$npm_package_version latest) || true))\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/promises\": \"workspace:*\",\n        \"@solana/rpc\": \"workspace:*\",\n        \"@solana/rpc-subscriptions\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/event-target-impl\": \"workspace:*\",\n        \"@solana/instructions\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__tests__/confirmation-strategy-blockheight-test.ts",
    "content": "import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport { Commitment } from '@solana/rpc-types';\n\nimport { createBlockHeightExceedencePromiseFactory } from '../confirmation-strategy-blockheight';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('createBlockHeightExceedencePromiseFactory', () => {\n    let createSubscriptionIterable: jest.Mock;\n    let getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n    let getEpochInfoMock: jest.Mock;\n    let getEpochInfoRequestSender: jest.Mock;\n    let slotNotificationsGenerator: jest.Mock;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        getEpochInfoRequestSender = jest.fn();\n        getEpochInfoMock = jest.fn().mockReturnValue({\n            send: getEpochInfoRequestSender,\n        });\n        slotNotificationsGenerator = jest.fn().mockImplementation(async function* () {\n            yield await FOREVER_PROMISE;\n        });\n        createSubscriptionIterable = jest.fn().mockResolvedValue({\n            [Symbol.asyncIterator]: slotNotificationsGenerator,\n        });\n        const rpcSubscriptions = {\n            slotNotifications: () => ({\n                reactive: jest.fn().mockRejectedValue(new Error('not implemented')),\n                reactiveStore: jest.fn().mockImplementation(() => {\n                    throw new Error('not implemented');\n                }),\n                subscribe: createSubscriptionIterable,\n            }),\n        };\n        const rpc = {\n            getEpochInfo: getEpochInfoMock,\n        };\n        getBlockHeightExceedencePromise = createBlockHeightExceedencePromiseFactory({\n            rpc,\n            rpcSubscriptions,\n        });\n    });\n    it('throws when the block height has already been exceeded when called', async () => {\n        expect.assertions(1);\n        getEpochInfoRequestSender.mockResolvedValue({ absoluteSlot: 101n, blockHeight: 101n });\n        const exceedencePromise = getBlockHeightExceedencePromise({\n            abortSignal: new AbortController().signal,\n            lastValidBlockHeight: 100n,\n        });\n        await expect(exceedencePromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n                currentBlockHeight: 101n,\n                lastValidBlockHeight: 100n,\n            }),\n        );\n    });\n    it('continues to pend when the block height in the initial fetch is lower than the last valid block height', async () => {\n        expect.assertions(1);\n        getEpochInfoRequestSender.mockResolvedValue({ absoluteSlot: 100n, blockHeight: 100n });\n        const exceedencePromise = getBlockHeightExceedencePromise({\n            abortSignal: new AbortController().signal,\n            lastValidBlockHeight: 100n,\n        });\n        await jest.runAllTimersAsync();\n        await expect(Promise.race([exceedencePromise, Promise.resolve('pending')])).resolves.toBe('pending');\n    });\n    it('throws when the slot at which the block height is expected to be exceeded is reached', async () => {\n        expect.assertions(1);\n        // Mock a delta between the slot height and the block height of 100 slots.\n        getEpochInfoRequestSender.mockResolvedValueOnce({ absoluteSlot: 198n, blockHeight: 98n });\n        slotNotificationsGenerator.mockImplementation(async function* () {\n            yield { slot: 199n };\n            yield { slot: 200n };\n            yield { slot: 201n }; // Expected to be exceeded here.\n            yield await FOREVER_PROMISE;\n        });\n        // Mock the block height recheck at the end\n        getEpochInfoRequestSender.mockResolvedValueOnce({ absoluteSlot: 201n, blockHeight: 101n });\n        const exceedencePromise = getBlockHeightExceedencePromise({\n            abortSignal: new AbortController().signal,\n            lastValidBlockHeight: 100n,\n        });\n        await expect(exceedencePromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n                currentBlockHeight: 101n,\n                lastValidBlockHeight: 100n,\n            }),\n        );\n    });\n    it('continues to pend when slot at which the block height is expected to be exceeded has not been reached', async () => {\n        expect.assertions(1);\n        // Mock a delta between the slot height and the block height of 100 slots.\n        getEpochInfoRequestSender.mockResolvedValue({ absoluteSlot: 198n, blockHeight: 98n });\n        slotNotificationsGenerator.mockImplementation(async function* () {\n            yield { slot: 199n };\n            yield { slot: 200n };\n            yield await FOREVER_PROMISE;\n        });\n        // Mock the block height recheck at the end\n        getEpochInfoRequestSender.mockResolvedValueOnce({ absoluteSlot: 200n, blockHeight: 100n });\n        const exceedencePromise = getBlockHeightExceedencePromise({\n            abortSignal: new AbortController().signal,\n            lastValidBlockHeight: 100n,\n        });\n        await jest.runOnlyPendingTimersAsync();\n        await expect(Promise.race([exceedencePromise, Promise.resolve('pending')])).resolves.toBe('pending');\n    });\n    it('throws when the slot height / block height delta eventually satisfies the slot at which the block height is expected to be exceeded being reached', async () => {\n        expect.assertions(1);\n        // Mock a delta between the slot height and the block height of 100 slots.\n        getEpochInfoRequestSender.mockResolvedValueOnce({ absoluteSlot: 198n, blockHeight: 98n });\n        slotNotificationsGenerator.mockImplementation(async function* () {\n            yield { slot: 199n };\n            yield { slot: 200n };\n            yield { slot: 201n }; // Expected to be exceeded here.\n            yield { slot: 202n }; // Actually exceeded here.\n            yield await FOREVER_PROMISE;\n        });\n        // Mock the slot height / block height delta having grown by one.\n        getEpochInfoRequestSender.mockResolvedValueOnce({ absoluteSlot: 201n, blockHeight: 100n });\n        // Mock the final recheck where the block height catches up.\n        getEpochInfoRequestSender.mockResolvedValueOnce({ absoluteSlot: 202n, blockHeight: 101n });\n        const exceedencePromise = getBlockHeightExceedencePromise({\n            abortSignal: new AbortController().signal,\n            lastValidBlockHeight: 100n,\n        });\n        await expect(exceedencePromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n                currentBlockHeight: 101n,\n                lastValidBlockHeight: 100n,\n            }),\n        );\n    });\n    it('continues to pend when the slot height / block height delta grows by the time the slot at which the block height is expected to be exceeded is reached', async () => {\n        expect.assertions(1);\n        // Mock a delta between the slot height and the block height of 100 slots.\n        getEpochInfoRequestSender.mockResolvedValueOnce({ absoluteSlot: 198n, blockHeight: 98n });\n        slotNotificationsGenerator.mockImplementation(async function* () {\n            yield { slot: 199n };\n            yield { slot: 200n };\n            yield { slot: 201n }; // Expected to be exceeded here.\n            yield await FOREVER_PROMISE;\n        });\n        // Mock the slot height / block height delta having grown by one by the end\n        getEpochInfoRequestSender.mockResolvedValueOnce({ absoluteSlot: 201n, blockHeight: 100n });\n        const exceedencePromise = getBlockHeightExceedencePromise({\n            abortSignal: new AbortController().signal,\n            lastValidBlockHeight: 100n,\n        });\n        await jest.runOnlyPendingTimersAsync();\n        await expect(Promise.race([exceedencePromise, Promise.resolve('pending')])).resolves.toBe('pending');\n    });\n    it.each(['processed', 'confirmed', 'finalized'] as Commitment[])(\n        'calls the epoch info getter with the configured commitment when configured with `%s` commitment',\n        commitment => {\n            getEpochInfoRequestSender.mockResolvedValue({ absoluteSlot: 100n, blockHeight: 100n });\n            getBlockHeightExceedencePromise({\n                abortSignal: new AbortController().signal,\n                commitment,\n                lastValidBlockHeight: 100n,\n            }).catch(() => {});\n            expect(getEpochInfoMock).toHaveBeenCalledWith({ commitment });\n        },\n    );\n    it('calls the abort signal passed to the epoch info fetcher when aborted', () => {\n        const abortController = new AbortController();\n        getBlockHeightExceedencePromise({\n            abortSignal: abortController.signal,\n            lastValidBlockHeight: 100n,\n        }).catch(() => {});\n        expect(getEpochInfoRequestSender).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: false }),\n        });\n        abortController.abort();\n        expect(getEpochInfoRequestSender).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: true }),\n        });\n    });\n    it('calls the abort signal passed to the slot subscription when aborted', () => {\n        const abortController = new AbortController();\n        getBlockHeightExceedencePromise({\n            abortSignal: abortController.signal,\n            lastValidBlockHeight: 100n,\n        }).catch(() => {});\n        expect(createSubscriptionIterable).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: false }),\n        });\n        abortController.abort();\n        expect(createSubscriptionIterable).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: true }),\n        });\n    });\n    it('throws errors thrown from the epoch info fetcher', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        getEpochInfoRequestSender.mockRejectedValue(new Error('o no'));\n        await expect(\n            getBlockHeightExceedencePromise({\n                abortSignal: abortController.signal,\n                lastValidBlockHeight: 100n,\n            }),\n        ).rejects.toThrow('o no');\n    });\n    it('throws errors thrown from the slot subscription', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        createSubscriptionIterable.mockRejectedValue(new Error('o no'));\n        await expect(\n            getBlockHeightExceedencePromise({\n                abortSignal: abortController.signal,\n                lastValidBlockHeight: 100n,\n            }),\n        ).rejects.toThrow('o no');\n    });\n    it('throws if started aborted', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        abortController.abort();\n        await expect(\n            getBlockHeightExceedencePromise({\n                abortSignal: abortController.signal,\n                lastValidBlockHeight: 100n,\n            }),\n        ).rejects.toThrow(/operation was aborted/);\n    });\n    it('throws if aborted while waiting for the epoch info', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        let resolveEpochInfo!: (value: { absoluteSlot: bigint; blockHeight: bigint }) => void;\n        const epochInfoPromise = new Promise(r => {\n            resolveEpochInfo = r;\n        });\n        getEpochInfoRequestSender.mockReturnValue(epochInfoPromise);\n        const blockHeightExceedencePromise = getBlockHeightExceedencePromise({\n            abortSignal: abortController.signal,\n            lastValidBlockHeight: 100n,\n        });\n        await jest.runAllTimersAsync();\n        abortController.abort();\n        resolveEpochInfo({ absoluteSlot: 101n, blockHeight: 101n });\n        await expect(blockHeightExceedencePromise).rejects.toThrow(/operation was aborted/);\n    });\n    it('throws if aborted while the slot subscription is working', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        let resolveSlotSubscription!: (value: { slot: bigint }) => void;\n        const slotSubscriptionReturnPromise = new Promise(r => {\n            resolveSlotSubscription = r;\n        });\n        getEpochInfoRequestSender.mockResolvedValue({ absoluteSlot: 100n, blockHeight: 100n });\n        slotNotificationsGenerator.mockImplementation(\n            // eslint-disable-next-line require-yield\n            async function* () {\n                await slotSubscriptionReturnPromise;\n            },\n        );\n        const blockHeightExceedencePromise = getBlockHeightExceedencePromise({\n            abortSignal: abortController.signal,\n            lastValidBlockHeight: 100n,\n        });\n        await jest.runAllTimersAsync();\n        abortController.abort();\n        resolveSlotSubscription({ slot: 101n });\n        await expect(blockHeightExceedencePromise).rejects.toThrow(/operation was aborted/);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__tests__/confirmation-strategy-nonce-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { getBase58Encoder, getBase64Decoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { Nonce } from '@solana/transaction-messages';\n\nimport { createNonceInvalidationPromiseFactory } from '../confirmation-strategy-nonce';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('createNonceInvalidationPromiseFactory', () => {\n    function getBase64EncodedNonceAccountData(nonceValue: Nonce) {\n        // This is mostly fake; we just put the nonce value in the correct spot in the byte buffer\n        // without actually implementing the rest.\n        const NONCE_VALUE_OFFSET =\n            4 + // version(u32)\n            4 + // state(u32)\n            32; // nonce authority(pubkey)\n        const bytes = new Uint8Array(\n            NONCE_VALUE_OFFSET + // zeros up to the offset\n                32, // nonce value(pubkey)\n            // don't care about anything after this\n        );\n        bytes.set(getBase58Encoder().encode(nonceValue), NONCE_VALUE_OFFSET);\n        return [getBase64Decoder().decode(bytes), 'base64'];\n    }\n    let accountNotificationGenerator: jest.Mock;\n    let createPendingSubscription: jest.Mock;\n    let createSubscriptionIterable: jest.Mock;\n    let getAccountInfoMock: jest.Mock;\n    let getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        accountNotificationGenerator = jest.fn().mockImplementation(async function* () {\n            yield await FOREVER_PROMISE;\n        });\n        getAccountInfoMock = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        const rpc = {\n            getAccountInfo: () => ({\n                reactiveStore: jest.fn().mockImplementation(() => {\n                    throw new Error('not implemented');\n                }),\n                send: getAccountInfoMock,\n            }),\n        };\n        createSubscriptionIterable = jest.fn().mockResolvedValue({\n            [Symbol.asyncIterator]: accountNotificationGenerator,\n        });\n        createPendingSubscription = jest.fn().mockReturnValue({\n            reactive: jest.fn().mockRejectedValue(new Error('not implemented')),\n            reactiveStore: jest.fn().mockImplementation(() => {\n                throw new Error('not implemented');\n            }),\n            subscribe: createSubscriptionIterable,\n        });\n        const rpcSubscriptions = {\n            accountNotifications: createPendingSubscription,\n        };\n        getNonceInvalidationPromise = createNonceInvalidationPromiseFactory({ rpc, rpcSubscriptions });\n    });\n    it('calls the abort signal passed to the account info query when aborted', async () => {\n        expect.assertions(2);\n        const abortController = new AbortController();\n        getNonceInvalidationPromise({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(getAccountInfoMock).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: false }),\n        });\n        abortController.abort();\n        expect(getAccountInfoMock).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: true }),\n        });\n    });\n    it('calls the abort signal passed to the account subscription when aborted', () => {\n        const abortController = new AbortController();\n        getNonceInvalidationPromise({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        }).catch(() => {});\n        expect(createSubscriptionIterable).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: false }),\n        });\n        abortController.abort();\n        expect(createSubscriptionIterable).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: true }),\n        });\n    });\n    it('sets up a subscription for notifications about nonce account changes', async () => {\n        expect.assertions(2);\n        getNonceInvalidationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(createPendingSubscription).toHaveBeenCalledWith('9'.repeat(44), {\n            commitment: 'finalized',\n            encoding: 'base64',\n        });\n        expect(createSubscriptionIterable).toHaveBeenCalled();\n    });\n    it('does not fire off the one shot query for the nonce value until the subscription is set up', async () => {\n        expect.assertions(2);\n        let setupSubscription;\n        createSubscriptionIterable.mockReturnValue(\n            new Promise(resolve => {\n                setupSubscription = resolve;\n            }),\n        );\n        getNonceInvalidationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(getAccountInfoMock).not.toHaveBeenCalled();\n        // FIXME: https://github.com/microsoft/TypeScript/issues/11498\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-ignore\n        setupSubscription({\n            [Symbol.asyncIterator]: accountNotificationGenerator,\n        });\n        await jest.runAllTimersAsync();\n        expect(getAccountInfoMock).toHaveBeenCalled();\n    });\n    it('continues to pend when the nonce value returned by the one-shot query is the same as the expected one', async () => {\n        expect.assertions(1);\n        getAccountInfoMock.mockResolvedValue({\n            value: {\n                data: ['4'.repeat(44), 'base58'],\n            },\n        });\n        const invalidationPromise = getNonceInvalidationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        });\n        await jest.runAllTimersAsync();\n        await expect(Promise.race([invalidationPromise, Promise.resolve('pending')])).resolves.toBe('pending');\n    });\n    it('fatals when the nonce account can not be found', async () => {\n        expect.assertions(1);\n        getAccountInfoMock.mockResolvedValue({ value: null });\n        const invalidationPromise = getNonceInvalidationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        });\n        await expect(invalidationPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n                nonceAccountAddress: '9'.repeat(44),\n            }),\n        );\n    });\n    it('fatals when the nonce value returned by the one-shot query is different than the expected one', async () => {\n        expect.assertions(1);\n        getAccountInfoMock.mockResolvedValue({\n            value: {\n                data: ['5'.repeat(44), 'base58'],\n            },\n        });\n        const invalidationPromise = getNonceInvalidationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        });\n        await expect(invalidationPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                actualNonceValue: '55555555555555555555555555555555555555555555',\n                expectedNonceValue: '44444444444444444444444444444444444444444444',\n            }),\n        );\n    });\n    it('continues to pend when the nonce value returned by the account subscription is the same as the expected one', async () => {\n        expect.assertions(1);\n        accountNotificationGenerator.mockImplementation(async function* () {\n            yield {\n                value: {\n                    data: getBase64EncodedNonceAccountData('4'.repeat(44) as Nonce),\n                },\n            };\n            yield FOREVER_PROMISE;\n        });\n        const invalidationPromise = getNonceInvalidationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        });\n        await jest.runAllTimersAsync();\n        await expect(Promise.race([invalidationPromise, Promise.resolve('pending')])).resolves.toBe('pending');\n    });\n    it('fatals when the nonce value returned by the account subscription is different than the expected one', async () => {\n        expect.assertions(1);\n        accountNotificationGenerator.mockImplementation(async function* () {\n            yield { value: { data: getBase64EncodedNonceAccountData('5'.repeat(44) as Nonce) } };\n            yield FOREVER_PROMISE;\n        });\n        const invalidationPromise = getNonceInvalidationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            currentNonceValue: '4'.repeat(44) as Nonce,\n            nonceAccountAddress: '9'.repeat(44) as Address,\n        });\n        await expect(invalidationPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                actualNonceValue: '55555555555555555555555555555555555555555555',\n                expectedNonceValue: '44444444444444444444444444444444444444444444',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__tests__/confirmation-strategy-racer-test.ts",
    "content": "import { Signature } from '@solana/keys';\n\nimport { raceStrategies } from '../confirmation-strategy-racer';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('raceStrategies', () => {\n    beforeEach(() => {\n        jest.useFakeTimers();\n    });\n    it('aborts the `AbortController` passed to `getRecentSignatureConfirmationPromise` when finished', async () => {\n        expect.assertions(2);\n        const getRecentSignatureConfirmationPromise = jest.fn();\n        raceStrategies(\n            'abc' as Signature,\n            {\n                commitment: 'finalized',\n                getRecentSignatureConfirmationPromise,\n            },\n            function getSpecificStrategiesForRace() {\n                return [];\n            },\n        ).catch(() => {});\n        expect(getRecentSignatureConfirmationPromise).toHaveBeenCalledWith(\n            expect.objectContaining({ abortSignal: expect.objectContaining({ aborted: false }) }),\n        );\n        await jest.runAllTimersAsync();\n        expect(getRecentSignatureConfirmationPromise).toHaveBeenCalledWith(\n            expect.objectContaining({ abortSignal: expect.objectContaining({ aborted: true }) }),\n        );\n    });\n    it('aborts the `AbortController` passed to `getRecentSignatureConfirmationPromise` when the caller-supplied `AbortSignal` aborts', () => {\n        const getRecentSignatureConfirmationPromise = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        const abortController = new AbortController();\n        raceStrategies(\n            'abc' as Signature,\n            {\n                abortSignal: abortController.signal,\n                commitment: 'finalized',\n                getRecentSignatureConfirmationPromise,\n            },\n            function getSpecificStrategiesForRace() {\n                return [];\n            },\n        ).catch(() => {});\n        expect(getRecentSignatureConfirmationPromise).toHaveBeenCalledWith(\n            expect.objectContaining({ abortSignal: expect.objectContaining({ aborted: false }) }),\n        );\n        abortController.abort();\n        expect(getRecentSignatureConfirmationPromise).toHaveBeenCalledWith(\n            expect.objectContaining({ abortSignal: expect.objectContaining({ aborted: true }) }),\n        );\n    });\n    it('aborts the `AbortController` passed to the specific strategies when finished', async () => {\n        expect.assertions(2);\n        const getSpecificStrategiesForRace = jest.fn().mockReturnValue([]);\n        raceStrategies(\n            'abc' as Signature,\n            {\n                commitment: 'finalized',\n                getRecentSignatureConfirmationPromise: jest.fn(),\n            },\n            getSpecificStrategiesForRace,\n        ).catch(() => {});\n        expect(getSpecificStrategiesForRace).toHaveBeenCalledWith(\n            expect.objectContaining({ abortSignal: expect.objectContaining({ aborted: false }) }),\n        );\n        await jest.runAllTimersAsync();\n        expect(getSpecificStrategiesForRace).toHaveBeenCalledWith(\n            expect.objectContaining({ abortSignal: expect.objectContaining({ aborted: true }) }),\n        );\n    });\n    it('aborts the `AbortController` passed to the specific strategies when the caller-supplied `AbortSignal` aborts', () => {\n        const getSpecificStrategiesForRace = jest.fn().mockReturnValue([]);\n        const abortController = new AbortController();\n        raceStrategies(\n            'abc' as Signature,\n            {\n                abortSignal: abortController.signal,\n                commitment: 'finalized',\n                getRecentSignatureConfirmationPromise: jest.fn().mockReturnValue(FOREVER_PROMISE),\n            },\n            getSpecificStrategiesForRace,\n        ).catch(() => {});\n        expect(getSpecificStrategiesForRace).toHaveBeenCalledWith(\n            expect.objectContaining({ abortSignal: expect.objectContaining({ aborted: false }) }),\n        );\n        abortController.abort();\n        expect(getSpecificStrategiesForRace).toHaveBeenCalledWith(\n            expect.objectContaining({ abortSignal: expect.objectContaining({ aborted: true }) }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__tests__/confirmation-strategy-signature-test.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN, SolanaError } from '@solana/errors';\nimport { Signature } from '@solana/keys';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from '../confirmation-strategy-recent-signature';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('createSignatureConfirmationPromiseFactory', () => {\n    let signatureNotificationGenerator: jest.Mock;\n    let createPendingSubscription: jest.Mock;\n    let createSubscriptionIterable: jest.Mock;\n    let getSignatureStatusesMock: jest.Mock;\n    let getSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n    beforeEach(() => {\n        jest.useFakeTimers();\n        signatureNotificationGenerator = jest.fn().mockImplementation(async function* () {\n            yield await FOREVER_PROMISE;\n        });\n        getSignatureStatusesMock = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        const rpc = {\n            getSignatureStatuses: () => ({\n                reactiveStore: jest.fn().mockImplementation(() => {\n                    throw new Error('not implemented');\n                }),\n                send: getSignatureStatusesMock,\n            }),\n        };\n        createSubscriptionIterable = jest.fn().mockResolvedValue({\n            [Symbol.asyncIterator]: signatureNotificationGenerator,\n        });\n        createPendingSubscription = jest.fn().mockReturnValue({\n            reactive: jest.fn().mockRejectedValue(new Error('not implemented')),\n            reactiveStore: jest.fn().mockImplementation(() => {\n                throw new Error('not implemented');\n            }),\n            subscribe: createSubscriptionIterable,\n        });\n        const rpcSubscriptions = {\n            signatureNotifications: createPendingSubscription,\n        };\n        getSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions });\n    });\n    it('sets up a subscription for notifications about signature changes', async () => {\n        expect.assertions(2);\n        getSignatureConfirmationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(createPendingSubscription).toHaveBeenCalledWith('abc', {\n            commitment: 'finalized',\n        });\n        expect(createSubscriptionIterable).toHaveBeenCalled();\n    });\n    it('does not fire off the one shot query for the signature status until the subscription is set up', async () => {\n        expect.assertions(2);\n        let setupSubscription;\n        createSubscriptionIterable.mockReturnValue(\n            new Promise(resolve => {\n                setupSubscription = resolve;\n            }),\n        );\n        getSignatureConfirmationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(getSignatureStatusesMock).not.toHaveBeenCalled();\n        // FIXME: https://github.com/microsoft/TypeScript/issues/11498\n        // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n        // @ts-ignore\n        setupSubscription({\n            [Symbol.asyncIterator]: signatureNotificationGenerator,\n        });\n        await jest.runAllTimersAsync();\n        expect(getSignatureStatusesMock).toHaveBeenCalled();\n    });\n    it.each(['processed', 'confirmed'])(\n        'continues to pend when the signature status returned by the one-shot query is at a lower level of commitment (eg. `%s`)',\n        async achievedCommitment => {\n            expect.assertions(1);\n            getSignatureStatusesMock.mockResolvedValue({\n                value: [{ confirmationStatus: achievedCommitment }],\n            });\n            const signatureConfirmationPromise = getSignatureConfirmationPromise({\n                abortSignal: new AbortController().signal,\n                commitment: 'finalized',\n                signature: 'abc' as Signature,\n            });\n            await jest.runAllTimersAsync();\n            await expect(Promise.race([signatureConfirmationPromise, Promise.resolve('pending')])).resolves.toBe(\n                'pending',\n            );\n        },\n    );\n    it('continues to pend when no signature status is returned by the one-shot query', async () => {\n        expect.assertions(1);\n        getSignatureStatusesMock.mockResolvedValue({\n            value: [null],\n        });\n        const signatureConfirmationPromise = getSignatureConfirmationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        });\n        await jest.runAllTimersAsync();\n        await expect(Promise.race([signatureConfirmationPromise, Promise.resolve('pending')])).resolves.toBe('pending');\n    });\n    it('resolves when the signature status returned by the one-shot query is at the target level of commitment', async () => {\n        expect.assertions(1);\n        getSignatureStatusesMock.mockResolvedValue({\n            value: [{ confirmationStatus: 'finalized' }],\n        });\n        const signatureConfirmationPromise = getSignatureConfirmationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        });\n        await expect(signatureConfirmationPromise).resolves.toBeUndefined();\n    });\n    it('fatals when the signature status returned by the one-shot query is an error', async () => {\n        expect.assertions(1);\n        getSignatureStatusesMock.mockResolvedValue({\n            value: [{ confirmationStatus: 'finalized', err: 'o no' }],\n        });\n        const signatureConfirmationPromise = getSignatureConfirmationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        });\n        await expect(signatureConfirmationPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN, { errorName: 'o no' }),\n        );\n    });\n    it('resolves when a signature status notification is returned by the signature subscription', async () => {\n        expect.assertions(1);\n        signatureNotificationGenerator.mockImplementation(async function* () {\n            yield {\n                value: { err: null },\n            };\n            yield FOREVER_PROMISE;\n        });\n        const signatureConfirmationPromise = getSignatureConfirmationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        });\n        await expect(signatureConfirmationPromise).resolves.toBeUndefined();\n    });\n    it('fatals when the signature subscription returns an error', async () => {\n        expect.assertions(1);\n        signatureNotificationGenerator.mockImplementation(async function* () {\n            yield { value: { err: 'o no' } };\n            yield FOREVER_PROMISE;\n        });\n        const signatureConfirmationPromise = getSignatureConfirmationPromise({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        });\n        await expect(signatureConfirmationPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION_ERROR__UNKNOWN, { errorName: 'o no' }),\n        );\n    });\n    it('calls the abort signal passed to the signature statuses query when aborted', async () => {\n        expect.assertions(2);\n        const abortController = new AbortController();\n        getSignatureConfirmationPromise({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        }).catch(() => {});\n        await jest.runAllTimersAsync();\n        expect(getSignatureStatusesMock).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: false }),\n        });\n        abortController.abort();\n        expect(getSignatureStatusesMock).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: true }),\n        });\n    });\n    it('calls the abort signal passed to the signature subscription when aborted', () => {\n        const abortController = new AbortController();\n        getSignatureConfirmationPromise({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            signature: 'abc' as Signature,\n        }).catch(() => {});\n        expect(createSubscriptionIterable).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: false }),\n        });\n        abortController.abort();\n        expect(createSubscriptionIterable).toHaveBeenCalledWith({\n            abortSignal: expect.objectContaining({ aborted: true }),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__tests__/confirmation-strategy-timeout-test.ts",
    "content": "import { getTimeoutPromise } from '../confirmation-strategy-timeout';\n\ndescribe('getTimeoutPromise', () => {\n    beforeEach(() => {\n        jest.useFakeTimers();\n    });\n    it.each`\n        commitment     | defaultTimeoutMs\n        ${'processed'} | ${30_000}\n        ${'confirmed'} | ${60_000}\n        ${'finalized'} | ${60_000}\n    `('pends for $defaultTimeoutMs when the commitment is `$commitment`', async ({ commitment, defaultTimeoutMs }) => {\n        expect.assertions(2);\n        const timeoutPromise = getTimeoutPromise({\n            abortSignal: new AbortController().signal,\n            commitment,\n        });\n        await jest.advanceTimersByTimeAsync(defaultTimeoutMs - 1);\n        await expect(Promise.race([timeoutPromise, Promise.resolve('pending')])).resolves.toBe('pending');\n        await jest.advanceTimersByTimeAsync(1);\n        await expect(Promise.race([timeoutPromise, Promise.resolve('pending')])).rejects.toThrow();\n    });\n    it('throws an abort error when aborted before the timeout', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        const timeoutPromise = getTimeoutPromise({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n        });\n        abortController.abort();\n        await expect(timeoutPromise).rejects.toThrow(/operation was aborted/);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__tests__/waiters-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING, SolanaError } from '@solana/errors';\nimport { Signature, SignatureBytes } from '@solana/keys';\nimport type { Blockhash } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\nimport {\n    Transaction,\n    TransactionMessageBytes,\n    TransactionWithBlockhashLifetime,\n    TransactionWithDurableNonceLifetime,\n} from '@solana/transactions';\n\nimport {\n    waitForDurableNonceTransactionConfirmation,\n    waitForRecentTransactionConfirmation,\n    waitForRecentTransactionConfirmationUntilTimeout,\n} from '../waiters';\n\nconst FOREVER_PROMISE = new Promise(() => {\n    /* never resolve */\n});\n\ndescribe('waitForDurableNonceTransactionConfirmation', () => {\n    const MOCK_DURABLE_NONCE_TRANSACTION: Transaction & TransactionWithDurableNonceLifetime = {\n        lifetimeConstraint: { nonce: 'xyz' as Nonce, nonceAccountAddress: '5'.repeat(44) as Address },\n        messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n        signatures: {\n            ['9'.repeat(44) as Address]: new Uint8Array(new Array(64).fill(0)) as SignatureBytes,\n        },\n    };\n    let getNonceInvalidationPromise: jest.Mock<Promise<void>>;\n    let getRecentSignatureConfirmationPromise: jest.Mock<Promise<void>>;\n    beforeEach(() => {\n        getNonceInvalidationPromise = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        getRecentSignatureConfirmationPromise = jest.fn().mockReturnValue(FOREVER_PROMISE);\n    });\n    it('throws when the signal is already aborted', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        abortController.abort();\n        const commitmentPromise = waitForDurableNonceTransactionConfirmation({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        });\n        await expect(commitmentPromise).rejects.toThrow('aborted');\n    });\n    it('calls `getNonceInvalidationPromise` with the necessary input', () => {\n        waitForDurableNonceTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        }).catch(() => {});\n        expect(getNonceInvalidationPromise).toHaveBeenCalledWith({\n            abortSignal: expect.any(AbortSignal),\n            commitment: 'finalized',\n            currentNonceValue: 'xyz',\n            nonceAccountAddress: '5'.repeat(44),\n        });\n    });\n    it('calls the abort signal passed to `getBlockHeightExceededPromise` when aborted', () => {\n        const handleAbortOnBlockHeightExceedencePromise = jest.fn();\n        getNonceInvalidationPromise.mockImplementation(async ({ abortSignal }) => {\n            abortSignal.addEventListener('abort', handleAbortOnBlockHeightExceedencePromise);\n            await FOREVER_PROMISE;\n        });\n        const abortController = new AbortController();\n        waitForDurableNonceTransactionConfirmation({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        }).catch(() => {});\n        abortController.abort();\n        expect(handleAbortOnBlockHeightExceedencePromise).toHaveBeenCalled();\n    });\n    it('calls the abort signal passed to `getRecentSignatureConfirmationPromise` when aborted', () => {\n        const handleAbortOnSignatureConfirmationPromise = jest.fn();\n        getRecentSignatureConfirmationPromise.mockImplementation(async ({ abortSignal }) => {\n            abortSignal.addEventListener('abort', handleAbortOnSignatureConfirmationPromise);\n            await FOREVER_PROMISE;\n        });\n        const abortController = new AbortController();\n        waitForDurableNonceTransactionConfirmation({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        }).catch(() => {});\n        abortController.abort();\n        expect(handleAbortOnSignatureConfirmationPromise).toHaveBeenCalled();\n    });\n    it('calls `getRecentSignatureConfirmationPromise` with the necessary input', () => {\n        waitForDurableNonceTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        }).catch(() => {});\n        expect(getRecentSignatureConfirmationPromise).toHaveBeenCalledWith({\n            abortSignal: expect.any(AbortSignal),\n            commitment: 'finalized',\n            signature: '1111111111111111111111111111111111111111111111111111111111111111' as Signature,\n        });\n    });\n    it('throws when supplied a transaction that has not been signed by the fee payer', async () => {\n        expect.assertions(1);\n        const transactionWithoutFeePayerSignature = {\n            ...MOCK_DURABLE_NONCE_TRANSACTION,\n            signatures: {\n                // No signature for fee payer.\n                ['9'.repeat(44) as Address]: null,\n            } as const,\n        };\n        const commitmentPromise = waitForDurableNonceTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: transactionWithoutFeePayerSignature,\n        });\n        await expect(commitmentPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING),\n        );\n    });\n    it('resolves when the signature confirmation promise resolves despite the block height exceedence promise having thrown', async () => {\n        expect.assertions(1);\n        getNonceInvalidationPromise.mockRejectedValue(new Error('o no'));\n        getRecentSignatureConfirmationPromise.mockResolvedValue(undefined);\n        const commitmentPromise = waitForDurableNonceTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        });\n        await expect(commitmentPromise).resolves.toBeUndefined();\n    });\n    it('throws when the block height exceedence promise throws', async () => {\n        expect.assertions(1);\n        getNonceInvalidationPromise.mockRejectedValue(new Error('o no'));\n        const commitmentPromise = waitForDurableNonceTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        });\n        await expect(commitmentPromise).rejects.toThrow('o no');\n    });\n    it('throws when the signature confirmation promise throws', async () => {\n        expect.assertions(1);\n        getRecentSignatureConfirmationPromise.mockRejectedValue(new Error('o no'));\n        const commitmentPromise = waitForDurableNonceTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getNonceInvalidationPromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_DURABLE_NONCE_TRANSACTION,\n        });\n        await expect(commitmentPromise).rejects.toThrow('o no');\n    });\n});\n\ndescribe('waitForRecentTransactionConfirmation', () => {\n    const MOCK_TRANSACTION: Transaction & TransactionWithBlockhashLifetime = {\n        lifetimeConstraint: { blockhash: '4'.repeat(44) as Blockhash, lastValidBlockHeight: 123n },\n        messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n        signatures: {\n            ['9'.repeat(44) as Address]: new Uint8Array(new Array(64).fill(0)) as SignatureBytes,\n        },\n    };\n    let getBlockHeightExceedencePromise: jest.Mock<Promise<void>>;\n    let getRecentSignatureConfirmationPromise: jest.Mock<Promise<void>>;\n    beforeEach(() => {\n        getBlockHeightExceedencePromise = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        getRecentSignatureConfirmationPromise = jest.fn().mockReturnValue(FOREVER_PROMISE);\n    });\n    it('throws when the signal is already aborted', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        abortController.abort();\n        const commitmentPromise = waitForRecentTransactionConfirmation({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_TRANSACTION,\n        });\n        await expect(commitmentPromise).rejects.toThrow('aborted');\n    });\n    it('calls `getBlockHeightExceededPromise` with the necessary input', () => {\n        waitForRecentTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_TRANSACTION,\n        }).catch(() => {});\n        expect(getBlockHeightExceedencePromise).toHaveBeenCalledWith({\n            abortSignal: expect.any(AbortSignal),\n            commitment: 'finalized',\n            lastValidBlockHeight: MOCK_TRANSACTION.lifetimeConstraint.lastValidBlockHeight,\n        });\n    });\n    it('calls `getRecentSignatureConfirmationPromise` with the necessary input', () => {\n        waitForRecentTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_TRANSACTION,\n        }).catch(() => {});\n        expect(getRecentSignatureConfirmationPromise).toHaveBeenCalledWith({\n            abortSignal: expect.any(AbortSignal),\n            commitment: 'finalized',\n            signature: '1111111111111111111111111111111111111111111111111111111111111111' as Signature,\n        });\n    });\n    it('throws when supplied a transaction that has not been signed by the fee payer', async () => {\n        expect.assertions(1);\n        const transactionWithoutFeePayerSignature = {\n            ...MOCK_TRANSACTION,\n            signatures: {\n                // No signature for fee payer\n                ['9'.repeat(44) as Address]: null,\n            } as const,\n        };\n        const commitmentPromise = waitForRecentTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: transactionWithoutFeePayerSignature,\n        });\n        await expect(commitmentPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING),\n        );\n    });\n    it('resolves when the signature confirmation promise resolves despite the block height exceedence promise having thrown', async () => {\n        expect.assertions(1);\n        getBlockHeightExceedencePromise.mockRejectedValue(new Error('o no'));\n        getRecentSignatureConfirmationPromise.mockResolvedValue(undefined);\n        const commitmentPromise = waitForRecentTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_TRANSACTION,\n        });\n        await expect(commitmentPromise).resolves.toBeUndefined();\n    });\n    it('throws when the block height exceedence promise throws', async () => {\n        expect.assertions(1);\n        getBlockHeightExceedencePromise.mockRejectedValue(new Error('o no'));\n        const commitmentPromise = waitForRecentTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_TRANSACTION,\n        });\n        await expect(commitmentPromise).rejects.toThrow('o no');\n    });\n    it('throws when the signature confirmation promise throws', async () => {\n        expect.assertions(1);\n        getRecentSignatureConfirmationPromise.mockRejectedValue(new Error('o no'));\n        const commitmentPromise = waitForRecentTransactionConfirmation({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_TRANSACTION,\n        });\n        await expect(commitmentPromise).rejects.toThrow('o no');\n    });\n    it('calls the abort signal passed to `getBlockHeightExceededPromise` when aborted', () => {\n        const handleAbortOnBlockHeightExceedencePromise = jest.fn();\n        getBlockHeightExceedencePromise.mockImplementation(async ({ abortSignal }) => {\n            abortSignal.addEventListener('abort', handleAbortOnBlockHeightExceedencePromise);\n            await FOREVER_PROMISE;\n        });\n        const abortController = new AbortController();\n        waitForRecentTransactionConfirmation({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_TRANSACTION,\n        }).catch(() => {});\n        abortController.abort();\n        expect(handleAbortOnBlockHeightExceedencePromise).toHaveBeenCalled();\n    });\n    it('calls the abort signal passed to `getRecentSignatureConfirmationPromise` when aborted', () => {\n        const handleAbortOnSignatureConfirmationPromise = jest.fn();\n        getRecentSignatureConfirmationPromise.mockImplementation(async ({ abortSignal }) => {\n            abortSignal.addEventListener('abort', handleAbortOnSignatureConfirmationPromise);\n            await FOREVER_PROMISE;\n        });\n        const abortController = new AbortController();\n        waitForRecentTransactionConfirmation({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getBlockHeightExceedencePromise,\n            getRecentSignatureConfirmationPromise,\n            transaction: MOCK_TRANSACTION,\n        }).catch(() => {});\n        abortController.abort();\n        expect(handleAbortOnSignatureConfirmationPromise).toHaveBeenCalled();\n    });\n});\n\ndescribe('waitForRecentTransactionConfirmationUntilTimeout', () => {\n    const MOCK_SIGNATURE = '4'.repeat(44) as Signature;\n    let getTimeoutPromise: jest.Mock<Promise<void>>;\n    let getRecentSignatureConfirmationPromise: jest.Mock<Promise<void>>;\n    beforeEach(() => {\n        getTimeoutPromise = jest.fn().mockReturnValue(FOREVER_PROMISE);\n        getRecentSignatureConfirmationPromise = jest.fn().mockReturnValue(FOREVER_PROMISE);\n    });\n    it('throws when the signal is already aborted', async () => {\n        expect.assertions(1);\n        const abortController = new AbortController();\n        abortController.abort();\n        const commitmentPromise = waitForRecentTransactionConfirmationUntilTimeout({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n            signature: MOCK_SIGNATURE,\n        });\n        await expect(commitmentPromise).rejects.toThrow('aborted');\n    });\n    it('calls `getTimeoutPromise` with the necessary input', () => {\n        waitForRecentTransactionConfirmationUntilTimeout({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n            signature: MOCK_SIGNATURE,\n        }).catch(() => {});\n        expect(getTimeoutPromise).toHaveBeenCalledWith({\n            abortSignal: expect.any(AbortSignal),\n            commitment: 'finalized',\n        });\n    });\n    it('calls `getRecentSignatureConfirmationPromise` with the necessary input', () => {\n        waitForRecentTransactionConfirmationUntilTimeout({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n            signature: MOCK_SIGNATURE,\n        }).catch(() => {});\n        expect(getRecentSignatureConfirmationPromise).toHaveBeenCalledWith({\n            abortSignal: expect.any(AbortSignal),\n            commitment: 'finalized',\n            signature: '4'.repeat(44),\n        });\n    });\n    it('resolves when the signature confirmation promise resolves despite the timeout promise having thrown', async () => {\n        expect.assertions(1);\n        getTimeoutPromise.mockRejectedValue(new Error('o no'));\n        getRecentSignatureConfirmationPromise.mockResolvedValue(undefined);\n        const commitmentPromise = waitForRecentTransactionConfirmationUntilTimeout({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n            signature: MOCK_SIGNATURE,\n        });\n        await expect(commitmentPromise).resolves.toBeUndefined();\n    });\n    it('throws when the timeout promise throws', async () => {\n        expect.assertions(1);\n        getTimeoutPromise.mockRejectedValue(new Error('o no'));\n        const commitmentPromise = waitForRecentTransactionConfirmationUntilTimeout({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n            signature: MOCK_SIGNATURE,\n        });\n        await expect(commitmentPromise).rejects.toThrow('o no');\n    });\n    it('throws when the signature confirmation promise throws', async () => {\n        expect.assertions(1);\n        getRecentSignatureConfirmationPromise.mockRejectedValue(new Error('o no'));\n        const commitmentPromise = waitForRecentTransactionConfirmationUntilTimeout({\n            abortSignal: new AbortController().signal,\n            commitment: 'finalized',\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n            signature: MOCK_SIGNATURE,\n        });\n        await expect(commitmentPromise).rejects.toThrow('o no');\n    });\n    it('calls the abort signal passed to `getTimeoutPromise` when aborted', () => {\n        const handleAbortOnTimeoutPromise = jest.fn();\n        getTimeoutPromise.mockImplementation(async ({ abortSignal }) => {\n            abortSignal.addEventListener('abort', handleAbortOnTimeoutPromise);\n            await FOREVER_PROMISE;\n        });\n        const abortController = new AbortController();\n        waitForRecentTransactionConfirmationUntilTimeout({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n            signature: MOCK_SIGNATURE,\n        }).catch(() => {});\n        abortController.abort();\n        expect(handleAbortOnTimeoutPromise).toHaveBeenCalled();\n    });\n    it('calls the abort signal passed to `getRecentSignatureConfirmationPromise` when aborted', () => {\n        const handleAbortOnSignatureConfirmationPromise = jest.fn();\n        getRecentSignatureConfirmationPromise.mockImplementation(async ({ abortSignal }) => {\n            abortSignal.addEventListener('abort', handleAbortOnSignatureConfirmationPromise);\n            await FOREVER_PROMISE;\n        });\n        const abortController = new AbortController();\n        waitForRecentTransactionConfirmationUntilTimeout({\n            abortSignal: abortController.signal,\n            commitment: 'finalized',\n            getRecentSignatureConfirmationPromise,\n            getTimeoutPromise,\n            signature: MOCK_SIGNATURE,\n        }).catch(() => {});\n        abortController.abort();\n        expect(handleAbortOnSignatureConfirmationPromise).toHaveBeenCalled();\n    });\n});\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__typetests__/confirmation-strategy-blockheight-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport { GetEpochInfoApi, Rpc, RpcDevnet, RpcMainnet, RpcTestnet } from '@solana/rpc';\nimport {\n    RpcSubscriptions,\n    RpcSubscriptionsDevnet,\n    RpcSubscriptionsMainnet,\n    RpcSubscriptionsTestnet,\n    SlotNotificationsApi,\n} from '@solana/rpc-subscriptions';\n\nimport { createBlockHeightExceedencePromiseFactory } from '../confirmation-strategy-blockheight';\n\nconst rpc = null as unknown as Rpc<GetEpochInfoApi>;\nconst rpcDevnet = null as unknown as RpcDevnet<GetEpochInfoApi>;\nconst rpcTestnet = null as unknown as RpcTestnet<GetEpochInfoApi>;\nconst rpcMainnet = null as unknown as RpcMainnet<GetEpochInfoApi>;\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<SlotNotificationsApi>;\nconst rpcSubscriptionsDevnet = null as unknown as RpcSubscriptionsDevnet<SlotNotificationsApi>;\nconst rpcSubscriptionsMainnet = null as unknown as RpcSubscriptionsMainnet<SlotNotificationsApi>;\nconst rpcSubscriptionsTestnet = null as unknown as RpcSubscriptionsTestnet<SlotNotificationsApi>;\n\n// [DESCRIBE] createBlockHeightExceedencePromiseFactory\n{\n    {\n        // It typechecks when the RPC clusters match.\n        createBlockHeightExceedencePromiseFactory({ rpc, rpcSubscriptions });\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It typechecks when either RPC is generic.\n        createBlockHeightExceedencePromiseFactory({ rpc, rpcSubscriptions });\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcDevnet, rpcSubscriptions });\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcTestnet, rpcSubscriptions });\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcMainnet, rpcSubscriptions });\n        createBlockHeightExceedencePromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsDevnet });\n        createBlockHeightExceedencePromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsTestnet });\n        createBlockHeightExceedencePromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It fails to typecheck when explicit RPC clusters mismatch.\n        // @ts-expect-error\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        // @ts-expect-error\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        createBlockHeightExceedencePromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n    }\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__typetests__/confirmation-strategy-nonce-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport { GetAccountInfoApi, Rpc, RpcDevnet, RpcMainnet, RpcTestnet } from '@solana/rpc';\nimport {\n    AccountNotificationsApi,\n    RpcSubscriptions,\n    RpcSubscriptionsDevnet,\n    RpcSubscriptionsMainnet,\n    RpcSubscriptionsTestnet,\n} from '@solana/rpc-subscriptions';\n\nimport { createNonceInvalidationPromiseFactory } from '../confirmation-strategy-nonce';\n\nconst rpc = null as unknown as Rpc<GetAccountInfoApi>;\nconst rpcDevnet = null as unknown as RpcDevnet<GetAccountInfoApi>;\nconst rpcTestnet = null as unknown as RpcTestnet<GetAccountInfoApi>;\nconst rpcMainnet = null as unknown as RpcMainnet<GetAccountInfoApi>;\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<AccountNotificationsApi>;\nconst rpcSubscriptionsDevnet = null as unknown as RpcSubscriptionsDevnet<AccountNotificationsApi>;\nconst rpcSubscriptionsMainnet = null as unknown as RpcSubscriptionsMainnet<AccountNotificationsApi>;\nconst rpcSubscriptionsTestnet = null as unknown as RpcSubscriptionsTestnet<AccountNotificationsApi>;\n\n// [DESCRIBE] createNonceInvalidationPromiseFactory\n{\n    {\n        // It typechecks when the RPC clusters match.\n        createNonceInvalidationPromiseFactory({ rpc, rpcSubscriptions });\n        createNonceInvalidationPromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        createNonceInvalidationPromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        createNonceInvalidationPromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It typechecks when either RPC is generic.\n        createNonceInvalidationPromiseFactory({ rpc, rpcSubscriptions });\n        createNonceInvalidationPromiseFactory({ rpc: rpcDevnet, rpcSubscriptions });\n        createNonceInvalidationPromiseFactory({ rpc: rpcTestnet, rpcSubscriptions });\n        createNonceInvalidationPromiseFactory({ rpc: rpcMainnet, rpcSubscriptions });\n        createNonceInvalidationPromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsDevnet });\n        createNonceInvalidationPromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsTestnet });\n        createNonceInvalidationPromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It fails to typecheck when explicit RPC clusters mismatch.\n        // @ts-expect-error\n        createNonceInvalidationPromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        // @ts-expect-error\n        createNonceInvalidationPromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        createNonceInvalidationPromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        createNonceInvalidationPromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        createNonceInvalidationPromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        createNonceInvalidationPromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n    }\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/__typetests__/confirmation-strategy-recent-signature-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/ban-ts-comment */\nimport { GetSignatureStatusesApi, Rpc, RpcDevnet, RpcMainnet, RpcTestnet } from '@solana/rpc';\nimport {\n    RpcSubscriptions,\n    RpcSubscriptionsDevnet,\n    RpcSubscriptionsMainnet,\n    RpcSubscriptionsTestnet,\n    SignatureNotificationsApi,\n} from '@solana/rpc-subscriptions';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from '../confirmation-strategy-recent-signature';\n\nconst rpc = null as unknown as Rpc<GetSignatureStatusesApi>;\nconst rpcDevnet = null as unknown as RpcDevnet<GetSignatureStatusesApi>;\nconst rpcTestnet = null as unknown as RpcTestnet<GetSignatureStatusesApi>;\nconst rpcMainnet = null as unknown as RpcMainnet<GetSignatureStatusesApi>;\n\nconst rpcSubscriptions = null as unknown as RpcSubscriptions<SignatureNotificationsApi>;\nconst rpcSubscriptionsDevnet = null as unknown as RpcSubscriptionsDevnet<SignatureNotificationsApi>;\nconst rpcSubscriptionsMainnet = null as unknown as RpcSubscriptionsMainnet<SignatureNotificationsApi>;\nconst rpcSubscriptionsTestnet = null as unknown as RpcSubscriptionsTestnet<SignatureNotificationsApi>;\n\n// [DESCRIBE] createRecentSignatureConfirmationPromiseFactory\n{\n    {\n        // It typechecks when the RPC clusters match.\n        createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions });\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It typechecks when either RPC is generic.\n        createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions });\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcDevnet, rpcSubscriptions });\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcTestnet, rpcSubscriptions });\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcMainnet, rpcSubscriptions });\n        createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsDevnet });\n        createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsTestnet });\n        createRecentSignatureConfirmationPromiseFactory({ rpc, rpcSubscriptions: rpcSubscriptionsMainnet });\n    }\n    {\n        // It fails to typecheck when explicit RPC clusters mismatch.\n        // @ts-expect-error\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n        // @ts-expect-error\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcDevnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsMainnet });\n        // @ts-expect-error\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcTestnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsDevnet });\n        // @ts-expect-error\n        createRecentSignatureConfirmationPromiseFactory({ rpc: rpcMainnet, rpcSubscriptions: rpcSubscriptionsTestnet });\n    }\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/confirmation-strategy-blockheight.ts",
    "content": "import { SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, SolanaError } from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\nimport type { GetEpochInfoApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SlotNotificationsApi } from '@solana/rpc-subscriptions';\nimport type { Commitment } from '@solana/rpc-types';\n\ntype GetBlockHeightExceedencePromiseFn = (config: {\n    abortSignal: AbortSignal;\n    /**\n     * Fetch the block height as of the highest slot that has reached this level of commitment.\n     *\n     * @defaultValue Whichever default is applied by the underlying {@link RpcApi} in use. For\n     * example, when using an API created by a `createSolanaRpc*()` helper, the default commitment\n     * is `\"confirmed\"` unless configured otherwise. Unmitigated by an API layer on the client, the\n     * default commitment applied by the server is `\"finalized\"`.\n     */\n    commitment?: Commitment;\n    /** The block height after which to reject the promise */\n    lastValidBlockHeight: bigint;\n}) => Promise<void>;\n\ntype CreateBlockHeightExceedencePromiseFactoryConfig<TCluster> = {\n    rpc: Rpc<GetEpochInfoApi> & { '~cluster'?: TCluster };\n    rpcSubscriptions: RpcSubscriptions<SlotNotificationsApi> & { '~cluster'?: TCluster };\n};\n\n/**\n * Creates a promise that throws when the network progresses past the block height after which the\n * supplied blockhash is considered expired for use as a transaction lifetime specifier.\n *\n * When a transaction's lifetime is tied to a blockhash, that transaction can be landed on the\n * network until that blockhash expires. All blockhashes have a block height after which they are\n * considered to have expired.\n *\n * @param config\n *\n * @example\n * ```ts\n * import { isSolanaError, SolanaError } from '@solana/errors';\n * import { createBlockHeightExceedencePromiseFactory } from '@solana/transaction-confirmation';\n *\n * const getBlockHeightExceedencePromise = createBlockHeightExceedencePromiseFactory({\n *     rpc,\n *     rpcSubscriptions,\n * });\n * try {\n *     await getBlockHeightExceedencePromise({ lastValidBlockHeight });\n * } catch (e) {\n *     if (isSolanaError(e, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {\n *         console.error(\n *             `The block height of the network has exceeded ${e.context.lastValidBlockHeight}. ` +\n *                 `It is now ${e.context.currentBlockHeight}`,\n *         );\n *         // Re-sign and retry the transaction.\n *         return;\n *     }\n *     throw e;\n * }\n * ```\n */\nexport function createBlockHeightExceedencePromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryConfig<'devnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryConfig<'testnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryConfig<'mainnet'>): GetBlockHeightExceedencePromiseFn;\nexport function createBlockHeightExceedencePromiseFactory<\n    TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n    rpc,\n    rpcSubscriptions,\n}: CreateBlockHeightExceedencePromiseFactoryConfig<TCluster>): GetBlockHeightExceedencePromiseFn {\n    return async function getBlockHeightExceedencePromise({\n        abortSignal: callerAbortSignal,\n        commitment,\n        lastValidBlockHeight,\n    }): Promise<never> {\n        callerAbortSignal.throwIfAborted();\n        const abortController = new AbortController();\n        const handleAbort = () => {\n            abortController.abort();\n        };\n        callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n        async function getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight() {\n            const { absoluteSlot, blockHeight } = await rpc\n                .getEpochInfo({ commitment })\n                .send({ abortSignal: abortController.signal });\n            return {\n                blockHeight,\n                differenceBetweenSlotHeightAndBlockHeight: absoluteSlot - blockHeight,\n            };\n        }\n        try {\n            const [slotNotifications, { blockHeight: initialBlockHeight, differenceBetweenSlotHeightAndBlockHeight }] =\n                await Promise.all([\n                    rpcSubscriptions.slotNotifications().subscribe({ abortSignal: abortController.signal }),\n                    getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight(),\n                ]);\n            callerAbortSignal.throwIfAborted();\n            let currentBlockHeight = initialBlockHeight;\n            if (currentBlockHeight <= lastValidBlockHeight) {\n                let lastKnownDifferenceBetweenSlotHeightAndBlockHeight = differenceBetweenSlotHeightAndBlockHeight;\n                for await (const slotNotification of slotNotifications) {\n                    const { slot } = slotNotification;\n                    if (slot - lastKnownDifferenceBetweenSlotHeightAndBlockHeight > lastValidBlockHeight) {\n                        // Before making a final decision, recheck the actual block height.\n                        const {\n                            blockHeight: recheckedBlockHeight,\n                            differenceBetweenSlotHeightAndBlockHeight: currentDifferenceBetweenSlotHeightAndBlockHeight,\n                        } = await getBlockHeightAndDifferenceBetweenSlotHeightAndBlockHeight();\n                        currentBlockHeight = recheckedBlockHeight;\n                        if (currentBlockHeight > lastValidBlockHeight) {\n                            // Verified; the block height has been exceeded.\n                            break;\n                        } else {\n                            // The block height has not been exceeded, which implies that the\n                            // difference between the slot height and the block height has grown\n                            // (ie. some blocks have been skipped since we started). Recalibrate the\n                            // difference and keep waiting.\n                            lastKnownDifferenceBetweenSlotHeightAndBlockHeight =\n                                currentDifferenceBetweenSlotHeightAndBlockHeight;\n                        }\n                    }\n                }\n            }\n            callerAbortSignal.throwIfAborted();\n            throw new SolanaError(SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED, {\n                currentBlockHeight,\n                lastValidBlockHeight,\n            });\n        } finally {\n            abortController.abort();\n        }\n    };\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/confirmation-strategy-nonce.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { getBase58Decoder, getBase64Encoder } from '@solana/codecs-strings';\nimport { SOLANA_ERROR__INVALID_NONCE, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, SolanaError } from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\nimport { safeRace } from '@solana/promises';\nimport type { GetAccountInfoApi, Rpc } from '@solana/rpc';\nimport type { AccountNotificationsApi, RpcSubscriptions } from '@solana/rpc-subscriptions';\nimport type { Base64EncodedDataResponse, Commitment } from '@solana/rpc-types';\nimport { Nonce } from '@solana/transaction-messages';\n\ntype GetNonceInvalidationPromiseFn = (config: {\n    abortSignal: AbortSignal;\n    /**\n     * Fetch the nonce account details as of the highest slot that has reached this level of\n     * commitment.\n     */\n    commitment: Commitment;\n    /**\n     * The value of the nonce that we would expect to see in the nonce account in order for any\n     * transaction with that nonce-based lifetime to be considered valid.\n     */\n    currentNonceValue: Nonce;\n    /** The address of the account in which the currently-valid nonce value is stored */\n    nonceAccountAddress: Address;\n}) => Promise<void>;\n\ntype CreateNonceInvalidationPromiseFactoryConfig<TCluster> = {\n    rpc: Rpc<GetAccountInfoApi> & { '~cluster'?: TCluster };\n    rpcSubscriptions: RpcSubscriptions<AccountNotificationsApi> & { '~cluster'?: TCluster };\n};\n\nconst NONCE_VALUE_OFFSET =\n    4 + // version(u32)\n    4 + // state(u32)\n    32; // nonce authority(pubkey)\n// Then comes the nonce value.\n\n/**\n * Creates a promise that throws when the value stored in a nonce account is not the expected one.\n *\n * When a transaction's lifetime is tied to the value stored in a nonce account, that transaction\n * can be landed on the network until the nonce is advanced to a new value.\n *\n * @param config\n *\n * @example\n * ```ts\n * import { isSolanaError, SolanaError } from '@solana/errors';\n * import { createNonceInvalidationPromiseFactory } from '@solana/transaction-confirmation';\n *\n * const getNonceInvalidationPromise = createNonceInvalidationPromiseFactory({\n *     rpc,\n *     rpcSubscriptions,\n * });\n * try {\n *     await getNonceInvalidationPromise({\n *         currentNonceValue,\n *         nonceAccountAddress,\n *     });\n * } catch (e) {\n *     if (isSolanaError(e, SOLANA_ERROR__NONCE_INVALID)) {\n *         console.error(`The nonce has advanced to ${e.context.actualNonceValue}`);\n *         // Re-sign and retry the transaction.\n *         return;\n *     } else if (isSolanaError(e, SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND)) {\n *         console.error(`No nonce account was found at ${nonceAccountAddress}`);\n *     }\n *     throw e;\n * }\n * ```\n */\nexport function createNonceInvalidationPromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'devnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'testnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<'mainnet'>): GetNonceInvalidationPromiseFn;\nexport function createNonceInvalidationPromiseFactory<TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void>({\n    rpc,\n    rpcSubscriptions,\n}: CreateNonceInvalidationPromiseFactoryConfig<TCluster>): GetNonceInvalidationPromiseFn {\n    return async function getNonceInvalidationPromise({\n        abortSignal: callerAbortSignal,\n        commitment,\n        currentNonceValue: expectedNonceValue,\n        nonceAccountAddress,\n    }) {\n        const abortController = new AbortController();\n        function handleAbort() {\n            abortController.abort();\n        }\n        callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n        /**\n         * STEP 1: Set up a subscription for nonce account changes.\n         */\n        const accountNotifications = await rpcSubscriptions\n            .accountNotifications(nonceAccountAddress, { commitment, encoding: 'base64' })\n            .subscribe({ abortSignal: abortController.signal });\n        const base58Decoder = getBase58Decoder();\n        const base64Encoder = getBase64Encoder();\n        function getNonceFromAccountData([base64EncodedBytes]: Base64EncodedDataResponse): Nonce {\n            const data = base64Encoder.encode(base64EncodedBytes);\n            const nonceValueBytes = data.slice(NONCE_VALUE_OFFSET, NONCE_VALUE_OFFSET + 32);\n            return base58Decoder.decode(nonceValueBytes) as Nonce;\n        }\n        const nonceAccountDidAdvancePromise = (async () => {\n            for await (const accountNotification of accountNotifications) {\n                const nonceValue = getNonceFromAccountData(accountNotification.value.data);\n                if (nonceValue !== expectedNonceValue) {\n                    throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                        actualNonceValue: nonceValue,\n                        expectedNonceValue,\n                    });\n                }\n            }\n        })();\n        /**\n         * STEP 2: Having subscribed for updates, make a one-shot request for the current nonce\n         *         value to check if it has already been advanced.\n         */\n        const nonceIsAlreadyInvalidPromise = (async () => {\n            const { value: nonceAccount } = await rpc\n                .getAccountInfo(nonceAccountAddress, {\n                    commitment,\n                    dataSlice: { length: 32, offset: NONCE_VALUE_OFFSET },\n                    encoding: 'base58',\n                })\n                .send({ abortSignal: abortController.signal });\n            if (!nonceAccount) {\n                throw new SolanaError(SOLANA_ERROR__NONCE_ACCOUNT_NOT_FOUND, {\n                    nonceAccountAddress,\n                });\n            }\n            const nonceValue =\n                // This works because we asked for the exact slice of data representing the nonce\n                // value, and furthermore asked for it in `base58` encoding.\n                nonceAccount.data[0] as unknown as Nonce;\n            if (nonceValue !== expectedNonceValue) {\n                throw new SolanaError(SOLANA_ERROR__INVALID_NONCE, {\n                    actualNonceValue: nonceValue,\n                    expectedNonceValue,\n                });\n            } else {\n                await new Promise(() => {\n                    /* never resolve */\n                });\n            }\n        })();\n        try {\n            return await safeRace([nonceAccountDidAdvancePromise, nonceIsAlreadyInvalidPromise]);\n        } finally {\n            abortController.abort();\n        }\n    };\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/confirmation-strategy-racer.ts",
    "content": "import { AbortController } from '@solana/event-target-impl';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { Commitment } from '@solana/rpc-types';\n\nimport { createRecentSignatureConfirmationPromiseFactory } from './confirmation-strategy-recent-signature';\n\nexport interface BaseTransactionConfirmationStrategyConfig {\n    abortSignal?: AbortSignal;\n    commitment: Commitment;\n    getRecentSignatureConfirmationPromise: ReturnType<typeof createRecentSignatureConfirmationPromiseFactory>;\n}\n\ntype WithNonNullableAbortSignal<T> = Omit<T, 'abortSignal'> & Readonly<{ abortSignal: AbortSignal }>;\n\nexport async function raceStrategies<TConfig extends BaseTransactionConfirmationStrategyConfig>(\n    signature: Signature,\n    config: TConfig,\n    getSpecificStrategiesForRace: (config: WithNonNullableAbortSignal<TConfig>) => readonly Promise<unknown>[],\n) {\n    const { abortSignal: callerAbortSignal, commitment, getRecentSignatureConfirmationPromise } = config;\n    callerAbortSignal?.throwIfAborted();\n    const abortController = new AbortController();\n    if (callerAbortSignal) {\n        const handleAbort = () => {\n            abortController.abort();\n        };\n        callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n    }\n    try {\n        const specificStrategies = getSpecificStrategiesForRace({\n            ...config,\n            abortSignal: abortController.signal,\n        });\n        return await safeRace([\n            getRecentSignatureConfirmationPromise({\n                abortSignal: abortController.signal,\n                commitment,\n                signature,\n            }),\n            ...specificStrategies,\n        ]);\n    } finally {\n        abortController.abort();\n    }\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/confirmation-strategy-recent-signature.ts",
    "content": "import { getSolanaErrorFromTransactionError } from '@solana/errors';\nimport { AbortController } from '@solana/event-target-impl';\nimport type { Signature } from '@solana/keys';\nimport { safeRace } from '@solana/promises';\nimport type { GetSignatureStatusesApi, Rpc } from '@solana/rpc';\nimport type { RpcSubscriptions, SignatureNotificationsApi } from '@solana/rpc-subscriptions';\nimport { type Commitment, commitmentComparator } from '@solana/rpc-types';\n\ntype GetRecentSignatureConfirmationPromiseFn = (config: {\n    abortSignal: AbortSignal;\n    /**\n     * The level of commitment the transaction must have achieved in order for the promise to\n     * resolve.\n     */\n    commitment: Commitment;\n    /**\n     * A 64 byte Ed25519 signature, encoded as a base-58 string, that uniquely identifies a\n     * transaction by virtue of being the first or only signature in its list of signatures.\n     */\n    signature: Signature;\n}) => Promise<void>;\n\ntype CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster> = {\n    rpc: Rpc<GetSignatureStatusesApi> & { '~cluster'?: TCluster };\n    rpcSubscriptions: RpcSubscriptions<SignatureNotificationsApi> & { '~cluster'?: TCluster };\n};\n\n/**\n * Creates a promise that resolves when a recently-landed transaction achieves the target\n * confirmation commitment, and throws when the transaction fails with an error.\n *\n * The status of recently-landed transactions is available in the network's status cache. This\n * confirmation strategy will only yield a result if the signature is still in the status cache. To\n * fetch the status of transactions older than those available in the status cache, use the\n * {@link GetSignatureStatusesApi.getSignatureStatuses} method setting the\n * `searchTransactionHistory` configuration param to `true`.\n *\n * @param config\n *\n * @example\n * ```ts\n * import { createRecentSignatureConfirmationPromiseFactory } from '@solana/transaction-confirmation';\n *\n * const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({\n *     rpc,\n *     rpcSubscriptions,\n * });\n * try {\n *     await getRecentSignatureConfirmationPromise({\n *         commitment,\n *         signature,\n *     });\n *     console.log(`The transaction with signature \\`${signature}\\` has achieved a commitment level of \\`${commitment}\\``);\n * } catch (e) {\n *     console.error(`The transaction with signature \\`${signature}\\` failed`, e.cause);\n *     throw e;\n * }\n * ```\n */\nexport function createRecentSignatureConfirmationPromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'devnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'testnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory({\n    rpc,\n    rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<'mainnet'>): GetRecentSignatureConfirmationPromiseFn;\nexport function createRecentSignatureConfirmationPromiseFactory<\n    TCluster extends 'devnet' | 'mainnet' | 'testnet' | void = void,\n>({\n    rpc,\n    rpcSubscriptions,\n}: CreateRecentSignatureConfirmationPromiseFactoryConfig<TCluster>): GetRecentSignatureConfirmationPromiseFn {\n    return async function getRecentSignatureConfirmationPromise({\n        abortSignal: callerAbortSignal,\n        commitment,\n        signature,\n    }) {\n        const abortController = new AbortController();\n        function handleAbort() {\n            abortController.abort();\n        }\n        callerAbortSignal.addEventListener('abort', handleAbort, { signal: abortController.signal });\n        /**\n         * STEP 1: Set up a subscription for status changes to a signature.\n         */\n        const signatureStatusNotifications = await rpcSubscriptions\n            .signatureNotifications(signature, { commitment })\n            .subscribe({ abortSignal: abortController.signal });\n        const signatureDidCommitPromise = (async () => {\n            for await (const signatureStatusNotification of signatureStatusNotifications) {\n                if (signatureStatusNotification.value.err) {\n                    throw getSolanaErrorFromTransactionError(signatureStatusNotification.value.err);\n                } else {\n                    return;\n                }\n            }\n        })();\n        /**\n         * STEP 2: Having subscribed for updates, make a one-shot request for the current status.\n         *         This will only yield a result if the signature is still in the status cache.\n         */\n        const signatureStatusLookupPromise = (async () => {\n            const { value: signatureStatusResults } = await rpc\n                .getSignatureStatuses([signature])\n                .send({ abortSignal: abortController.signal });\n            const signatureStatus = signatureStatusResults[0];\n            if (signatureStatus?.err) {\n                throw getSolanaErrorFromTransactionError(signatureStatus.err);\n            } else if (\n                signatureStatus?.confirmationStatus &&\n                commitmentComparator(signatureStatus.confirmationStatus, commitment) >= 0\n            ) {\n                return;\n            } else {\n                await new Promise(() => {\n                    /* never resolve */\n                });\n            }\n        })();\n        try {\n            return await safeRace([signatureDidCommitPromise, signatureStatusLookupPromise]);\n        } finally {\n            abortController.abort();\n        }\n    };\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/confirmation-strategy-timeout.ts",
    "content": "import type { Commitment } from '@solana/rpc-types';\n\ntype Config = Readonly<{\n    abortSignal: AbortSignal;\n    /**\n     * The timeout promise will throw after 30 seconds when the commitment is `processed`, and 60\n     * seconds otherwise.\n     */\n    commitment: Commitment;\n}>;\n\n/**\n * When no other heuristic exists to infer that a transaction has expired, you can use this promise\n * factory with a commitment level. It throws after 30 seconds when the commitment is `processed`,\n * and 60 seconds otherwise. You would typically race this with another confirmation strategy.\n *\n * @param config\n *\n * @example\n * ```ts\n * import { safeRace } from '@solana/promises';\n * import { getTimeoutPromise } from '@solana/transaction-confirmation';\n *\n * try {\n *     await safeRace([getCustomTransactionConfirmationPromise(/* ... *\\/), getTimeoutPromise({ commitment })]);\n * } catch (e) {\n *     if (e instanceof DOMException && e.name === 'TimeoutError') {\n *         console.log('Could not confirm transaction after a timeout');\n *     }\n *     throw e;\n * }\n * ```\n */\nexport async function getTimeoutPromise({ abortSignal: callerAbortSignal, commitment }: Config) {\n    return await new Promise((_, reject) => {\n        const handleAbort = (e: AbortSignalEventMap['abort']) => {\n            clearTimeout(timeoutId);\n            const abortError = new DOMException((e.target as AbortSignal).reason, 'AbortError');\n            reject(abortError);\n        };\n        callerAbortSignal.addEventListener('abort', handleAbort);\n        const timeoutMs = commitment === 'processed' ? 30_000 : 60_000;\n        const startMs = performance.now();\n        const timeoutId =\n            // We use `setTimeout` instead of `AbortSignal.timeout()` because we want to measure\n            // elapsed time instead of active time.\n            // See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/timeout_static\n            setTimeout(() => {\n                const elapsedMs = performance.now() - startMs;\n                reject(new DOMException(`Timeout elapsed after ${elapsedMs} ms`, 'TimeoutError'));\n            }, timeoutMs);\n    });\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/src/index.ts",
    "content": "/**\n * This package contains utilities for confirming transactions and for building your own transaction\n * confirmation strategies.\n *\n * @packageDocumentation\n */\nexport * from './confirmation-strategy-blockheight';\nexport * from './confirmation-strategy-nonce';\nexport * from './confirmation-strategy-recent-signature';\nexport * from './confirmation-strategy-timeout';\nexport * from './waiters';\n"
  },
  {
    "path": "packages/transaction-confirmation/src/waiters.ts",
    "content": "import { Signature } from '@solana/keys';\nimport {\n    getSignatureFromTransaction,\n    Transaction,\n    TransactionWithBlockhashLifetime,\n    TransactionWithDurableNonceLifetime,\n} from '@solana/transactions';\n\nimport { createBlockHeightExceedencePromiseFactory } from './confirmation-strategy-blockheight';\nimport { createNonceInvalidationPromiseFactory } from './confirmation-strategy-nonce';\nimport { BaseTransactionConfirmationStrategyConfig, raceStrategies } from './confirmation-strategy-racer';\nimport { getTimeoutPromise } from './confirmation-strategy-timeout';\n\nexport type TransactionWithLastValidBlockHeight = Omit<TransactionWithBlockhashLifetime, 'lifetimeConstraint'> & {\n    lifetimeConstraint: Omit<TransactionWithBlockhashLifetime['lifetimeConstraint'], 'blockhash'>;\n};\n\ninterface WaitForDurableNonceTransactionConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n    getNonceInvalidationPromise: ReturnType<typeof createNonceInvalidationPromiseFactory>;\n    transaction: Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n}\n\ninterface WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n    getBlockHeightExceedencePromise: ReturnType<typeof createBlockHeightExceedencePromiseFactory>;\n    transaction: Readonly<Transaction & TransactionWithLastValidBlockHeight>;\n}\n\ninterface WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig extends BaseTransactionConfirmationStrategyConfig {\n    getTimeoutPromise: typeof getTimeoutPromise;\n    /**\n     * A 64 byte Ed25519 signature, encoded as a base-58 string, that uniquely identifies a\n     * transaction by virtue of being the first or only signature in its list of signatures.\n     */\n    signature: Signature;\n}\n\n/**\n * Supply your own confirmation implementations to this function to create a custom nonce\n * transaction confirmation strategy.\n *\n * @example\n * ```ts\n * import { waitForDurableNonceTransactionConfirmation } from '@solana/transaction-confirmation';\n *\n * try {\n *     await waitForDurableNonceTransactionConfirmation({\n *         getNonceInvalidationPromise({ abortSignal, commitment, currentNonceValue, nonceAccountAddress }) {\n *             // Return a promise that rejects when a nonce becomes invalid.\n *         },\n *         getRecentSignatureConfirmationPromise({ abortSignal, commitment, signature }) {\n *             // Return a promise that resolves when a transaction achieves confirmation\n *         },\n *     });\n * } catch (e) {\n *     // Handle errors.\n * }\n * ```\n */\nexport async function waitForDurableNonceTransactionConfirmation(\n    config: WaitForDurableNonceTransactionConfirmationConfig,\n): Promise<void> {\n    await raceStrategies(\n        getSignatureFromTransaction(config.transaction),\n        config,\n        function getSpecificStrategiesForRace({ abortSignal, commitment, getNonceInvalidationPromise, transaction }) {\n            return [\n                getNonceInvalidationPromise({\n                    abortSignal,\n                    commitment,\n                    currentNonceValue: transaction.lifetimeConstraint.nonce,\n                    nonceAccountAddress: transaction.lifetimeConstraint.nonceAccountAddress,\n                }),\n            ];\n        },\n    );\n}\n\n/**\n * Supply your own confirmation implementations to this function to create a custom confirmation\n * strategy for recently-landed transactions.\n *\n * @example\n * ```ts\n * import { waitForRecentTransactionConfirmation } from '@solana/transaction-confirmation';\n *\n * try {\n *     await waitForRecentTransactionConfirmation({\n *         getBlockHeightExceedencePromise({ abortSignal, commitment, lastValidBlockHeight }) {\n *             // Return a promise that rejects when the blockhash's block height has been exceeded\n *         },\n *         getRecentSignatureConfirmationPromise({ abortSignal, commitment, signature }) {\n *             // Return a promise that resolves when a transaction achieves confirmation\n *         },\n *     });\n * } catch (e) {\n *     // Handle errors.\n * }\n * ```\n */\nexport async function waitForRecentTransactionConfirmation(\n    config: WaitForRecentTransactionWithBlockhashLifetimeConfirmationConfig,\n): Promise<void> {\n    await raceStrategies(\n        getSignatureFromTransaction(config.transaction),\n        config,\n        function getSpecificStrategiesForRace({\n            abortSignal,\n            commitment,\n            getBlockHeightExceedencePromise,\n            transaction,\n        }) {\n            return [\n                getBlockHeightExceedencePromise({\n                    abortSignal,\n                    commitment,\n                    lastValidBlockHeight: transaction.lifetimeConstraint.lastValidBlockHeight,\n                }),\n            ];\n        },\n    );\n}\n\n/** @deprecated */\nexport async function waitForRecentTransactionConfirmationUntilTimeout(\n    config: WaitForRecentTransactionWithTimeBasedLifetimeConfirmationConfig,\n): Promise<void> {\n    await raceStrategies(\n        config.signature,\n        config,\n        function getSpecificStrategiesForRace({ abortSignal, commitment, getTimeoutPromise }) {\n            return [\n                getTimeoutPromise({\n                    abortSignal,\n                    commitment,\n                }),\n            ];\n        },\n    );\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2020\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/transaction-confirmation\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/transaction-confirmation/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/transaction-messages/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/transaction-messages/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/transaction-messages/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/transaction-messages/CHANGELOG.md",
    "content": "# @solana/transaction-messages\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-data-structures@6.9.0\n    - @solana/codecs-numbers@6.9.0\n    - @solana/functional@6.9.0\n    - @solana/instructions@6.9.0\n    - @solana/nominal-types@6.9.0\n    - @solana/rpc-types@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-data-structures@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/functional@6.8.0\n    - @solana/instructions@6.8.0\n    - @solana/nominal-types@6.8.0\n    - @solana/rpc-types@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-data-structures@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/functional@6.7.0\n    - @solana/instructions@6.7.0\n    - @solana/nominal-types@6.7.0\n    - @solana/rpc-types@6.7.0\n\n## 6.6.0\n\n### Minor Changes\n\n- [#1496](https://github.com/anza-xyz/kit/pull/1496) [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad) Thanks [@mcintyre94](https://github.com/mcintyre94)! - `compileTransactionMessage` now enforces four Solana protocol limits at compile time, throwing a typed `SolanaError` instead of silently producing a transaction that would be rejected by the network:\n    - More than 64 unique account addresses → `SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES`\n    - More than 12 unique signer addresses → `SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES`\n    - More than 64 instructions → `SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS`\n    - More than 255 accounts in a single instruction → `SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION`\n\n    All four error codes (and their context types / human-readable messages) are exported from `@solana/errors`.\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-data-structures@6.6.0\n    - @solana/codecs-numbers@6.6.0\n    - @solana/instructions@6.6.0\n    - @solana/rpc-types@6.6.0\n    - @solana/functional@6.6.0\n    - @solana/nominal-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-data-structures@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/functional@6.5.0\n    - @solana/instructions@6.5.0\n    - @solana/nominal-types@6.5.0\n    - @solana/rpc-types@6.5.0\n\n## 6.4.0\n\n### Minor Changes\n\n- [#1472](https://github.com/anza-xyz/kit/pull/1472) [`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add legacy and v0 transaction support to compute budget setters and getters. Priority fees are now handled by version-gated helpers: `(get|set)TransactionMessagePriorityFeeLamports` for v1 (total lamports) and `(get|set)TransactionMessageComputeUnitPrice` for legacy/v0 (micro-lamports per compute unit).\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/codecs-data-structures@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/instructions@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/functional@6.4.0\n    - @solana/nominal-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-data-structures@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/functional@6.3.1\n    - @solana/instructions@6.3.1\n    - @solana/nominal-types@6.3.1\n    - @solana/rpc-types@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-data-structures@6.3.0\n    - @solana/codecs-numbers@6.3.0\n    - @solana/instructions@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/functional@6.3.0\n    - @solana/nominal-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`5390602`](https://github.com/anza-xyz/kit/commit/53906024cffc3facb7259ab65ab974b6b1038f56), [`3f4c5f0`](https://github.com/anza-xyz/kit/commit/3f4c5f003e343c21a785e8f339f84c8d6bd3a3b1), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-data-structures@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n    - @solana/instructions@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/functional@6.2.0\n    - @solana/nominal-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`70b1ed8`](https://github.com/anza-xyz/kit/commit/70b1ed83be4c5445f81c600a8ca70127dbdf3463), [`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75), [`7ce7545`](https://github.com/anza-xyz/kit/commit/7ce75455659ace9776042def6774678a81c43a4a)]:\n    - @solana/codecs-data-structures@6.1.0\n    - @solana/errors@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-numbers@6.1.0\n    - @solana/instructions@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/functional@6.1.0\n    - @solana/nominal-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- [#1321](https://github.com/anza-xyz/kit/pull/1321) [`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix a bug in the type of `TransactionMessageWithSigners`\n\n- [#1318](https://github.com/anza-xyz/kit/pull/1318) [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Fix bugs in types of `setTransactionMessageLifetimeUsingBlockhash` and `setTransactionMessageLifetimeUsingDurableNonce`\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-data-structures@6.0.1\n    - @solana/codecs-numbers@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/functional@6.0.1\n    - @solana/instructions@6.0.1\n    - @solana/nominal-types@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Major Changes\n\n- [#1289](https://github.com/anza-xyz/kit/pull/1289) [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Remove the export of BaseTransactionMessage, which was previously deprecated. Use TransactionMessage instead.\n\n### Patch Changes\n\n- [#1287](https://github.com/anza-xyz/kit/pull/1287) [`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor compressTransactionMessageUsingAddressLookupTables to not use BaseTransactionMessage\n\n- [#1288](https://github.com/anza-xyz/kit/pull/1288) [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor transaction-messages package to stop using BaseTransactionMessage\n\n- Updated dependencies []:\n    - @solana/addresses@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-data-structures@6.0.0\n    - @solana/codecs-numbers@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/functional@6.0.0\n    - @solana/instructions@6.0.0\n    - @solana/nominal-types@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-data-structures@5.5.1\n    - @solana/codecs-numbers@5.5.1\n    - @solana/instructions@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/functional@5.5.1\n    - @solana/nominal-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-data-structures@5.5.0\n    - @solana/codecs-numbers@5.5.0\n    - @solana/instructions@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/functional@5.5.0\n    - @solana/nominal-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-data-structures@5.4.0\n    - @solana/codecs-numbers@5.4.0\n    - @solana/nominal-types@5.4.0\n    - @solana/instructions@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/functional@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/errors@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-data-structures@5.3.0\n    - @solana/codecs-numbers@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/functional@5.3.0\n    - @solana/instructions@5.3.0\n    - @solana/nominal-types@5.3.0\n    - @solana/rpc-types@5.3.0\n\n## 5.2.0\n\n### Minor Changes\n\n- [#1139](https://github.com/anza-xyz/kit/pull/1139) [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Return more precise types from transaction message functions\n\n    Deprecate `BaseTransactionMessage` in favour of `TransactionMessage`\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-numbers@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/codecs-data-structures@5.2.0\n    - @solana/instructions@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/functional@5.2.0\n    - @solana/nominal-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#1026](https://github.com/anza-xyz/kit/pull/1026) [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Export BlockhashLifetimeConstraint and NonceLifetimeConstraint\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c)]:\n    - @solana/errors@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/codecs-data-structures@5.1.0\n    - @solana/codecs-numbers@5.1.0\n    - @solana/instructions@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/functional@5.1.0\n    - @solana/nominal-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-data-structures@5.0.0\n    - @solana/codecs-numbers@5.0.0\n    - @solana/instructions@5.0.0\n    - @solana/functional@5.0.0\n    - @solana/nominal-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#871](https://github.com/anza-xyz/kit/pull/871) [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Do not allow decoding transactions with an unsupported version\n\n- [#951](https://github.com/anza-xyz/kit/pull/951) [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013) Thanks [@tanmay5114](https://github.com/tanmay5114)! - `compressTransactionMessageUsingAddressLookupTables()` will no longer convert an account to a lookup table account, if the address of that account is used as a program address anywhere in the transaction.\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df)]:\n    - @solana/errors@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/codecs-data-structures@4.0.0\n    - @solana/codecs-numbers@4.0.0\n    - @solana/instructions@4.0.0\n    - @solana/functional@4.0.0\n    - @solana/nominal-types@4.0.0\n\n## 3.0.0\n\n### Major Changes\n\n- [#691](https://github.com/anza-xyz/kit/pull/691) [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: Removes the following deprecated types and functions: `CompilableTransactionMessage`, `ITransactionMessageWithFeePayer`, `assertIsDurableNonceTransactionMessage` and `isDurableNonceTransaction`. Removes the deprecated `readableIndices` and `writableIndices` properties from the `AddressTableLookup` type — use `readonlyIndexes` and `writableIndexes` respectively instead.\n\n- [#594](https://github.com/anza-xyz/kit/pull/594) [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Extract lifetime token from `CompiledTransactionMessage`. `CompiledTransactionMessage & CompiledTransactionMessageWithLifetime` may now be used to refer to a compiled transaction message with a lifetime token. This enables `CompiledTransactionMessages` to be encoded without the need to specify a mock lifetime token.\n\n### Minor Changes\n\n- [#581](https://github.com/anza-xyz/kit/pull/581) [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Allow transaction messages with no lifetime constraints to be compiled. Renames `TransactionFromCompilableTransactionMessage` and `SetTransactionLifetimeFromCompilableTransactionMessage` type helpers to `TransactionFromTransactionMessage` and `SetTransactionLifetimeFromTransactionMessage` respectively, to reflect that they can now be used with transaction messages that do not have a lifetime constraint.\n\n### Patch Changes\n\n- [#584](https://github.com/anza-xyz/kit/pull/584) [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate `CompilableTransactionMessage` in favour of `TransactionMessage & TransactionMessageWithFeePayer`\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`9205484`](https://github.com/anza-xyz/kit/commit/9205484d33af9426fc9de9594bab204b8f954faf), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0)]:\n    - @solana/instructions@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/codecs-data-structures@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/codecs-numbers@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/functional@3.0.0\n    - @solana/nominal-types@3.0.0\n\n## 2.3.0\n\n### Minor Changes\n\n- [#468](https://github.com/anza-xyz/kit/pull/468) [`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add, remove and forward the `TransactionMessageWithinSizeLimit` and `TransactionWithinSizeLimit` types in all helpers that may affect the size of a transaction or transaction message.\n\n- [#427](https://github.com/anza-xyz/kit/pull/427) [`eb61d94`](https://github.com/anza-xyz/kit/commit/eb61d94786e212fc23778d445a94b86d2b1b024f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Rename `isDurableNonceTransaction` to `isTransactionMessageWithDurableNonceLifetime` and `assertIsDurableNonceTransactionMessage` to `assertIsTransactionMessageWithDurableNonceLifetime` for consistency with the blockhash lifetime. The old names are kept as aliases but marked as deprecated.\n\n- [#426](https://github.com/anza-xyz/kit/pull/426) [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate the `I` prefix of four transaction message types to stay consistent with the rest of them. Namely, the following types are renamed and their old names are marked as deprecated:\n    - `ITransactionMessageWithFeePayer` -> `TransactionMessageWithFeePayer`\n    - `ITransactionMessageWithFeePayerSigner` -> `TransactionMessageWithFeePayerSigner`\n    - `ITransactionMessageWithSigners` -> `TransactionMessageWithSigners`\n    - `ITransactionMessageWithSingleSendingSigner` -> `TransactionMessageWithSingleSendingSigner`\n\n- [#488](https://github.com/anza-xyz/kit/pull/488) [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Remove the `I` prefix on the following types: `IInstruction`, `IInstructionWithAccounts`, `IInstructionWithData`, `IInstructionWithSigners`, `IAccountMeta`, `IAccountLookupMeta` and `IAccountSignerMeta`. The old names are kept as aliases but marked as deprecated.\n\n### Patch Changes\n\n- [#432](https://github.com/anza-xyz/kit/pull/432) [`53e1336`](https://github.com/anza-xyz/kit/commit/53e1336149878c84048e0fde5c7e7ace6cc1e97f) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Keep type safety when appending or prepending instructions to transaction messages\n\n- [#430](https://github.com/anza-xyz/kit/pull/430) [`e6c0568`](https://github.com/anza-xyz/kit/commit/e6c0568ef34fdc04075af27eb102851123a02be0) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Introduce a new `TransactionMessageWithLifetime` type and special Exclude type helpers to remove information from transaction messages\n\n- Updated dependencies [[`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/errors@2.3.0\n    - @solana/instructions@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-data-structures@2.3.0\n    - @solana/codecs-numbers@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/functional@2.3.0\n    - @solana/nominal-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-data-structures@2.2.1\n    - @solana/codecs-numbers@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/functional@2.2.1\n    - @solana/instructions@2.2.1\n    - @solana/nominal-types@2.2.1\n    - @solana/rpc-types@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893), [`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/nominal-types@2.2.0\n    - @solana/addresses@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/instructions@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-data-structures@2.2.0\n    - @solana/codecs-numbers@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/functional@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#433](https://github.com/anza-xyz/kit/pull/433) [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a) Thanks [@steveluscher](https://github.com/steveluscher)! - Deprecated the `writableIndices`/`readableIndices` spellings in transaction messages in favour of `readonlyIndexes`/`writableIndexes`. This will make this shape compatible with the output of the `getTransaction` API that uses those spellings for address lookup table data.\n\n- [#193](https://github.com/anza-xyz/kit/pull/193) [`776e18d`](https://github.com/anza-xyz/kit/commit/776e18d75c759a839608069c61da3f70b775540b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Strip the TransactionMessageWithDurableNonceLifetime type when prepending instructions to a TransactionMessage\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-data-structures@2.1.1\n    - @solana/codecs-numbers@2.1.1\n    - @solana/nominal-types@2.1.1\n    - @solana/instructions@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/functional@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/errors@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Change `data` field of transaction message instructions to use `ReadonlyUint8Array`\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`cfe6910`](https://github.com/anza-xyz/kit/commit/cfe691010a493d06983a8a2728cda9751135906d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-data-structures@2.1.0\n    - @solana/codecs-numbers@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/instructions@2.1.0\n    - @solana/functional@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2969](https://github.com/solana-labs/solana-web3.js/pull/2969) [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function to replace accounts in a transaction message using lookup tables\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3480](https://github.com/solana-labs/solana-web3.js/pull/3480) [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Change `feePayer` type of transaction messages from `Address` to `{ address: Address }`\n\n- [#2550](https://github.com/solana-labs/solana-web3.js/pull/2550) [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor transactions, to separate constructing transaction messages from signing/sending compiled transactions\n\n    A transaction message contains a transaction version and an array of transaction instructions. It may also have a fee payer and a lifetime. Transaction messages can be built up incrementally, for example by adding instructions or a fee payer.\n\n    Transactions represent a compiled transaction message (serialized to an immutable byte array) and a map of signatures for each required signer of the transaction message. These signatures are only valid for the byte array stored in the transaction. Transactions can be signed by updating this map of signatures, and when they have a valid signature for all required signers they can be landed on the network.\n\n    Note that this change essentially splits the previous `@solana/transactions` API in two, with functionality for creating/modifying transaction messages moved to `@solana/transaction-messages`.\n\n- [#2607](https://github.com/solana-labs/solana-web3.js/pull/2607) [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Freeze the instructions and lifetimeConstraint fields within transaction messages\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6), [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-data-structures@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/codecs-numbers@2.0.0\n    - @solana/instructions@2.0.0\n    - @solana/functional@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-data-structures@2.0.0-rc.4\n    - @solana/codecs-numbers@2.0.0-rc.4\n    - @solana/instructions@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/functional@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-data-structures@2.0.0-rc.3\n    - @solana/codecs-numbers@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/functional@2.0.0-rc.3\n    - @solana/instructions@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3480](https://github.com/solana-labs/solana-web3.js/pull/3480) [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Change `feePayer` type of transaction messages from `Address` to `{ address: Address }`\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-data-structures@2.0.0-rc.2\n    - @solana/codecs-numbers@2.0.0-rc.2\n    - @solana/instructions@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n    - @solana/functional@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-data-structures@2.0.0-rc.1\n    - @solana/codecs-numbers@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/functional@2.0.0-rc.1\n    - @solana/instructions@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2969](https://github.com/solana-labs/solana-web3.js/pull/2969) [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function to replace accounts in a transaction message using lookup tables\n\n- Updated dependencies [[`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/errors@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-data-structures@2.0.0-rc.0\n    - @solana/codecs-numbers@2.0.0-rc.0\n    - @solana/instructions@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n    - @solana/functional@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2607](https://github.com/solana-labs/solana-web3.js/pull/2607) [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Freeze the instructions and lifetimeConstraint fields within transaction messages\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs-data-structures@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/codecs-numbers@2.0.0-preview.4\n    - @solana/instructions@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/functional@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2550](https://github.com/solana-labs/solana-web3.js/pull/2550) [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor transactions, to separate constructing transaction messages from signing/sending compiled transactions\n\n    A transaction message contains a transaction version and an array of transaction instructions. It may also have a fee payer and a lifetime. Transaction messages can be built up incrementally, for example by adding instructions or a fee payer.\n\n    Transactions represent a compiled transaction message (serialized to an immutable byte array) and a map of signatures for each required signer of the transaction message. These signatures are only valid for the byte array stored in the transaction. Transactions can be signed by updating this map of signatures, and when they have a valid signature for all required signers they can be landed on the network.\n\n    Note that this change essentially splits the previous `@solana/transactions` API in two, with functionality for creating/modifying transaction messages moved to `@solana/transaction-messages`.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6), [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-data-structures@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/codecs-numbers@2.0.0-preview.3\n    - @solana/instructions@2.0.0-preview.3\n    - @solana/functional@2.0.0-preview.3\n"
  },
  {
    "path": "packages/transaction-messages/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/transaction-messages/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/transactions?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/transactions?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/transactions\n\n# @solana/transaction-messages\n\nThis package contains types and functions for creating transaction messages. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nTransaction messages are built one step at a time using the transform functions offered by this package. To make it more ergonomic to apply consecutive transforms to your transaction messages, consider using a pipelining helper like the one in `@solana/functional`.\n\n```ts\nimport { pipe } from '@solana/functional';\nimport {\n    appendTransactionMessageInstruction,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n} from '@solana/transaction-messages';\n\nconst transferTransactionMessage = pipe(\n    createTransactionMessage({ version: 0 }),\n    m => setTransactionMessageFeePayer(myAddress, m),\n    m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n    m => appendTransactionMessageInstruction(getTransferSolInstruction({ source, destination, amount }), m),\n);\n```\n\n## Creating transaction messages\n\n### Types\n\n#### `TransactionVersion`\n\nAs Solana transactions acquire more capabilities their version will advance. This type is a union of all possible transaction versions.\n\n### Functions\n\n#### `createTransactionMessage()`\n\nGiven a `TransactionVersion` this method will return an empty transaction having the capabilities of that version.\n\n```ts\nimport { createTransactionMessage } from '@solana/transaction-messages';\n\nconst message = createTransactionMessage({ version: 0 });\n```\n\n## Setting the fee payer\n\n### Types\n\n#### `TransactionMessageWithFeePayer`\n\nThis type represents a transaction message for which a fee payer has been declared. A transaction must conform to this type to be compiled and landed on the network.\n\n### Functions\n\n#### `setTransactionMessageFeePayer()`\n\nGiven a base58-encoded address of a system account, this method will return a new transaction message having the same type as the one supplied plus the `TransactionMessageWithFeePayer` type.\n\n```ts\nimport { address } from '@solana/addresses';\nimport { setTransactionMessageFeePayer } from '@solana/transaction-messages';\n\nconst myAddress = address('mpngsFd4tmbUfzDYJayjKZwZcaR7aWb2793J6grLsGu');\nconst txPaidByMe = setTransactionMessageFeePayer(myAddress, tx);\n```\n\n## Defining a transaction message's lifetime\n\nA signed transaction can be only be landed on the network if certain conditions are met:\n\n- It includes the hash of a recent block\n- Or it includes the value of an unused nonce known to the network\n\nThese conditions define a transaction's lifetime, after which it can no longer be landed, even if signed. The lifetime must be added to the transaction message before it is compiled to be sent.\n\n### Types\n\n#### `TransactionMessageWithBlockhashLifetime`\n\nThis type represents a transaction message whose lifetime is defined by the age of the blockhash it includes. Such a transaction can only be landed on the network if the current block height of the network is less than or equal to the value of `TransactionMessageWithBlockhashLifetime['lifetimeConstraint']['lastValidBlockHeight']`.\n\n#### `TransactionMessageWithDurableNonceLifetime`\n\nThis type represents a transaction message whose lifetime is defined by the value of a nonce it includes. Such a transaction can only be landed on the network if the nonce is known to the network and has not already been used to land a different transaction.\n\n#### `Blockhash`\n\nThis type represents a string that is particularly known to be the base58-encoded value of a block.\n\n#### `Nonce`\n\nThis type represents a string that is particularly known to be the base58-encoded value of a nonce.\n\n### Functions\n\n#### `setTransactionMessageLifetimeUsingBlockhash()`\n\nGiven a blockhash and the last block height at which that blockhash is considered usable to land transactions, this method will return a new transaction message having the same type as the one supplied plus the `TransactionMessageWithBlockhashLifetime` type.\n\n```ts\nimport { setTransactionMessageLifetimeUsingBlockhash } from '@solana/transaction-messages';\n\nconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\nconst txMessageWithBlockhashLifetime = setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, txMessage);\n```\n\n#### `setTransactionMessageLifetimeUsingDurableNonce()`\n\nGiven a nonce, the account where the value of the nonce is stored, and the address of the account authorized to consume that nonce, this method will return a new transaction having the same type as the one supplied plus the `TransactionMessageWithDurableNonceLifetime` type. In particular, this method _prepends_ an instruction to the transaction message designed to consume (or &lsquo;advance&rsquo;) the nonce in the same transaction whose lifetime is defined by it.\n\n```ts\nimport { Nonce, setTransactionMessageLifetimeUsingDurableNonce } from '@solana/transaction-messages';\nimport { fetchNonce } from '@solana-program/system';\n\nconst nonceAccountAddress = address('EGtMh4yvXswwHhwVhyPxGrVV2TkLTgUqGodbATEPvojZ');\nconst nonceAuthorityAddress = address('4KD1Rdrd89NG7XbzW3xsX9Aqnx2EExJvExiNme6g9iAT');\n\nconst {\n    data: { blockhash },\n} = await fetchNonce(rpc, nonceAccountAddress);\nconst nonce = blockhash as string as Nonce;\n\nconst durableNonceTransactionMessage = setTransactionMessageLifetimeUsingDurableNonce(\n    { nonce, nonceAccountAddress, nonceAuthorityAddress },\n    transactionMessage,\n);\n```\n\n#### `assertIsBlockhash()`\n\nClient applications primarily deal with blockhashes in the form of base58-encoded strings. Blockhashes returned from the RPC API conform to the type `Blockhash`. You can use a value of that type wherever a blockhash is expected.\n\nFrom time to time you might acquire a string, that you expect to validate as a blockhash, from an untrusted network API or user input. To assert that such an arbitrary string is a base58-encoded blockhash, use the `assertIsBlockhash` function.\n\n```ts\nimport { assertIsBlockhash } from '@solana/transaction-messages';\n\n// Imagine a function that asserts whether a user-supplied blockhash is valid or not.\nfunction handleSubmit() {\n    // We know only that what the user typed conforms to the `string` type.\n    const blockhash: string = blockhashInput.value;\n    try {\n        // If this type assertion function doesn't throw, then\n        // Typescript will upcast `blockhash` to `Blockhash`.\n        assertIsBlockhash(blockhash);\n        // At this point, `blockhash` is a `Blockhash` that can be used with the RPC.\n        const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n    } catch (e) {\n        // `blockhash` turned out not to be a base58-encoded blockhash\n    }\n}\n```\n\n#### `assertIsTransactionMessageWithDurableNonceLifetime()`\n\nFrom time to time you might acquire a transaction message that you expect to be a durable nonce transaction, from an untrusted network API or user input. To assert that such an arbitrary transaction is in fact a durable nonce transaction, use the `assertIsTransactionMessageWithDurableNonceLifetime` function.\n\nSee [`assertIsBlockhash()`](#assertisblockhash) for an example of how to use an assertion function.\n\n## Adding instructions to a transaction message\n\n### Types\n\n#### `Instruction`\n\nThis type represents an instruction to be issued to a program. Objects that conform to this type have a `programAddress` property that is the base58-encoded address of the program in question.\n\n#### `InstructionWithAccounts`\n\nThis type represents an instruction that specifies a list of accounts that a program may read from, write to, or require be signers of the transaction itself. Objects that conform to this type have an `accounts` property that is an array of `AccountMeta | AccountLookupMeta` in the order the instruction requires.\n\n#### `InstructionWithData`\n\nThis type represents an instruction that supplies some data as input to the program. Objects that conform to this type have a `data` property that can be any type of `Uint8Array`.\n\n### Functions\n\n#### `appendTransactionMessageInstruction()`\n\nGiven an instruction, this method will return a new transaction message with that instruction having been added to the end of the list of existing instructions.\n\n```ts\nimport { address } from '@solana/addresses';\nimport { getUtf8Encoder } from '@solana/codecs-strings';\nimport { appendTransactionMessageInstruction } from '@solana/transaction-messages';\n\nconst memoTransactionMessage = appendTransactionMessageInstruction(\n    {\n        data: getUtf8Encoder().encode('Hello world!'),\n        programAddress: address('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),\n    },\n    transactionMessage,\n);\n```\n\nIf you'd like to add multiple instructions to a transaction message at once, you may use the `appendTransactionInstructions` function instead which accepts an array of instructions.\n\n#### `prependTransactionMessageInstruction()`\n\nGiven an instruction, this method will return a new transaction message with that instruction having been added to the beginning of the list of existing instructions.\n\nIf you'd like to prepend multiple instructions to a transaction message at once, you may use the `prependTransactionMessageInstructions` function instead which accepts an array of instructions.\n\nSee [`appendTransactionMessageInstruction()`](#appendtransactioninstruction) for an example of how to use this function.\n\n## Compress transaction message using lookup tables\n\n### Types\n\n#### `AddressesByLookupTableAddress`\n\nThis type represents a mapping of lookup table addresses to the addresses of the accounts that are stored in them.\n\n### Functions\n\n#### `compressTransactionMessageUsingAddressLookupTables`\n\nGiven a transaction message and a mapping of lookup tables to the addresses stored in them, this function will return a new transaction message with the same instructions but with all non-signer accounts that are found in the given lookup tables represented by an `AccountLookupMeta` instead of an `AccountMeta`.\n\nThis means that these accounts will take up less space in the compiled transaction message. This size reduction is most significant when the transaction includes many accounts from the same lookup table.\n\n```ts\nimport { address } from '@solana/addresses';\nimport {\n    AddressesByLookupTableAddress,\n    compressTransactionMessageUsingAddressLookupTables,\n} from '@solana/transaction-messages';\nimport { fetchAddressLookupTable } from '@solana-program/address-lookup-table';\n\nconst lookupTableAddress = address('4QwSwNriKPrz8DLW4ju5uxC2TN5cksJx6tPUPj7DGLAW');\nconst {\n    data: { addresses },\n} = await fetchAddressLookupTable(rpc, lookupTableAddress);\nconst addressesByAddressLookupTable: AddressesByLookupTableAddress = {\n    [lookupTableAddress]: addresses,\n};\n\nconst compressedTransactionMessage = compressTransactionMessageUsingAddressLookupTables(\n    transactionMessage,\n    addressesByAddressLookupTable,\n);\n```\n"
  },
  {
    "path": "packages/transaction-messages/package.json",
    "content": "{\n    \"name\": \"@solana/transaction-messages\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for creating transaction messages\",\n    \"homepage\": \"https://www.solanakit.com/api#solanatransaction-messages\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-data-structures\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/functional\": \"workspace:*\",\n        \"@solana/instructions\": \"workspace:*\",\n        \"@solana/nominal-types\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\"\n    },\n    \"devDependencies\": {\n        \"@solana/codecs-strings\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/blockhash-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { getBase58Encoder } from '@solana/codecs-strings';\nimport type { Blockhash } from '@solana/rpc-types';\n\nimport {\n    assertIsTransactionMessageWithBlockhashLifetime,\n    setTransactionMessageLifetimeUsingBlockhash,\n    TransactionMessageWithBlockhashLifetime,\n} from '../blockhash';\nimport { TransactionMessage } from '../transaction-message';\n\njest.mock('@solana/codecs-strings', () => ({\n    ...jest.requireActual('@solana/codecs-strings'),\n    getBase58Encoder: jest.fn(),\n}));\n\n// real implementations\nconst originalBase58Module = jest.requireActual('@solana/codecs-strings');\nconst originalGetBase58Encoder = originalBase58Module.getBase58Encoder();\n\ndescribe('assertIsTransactionMessageWithBlockhashLifetime', () => {\n    beforeEach(() => {\n        // use real implementation\n        jest.mocked(getBase58Encoder).mockReturnValue(originalGetBase58Encoder);\n    });\n    it('throws for a transaction with no lifetime constraint', () => {\n        const transaction: TransactionMessage = {\n            instructions: [],\n            version: 0,\n        };\n        expect(() => assertIsTransactionMessageWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a durable nonce constraint', () => {\n        const transaction = {\n            instructions: [],\n            lifetimeConstraint: {\n                nonce: 'abcd',\n            },\n            version: 0,\n        } as TransactionMessage;\n        expect(() => assertIsTransactionMessageWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a blockhash but no lastValidBlockHeight in lifetimeConstraint', () => {\n        const transaction = {\n            instructions: [],\n            lifetimeConstraint: {\n                blockhash: '11111111111111111111111111111111',\n            },\n            version: 0,\n        } as TransactionMessage;\n        expect(() => assertIsTransactionMessageWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a lastValidBlockHeight but no blockhash in lifetimeConstraint', () => {\n        const transaction = {\n            instructions: [],\n            lifetimeConstraint: {\n                lastValidBlockHeight: 1234n,\n            },\n            version: 0,\n        } as TransactionMessage;\n        expect(() => assertIsTransactionMessageWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a blockhash lifetime but an invalid blockhash value', () => {\n        const transaction = {\n            instructions: [],\n            lifetimeConstraint: {\n                blockhash: 'not a valid blockhash value',\n            },\n            version: 0,\n        } as TransactionMessage;\n        expect(() => assertIsTransactionMessageWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('does not throw for a transaction with a valid blockhash lifetime constraint', () => {\n        const transaction = {\n            instructions: [],\n            lifetimeConstraint: {\n                blockhash: '11111111111111111111111111111111',\n                lastValidBlockHeight: 1234n,\n            },\n            version: 0,\n        } as TransactionMessage;\n        expect(() => assertIsTransactionMessageWithBlockhashLifetime(transaction)).not.toThrow();\n    });\n});\n\ndescribe('setTransactionMessageLifetimeUsingBlockhash', () => {\n    let baseTx: TransactionMessage;\n    const BLOCKHASH_CONSTRAINT_A = {\n        blockhash: 'F7vmkY3DTaxfagttWjQweib42b6ZHADSx94Tw8gHx3W7' as Blockhash,\n        lastValidBlockHeight: 123n,\n    };\n    const BLOCKHASH_CONSTRAINT_B = {\n        blockhash: '6bjroqDcZgTv6Vavhqf81oBHTv3aMnX19UTB51YhAZnN' as Blockhash,\n        lastValidBlockHeight: 123n,\n    };\n    beforeEach(() => {\n        baseTx = {\n            instructions: [],\n            version: 0,\n        };\n    });\n    it('sets the lifetime constraint on the transaction to the supplied blockhash lifetime constraint', () => {\n        const txWithBlockhashLifetimeConstraint = setTransactionMessageLifetimeUsingBlockhash(\n            BLOCKHASH_CONSTRAINT_A,\n            baseTx,\n        );\n        expect(txWithBlockhashLifetimeConstraint).toHaveProperty('lifetimeConstraint', BLOCKHASH_CONSTRAINT_A);\n    });\n    describe('given a transaction with a blockhash lifetime already set', () => {\n        let txWithBlockhashLifetimeConstraint: TransactionMessage & TransactionMessageWithBlockhashLifetime;\n        beforeEach(() => {\n            txWithBlockhashLifetimeConstraint = {\n                ...baseTx,\n                lifetimeConstraint: BLOCKHASH_CONSTRAINT_A,\n            };\n        });\n        it('sets the new blockhash lifetime constraint on the transaction when it differs from the existing one', () => {\n            const txWithBlockhashLifetimeConstraintB = setTransactionMessageLifetimeUsingBlockhash(\n                BLOCKHASH_CONSTRAINT_B,\n                txWithBlockhashLifetimeConstraint,\n            );\n            expect(txWithBlockhashLifetimeConstraintB).toHaveProperty('lifetimeConstraint', BLOCKHASH_CONSTRAINT_B);\n        });\n        it('returns the original transaction when trying to set the same blockhash lifetime constraint again', () => {\n            const txWithSameBlockhashLifetimeConstraint = setTransactionMessageLifetimeUsingBlockhash(\n                BLOCKHASH_CONSTRAINT_A,\n                txWithBlockhashLifetimeConstraint,\n            );\n            expect(txWithBlockhashLifetimeConstraint).toBe(txWithSameBlockhashLifetimeConstraint);\n        });\n    });\n    it('freezes the object', () => {\n        const txWithBlockhashLifetimeConstraint = setTransactionMessageLifetimeUsingBlockhash(\n            BLOCKHASH_CONSTRAINT_A,\n            baseTx,\n        );\n        expect(txWithBlockhashLifetimeConstraint).toBeFrozenObject();\n    });\n    it('freezes the blockhash constraint', () => {\n        const txWithBlockhashLifetimeConstraint = setTransactionMessageLifetimeUsingBlockhash(\n            BLOCKHASH_CONSTRAINT_A,\n            baseTx,\n        );\n        expect(txWithBlockhashLifetimeConstraint.lifetimeConstraint).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/compress-transaction-message-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport { AccountLookupMeta, AccountMeta, AccountRole, Instruction } from '@solana/instructions';\n\nimport { AddressesByLookupTableAddress } from '../addresses-by-lookup-table-address';\nimport { compressTransactionMessageUsingAddressLookupTables } from '../compress-transaction-message';\nimport { createTransactionMessage } from '../create-transaction-message';\nimport { appendTransactionMessageInstruction, appendTransactionMessageInstructions } from '../instructions';\n\nconst programAddress = 'program' as Address;\n\ndescribe('compressTransactionMessageUsingAddressLookupTables', () => {\n    it('should replace a read-only account with a lookup table', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [\n                        {\n                            address,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        const expectedLookupMeta: AccountLookupMeta = {\n            address,\n            addressIndex: 0,\n            lookupTableAddress,\n            role: AccountRole.READONLY,\n        };\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual(expectedLookupMeta);\n    });\n\n    it('should replace a writable account with a lookup table', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [\n                        {\n                            address,\n                            role: AccountRole.WRITABLE,\n                        },\n                    ],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        const expectedLookupMeta: AccountLookupMeta = {\n            address,\n            addressIndex: 0,\n            lookupTableAddress,\n            role: AccountRole.WRITABLE,\n        };\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual(expectedLookupMeta);\n    });\n\n    it('should not replace a read-only signer account with a lookup table', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const accountMeta: AccountMeta = {\n            address,\n            role: AccountRole.READONLY_SIGNER,\n        };\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [accountMeta],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual(accountMeta);\n    });\n\n    it('should not replace a writable signer account with a lookup table', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const accountMeta: AccountMeta = {\n            address,\n            role: AccountRole.WRITABLE_SIGNER,\n        };\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [accountMeta],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual(accountMeta);\n    });\n\n    it('should not modify an account that is already from a lookup table', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const lookupMeta: AccountLookupMeta = {\n            address,\n            addressIndex: 0,\n            lookupTableAddress,\n            role: AccountRole.READONLY,\n        };\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [lookupMeta],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual(lookupMeta);\n    });\n\n    it('should replace multiple accounts with different addresses from a lookup table', () => {\n        const address1 = 'address1' as Address;\n        const address2 = 'address2' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [\n                        {\n                            address: address1,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: address2,\n                            role: AccountRole.WRITABLE,\n                        },\n                    ],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address1, address2],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        const expectedLookupMeta1: AccountLookupMeta = {\n            address: address1,\n            addressIndex: 0,\n            lookupTableAddress,\n            role: AccountRole.READONLY,\n        };\n\n        const expectedLookupMeta2: AccountLookupMeta = {\n            address: address2,\n            addressIndex: 1,\n            lookupTableAddress,\n            role: AccountRole.WRITABLE,\n        };\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual(expectedLookupMeta1);\n        expect(result.instructions[0].accounts![1]).toStrictEqual(expectedLookupMeta2);\n    });\n\n    it('should replace the same account in multiple instructions from a lookup table', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(\n            createTransactionMessage({ version: 0 }),\n            tx =>\n                appendTransactionMessageInstruction(\n                    {\n                        accounts: [\n                            {\n                                address,\n                                role: AccountRole.READONLY,\n                            },\n                        ],\n                        programAddress,\n                    },\n                    tx,\n                ),\n            tx =>\n                appendTransactionMessageInstruction(\n                    {\n                        accounts: [\n                            {\n                                address,\n                                role: AccountRole.READONLY,\n                            },\n                        ],\n                        programAddress,\n                    },\n                    tx,\n                ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        const expectedLookupMeta: AccountLookupMeta = {\n            address: address,\n            addressIndex: 0,\n            lookupTableAddress,\n            role: AccountRole.READONLY,\n        };\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual(expectedLookupMeta);\n        expect(result.instructions[1].accounts![0]).toStrictEqual(expectedLookupMeta);\n    });\n\n    it('should replace multiple accounts with different addresses from different lookup tables', () => {\n        const address1 = 'address1' as Address;\n        const address2 = 'address2' as Address;\n        const lookupTableAddress1 = 'lookupTableAddress1' as Address;\n        const lookupTableAddress2 = 'lookupTableAddress2' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [\n                        {\n                            address: address1,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: address2,\n                            role: AccountRole.WRITABLE,\n                        },\n                    ],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress1]: [address1],\n            [lookupTableAddress2]: [address2],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        const expectedLookupMeta1: AccountLookupMeta = {\n            address: address1,\n            addressIndex: 0,\n            lookupTableAddress: lookupTableAddress1,\n            role: AccountRole.READONLY,\n        };\n\n        const expectedLookupMeta2: AccountLookupMeta = {\n            address: address2,\n            addressIndex: 0,\n            lookupTableAddress: lookupTableAddress2,\n            role: AccountRole.WRITABLE,\n        };\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual(expectedLookupMeta1);\n        expect(result.instructions[0].accounts![1]).toStrictEqual(expectedLookupMeta2);\n    });\n\n    it('should not replace an account that is not in lookup tables', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [\n                        {\n                            address,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: ['abc' as Address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual({\n            address,\n            role: AccountRole.READONLY,\n        });\n    });\n\n    it('should replace some accounts if there is a mix of signers and not', () => {\n        const address1 = 'address1' as Address;\n        const address2 = 'address2' as Address;\n\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(\n            createTransactionMessage({ version: 0 }),\n            tx =>\n                // address1 and address2 are non-signers in this instruction\n                appendTransactionMessageInstruction(\n                    {\n                        accounts: [\n                            {\n                                address: address1,\n                                role: AccountRole.READONLY,\n                            },\n                            {\n                                address: address2,\n                                role: AccountRole.WRITABLE,\n                            },\n                        ],\n                        programAddress,\n                    },\n                    tx,\n                ),\n            // address2 is a signer in this instruction\n            tx =>\n                appendTransactionMessageInstruction(\n                    {\n                        accounts: [\n                            {\n                                address: address1,\n                                role: AccountRole.READONLY,\n                            },\n                            {\n                                address: address2,\n                                role: AccountRole.READONLY_SIGNER,\n                            },\n                        ],\n                        programAddress,\n                    },\n                    tx,\n                ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address1, address2],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result.instructions[0].accounts![0]).toStrictEqual({\n            address: address1,\n            addressIndex: 0,\n            lookupTableAddress,\n            role: AccountRole.READONLY,\n        });\n\n        // address2 uses the LUT in the first instruction\n        expect(result.instructions[0].accounts![1]).toStrictEqual({\n            address: address2,\n            addressIndex: 1,\n            lookupTableAddress,\n            role: AccountRole.WRITABLE,\n        });\n\n        expect(result.instructions[1].accounts![0]).toStrictEqual({\n            address: address1,\n            addressIndex: 0,\n            lookupTableAddress,\n            role: AccountRole.READONLY,\n        });\n\n        // but not the second\n        expect(result.instructions[1].accounts![1]).toStrictEqual({\n            address: address2,\n            role: AccountRole.READONLY_SIGNER,\n        });\n    });\n\n    it('should return the input instruction if no accounts are replaced', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const instruction: Instruction = {\n            accounts: [\n                {\n                    address,\n                    role: AccountRole.READONLY_SIGNER,\n                },\n            ],\n            programAddress,\n        };\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(instruction, tx),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result.instructions[0]).toBe(instruction);\n    });\n\n    it('should return the input transaction message if no accounts are replaced in any instruction', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstructions(\n                [\n                    {\n                        accounts: [\n                            {\n                                address,\n                                role: AccountRole.READONLY_SIGNER,\n                            },\n                        ],\n                        programAddress,\n                    },\n                    {\n                        accounts: [\n                            {\n                                address,\n                                role: AccountRole.READONLY_SIGNER,\n                            },\n                        ],\n                        programAddress,\n                    },\n                ],\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result).toBe(transactionMessage);\n    });\n\n    it('should freeze the returned transaction message', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [\n                        {\n                            address,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result).toBeFrozenObject();\n    });\n\n    it('should freeze the instructions in the returned transaction message', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [\n                        {\n                            address,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result.instructions[0]).toBeFrozenObject();\n    });\n\n    it('should freeze the replaced accounts in the returned transaction message', () => {\n        const address = 'address1' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        const transactionMessage = pipe(createTransactionMessage({ version: 0 }), tx =>\n            appendTransactionMessageInstruction(\n                {\n                    accounts: [\n                        {\n                            address,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    programAddress,\n                },\n                tx,\n            ),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [address],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        expect(result.instructions[0].accounts![0]).toBeFrozenObject();\n    });\n\n    it('should not replace a program address that appears as an account in another instruction', () => {\n        const programAddressA = 'programA' as Address;\n        const programAddressB = 'programB' as Address;\n        const lookupTableAddress = 'lookupTableAddress' as Address;\n\n        // Create a transaction and append two instructions sequentially\n        const transactionMessage = appendTransactionMessageInstructions(\n            [\n                {\n                    accounts: [] as AccountMeta[],\n                    programAddress: programAddressA,\n                },\n                {\n                    accounts: [\n                        {\n                            address: programAddressA,\n                            role: AccountRole.READONLY,\n                        },\n                    ] as AccountMeta[],\n                    programAddress: programAddressB,\n                },\n            ],\n            createTransactionMessage({ version: 0 }),\n        );\n\n        const lookupTables: AddressesByLookupTableAddress = {\n            [lookupTableAddress]: [programAddressA],\n        };\n\n        const result = compressTransactionMessageUsingAddressLookupTables(transactionMessage, lookupTables);\n\n        // The first instruction’s programAddressA should be excluded from compression,\n        // even though it exists in the lookup table.\n        expect(result.instructions[1].accounts![0]).toStrictEqual({\n            address: programAddressA,\n            role: AccountRole.READONLY,\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/compute-budget-instruction-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    COMPUTE_BUDGET_PROGRAM_ADDRESS,\n    getComputeUnitLimitFromInstructionData,\n    getHeapSizeFromInstructionData,\n    getLoadedAccountsDataSizeLimitFromInstructionData,\n    getPriorityFeeFromInstructionData,\n    getRequestHeapFrameInstruction,\n    getSetComputeUnitLimitInstruction,\n    getSetComputeUnitPriceInstruction,\n    getSetLoadedAccountsDataSizeLimitInstruction,\n    isRequestHeapFrameInstruction,\n    isSetComputeUnitLimitInstruction,\n    isSetComputeUnitPriceInstruction,\n    isSetLoadedAccountsDataSizeLimitInstruction,\n} from '../compute-budget-instruction';\n\ndescribe('SetComputeUnitLimit', () => {\n    describe('getSetComputeUnitLimitInstruction', () => {\n        it('creates an instruction with the correct program address', () => {\n            const ix = getSetComputeUnitLimitInstruction(200_000);\n            expect(ix.programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n        });\n\n        it('creates an instruction with discriminator 2 and u32 value', () => {\n            const ix = getSetComputeUnitLimitInstruction(200_000);\n            expect(ix.data[0]).toBe(2);\n            expect(ix.data.byteLength).toBe(5); // 1 byte discriminator + 4 bytes u32\n        });\n\n        it('encodes the value correctly', () => {\n            const ix = getSetComputeUnitLimitInstruction(200_000);\n            expect(getComputeUnitLimitFromInstructionData(ix.data)).toBe(200_000);\n        });\n    });\n\n    describe('isSetComputeUnitLimitInstruction', () => {\n        it('returns true for a SetComputeUnitLimit instruction', () => {\n            const ix = getSetComputeUnitLimitInstruction(200_000);\n            expect(isSetComputeUnitLimitInstruction(ix)).toBe(true);\n        });\n\n        it('returns false for a different compute budget instruction', () => {\n            const ix = getSetComputeUnitPriceInstruction(100n);\n            expect(isSetComputeUnitLimitInstruction(ix)).toBe(false);\n        });\n    });\n});\n\ndescribe('SetComputeUnitPrice', () => {\n    describe('getSetComputeUnitPriceInstruction', () => {\n        it('creates an instruction with the correct program address', () => {\n            const ix = getSetComputeUnitPriceInstruction(100n);\n            expect(ix.programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n        });\n\n        it('creates an instruction with discriminator 3 and u64 value', () => {\n            const ix = getSetComputeUnitPriceInstruction(100n);\n            expect(ix.data[0]).toBe(3);\n            expect(ix.data.byteLength).toBe(9); // 1 byte discriminator + 8 bytes u64\n        });\n\n        it('encodes the value correctly', () => {\n            const ix = getSetComputeUnitPriceInstruction(5_000n);\n            expect(getPriorityFeeFromInstructionData(ix.data)).toBe(5_000n);\n        });\n\n        it('handles zero', () => {\n            const ix = getSetComputeUnitPriceInstruction(0n);\n            expect(getPriorityFeeFromInstructionData(ix.data)).toBe(0n);\n        });\n\n        it('handles large u64 values', () => {\n            const largeValue = 2n ** 63n;\n            const ix = getSetComputeUnitPriceInstruction(largeValue);\n            expect(getPriorityFeeFromInstructionData(ix.data)).toBe(largeValue);\n        });\n    });\n\n    describe('isSetComputeUnitPriceInstruction', () => {\n        it('returns true for a SetComputeUnitPrice instruction', () => {\n            const ix = getSetComputeUnitPriceInstruction(100n);\n            expect(isSetComputeUnitPriceInstruction(ix)).toBe(true);\n        });\n\n        it('returns false for a different compute budget instruction', () => {\n            const ix = getSetComputeUnitLimitInstruction(200_000);\n            expect(isSetComputeUnitPriceInstruction(ix)).toBe(false);\n        });\n    });\n});\n\ndescribe('RequestHeapFrame', () => {\n    describe('getRequestHeapFrameInstruction', () => {\n        it('creates an instruction with the correct program address', () => {\n            const ix = getRequestHeapFrameInstruction(256_000);\n            expect(ix.programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n        });\n\n        it('creates an instruction with discriminator 1 and u32 value', () => {\n            const ix = getRequestHeapFrameInstruction(256_000);\n            expect(ix.data[0]).toBe(1);\n            expect(ix.data.byteLength).toBe(5); // 1 byte discriminator + 4 bytes u32\n        });\n\n        it('encodes the value correctly', () => {\n            const ix = getRequestHeapFrameInstruction(256_000);\n            expect(getHeapSizeFromInstructionData(ix.data)).toBe(256_000);\n        });\n    });\n\n    describe('isRequestHeapFrameInstruction', () => {\n        it('returns true for a RequestHeapFrame instruction', () => {\n            const ix = getRequestHeapFrameInstruction(256_000);\n            expect(isRequestHeapFrameInstruction(ix)).toBe(true);\n        });\n\n        it('returns false for a different compute budget instruction', () => {\n            const ix = getSetComputeUnitLimitInstruction(200_000);\n            expect(isRequestHeapFrameInstruction(ix)).toBe(false);\n        });\n    });\n});\n\ndescribe('SetLoadedAccountsDataSizeLimit', () => {\n    describe('getSetLoadedAccountsDataSizeLimitInstruction', () => {\n        it('creates an instruction with the correct program address', () => {\n            const ix = getSetLoadedAccountsDataSizeLimitInstruction(64_000);\n            expect(ix.programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n        });\n\n        it('creates an instruction with discriminator 4 and u32 value', () => {\n            const ix = getSetLoadedAccountsDataSizeLimitInstruction(64_000);\n            expect(ix.data[0]).toBe(4);\n            expect(ix.data.byteLength).toBe(5); // 1 byte discriminator + 4 bytes u32\n        });\n\n        it('encodes the value correctly', () => {\n            const ix = getSetLoadedAccountsDataSizeLimitInstruction(64_000);\n            expect(getLoadedAccountsDataSizeLimitFromInstructionData(ix.data)).toBe(64_000);\n        });\n    });\n\n    describe('isSetLoadedAccountsDataSizeLimitInstruction', () => {\n        it('returns true for a SetLoadedAccountsDataSizeLimit instruction', () => {\n            const ix = getSetLoadedAccountsDataSizeLimitInstruction(64_000);\n            expect(isSetLoadedAccountsDataSizeLimitInstruction(ix)).toBe(true);\n        });\n\n        it('returns false for a different compute budget instruction', () => {\n            const ix = getSetComputeUnitLimitInstruction(200_000);\n            expect(isSetLoadedAccountsDataSizeLimitInstruction(ix)).toBe(false);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/compute-unit-limit-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\n\nimport {\n    COMPUTE_BUDGET_PROGRAM_ADDRESS,\n    getComputeUnitLimitFromInstructionData,\n    getSetComputeUnitLimitInstruction,\n} from '../compute-budget-instruction';\nimport { getTransactionMessageComputeUnitLimit, setTransactionMessageComputeUnitLimit } from '../compute-unit-limit';\nimport { TransactionMessage } from '../transaction-message';\n\nconst COMPUTE_UNIT_LIMIT_A = 200_000;\nconst COMPUTE_UNIT_LIMIT_B = 400_000;\n\ndescribe('setTransactionMessageComputeUnitLimit', () => {\n    describe('given a v1 transaction', () => {\n        const baseTx: TransactionMessage & { version: 1 } = { instructions: [], version: 1 };\n\n        it('sets the compute unit limit on the transaction', () => {\n            const txWithLimit = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n            expect(txWithLimit).toHaveProperty('config', { computeUnitLimit: COMPUTE_UNIT_LIMIT_A });\n        });\n\n        it('freezes the transaction object', () => {\n            const txWithLimit = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n            expect(txWithLimit).toBeFrozenObject();\n        });\n\n        it('freezes the config object', () => {\n            const txWithLimit = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n            expect(txWithLimit.config).toBeFrozenObject();\n        });\n\n        describe('given a transaction with an existing config', () => {\n            const txWithConfig = {\n                ...baseTx,\n                config: {\n                    heapSize: 1_000,\n                    priorityFeeLamports: 5_000n,\n                },\n            };\n\n            it('sets the compute unit limit while preserving other config properties', () => {\n                const txWithLimit = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, txWithConfig);\n                expect(txWithLimit.config).toMatchObject({\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    heapSize: 1_000,\n                    priorityFeeLamports: 5_000n,\n                });\n            });\n\n            it('returns the same reference when setting the same compute unit limit', () => {\n                const txWithLimitA = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n                const txWithSameLimit = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, txWithLimitA);\n                expect(txWithLimitA).toBe(txWithSameLimit);\n            });\n\n            it('returns a new reference when setting a different compute unit limit', () => {\n                const txWithLimitA = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n                const txWithLimitB = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_B, txWithLimitA);\n                expect(txWithLimitA).not.toBe(txWithLimitB);\n                expect(txWithLimitB.config).toHaveProperty('computeUnitLimit', COMPUTE_UNIT_LIMIT_B);\n            });\n        });\n\n        describe('empty config normalization', () => {\n            it('removes config when setting to undefined as only property', () => {\n                const txWithLimit = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n                const txWithoutConfig = setTransactionMessageComputeUnitLimit(undefined, txWithLimit);\n                expect(txWithoutConfig).not.toHaveProperty('config');\n            });\n\n            it('preserves config when setting to undefined with other properties present', () => {\n                const txWithConfig = {\n                    ...baseTx,\n                    config: {\n                        computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                        heapSize: 1_000,\n                    },\n                };\n                const txWithoutLimit = setTransactionMessageComputeUnitLimit(undefined, txWithConfig);\n                expect(txWithoutLimit).toHaveProperty('config', {\n                    computeUnitLimit: undefined,\n                    heapSize: 1_000,\n                });\n            });\n        });\n    });\n\n    describe.each([{ version: 'legacy' as const }, { version: 0 as const }])(\n        'given a $version transaction',\n        ({ version }) => {\n            const baseTx: TransactionMessage = { instructions: [], version };\n\n            it('appends a SetComputeUnitLimit instruction', () => {\n                const result = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n                expect(result.instructions).toHaveLength(1);\n                expect(result.instructions[0].programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n                expect(getComputeUnitLimitFromInstructionData(result.instructions[0].data as Uint8Array)).toBe(\n                    COMPUTE_UNIT_LIMIT_A,\n                );\n            });\n\n            it('freezes the transaction object', () => {\n                const result = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n                expect(result).toBeFrozenObject();\n            });\n\n            it('freezes the instructions array', () => {\n                const result = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n                expect(result.instructions).toBeFrozenObject();\n            });\n\n            it('appends the instruction after existing instructions', () => {\n                const existingIx = { programAddress: '11111111111111111111111111111111' as Address };\n                const txWithIx: TransactionMessage = { instructions: [existingIx], version };\n                const result = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, txWithIx);\n                expect(result.instructions).toHaveLength(2);\n                expect(result.instructions[0]).toBe(existingIx);\n                expect(result.instructions[1].programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n            });\n\n            describe('given a transaction with an existing SetComputeUnitLimit instruction', () => {\n                const existingIx = Object.freeze(getSetComputeUnitLimitInstruction(COMPUTE_UNIT_LIMIT_A));\n                const otherIx = Object.freeze({ programAddress: '11111111111111111111111111111111' as Address });\n                const txWithExisting = { instructions: [otherIx, existingIx] as const, version };\n\n                it('replaces the existing instruction in-place when setting a different value', () => {\n                    const result = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_B, txWithExisting);\n                    expect(result.instructions).toHaveLength(2);\n                    expect(result.instructions[0]).toBe(otherIx);\n                    expect(getComputeUnitLimitFromInstructionData(result.instructions[1].data)).toBe(\n                        COMPUTE_UNIT_LIMIT_B,\n                    );\n                });\n\n                it('returns the same reference when setting the same value', () => {\n                    const result = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, txWithExisting);\n                    expect(result).toBe(txWithExisting);\n                });\n\n                it('returns a new reference when setting a different value', () => {\n                    const result = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_B, txWithExisting);\n                    expect(result).not.toBe(txWithExisting);\n                });\n            });\n\n            describe('setting to undefined', () => {\n                it('returns the same reference when no instruction exists', () => {\n                    const result = setTransactionMessageComputeUnitLimit(undefined, baseTx);\n                    expect(result).toBe(baseTx);\n                });\n\n                it('removes the instruction when one exists', () => {\n                    const txWithIx = setTransactionMessageComputeUnitLimit(COMPUTE_UNIT_LIMIT_A, baseTx);\n                    const result = setTransactionMessageComputeUnitLimit(undefined, txWithIx);\n                    expect(result.instructions).toHaveLength(0);\n                });\n\n                it('preserves other instructions when removing', () => {\n                    const otherIx = { programAddress: '11111111111111111111111111111111' as Address };\n                    const cuIx = getSetComputeUnitLimitInstruction(COMPUTE_UNIT_LIMIT_A);\n                    const txWithIxs: TransactionMessage = {\n                        instructions: [cuIx, otherIx],\n                        version,\n                    };\n                    const result = setTransactionMessageComputeUnitLimit(undefined, txWithIxs);\n                    expect(result.instructions).toHaveLength(1);\n                    expect(result.instructions[0]).toBe(otherIx);\n                });\n            });\n        },\n    );\n});\n\ndescribe('getTransactionMessageComputeUnitLimit', () => {\n    describe('given a v1 transaction', () => {\n        it('returns undefined without config', () => {\n            const tx: TransactionMessage = { instructions: [], version: 1 };\n            expect(getTransactionMessageComputeUnitLimit(tx)).toBeUndefined();\n        });\n\n        it('returns the value from config', () => {\n            const tx: TransactionMessage & { version: 1 } = {\n                config: { computeUnitLimit: COMPUTE_UNIT_LIMIT_A },\n                instructions: [],\n                version: 1,\n            };\n            expect(getTransactionMessageComputeUnitLimit(tx)).toBe(COMPUTE_UNIT_LIMIT_A);\n        });\n    });\n\n    describe.each([{ version: 'legacy' as const }, { version: 0 as const }])(\n        'given a $version transaction',\n        ({ version }) => {\n            it('returns undefined without instruction', () => {\n                const tx: TransactionMessage = { instructions: [], version };\n                expect(getTransactionMessageComputeUnitLimit(tx)).toBeUndefined();\n            });\n\n            it('returns the value from instruction', () => {\n                const tx: TransactionMessage = {\n                    instructions: [getSetComputeUnitLimitInstruction(COMPUTE_UNIT_LIMIT_A)],\n                    version,\n                };\n                expect(getTransactionMessageComputeUnitLimit(tx)).toBe(COMPUTE_UNIT_LIMIT_A);\n            });\n        },\n    );\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/compute-unit-price-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\n\nimport {\n    COMPUTE_BUDGET_PROGRAM_ADDRESS,\n    getPriorityFeeFromInstructionData,\n    getSetComputeUnitPriceInstruction,\n} from '../compute-budget-instruction';\nimport { getTransactionMessageComputeUnitPrice, setTransactionMessageComputeUnitPrice } from '../compute-unit-price';\nimport { TransactionMessage } from '../transaction-message';\n\ntype LegacyOrV0TransactionMessage = Extract<TransactionMessage, { version: 'legacy' | 0 }>;\n\nconst COMPUTE_UNIT_PRICE_A = 5_000n;\nconst COMPUTE_UNIT_PRICE_B = 10_000n;\n\ndescribe('setTransactionMessageComputeUnitPrice', () => {\n    describe.each([{ version: 'legacy' as const }, { version: 0 as const }])(\n        'given a $version transaction',\n        ({ version }) => {\n            const baseTx: LegacyOrV0TransactionMessage = { instructions: [], version };\n\n            it('appends a SetComputeUnitPrice instruction', () => {\n                const result = setTransactionMessageComputeUnitPrice(COMPUTE_UNIT_PRICE_A, baseTx);\n                expect(result.instructions).toHaveLength(1);\n                expect(result.instructions[0].programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n                expect(getPriorityFeeFromInstructionData(result.instructions[0].data as Uint8Array)).toBe(\n                    COMPUTE_UNIT_PRICE_A,\n                );\n            });\n\n            it('freezes the transaction object', () => {\n                const result = setTransactionMessageComputeUnitPrice(COMPUTE_UNIT_PRICE_A, baseTx);\n                expect(result).toBeFrozenObject();\n            });\n\n            it('freezes the instructions array', () => {\n                const result = setTransactionMessageComputeUnitPrice(COMPUTE_UNIT_PRICE_A, baseTx);\n                expect(result.instructions).toBeFrozenObject();\n            });\n\n            it('appends the instruction after existing instructions', () => {\n                const existingIx = { programAddress: '11111111111111111111111111111111' as Address };\n                const txWithIx: LegacyOrV0TransactionMessage = { instructions: [existingIx], version };\n                const result = setTransactionMessageComputeUnitPrice(COMPUTE_UNIT_PRICE_A, txWithIx);\n                expect(result.instructions).toHaveLength(2);\n                expect(result.instructions[0]).toBe(existingIx);\n                expect(result.instructions[1].programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n            });\n\n            describe('given a transaction with an existing SetComputeUnitPrice instruction', () => {\n                const existingIx = Object.freeze(getSetComputeUnitPriceInstruction(COMPUTE_UNIT_PRICE_A));\n                const otherIx = Object.freeze({ programAddress: '11111111111111111111111111111111' as Address });\n                const txWithExisting: LegacyOrV0TransactionMessage = {\n                    instructions: [otherIx, existingIx],\n                    version,\n                };\n\n                it('replaces the existing instruction in-place when setting a different value', () => {\n                    const result = setTransactionMessageComputeUnitPrice(COMPUTE_UNIT_PRICE_B, txWithExisting);\n                    expect(result.instructions).toHaveLength(2);\n                    expect(result.instructions[0]).toBe(otherIx);\n                    expect(getPriorityFeeFromInstructionData(result.instructions[1].data as Uint8Array)).toBe(\n                        COMPUTE_UNIT_PRICE_B,\n                    );\n                });\n\n                it('returns the same reference when setting the same value', () => {\n                    const result = setTransactionMessageComputeUnitPrice(COMPUTE_UNIT_PRICE_A, txWithExisting);\n                    expect(result).toBe(txWithExisting);\n                });\n\n                it('returns a new reference when setting a different value', () => {\n                    const result = setTransactionMessageComputeUnitPrice(COMPUTE_UNIT_PRICE_B, txWithExisting);\n                    expect(result).not.toBe(txWithExisting);\n                });\n            });\n\n            describe('setting to undefined', () => {\n                it('returns the same reference when no instruction exists', () => {\n                    const result = setTransactionMessageComputeUnitPrice(undefined, baseTx);\n                    expect(result).toBe(baseTx);\n                });\n\n                it('removes the instruction when one exists', () => {\n                    const txWithIx = setTransactionMessageComputeUnitPrice(COMPUTE_UNIT_PRICE_A, baseTx);\n                    const result = setTransactionMessageComputeUnitPrice(undefined, txWithIx);\n                    expect(result.instructions).toHaveLength(0);\n                });\n\n                it('preserves other instructions when removing', () => {\n                    const otherIx = { programAddress: '11111111111111111111111111111111' as Address };\n                    const priceIx = getSetComputeUnitPriceInstruction(COMPUTE_UNIT_PRICE_A);\n                    const txWithIxs: LegacyOrV0TransactionMessage = {\n                        instructions: [priceIx, otherIx],\n                        version,\n                    };\n                    const result = setTransactionMessageComputeUnitPrice(undefined, txWithIxs);\n                    expect(result.instructions).toHaveLength(1);\n                    expect(result.instructions[0]).toBe(otherIx);\n                });\n            });\n        },\n    );\n});\n\ndescribe('getTransactionMessageComputeUnitPrice', () => {\n    describe.each([{ version: 'legacy' as const }, { version: 0 as const }])(\n        'given a $version transaction',\n        ({ version }) => {\n            it('returns undefined without instruction', () => {\n                const tx: LegacyOrV0TransactionMessage = { instructions: [], version };\n                expect(getTransactionMessageComputeUnitPrice(tx)).toBeUndefined();\n            });\n\n            it('returns the value from instruction', () => {\n                const tx: LegacyOrV0TransactionMessage = {\n                    instructions: [getSetComputeUnitPriceInstruction(COMPUTE_UNIT_PRICE_A)],\n                    version,\n                };\n                expect(getTransactionMessageComputeUnitPrice(tx)).toBe(COMPUTE_UNIT_PRICE_A);\n            });\n        },\n    );\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/create-transaction-message-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { createTransactionMessage } from '../create-transaction-message';\n\ndescribe('createTransactionMessage', () => {\n    it('creates a legacy transaction', () => {\n        expect(createTransactionMessage({ version: 'legacy' })).toMatchObject({\n            instructions: [],\n            version: 'legacy',\n        });\n    });\n    it('creates a v0 transaction', () => {\n        expect(createTransactionMessage({ version: 0 })).toMatchObject({\n            instructions: [],\n            version: 0,\n        });\n    });\n    it('freezes the object', () => {\n        const tx = createTransactionMessage({ version: 0 });\n        expect(tx).toBeFrozenObject();\n    });\n    it('freezes the instructions array', () => {\n        const tx = createTransactionMessage({ version: 0 });\n        expect(tx.instructions).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/durable-nonce-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { AccountRole, Instruction, ReadonlySignerAccount, WritableAccount } from '@solana/instructions';\nimport type { Blockhash } from '@solana/rpc-types';\n\nimport { TransactionMessageWithBlockhashLifetime } from '../blockhash';\nimport {\n    assertIsTransactionMessageWithDurableNonceLifetime,\n    Nonce,\n    setTransactionMessageLifetimeUsingDurableNonce,\n    TransactionMessageWithDurableNonceLifetime,\n} from '../durable-nonce';\nimport { TransactionMessage } from '../transaction-message';\n\nfunction createMockAdvanceNonceAccountInstruction<\n    TNonceAccountAddress extends string = string,\n    TNonceAuthorityAddress extends string = string,\n>({\n    nonceAccountAddress,\n    nonceAuthorityAddress,\n}: {\n    nonceAccountAddress: Address<TNonceAccountAddress>;\n    nonceAuthorityAddress: Address<TNonceAuthorityAddress>;\n}): TransactionMessageWithDurableNonceLifetime['instructions'][0] {\n    return {\n        accounts: [\n            { address: nonceAccountAddress, role: AccountRole.WRITABLE } as WritableAccount<TNonceAccountAddress>,\n            {\n                address:\n                    'SysvarRecentB1ockHashes11111111111111111111' as Address<'SysvarRecentB1ockHashes11111111111111111111'>,\n                role: AccountRole.READONLY,\n            },\n            {\n                address: nonceAuthorityAddress,\n                role: AccountRole.READONLY_SIGNER,\n            } as ReadonlySignerAccount<TNonceAuthorityAddress>,\n        ],\n        data: new Uint8Array([4, 0, 0, 0]) as TransactionMessageWithDurableNonceLifetime['instructions'][0]['data'],\n        programAddress: '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>,\n    };\n}\n\ndescribe('assertIsDurableNonceTransactionMessage()', () => {\n    let durableNonceTx: TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n    const NONCE_CONSTRAINT = {\n        nonce: '123' as Nonce,\n        nonceAccountAddress: '123' as Address,\n        nonceAuthorityAddress: '123' as Address,\n    };\n    beforeEach(() => {\n        durableNonceTx = {\n            instructions: [createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT)],\n            lifetimeConstraint: {\n                nonce: NONCE_CONSTRAINT.nonce,\n            } as TransactionMessageWithDurableNonceLifetime['lifetimeConstraint'],\n            version: 0,\n        } as const;\n    });\n    it('throws when supplied a transaction with a nonce lifetime constraint but no instructions', () => {\n        expect(() => {\n            assertIsTransactionMessageWithDurableNonceLifetime({\n                ...durableNonceTx,\n                instructions: [],\n            });\n        }).toThrow();\n    });\n    it('throws when supplied a transaction with a nonce lifetime constraint but an instruction at index 0 for a program other than the system program', () => {\n        expect(() => {\n            assertIsTransactionMessageWithDurableNonceLifetime({\n                ...durableNonceTx,\n                instructions: [\n                    {\n                        ...durableNonceTx.instructions[0],\n                        programAddress: '32JTd9jz5xGuLegzVouXxfzAVTiJYWMLrg6p8RxbV5xc' as Address,\n                    },\n                ],\n                lifetimeConstraint: {\n                    nonce: NONCE_CONSTRAINT.nonce,\n                } as TransactionMessageWithDurableNonceLifetime['lifetimeConstraint'],\n            });\n        }).toThrow();\n    });\n    it('throws when supplied a transaction with a nonce lifetime constraint but a system program instruction at index 0 for something other than the `AdvanceNonceAccount` instruction', () => {\n        expect(() => {\n            assertIsTransactionMessageWithDurableNonceLifetime({\n                ...durableNonceTx,\n                instructions: [\n                    {\n                        ...durableNonceTx.instructions[0],\n                        data: new Uint8Array([2, 0, 0, 0]), // Transfer instruction\n                    },\n                ],\n                lifetimeConstraint: {\n                    nonce: NONCE_CONSTRAINT.nonce,\n                } as TransactionMessageWithDurableNonceLifetime['lifetimeConstraint'],\n            });\n        }).toThrow();\n    });\n    it('throws when supplied a transaction with a nonce lifetime constraint but a system program instruction at index 0 with malformed accounts', () => {\n        expect(() => {\n            assertIsTransactionMessageWithDurableNonceLifetime({\n                ...durableNonceTx,\n                instructions: [\n                    {\n                        ...durableNonceTx.instructions[0],\n                        accounts: [],\n                    },\n                ],\n                lifetimeConstraint: {\n                    nonce: NONCE_CONSTRAINT.nonce,\n                } as TransactionMessageWithDurableNonceLifetime['lifetimeConstraint'],\n            });\n        }).toThrow();\n    });\n    it('throws when supplied a transaction with an `AdvanceNonceAccount` instruction at index 0 but no lifetime constraint', () => {\n        expect(() => {\n            assertIsTransactionMessageWithDurableNonceLifetime({\n                ...durableNonceTx,\n                lifetimeConstraint: undefined,\n            });\n        }).toThrow();\n    });\n    it('throws when supplied a transaction with an `AdvanceNonceAccount` instruction at index 0 but a blockhash lifetime constraint', () => {\n        expect(() => {\n            assertIsTransactionMessageWithDurableNonceLifetime({\n                ...durableNonceTx,\n                lifetimeConstraint: {\n                    blockhash: '123' as Blockhash,\n                    lastValidBlockHeight: 123n,\n                } as TransactionMessageWithBlockhashLifetime['lifetimeConstraint'],\n            } as unknown as TransactionMessage);\n        }).toThrow();\n    });\n    it('does not throw when supplied a durable nonce transaction', () => {\n        expect(() => {\n            assertIsTransactionMessageWithDurableNonceLifetime({ ...durableNonceTx });\n        }).not.toThrow();\n    });\n    it('does not throw when the nonce authority is a writable signer', () => {\n        const advanceDurableNonceInstruction = createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT);\n        const { accounts } = advanceDurableNonceInstruction;\n        const updatedInstruction: Instruction = {\n            ...advanceDurableNonceInstruction,\n            accounts: [\n                accounts[0],\n                accounts[1],\n                {\n                    ...accounts[2],\n                    role: AccountRole.WRITABLE_SIGNER,\n                },\n            ],\n        };\n        const transaction = {\n            instructions: [updatedInstruction],\n            lifetimeConstraint: {\n                nonce: NONCE_CONSTRAINT.nonce,\n            } as TransactionMessageWithDurableNonceLifetime['lifetimeConstraint'],\n            version: 0,\n        } as const;\n        expect(() => {\n            assertIsTransactionMessageWithDurableNonceLifetime({ ...transaction });\n        }).not.toThrow();\n    });\n});\n\ndescribe('setTransactionMessageLifetimeUsingDurableNonce', () => {\n    let baseTx: TransactionMessage;\n    const NONCE_CONSTRAINT_A = {\n        nonce: '123' as Nonce,\n        nonceAccountAddress: '123' as Address,\n        nonceAuthorityAddress: '123' as Address,\n    };\n    const NONCE_CONSTRAINT_B = {\n        nonce: '456' as Nonce,\n        nonceAccountAddress: '456' as Address,\n        nonceAuthorityAddress: '456' as Address,\n    };\n    beforeEach(() => {\n        baseTx = {\n            instructions: [{ programAddress: '32JTd9jz5xGuLegzVouXxfzAVTiJYWMLrg6p8RxbV5xc' as Address }],\n            version: 0,\n        };\n    });\n    it('sets the lifetime constraint on the transaction to the supplied durable nonce constraint', () => {\n        const durableNonceTxWithConstraintA = setTransactionMessageLifetimeUsingDurableNonce(\n            NONCE_CONSTRAINT_A,\n            baseTx,\n        );\n        expect(durableNonceTxWithConstraintA).toHaveProperty('lifetimeConstraint', { nonce: NONCE_CONSTRAINT_A.nonce });\n    });\n    it('prepends an `AdvanceNonceAccount` instruction', () => {\n        const durableNonceTxWithConstraintA = setTransactionMessageLifetimeUsingDurableNonce(\n            NONCE_CONSTRAINT_A,\n            baseTx,\n        );\n        expect(durableNonceTxWithConstraintA.instructions).toEqual([\n            createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT_A),\n            baseTx.instructions[0],\n        ]);\n    });\n    it('freezes the prepended `AdvanceNonceAccount` instruction', () => {\n        const durableNonceTxWithConstraintA = setTransactionMessageLifetimeUsingDurableNonce(\n            NONCE_CONSTRAINT_A,\n            baseTx,\n        );\n        expect(durableNonceTxWithConstraintA.instructions[0]).toBeFrozenObject();\n    });\n    describe('given a transaction with an advance nonce account instruction but no nonce lifetime constraint', () => {\n        it('does not modify an `AdvanceNonceAccount` instruction if the existing one matches the constraint added', () => {\n            const instruction = createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT_A);\n            instruction.accounts[2].role = AccountRole.WRITABLE_SIGNER;\n            const transaction: TransactionMessage = {\n                ...baseTx,\n                instructions: [instruction, baseTx.instructions[0]],\n            };\n            const durableNonceTxWithConstraintA = setTransactionMessageLifetimeUsingDurableNonce(\n                NONCE_CONSTRAINT_A,\n                transaction,\n            );\n            expect(durableNonceTxWithConstraintA.instructions).toEqual([instruction, baseTx.instructions[0]]);\n        });\n        describe('when the existing `AdvanceNonceAccount` instruction does not match the constraint added', () => {\n            it('replaces the existing instruction', () => {\n                const transaction: TransactionMessage = {\n                    ...baseTx,\n                    instructions: [\n                        createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT_B),\n                        baseTx.instructions[0],\n                    ],\n                };\n                const durableNonceTxWithConstraintA = setTransactionMessageLifetimeUsingDurableNonce(\n                    NONCE_CONSTRAINT_A,\n                    transaction,\n                );\n                expect(durableNonceTxWithConstraintA.instructions).toEqual([\n                    createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT_A),\n                    baseTx.instructions[0],\n                ]);\n            });\n\n            it('freezes the replacement instruction', () => {\n                const transaction: TransactionMessage = {\n                    ...baseTx,\n                    instructions: [\n                        createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT_B),\n                        baseTx.instructions[0],\n                    ],\n                };\n                const durableNonceTxWithConstraintA = setTransactionMessageLifetimeUsingDurableNonce(\n                    NONCE_CONSTRAINT_A,\n                    transaction,\n                );\n                expect(durableNonceTxWithConstraintA.instructions[0]).toBeFrozenObject();\n            });\n        });\n    });\n    describe('given a durable nonce transaction', () => {\n        let durableNonceTxWithConstraintA: TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n        beforeEach(() => {\n            durableNonceTxWithConstraintA = {\n                ...baseTx,\n                instructions: [\n                    createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT_A),\n                    { programAddress: '32JTd9jz5xGuLegzVouXxfzAVTiJYWMLrg6p8RxbV5xc' as Address },\n                ],\n                lifetimeConstraint: { nonce: NONCE_CONSTRAINT_A.nonce },\n                version: 0,\n            };\n        });\n        it('sets the new durable nonce constraint on the transaction when it differs from the existing one', () => {\n            const durableNonceTxWithConstraintB = setTransactionMessageLifetimeUsingDurableNonce(\n                NONCE_CONSTRAINT_B,\n                durableNonceTxWithConstraintA,\n            );\n            expect(durableNonceTxWithConstraintB).toHaveProperty('lifetimeConstraint', {\n                nonce: NONCE_CONSTRAINT_B.nonce,\n            });\n        });\n        it('replaces the advance nonce account instruction when it differs from the existing one', () => {\n            const durableNonceTxWithConstraintB = setTransactionMessageLifetimeUsingDurableNonce(\n                NONCE_CONSTRAINT_B,\n                durableNonceTxWithConstraintA,\n            );\n            expect(durableNonceTxWithConstraintB.instructions).toEqual([\n                createMockAdvanceNonceAccountInstruction(NONCE_CONSTRAINT_B),\n                durableNonceTxWithConstraintA.instructions[1],\n            ]);\n        });\n        it('freezes the replacement advance nonce account instruction', () => {\n            const durableNonceTxWithConstraintB = setTransactionMessageLifetimeUsingDurableNonce(\n                NONCE_CONSTRAINT_B,\n                durableNonceTxWithConstraintA,\n            );\n            expect(durableNonceTxWithConstraintB.instructions[0]).toBeFrozenObject();\n        });\n        it('returns the original transaction when trying to set the same durable nonce constraint again', () => {\n            const txWithSameNonceLifetimeConstraint = setTransactionMessageLifetimeUsingDurableNonce(\n                NONCE_CONSTRAINT_A,\n                durableNonceTxWithConstraintA,\n            );\n            expect(durableNonceTxWithConstraintA).toBe(txWithSameNonceLifetimeConstraint);\n        });\n    });\n    it('freezes the object', () => {\n        const durableNonceTx = setTransactionMessageLifetimeUsingDurableNonce(NONCE_CONSTRAINT_A, baseTx);\n        expect(durableNonceTx).toBeFrozenObject();\n    });\n    it('freezes the instructions array', () => {\n        const durableNonceTx = setTransactionMessageLifetimeUsingDurableNonce(NONCE_CONSTRAINT_A, baseTx);\n        expect(durableNonceTx.instructions).toBeFrozenObject();\n    });\n    it('freezes the nonce lifetime', () => {\n        const durableNonceTx = setTransactionMessageLifetimeUsingDurableNonce(NONCE_CONSTRAINT_A, baseTx);\n        expect(durableNonceTx.lifetimeConstraint).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/fee-payer-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\n\nimport { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../fee-payer';\nimport { TransactionMessage } from '../transaction-message';\n\nconst EXAMPLE_FEE_PAYER_A =\n    '7mvYAxeCui21xYkAyQSjh6iBVZPpgVyt7PYv9km8V5mE' as Address<'7mvYAxeCui21xYkAyQSjh6iBVZPpgVyt7PYv9km8V5mE'>;\nconst EXAMPLE_FEE_PAYER_B =\n    '5LHng8dLBxCYyR3jdDbobLiRQ6pR74pYtxKohY93RbZN' as Address<'5LHng8dLBxCYyR3jdDbobLiRQ6pR74pYtxKohY93RbZN'>;\n\ndescribe('setTransactionMessageFeePayer', () => {\n    let baseTx: TransactionMessage;\n    beforeEach(() => {\n        baseTx = {\n            instructions: [],\n            version: 0,\n        };\n    });\n    it('sets the fee payer on the transaction', () => {\n        const txWithFeePayerA = setTransactionMessageFeePayer(EXAMPLE_FEE_PAYER_A, baseTx);\n        expect(txWithFeePayerA).toHaveProperty('feePayer', { address: EXAMPLE_FEE_PAYER_A });\n    });\n    describe('given a transaction with a fee payer already set', () => {\n        let txWithFeePayerA: TransactionMessage & TransactionMessageWithFeePayer;\n        beforeEach(() => {\n            txWithFeePayerA = {\n                ...baseTx,\n                feePayer: { address: EXAMPLE_FEE_PAYER_A },\n            };\n        });\n        it('sets the new fee payer on the transaction when it differs from the existing one', () => {\n            const txWithFeePayerB = setTransactionMessageFeePayer(EXAMPLE_FEE_PAYER_B, txWithFeePayerA);\n            expect(txWithFeePayerB).toHaveProperty('feePayer', { address: EXAMPLE_FEE_PAYER_B });\n        });\n        it('returns the original transaction when trying to set the same fee payer again', () => {\n            const txWithSameFeePayer = setTransactionMessageFeePayer(EXAMPLE_FEE_PAYER_A, txWithFeePayerA);\n            expect(txWithFeePayerA).toBe(txWithSameFeePayer);\n        });\n    });\n    describe('given a transaction with a fee payer with extra properties set', () => {\n        let txWithFeePayerA: TransactionMessage & {\n            readonly feePayer: Readonly<{ address: Address; extra: 'extra' }>;\n        };\n        beforeEach(() => {\n            txWithFeePayerA = {\n                ...baseTx,\n                feePayer: { address: EXAMPLE_FEE_PAYER_A, extra: 'extra' },\n            };\n        });\n        it('sets the new fee payer on the transaction when it differs from the existing one', () => {\n            const txWithFeePayerB = setTransactionMessageFeePayer(EXAMPLE_FEE_PAYER_B, txWithFeePayerA);\n            expect(txWithFeePayerB).toHaveProperty('feePayer', { address: EXAMPLE_FEE_PAYER_B });\n        });\n        it('sets the new fee payer on the transaction even when it is the same as the existing one', () => {\n            const txWithSameFeePayer = setTransactionMessageFeePayer(EXAMPLE_FEE_PAYER_A, txWithFeePayerA);\n            expect(txWithSameFeePayer).toHaveProperty('feePayer', { address: EXAMPLE_FEE_PAYER_A });\n            expect(txWithSameFeePayer).not.toBe(txWithFeePayerA);\n        });\n    });\n    it('freezes the object', () => {\n        const txWithFeePayer = setTransactionMessageFeePayer(EXAMPLE_FEE_PAYER_A, baseTx);\n        expect(txWithFeePayer).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/heap-size-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\n\nimport {\n    COMPUTE_BUDGET_PROGRAM_ADDRESS,\n    getHeapSizeFromInstructionData,\n    getRequestHeapFrameInstruction,\n} from '../compute-budget-instruction';\nimport { getTransactionMessageHeapSize, setTransactionMessageHeapSize } from '../heap-size';\nimport { TransactionMessage } from '../transaction-message';\n\nconst COMPUTE_UNIT_LIMIT_A = 200_000;\n\nconst HEAP_SIZE_A = 30_000;\nconst HEAP_SIZE_B = 50_000;\n\nconst PRIORITY_FEE_LAMPORTS_A = 5_000n;\n\ndescribe('setTransactionMessageHeapSize', () => {\n    describe('given a v1 transaction', () => {\n        const baseTx: TransactionMessage & { version: 1 } = { instructions: [], version: 1 };\n\n        it('sets the heap size on the transaction', () => {\n            const txWithHeapSize = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n            expect(txWithHeapSize).toHaveProperty('config', { heapSize: HEAP_SIZE_A });\n        });\n\n        it('freezes the transaction object', () => {\n            const txWithHeapSize = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n            expect(txWithHeapSize).toBeFrozenObject();\n        });\n\n        it('freezes the config object', () => {\n            const txWithHeapSize = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n            expect(txWithHeapSize.config).toBeFrozenObject();\n        });\n\n        describe('given a transaction with an existing config', () => {\n            const txWithConfig = {\n                ...baseTx,\n                config: {\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n                },\n            };\n\n            it('sets the heap size while preserving other config properties', () => {\n                const txWithHeapSize = setTransactionMessageHeapSize(HEAP_SIZE_A, txWithConfig);\n                expect(txWithHeapSize.config).toMatchObject({\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    heapSize: HEAP_SIZE_A,\n                    priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n                });\n            });\n\n            it('returns the same reference when setting the same heap size', () => {\n                const txWithHeapSizeA = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n                const txWithSameHeapSize = setTransactionMessageHeapSize(HEAP_SIZE_A, txWithHeapSizeA);\n                expect(txWithHeapSizeA).toBe(txWithSameHeapSize);\n            });\n\n            it('returns a new reference when setting a different heap size', () => {\n                const txWithHeapSizeA = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n                const txWithHeapSizeB = setTransactionMessageHeapSize(HEAP_SIZE_B, txWithHeapSizeA);\n                expect(txWithHeapSizeA).not.toBe(txWithHeapSizeB);\n                expect(txWithHeapSizeB.config).toHaveProperty('heapSize', HEAP_SIZE_B);\n            });\n        });\n\n        describe('empty config normalization', () => {\n            it('removes config when setting to undefined as only property', () => {\n                const txWithHeapSize = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n                const txWithoutConfig = setTransactionMessageHeapSize(undefined, txWithHeapSize);\n                expect(txWithoutConfig).not.toHaveProperty('config');\n            });\n\n            it('preserves config when setting to undefined with other properties present', () => {\n                const txWithConfig = {\n                    ...baseTx,\n                    config: {\n                        computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                        heapSize: HEAP_SIZE_A,\n                    },\n                };\n                const txWithoutHeapSize = setTransactionMessageHeapSize(undefined, txWithConfig);\n                expect(txWithoutHeapSize).toHaveProperty('config', {\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    heapSize: undefined,\n                });\n            });\n        });\n    });\n\n    describe.each([{ version: 'legacy' as const }, { version: 0 as const }])(\n        'given a $version transaction',\n        ({ version }) => {\n            const baseTx: TransactionMessage = { instructions: [], version };\n\n            it('appends a RequestHeapFrame instruction', () => {\n                const result = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n                expect(result.instructions).toHaveLength(1);\n                expect(result.instructions[0].programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n                expect(getHeapSizeFromInstructionData(result.instructions[0].data as Uint8Array)).toBe(HEAP_SIZE_A);\n            });\n\n            it('freezes the transaction object', () => {\n                const result = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n                expect(result).toBeFrozenObject();\n            });\n\n            it('freezes the instructions array', () => {\n                const result = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n                expect(result.instructions).toBeFrozenObject();\n            });\n\n            it('appends the instruction after existing instructions', () => {\n                const existingIx = { programAddress: '11111111111111111111111111111111' as Address };\n                const txWithIx: TransactionMessage = { instructions: [existingIx], version };\n                const result = setTransactionMessageHeapSize(HEAP_SIZE_A, txWithIx);\n                expect(result.instructions).toHaveLength(2);\n                expect(result.instructions[0]).toBe(existingIx);\n                expect(result.instructions[1].programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n            });\n\n            describe('given a transaction with an existing RequestHeapFrame instruction', () => {\n                const existingIx = Object.freeze(getRequestHeapFrameInstruction(HEAP_SIZE_A));\n                const otherIx = Object.freeze({ programAddress: '11111111111111111111111111111111' as Address });\n                const txWithExisting = { instructions: [otherIx, existingIx] as const, version };\n\n                it('replaces the existing instruction in-place when setting a different value', () => {\n                    const result = setTransactionMessageHeapSize(HEAP_SIZE_B, txWithExisting);\n                    expect(result.instructions).toHaveLength(2);\n                    expect(result.instructions[0]).toBe(otherIx);\n                    expect(getHeapSizeFromInstructionData(result.instructions[1].data)).toBe(HEAP_SIZE_B);\n                });\n\n                it('returns the same reference when setting the same value', () => {\n                    const result = setTransactionMessageHeapSize(HEAP_SIZE_A, txWithExisting);\n                    expect(result).toBe(txWithExisting);\n                });\n\n                it('returns a new reference when setting a different value', () => {\n                    const result = setTransactionMessageHeapSize(HEAP_SIZE_B, txWithExisting);\n                    expect(result).not.toBe(txWithExisting);\n                });\n            });\n\n            describe('setting to undefined', () => {\n                it('returns the same reference when no instruction exists', () => {\n                    const result = setTransactionMessageHeapSize(undefined, baseTx);\n                    expect(result).toBe(baseTx);\n                });\n\n                it('removes the instruction when one exists', () => {\n                    const txWithIx = setTransactionMessageHeapSize(HEAP_SIZE_A, baseTx);\n                    const result = setTransactionMessageHeapSize(undefined, txWithIx);\n                    expect(result.instructions).toHaveLength(0);\n                });\n\n                it('preserves other instructions when removing', () => {\n                    const otherIx = { programAddress: '11111111111111111111111111111111' as Address };\n                    const heapIx = getRequestHeapFrameInstruction(HEAP_SIZE_A);\n                    const txWithIxs: TransactionMessage = {\n                        instructions: [heapIx, otherIx],\n                        version,\n                    };\n                    const result = setTransactionMessageHeapSize(undefined, txWithIxs);\n                    expect(result.instructions).toHaveLength(1);\n                    expect(result.instructions[0]).toBe(otherIx);\n                });\n            });\n        },\n    );\n});\n\ndescribe('getTransactionMessageHeapSize', () => {\n    describe('given a v1 transaction', () => {\n        it('returns undefined without config', () => {\n            const tx: TransactionMessage = { instructions: [], version: 1 };\n            expect(getTransactionMessageHeapSize(tx)).toBeUndefined();\n        });\n\n        it('returns the value from config', () => {\n            const tx: TransactionMessage & { version: 1 } = {\n                config: { heapSize: HEAP_SIZE_A },\n                instructions: [],\n                version: 1,\n            };\n            expect(getTransactionMessageHeapSize(tx)).toBe(HEAP_SIZE_A);\n        });\n    });\n\n    describe.each([{ version: 'legacy' as const }, { version: 0 as const }])(\n        'given a $version transaction',\n        ({ version }) => {\n            it('returns undefined without instruction', () => {\n                const tx: TransactionMessage = { instructions: [], version };\n                expect(getTransactionMessageHeapSize(tx)).toBeUndefined();\n            });\n\n            it('returns the value from instruction', () => {\n                const tx: TransactionMessage = {\n                    instructions: [getRequestHeapFrameInstruction(HEAP_SIZE_A)],\n                    version,\n                };\n                expect(getTransactionMessageHeapSize(tx)).toBe(HEAP_SIZE_A);\n            });\n        },\n    );\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/instructions-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { Instruction } from '@solana/instructions';\n\nimport {\n    appendTransactionMessageInstruction,\n    appendTransactionMessageInstructions,\n    prependTransactionMessageInstruction,\n    prependTransactionMessageInstructions,\n} from '../instructions';\nimport { TransactionMessage } from '../transaction-message';\n\nconst PROGRAM_A =\n    'AALQD2dt1k43Acrkp4SvdhZaN4S115Ff2Bi7rHPti3sL' as Address<'AALQD2dt1k43Acrkp4SvdhZaN4S115Ff2Bi7rHPti3sL'>;\nconst PROGRAM_B =\n    'DNAbkMkoMLRXF7wuLCrTzouMyzi25krr3B94yW87VvxU' as Address<'DNAbkMkoMLRXF7wuLCrTzouMyzi25krr3B94yW87VvxU'>;\nconst PROGRAM_C =\n    '6Bkt4j67rxzFF6s9DaMRyfitftRrGxe4oYHPRHuFChzi' as Address<'6Bkt4j67rxzFF6s9DaMRyfitftRrGxe4oYHPRHuFChzi'>;\n\ndescribe('Transaction instruction helpers', () => {\n    let baseTx: TransactionMessage;\n    let exampleInstruction: Instruction<string>;\n    let secondExampleInstruction: Instruction<string>;\n    beforeEach(() => {\n        baseTx = {\n            instructions: [\n                {\n                    programAddress: PROGRAM_A,\n                },\n            ],\n            version: 0,\n        };\n        exampleInstruction = {\n            programAddress: PROGRAM_B,\n        };\n        secondExampleInstruction = {\n            programAddress: PROGRAM_C,\n        };\n    });\n    describe('appendTransactionMessageInstruction', () => {\n        it('adds the instruction to the end of the list', () => {\n            const txWithAddedInstruction = appendTransactionMessageInstruction(exampleInstruction, baseTx);\n            expect(txWithAddedInstruction.instructions).toMatchObject([...baseTx.instructions, exampleInstruction]);\n        });\n        it('freezes the object', () => {\n            const txWithAddedInstruction = appendTransactionMessageInstruction(exampleInstruction, baseTx);\n            expect(txWithAddedInstruction).toBeFrozenObject();\n        });\n        it('freezes the instructions array', () => {\n            const txWithAddedInstruction = appendTransactionMessageInstruction(exampleInstruction, baseTx);\n            expect(txWithAddedInstruction.instructions).toBeFrozenObject();\n        });\n    });\n    describe('appendTransactionMessageInstructions', () => {\n        it('adds the instructions to the end of the list', () => {\n            const txWithAddedInstructions = appendTransactionMessageInstructions(\n                [exampleInstruction, secondExampleInstruction],\n                baseTx,\n            );\n            expect(txWithAddedInstructions.instructions).toMatchObject([\n                ...baseTx.instructions,\n                exampleInstruction,\n                secondExampleInstruction,\n            ]);\n        });\n        it('freezes the object', () => {\n            const txWithAddedInstruction = appendTransactionMessageInstructions(\n                [exampleInstruction, secondExampleInstruction],\n                baseTx,\n            );\n            expect(txWithAddedInstruction).toBeFrozenObject();\n        });\n        it('freezes the instructions array', () => {\n            const txWithAddedInstruction = appendTransactionMessageInstructions(\n                [exampleInstruction, secondExampleInstruction],\n                baseTx,\n            );\n            expect(txWithAddedInstruction.instructions).toBeFrozenObject();\n        });\n    });\n    describe('prependTransactionMessageInstruction', () => {\n        it('adds the instruction to the beginning of the list', () => {\n            const txWithAddedInstruction = prependTransactionMessageInstruction(exampleInstruction, baseTx);\n            expect(txWithAddedInstruction.instructions).toMatchObject([exampleInstruction, ...baseTx.instructions]);\n        });\n        it('freezes the object', () => {\n            const txWithAddedInstruction = prependTransactionMessageInstruction(exampleInstruction, baseTx);\n            expect(txWithAddedInstruction).toBeFrozenObject();\n        });\n        it('freezes the instructions array', () => {\n            const txWithAddedInstruction = prependTransactionMessageInstruction(exampleInstruction, baseTx);\n            expect(txWithAddedInstruction.instructions).toBeFrozenObject();\n        });\n    });\n    describe('prependTransactionMessageInstructions', () => {\n        it('adds the instructions to the beginning of the list', () => {\n            const txWithAddedInstruction = prependTransactionMessageInstructions(\n                [exampleInstruction, secondExampleInstruction],\n                baseTx,\n            );\n            expect(txWithAddedInstruction.instructions).toMatchObject([\n                exampleInstruction,\n                secondExampleInstruction,\n                ...baseTx.instructions,\n            ]);\n        });\n        it('freezes the object', () => {\n            const txWithAddedInstruction = prependTransactionMessageInstructions(\n                [exampleInstruction, secondExampleInstruction],\n                baseTx,\n            );\n            expect(txWithAddedInstruction).toBeFrozenObject();\n        });\n        it('freezes the instructions array', () => {\n            const txWithAddedInstruction = prependTransactionMessageInstructions(\n                [exampleInstruction, secondExampleInstruction],\n                baseTx,\n            );\n            expect(txWithAddedInstruction.instructions).toBeFrozenObject();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/loaded-accounts-data-size-limit-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\n\nimport {\n    COMPUTE_BUDGET_PROGRAM_ADDRESS,\n    getLoadedAccountsDataSizeLimitFromInstructionData,\n    getSetLoadedAccountsDataSizeLimitInstruction,\n} from '../compute-budget-instruction';\nimport {\n    getTransactionMessageLoadedAccountsDataSizeLimit,\n    setTransactionMessageLoadedAccountsDataSizeLimit,\n} from '../loaded-accounts-data-size-limit';\nimport { TransactionMessage } from '../transaction-message';\n\nconst COMPUTE_UNIT_LIMIT_A = 200_000;\n\nconst HEAP_SIZE_A = 30_000;\n\nconst LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A = 60_000;\nconst LOADED_ACCOUNTS_DATA_SIZE_LIMIT_B = 100_000;\n\ndescribe('setTransactionMessageLoadedAccountsDataSizeLimit', () => {\n    describe('given a v1 transaction', () => {\n        const baseTx: TransactionMessage & { version: 1 } = { instructions: [], version: 1 };\n\n        it('sets the loaded accounts data size limit on the transaction', () => {\n            const txWithLimit = setTransactionMessageLoadedAccountsDataSizeLimit(\n                LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                baseTx,\n            );\n            expect(txWithLimit).toHaveProperty('config', {\n                loadedAccountsDataSizeLimit: LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n            });\n        });\n\n        it('freezes the transaction object', () => {\n            const txWithLimit = setTransactionMessageLoadedAccountsDataSizeLimit(\n                LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                baseTx,\n            );\n            expect(txWithLimit).toBeFrozenObject();\n        });\n\n        it('freezes the config object', () => {\n            const txWithLimit = setTransactionMessageLoadedAccountsDataSizeLimit(\n                LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                baseTx,\n            );\n            expect(txWithLimit.config).toBeFrozenObject();\n        });\n\n        describe('given a transaction with an existing config', () => {\n            const txWithConfig = {\n                ...baseTx,\n                config: {\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    heapSize: HEAP_SIZE_A,\n                },\n            };\n\n            it('sets the loaded accounts data size limit while preserving other config properties', () => {\n                const txWithLimit = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    txWithConfig,\n                );\n                expect(txWithLimit.config).toMatchObject({\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    heapSize: HEAP_SIZE_A,\n                    loadedAccountsDataSizeLimit: LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                });\n            });\n\n            it('returns the same reference when setting the same loaded accounts data size limit', () => {\n                const txWithLimitA = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    baseTx,\n                );\n                const txWithSameLimit = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    txWithLimitA,\n                );\n                expect(txWithLimitA).toBe(txWithSameLimit);\n            });\n\n            it('returns a new reference when setting a different loaded accounts data size limit', () => {\n                const txWithLimitA = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    baseTx,\n                );\n                const txWithLimitB = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_B,\n                    txWithLimitA,\n                );\n                expect(txWithLimitA).not.toBe(txWithLimitB);\n                expect(txWithLimitB.config).toHaveProperty(\n                    'loadedAccountsDataSizeLimit',\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_B,\n                );\n            });\n        });\n\n        describe('empty config normalization', () => {\n            it('removes config when setting to undefined as only property', () => {\n                const txWithLimit = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    baseTx,\n                );\n                const txWithoutConfig = setTransactionMessageLoadedAccountsDataSizeLimit(undefined, txWithLimit);\n                expect(txWithoutConfig).not.toHaveProperty('config');\n            });\n\n            it('preserves config when setting to undefined with other properties present', () => {\n                const txWithConfig = {\n                    ...baseTx,\n                    config: {\n                        computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                        loadedAccountsDataSizeLimit: LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    },\n                };\n                const txWithoutLimit = setTransactionMessageLoadedAccountsDataSizeLimit(undefined, txWithConfig);\n                expect(txWithoutLimit).toHaveProperty('config', {\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    loadedAccountsDataSizeLimit: undefined,\n                });\n            });\n        });\n    });\n\n    describe.each([{ version: 'legacy' as const }, { version: 0 as const }])(\n        'given a $version transaction',\n        ({ version }) => {\n            const baseTx: TransactionMessage = { instructions: [], version };\n\n            it('appends a SetLoadedAccountsDataSizeLimit instruction', () => {\n                const result = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    baseTx,\n                );\n                expect(result.instructions).toHaveLength(1);\n                expect(result.instructions[0].programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n                expect(\n                    getLoadedAccountsDataSizeLimitFromInstructionData(result.instructions[0].data as Uint8Array),\n                ).toBe(LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A);\n            });\n\n            it('freezes the transaction object', () => {\n                const result = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    baseTx,\n                );\n                expect(result).toBeFrozenObject();\n            });\n\n            it('freezes the instructions array', () => {\n                const result = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    baseTx,\n                );\n                expect(result.instructions).toBeFrozenObject();\n            });\n\n            it('appends the instruction after existing instructions', () => {\n                const existingIx = { programAddress: '11111111111111111111111111111111' as Address };\n                const txWithIx: TransactionMessage = { instructions: [existingIx], version };\n                const result = setTransactionMessageLoadedAccountsDataSizeLimit(\n                    LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                    txWithIx,\n                );\n                expect(result.instructions).toHaveLength(2);\n                expect(result.instructions[0]).toBe(existingIx);\n                expect(result.instructions[1].programAddress).toBe(COMPUTE_BUDGET_PROGRAM_ADDRESS);\n            });\n\n            describe('given a transaction with an existing SetLoadedAccountsDataSizeLimit instruction', () => {\n                const existingIx = Object.freeze(\n                    getSetLoadedAccountsDataSizeLimitInstruction(LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A),\n                );\n                const otherIx = Object.freeze({ programAddress: '11111111111111111111111111111111' as Address });\n                const txWithExisting = { instructions: [otherIx, existingIx] as const, version };\n\n                it('replaces the existing instruction in-place when setting a different value', () => {\n                    const result = setTransactionMessageLoadedAccountsDataSizeLimit(\n                        LOADED_ACCOUNTS_DATA_SIZE_LIMIT_B,\n                        txWithExisting,\n                    );\n                    expect(result.instructions).toHaveLength(2);\n                    expect(result.instructions[0]).toBe(otherIx);\n                    expect(getLoadedAccountsDataSizeLimitFromInstructionData(result.instructions[1].data)).toBe(\n                        LOADED_ACCOUNTS_DATA_SIZE_LIMIT_B,\n                    );\n                });\n\n                it('returns the same reference when setting the same value', () => {\n                    const result = setTransactionMessageLoadedAccountsDataSizeLimit(\n                        LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                        txWithExisting,\n                    );\n                    expect(result).toBe(txWithExisting);\n                });\n\n                it('returns a new reference when setting a different value', () => {\n                    const result = setTransactionMessageLoadedAccountsDataSizeLimit(\n                        LOADED_ACCOUNTS_DATA_SIZE_LIMIT_B,\n                        txWithExisting,\n                    );\n                    expect(result).not.toBe(txWithExisting);\n                });\n            });\n\n            describe('setting to undefined', () => {\n                it('returns the same reference when no instruction exists', () => {\n                    const result = setTransactionMessageLoadedAccountsDataSizeLimit(undefined, baseTx);\n                    expect(result).toBe(baseTx);\n                });\n\n                it('removes the instruction when one exists', () => {\n                    const txWithIx = setTransactionMessageLoadedAccountsDataSizeLimit(\n                        LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n                        baseTx,\n                    );\n                    const result = setTransactionMessageLoadedAccountsDataSizeLimit(undefined, txWithIx);\n                    expect(result.instructions).toHaveLength(0);\n                });\n\n                it('preserves other instructions when removing', () => {\n                    const otherIx = { programAddress: '11111111111111111111111111111111' as Address };\n                    const limitIx = getSetLoadedAccountsDataSizeLimitInstruction(LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A);\n                    const txWithIxs: TransactionMessage = {\n                        instructions: [limitIx, otherIx],\n                        version,\n                    };\n                    const result = setTransactionMessageLoadedAccountsDataSizeLimit(undefined, txWithIxs);\n                    expect(result.instructions).toHaveLength(1);\n                    expect(result.instructions[0]).toBe(otherIx);\n                });\n            });\n        },\n    );\n});\n\ndescribe('getTransactionMessageLoadedAccountsDataSizeLimit', () => {\n    describe('given a v1 transaction', () => {\n        it('returns undefined without config', () => {\n            const tx: TransactionMessage = { instructions: [], version: 1 };\n            expect(getTransactionMessageLoadedAccountsDataSizeLimit(tx)).toBeUndefined();\n        });\n\n        it('returns the value from config', () => {\n            const tx: TransactionMessage & { version: 1 } = {\n                config: { loadedAccountsDataSizeLimit: LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A },\n                instructions: [],\n                version: 1,\n            };\n            expect(getTransactionMessageLoadedAccountsDataSizeLimit(tx)).toBe(LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A);\n        });\n    });\n\n    describe.each([{ version: 'legacy' as const }, { version: 0 as const }])(\n        'given a $version transaction',\n        ({ version }) => {\n            it('returns undefined without instruction', () => {\n                const tx: TransactionMessage = { instructions: [], version };\n                expect(getTransactionMessageLoadedAccountsDataSizeLimit(tx)).toBeUndefined();\n            });\n\n            it('returns the value from instruction', () => {\n                const tx: TransactionMessage = {\n                    instructions: [getSetLoadedAccountsDataSizeLimitInstruction(LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A)],\n                    version,\n                };\n                expect(getTransactionMessageLoadedAccountsDataSizeLimit(tx)).toBe(LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A);\n            });\n        },\n    );\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/priority-fee-lamports-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport {\n    getTransactionMessagePriorityFeeLamports,\n    setTransactionMessagePriorityFeeLamports,\n} from '../priority-fee-lamports';\nimport { TransactionMessage } from '../transaction-message';\n\nconst COMPUTE_UNIT_LIMIT_A = 200_000;\nconst HEAP_SIZE_A = 30_000;\n\nconst PRIORITY_FEE_LAMPORTS_A = 5_000n;\nconst PRIORITY_FEE_LAMPORTS_B = 10_000n;\n\ndescribe('setTransactionMessagePriorityFeeLamports', () => {\n    describe('given a v1 transaction', () => {\n        const baseTx: TransactionMessage & { version: 1 } = { instructions: [], version: 1 };\n\n        it('sets the priority fee lamports on the transaction', () => {\n            const txWithFee = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_A, baseTx);\n            expect(txWithFee).toHaveProperty('config', { priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A });\n        });\n\n        it('freezes the transaction object', () => {\n            const txWithFee = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_A, baseTx);\n            expect(txWithFee).toBeFrozenObject();\n        });\n\n        it('freezes the config object', () => {\n            const txWithFee = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_A, baseTx);\n            expect(txWithFee.config).toBeFrozenObject();\n        });\n\n        describe('given a transaction with an existing config', () => {\n            const txWithConfig = {\n                ...baseTx,\n                config: {\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    heapSize: HEAP_SIZE_A,\n                },\n            };\n\n            it('sets the priority fee lamports while preserving other config properties', () => {\n                const txWithFee = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_A, txWithConfig);\n                expect(txWithFee.config).toMatchObject({\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    heapSize: HEAP_SIZE_A,\n                    priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n                });\n            });\n\n            it('returns the same reference when setting the same priority fee lamports', () => {\n                const txWithFeeA = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_A, baseTx);\n                const txWithSameFee = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_A, txWithFeeA);\n                expect(txWithFeeA).toBe(txWithSameFee);\n            });\n\n            it('returns a new reference when setting different priority fee lamports', () => {\n                const txWithFeeA = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_A, baseTx);\n                const txWithFeeB = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_B, txWithFeeA);\n                expect(txWithFeeA).not.toBe(txWithFeeB);\n                expect(txWithFeeB.config).toHaveProperty('priorityFeeLamports', PRIORITY_FEE_LAMPORTS_B);\n            });\n        });\n\n        describe('empty config normalization', () => {\n            it('removes config when setting to undefined as only property', () => {\n                const txWithFee = setTransactionMessagePriorityFeeLamports(PRIORITY_FEE_LAMPORTS_A, baseTx);\n                const txWithoutConfig = setTransactionMessagePriorityFeeLamports(undefined, txWithFee);\n                expect(txWithoutConfig).not.toHaveProperty('config');\n            });\n\n            it('preserves config when setting to undefined with other properties present', () => {\n                const txWithConfig = {\n                    ...baseTx,\n                    config: {\n                        computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                        priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n                    },\n                };\n                const txWithoutFee = setTransactionMessagePriorityFeeLamports(undefined, txWithConfig);\n                expect(txWithoutFee).toHaveProperty('config', {\n                    computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                    priorityFeeLamports: undefined,\n                });\n            });\n        });\n    });\n});\n\ndescribe('getTransactionMessagePriorityFeeLamports', () => {\n    describe('given a v1 transaction', () => {\n        it('returns undefined without config', () => {\n            const tx: TransactionMessage & { version: 1 } = { instructions: [], version: 1 };\n            expect(getTransactionMessagePriorityFeeLamports(tx)).toBeUndefined();\n        });\n\n        it('returns the value from config', () => {\n            const tx: TransactionMessage & { version: 1 } = {\n                config: { priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A },\n                instructions: [],\n                version: 1,\n            };\n            expect(getTransactionMessagePriorityFeeLamports(tx)).toBe(PRIORITY_FEE_LAMPORTS_A);\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__tests__/v1-transaction-config-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS, SolanaError } from '@solana/errors';\n\nimport { TransactionMessage } from '../transaction-message';\nimport {\n    setTransactionMessageConfig,\n    transactionConfigMaskHasComputeUnitLimit,\n    transactionConfigMaskHasHeapSize,\n    transactionConfigMaskHasLoadedAccountsDataSizeLimit,\n    transactionConfigMaskHasPriorityFee,\n    V1TransactionConfig,\n} from '../v1-transaction-config';\n\nconst COMPUTE_UNIT_LIMIT_A = 200_000;\nconst COMPUTE_UNIT_LIMIT_B = 400_000;\n\nconst HEAP_SIZE_A = 30_000;\nconst LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A = 60_000;\nconst PRIORITY_FEE_LAMPORTS_A = 5_000n;\n\nconst baseTx: TransactionMessage & { version: 1 } = {\n    instructions: [],\n    version: 1,\n};\n\ndescribe('setTransactionMessageConfig', () => {\n    it('sets a complete config on the transaction', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n            heapSize: HEAP_SIZE_A,\n            loadedAccountsDataSizeLimit: LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n            priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n        };\n        const txWithConfig = setTransactionMessageConfig(config, baseTx);\n        expect(txWithConfig).toHaveProperty('config', config);\n    });\n\n    it('sets a partial config on the transaction', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n        };\n        const txWithConfig = setTransactionMessageConfig(config, baseTx);\n        expect(txWithConfig).toHaveProperty('config', { computeUnitLimit: COMPUTE_UNIT_LIMIT_A });\n    });\n\n    it('sets multiple properties at once', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n            priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n        };\n        const txWithConfig = setTransactionMessageConfig(config, baseTx);\n        expect(txWithConfig.config).toMatchObject({\n            computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n            priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n        });\n    });\n\n    it('freezes the transaction object', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n        };\n        const txWithConfig = setTransactionMessageConfig(config, baseTx);\n        expect(txWithConfig).toBeFrozenObject();\n    });\n\n    it('freezes the config object', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n        };\n        const txWithConfig = setTransactionMessageConfig(config, baseTx);\n        expect(txWithConfig.config).toBeFrozenObject();\n    });\n\n    describe('empty config normalization', () => {\n        it('removes config when setting empty object', () => {\n            const txWithConfig = setTransactionMessageConfig({}, baseTx);\n            expect(txWithConfig).not.toHaveProperty('config');\n        });\n\n        it('removes config when all properties are undefined', () => {\n            const config: V1TransactionConfig = {\n                computeUnitLimit: undefined,\n                heapSize: undefined,\n                loadedAccountsDataSizeLimit: undefined,\n                priorityFeeLamports: undefined,\n            };\n            const txWithConfig = setTransactionMessageConfig(config, baseTx);\n            expect(txWithConfig).not.toHaveProperty('config');\n        });\n\n        it('returns same reference when config stays absent', () => {\n            const txWithEmptyConfig = setTransactionMessageConfig({}, baseTx);\n            expect(txWithEmptyConfig).toBe(baseTx);\n        });\n    });\n\n    describe('given a transaction with no existing config', () => {\n        it('sets a new config object', () => {\n            const config: V1TransactionConfig = {\n                computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                heapSize: HEAP_SIZE_A,\n            };\n            const txWithConfig = setTransactionMessageConfig(config, baseTx);\n            expect(txWithConfig.config).toMatchObject(config);\n        });\n    });\n\n    describe('given a transaction with an existing config', () => {\n        const txWithConfig = {\n            ...baseTx,\n            config: {\n                computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                heapSize: HEAP_SIZE_A,\n            },\n        };\n\n        it('merges new config properties with existing ones', () => {\n            const newConfig: V1TransactionConfig = {\n                priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n            };\n            const txWithMergedConfig = setTransactionMessageConfig(newConfig, txWithConfig);\n            expect(txWithMergedConfig.config).toMatchObject({\n                computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                heapSize: HEAP_SIZE_A,\n                priorityFeeLamports: PRIORITY_FEE_LAMPORTS_A,\n            });\n        });\n\n        it('preserves existing config properties not being updated', () => {\n            const newConfig: V1TransactionConfig = {\n                loadedAccountsDataSizeLimit: LOADED_ACCOUNTS_DATA_SIZE_LIMIT_A,\n            };\n            const txWithMergedConfig = setTransactionMessageConfig(newConfig, txWithConfig);\n            expect(txWithMergedConfig.config).toHaveProperty('computeUnitLimit', COMPUTE_UNIT_LIMIT_A);\n            expect(txWithMergedConfig.config).toHaveProperty('heapSize', HEAP_SIZE_A);\n        });\n\n        it('overwrites existing config properties with new values', () => {\n            const newConfig: V1TransactionConfig = {\n                computeUnitLimit: COMPUTE_UNIT_LIMIT_B,\n            };\n            const txWithUpdatedConfig = setTransactionMessageConfig(newConfig, txWithConfig);\n            expect(txWithUpdatedConfig.config).toHaveProperty('computeUnitLimit', COMPUTE_UNIT_LIMIT_B);\n        });\n\n        it('returns the same reference when setting identical config', () => {\n            const sameConfig: V1TransactionConfig = {\n                computeUnitLimit: COMPUTE_UNIT_LIMIT_A,\n                heapSize: HEAP_SIZE_A,\n            };\n            const txWithSameConfig = setTransactionMessageConfig(sameConfig, txWithConfig);\n            expect(txWithSameConfig).toBe(txWithConfig);\n        });\n\n        it('returns a new reference when setting different config', () => {\n            const differentConfig: V1TransactionConfig = {\n                computeUnitLimit: COMPUTE_UNIT_LIMIT_B,\n            };\n            const txWithDifferentConfig = setTransactionMessageConfig(differentConfig, txWithConfig);\n            expect(txWithDifferentConfig).not.toBe(txWithConfig);\n        });\n\n        it('removes config when overwriting all values with undefined', () => {\n            const undefinedConfig: V1TransactionConfig = {\n                computeUnitLimit: undefined,\n                heapSize: undefined,\n            };\n            const txWithoutConfig = setTransactionMessageConfig(undefinedConfig, txWithConfig);\n            expect(txWithoutConfig).not.toHaveProperty('config');\n        });\n    });\n\n    describe('setting undefined values', () => {\n        it('can set individual properties to undefined', () => {\n            const txWithConfig = setTransactionMessageConfig(\n                { computeUnitLimit: COMPUTE_UNIT_LIMIT_A, heapSize: HEAP_SIZE_A },\n                baseTx,\n            );\n            const txWithUndefined = setTransactionMessageConfig({ computeUnitLimit: undefined }, txWithConfig);\n            expect(txWithUndefined.config).toHaveProperty('computeUnitLimit', undefined);\n            expect(txWithUndefined.config).toHaveProperty('heapSize', HEAP_SIZE_A);\n        });\n\n        it('removes config when last property set to undefined', () => {\n            const txWithConfig = setTransactionMessageConfig({ computeUnitLimit: COMPUTE_UNIT_LIMIT_A }, baseTx);\n            const txWithoutConfig = setTransactionMessageConfig({ computeUnitLimit: undefined }, txWithConfig);\n            expect(txWithoutConfig).not.toHaveProperty('config');\n        });\n    });\n});\n\ndescribe('transactionConfigMaskHasPriorityFee', () => {\n    it('returns true when both bits 0 and 1 are set', () => {\n        const mask = 0b11;\n        expect(transactionConfigMaskHasPriorityFee(mask)).toBe(true);\n    });\n\n    it('returns false when both bits 0 and 1 are unset', () => {\n        const mask = 0b00;\n        expect(transactionConfigMaskHasPriorityFee(mask)).toBe(false);\n    });\n\n    it('returns true when priority fee bits are set with other bits', () => {\n        const mask = 0b11111;\n        expect(transactionConfigMaskHasPriorityFee(mask)).toBe(true);\n    });\n\n    it('returns false when priority fee bits are unset but other bits are set', () => {\n        const mask = 0b11100;\n        expect(transactionConfigMaskHasPriorityFee(mask)).toBe(false);\n    });\n\n    it('throws when only bit 0 is set', () => {\n        const mask = 0b01;\n        expect(() => transactionConfigMaskHasPriorityFee(mask)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS, { mask }),\n        );\n    });\n\n    it('throws when only bit 1 is set', () => {\n        const mask = 0b10;\n        expect(() => transactionConfigMaskHasPriorityFee(mask)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS, { mask }),\n        );\n    });\n});\n\ndescribe('transactionConfigMaskHasComputeUnitLimit', () => {\n    it('returns true when bit 2 is set', () => {\n        const mask = 0b100;\n        expect(transactionConfigMaskHasComputeUnitLimit(mask)).toBe(true);\n    });\n\n    it('returns false when bit 2 is unset', () => {\n        const mask = 0b0;\n        expect(transactionConfigMaskHasComputeUnitLimit(mask)).toBe(false);\n    });\n\n    it('returns true when bit 2 is set with other bits', () => {\n        const mask = 0b111;\n        expect(transactionConfigMaskHasComputeUnitLimit(mask)).toBe(true);\n    });\n\n    it('returns false when bit 2 is unset but other bits are set', () => {\n        const mask = 0b11011;\n        expect(transactionConfigMaskHasComputeUnitLimit(mask)).toBe(false);\n    });\n});\n\ndescribe('transactionConfigMaskHasLoadedAccountsDataSizeLimit', () => {\n    it('returns true when bit 3 is set', () => {\n        const mask = 0b1000;\n        expect(transactionConfigMaskHasLoadedAccountsDataSizeLimit(mask)).toBe(true);\n    });\n\n    it('returns false when bit 3 is unset', () => {\n        const mask = 0b0;\n        expect(transactionConfigMaskHasLoadedAccountsDataSizeLimit(mask)).toBe(false);\n    });\n\n    it('returns true when bit 3 is set with other bits', () => {\n        const mask = 0b1111;\n        expect(transactionConfigMaskHasLoadedAccountsDataSizeLimit(mask)).toBe(true);\n    });\n\n    it('returns false when bit 3 is unset but other bits are set', () => {\n        const mask = 0b10111;\n        expect(transactionConfigMaskHasLoadedAccountsDataSizeLimit(mask)).toBe(false);\n    });\n});\n\ndescribe('transactionConfigMaskHasHeapSize', () => {\n    it('returns true when bit 4 is set', () => {\n        const mask = 0b10000;\n        expect(transactionConfigMaskHasHeapSize(mask)).toBe(true);\n    });\n\n    it('returns false when bit 4 is unset', () => {\n        const mask = 0b0;\n        expect(transactionConfigMaskHasHeapSize(mask)).toBe(false);\n    });\n\n    it('returns true when bit 4 is set with other bits', () => {\n        const mask = 0b11111;\n        expect(transactionConfigMaskHasHeapSize(mask)).toBe(true);\n    });\n\n    it('returns false when bit 4 is unset but other bits are set', () => {\n        const mask = 0b01111;\n        expect(transactionConfigMaskHasHeapSize(mask)).toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/blockhash-typetest.ts",
    "content": "import { Blockhash } from '@solana/rpc-types';\n\nimport {\n    assertIsTransactionMessageWithBlockhashLifetime,\n    isTransactionMessageWithBlockhashLifetime,\n    setTransactionMessageLifetimeUsingBlockhash,\n    TransactionMessageWithBlockhashLifetime,\n} from '../blockhash';\nimport { TransactionMessage } from '../transaction-message';\n\nconst mockBlockhash = null as unknown as Blockhash;\nconst mockBlockhashLifetime = { blockhash: mockBlockhash, lastValidBlockHeight: 0n };\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\n\n// [DESCRIBE] isTransactionMessageWithBlockhashLifetime\n{\n    // It narrows the transaction message type to one with a blockhash-based lifetime.\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        if (isTransactionMessageWithBlockhashLifetime(message)) {\n            message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };\n        } else {\n            message satisfies TransactionMessage & { some: 1 };\n            // @ts-expect-error It does not have a blockhash-based lifetime.\n            message satisfies TransactionMessageWithBlockhashLifetime;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsTransactionMessageWithBlockhashLifetime\n{\n    // It narrows the transaction message type to one with a blockhash-based lifetime.\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        // @ts-expect-error Should not be blockhash lifetime\n        message satisfies TransactionMessageWithBlockhashLifetime;\n        // @ts-expect-error Should not satisfy has blockhash\n        message satisfies { lifetimeConstraint: { blockhash: Blockhash } };\n        // @ts-expect-error Should not satisfy has lastValidBlockHeight\n        message satisfies { lifetimeConstraint: { lastValidBlockHeight: bigint } };\n        assertIsTransactionMessageWithBlockhashLifetime(message);\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };\n        message satisfies TransactionMessageWithBlockhashLifetime;\n        message satisfies { lifetimeConstraint: { blockhash: Blockhash } };\n        message satisfies { lifetimeConstraint: { lastValidBlockHeight: bigint } };\n    }\n}\n\n// [DESCRIBE] setTransactionMessageLifetimeUsingBlockhash\n{\n    // It sets the blockhash lifetime on the transaction message for v0 messages.\n    {\n        const message = null as unknown as V0TransactionMessage & { some: 1 };\n        const newMessage = setTransactionMessageLifetimeUsingBlockhash(mockBlockhashLifetime, message);\n        newMessage satisfies TransactionMessageWithBlockhashLifetime & V0TransactionMessage & { some: 1 };\n        // @ts-expect-error Should not be a legacy message.\n        newMessage satisfies LegacyTransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };\n    }\n\n    // It sets the blockhash lifetime on the transaction message for legacy messages.\n    {\n        const message = null as unknown as LegacyTransactionMessage & { some: 1 };\n        const newMessage = setTransactionMessageLifetimeUsingBlockhash(mockBlockhashLifetime, message);\n        newMessage satisfies LegacyTransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };\n        // @ts-expect-error Should not be a v0 message.\n        newMessage satisfies TransactionMessageWithBlockhashLifetime & V0TransactionMessage & { some: 1 };\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/compress-transaction-message-typetest.ts",
    "content": "import { AccountLookupMeta, AccountMeta, AccountRole, Instruction } from '@solana/instructions';\n\nimport { TransactionMessageWithBlockhashLifetime } from '../blockhash';\nimport { compressTransactionMessageUsingAddressLookupTables } from '../compress-transaction-message';\nimport { TransactionMessageWithFeePayer } from '../fee-payer';\nimport { TransactionMessage } from '../transaction-message';\n\ntype v0TransactionMessage = TransactionMessage & { version: 0 };\n\ntype AddressesByLookupTableAddress = Parameters<typeof compressTransactionMessageUsingAddressLookupTables>[1];\nconst addressesByLookupTableAddress = null as unknown as AddressesByLookupTableAddress;\n\n// [DESCRIBE] compressTransactionMessageUsingAddressLookupTables\n{\n    // It returns the input type or a widened version of it\n    {\n        const message = null as unknown as v0TransactionMessage;\n        const result = compressTransactionMessageUsingAddressLookupTables(message, addressesByLookupTableAddress);\n        result satisfies v0TransactionMessage;\n    }\n\n    // It accepts only v0 transaction messages\n    {\n        const invalidMessage = null as unknown as Exclude<TransactionMessage, { version: 0 }>;\n        // @ts-expect-error Only v0 messages are accepted.\n        compressTransactionMessageUsingAddressLookupTables(invalidMessage, addressesByLookupTableAddress);\n    }\n\n    // It preserves the fee payer type\n    {\n        const message = null as unknown as TransactionMessageWithFeePayer & v0TransactionMessage;\n        const result = compressTransactionMessageUsingAddressLookupTables(message, addressesByLookupTableAddress);\n        result satisfies TransactionMessageWithFeePayer;\n    }\n\n    // It preserves the blockhash lifetime type\n    {\n        const message = null as unknown as TransactionMessageWithBlockhashLifetime & v0TransactionMessage;\n        const result = compressTransactionMessageUsingAddressLookupTables(message, addressesByLookupTableAddress);\n        result satisfies TransactionMessageWithBlockhashLifetime;\n    }\n\n    // It preserves additional properties\n    {\n        const message = null as unknown as v0TransactionMessage & { some: 1 };\n        const result = compressTransactionMessageUsingAddressLookupTables(message, addressesByLookupTableAddress);\n        result satisfies { some: 1 };\n    }\n\n    // It widens AccountMeta to include AccountLookupMeta in instruction accounts\n    {\n        type MyInstruction = Instruction<\n            '1111',\n            readonly [AccountMeta<'aaaa'> & { readonly role: AccountRole.WRITABLE }]\n        >;\n        const message = null as unknown as { readonly instructions: readonly MyInstruction[]; readonly version: 0 };\n        const result = compressTransactionMessageUsingAddressLookupTables(message, addressesByLookupTableAddress);\n        const accounts = result.instructions[0].accounts!;\n        accounts[0] satisfies AccountLookupMeta<'aaaa'> | AccountMeta<'aaaa'>;\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/compute-unit-limit-typetest.ts",
    "content": "import { TransactionMessage } from '..';\nimport { getTransactionMessageComputeUnitLimit, setTransactionMessageComputeUnitLimit } from '../compute-unit-limit';\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\ntype V1TransactionMessage = Extract<TransactionMessage, { version: 1 }>;\n\n// [DESCRIBE] setTransactionMessageComputeUnitLimit\n{\n    // It accepts v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = setTransactionMessageComputeUnitLimit(200_000, message);\n        result satisfies V1TransactionMessage;\n    }\n\n    // It accepts legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = setTransactionMessageComputeUnitLimit(200_000, message);\n        result satisfies LegacyTransactionMessage;\n    }\n\n    // It accepts v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = setTransactionMessageComputeUnitLimit(200_000, message);\n        result satisfies V0TransactionMessage;\n    }\n\n    // It preserves input type\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessageComputeUnitLimit(200_000, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n\n    // It preserves input type for legacy\n    {\n        const message = null as unknown as LegacyTransactionMessage & { some: 1 };\n        const result = setTransactionMessageComputeUnitLimit(200_000, message);\n        result satisfies LegacyTransactionMessage & { some: 1 };\n    }\n\n    // It can set undefined value\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessageComputeUnitLimit(undefined, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n\n    // It can set undefined value for legacy\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = setTransactionMessageComputeUnitLimit(undefined, message);\n        result satisfies LegacyTransactionMessage;\n    }\n}\n\n// [DESCRIBE] getTransactionMessageComputeUnitLimit\n{\n    // It returns number | undefined for v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = getTransactionMessageComputeUnitLimit(message);\n        result satisfies number | undefined;\n    }\n\n    // It returns number | undefined for legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = getTransactionMessageComputeUnitLimit(message);\n        result satisfies number | undefined;\n    }\n\n    // It returns number | undefined for v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = getTransactionMessageComputeUnitLimit(message);\n        result satisfies number | undefined;\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/compute-unit-price-typetest.ts",
    "content": "import { TransactionMessage } from '..';\nimport { getTransactionMessageComputeUnitPrice, setTransactionMessageComputeUnitPrice } from '../compute-unit-price';\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\ntype V1TransactionMessage = Extract<TransactionMessage, { version: 1 }>;\n\n// [DESCRIBE] setTransactionMessageComputeUnitPrice\n{\n    // It accepts legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = setTransactionMessageComputeUnitPrice(10_000n, message);\n        result satisfies LegacyTransactionMessage;\n    }\n\n    // It accepts v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = setTransactionMessageComputeUnitPrice(10_000n, message);\n        result satisfies V0TransactionMessage;\n    }\n\n    // It rejects v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        // @ts-expect-error v1 messages are not supported\n        setTransactionMessageComputeUnitPrice(10_000n, message);\n    }\n\n    // It preserves input type for legacy\n    {\n        const message = null as unknown as LegacyTransactionMessage & { some: 1 };\n        const result = setTransactionMessageComputeUnitPrice(10_000n, message);\n        result satisfies LegacyTransactionMessage & { some: 1 };\n    }\n\n    // It preserves input type for v0\n    {\n        const message = null as unknown as V0TransactionMessage & { some: 1 };\n        const result = setTransactionMessageComputeUnitPrice(10_000n, message);\n        result satisfies V0TransactionMessage & { some: 1 };\n    }\n\n    // It can set undefined value for legacy\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = setTransactionMessageComputeUnitPrice(undefined, message);\n        result satisfies LegacyTransactionMessage;\n    }\n\n    // It can set undefined value for v0\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = setTransactionMessageComputeUnitPrice(undefined, message);\n        result satisfies V0TransactionMessage;\n    }\n}\n\n// [DESCRIBE] getTransactionMessageComputeUnitPrice\n{\n    // It returns bigint | undefined for legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = getTransactionMessageComputeUnitPrice(message);\n        result satisfies bigint | undefined;\n    }\n\n    // It returns bigint | undefined for v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = getTransactionMessageComputeUnitPrice(message);\n        result satisfies bigint | undefined;\n    }\n\n    // It rejects v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        // @ts-expect-error v1 messages are not supported\n        getTransactionMessageComputeUnitPrice(message);\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/create-transaction-message-typetest.ts",
    "content": "import { createTransactionMessage } from '../create-transaction-message';\nimport { TransactionMessage } from '../transaction-message';\nimport { TransactionMessageWithinSizeLimit } from '../transaction-message-size';\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\n\n// It creates legacy transaction messages.\n{\n    const message = createTransactionMessage({ version: 'legacy' });\n    message satisfies LegacyTransactionMessage;\n    // @ts-expect-error Should not be V0.\n    message satisfies V0TransactionMessage;\n}\n\n// It creates v0 transaction messages.\n{\n    const message = createTransactionMessage({ version: 0 });\n    message satisfies V0TransactionMessage;\n    // @ts-expect-error Should not be legacy.\n    message satisfies LegacyTransactionMessage;\n}\n\n// It does not create v1 transaction messages.\n{\n    // @ts-expect-error Does not support version 1.\n    createTransactionMessage({ version: 1 });\n}\n\n// It returns an empty transaction message with size limit type safety.\n{\n    createTransactionMessage({ version: 'legacy' }) satisfies TransactionMessageWithinSizeLimit;\n    createTransactionMessage({ version: 0 }) satisfies TransactionMessageWithinSizeLimit;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/durable-nonce-typetest.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport { Instruction } from '@solana/instructions';\n\nimport { TransactionMessageWithBlockhashLifetime } from '../blockhash';\nimport { createTransactionMessage } from '../create-transaction-message';\nimport {\n    assertIsTransactionMessageWithDurableNonceLifetime,\n    isTransactionMessageWithDurableNonceLifetime,\n    Nonce,\n    setTransactionMessageLifetimeUsingDurableNonce,\n    TransactionMessageWithDurableNonceLifetime,\n} from '../durable-nonce';\nimport { AdvanceNonceAccountInstruction } from '../durable-nonce-instruction';\nimport { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../fee-payer';\nimport { appendTransactionMessageInstruction } from '../instructions';\nimport { TransactionMessage } from '../transaction-message';\nimport { TransactionMessageWithinSizeLimit } from '../transaction-message-size';\n\nconst mockNonceConfig = {\n    nonce: null as unknown as Nonce<'nonce'>,\n    nonceAccountAddress: null as unknown as Address<'nonce'>,\n    nonceAuthorityAddress: null as unknown as Address<'nonceAuthority'>,\n};\n\nconst newMockNonceConfig = {\n    nonce: null as unknown as Nonce<'newNonce'>,\n    nonceAccountAddress: null as unknown as Address<'newNonce'>,\n    nonceAuthorityAddress: null as unknown as Address<'newNonceAuthority'>,\n};\n\ntype InstructionA = Instruction & { identifier: 'A' };\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\n\n// [DESCRIBE] isTransactionMessageWithDurableNonceLifetime\n{\n    // It narrows the transaction message type to one with a nonce-based lifetime.\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        if (isTransactionMessageWithDurableNonceLifetime(message)) {\n            message satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime & { some: 1 };\n        } else {\n            message satisfies TransactionMessage & { some: 1 };\n            // @ts-expect-error It does not have a nonce-based lifetime.\n            message satisfies TransactionMessageWithDurableNonceLifetime;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsTransactionMessageWithDurableNonceLifetime\n{\n    // It narrows the transaction message type to one with a nonce-based lifetime.\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        // @ts-expect-error Should not be durable nonce lifetime\n        message satisfies TransactionMessageWithDurableNonceLifetime;\n        // @ts-expect-error Should not have a nonce-based lifetime\n        message satisfies { lifetimeConstraint: { nonce: Nonce } };\n        // @ts-expect-error Should not start with a nonce instruction.\n        message.instructions[0] satisfies AdvanceNonceAccountInstruction;\n        assertIsTransactionMessageWithDurableNonceLifetime(message);\n        message satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime & { some: 1 };\n        message satisfies TransactionMessageWithDurableNonceLifetime;\n        message satisfies { lifetimeConstraint: { nonce: Nonce } };\n        message.instructions[0] satisfies AdvanceNonceAccountInstruction;\n    }\n}\n\n// [DESCRIBE] setTransactionMessageLifetimeUsingDurableNonce\n{\n    // It sets the durable nonce lifetime on the transaction message for v0 messages.\n    {\n        const message = null as unknown as V0TransactionMessage & { some: 1 };\n        const newMessage = setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, message);\n        newMessage satisfies TransactionMessageWithDurableNonceLifetime & V0TransactionMessage & { some: 1 };\n        // @ts-expect-error Should not be a legacy message.\n        newMessage satisfies LegacyTransactionMessage & TransactionMessageWithDurableNonceLifetime & { some: 1 };\n    }\n\n    // It sets the durable nonce lifetime on the transaction message for legacy messages.\n    {\n        const message = null as unknown as LegacyTransactionMessage & { some: 1 };\n        const newMessage = setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, message);\n        newMessage satisfies LegacyTransactionMessage & TransactionMessageWithDurableNonceLifetime & { some: 1 };\n        // @ts-expect-error Should not be a v0 message.\n        newMessage satisfies TransactionMessageWithDurableNonceLifetime & V0TransactionMessage & { some: 1 };\n    }\n\n    // It prepends the nonce instruction to the transaction message.\n    {\n        const feePayer = null as unknown as Address;\n        const message = pipe(\n            createTransactionMessage({ version: 0 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => appendTransactionMessageInstruction(null as unknown as InstructionA, m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, m),\n        );\n\n        message satisfies TransactionMessage & TransactionMessageWithFeePayer;\n        message satisfies TransactionMessageWithDurableNonceLifetime<'nonce', 'nonceAuthority', 'nonce'>;\n        message.instructions satisfies readonly [\n            AdvanceNonceAccountInstruction<'nonce', 'nonceAuthority'>,\n            InstructionA,\n        ];\n    }\n\n    // It replaces the existing nonce instruction with the new one.\n    {\n        const feePayer = null as unknown as Address;\n        const message = pipe(\n            createTransactionMessage({ version: 0 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => appendTransactionMessageInstruction(null as unknown as InstructionA, m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(newMockNonceConfig, m),\n        );\n\n        message satisfies TransactionMessage & TransactionMessageWithFeePayer;\n        message satisfies TransactionMessageWithDurableNonceLifetime<'newNonce', 'newNonceAuthority', 'newNonce'>;\n        message.instructions satisfies readonly [\n            AdvanceNonceAccountInstruction<'newNonce', 'newNonceAuthority'>,\n            InstructionA,\n        ];\n    }\n\n    // It keeps the size limit type safety if we are only updating the durable nonce lifetime.\n    {\n        const message = null as unknown as TransactionMessage &\n            TransactionMessageWithDurableNonceLifetime &\n            TransactionMessageWithinSizeLimit;\n        const newMessage = setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, message);\n        newMessage satisfies TransactionMessageWithinSizeLimit;\n    }\n\n    // It removes the size limit type safety if we previously has a blockhash lifetime.\n    {\n        const message = null as unknown as TransactionMessage &\n            TransactionMessageWithBlockhashLifetime &\n            TransactionMessageWithinSizeLimit;\n        const newMessage = setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, message);\n        // @ts-expect-error The message may no longer be within size limit.\n        newMessage satisfies TransactionMessageWithinSizeLimit;\n    }\n\n    // It removes the size limit type safety if we previously had no lifetime set.\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithinSizeLimit;\n        const newMessage = setTransactionMessageLifetimeUsingDurableNonce(mockNonceConfig, message);\n        // @ts-expect-error The message may no longer be within size limit.\n        newMessage satisfies TransactionMessageWithinSizeLimit;\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/fee-payer-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { TransactionMessageWithBlockhashLifetime } from '../blockhash';\nimport { TransactionMessageWithDurableNonceLifetime } from '../durable-nonce';\nimport { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../fee-payer';\nimport { TransactionMessage } from '../transaction-message';\n\nconst mockFeePayer = 'mock' as Address<'mockFeePayer'>;\nconst aliceAddress = 'alice' as Address<'alice'>;\nconst bobAddress = 'bob' as Address<'bob'>;\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\n\n// [DESCRIBE] setTransactionFeePayer\n{\n    // It adds the fee payer to the new message\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        const messageWithFeePayer = setTransactionMessageFeePayer(aliceAddress, message);\n        messageWithFeePayer satisfies TransactionMessage & TransactionMessageWithFeePayer<'alice'> & { some: 1 };\n    }\n\n    // It *replaces* an existing fee payer with the new one\n    {\n        const messageWithAliceFeePayer = null as unknown as TransactionMessage &\n            TransactionMessageWithFeePayer<'alice'> & { some: 1 };\n        const messageWithBobFeePayer = setTransactionMessageFeePayer(bobAddress, messageWithAliceFeePayer);\n        messageWithBobFeePayer satisfies TransactionMessage & TransactionMessageWithFeePayer<'bob'> & { some: 1 };\n        // @ts-expect-error Alice should no longer be a payer.\n        messageWithBobFeePayer satisfies TransactionMessageWithFeePayer<'alice'>;\n    }\n\n    // Legacy messages with no lifetimes.\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);\n        messageWithFeePayer satisfies LegacyTransactionMessage & TransactionMessageWithFeePayer<'mockFeePayer'>;\n        // @ts-expect-error Should not be V0.\n        messageWithFeePayer satisfies TransactionMessageWithFeePayer<'mockFeePayer'> & V0TransactionMessage;\n    }\n\n    // V0 messages with no lifetimes.\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);\n        messageWithFeePayer satisfies TransactionMessageWithFeePayer<'mockFeePayer'> & V0TransactionMessage;\n        // @ts-expect-error Should not be legacy.\n        messageWithFeePayer satisfies LegacyTransactionMessage & TransactionMessageWithFeePayer<'mockFeePayer'>;\n    }\n\n    // Legacy messages with blockhash lifetime.\n    {\n        const message = null as unknown as LegacyTransactionMessage & TransactionMessageWithBlockhashLifetime;\n        const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);\n        messageWithFeePayer satisfies LegacyTransactionMessage &\n            TransactionMessageWithBlockhashLifetime &\n            TransactionMessageWithFeePayer<'mockFeePayer'>;\n        // @ts-expect-error Should not be V0.\n        messageWithFeePayer satisfies TransactionMessageWithBlockhashLifetime &\n            TransactionMessageWithFeePayer<'mockFeePayer'> &\n            V0TransactionMessage;\n    }\n\n    // V0 messages with blockhash lifetime.\n    {\n        const message = null as unknown as TransactionMessageWithBlockhashLifetime & V0TransactionMessage;\n        const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);\n        messageWithFeePayer satisfies TransactionMessageWithBlockhashLifetime &\n            TransactionMessageWithFeePayer<'mockFeePayer'> &\n            V0TransactionMessage;\n        // @ts-expect-error Should not be legacy.\n        messageWithFeePayer satisfies LegacyTransactionMessage &\n            TransactionMessageWithBlockhashLifetime &\n            TransactionMessageWithFeePayer<'mockFeePayer'>;\n    }\n\n    // Legacy messages with durable nonce lifetime.\n    {\n        const message = null as unknown as LegacyTransactionMessage & TransactionMessageWithDurableNonceLifetime;\n        const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);\n        messageWithFeePayer satisfies LegacyTransactionMessage &\n            TransactionMessageWithDurableNonceLifetime &\n            TransactionMessageWithFeePayer<'mockFeePayer'>;\n        // @ts-expect-error Should not be V0.\n        messageWithFeePayer satisfies TransactionMessageWithDurableNonceLifetime &\n            TransactionMessageWithFeePayer<'mockFeePayer'> &\n            V0TransactionMessage;\n    }\n\n    // V0 messages with durable nonce lifetime.\n    {\n        const message = null as unknown as TransactionMessageWithDurableNonceLifetime & V0TransactionMessage;\n        const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);\n        messageWithFeePayer satisfies TransactionMessageWithDurableNonceLifetime &\n            TransactionMessageWithFeePayer<'mockFeePayer'> &\n            V0TransactionMessage;\n        // @ts-expect-error Should not be legacy.\n        messageWithFeePayer satisfies LegacyTransactionMessage &\n            TransactionMessageWithDurableNonceLifetime &\n            TransactionMessageWithFeePayer<'mockFeePayer'>;\n    }\n\n    // It can narrow the result by transaction version\n    {\n        type TransactionMessageNotLegacy = Exclude<TransactionMessage, { version: 'legacy' }>;\n\n        const message = null as unknown as TransactionMessage;\n        const messageWithFeePayer = setTransactionMessageFeePayer(mockFeePayer, message);\n        // @ts-expect-error Could be legacy\n        messageWithFeePayer satisfies TransactionMessageNotLegacy;\n        if (messageWithFeePayer.version === 0) {\n            messageWithFeePayer satisfies TransactionMessageNotLegacy;\n        }\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/heap-size-typetest.ts",
    "content": "import { TransactionMessage } from '..';\nimport { getTransactionMessageHeapSize, setTransactionMessageHeapSize } from '../heap-size';\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\ntype V1TransactionMessage = Extract<TransactionMessage, { version: 1 }>;\n\n// [DESCRIBE] setTransactionMessageHeapSize\n{\n    // It accepts v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = setTransactionMessageHeapSize(256_000, message);\n        result satisfies V1TransactionMessage;\n    }\n\n    // It accepts legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = setTransactionMessageHeapSize(256_000, message);\n        result satisfies LegacyTransactionMessage;\n    }\n\n    // It accepts v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = setTransactionMessageHeapSize(256_000, message);\n        result satisfies V0TransactionMessage;\n    }\n\n    // It preserves input type\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessageHeapSize(256_000, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n\n    // It preserves input type for legacy\n    {\n        const message = null as unknown as LegacyTransactionMessage & { some: 1 };\n        const result = setTransactionMessageHeapSize(256_000, message);\n        result satisfies LegacyTransactionMessage & { some: 1 };\n    }\n\n    // It can set undefined value\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessageHeapSize(undefined, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n\n    // It can set undefined value for legacy\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = setTransactionMessageHeapSize(undefined, message);\n        result satisfies LegacyTransactionMessage;\n    }\n}\n\n// [DESCRIBE] getTransactionMessageHeapSize\n{\n    // It returns number | undefined for v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = getTransactionMessageHeapSize(message);\n        result satisfies number | undefined;\n    }\n\n    // It returns number | undefined for legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = getTransactionMessageHeapSize(message);\n        result satisfies number | undefined;\n    }\n\n    // It returns number | undefined for v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = getTransactionMessageHeapSize(message);\n        result satisfies number | undefined;\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/instructions-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\n\nimport { setTransactionMessageLifetimeUsingBlockhash, TransactionMessageWithBlockhashLifetime } from '../blockhash';\nimport { createTransactionMessage } from '../create-transaction-message';\nimport {\n    setTransactionMessageLifetimeUsingDurableNonce,\n    TransactionMessageWithDurableNonceLifetime,\n} from '../durable-nonce';\nimport { AdvanceNonceAccountInstruction } from '../durable-nonce-instruction';\nimport { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../fee-payer';\nimport {\n    appendTransactionMessageInstruction,\n    appendTransactionMessageInstructions,\n    prependTransactionMessageInstruction,\n    prependTransactionMessageInstructions,\n} from '../instructions';\nimport { TransactionMessage } from '../transaction-message';\nimport { TransactionMessageWithinSizeLimit } from '../transaction-message-size';\n\ntype Instruction = TransactionMessage['instructions'][number];\ntype InstructionA = Instruction & { identifier: 'A' };\ntype InstructionB = Instruction & { identifier: 'B' };\ntype InstructionC = Instruction & { identifier: 'C' };\n\ntype TransactionMessageNotLegacy = Exclude<TransactionMessage, { version: 'legacy' }>;\n\n// [DESCRIBE] appendTransactionMessageInstruction\n{\n    // It returns the same TransactionMessage type\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        const newMessage = appendTransactionMessageInstruction(null as unknown as Instruction, message);\n        newMessage satisfies TransactionMessage & { some: 1 };\n    }\n\n    // It concatenates the instruction types\n    {\n        const message = null as unknown as { instructions: [InstructionA]; version: 0 };\n        const newMessage = appendTransactionMessageInstruction(null as unknown as InstructionB, message);\n        newMessage.instructions satisfies readonly [InstructionA, InstructionB];\n        // @ts-expect-error Wrong order.\n        newMessage.instructions satisfies readonly [InstructionB, InstructionA];\n        // @ts-expect-error Not readonly.\n        newMessage.instructions satisfies [InstructionA, InstructionB];\n    }\n\n    // It adds instruction types to base transaction messages\n    {\n        const message = null as unknown as TransactionMessage;\n        const newMessage = appendTransactionMessageInstruction(null as unknown as InstructionA, message);\n        newMessage.instructions satisfies readonly [...Instruction[], InstructionA];\n    }\n\n    // It keeps the blockhash lifetime type safety.\n    {\n        const feePayer = null as unknown as Address;\n        const blockhash = null as unknown as Parameters<typeof setTransactionMessageLifetimeUsingBlockhash>[0];\n        const message = pipe(\n            createTransactionMessage({ version: 0 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhash, m),\n            m => appendTransactionMessageInstruction(null as unknown as InstructionA, m),\n        );\n\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime & TransactionMessageWithFeePayer;\n        message.instructions satisfies readonly [InstructionA];\n    }\n\n    // It keeps the durable nonce lifetime type safety.\n    {\n        const feePayer = null as unknown as Address;\n        const nonceConfig = null as unknown as Parameters<typeof setTransactionMessageLifetimeUsingDurableNonce>[0];\n        const message = pipe(\n            createTransactionMessage({ version: 0 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(nonceConfig, m),\n            m => appendTransactionMessageInstruction(null as unknown as InstructionA, m),\n        );\n\n        message satisfies TransactionMessage &\n            TransactionMessageWithDurableNonceLifetime &\n            TransactionMessageWithFeePayer;\n        message.instructions satisfies readonly [AdvanceNonceAccountInstruction, InstructionA];\n    }\n\n    // It removes the size limit type safety.\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithinSizeLimit;\n        const newMessage = appendTransactionMessageInstruction(null as unknown as Instruction, message);\n        // @ts-expect-error Potentially no longer within size limit.\n        newMessage satisfies TransactionMessageWithinSizeLimit;\n    }\n\n    // It can narrow the version type\n    {\n        const message = null as unknown as TransactionMessage;\n        const newMessage = appendTransactionMessageInstruction(null as unknown as Instruction, message);\n        // @ts-expect-error Could be legacy\n        newMessage satisfies TransactionMessageNotLegacy;\n        if (newMessage.version === 0) {\n            newMessage satisfies TransactionMessageNotLegacy;\n        }\n    }\n}\n\n// [DESCRIBE] appendTransactionMessageInstructions\n{\n    // It returns the same TransactionMessage type\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        const newMessage = appendTransactionMessageInstructions(null as unknown as Instruction[], message);\n        newMessage satisfies TransactionMessage & { some: 1 };\n    }\n\n    // It concatenates the instruction types\n    {\n        const message = null as unknown as { instructions: [InstructionA]; version: 0 };\n        const newMessage = appendTransactionMessageInstructions(\n            [null as unknown as InstructionB, null as unknown as InstructionC],\n            message,\n        );\n        newMessage.instructions satisfies readonly [InstructionA, InstructionB, InstructionC];\n        // @ts-expect-error Wrong order.\n        newMessage.instructions satisfies readonly [InstructionC, InstructionB, InstructionA];\n        // @ts-expect-error Not readonly.\n        newMessage.instructions satisfies [InstructionA, InstructionB, InstructionC];\n    }\n\n    // It adds instruction types to base transaction messages\n    {\n        const message = null as unknown as TransactionMessage;\n        const newMessage = appendTransactionMessageInstructions(\n            [null as unknown as InstructionA, null as unknown as InstructionB],\n            message,\n        );\n        newMessage.instructions satisfies readonly [...Instruction[], InstructionA, InstructionB];\n    }\n\n    // It removes the size limit type safety.\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithinSizeLimit;\n        const newMessage = appendTransactionMessageInstructions([null as unknown as Instruction], message);\n        // @ts-expect-error Potentially no longer within size limit.\n        newMessage satisfies TransactionMessageWithinSizeLimit;\n    }\n\n    // It can narrow the version type\n    {\n        const message = null as unknown as TransactionMessage;\n        const newMessage = appendTransactionMessageInstructions([null as unknown as Instruction], message);\n        // @ts-expect-error Could be legacy\n        newMessage satisfies TransactionMessageNotLegacy;\n        if (newMessage.version === 0) {\n            newMessage satisfies TransactionMessageNotLegacy;\n        }\n    }\n}\n\n// [DESCRIBE] prependTransactionMessageInstruction\n{\n    // It returns the same TransactionMessage type\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        const newMessage = prependTransactionMessageInstruction(null as unknown as Instruction, message);\n        newMessage satisfies TransactionMessage & { some: 1 };\n    }\n\n    // It strips the durable nonce transaction message type\n    {\n        const message = null as unknown as TransactionMessage &\n            TransactionMessageWithDurableNonceLifetime & { some: 1 };\n        const newMessage = prependTransactionMessageInstruction(null as unknown as Instruction, message);\n        newMessage satisfies TransactionMessage & { some: 1 };\n        // @ts-expect-error The durable nonce transaction message type should be stripped.\n        newMessage satisfies TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It does not remove blockhash lifetimes.\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };\n        const newMessage = prependTransactionMessageInstruction(null as unknown as Instruction, message);\n        newMessage satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime & { some: 1 };\n    }\n\n    // It concatenates the instruction types\n    {\n        const message = null as unknown as { instructions: [InstructionA]; version: 0 };\n        const newMessage = prependTransactionMessageInstruction(null as unknown as InstructionB, message);\n        newMessage.instructions satisfies readonly [InstructionB, InstructionA];\n        // @ts-expect-error Wrong order.\n        newMessage.instructions satisfies readonly [InstructionA, InstructionB];\n        // @ts-expect-error Not readonly.\n        newMessage.instructions satisfies [InstructionB, InstructionA];\n    }\n\n    // It adds instruction types to base transaction messages\n    {\n        const message = null as unknown as TransactionMessage;\n        const newMessage = prependTransactionMessageInstruction(null as unknown as InstructionA, message);\n        newMessage.instructions satisfies readonly [InstructionA, ...Instruction[]];\n    }\n\n    // It keeps the blockhash lifetime type safety.\n    {\n        const feePayer = null as unknown as Address;\n        const blockhash = null as unknown as Parameters<typeof setTransactionMessageLifetimeUsingBlockhash>[0];\n        const message = pipe(\n            createTransactionMessage({ version: 0 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhash, m),\n            m => prependTransactionMessageInstruction(null as unknown as InstructionA, m),\n        );\n\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime & TransactionMessageWithFeePayer;\n        message.instructions satisfies readonly [InstructionA];\n    }\n\n    // It removes the durable nonce lifetime type safety but keep the nonce instruction.\n    {\n        const feePayer = null as unknown as Address;\n        const nonceConfig = null as unknown as Parameters<typeof setTransactionMessageLifetimeUsingDurableNonce>[0];\n        const message = pipe(\n            createTransactionMessage({ version: 0 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(nonceConfig, m),\n            m => prependTransactionMessageInstruction(null as unknown as InstructionA, m),\n        );\n\n        message.instructions satisfies readonly [InstructionA, AdvanceNonceAccountInstruction];\n        message satisfies TransactionMessage & TransactionMessageWithFeePayer;\n        // @ts-expect-error No longer a durable nonce lifetime.\n        message satisfies TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It removes the size limit type safety.\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithinSizeLimit;\n        const newMessage = prependTransactionMessageInstruction(null as unknown as Instruction, message);\n        // @ts-expect-error Potentially no longer within size limit.\n        newMessage satisfies TransactionMessageWithinSizeLimit;\n    }\n\n    // It can narrow the version type\n    {\n        const message = null as unknown as TransactionMessage;\n        const newMessage = prependTransactionMessageInstruction(null as unknown as Instruction, message);\n        // @ts-expect-error Could be legacy\n        newMessage satisfies TransactionMessageNotLegacy;\n        if (newMessage.version === 0) {\n            newMessage satisfies TransactionMessageNotLegacy;\n        }\n    }\n}\n\n// [DESCRIBE] prependTransactionMessageInstructions\n{\n    // It returns the same TransactionMessage type\n    {\n        const message = null as unknown as TransactionMessage & { some: 1 };\n        const newMessage = prependTransactionMessageInstructions(null as unknown as Instruction[], message);\n        newMessage satisfies TransactionMessage & { some: 1 };\n    }\n\n    // It strips the durable nonce transaction message type\n    {\n        const message = null as unknown as TransactionMessage &\n            TransactionMessageWithDurableNonceLifetime & { some: 1 };\n        const newMessage = prependTransactionMessageInstructions(null as unknown as Instruction[], message);\n        newMessage satisfies TransactionMessage & { some: 1 };\n        // @ts-expect-error The durable nonce transaction message type should be stripped.\n        newMessage satisfies TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It concatenates the instruction types\n    {\n        const message = null as unknown as { instructions: [InstructionA]; version: 0 };\n        const newMessage = prependTransactionMessageInstructions(\n            [null as unknown as InstructionB, null as unknown as InstructionC],\n            message,\n        );\n        newMessage.instructions satisfies readonly [InstructionB, InstructionC, InstructionA];\n        // @ts-expect-error Wrong order.\n        newMessage.instructions satisfies readonly [InstructionA, InstructionC, InstructionB];\n        // @ts-expect-error Not readonly.\n        newMessage.instructions satisfies [InstructionB, InstructionC, InstructionA];\n    }\n\n    // It adds instruction types to base transaction messages\n    {\n        const message = null as unknown as TransactionMessage;\n        const newMessage = prependTransactionMessageInstructions(\n            [null as unknown as InstructionA, null as unknown as InstructionB],\n            message,\n        );\n        newMessage.instructions satisfies readonly [InstructionA, InstructionB, ...Instruction[]];\n    }\n\n    // It removes the size limit type safety.\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithinSizeLimit;\n        const newMessage = prependTransactionMessageInstructions([null as unknown as Instruction], message);\n        // @ts-expect-error Potentially no longer within size limit.\n        newMessage satisfies TransactionMessageWithinSizeLimit;\n    }\n\n    // It can narrow the version type\n    {\n        const message = null as unknown as TransactionMessage;\n        const newMessage = prependTransactionMessageInstructions([null as unknown as Instruction], message);\n        // @ts-expect-error Could be legacy\n        newMessage satisfies TransactionMessageNotLegacy;\n        if (newMessage.version === 0) {\n            newMessage satisfies TransactionMessageNotLegacy;\n        }\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/loaded-accounts-data-size-limit-typetest.ts",
    "content": "import { TransactionMessage } from '..';\nimport {\n    getTransactionMessageLoadedAccountsDataSizeLimit,\n    setTransactionMessageLoadedAccountsDataSizeLimit,\n} from '../loaded-accounts-data-size-limit';\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\ntype V1TransactionMessage = Extract<TransactionMessage, { version: 1 }>;\n\n// [DESCRIBE] setTransactionMessageLoadedAccountsDataSizeLimit\n{\n    // It accepts v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = setTransactionMessageLoadedAccountsDataSizeLimit(64_000, message);\n        result satisfies V1TransactionMessage;\n    }\n\n    // It accepts legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = setTransactionMessageLoadedAccountsDataSizeLimit(64_000, message);\n        result satisfies LegacyTransactionMessage;\n    }\n\n    // It accepts v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = setTransactionMessageLoadedAccountsDataSizeLimit(64_000, message);\n        result satisfies V0TransactionMessage;\n    }\n\n    // It preserves input type\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessageLoadedAccountsDataSizeLimit(64_000, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n\n    // It preserves input type for legacy\n    {\n        const message = null as unknown as LegacyTransactionMessage & { some: 1 };\n        const result = setTransactionMessageLoadedAccountsDataSizeLimit(64_000, message);\n        result satisfies LegacyTransactionMessage & { some: 1 };\n    }\n\n    // It can set undefined value\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessageLoadedAccountsDataSizeLimit(undefined, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n\n    // It can set undefined value for legacy\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = setTransactionMessageLoadedAccountsDataSizeLimit(undefined, message);\n        result satisfies LegacyTransactionMessage;\n    }\n}\n\n// [DESCRIBE] getTransactionMessageLoadedAccountsDataSizeLimit\n{\n    // It returns number | undefined for v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = getTransactionMessageLoadedAccountsDataSizeLimit(message);\n        result satisfies number | undefined;\n    }\n\n    // It returns number | undefined for legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        const result = getTransactionMessageLoadedAccountsDataSizeLimit(message);\n        result satisfies number | undefined;\n    }\n\n    // It returns number | undefined for v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        const result = getTransactionMessageLoadedAccountsDataSizeLimit(message);\n        result satisfies number | undefined;\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/priority-fee-lamports-typetest.ts",
    "content": "import { TransactionMessage } from '..';\nimport {\n    getTransactionMessagePriorityFeeLamports,\n    setTransactionMessagePriorityFeeLamports,\n} from '../priority-fee-lamports';\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\ntype V1TransactionMessage = Extract<TransactionMessage, { version: 1 }>;\n\n// [DESCRIBE] setTransactionMessagePriorityFeeLamports\n{\n    // It accepts v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = setTransactionMessagePriorityFeeLamports(5_000n, message);\n        result satisfies V1TransactionMessage;\n    }\n\n    // It rejects legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        // @ts-expect-error legacy messages are not supported\n        setTransactionMessagePriorityFeeLamports(5_000n, message);\n    }\n\n    // It rejects v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        // @ts-expect-error v0 messages are not supported\n        setTransactionMessagePriorityFeeLamports(5_000n, message);\n    }\n\n    // It preserves input type\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessagePriorityFeeLamports(5_000n, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n\n    // It can set undefined value\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessagePriorityFeeLamports(undefined, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n}\n\n// [DESCRIBE] getTransactionMessagePriorityFeeLamports\n{\n    // It returns bigint | undefined for v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = getTransactionMessagePriorityFeeLamports(message);\n        result satisfies bigint | undefined;\n    }\n\n    // It rejects legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        // @ts-expect-error legacy messages are not supported\n        getTransactionMessagePriorityFeeLamports(message);\n    }\n\n    // It rejects v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        // @ts-expect-error v0 messages are not supported\n        getTransactionMessagePriorityFeeLamports(message);\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/scenarios/message-modifications-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { pipe } from '@solana/functional';\nimport { Instruction } from '@solana/instructions';\n\nimport {\n    appendTransactionMessageInstruction,\n    appendTransactionMessageInstructions,\n    decompileTransactionMessage,\n    prependTransactionMessageInstruction,\n    prependTransactionMessageInstructions,\n} from '../..';\nimport { setTransactionMessageLifetimeUsingBlockhash, TransactionMessageWithBlockhashLifetime } from '../../blockhash';\nimport { compressTransactionMessageUsingAddressLookupTables } from '../../compress-transaction-message';\nimport { createTransactionMessage } from '../../create-transaction-message';\nimport {\n    setTransactionMessageLifetimeUsingDurableNonce,\n    TransactionMessageWithDurableNonceLifetime,\n} from '../../durable-nonce';\nimport { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../../fee-payer';\nimport { TransactionMessage, TransactionVersion } from '../../transaction-message';\n\nconst blockhashLifetime = null as unknown as Parameters<typeof setTransactionMessageLifetimeUsingBlockhash>[0];\nconst durableNonceLifetime = null as unknown as Parameters<typeof setTransactionMessageLifetimeUsingDurableNonce>[0];\nconst addressesByLookupTableAddress = null as unknown as Parameters<\n    typeof compressTransactionMessageUsingAddressLookupTables\n>[1];\nconst compiledTransactionMessage = null as unknown as Parameters<typeof decompileTransactionMessage>[0];\nconst feePayer = null as unknown as Address;\nconst instruction = null as unknown as Instruction;\n\n// Temporary, until we support v1 transactions in `createTransactionMessage`\n// When this is removed, use `TransactionVersion`\ntype TransactionVersionWithoutV1 = Exclude<TransactionVersion, 1>;\n\n// [DESCRIBE] setTransactionMessageLifetimeUsingBlockhash\n{\n    // It sets the blockhash after `createTransactionMessage`\n    {\n        const message = pipe(createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }), m =>\n            setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime;\n    }\n\n    // It sets the blockhash after other transformations\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageFeePayer(null as unknown as Address, m),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime & TransactionMessageWithFeePayer;\n    }\n\n    // It sets the blockhash after a durable nonce lifetime\n    {\n        const messageWithDurableNonce = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n        );\n        messageWithDurableNonce satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n\n        const messageWithBlockhash = setTransactionMessageLifetimeUsingBlockhash(\n            blockhashLifetime,\n            messageWithDurableNonce,\n        );\n        messageWithBlockhash satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime;\n        // @ts-expect-error It should strip the durable nonce lifetime\n        messageWithBlockhash satisfies TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It sets the blockhash after compressing a transaction message\n    {\n        const message = pipe(\n            createTransactionMessage({ version: 0 }), // only supported for v0\n            m => compressTransactionMessageUsingAddressLookupTables(m, addressesByLookupTableAddress),\n        );\n        const messageWithBlockhash = setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, message);\n        messageWithBlockhash satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime;\n    }\n\n    // It sets the blockhash after decompiling a message\n    {\n        const message = pipe(decompileTransactionMessage(compiledTransactionMessage), m =>\n            setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime;\n    }\n\n    // It sets the blockhash with instructions\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n            m => prependTransactionMessageInstructions([instruction], m),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime;\n    }\n\n    // It sets the blockhash multiple times\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime;\n    }\n}\n\n// [DESCRIBE] setTransactionMessageLifetimeUsingDurableNonce\n{\n    // It sets the durable nonce after `createTransactionMessage`\n    {\n        const message = pipe(createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }), m =>\n            setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It sets the durable nonce after other transformations\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageFeePayer(null as unknown as Address, m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n        );\n        message satisfies TransactionMessage &\n            TransactionMessageWithDurableNonceLifetime &\n            TransactionMessageWithFeePayer;\n    }\n\n    // It sets the durable nonce after a blockhash lifetime\n    {\n        const messageWithBlockhash = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n        );\n        messageWithBlockhash satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime;\n\n        const messageWithDurableNonce = setTransactionMessageLifetimeUsingDurableNonce(\n            durableNonceLifetime,\n            messageWithBlockhash,\n        );\n        messageWithDurableNonce satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n        // @ts-expect-error It should strip the blockhash lifetime\n        messageWithDurableNonce satisfies TransactionMessageWithBlockhashLifetime;\n    }\n\n    // It sets the durable nonce after compressing a transaction message\n    {\n        const message = pipe(\n            createTransactionMessage({ version: 0 }), // only supported for v0\n            m => compressTransactionMessageUsingAddressLookupTables(m, addressesByLookupTableAddress),\n        );\n        const messageWithDurableNonce = setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, message);\n        messageWithDurableNonce satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It sets the durable nonce after decompiling a message\n    {\n        const message = pipe(decompileTransactionMessage(compiledTransactionMessage), m =>\n            setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It sets the durable nonce with instructions\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n            m => prependTransactionMessageInstructions([instruction], m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It sets the durable nonce multiple times\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n            m => setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n    }\n}\n\n// [DESCRIBE] compressTransactionMessageUsingAddressLookupTables\n{\n    // It compresses after `createTransactionMessage`\n    {\n        const message = createTransactionMessage({ version: 0 }); // only supported for v0\n        const compressedMessage = compressTransactionMessageUsingAddressLookupTables(\n            message,\n            addressesByLookupTableAddress,\n        );\n        compressedMessage satisfies TransactionMessage & { version: 0 };\n    }\n\n    // It cannot be used with legacy messages from `createTransactionMessage`\n    {\n        const message = createTransactionMessage({ version: 'legacy' });\n        compressTransactionMessageUsingAddressLookupTables(\n            // @ts-expect-error Only v0 messages are accepted.\n            message,\n            addressesByLookupTableAddress,\n        );\n    }\n\n    // It compresses after other transformations\n    {\n        const message = pipe(\n            createTransactionMessage({ version: 0 }), // only supported for v0\n            m => setTransactionMessageFeePayer(null as unknown as Address, m),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n            m => prependTransactionMessageInstructions([instruction], m),\n        );\n        const compressedMessage = compressTransactionMessageUsingAddressLookupTables(\n            message,\n            addressesByLookupTableAddress,\n        );\n        compressedMessage satisfies TransactionMessage & { version: 0 };\n        compressedMessage satisfies TransactionMessageWithBlockhashLifetime;\n        compressedMessage satisfies TransactionMessageWithFeePayer;\n    }\n\n    // It compresses after decompiling a message\n    {\n        const message = decompileTransactionMessage(compiledTransactionMessage);\n        if (message.version === 0) {\n            const compressedMessage = compressTransactionMessageUsingAddressLookupTables(\n                message,\n                addressesByLookupTableAddress,\n            );\n            compressedMessage satisfies TransactionMessage & { version: 0 };\n        }\n    }\n}\n\n// [DESCRIBE] setTransactionMessageFeePayer\n{\n    // It sets the fee payer after `createTransactionMessage`\n    {\n        const message = createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 });\n        const newMessage = setTransactionMessageFeePayer(feePayer, message);\n        newMessage satisfies TransactionMessage & TransactionMessageWithFeePayer;\n    }\n\n    // It sets the fee payer after setting a blockhash lifetime\n    {\n        const message = pipe(createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }), m =>\n            setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n        );\n        const newMessage = setTransactionMessageFeePayer(feePayer, message);\n        newMessage satisfies TransactionMessage &\n            TransactionMessageWithBlockhashLifetime &\n            TransactionMessageWithFeePayer;\n    }\n\n    // It sets the fee payer after setting a durable nonce lifetime\n    {\n        const message = pipe(createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }), m =>\n            setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n        );\n        const newMessage = setTransactionMessageFeePayer(feePayer, message);\n        newMessage satisfies TransactionMessage &\n            TransactionMessageWithDurableNonceLifetime &\n            TransactionMessageWithFeePayer;\n    }\n\n    // It sets the fee payer multiple times\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => setTransactionMessageFeePayer(feePayer, m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithFeePayer;\n    }\n}\n\n// [DESCRIBE] instructions functions\n{\n    // It can call instruction functions after `createTransactionMessage`\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n            m => prependTransactionMessageInstructions([instruction], m),\n        );\n        message satisfies TransactionMessage;\n    }\n\n    // It can call instruction functions after setting a blockhash lifetime\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageLifetimeUsingBlockhash(blockhashLifetime, m),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n            m => prependTransactionMessageInstructions([instruction], m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithBlockhashLifetime;\n    }\n\n    // It can call append instruction functions after setting a durable nonce lifetime\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It can call prepend instruction functions after setting a durable nonce lifetime, but\n    // the durable nonce lifetime is stripped because the first instruction must be the AdvanceNonceAccount instruction\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageLifetimeUsingDurableNonce(durableNonceLifetime, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstructions([instruction], m),\n        );\n        message satisfies TransactionMessage;\n        // @ts-expect-error It should strip the durable nonce lifetime\n        message satisfies TransactionMessageWithDurableNonceLifetime;\n    }\n\n    // It can call instruction functions after setting a fee payer\n    {\n        const message = pipe(\n            createTransactionMessage({ version: null as unknown as TransactionVersionWithoutV1 }),\n            m => setTransactionMessageFeePayer(feePayer, m),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n            m => prependTransactionMessageInstructions([instruction], m),\n        );\n        message satisfies TransactionMessage & TransactionMessageWithFeePayer;\n    }\n\n    // It can call instruction functions after compressing a transaction message\n    {\n        const message = pipe(\n            createTransactionMessage({ version: 0 }), // only supported for v0\n            m => compressTransactionMessageUsingAddressLookupTables(m, addressesByLookupTableAddress),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n            m => prependTransactionMessageInstructions([instruction], m),\n        );\n        message satisfies TransactionMessage & { version: 0 };\n    }\n\n    // It can call instruction functions after decompiling a message\n    {\n        const message = pipe(\n            decompileTransactionMessage(compiledTransactionMessage),\n            m => appendTransactionMessageInstruction(instruction, m),\n            m => prependTransactionMessageInstruction(instruction, m),\n            m => appendTransactionMessageInstructions([instruction], m),\n            m => prependTransactionMessageInstructions([instruction], m),\n        );\n        message satisfies TransactionMessage;\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/__typetests__/transaction-config-typetest.ts",
    "content": "import { TransactionMessage } from '../transaction-message';\nimport { setTransactionMessageConfig, V1TransactionConfig } from '../v1-transaction-config';\n\ntype LegacyTransactionMessage = Extract<TransactionMessage, { version: 'legacy' }>;\ntype V0TransactionMessage = Extract<TransactionMessage, { version: 0 }>;\ntype V1TransactionMessage = Extract<TransactionMessage, { version: 1 }>;\n\n// [DESCRIBE] setTransactionMessageConfig\n{\n    const mockConfig = null as unknown as V1TransactionConfig;\n\n    // It accepts v1 messages\n    {\n        const message = null as unknown as V1TransactionMessage;\n        const result = setTransactionMessageConfig(mockConfig, message);\n        result satisfies V1TransactionMessage;\n    }\n\n    // It preserves input message type\n    {\n        const message = null as unknown as V1TransactionMessage & { some: 1 };\n        const result = setTransactionMessageConfig(mockConfig, message);\n        result satisfies V1TransactionMessage & { some: 1 };\n    }\n\n    // It rejects legacy messages\n    {\n        const message = null as unknown as LegacyTransactionMessage;\n        // @ts-expect-error Legacy transactions are not supported\n        setTransactionMessageConfig(mockConfig, message);\n    }\n\n    // It rejects v0 messages\n    {\n        const message = null as unknown as V0TransactionMessage;\n        // @ts-expect-error V0 transactions are not supported\n        setTransactionMessageConfig(mockConfig, message);\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/addresses-by-lookup-table-address.ts",
    "content": "import { Address } from '@solana/addresses';\n\n/**\n * Represents a mapping of lookup table addresses to the addresses of the accounts that are stored\n * in them.\n */\nexport type AddressesByLookupTableAddress = { [lookupTableAddress: Address]: Address[] };\n"
  },
  {
    "path": "packages/transaction-messages/src/blockhash.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME, SolanaError } from '@solana/errors';\nimport { type Blockhash, isBlockhash } from '@solana/rpc-types';\n\nimport { ExcludeTransactionMessageLifetime, TransactionMessageWithLifetime } from './lifetime';\nimport { TransactionMessage } from './transaction-message';\n\n/**\n * A constraint which, when applied to a transaction message, makes that transaction message\n * eligible to land on the network. The transaction message will continue to be eligible to land\n * until the network considers the `blockhash` to be expired.\n *\n * This can happen when the network proceeds past the `lastValidBlockHeight` for which the blockhash\n * is considered valid, or when the network switches to a fork where that blockhash is not present.\n */\nexport type BlockhashLifetimeConstraint = Readonly<{\n    /**\n     * A recent blockhash observed by the transaction proposer.\n     *\n     * The transaction message will be considered eligible to land until the network determines this\n     * blockhash to be too old, or has switched to a fork where it is not present.\n     */\n    blockhash: Blockhash;\n    /**\n     * This is the block height beyond which the network will consider the blockhash to be too old\n     * to make a transaction message eligible to land.\n     */\n    lastValidBlockHeight: bigint;\n}>;\n\n/**\n * Represents a transaction message whose lifetime is defined by the age of the blockhash it\n * includes.\n *\n * Such a transaction can only be landed on the network if the current block height of the network\n * is less than or equal to the value of\n * `TransactionMessageWithBlockhashLifetime['lifetimeConstraint']['lastValidBlockHeight']`.\n */\nexport interface TransactionMessageWithBlockhashLifetime {\n    readonly lifetimeConstraint: BlockhashLifetimeConstraint;\n}\n\n/**\n * A type guard that returns `true` if the transaction message conforms to the\n * {@link TransactionMessageWithBlockhashLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionMessageWithBlockhashLifetime } from '@solana/transaction-messages';\n *\n * if (isTransactionMessageWithBlockhashLifetime(message)) {\n *     // At this point, `message` has been refined to a `TransactionMessageWithBlockhashLifetime`.\n *     const { blockhash } = message.lifetimeConstraint;\n *     const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n *     setBlockhashIsValid(blockhashIsValid);\n * } else {\n *     setError(\n *         `${getSignatureFromTransaction(transaction)} does not have a blockhash-based lifetime`,\n *     );\n * }\n * ```\n */\nexport function isTransactionMessageWithBlockhashLifetime(\n    transactionMessage: TransactionMessage | (TransactionMessage & TransactionMessageWithBlockhashLifetime),\n): transactionMessage is TransactionMessage & TransactionMessageWithBlockhashLifetime {\n    return (\n        'lifetimeConstraint' in transactionMessage &&\n        typeof transactionMessage.lifetimeConstraint.blockhash === 'string' &&\n        typeof transactionMessage.lifetimeConstraint.lastValidBlockHeight === 'bigint' &&\n        isBlockhash(transactionMessage.lifetimeConstraint.blockhash)\n    );\n}\n\n/**\n * From time to time you might acquire a transaction message, that you expect to have a\n * blockhash-based lifetime, from an untrusted network API or user input. Use this function to\n * assert that such a transaction message actually has a blockhash-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionMessageWithBlockhashLifetime } from '@solana/transaction-messages';\n *\n * try {\n *     // If this type assertion function doesn't throw, then\n *     // Typescript will upcast `message` to `TransactionMessageWithBlockhashLifetime`.\n *     assertIsTransactionMessageWithBlockhashLifetime(message);\n *     // At this point, `message` is a `TransactionMessageWithBlockhashLifetime` that can be used\n *     // with the RPC.\n *     const { blockhash } = message.lifetimeConstraint;\n *     const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * } catch (e) {\n *     // `message` turned out not to have a blockhash-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionMessageWithBlockhashLifetime(\n    transactionMessage: TransactionMessage | (TransactionMessage & TransactionMessageWithBlockhashLifetime),\n): asserts transactionMessage is TransactionMessage & TransactionMessageWithBlockhashLifetime {\n    if (!isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME);\n    }\n}\n\n/**\n * Given a blockhash and the last block height at which that blockhash is considered usable to land\n * transactions, this method will return a new transaction message having the same type as the one\n * supplied plus the `TransactionMessageWithBlockhashLifetime` type.\n *\n * @example\n * ```ts\n * import { setTransactionMessageLifetimeUsingBlockhash } from '@solana/transaction-messages';\n *\n * const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();\n * const txMessageWithBlockhashLifetime = setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, txMessage);\n * ```\n */\nexport function setTransactionMessageLifetimeUsingBlockhash<\n    TTransactionMessage extends Partial<Pick<TransactionMessageWithLifetime, 'lifetimeConstraint'>> &\n        TransactionMessage,\n>(\n    blockhashLifetimeConstraint: BlockhashLifetimeConstraint,\n    transactionMessage: TTransactionMessage,\n): ExcludeTransactionMessageLifetime<TTransactionMessage> & TransactionMessageWithBlockhashLifetime {\n    type ReturnType = ExcludeTransactionMessageLifetime<TTransactionMessage> & TransactionMessageWithBlockhashLifetime;\n\n    if (\n        'lifetimeConstraint' in transactionMessage &&\n        transactionMessage.lifetimeConstraint &&\n        'blockhash' in transactionMessage.lifetimeConstraint &&\n        transactionMessage.lifetimeConstraint.blockhash === blockhashLifetimeConstraint.blockhash &&\n        transactionMessage.lifetimeConstraint.lastValidBlockHeight === blockhashLifetimeConstraint.lastValidBlockHeight\n    ) {\n        return transactionMessage as ReturnType;\n    }\n\n    return Object.freeze({\n        ...transactionMessage,\n        lifetimeConstraint: Object.freeze(blockhashLifetimeConstraint),\n    }) as ReturnType;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/__tests__/message-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    LegacyCompiledTransactionMessage,\n    V0CompiledTransactionMessage,\n    V1CompiledTransactionMessage,\n} from '../../compile/message';\nimport {\n    getCompiledTransactionMessageCodec,\n    getCompiledTransactionMessageDecoder,\n    getCompiledTransactionMessageEncoder,\n} from '../message';\n\ndescribe.each([getCompiledTransactionMessageCodec, getCompiledTransactionMessageEncoder])(\n    'Message encoder %p',\n    encoderFactory => {\n        const encoder = encoderFactory();\n\n        it('encodes a legacy transaction correctly', () => {\n            const encoder = encoderFactory();\n            const message: CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage = {\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 2,\n                    numSignerAccounts: 3,\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 2],\n                        data: new Uint8Array([4, 5, 6]),\n                        programAddressIndex: 0,\n                    },\n                    {\n                        accountIndices: [2],\n                        data: new Uint8Array([7, 8, 9]),\n                        programAddressIndex: 1,\n                    },\n                ],\n                lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n                staticAccounts: [\n                    'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                    'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                    'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n                ],\n                version: 'legacy',\n            };\n\n            expect(encoder.encode(message)).toStrictEqual(\n                // prettier-ignore\n                new Uint8Array([\n                    /** NO VERSION HEADER */\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    2, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    3, // Number of static accounts\n                    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                    /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                    /* INSTRUCTIONS */\n                    2, // Number of instructions\n\n                    // First instruction\n                    0, // Program address index\n                    2, // Number of address indices\n                    1, 2, // Address indices\n                    3, // Length of instruction data\n                    4, 5, 6, // Instruction data itself\n\n                    // Second instruction\n                    1, // Program address index\n                    1, // Number of address indices\n                    2, // Address indices\n                    3, // Length of instruction data\n                    7, 8, 9, // Instruction data itself\n                ]),\n            );\n        });\n\n        it('encodes a v0 transaction with address lookup tables correctly', () => {\n            const message: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n                addressTableLookups: [\n                    {\n                        lookupTableAddress: '3yS1JFVT284y8z1LC9MRoWxZjzFrdoD5axKsZiyMsfC7' as Address, // decodes to [44{32}]\n                        readonlyIndexes: [77],\n                        writableIndexes: [66, 55],\n                    },\n                ],\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 2,\n                    numSignerAccounts: 3,\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 2],\n                        data: new Uint8Array([4, 5, 6]),\n                        programAddressIndex: 0,\n                    },\n                    {\n                        accountIndices: [2],\n                        data: new Uint8Array([7, 8, 9]),\n                        programAddressIndex: 1,\n                    },\n                ],\n                lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n                staticAccounts: [\n                    'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                    'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                    'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n                ],\n                version: 0,\n            };\n\n            expect(encoder.encode(message)).toStrictEqual(\n                // prettier-ignore\n                new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    2, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    3, // Number of static accounts\n                    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                    /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                    /* INSTRUCTIONS */\n                    2, // Number of instructions\n\n                    // First instruction\n                    0, // Program address index\n                    2, // Number of address indices\n                    1, 2, // Address indices\n                    3, // Length of instruction data\n                    4, 5, 6, // Instruction data itself\n\n                    // Second instruction\n                    1, // Program address index\n                    1, // Number of address indices\n                    2, // Address indices\n                    3, // Length of instruction data\n                    7, 8, 9, // Instruction data itself\n\n                    /** ADDRESS TABLE LOOKUPS */\n                    1, // Number of address table lookups\n\n                    // First address table lookup\n                    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, // Address of lookup table 3yS1JFVT284y8z1LC9MRoWxZjzFrdoD5axKsZiyMsfC7\n                    2, // Number of writable indices\n                    66, 55, // Writable indices\n                    1, // Number of readonly indices\n                    77, // Readonly indices\n                ]),\n            );\n        });\n\n        it('encodes a v1 transaction with all config values', () => {\n            const message: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                configMask: 0b11111,\n                // All config flags set\n                configValues: [\n                    { kind: 'u64', value: 5000n }, // Priority fee\n                    { kind: 'u32', value: 200000 }, // Compute unit limit\n                    { kind: 'u32', value: 64000 }, // Loaded accounts data size limit\n                    { kind: 'u32', value: 256000 }, // Heap size\n                ],\n\n                header: {\n                    numReadonlyNonSignerAccounts: 0,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n\n                instructionHeaders: [],\n\n                instructionPayloads: [],\n                lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5',\n                numInstructions: 0,\n                numStaticAccounts: 1,\n                staticAccounts: ['k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address],\n                version: 1,\n            };\n\n            expect(encoder.encode(message)).toStrictEqual(\n                // prettier-ignore\n                new Uint8Array([\n                    /** VERSION HEADER */\n                    129,\n\n                    /** MESSAGE HEADER */\n                    1, 0, 0,\n\n                    /** CONFIG MASK */\n                    31, 0, 0, 0, // configMask (u32) = 0b11111\n\n                    /** LIFETIME TOKEN */\n                    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n                    /** NUM INSTRUCTIONS */\n                    0,\n\n                    /** NUM ADDRESSES */\n                    1,\n\n                    /** STATIC ADDRESSES */\n                    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\n                    /** CONFIG VALUES */\n                    136, 19, 0, 0, 0, 0, 0, 0, // 5000 as u64\n                    64, 13, 3, 0, // 200000 as u32\n                    0, 250, 0, 0, // 64000 as u32\n                    0, 232, 3, 0, // 256000 as u32\n\n                    /** INSTRUCTION HEADERS */\n                    // (none)\n\n                    /** INSTRUCTION PAYLOADS */\n                    // (none)\n                ]),\n            );\n        });\n\n        it('errors when encoding an unsupported v2 transaction', () => {\n            const message = {\n                version: 2,\n            } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n            expect(() => encoder.encode(message)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                    unsupportedVersion: 2,\n                }),\n            );\n        });\n    },\n);\n\ndescribe.each([getCompiledTransactionMessageCodec, getCompiledTransactionMessageDecoder])(\n    'Message decoder %p',\n    decoderFactory => {\n        const decoder = decoderFactory();\n\n        it('decodes a legacy transaction correctly', () => {\n            const byteArray =\n                // prettier-ignore\n                new Uint8Array([\n                    /** NO VERSION HEADER */\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    2, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    3, // Number of static accounts\n                    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                    /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                    /* INSTRUCTIONS */\n                    2, // Number of instructions\n\n                    // First instruction\n                    0, // Program address index\n                    2, // Number of address indices\n                    1, 2, // Address indices\n                    3, // Length of instruction data\n                    4, 5, 6, // Instruction data itself\n\n                    // Second instruction\n                    1, // Program address index\n                    1, // Number of address indices\n                    2, // Address indices\n                    3, // Length of instruction data\n                    7, 8, 9, // Instruction data itself\n                ]);\n\n            const expectedMessage: CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage = {\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 2,\n                    numSignerAccounts: 3,\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 2],\n                        data: new Uint8Array([4, 5, 6]),\n                        programAddressIndex: 0,\n                    },\n                    {\n                        accountIndices: [2],\n                        data: new Uint8Array([7, 8, 9]),\n                        programAddressIndex: 1,\n                    },\n                ],\n                lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // decodes to [10{32}]\n                staticAccounts: [\n                    'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // decodes to [11{32}]\n                    'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // decodes to [12{32}]\n                    'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // decodes to [13{32}]\n                ],\n                version: 'legacy',\n            };\n\n            expect(decoder.decode(byteArray)).toStrictEqual(expectedMessage);\n        });\n\n        it('decodes a v0 transaction with address lookup tables correctly', () => {\n            const byteArray =\n                // prettier-ignore\n                new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    2, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    3, // Number of static accounts\n                    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                    /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                    /* INSTRUCTIONS */\n                    2, // Number of instructions\n\n                    // First instruction\n                    0, // Program address index\n                    2, // Number of address indices\n                    1, 2, // Address indices\n                    3, // Length of instruction data\n                    4, 5, 6, // Instruction data itself\n\n                    // Second instruction\n                    1, // Program address index\n                    1, // Number of address indices\n                    2, // Address indices\n                    3, // Length of instruction data\n                    7, 8, 9, // Instruction data itself\n\n                    /** ADDRESS TABLE LOOKUPS */\n                    1, // Number of address table lookups\n\n                    // First address table lookup\n                    44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, // Address of lookup table 3yS1JFVT284y8z1LC9MRoWxZjzFrdoD5axKsZiyMsfC7\n                    2, // Number of writable indices\n                    66, 55, // Writable indices\n                    1, // Number of readonly indices\n                    77, // Readonly indices\n                ]);\n\n            const expectedMessage: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n                addressTableLookups: [\n                    {\n                        lookupTableAddress: '3yS1JFVT284y8z1LC9MRoWxZjzFrdoD5axKsZiyMsfC7' as Address, // decodes to [44{32}]\n                        readonlyIndexes: [77],\n                        writableIndexes: [66, 55],\n                    },\n                ],\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 2,\n                    numSignerAccounts: 3,\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 2],\n                        data: new Uint8Array([4, 5, 6]),\n                        programAddressIndex: 0,\n                    },\n                    {\n                        accountIndices: [2],\n                        data: new Uint8Array([7, 8, 9]),\n                        programAddressIndex: 1,\n                    },\n                ],\n                lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // decodes to [10{32}]\n                staticAccounts: [\n                    'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // decodes to [11{32}]\n                    'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // decodes to [12{32}]\n                    'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // decodes to [13{32}]\n                ],\n                version: 0,\n            };\n\n            expect(decoder.decode(byteArray)).toStrictEqual(expectedMessage);\n        });\n\n        it('decodes a v1 transaction with all config values', () => {\n            // prettier-ignore\n            const bytes = new Uint8Array([\n                /** VERSION HEADER */\n                129,\n\n                /** MESSAGE HEADER */\n                1, 0, 0,\n\n                /** CONFIG MASK */\n                31, 0, 0, 0, // configMask (u32) = 0b11111\n\n                /** LIFETIME TOKEN */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n                /** NUM INSTRUCTIONS */\n                0,\n\n                /** NUM ADDRESSES */\n                1,\n\n                /** STATIC ADDRESSES */\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\n                /** CONFIG VALUES */\n                136, 19, 0, 0, 0, 0, 0, 0, // 5000 as u64\n                64, 13, 3, 0, // 200000 as u32\n                0, 250, 0, 0, // 64000 as u32\n                0, 232, 3, 0, // 256000 as u32\n\n                /** INSTRUCTION HEADERS */\n                // (none)\n\n                /** INSTRUCTION PAYLOADS */\n                // (none)\n            ]);\n\n            const message = decoder.decode(bytes);\n\n            expect(message).toMatchObject({\n                configMask: 31,\n                configValues: [\n                    { kind: 'u64', value: 5000n },\n                    { kind: 'u32', value: 200000 },\n                    { kind: 'u32', value: 64000 },\n                    { kind: 'u32', value: 256000 },\n                ],\n                version: 1,\n            });\n        });\n\n        it('errors when decoding a transaction with an unsupported version', () => {\n            // prettier-ignore\n            const bytes = new Uint8Array([\n                /** VERSION HEADER */\n                130, // 2 + version mask (0x80)\n\n                /** The rest of the bytes don't matter since the decoder should error on the version */\n                0, 0, 0, 0,\n            ]);\n\n            expect(() => decoder.decode(bytes)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                    unsupportedVersion: 2,\n                }),\n            );\n        });\n    },\n);\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/__tests__/transaction-version-test.ts",
    "content": "import { Decoder, Encoder } from '@solana/codecs-core';\nimport { SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport { TransactionVersion } from '../../transaction-message';\nimport {\n    getTransactionVersionCodec,\n    getTransactionVersionDecoder,\n    getTransactionVersionEncoder,\n} from '../transaction-version';\n\nconst VERSION_FLAG_MASK = 0x80;\nconst VERSION_TEST_CASES = // Versions 0–127\n    [...Array(128).keys()].map(version => [version | VERSION_FLAG_MASK, version as TransactionVersion] as const);\nconst UNSUPPORTED_VERSION_TEST_CASES = VERSION_TEST_CASES.slice(2); // versions 2-127\n\ndescribe.each([getTransactionVersionCodec, getTransactionVersionEncoder])(\n    'Transaction version encoder',\n    serializerFactory => {\n        let transactionVersion: Encoder<TransactionVersion>;\n        beforeEach(() => {\n            transactionVersion = serializerFactory();\n        });\n        it('serializes no data when the version is `legacy`', () => {\n            expect(transactionVersion.encode('legacy')).toEqual(new Uint8Array());\n        });\n        it('serializes to `0x80` when the version is `0`', () => {\n            expect(transactionVersion.encode(0)).toEqual(new Uint8Array([0x80]));\n        });\n        it('serializes to `0x81` when the version is `1`', () => {\n            expect(transactionVersion.encode(1)).toEqual(new Uint8Array([0x81]));\n        });\n        it.each(UNSUPPORTED_VERSION_TEST_CASES)('fatals for unsupported version `%s`', (_byte, version) => {\n            expect(() => transactionVersion.encode(version)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                    unsupportedVersion: version,\n                }),\n            );\n        });\n        it.each([-1 as TransactionVersion, 128 as TransactionVersion])(\n            'throws when passed the out-of-range version `%s`',\n            version => {\n                expect(() => transactionVersion.encode(version)).toThrow();\n            },\n        );\n    },\n);\n\ndescribe.each([getTransactionVersionCodec, getTransactionVersionDecoder])(\n    'Transaction version decoder',\n    serializerFactory => {\n        let transactionVersion: Decoder<TransactionVersion>;\n        beforeEach(() => {\n            transactionVersion = serializerFactory();\n        });\n        it('deserializes to `legacy` when missing the version flag', () => {\n            expect(\n                transactionVersion.decode(\n                    // eg. just a byte that indicates that there are 3 required signers\n                    new Uint8Array([3]),\n                ),\n            ).toBe('legacy');\n        });\n        it('deserializes to 0 for a version 0 transaction', () => {\n            expect(\n                transactionVersion.decode(\n                    new Uint8Array([0 | VERSION_FLAG_MASK]), // version 0 with the version flag\n                ),\n            ).toBe(0);\n        });\n        it('deserializes to 1 for a version 1 transaction', () => {\n            expect(\n                transactionVersion.decode(\n                    new Uint8Array([1 | VERSION_FLAG_MASK]), // version 1 with the version flag\n                ),\n            ).toBe(1);\n        });\n        it.each(UNSUPPORTED_VERSION_TEST_CASES)('fatals for unsupported version `%s`', (byte, version) => {\n            expect(() => transactionVersion.decode(new Uint8Array([byte]))).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                    unsupportedVersion: version,\n                }),\n            );\n        });\n    },\n);\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/index.ts",
    "content": "export * from './message';\nexport * from './transaction-version';\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/legacy/__tests__/header-test.ts",
    "content": "import { getMessageHeaderCodec, getMessageHeaderDecoder, getMessageHeaderEncoder } from '../header';\n\ndescribe('Message header codec', () => {\n    describe.each([getMessageHeaderEncoder, getMessageHeaderCodec])('message header encoder %p', encoderFactory => {\n        let messageHeader: ReturnType<typeof getMessageHeaderEncoder>;\n        beforeEach(() => {\n            messageHeader = encoderFactory();\n        });\n\n        it('serializes header data according to spec', () => {\n            expect(\n                messageHeader.encode({\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 2,\n                    numSignerAccounts: 3,\n                }),\n            ).toEqual(new Uint8Array([3, 2, 1]));\n        });\n    });\n\n    describe.each([getMessageHeaderDecoder, getMessageHeaderCodec])('message header decoder %p', decoderFactory => {\n        let messageHeader: ReturnType<typeof getMessageHeaderDecoder>;\n        beforeEach(() => {\n            messageHeader = decoderFactory();\n        });\n\n        it('serializes header data according to spec', () => {\n            expect(messageHeader.decode(new Uint8Array([3, 2, 1]))).toEqual({\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/legacy/__tests__/instruction-test.ts",
    "content": "import { getInstructionCodec, getInstructionDecoder, getInstructionEncoder } from '../instruction';\n\ndescribe('Instruction codec', () => {\n    describe.each([getInstructionEncoder, getInstructionCodec])('instruction encoder %p', encoderFactory => {\n        let instruction: ReturnType<typeof getInstructionEncoder>;\n        beforeEach(() => {\n            instruction = encoderFactory();\n        });\n        it('serializes an instruction according to spec', () => {\n            expect(\n                instruction.encode({\n                    accountIndices: [1, 2],\n                    data: new Uint8Array([4, 5, 6]),\n                    programAddressIndex: 7,\n                }),\n            ).toEqual(\n                new Uint8Array([\n                    // Program id index\n                    7,\n                    // Compact array of account indices\n                    2, // Compact-u16 length\n                    1,\n                    2,\n                    // Compact array of instruction data\n                    3, // Compact-u16 length\n                    4,\n                    5,\n                    6,\n                ]),\n            );\n        });\n        it('serializes a zero-length compact array when `accountIndices` is `undefined`', () => {\n            expect(\n                instruction.encode({\n                    data: new Uint8Array([3, 4]),\n                    programAddressIndex: 1,\n                }),\n            ).toEqual(\n                new Uint8Array([\n                    // Program id index\n                    1,\n                    // Compact array of account indices\n                    0, // Compact-u16 length\n                    // Compact array of instruction data\n                    2, // Compact-u16 length\n                    3,\n                    4,\n                ]),\n            );\n        });\n        it('serializes a zero-length compact array when `data` is `undefined`', () => {\n            expect(\n                instruction.encode({\n                    accountIndices: [3, 4],\n                    programAddressIndex: 1,\n                }),\n            ).toEqual(\n                new Uint8Array([\n                    // Program id index\n                    1,\n                    // Compact array of account indices\n                    2, // Compact-u16 length\n                    3,\n                    4,\n                    // Compact array of instruction data\n                    0, // Compact-u16 length\n                ]),\n            );\n        });\n    });\n\n    describe.each([getInstructionDecoder, getInstructionCodec])('instruction decoder %p', decoderFactory => {\n        let instruction: ReturnType<typeof getInstructionDecoder>;\n        beforeEach(() => {\n            instruction = decoderFactory();\n        });\n        it('deserializes an instruction according to spec', () => {\n            expect(\n                instruction.decode(\n                    new Uint8Array([\n                        // Program id index\n                        1,\n                        // Compact array of account indices\n                        2, // Compact-u16 length\n                        3,\n                        4,\n                        // Compact array of instruction data\n                        5, // Compact-u16 length\n                        6,\n                        7,\n                        8,\n                        9,\n                        10,\n                    ]),\n                ),\n            ).toEqual({\n                accountIndices: [3, 4],\n                data: new Uint8Array([6, 7, 8, 9, 10]),\n                programAddressIndex: 1,\n            });\n        });\n        it('omits the `accountIndices` property when the indices data is zero-length', () => {\n            expect(\n                instruction.decode(\n                    new Uint8Array([\n                        // Program id index\n                        1,\n                        // Compact array of account indices\n                        0, // Compact-u16 length\n                        // Compact array of instruction data\n                        2, // Compact-u16 length\n                        3,\n                        4,\n                    ]),\n                ),\n            ).not.toHaveProperty('accountIndices');\n        });\n        it('omits the `data` property when the instruction data is zero-length', () => {\n            expect(\n                instruction.decode(\n                    new Uint8Array([\n                        // Program id index\n                        1,\n                        // Compact array of account indices\n                        2, // Compact-u16 length\n                        3,\n                        4,\n                        // Compact array of instruction data\n                        0, // Compact-u16 length\n                    ]),\n                ),\n            ).not.toHaveProperty('data');\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/legacy/__tests__/lifetime-token-test.ts",
    "content": "import { getLifetimeTokenDecoder, getLifetimeTokenEncoder } from '../lifetime-token';\n\ndescribe('getOptionalLifetimeTokenEncoder', () => {\n    it('should encode a 23 byte base58 string', () => {\n        const token = '3EKkiwNLWqoUbzFkPrmKbtUB4EweE6f4STzevYUmezeL';\n        expect(getLifetimeTokenEncoder().encode(token)).toStrictEqual(new Uint8Array(32).fill(33));\n    });\n\n    it('should encode undefined as 32 zero bytes', () => {\n        expect(getLifetimeTokenEncoder().encode(undefined)).toStrictEqual(new Uint8Array(32));\n    });\n});\n\ndescribe('getLifetimeTokenDecoder', () => {\n    it('should decode a valid base58 encoded string', () => {\n        const encoded = new Uint8Array(32).fill(33);\n        expect(getLifetimeTokenDecoder().decode(encoded)).toBe('3EKkiwNLWqoUbzFkPrmKbtUB4EweE6f4STzevYUmezeL');\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/legacy/__tests__/message-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Decoder, Encoder } from '@solana/codecs-core';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../../../compile/message';\nimport { getMessageCodec, getMessageDecoder, getMessageEncoder } from '../message';\n\ntype LegacyCompiledTransactionMessage = CompiledTransactionMessage & { version: 'legacy' };\n\ndescribe.each([getMessageCodec, getMessageEncoder])('Transaction message encoder %p', encoderFactory => {\n    let encoder: Encoder<\n        LegacyCompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage)\n    >;\n    beforeEach(() => {\n        encoder = encoderFactory();\n    });\n\n    it('encodes a legacy transaction correctly', () => {\n        const message: CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [\n                {\n                    accountIndices: [1, 2],\n                    data: new Uint8Array([4, 5, 6]),\n                    programAddressIndex: 0,\n                },\n                {\n                    accountIndices: [2],\n                    data: new Uint8Array([7, 8, 9]),\n                    programAddressIndex: 1,\n                },\n            ],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n            ],\n            version: 'legacy',\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** NO VERSION HEADER */\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                3, // Number of static accounts\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                2, // Number of instructions\n\n                // First instruction\n                0, // Program address index\n                2, // Number of address indices\n                1, 2, // Address indices\n                3, // Length of instruction data\n                4, 5, 6, // Instruction data itself\n\n                // Second instruction\n                1, // Program address index\n                1, // Number of address indices\n                2, // Address indices\n                3, // Length of instruction data\n                7, 8, 9, // Instruction data itself\n            ]),\n        );\n    });\n\n    it('encodes a legacy transaction with no instructions correctly', () => {\n        const message: CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n            ],\n            version: 'legacy',\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** NO VERSION HEADER */\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                3, // Number of static accounts\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                0, // Number of instructions\n            ]),\n        );\n    });\n\n    it('encodes a legacy transaction with no instructions and no accounts correctly', () => {\n        const message: CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [],\n            version: 'legacy',\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** NO VERSION HEADER */\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                0, // Number of static accounts\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                0, // Number of instructions\n            ]),\n        );\n    });\n});\n\ndescribe.each([getMessageCodec, getMessageDecoder])('Transaction message decoder %p', decoderFactory => {\n    let decoder: Decoder<LegacyCompiledTransactionMessage>;\n    beforeEach(() => {\n        decoder = decoderFactory();\n    });\n\n    it('decodes a legacy transaction correctly', () => {\n        const byteArray =\n            // prettier-ignore\n            new Uint8Array([\n                    /** NO VERSION HEADER */\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    2, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    3, // Number of static accounts\n                    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                    /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                    /* INSTRUCTIONS */\n                    2, // Number of instructions\n\n                    // First instruction\n                    0, // Program address index\n                    2, // Number of address indices\n                    1, 2, // Address indices\n                    3, // Length of instruction data\n                    4, 5, 6, // Instruction data itself\n\n                    // Second instruction\n                    1, // Program address index\n                    1, // Number of address indices\n                    2, // Address indices\n                    3, // Length of instruction data\n                    7, 8, 9, // Instruction data itself\n                ]);\n\n        const expectedMessage: CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [\n                {\n                    accountIndices: [1, 2],\n                    data: new Uint8Array([4, 5, 6]),\n                    programAddressIndex: 0,\n                },\n                {\n                    accountIndices: [2],\n                    data: new Uint8Array([7, 8, 9]),\n                    programAddressIndex: 1,\n                },\n            ],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // decodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // decodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // decodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // decodes to [13{32}]\n            ],\n            version: 'legacy',\n        };\n\n        expect(decoder.decode(byteArray)).toStrictEqual(expectedMessage);\n    });\n\n    it('decodes a legacy transaction with no instructions correctly', () => {\n        const byteArray =\n            // prettier-ignore\n            new Uint8Array([\n                    /** NO VERSION HEADER */\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    2, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    3, // Number of static accounts\n                    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                    /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                    /* INSTRUCTIONS */\n                    0, // Number of instructions\n                ]);\n\n        const expectedMessage: CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n            ],\n            version: 'legacy',\n        };\n\n        expect(decoder.decode(byteArray)).toStrictEqual(expectedMessage);\n    });\n\n    it('decodes a legacy transaction with no instructions and no accounts correctly', () => {\n        const byteArray =\n            // prettier-ignore\n            new Uint8Array([\n                    /** NO VERSION HEADER */\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    2, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    0, // Number of static accounts\n\n                    /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                    /* INSTRUCTIONS */\n                    0, // Number of instructions\n                ]);\n\n        const expectedMessage: CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [],\n            version: 'legacy',\n        };\n\n        expect(decoder.decode(byteArray)).toStrictEqual(expectedMessage);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/legacy/header.ts",
    "content": "import { FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core';\nimport { getStructCodec, getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getU8Codec, getU8Decoder, getU8Encoder } from '@solana/codecs-numbers';\n\nimport { getCompiledMessageHeader } from '../../compile/legacy/header';\n\ntype MessageHeader = ReturnType<typeof getCompiledMessageHeader>;\n\nlet memoizedU8Encoder: FixedSizeEncoder<number, 1> | undefined;\nfunction getMemoizedU8Encoder(): FixedSizeEncoder<number, 1> {\n    if (!memoizedU8Encoder) memoizedU8Encoder = getU8Encoder();\n    return memoizedU8Encoder;\n}\n\nlet memoizedU8Decoder: FixedSizeDecoder<number, 1> | undefined;\nfunction getMemoizedU8Decoder(): FixedSizeDecoder<number, 1> {\n    if (!memoizedU8Decoder) memoizedU8Decoder = getU8Decoder();\n    return memoizedU8Decoder;\n}\n\nlet memoizedU8Codec: FixedSizeCodec<number, number, 1> | undefined;\nfunction getMemoizedU8Codec(): FixedSizeCodec<number, number, 1> {\n    if (!memoizedU8Codec) memoizedU8Codec = getU8Codec();\n    return memoizedU8Codec;\n}\n\nexport function getMessageHeaderEncoder(): FixedSizeEncoder<MessageHeader, 3> {\n    return getStructEncoder([\n        ['numSignerAccounts', getMemoizedU8Encoder()],\n        ['numReadonlySignerAccounts', getMemoizedU8Encoder()],\n        ['numReadonlyNonSignerAccounts', getMemoizedU8Encoder()],\n    ]) as FixedSizeEncoder<MessageHeader, 3>;\n}\n\nexport function getMessageHeaderDecoder(): FixedSizeDecoder<MessageHeader, 3> {\n    return getStructDecoder([\n        ['numSignerAccounts', getMemoizedU8Decoder()],\n        ['numReadonlySignerAccounts', getMemoizedU8Decoder()],\n        ['numReadonlyNonSignerAccounts', getMemoizedU8Decoder()],\n    ]) as FixedSizeDecoder<MessageHeader, 3>;\n}\n\nexport function getMessageHeaderCodec(): FixedSizeCodec<MessageHeader, MessageHeader, 3> {\n    return getStructCodec([\n        ['numSignerAccounts', getMemoizedU8Codec()],\n        ['numReadonlySignerAccounts', getMemoizedU8Codec()],\n        ['numReadonlyNonSignerAccounts', getMemoizedU8Codec()],\n    ]) as FixedSizeCodec<MessageHeader, MessageHeader, 3>;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/legacy/instruction.ts",
    "content": "import {\n    addDecoderSizePrefix,\n    addEncoderSizePrefix,\n    combineCodec,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    getArrayDecoder,\n    getArrayEncoder,\n    getBytesDecoder,\n    getBytesEncoder,\n    getStructDecoder,\n    getStructEncoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getShortU16Encoder, getU8Decoder, getU8Encoder } from '@solana/codecs-numbers';\n\nimport { getCompiledInstructions } from '../../compile/v0/instructions';\n\ntype CompiledInstruction = ReturnType<typeof getCompiledInstructions>[number];\n\nlet memoizedGetInstructionEncoder: VariableSizeEncoder<CompiledInstruction> | undefined;\nexport function getInstructionEncoder(): VariableSizeEncoder<CompiledInstruction> {\n    if (!memoizedGetInstructionEncoder) {\n        memoizedGetInstructionEncoder = transformEncoder<Required<CompiledInstruction>, CompiledInstruction>(\n            getStructEncoder([\n                ['programAddressIndex', getU8Encoder()],\n                ['accountIndices', getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() })],\n                ['data', addEncoderSizePrefix(getBytesEncoder(), getShortU16Encoder())],\n            ]),\n            // Convert an instruction to have all fields defined\n            (instruction: CompiledInstruction): Required<CompiledInstruction> => {\n                if (instruction.accountIndices !== undefined && instruction.data !== undefined) {\n                    return instruction as Required<CompiledInstruction>;\n                }\n                return {\n                    ...instruction,\n                    accountIndices: instruction.accountIndices ?? [],\n                    data: instruction.data ?? new Uint8Array(0),\n                } as Required<CompiledInstruction>;\n            },\n        );\n    }\n\n    return memoizedGetInstructionEncoder;\n}\n\nlet memoizedGetInstructionDecoder: VariableSizeDecoder<CompiledInstruction> | undefined;\nexport function getInstructionDecoder(): VariableSizeDecoder<CompiledInstruction> {\n    if (!memoizedGetInstructionDecoder) {\n        memoizedGetInstructionDecoder = transformDecoder<Required<CompiledInstruction>, CompiledInstruction>(\n            getStructDecoder([\n                ['programAddressIndex', getU8Decoder()],\n                ['accountIndices', getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() })],\n                [\n                    'data',\n                    addDecoderSizePrefix(getBytesDecoder(), getShortU16Decoder()) as VariableSizeDecoder<Uint8Array>,\n                ],\n            ]),\n            // Convert an instruction to exclude optional fields if they are empty\n            (instruction: Required<CompiledInstruction>): CompiledInstruction => {\n                if (instruction.accountIndices.length && instruction.data.byteLength) {\n                    return instruction;\n                }\n                const { accountIndices, data, ...rest } = instruction;\n                return {\n                    ...rest,\n                    ...(accountIndices.length ? { accountIndices } : null),\n                    ...(data.byteLength ? { data } : null),\n                };\n            },\n        );\n    }\n    return memoizedGetInstructionDecoder;\n}\n\nexport function getInstructionCodec(): VariableSizeCodec<CompiledInstruction> {\n    return combineCodec(getInstructionEncoder(), getInstructionDecoder());\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/legacy/lifetime-token.ts",
    "content": "import {\n    fixDecoderSize,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    fixEncoderSize,\n    transformEncoder,\n} from '@solana/codecs-core';\nimport { getNullableEncoder } from '@solana/codecs-data-structures';\nimport { getBase58Decoder, getBase58Encoder } from '@solana/codecs-strings';\n\nimport { getCompiledLifetimeToken } from '../../compile/legacy/lifetime-token';\n\ntype LifetimeToken = ReturnType<typeof getCompiledLifetimeToken>;\n\nexport function getLifetimeTokenEncoder(): FixedSizeEncoder<LifetimeToken | undefined> {\n    return transformEncoder(\n        getNullableEncoder(fixEncoderSize(getBase58Encoder(), 32), {\n            noneValue: 'zeroes',\n            prefix: null,\n        }),\n        token => token ?? null,\n    );\n}\n\nexport function getLifetimeTokenDecoder(): FixedSizeDecoder<LifetimeToken> {\n    return fixDecoderSize(getBase58Decoder(), 32);\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/legacy/message.ts",
    "content": "import { getAddressDecoder, getAddressEncoder } from '@solana/addresses';\nimport {\n    combineCodec,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder, getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getShortU16Encoder } from '@solana/codecs-numbers';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../..';\nimport { getMessageHeaderDecoder, getMessageHeaderEncoder } from './header';\nimport { getInstructionDecoder, getInstructionEncoder } from './instruction';\nimport { getLifetimeTokenDecoder, getLifetimeTokenEncoder } from './lifetime-token';\n\ntype LegacyCompiledTransactionMessage = CompiledTransactionMessage & { version: 'legacy' };\n\nexport function getMessageEncoder(): VariableSizeEncoder<\n    LegacyCompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage)\n> {\n    return transformEncoder(\n        getStructEncoder([\n            ['header', getMessageHeaderEncoder()],\n            ['staticAccounts', getArrayEncoder(getAddressEncoder(), { size: getShortU16Encoder() })],\n            ['lifetimeToken', getLifetimeTokenEncoder()],\n            ['instructions', getArrayEncoder(getInstructionEncoder(), { size: getShortU16Encoder() })],\n        ]),\n        value => ({\n            ...value,\n            lifetimeToken: 'lifetimeToken' in value ? value.lifetimeToken : undefined,\n        }),\n    );\n}\nexport function getMessageDecoder(): VariableSizeDecoder<\n    CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage\n> {\n    return transformDecoder(\n        getStructDecoder([\n            ['header', getMessageHeaderDecoder()],\n            ['staticAccounts', getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() })],\n            ['lifetimeToken', getLifetimeTokenDecoder()],\n            ['instructions', getArrayDecoder(getInstructionDecoder(), { size: getShortU16Decoder() })],\n        ]),\n        value => ({\n            ...value,\n            version: 'legacy',\n        }),\n    );\n}\n\nexport function getMessageCodec(): VariableSizeCodec<\n    LegacyCompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage),\n    CompiledTransactionMessageWithLifetime & LegacyCompiledTransactionMessage\n> {\n    return combineCodec(getMessageEncoder(), getMessageDecoder());\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/message.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getPatternMatchDecoder, getPatternMatchEncoder } from '@solana/codecs-data-structures';\nimport { SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../compile/message';\nimport { MAX_SUPPORTED_TRANSACTION_VERSION } from '../transaction-message';\nimport {\n    getMessageDecoder as getLegacyMessageDecoder,\n    getMessageEncoder as getLegacyMessageEncoder,\n} from './legacy/message';\nimport { getTransactionVersionDecoder } from './transaction-version';\nimport { getMessageDecoder as getV0MessageDecoder, getMessageEncoder as getV0MessageEncoder } from './v0/message';\nimport { getMessageDecoder as getV1MessageDecoder, getMessageEncoder as getV1MessageEncoder } from './v1/message';\n\n/**\n * Returns an encoder that you can use to encode a {@link CompiledTransactionMessage} to a byte\n * array.\n *\n * The wire format of a Solana transaction consists of signatures followed by a compiled transaction\n * message. The byte array produced by this encoder is the message part.\n */\nexport function getCompiledTransactionMessageEncoder(): VariableSizeEncoder<\n    CompiledTransactionMessage | (CompiledTransactionMessage & CompiledTransactionMessageWithLifetime)\n> {\n    return transformEncoder(\n        getPatternMatchEncoder<\n            CompiledTransactionMessage | (CompiledTransactionMessage & CompiledTransactionMessageWithLifetime)\n        >([\n            [m => m.version === 'legacy', getLegacyMessageEncoder()],\n            [m => m.version === 0, getV0MessageEncoder()],\n            [m => m.version === 1, getV1MessageEncoder()],\n        ]),\n        value => {\n            // check version is valid before encoding, so we don't get the generic pattern match error\n            if (value.version !== 'legacy' && value.version > MAX_SUPPORTED_TRANSACTION_VERSION) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                    unsupportedVersion: value.version,\n                });\n            }\n            return value;\n        },\n    );\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing a\n * {@link CompiledTransactionMessage}.\n *\n * The wire format of a Solana transaction consists of signatures followed by a compiled transaction\n * message. You can use this decoder to decode the message part.\n */\nexport function getCompiledTransactionMessageDecoder(): VariableSizeDecoder<\n    CompiledTransactionMessage & CompiledTransactionMessageWithLifetime\n> {\n    type ReturnType = VariableSizeDecoder<CompiledTransactionMessage & CompiledTransactionMessageWithLifetime>;\n\n    return createDecoder({\n        read(bytes, offset) {\n            const [version] = getTransactionVersionDecoder().read(bytes, offset);\n\n            return getPatternMatchDecoder([\n                [() => version === 'legacy', getLegacyMessageDecoder() as ReturnType],\n                [() => version === 0, getV0MessageDecoder() as ReturnType],\n                [() => version === 1, getV1MessageDecoder() as ReturnType],\n            ]).read(bytes, offset);\n        },\n    });\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link CompiledTransactionMessage}\n *\n * @see {@link getCompiledTransactionMessageDecoder}\n * @see {@link getCompiledTransactionMessageEncoder}\n */\nexport function getCompiledTransactionMessageCodec(): VariableSizeCodec<\n    CompiledTransactionMessage | (CompiledTransactionMessage & CompiledTransactionMessageWithLifetime),\n    CompiledTransactionMessage & CompiledTransactionMessageWithLifetime\n> {\n    return combineCodec(getCompiledTransactionMessageEncoder(), getCompiledTransactionMessageDecoder());\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/transaction-version.ts",
    "content": "import {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\n\nimport { MAX_SUPPORTED_TRANSACTION_VERSION, TransactionVersion } from '../transaction-message';\n\nconst VERSION_FLAG_MASK = 0x80;\n\n/**\n * Returns an encoder that you can use to encode a {@link TransactionVersion} to a byte array.\n *\n * Legacy messages will produce an empty array and will not advance the offset. Versioned messages\n * will produce an array with a single byte.\n */\nexport function getTransactionVersionEncoder(): VariableSizeEncoder<TransactionVersion> {\n    return createEncoder({\n        getSizeFromValue: value => (value === 'legacy' ? 0 : 1),\n        maxSize: 1,\n        write: (value, bytes, offset) => {\n            if (value === 'legacy') {\n                return offset;\n            }\n            if (value < 0 || value > 127) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_OUT_OF_RANGE, {\n                    actualVersion: value,\n                });\n            }\n\n            if (value > MAX_SUPPORTED_TRANSACTION_VERSION) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                    unsupportedVersion: value,\n                });\n            }\n            bytes.set([value | VERSION_FLAG_MASK], offset);\n            return offset + 1;\n        },\n    });\n}\n\n/**\n * Returns a decoder that you can use to decode a byte array representing a\n * {@link TransactionVersion}.\n *\n * When the byte at the current offset is determined to represent a legacy transaction, this decoder\n * will return `'legacy'` and will not advance the offset.\n */\nexport function getTransactionVersionDecoder(): VariableSizeDecoder<TransactionVersion> {\n    return createDecoder({\n        maxSize: 1,\n        read: (bytes, offset) => {\n            const firstByte = bytes[offset];\n            if ((firstByte & VERSION_FLAG_MASK) === 0) {\n                // No version flag set; it's a legacy (unversioned) transaction.\n                return ['legacy', offset];\n            } else {\n                const version = firstByte ^ VERSION_FLAG_MASK;\n                if (version > MAX_SUPPORTED_TRANSACTION_VERSION) {\n                    throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                        unsupportedVersion: version,\n                    });\n                }\n                return [version as TransactionVersion, offset + 1];\n            }\n        },\n    });\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to {@link TransactionVersion}\n *\n * @see {@link getTransactionVersionDecoder}\n * @see {@link getTransactionVersionEncoder}\n */\nexport function getTransactionVersionCodec(): VariableSizeCodec<TransactionVersion> {\n    return combineCodec(getTransactionVersionEncoder(), getTransactionVersionDecoder());\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v0/__tests__/address-table-lookup-test.ts",
    "content": "import type { Address } from '@solana/addresses';\n\nimport type { getCompiledAddressTableLookups } from '../../../compile/v0/address-table-lookups';\nimport {\n    getAddressTableLookupCodec,\n    getAddressTableLookupDecoder,\n    getAddressTableLookupEncoder,\n} from '../address-table-lookup';\n\ntype AddressTableLookup = ReturnType<typeof getCompiledAddressTableLookups>[number];\n\ndescribe('Address table lookup codec', () => {\n    describe.each([getAddressTableLookupEncoder, getAddressTableLookupCodec])(\n        'address table lookup encoder %p',\n        encoderFactory => {\n            let addressTableLookup: ReturnType<typeof getAddressTableLookupEncoder>;\n            beforeEach(() => {\n                addressTableLookup = encoderFactory();\n            });\n            it('serializes an `AddressTableLookup` according to the spec', () => {\n                expect(\n                    addressTableLookup.encode({\n                        lookupTableAddress: 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // decodes to [11{32}]\n                        readonlyIndexes: [33, 22],\n                        writableIndexes: [44],\n                    } as AddressTableLookup),\n                ).toEqual(\n                    // prettier-ignore\n                    new Uint8Array([\n                        // Lookup table account address\n                        11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                        // Compact array of writable indices\n                        1, // Compact-u16 length\n                        44, // Writable indicies\n                        // Compact array of read-only indices\n                        2, // Compact-u16 length\n                        33, 22, // Read-only indicies\n                    ]),\n                );\n            });\n        },\n    );\n\n    describe.each([getAddressTableLookupDecoder, getAddressTableLookupCodec])(\n        'address table lookup decoder %p',\n        decoderFactory => {\n            let addressTableLookup: ReturnType<typeof getAddressTableLookupDecoder>;\n            beforeEach(() => {\n                addressTableLookup = decoderFactory();\n            });\n\n            it('deserializes an `AddressTableLookup` according to the spec', () => {\n                const byteArray =\n                    // prettier-ignore\n                    new Uint8Array([\n                        // Lookup table account address\n                        11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                        // Compact array of writable indices\n                        1, // Compact-u16 length\n                        44, // Writable indicies\n                        // Compact array of read-only indices\n                        2, // Compact-u16 length\n                        33, 22, // Read-only indicies\n                    ]);\n                const [lookup, offset] = addressTableLookup.read(byteArray, 0);\n                expect(lookup).toEqual({\n                    lookupTableAddress: 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // decodes to [11{32}]\n                    readonlyIndexes: [33, 22],\n                    writableIndexes: [44],\n                });\n                // Expect the entire byte array to have been consumed.\n                expect(offset).toBe(byteArray.byteLength);\n            });\n        },\n    );\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v0/__tests__/message-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Decoder, Encoder } from '@solana/codecs-core';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../../../compile/message';\nimport { getMessageCodec, getMessageDecoder, getMessageEncoder } from '../message';\n\ntype V0CompiledTransactionMessage = CompiledTransactionMessage & { version: 0 };\n\ndescribe.each([getMessageCodec, getMessageEncoder])('Transaction message encoder %p', encoderFactory => {\n    let encoder: Encoder<\n        V0CompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage)\n    >;\n    beforeEach(() => {\n        encoder = encoderFactory();\n    });\n\n    it('encodes a v0 transaction with address lookup tables correctly', () => {\n        const message: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n            addressTableLookups: [\n                {\n                    lookupTableAddress: '3yS1JFVT284y8z1LC9MRoWxZjzFrdoD5axKsZiyMsfC7' as Address, // decodes to [44{32}]\n                    readonlyIndexes: [77],\n                    writableIndexes: [66, 55],\n                },\n            ],\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [\n                {\n                    accountIndices: [1, 2],\n                    data: new Uint8Array([4, 5, 6]),\n                    programAddressIndex: 0,\n                },\n                {\n                    accountIndices: [2],\n                    data: new Uint8Array([7, 8, 9]),\n                    programAddressIndex: 1,\n                },\n            ],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n            ],\n            version: 0,\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                128, // 0 + version mask\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                3, // Number of static accounts\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                2, // Number of instructions\n\n                // First instruction\n                0, // Program address index\n                2, // Number of address indices\n                1, 2, // Address indices\n                3, // Length of instruction data\n                4, 5, 6, // Instruction data itself\n\n                // Second instruction\n                1, // Program address index\n                1, // Number of address indices\n                2, // Address indices\n                3, // Length of instruction data\n                7, 8, 9, // Instruction data itself\n\n                /** ADDRESS TABLE LOOKUPS */\n                1, // Number of address table lookups\n\n                // First address table lookup\n                44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, // Address of lookup table 3yS1JFVT284y8z1LC9MRoWxZjzFrdoD5axKsZiyMsfC7\n                2, // Number of writable indices\n                66, 55, // Writable indices\n                1, // Number of readonly indices\n                77, // Readonly indices\n            ]),\n        );\n    });\n\n    it('encodes a v0 transaction with no address lookup tables correctly', () => {\n        const message: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [\n                {\n                    accountIndices: [1, 2],\n                    data: new Uint8Array([4, 5, 6]),\n                    programAddressIndex: 0,\n                },\n                {\n                    accountIndices: [2],\n                    data: new Uint8Array([7, 8, 9]),\n                    programAddressIndex: 1,\n                },\n            ],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n            ],\n            version: 0,\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                128, // 0 + version mask\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                3, // Number of static accounts\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                2, // Number of instructions\n\n                // First instruction\n                0, // Program address index\n                2, // Number of address indices\n                1, 2, // Address indices\n                3, // Length of instruction data\n                4, 5, 6, // Instruction data itself\n\n                // Second instruction\n                1, // Program address index\n                1, // Number of address indices\n                2, // Address indices\n                3, // Length of instruction data\n                7, 8, 9, // Instruction data itself\n\n                /** ADDRESS TABLE LOOKUPS */\n                0, // Number of address table lookups\n            ]),\n        );\n    });\n\n    it('encodes a v0 transaction with no instructions correctly', () => {\n        const message: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n            ],\n            version: 0,\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                128, // 0 + version mask\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                3, // Number of static accounts\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                0, // Number of instructions\n\n                /** ADDRESS TABLE LOOKUPS */\n                0, // Number of address table lookups\n            ]),\n        );\n    });\n\n    it('encodes a v0 transaction with no instructions and no accounts correctly', () => {\n        const message: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [],\n            version: 0,\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                128, // 0 + version mask\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                0, // Number of static accounts\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                0, // Number of instructions\n\n                /** ADDRESS TABLE LOOKUPS */\n                0, // Number of address table lookups\n            ]),\n        );\n    });\n});\n\ndescribe.each([getMessageCodec, getMessageDecoder])('Transaction message decoder %p', decoderFactory => {\n    let decoder: Decoder<V0CompiledTransactionMessage>;\n    beforeEach(() => {\n        decoder = decoderFactory();\n    });\n\n    it('decodes a v0 transaction with address lookup tables correctly', () => {\n        const byteArray =\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                128, // 0 + version mask\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                3, // Number of static accounts\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                2, // Number of instructions\n\n                // First instruction\n                0, // Program address index\n                2, // Number of address indices\n                1, 2, // Address indices\n                3, // Length of instruction data\n                4, 5, 6, // Instruction data itself\n\n                // Second instruction\n                1, // Program address index\n                1, // Number of address indices\n                2, // Address indices\n                3, // Length of instruction data\n                7, 8, 9, // Instruction data itself\n\n                /** ADDRESS TABLE LOOKUPS */\n                1, // Number of address table lookups\n\n                // First address table lookup\n                44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, // Address of lookup table 3yS1JFVT284y8z1LC9MRoWxZjzFrdoD5axKsZiyMsfC7\n                2, // Number of writable indices\n                66, 55, // Writable indices\n                1, // Number of readonly indices\n                77, // Readonly indices\n            ]);\n\n        const expectedMessage: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n            addressTableLookups: [\n                {\n                    lookupTableAddress: '3yS1JFVT284y8z1LC9MRoWxZjzFrdoD5axKsZiyMsfC7' as Address, // decodes to [44{32}]\n                    readonlyIndexes: [77],\n                    writableIndexes: [66, 55],\n                },\n            ],\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [\n                {\n                    accountIndices: [1, 2],\n                    data: new Uint8Array([4, 5, 6]),\n                    programAddressIndex: 0,\n                },\n                {\n                    accountIndices: [2],\n                    data: new Uint8Array([7, 8, 9]),\n                    programAddressIndex: 1,\n                },\n            ],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // decodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // decodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // decodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // decodes to [13{32}]\n            ],\n            version: 0,\n        };\n\n        expect(decoder.decode(byteArray)).toStrictEqual(expectedMessage);\n    });\n\n    it('decodes a v0 transaction with no address lookup tables to exclude the addressLookupTables field', () => {\n        const byteArray =\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                128, // 0 + version mask\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                3, // Number of static accounts\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                2, // Number of instructions\n\n                // First instruction\n                0, // Program address index\n                2, // Number of address indices\n                1, 2, // Address indices\n                3, // Length of instruction data\n                4, 5, 6, // Instruction data itself\n\n                // Second instruction\n                1, // Program address index\n                1, // Number of address indices\n                2, // Address indices\n                3, // Length of instruction data\n                7, 8, 9, // Instruction data itself\n\n                /** ADDRESS TABLE LOOKUPS */\n                0, // Number of address table lookups\n            ]);\n\n        expect(decoder.decode(byteArray)).not.toHaveProperty('addressTableLookups');\n    });\n\n    it('decodes a v0 transaction with no instructions correctly', () => {\n        const byteArray =\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                128, // 0 + version mask\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                3, // Number of static accounts\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, // p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, // swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                0, // Number of instructions\n            ]);\n\n        const expectedMessage: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address, // encodes to [13{32}]\n            ],\n            version: 0,\n        };\n\n        expect(decoder.decode(byteArray)).toStrictEqual(expectedMessage);\n    });\n\n    it('decodes a v0 transaction with no instructions and no accounts correctly', () => {\n        const byteArray =\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                128, // 0 + version mask\n\n                /** MESSAGE HEADER */\n                3, // numSignerAccounts\n                2, // numReadonlySignerAccount\n                1, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                0, // Number of static accounts\n\n                /** TRANSACTION LIFETIME TOKEN (ie. the blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, // gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5\n\n                /* INSTRUCTIONS */\n                0, // Number of instructions\n            ]);\n\n        const expectedMessage: CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 3,\n            },\n            instructions: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5', // encodes to [10{32}]\n            staticAccounts: [],\n            version: 0,\n        };\n\n        expect(decoder.decode(byteArray)).toStrictEqual(expectedMessage);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v0/address-table-lookup.ts",
    "content": "import { getAddressDecoder, getAddressEncoder } from '@solana/addresses';\nimport {\n    combineCodec,\n    type Encoder,\n    type VariableSizeCodec,\n    type VariableSizeDecoder,\n    type VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder, getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getShortU16Encoder, getU8Decoder, getU8Encoder } from '@solana/codecs-numbers';\n\nimport type { getCompiledAddressTableLookups } from '../../compile/v0/address-table-lookups';\n\ntype AddressTableLookup = ReturnType<typeof getCompiledAddressTableLookups>[number];\n\nlet memoizedAddressTableLookupEncoder: VariableSizeEncoder<AddressTableLookup> | undefined;\nexport function getAddressTableLookupEncoder(): VariableSizeEncoder<AddressTableLookup> {\n    if (!memoizedAddressTableLookupEncoder) {\n        const indexEncoder = getArrayEncoder(getU8Encoder(), { size: getShortU16Encoder() }) as Encoder<\n            readonly number[]\n        >;\n        memoizedAddressTableLookupEncoder = getStructEncoder([\n            ['lookupTableAddress', getAddressEncoder()],\n            ['writableIndexes', indexEncoder],\n            ['readonlyIndexes', indexEncoder],\n        ]);\n    }\n\n    return memoizedAddressTableLookupEncoder;\n}\n\nlet memoizedAddressTableLookupDecoder: VariableSizeDecoder<AddressTableLookup> | undefined;\nexport function getAddressTableLookupDecoder(): VariableSizeDecoder<AddressTableLookup> {\n    if (!memoizedAddressTableLookupDecoder) {\n        const indexEncoder = getArrayDecoder(getU8Decoder(), { size: getShortU16Decoder() });\n        memoizedAddressTableLookupDecoder = getStructDecoder([\n            ['lookupTableAddress', getAddressDecoder()],\n            ['writableIndexes', indexEncoder],\n            ['readonlyIndexes', indexEncoder],\n        ]);\n    }\n\n    return memoizedAddressTableLookupDecoder;\n}\n\nexport function getAddressTableLookupCodec(): VariableSizeCodec<AddressTableLookup> {\n    return combineCodec(getAddressTableLookupEncoder(), getAddressTableLookupDecoder());\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v0/message.ts",
    "content": "import { getAddressDecoder, getAddressEncoder } from '@solana/addresses';\nimport {\n    combineCodec,\n    transformDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder, getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getShortU16Encoder } from '@solana/codecs-numbers';\n\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    getTransactionVersionDecoder,\n    getTransactionVersionEncoder,\n} from '../..';\nimport { getMessageHeaderDecoder, getMessageHeaderEncoder } from '../legacy/header';\nimport { getInstructionDecoder, getInstructionEncoder } from '../legacy/instruction';\nimport { getLifetimeTokenDecoder, getLifetimeTokenEncoder } from '../legacy/lifetime-token';\nimport { getAddressTableLookupDecoder, getAddressTableLookupEncoder } from './address-table-lookup';\n\ntype V0CompiledTransactionMessage = CompiledTransactionMessage & { version: 0 };\n\nexport function getMessageEncoder(): VariableSizeEncoder<\n    V0CompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage)\n> {\n    return transformEncoder(\n        getStructEncoder([\n            ['version', getTransactionVersionEncoder()],\n            ['header', getMessageHeaderEncoder()],\n            ['staticAccounts', getArrayEncoder(getAddressEncoder(), { size: getShortU16Encoder() })],\n            ['lifetimeToken', getLifetimeTokenEncoder()],\n            ['instructions', getArrayEncoder(getInstructionEncoder(), { size: getShortU16Encoder() })],\n            ['addressTableLookups', getArrayEncoder(getAddressTableLookupEncoder(), { size: getShortU16Encoder() })],\n        ]),\n        value => ({\n            ...value,\n            addressTableLookups: value.addressTableLookups ?? [],\n            lifetimeToken: 'lifetimeToken' in value ? value.lifetimeToken : undefined,\n        }),\n    );\n}\n\nexport function getMessageDecoder(): VariableSizeDecoder<\n    CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage\n> {\n    return transformDecoder(\n        getStructDecoder([\n            ['version', getTransactionVersionDecoder()],\n            ['header', getMessageHeaderDecoder()],\n            ['staticAccounts', getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() })],\n            ['lifetimeToken', getLifetimeTokenDecoder()],\n            ['instructions', getArrayDecoder(getInstructionDecoder(), { size: getShortU16Decoder() })],\n            ['addressTableLookups', getArrayDecoder(getAddressTableLookupDecoder(), { size: getShortU16Decoder() })],\n        ]),\n        ({ addressTableLookups, ...restOfMessage }) => {\n            if (!addressTableLookups?.length) {\n                return { ...restOfMessage, version: 0 };\n            }\n            return { ...restOfMessage, addressTableLookups, version: 0 };\n        },\n    );\n}\n\nexport function getMessageCodec(): VariableSizeCodec<\n    V0CompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage),\n    CompiledTransactionMessageWithLifetime & V0CompiledTransactionMessage\n> {\n    return combineCodec(getMessageEncoder(), getMessageDecoder());\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v1/__tests__/config-test.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS, SolanaError } from '@solana/errors';\n\nimport { CompiledTransactionConfigValue } from '../../../compile/v1/config';\nimport { getCompiledTransactionConfigValuesDecoder, getCompiledTransactionConfigValuesEncoder } from '../config';\n\ndescribe('getTransactionConfigValuesEncoder', () => {\n    const encoder = getCompiledTransactionConfigValuesEncoder();\n\n    it('should encode to an empty array when no values are set', () => {\n        const config: CompiledTransactionConfigValue[] = [];\n        const encoded = encoder.encode(config);\n        expect(encoded).toEqual(new Uint8Array([]));\n    });\n\n    it('should encode an array of config values correctly', () => {\n        const config: CompiledTransactionConfigValue[] = [\n            { kind: 'u64', value: 40n },\n            { kind: 'u32', value: 30 },\n            { kind: 'u32', value: 20 },\n            { kind: 'u32', value: 10 },\n        ];\n        const encoded = encoder.encode(config);\n        expect(encoded).toEqual(\n            // prettier-ignore\n            new Uint8Array([\n                // first value (8 bytes)\n                40, 0, 0, 0, 0, 0, 0, 0,\n                // second value (4 bytes)\n                30, 0, 0, 0,\n                // third value (4 bytes)\n                20, 0, 0, 0,\n                // fourth value (4 bytes)\n                10, 0, 0, 0\n            ]),\n        );\n    });\n});\n\ndescribe('getTransactionConfigValuesDecoder', () => {\n    it('should decode an empty array when no values are set', () => {\n        const mask = 0b00000000;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(new Uint8Array([]));\n        const expected: CompiledTransactionConfigValue[] = [];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should decode all values correctly', () => {\n        // Mask with all 5 lowest bits set\n        const mask = 0b00011111;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(\n            // prettier-ignore\n            new Uint8Array([\n                // priorityFeeLamports (8 bytes)\n                10, 0, 0, 0, 0, 0, 0, 0,\n                // computeUnitLimit (4 bytes)\n                20, 0, 0, 0,\n                // loadedAccountsDataSizeLimit (4 bytes)\n                30, 0, 0, 0,\n                // heapSize (4 bytes)\n                40, 0, 0, 0\n            ]),\n        );\n        const expected: CompiledTransactionConfigValue[] = [\n            { kind: 'u64', value: 10n },\n            { kind: 'u32', value: 20 },\n            { kind: 'u32', value: 30 },\n            { kind: 'u32', value: 40 },\n        ];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should decode just priority fee correctly', () => {\n        const mask = 0b00000011;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(\n            // prettier-ignore\n            new Uint8Array([\n                // priorityFeeLamports (8 bytes)\n                10, 0, 0, 0, 0, 0, 0, 0,\n            ]),\n        );\n        const expected: CompiledTransactionConfigValue[] = [{ kind: 'u64', value: 10n }];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should decode a large priority fee value correctly', () => {\n        const mask = 0b00000011;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(\n            // prettier-ignore\n            new Uint8Array([\n                // priorityFeeLamports (8 bytes)\n                255, 255, 255, 255, 255, 255, 255, 255,\n            ]),\n        );\n        const expected: CompiledTransactionConfigValue[] = [{ kind: 'u64', value: 2n ** 64n - 1n }];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should decode just compute unit limit correctly', () => {\n        const mask = 0b00000100;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(\n            // prettier-ignore\n            new Uint8Array([\n                // computeUnitLimit (4 bytes)\n                20, 0, 0, 0\n            ]),\n        );\n        const expected: CompiledTransactionConfigValue[] = [{ kind: 'u32', value: 20 }];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should decode just loaded accounts data size limit correctly', () => {\n        const mask = 0b00001000;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(\n            // prettier-ignore\n            new Uint8Array([\n                // loadedAccountsDataSizeLimit (4 bytes)\n                30, 0, 0, 0\n            ]),\n        );\n        const expected: CompiledTransactionConfigValue[] = [{ kind: 'u32', value: 30 }];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should decode just heap size correctly', () => {\n        const mask = 0b00010000;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(\n            // prettier-ignore\n            new Uint8Array([\n                // heapSize (4 bytes)\n                40, 0, 0, 0\n            ]),\n        );\n        const expected: CompiledTransactionConfigValue[] = [{ kind: 'u32', value: 40 }];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should decode multiple values correctly', () => {\n        const mask = 0b00001011;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(\n            // prettier-ignore\n            new Uint8Array([\n                // priorityFeeLamports (8 bytes)\n                10, 0, 0, 0, 0, 0, 0, 0,\n                // loadedAccountsDataSizeLimit (4 bytes)\n                30, 0, 0, 0\n            ]),\n        );\n        const expected: CompiledTransactionConfigValue[] = [\n            { kind: 'u64', value: 10n },\n            { kind: 'u32', value: 30 },\n        ];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should decode a large priority fee value correctly with another value', () => {\n        const mask = 0b00000111;\n        const decoder = getCompiledTransactionConfigValuesDecoder(mask);\n        const decoded = decoder.decode(\n            // prettier-ignore\n            new Uint8Array([\n                // priorityFeeLamports (8 bytes)\n                255, 255, 255, 255, 255, 255, 255, 255,\n                // computeUnitLimit (4 bytes)\n                20, 0, 0, 0\n            ]),\n        );\n        const expected: CompiledTransactionConfigValue[] = [\n            { kind: 'u64', value: 2n ** 64n - 1n },\n            { kind: 'u32', value: 20 },\n        ];\n        expect(decoded).toEqual(expected);\n    });\n\n    it('should throw an error if only one priority fee bit is set (malformed)', () => {\n        // Only bit 0 set - malformed, bits 0 and 1 must match\n        const mask = 0b01;\n        expect(() => getCompiledTransactionConfigValuesDecoder(mask)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS, { mask }),\n        );\n    });\n\n    it('should throw an error if only the other priority fee bit is set (malformed)', () => {\n        // Only bit 1 set - malformed, bits 0 and 1 must match\n        const mask = 0b10;\n        expect(() => getCompiledTransactionConfigValuesDecoder(mask)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS, { mask }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v1/__tests__/instruction-test.ts",
    "content": "import { InstructionHeader, InstructionPayload } from '../../../compile/v1/instructions';\nimport {\n    getInstructionHeaderCodec,\n    getInstructionHeaderDecoder,\n    getInstructionHeaderEncoder,\n    getInstructionPayloadDecoder,\n    getInstructionPayloadEncoder,\n} from '../instruction';\n\ndescribe.each([getInstructionHeaderEncoder, getInstructionHeaderCodec])(\n    'instruction header encoder %p',\n    encoderFactory => {\n        const encoder = encoderFactory();\n\n        it('encodes the instruction header when all fields are defined', () => {\n            const instructionHeader: InstructionHeader = {\n                numInstructionAccounts: 2,\n                numInstructionDataBytes: 3,\n                programAccountIndex: 1,\n            };\n            expect(encoder.encode(instructionHeader)).toEqual(\n                new Uint8Array([\n                    1, // programAccountIndex (1 byte)\n                    2, // numInstructionAccounts (1 byte)\n                    3,\n                    0, // numInstructionDataBytes (2 bytes)\n                ]),\n            );\n        });\n    },\n);\n\ndescribe.each([getInstructionHeaderDecoder, getInstructionHeaderCodec])(\n    'instruction header decoder %p',\n    decoderFactory => {\n        const decoder = decoderFactory();\n\n        it('decodes the instruction header when all fields are defined', () => {\n            // pretter-ignore\n            const encoded = new Uint8Array([\n                1, // programAccountIndex (1 byte)\n                2, // numInstructionAccounts (1 byte)\n                3,\n                0, // numInstructionDataBytes (2 bytes)\n            ]);\n            expect(decoder.decode(encoded)).toEqual({\n                numInstructionAccounts: 2,\n                numInstructionDataBytes: 3,\n                programAccountIndex: 1,\n            });\n        });\n    },\n);\n\ndescribe('getInstructionPayloadEncoder', () => {\n    const encoder = getInstructionPayloadEncoder();\n\n    it('encodes the instruction payload when all fields are defined', () => {\n        const instruction: InstructionPayload = {\n            instructionAccountIndices: [2, 3],\n            instructionData: new Uint8Array([1, 2, 3]),\n        };\n        expect(encoder.encode(instruction)).toEqual(\n            new Uint8Array([\n                2,\n                3, // account indices (2 bytes)\n                1,\n                2,\n                3, // data bytes (3 bytes)\n            ]),\n        );\n    });\n\n    it('encodes just the data when `instructionAccountIndices` is empty', () => {\n        const instruction: InstructionPayload = {\n            instructionAccountIndices: [],\n            instructionData: new Uint8Array([1, 2, 3]),\n        };\n        expect(encoder.encode(instruction)).toEqual(\n            new Uint8Array([\n                1,\n                2,\n                3, // data bytes (3 bytes)\n            ]),\n        );\n    });\n\n    it('encodes just the account indices when `instructionData` is empty', () => {\n        const instruction: InstructionPayload = {\n            instructionAccountIndices: [2, 3],\n            instructionData: new Uint8Array([]),\n        };\n        expect(encoder.encode(instruction)).toEqual(\n            new Uint8Array([\n                2,\n                3, // account indices (2 bytes)\n            ]),\n        );\n    });\n\n    it('encodes an empty payload when both `instructionAccountIndices` and `instructionData` are empty', () => {\n        const instruction: InstructionPayload = {\n            instructionAccountIndices: [],\n            instructionData: new Uint8Array([]),\n        };\n        expect(encoder.encode(instruction)).toEqual(new Uint8Array([]));\n    });\n});\n\ndescribe('getInstructionPayloadDecoder', () => {\n    it('decodes the instruction payload when all fields are defined', () => {\n        const decoder = getInstructionPayloadDecoder({\n            numInstructionAccounts: 2,\n            numInstructionDataBytes: 3,\n        });\n        const bytes = new Uint8Array([\n            1,\n            2, // account indices (2 bytes)\n            3,\n            4,\n            5, // data bytes (3 bytes)\n        ]);\n        const expected: InstructionPayload = {\n            instructionAccountIndices: [1, 2],\n            instructionData: new Uint8Array([3, 4, 5]),\n        };\n        expect(decoder.decode(bytes)).toEqual(expected);\n    });\n\n    it('reads empty `accountIndices` when `numInstructionAccounts` is 0', () => {\n        const decoder = getInstructionPayloadDecoder({\n            numInstructionAccounts: 0,\n            numInstructionDataBytes: 3,\n        });\n        const bytes = new Uint8Array([\n            1,\n            2,\n            3, // data bytes (3 bytes)\n        ]);\n        const expected: InstructionPayload = {\n            instructionAccountIndices: [],\n            instructionData: new Uint8Array([1, 2, 3]),\n        };\n        expect(decoder.decode(bytes)).toEqual(expected);\n    });\n\n    it('reads empty `data` when `numInstructionDataBytes` is 0', () => {\n        const decoder = getInstructionPayloadDecoder({\n            numInstructionAccounts: 2,\n            numInstructionDataBytes: 0,\n        });\n        const bytes = new Uint8Array([\n            2,\n            3, // account indices (2 bytes)\n        ]);\n        const expected: InstructionPayload = {\n            instructionAccountIndices: [2, 3],\n            instructionData: new Uint8Array([]),\n        };\n        expect(decoder.decode(bytes)).toEqual(expected);\n    });\n\n    it('decodes an empty payload when both `numInstructionAccounts` and `numInstructionDataBytes` are 0', () => {\n        const decoder = getInstructionPayloadDecoder({\n            numInstructionAccounts: 0,\n            numInstructionDataBytes: 0,\n        });\n        expect(decoder.decode(new Uint8Array([]))).toEqual({\n            instructionAccountIndices: [],\n            instructionData: new Uint8Array([]),\n        });\n    });\n\n    it('only reads the number of bytes specified by `numInstructionDataBytes`', () => {\n        const decoder = getInstructionPayloadDecoder({\n            numInstructionAccounts: 0,\n            numInstructionDataBytes: 2,\n        });\n        const bytes = new Uint8Array([\n            1,\n            2, // data bytes (2 bytes)\n            3, // additional byte that should not be read as data\n        ]);\n        const expected: InstructionPayload = {\n            instructionAccountIndices: [],\n            instructionData: new Uint8Array([1, 2]),\n        };\n        expect(decoder.decode(bytes)).toEqual(expected);\n    });\n\n    it('only reads the number of account indices specified by `numInstructionAccounts`', () => {\n        const decoder = getInstructionPayloadDecoder({\n            numInstructionAccounts: 2,\n            numInstructionDataBytes: 0,\n        });\n        const bytes = new Uint8Array([\n            2,\n            3, // account indices (2 bytes)\n            4, // additional byte that should not be read as an account index\n        ]);\n        const expected: InstructionPayload = {\n            instructionAccountIndices: [2, 3],\n            instructionData: new Uint8Array([]),\n        };\n        expect(decoder.decode(bytes)).toEqual(expected);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v1/__tests__/message-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Decoder, Encoder, ReadonlyUint8Array } from '@solana/codecs-core';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../../../compile/message';\nimport { getMessageCodec, getMessageDecoder, getMessageEncoder } from '../message';\n\ntype V1CompiledTransactionMessage = CompiledTransactionMessage & { version: 1 };\n\ndescribe.each([getMessageCodec, getMessageEncoder])('V1 Transaction message encoder %p', encoderFactory => {\n    let encoder: Encoder<\n        V1CompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage)\n    >;\n    beforeEach(() => {\n        encoder = encoderFactory();\n    });\n\n    it('encodes a v1 transaction with no config values', () => {\n        const message: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n            // encodes to [10{32}]\n            configMask: 0,\n\n            configValues: [],\n\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 1,\n                numSignerAccounts: 2,\n            },\n\n            instructionHeaders: [\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 3,\n                    programAccountIndex: 1,\n                },\n            ],\n            instructionPayloads: [\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array([1, 2, 3]) as ReadonlyUint8Array,\n                },\n            ],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5',\n            numInstructions: 1,\n            numStaticAccounts: 2,\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address, // encodes to [11{32}]\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address, // encodes to [12{32}]\n            ],\n            version: 1,\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                129, // 1 + version mask (0x80)\n\n                /** MESSAGE HEADER */\n                2, // numSignerAccounts\n                1, // numReadonlySignerAccounts\n                1, // numReadonlyNonSignerAccounts\n\n                /** CONFIG MASK */\n                0, 0, 0, 0, // configMask (u32) = 0\n\n                /** LIFETIME TOKEN (blockhash) */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n                /** NUM INSTRUCTIONS */\n                1, // numInstructions (u8)\n\n                /** NUM ADDRESSES */\n                2, // numStaticAccounts (u8)\n\n                /** STATIC ADDRESSES */\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\n                /** CONFIG VALUES */\n                // (none - mask is 0)\n\n                /** INSTRUCTION HEADERS */\n                1, // programAccountIndex\n                1, // numInstructionAccounts\n                3, 0, // numInstructionDataBytes (u16, little endian)\n\n                /** INSTRUCTION PAYLOADS */\n                0, // account index\n                1, 2, 3, // instruction data\n            ]),\n        );\n    });\n\n    it('encodes a v1 transaction with priority fee only', () => {\n        const message: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n            configMask: 0b11,\n            // Priority fee bits\n            configValues: [{ kind: 'u64', value: 5000n }],\n\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 1,\n            },\n\n            instructionHeaders: [],\n\n            instructionPayloads: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5',\n            numInstructions: 0,\n            numStaticAccounts: 1,\n            staticAccounts: ['k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address],\n            version: 1,\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                129,\n\n                /** MESSAGE HEADER */\n                1, 0, 1,\n\n                /** CONFIG MASK */\n                3, 0, 0, 0, // configMask (u32) = 0b11\n\n                /** LIFETIME TOKEN */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n                /** NUM INSTRUCTIONS */\n                0,\n\n                /** NUM ADDRESSES */\n                1,\n\n                /** STATIC ADDRESSES */\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\n                /** CONFIG VALUES */\n                136, 19, 0, 0, 0, 0, 0, 0, // 5000 as u64 (little endian)\n\n                /** INSTRUCTION HEADERS */\n                // (none)\n\n                /** INSTRUCTION PAYLOADS */\n                // (none)\n            ]),\n        );\n    });\n\n    it('encodes a v1 transaction with all config values', () => {\n        const message: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n            configMask: 0b11111,\n            // All config flags set\n            configValues: [\n                { kind: 'u64', value: 5000n }, // Priority fee\n                { kind: 'u32', value: 200000 }, // Compute unit limit\n                { kind: 'u32', value: 64000 }, // Loaded accounts data size limit\n                { kind: 'u32', value: 256000 }, // Heap size\n            ],\n\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 1,\n            },\n\n            instructionHeaders: [],\n\n            instructionPayloads: [],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5',\n            numInstructions: 0,\n            numStaticAccounts: 1,\n            staticAccounts: ['k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address],\n            version: 1,\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                129,\n\n                /** MESSAGE HEADER */\n                1, 0, 0,\n\n                /** CONFIG MASK */\n                31, 0, 0, 0, // configMask (u32) = 0b11111\n\n                /** LIFETIME TOKEN */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n                /** NUM INSTRUCTIONS */\n                0,\n\n                /** NUM ADDRESSES */\n                1,\n\n                /** STATIC ADDRESSES */\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\n                /** CONFIG VALUES */\n                136, 19, 0, 0, 0, 0, 0, 0, // 5000 as u64\n                64, 13, 3, 0, // 200000 as u32\n                0, 250, 0, 0, // 64000 as u32\n                0, 232, 3, 0, // 256000 as u32\n\n                /** INSTRUCTION HEADERS */\n                // (none)\n\n                /** INSTRUCTION PAYLOADS */\n                // (none)\n            ]),\n        );\n    });\n\n    it('encodes a v1 transaction with multiple instructions', () => {\n        const message: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n            configMask: 0,\n            configValues: [],\n            header: {\n                numReadonlyNonSignerAccounts: 2,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 1,\n            },\n            instructionHeaders: [\n                {\n                    numInstructionAccounts: 2,\n                    numInstructionDataBytes: 3,\n                    programAccountIndex: 1,\n                },\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 2,\n                },\n            ],\n            instructionPayloads: [\n                {\n                    instructionAccountIndices: [0, 2],\n                    instructionData: new Uint8Array([10, 20, 30]) as ReadonlyUint8Array,\n                },\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array([]) as ReadonlyUint8Array,\n                },\n            ],\n            lifetimeToken: 'gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5',\n            numInstructions: 2,\n            numStaticAccounts: 3,\n            staticAccounts: [\n                'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address,\n                'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address,\n                'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address,\n            ],\n            version: 1,\n        };\n\n        expect(encoder.encode(message)).toStrictEqual(\n            // prettier-ignore\n            new Uint8Array([\n                /** VERSION HEADER */\n                129,\n\n                /** MESSAGE HEADER */\n                1, 0, 2,\n\n                /** CONFIG MASK */\n                0, 0, 0, 0,\n\n                /** LIFETIME TOKEN */\n                10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n                /** NUM INSTRUCTIONS */\n                2,\n\n                /** NUM ADDRESSES */\n                3,\n\n                /** STATIC ADDRESSES */\n                11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n                12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n                13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\n                /** CONFIG VALUES */\n                // (none)\n\n                /** INSTRUCTION HEADERS */\n                1, 2, 3, 0, // First header\n                2, 1, 0, 0, // Second header\n\n                /** INSTRUCTION PAYLOADS */\n                0, 2, // First payload account indices\n                10, 20, 30, // First payload data\n                0, // Second payload account index\n                // Second payload has no data\n            ]),\n        );\n    });\n});\n\ndescribe.each([getMessageCodec, getMessageDecoder])('V1 Transaction message decoder %p', decoderFactory => {\n    let decoder: Decoder<CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage>;\n    beforeEach(() => {\n        decoder = decoderFactory();\n    });\n\n    it('decodes a v1 transaction with no config values', () => {\n        // prettier-ignore\n        const bytes = new Uint8Array([\n            /** VERSION HEADER */\n            129, // 1 + version mask (0x80)\n\n            /** MESSAGE HEADER */\n            2, // numSignerAccounts\n            1, // numReadonlySignerAccounts\n            1, // numReadonlyNonSignerAccounts\n\n            /** CONFIG MASK */\n            0, 0, 0, 0, // configMask (u32) = 0\n\n            /** LIFETIME TOKEN (blockhash) */\n            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n            /** NUM INSTRUCTIONS */\n            1, // numInstructions (u8)\n\n            /** NUM ADDRESSES */\n            2, // numStaticAccounts (u8)\n\n            /** STATIC ADDRESSES */\n            11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\n            /** CONFIG VALUES */\n            // (none - mask is 0)\n\n            /** INSTRUCTION HEADERS */\n            1, // programAccountIndex\n            1, // numInstructionAccounts\n            3, 0, // numInstructionDataBytes (u16, little endian)\n\n            /** INSTRUCTION PAYLOADS */\n            0, // account index\n            1, 2, 3, // instruction data\n        ]);\n\n        const message = decoder.decode(bytes);\n\n        expect(message).toMatchObject({\n            configMask: 0,\n            configValues: [],\n            header: {\n                numReadonlyNonSignerAccounts: 1,\n                numReadonlySignerAccounts: 1,\n                numSignerAccounts: 2,\n            },\n            instructionHeaders: [\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 3,\n                    programAccountIndex: 1,\n                },\n            ],\n            instructionPayloads: [\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array([1, 2, 3]),\n                },\n            ],\n            numInstructions: 1,\n            numStaticAccounts: 2,\n            version: 1,\n        });\n        expect(message.staticAccounts).toHaveLength(2);\n        expect(message.lifetimeToken).toBe('gBxS1f6uyyGPuW5MzGBukidSb71jdsCb5fZaoSzULE5');\n    });\n\n    it('decodes a v1 transaction with priority fee', () => {\n        // prettier-ignore\n        const bytes = new Uint8Array([\n            /** VERSION HEADER */\n            129,\n\n            /** MESSAGE HEADER */\n            1, 0, 1,\n\n            /** CONFIG MASK */\n            3, 0, 0, 0, // configMask (u32) = 0b11\n\n            /** LIFETIME TOKEN */\n            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n            /** NUM INSTRUCTIONS */\n            0,\n\n            /** NUM ADDRESSES */\n            1,\n\n            /** STATIC ADDRESSES */\n            11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\n            /** CONFIG VALUES */\n            136, 19, 0, 0, 0, 0, 0, 0, // 5000 as u64 (little endian)\n\n            /** INSTRUCTION HEADERS */\n            // (none)\n\n            /** INSTRUCTION PAYLOADS */\n            // (none)\n        ]);\n\n        const message = decoder.decode(bytes);\n\n        expect(message).toMatchObject({\n            configMask: 3,\n            configValues: [{ kind: 'u64', value: 5000n }],\n            numInstructions: 0,\n            numStaticAccounts: 1,\n            version: 1,\n        });\n    });\n\n    it('decodes a v1 transaction with all config values', () => {\n        // prettier-ignore\n        const bytes = new Uint8Array([\n            /** VERSION HEADER */\n            129,\n\n            /** MESSAGE HEADER */\n            1, 0, 0,\n\n            /** CONFIG MASK */\n            31, 0, 0, 0, // configMask (u32) = 0b11111\n\n            /** LIFETIME TOKEN */\n            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n            /** NUM INSTRUCTIONS */\n            0,\n\n            /** NUM ADDRESSES */\n            1,\n\n            /** STATIC ADDRESSES */\n            11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\n            /** CONFIG VALUES */\n            136, 19, 0, 0, 0, 0, 0, 0, // 5000 as u64\n            64, 13, 3, 0, // 200000 as u32\n            0, 250, 0, 0, // 64000 as u32\n            0, 232, 3, 0, // 256000 as u32\n\n            /** INSTRUCTION HEADERS */\n            // (none)\n\n            /** INSTRUCTION PAYLOADS */\n            // (none)\n        ]);\n\n        const message = decoder.decode(bytes);\n\n        expect(message).toMatchObject({\n            configMask: 31,\n            configValues: [\n                { kind: 'u64', value: 5000n },\n                { kind: 'u32', value: 200000 },\n                { kind: 'u32', value: 64000 },\n                { kind: 'u32', value: 256000 },\n            ],\n            version: 1,\n        });\n    });\n\n    it('decodes a v1 transaction with multiple instructions', () => {\n        // prettier-ignore\n        const bytes = new Uint8Array([\n            /** VERSION HEADER */\n            129,\n\n            /** MESSAGE HEADER */\n            1, 0, 2,\n\n            /** CONFIG MASK */\n            0, 0, 0, 0,\n\n            /** LIFETIME TOKEN */\n            10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\n            /** NUM INSTRUCTIONS */\n            2,\n\n            /** NUM ADDRESSES */\n            3,\n\n            /** STATIC ADDRESSES */\n            11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n            12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n            13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\n            /** CONFIG VALUES */\n            // (none)\n\n            /** INSTRUCTION HEADERS */\n            1, 2, 3, 0, // First header\n            2, 1, 0, 0, // Second header\n\n            /** INSTRUCTION PAYLOADS */\n            0, 2, // First payload account indices\n            10, 20, 30, // First payload data\n            0, // Second payload account index\n            // Second payload has no data\n        ]);\n\n        const message = decoder.decode(bytes);\n\n        expect(message).toMatchObject({\n            instructionHeaders: [\n                {\n                    numInstructionAccounts: 2,\n                    numInstructionDataBytes: 3,\n                    programAccountIndex: 1,\n                },\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 2,\n                },\n            ],\n            instructionPayloads: [\n                {\n                    instructionAccountIndices: [0, 2],\n                    instructionData: new Uint8Array([10, 20, 30]),\n                },\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array([]),\n                },\n            ],\n            numInstructions: 2,\n            numStaticAccounts: 3,\n            version: 1,\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v1/config.ts",
    "content": "import { transformDecoder, VariableSizeDecoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport {\n    getArrayEncoder,\n    getPatternMatchEncoder,\n    getStructEncoder,\n    getTupleDecoder,\n    getUnitDecoder,\n} from '@solana/codecs-data-structures';\nimport { getU32Decoder, getU32Encoder, getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\n\nimport { CompiledTransactionConfigValue } from '../../compile/v1/config';\nimport {\n    transactionConfigMaskHasComputeUnitLimit,\n    transactionConfigMaskHasHeapSize,\n    transactionConfigMaskHasLoadedAccountsDataSizeLimit,\n    transactionConfigMaskHasPriorityFee,\n} from '../../v1-transaction-config';\n\n/* TODO issue #1143 - we have a type error on `getPatternMatchEncoder` where it incorrectly\n * types the return as FixedSizeEncoder when used with differently sized FixedSizEencoder\n * inputs. For now we cast to VariableSizeEncoder, which is what the underlying union codec\n * actually returns.\n */\nfunction getCompiledTransactionConfigValueEncoder(): VariableSizeEncoder<CompiledTransactionConfigValue> {\n    return getPatternMatchEncoder<CompiledTransactionConfigValue>([\n        [value => value.kind === 'u32', getStructEncoder([['value', getU32Encoder()]])],\n        [value => value.kind === 'u64', getStructEncoder([['value', getU64Encoder()]])],\n    ]) as unknown as VariableSizeEncoder<CompiledTransactionConfigValue>;\n}\n\n/**\n * Encode a {@link TransactionMessageConfig} into a variable length byte array, where the fields set are encoded based on their data size.\n * @returns An Encoder for {@link TransactionMessageConfig}\n */\nexport function getCompiledTransactionConfigValuesEncoder(): VariableSizeEncoder<CompiledTransactionConfigValue[]> {\n    return getArrayEncoder(getCompiledTransactionConfigValueEncoder(), { size: 'remainder' });\n}\n\n/**\n * Decode a {@link TransactionMessageConfig} from a byte array of values, using the provided mask.\n * @param mask A mask indicating which fields are set\n * @returns A Decoder for {@link TransactionMessageConfig}\n */\nexport function getCompiledTransactionConfigValuesDecoder(\n    mask: number,\n): VariableSizeDecoder<CompiledTransactionConfigValue[]> {\n    const hasPriorityFee = transactionConfigMaskHasPriorityFee(mask);\n    const hasComputeUnitLimit = transactionConfigMaskHasComputeUnitLimit(mask);\n    const hasLoadedAccountsDataSizeLimit = transactionConfigMaskHasLoadedAccountsDataSizeLimit(mask);\n    const hasHeapSize = transactionConfigMaskHasHeapSize(mask);\n\n    const u32Decoder = transformDecoder(getU32Decoder(), value => ({ kind: 'u32', value }));\n    const u64Decoder = transformDecoder(getU64Decoder(), value => ({ kind: 'u64', value }));\n    const unitDecoder = getUnitDecoder();\n\n    return transformDecoder(\n        getTupleDecoder([\n            hasPriorityFee ? u64Decoder : unitDecoder,\n            hasComputeUnitLimit ? u32Decoder : unitDecoder,\n            hasLoadedAccountsDataSizeLimit ? u32Decoder : unitDecoder,\n            hasHeapSize ? u32Decoder : unitDecoder,\n        ]),\n        arr => arr.filter(Boolean) as CompiledTransactionConfigValue[],\n    );\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v1/instruction.ts",
    "content": "import {\n    combineCodec,\n    fixDecoderSize,\n    FixedSizeCodec,\n    FixedSizeDecoder,\n    FixedSizeEncoder,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    getArrayDecoder,\n    getArrayEncoder,\n    getBytesDecoder,\n    getBytesEncoder,\n    getStructDecoder,\n    getStructEncoder,\n} from '@solana/codecs-data-structures';\nimport { getU8Decoder, getU8Encoder, getU16Decoder, getU16Encoder } from '@solana/codecs-numbers';\n\nimport { InstructionHeader, InstructionPayload } from '../../compile/v1/instructions';\n\n/**\n * Encode the fixed size {@link InstructionHeader}\n * @returns A FixedSizeEncoder for the instruction header\n */\nexport function getInstructionHeaderEncoder(): FixedSizeEncoder<InstructionHeader> {\n    return getStructEncoder([\n        ['programAccountIndex', getU8Encoder()],\n        ['numInstructionAccounts', getU8Encoder()],\n        ['numInstructionDataBytes', getU16Encoder()],\n    ]);\n}\n\n/**\n * Decode an {@link InstructionHeader} from a byte array\n * @returns A FixedSizeDecoder for the instruction header\n */\nexport function getInstructionHeaderDecoder(): FixedSizeDecoder<InstructionHeader> {\n    return getStructDecoder([\n        ['programAccountIndex', getU8Decoder()],\n        ['numInstructionAccounts', getU8Decoder()],\n        ['numInstructionDataBytes', getU16Decoder()],\n    ]);\n}\n\n/**\n * Get a codec for the {@link InstructionHeader}, which includes both the encoder and decoder\n * @returns A FixedSizeCodec for the instruction header\n */\nexport function getInstructionHeaderCodec(): FixedSizeCodec<InstructionHeader> {\n    return combineCodec(getInstructionHeaderEncoder(), getInstructionHeaderDecoder());\n}\n\n/**\n * Encode the variable size {@link InstructionPayload}, which includes the account indices and instruction data.\n * Both arrays may be empty\n * @returns A VariableSizeEncoder for the instruction payload\n */\nexport function getInstructionPayloadEncoder(): VariableSizeEncoder<InstructionPayload> {\n    return getStructEncoder([\n        ['instructionAccountIndices', getArrayEncoder(getU8Encoder(), { size: 'remainder' })],\n        ['instructionData', getBytesEncoder()],\n    ]);\n}\n\n/**\n * Decode an {@link InstructionPayload} from a byte array, given the instruction header\n * @param instructionHeader The header for the instruction\n * @returns A decoder for InstructionPayload\n */\nexport function getInstructionPayloadDecoder(\n    instructionHeader: Pick<InstructionHeader, 'numInstructionAccounts' | 'numInstructionDataBytes'>,\n): VariableSizeDecoder<InstructionPayload> {\n    return getStructDecoder([\n        [\n            'instructionAccountIndices',\n            getArrayDecoder(getU8Decoder(), { size: instructionHeader.numInstructionAccounts }),\n        ],\n        ['instructionData', fixDecoderSize(getBytesDecoder(), instructionHeader.numInstructionDataBytes)],\n    ]);\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/codecs/v1/message.ts",
    "content": "import { getAddressDecoder, getAddressEncoder } from '@solana/addresses';\nimport {\n    combineCodec,\n    createDecoder,\n    transformEncoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport { getArrayDecoder, getArrayEncoder, getStructDecoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getU8Decoder, getU8Encoder, getU32Decoder, getU32Encoder } from '@solana/codecs-numbers';\n\nimport { CompiledTransactionMessageWithLifetime, V1CompiledTransactionMessage } from '../..';\nimport { InstructionPayload } from '../../compile/v1/instructions';\nimport { getMessageHeaderDecoder, getMessageHeaderEncoder } from '../legacy/header';\nimport { getLifetimeTokenDecoder, getLifetimeTokenEncoder } from '../legacy/lifetime-token';\nimport { getTransactionVersionDecoder, getTransactionVersionEncoder } from '../transaction-version';\nimport { getCompiledTransactionConfigValuesDecoder, getCompiledTransactionConfigValuesEncoder } from './config';\nimport {\n    getInstructionHeaderDecoder,\n    getInstructionHeaderEncoder,\n    getInstructionPayloadDecoder,\n    getInstructionPayloadEncoder,\n} from './instruction';\n\nexport function getMessageEncoder(): VariableSizeEncoder<\n    V1CompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage)\n> {\n    return transformEncoder(\n        getStructEncoder([\n            ['version', getTransactionVersionEncoder()],\n            ['header', getMessageHeaderEncoder()],\n            ['configMask', getU32Encoder()],\n            ['lifetimeToken', getLifetimeTokenEncoder()],\n            ['numInstructions', getU8Encoder()],\n            ['numStaticAccounts', getU8Encoder()],\n            ['staticAccounts', getArrayEncoder(getAddressEncoder(), { size: 'remainder' })],\n            ['configValues', getCompiledTransactionConfigValuesEncoder()],\n            ['instructionHeaders', getArrayEncoder(getInstructionHeaderEncoder(), { size: 'remainder' })],\n            ['instructionPayloads', getArrayEncoder(getInstructionPayloadEncoder(), { size: 'remainder' })],\n        ]),\n        value => ({\n            ...value,\n            lifetimeToken: 'lifetimeToken' in value ? value.lifetimeToken : undefined,\n        }),\n    );\n}\n\nexport function getMessageDecoder(): VariableSizeDecoder<\n    CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage\n> {\n    return createDecoder({\n        read(bytes, offset) {\n            const [{ header, configMask, lifetimeToken, numInstructions, numStaticAccounts }, afterFixedFields] =\n                getStructDecoder([\n                    ['version', getTransactionVersionDecoder()],\n                    ['header', getMessageHeaderDecoder()],\n                    ['configMask', getU32Decoder()],\n                    ['lifetimeToken', getLifetimeTokenDecoder()],\n                    ['numInstructions', getU8Decoder()],\n                    ['numStaticAccounts', getU8Decoder()],\n                ]).read(bytes, offset);\n\n            let nextOffset = afterFixedFields;\n            const [staticAccounts, afterAddresses] = getArrayDecoder(getAddressDecoder(), {\n                size: numStaticAccounts,\n            }).read(bytes, nextOffset);\n            nextOffset = afterAddresses;\n\n            const [configValues, afterConfig] = getCompiledTransactionConfigValuesDecoder(configMask).read(\n                bytes,\n                nextOffset,\n            );\n            nextOffset = afterConfig;\n\n            const [instructionHeaders, afterHeaders] = getArrayDecoder(getInstructionHeaderDecoder(), {\n                size: numInstructions,\n            }).read(bytes, nextOffset);\n            nextOffset = afterHeaders;\n\n            const instructionPayloads: InstructionPayload[] = [];\n            for (const header of instructionHeaders) {\n                const [payload, next] = getInstructionPayloadDecoder(header).read(bytes, nextOffset);\n                instructionPayloads.push(payload);\n                nextOffset = next;\n            }\n\n            const compiledMessage: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                configMask,\n                configValues,\n                header,\n                instructionHeaders,\n                instructionPayloads,\n                lifetimeToken,\n                numInstructions,\n                numStaticAccounts,\n                staticAccounts,\n                version: 1,\n            };\n\n            return [compiledMessage, nextOffset];\n        },\n    });\n}\n\nexport function getMessageCodec(): VariableSizeCodec<\n    V1CompiledTransactionMessage | (CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage),\n    CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage\n> {\n    return combineCodec(getMessageEncoder(), getMessageDecoder());\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/__tests__/message-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport {\n    compileTransactionMessage,\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithLifetime,\n} from '../..';\nimport { compileTransactionMessage as compileLegacyTransactionMessage } from '../legacy/message';\nimport { compileTransactionMessage as compileV0TransactionMessage } from '../v0/message';\nimport { compileTransactionMessage as compileV1TransactionMessage } from '../v1/message';\n\njest.mock('../legacy/message');\njest.mock('../v0/message');\njest.mock('../v1/message');\n\nconst MOCK_LIFETIME_CONSTRAINT =\n    'SOME_CONSTRAINT' as unknown as TransactionMessageWithBlockhashLifetime['lifetimeConstraint'];\n\ndescribe('compileTransactionMessage', () => {\n    it('uses the legacy compiler for legacy messages', () => {\n        const mockCompiledMessage = { version: 'legacy' } as unknown as ReturnType<\n            typeof compileLegacyTransactionMessage\n        >;\n        jest.mocked(compileLegacyTransactionMessage).mockReturnValue(mockCompiledMessage);\n\n        const tx: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime = {\n            feePayer: { address: 'abc' as Address },\n            instructions: [],\n            lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n            version: 'legacy',\n        };\n\n        expect(compileTransactionMessage(tx)).toBe(mockCompiledMessage);\n        expect(compileLegacyTransactionMessage).toHaveBeenCalledTimes(1);\n        expect(compileLegacyTransactionMessage).toHaveBeenCalledWith(tx);\n    });\n\n    it('uses the v0 compiler for v0 messages', () => {\n        const mockCompiledMessage = { version: 0 } as unknown as ReturnType<typeof compileV0TransactionMessage>;\n        jest.mocked(compileV0TransactionMessage).mockReturnValue(mockCompiledMessage);\n\n        const tx: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime = {\n            feePayer: { address: 'abc' as Address },\n            instructions: [],\n            lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n            version: 0,\n        };\n\n        expect(compileTransactionMessage(tx)).toBe(mockCompiledMessage);\n        expect(compileV0TransactionMessage).toHaveBeenCalledTimes(1);\n        expect(compileV0TransactionMessage).toHaveBeenCalledWith(tx);\n    });\n\n    it('uses the v1 compiler for v1 messages', () => {\n        const mockCompiledMessage = { version: 1 } as unknown as ReturnType<typeof compileV1TransactionMessage>;\n        jest.mocked(compileV1TransactionMessage).mockReturnValue(mockCompiledMessage);\n\n        const tx: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime = {\n            feePayer: { address: 'abc' as Address },\n            instructions: [],\n            lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n            version: 1,\n        };\n\n        expect(compileTransactionMessage(tx)).toBe(mockCompiledMessage);\n        expect(compileV1TransactionMessage).toHaveBeenCalledTimes(1);\n        expect(compileV1TransactionMessage).toHaveBeenCalledWith(tx);\n    });\n\n    it('throws for unsupported v2 transaction', () => {\n        const tx = {\n            feePayer: { address: 'abc' as Address },\n            instructions: [],\n            lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n            version: 2,\n        } as unknown as TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime;\n\n        expect(() => compileTransactionMessage(tx)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                version: 2,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/__typetests__/message-typetest.ts",
    "content": "import {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithLifetime,\n} from '../..';\nimport { compileTransactionMessage } from '../message';\n\n// [DESCRIBE] compileTransactionMessage\n{\n    // It returns a CompiledTransactionMessage\n    {\n        // For legacy\n        {\n            const message = null as unknown as TransactionMessage &\n                TransactionMessageWithFeePayer & { version: 'legacy' };\n            compileTransactionMessage(message) satisfies CompiledTransactionMessage;\n        }\n\n        // For v0\n        {\n            const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { version: 0 };\n            compileTransactionMessage(message) satisfies CompiledTransactionMessage;\n        }\n\n        // For v1\n        {\n            const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { version: 1 };\n            compileTransactionMessage(message) satisfies CompiledTransactionMessage;\n        }\n    }\n\n    // It does not satisfy `CompiledTransactionMessageWithLifetime` if the source message does not have a lifetime constraint\n    {\n        // For legacy\n        {\n            const message = null as unknown as TransactionMessage &\n                TransactionMessageWithFeePayer & { version: 'legacy' };\n            const compiled = compileTransactionMessage(message);\n            // @ts-expect-error Should not have a lifetime token\n            compiled satisfies CompiledTransactionMessageWithLifetime;\n        }\n\n        // For v0\n        {\n            const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { version: 0 };\n            const compiled = compileTransactionMessage(message);\n            // @ts-expect-error Should not have a lifetime token\n            compiled satisfies CompiledTransactionMessageWithLifetime;\n        }\n\n        // For v1\n        {\n            const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { version: 1 };\n            const compiled = compileTransactionMessage(message);\n            // @ts-expect-error Should not have a lifetime token\n            compiled satisfies CompiledTransactionMessageWithLifetime;\n        }\n    }\n\n    // It satisfies `CompiledTransactionMessageWithLifetime` if the source message has a lifetime constraint\n    {\n        // For legacy\n        {\n            const message = null as unknown as TransactionMessage &\n                TransactionMessageWithFeePayer &\n                TransactionMessageWithLifetime & { version: 'legacy' };\n            const compiled = compileTransactionMessage(message);\n            compiled satisfies CompiledTransactionMessageWithLifetime;\n        }\n\n        // For v0\n        {\n            const message = null as unknown as TransactionMessage &\n                TransactionMessageWithFeePayer &\n                TransactionMessageWithLifetime & { version: 0 };\n            const compiled = compileTransactionMessage(message);\n            compiled satisfies CompiledTransactionMessageWithLifetime;\n        }\n\n        // For v1\n        {\n            const message = null as unknown as TransactionMessage &\n                TransactionMessageWithFeePayer &\n                TransactionMessageWithLifetime & { version: 1 };\n            const compiled = compileTransactionMessage(message);\n            compiled satisfies CompiledTransactionMessageWithLifetime;\n        }\n    }\n\n    // It forwards a legacy version from the source message to the compiled message\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { version: 'legacy' };\n        compileTransactionMessage(message) satisfies CompiledTransactionMessage & { version: 'legacy' };\n    }\n\n    // It forwards a v0 version from the source message to the compiled message\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { version: 0 };\n        compileTransactionMessage(message) satisfies CompiledTransactionMessage & { version: 0 };\n    }\n\n    // It forwards a v1 version from the source message to the compiled message\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { version: 1 };\n        compileTransactionMessage(message) satisfies CompiledTransactionMessage & { version: 1 };\n    }\n\n    // The version can be narrowed\n    {\n        const message = null as unknown as TransactionMessage & TransactionMessageWithFeePayer;\n        const compiled = compileTransactionMessage(message);\n        compiled satisfies CompiledTransactionMessage;\n        // @ts-expect-error Version could be different\n        compiled satisfies CompiledTransactionMessage & { version: 'legacy' };\n        if (compiled.version === 'legacy') {\n            compiled satisfies CompiledTransactionMessage & { version: 'legacy' };\n        }\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/index.ts",
    "content": "export * from './message';\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/__tests__/accounts-test.ts",
    "content": "import { Address, getAddressComparator } from '@solana/addresses';\nimport { AccountRole, Instruction } from '@solana/instructions';\n\nimport {\n    ADDRESS_MAP_TYPE_PROPERTY as TYPE,\n    AddressMapEntryType,\n    getAddressMapFromInstructions,\n    getOrderedAccountsFromAddressMap,\n} from '../accounts';\n\ntype AccountRoleEnumName = keyof typeof AccountRole;\ntype TestCase = {\n    aRole: AccountRoleEnumName;\n    bRole: AccountRoleEnumName;\n    expectedEntry:\n        | typeof FEE_PAYER_ENTRY\n        | typeof STATIC_ENTRY_READONLY\n        | typeof STATIC_ENTRY_READONLY_SIGNER\n        | typeof STATIC_ENTRY_WRITABLE\n        | typeof STATIC_ENTRY_WRITABLE_SIGNER;\n    instructionOrder: [string, (i: Instruction[]) => Instruction[]];\n    role: AccountRoleEnumName;\n    staticRole: AccountRoleEnumName;\n};\n\nconst MOCK_ADDRESSES: ReadonlyArray<Address> = [\n    'BRwZRKsvKkG45g59269qZ5e8UaECFim5Qfxex44UKwDG',\n    'AZE3mXbzNp8SfZYBfL4L67ejQ8zmatAKKezUdCarKnUL',\n    'Awft9caFzun5FcVTaXJAkAYDBgbEDF5QALeaqeY3M3Va',\n    'ARc8zz6T14LZQTpjryhBGDuNZb3YmNT9PtEuBSuVM5xo',\n    '6Tu9wk1r9yGwzd3xdrVzDttmkTN98iiffq7L25JKTvwh',\n    '4R6dgeBbwPjnTSN78KGxhB78oFsxaobiwBsCBLAyauqA',\n] as Address[];\n\nlet _nextMockAddress = 0;\nfunction getMockAddress() {\n    return `${_nextMockAddress++}` as Address;\n}\nfunction forwardOrder(i: Instruction[]) {\n    return i;\n}\nfunction reverseOrder(i: Instruction[]) {\n    return i.reverse();\n}\n\nconst FEE_PAYER_ENTRY = { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER } as const;\nconst STATIC_ENTRY_READONLY = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.READONLY } as const;\nconst STATIC_ENTRY_READONLY_SIGNER = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.READONLY_SIGNER } as const;\nconst STATIC_ENTRY_WRITABLE = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.WRITABLE } as const;\nconst STATIC_ENTRY_WRITABLE_SIGNER = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.WRITABLE_SIGNER } as const;\n\ndescribe('getAddressMapFromInstructions', () => {\n    it('creates a fee-payer entry for the fee payer', () => {\n        const feePayerAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(feePayerAddress, []);\n        expect(addressMap).toHaveProperty(feePayerAddress, FEE_PAYER_ENTRY);\n    });\n    it('creates a READONLY static entry for a program address', () => {\n        const programAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [{ programAddress }]);\n        expect(addressMap).toHaveProperty(programAddress, STATIC_ENTRY_READONLY);\n    });\n    it('creates a READONLY static entry for a static account address', () => {\n        const staticAccountAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n            {\n                accounts: [{ address: staticAccountAddress, role: AccountRole.READONLY }],\n                programAddress: getMockAddress(),\n            },\n        ]);\n        expect(addressMap).toHaveProperty(staticAccountAddress, STATIC_ENTRY_READONLY);\n    });\n    it.each`\n        role                 | expectedEntry\n        ${'READONLY'}        | ${STATIC_ENTRY_READONLY}\n        ${'WRITABLE'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n    `('creates a $role static entry for a $role static account address', ({ expectedEntry, role }: TestCase) => {\n        const staticAccountAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n            {\n                accounts: [{ address: staticAccountAddress, role: AccountRole[role] }],\n                programAddress: getMockAddress(),\n            },\n        ]);\n        expect(addressMap).toHaveProperty(staticAccountAddress, expectedEntry);\n    });\n    it('fatals given a matching fee payer and program address', () => {\n        const commonAddress = getMockAddress();\n        expect(() => {\n            getAddressMapFromInstructions(/* fee payer */ commonAddress, [{ programAddress: commonAddress }]);\n        }).toThrow();\n    });\n    it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])(\n        'creates a fee-payer entry given a matching fee payer and %s static account address',\n        role => {\n            const commonAddress = getMockAddress();\n            const addressMap = getAddressMapFromInstructions(/* fee payer */ commonAddress, [\n                {\n                    accounts: [{ address: commonAddress, role: AccountRole[role] }],\n                    programAddress: getMockAddress(),\n                },\n            ]);\n            expect(addressMap).toHaveProperty(commonAddress, FEE_PAYER_ENTRY);\n        },\n    );\n    it('creates one READONLY static entry given two matching program addresses', () => {\n        const commonAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n            { programAddress: commonAddress },\n            { programAddress: commonAddress },\n        ]);\n        expect(addressMap).toHaveProperty(commonAddress, STATIC_ENTRY_READONLY);\n    });\n    it.each`\n        role                 | instructionOrder\n        ${'READONLY'}        | ${['static address comes first', forwardOrder]}\n        ${'READONLY_SIGNER'} | ${['static address comes first', forwardOrder]}\n        ${'READONLY'}        | ${['program address comes first', reverseOrder]}\n        ${'READONLY_SIGNER'} | ${['program address comes first', reverseOrder]}\n    `(\n        'creates a $role static entry given a matching program and $role static account address when the $instructionOrder.0',\n        ({ instructionOrder: [_, orderInstructions], role }: TestCase) => {\n            const commonAddress = getMockAddress();\n            const addressMap = getAddressMapFromInstructions(\n                /* fee payer */ getMockAddress(),\n                orderInstructions([\n                    {\n                        accounts: [{ address: commonAddress, role: AccountRole[role] }],\n                        programAddress: getMockAddress(),\n                    },\n                    {\n                        programAddress: commonAddress,\n                    },\n                ]),\n            );\n            expect(addressMap).toHaveProperty(commonAddress, {\n                [TYPE]: AddressMapEntryType.STATIC,\n                role: AccountRole[role],\n            });\n        },\n    );\n    it.each`\n        role                 | instructionOrder\n        ${'WRITABLE'}        | ${['static address comes first', forwardOrder]}\n        ${'WRITABLE_SIGNER'} | ${['static address comes first', forwardOrder]}\n        ${'WRITABLE'}        | ${['program address comes first', reverseOrder]}\n        ${'WRITABLE_SIGNER'} | ${['program address comes first', reverseOrder]}\n    `(\n        'fatals given a matching program and $role static account address when the $instructionOrder.0',\n        ({ instructionOrder: [_, orderInstructions], role }: TestCase) => {\n            const commonAddress = getMockAddress();\n            expect(() =>\n                getAddressMapFromInstructions(\n                    /* fee payer */ getMockAddress(),\n                    orderInstructions([\n                        {\n                            accounts: [{ address: commonAddress, role: AccountRole[role] }],\n                            programAddress: getMockAddress(),\n                        },\n                        { programAddress: commonAddress },\n                    ]),\n                ),\n            ).toThrow();\n        },\n    );\n    it.each`\n        aRole                | bRole                | endRole              | expectedEntry\n        ${'READONLY'}        | ${'READONLY'}        | ${'READONLY'}        | ${STATIC_ENTRY_READONLY}\n        ${'READONLY'}        | ${'WRITABLE'}        | ${'WRITABLE'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'READONLY'}        | ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER}\n        ${'READONLY'}        | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE'}        | ${'READONLY'}        | ${'WRITABLE'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'WRITABLE'}        | ${'WRITABLE'}        | ${'WRITABLE'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'WRITABLE'}        | ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE'}        | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'READONLY_SIGNER'} | ${'READONLY'}        | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER}\n        ${'READONLY_SIGNER'} | ${'WRITABLE'}        | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER}\n        ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${'READONLY'}        | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE'}        | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n    `(\n        'creates one $endRole static entry given matching $aRole and $bRole static accounts',\n        ({ aRole, bRole, expectedEntry }: TestCase) => {\n            const commonAddress = getMockAddress();\n            const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n                {\n                    accounts: [{ address: commonAddress, role: AccountRole[aRole] }],\n                    programAddress: getMockAddress(),\n                },\n                {\n                    accounts: [{ address: commonAddress, role: AccountRole[bRole] }],\n                    programAddress: getMockAddress(),\n                },\n            ]);\n            expect(addressMap).toHaveProperty(commonAddress, expectedEntry);\n        },\n    );\n});\n\ndescribe('getOrderedAccountsFromAddressMap', () => {\n    let sortedAddresses: Address[];\n    beforeEach(() => {\n        sortedAddresses = [...MOCK_ADDRESSES].sort(getAddressComparator());\n    });\n    it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])(\n        'puts the fee payer before %s static addresses',\n        role => {\n            const orderedAccounts = getOrderedAccountsFromAddressMap({\n                [sortedAddresses[0]]: { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole[role] },\n                [sortedAddresses[1]]: { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER },\n            });\n            expect(orderedAccounts).toHaveProperty('0', {\n                [TYPE]: AddressMapEntryType.FEE_PAYER,\n                address: sortedAddresses[1],\n                role: AccountRole.WRITABLE_SIGNER,\n            });\n        },\n    );\n    it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])(\n        'orders %s static account addresses in lexical order',\n        role => {\n            const roleMeta = { role: AccountRole[role] };\n            const orderedAccounts = getOrderedAccountsFromAddressMap({\n                [sortedAddresses[1]]: { [TYPE]: AddressMapEntryType.STATIC, ...roleMeta },\n                [sortedAddresses[0]]: { [TYPE]: AddressMapEntryType.STATIC, ...roleMeta },\n            });\n            expect(orderedAccounts).toEqual([\n                { [TYPE]: AddressMapEntryType.STATIC, address: sortedAddresses[0], ...roleMeta },\n                { [TYPE]: AddressMapEntryType.STATIC, address: sortedAddresses[1], ...roleMeta },\n            ]);\n        },\n    );\n    it.each`\n        beforeKind                  | beforeEntry                     | afterKind                   | afterEntry\n        ${'WRITABLE static'}        | ${STATIC_ENTRY_WRITABLE}        | ${'READONLY static'}        | ${STATIC_ENTRY_READONLY}\n        ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'READONLY static'}        | ${STATIC_ENTRY_READONLY}\n        ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'WRITABLE static'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'READONLY static'}        | ${STATIC_ENTRY_READONLY}\n        ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'WRITABLE static'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER}\n    `('orders $beforeKind addresses before $afterKind addresses', ({ afterEntry, beforeEntry }) => {\n        const orderedAccounts = getOrderedAccountsFromAddressMap({\n            [sortedAddresses[0]]: afterEntry,\n            [sortedAddresses[1]]: beforeEntry,\n        });\n        expect(orderedAccounts).toEqual([\n            { address: sortedAddresses[1], ...beforeEntry },\n            { address: sortedAddresses[0], ...afterEntry },\n        ]);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/__tests__/header-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountRole } from '@solana/instructions';\n\nimport { OrderedAccounts } from '../accounts';\nimport { getCompiledMessageHeader } from '../header';\n\nlet _nextMockAddress = 0;\nfunction getMockAddress() {\n    return `${_nextMockAddress++}` as Address;\n}\n\ndescribe('getCompiledMessageHeader', () => {\n    it('counts the number of signers', () => {\n        expect(\n            getCompiledMessageHeader([\n                { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n                { address: getMockAddress(), role: AccountRole.READONLY_SIGNER },\n                { address: getMockAddress(), role: AccountRole.READONLY_SIGNER },\n                { address: getMockAddress(), role: AccountRole.WRITABLE },\n                { address: getMockAddress(), role: AccountRole.READONLY },\n                {\n                    address: getMockAddress(),\n                    addressIndex: 0,\n                    lookupTableAddress: getMockAddress(),\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: getMockAddress(),\n                    addressIndex: 1,\n                    lookupTableAddress: getMockAddress(),\n                    role: AccountRole.READONLY,\n                },\n            ] as OrderedAccounts),\n        ).toHaveProperty('numSignerAccounts', 3);\n    });\n    it('counts the number of readonly signers', () => {\n        expect(\n            getCompiledMessageHeader([\n                { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n                { address: getMockAddress(), role: AccountRole.READONLY_SIGNER },\n                { address: getMockAddress(), role: AccountRole.READONLY_SIGNER },\n                { address: getMockAddress(), role: AccountRole.WRITABLE },\n                { address: getMockAddress(), role: AccountRole.READONLY },\n                {\n                    address: getMockAddress(),\n                    addressIndex: 0,\n                    lookupTableAddress: getMockAddress(),\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: getMockAddress(),\n                    addressIndex: 1,\n                    lookupTableAddress: getMockAddress(),\n                    role: AccountRole.READONLY,\n                },\n            ] as OrderedAccounts),\n        ).toHaveProperty('numReadonlySignerAccounts', 2);\n    });\n    it('counts the number of readonly non-signers, ignoring lookup table addresses', () => {\n        expect(\n            getCompiledMessageHeader([\n                { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n                { address: getMockAddress(), role: AccountRole.READONLY_SIGNER },\n                { address: getMockAddress(), role: AccountRole.READONLY_SIGNER },\n                { address: getMockAddress(), role: AccountRole.WRITABLE },\n                { address: getMockAddress(), role: AccountRole.READONLY },\n                {\n                    address: getMockAddress(),\n                    addressIndex: 0,\n                    lookupTableAddress: getMockAddress(),\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: getMockAddress(),\n                    addressIndex: 1,\n                    lookupTableAddress: getMockAddress(),\n                    role: AccountRole.READONLY,\n                },\n            ] as OrderedAccounts),\n        ).toHaveProperty('numReadonlyNonSignerAccounts', 1);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/__tests__/instructions-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountRole, Instruction } from '@solana/instructions';\n\nimport { OrderedAccounts } from '../accounts';\nimport { getAccountIndex, getCompiledInstructions } from '../instructions';\n\nlet _nextMockAddress = 0;\nfunction getMockAddress() {\n    return `${_nextMockAddress++}` as Address;\n}\n\ndescribe('getCompiledInstructions', () => {\n    it('compiles no account indices when are no accounts', () => {\n        const compiledInstructions = getCompiledInstructions(\n            [{ programAddress: getMockAddress() }],\n            [] as unknown as OrderedAccounts,\n        );\n        expect(compiledInstructions[0]).not.toHaveProperty('accountIndices');\n    });\n    it('compiles no data when there is no data', () => {\n        const compiledInstructions = getCompiledInstructions(\n            [{ programAddress: getMockAddress() }],\n            [] as unknown as OrderedAccounts,\n        );\n        expect(compiledInstructions[0]).not.toHaveProperty('data');\n    });\n    it('compiles account addresses into indices of the account addresses', () => {\n        const addressAtIndex2 = getMockAddress();\n        const addressAtIndex3 = getMockAddress();\n        const addressAtIndex4 = getMockAddress();\n        const programAddressAtIndex1 = getMockAddress();\n        const instructions = [\n            {\n                accounts: [\n                    { address: addressAtIndex3, role: AccountRole.READONLY },\n                    { address: addressAtIndex2, role: AccountRole.WRITABLE },\n                ],\n                programAddress: programAddressAtIndex1,\n            },\n            {\n                accounts: [{ address: addressAtIndex4, role: AccountRole.READONLY }],\n                programAddress: programAddressAtIndex1,\n            },\n        ] as Instruction[];\n        const compiledInstructions = getCompiledInstructions(instructions, [\n            { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n            { address: programAddressAtIndex1, role: AccountRole.READONLY },\n            { address: addressAtIndex2, role: AccountRole.WRITABLE },\n            { address: addressAtIndex3, role: AccountRole.READONLY },\n            { address: addressAtIndex4, role: AccountRole.READONLY },\n        ] as OrderedAccounts);\n        expect(compiledInstructions).toHaveProperty('0.accountIndices', [3, 2]);\n        expect(compiledInstructions).toHaveProperty('1.accountIndices', [4]);\n    });\n    it('copies over the instruction data verbatim', () => {\n        const expectedData = new Uint8Array([1, 2, 3]);\n        const compiledInstructions = getCompiledInstructions(\n            [{ data: expectedData, programAddress: getMockAddress() }],\n            [] as unknown as OrderedAccounts,\n        );\n        expect(compiledInstructions[0]).toHaveProperty('data', expectedData);\n    });\n    it('compiles the program address into a program address index', () => {\n        const programAddress = getMockAddress();\n        const compiledInstructions = getCompiledInstructions([{ programAddress }], [\n            { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n            { address: programAddress, role: AccountRole.READONLY },\n        ] as OrderedAccounts);\n        expect(compiledInstructions[0]).toHaveProperty('programAddressIndex', 1);\n    });\n});\n\ndescribe('getAccountIndex', () => {\n    it('returns an empty object when given an empty array', () => {\n        const accountIndex = getAccountIndex([] as unknown as OrderedAccounts);\n        expect(accountIndex).toEqual({});\n    });\n\n    it('returns a mapping of addresses to their indices for a single account', () => {\n        const address = getMockAddress();\n        const accountIndex = getAccountIndex([{ address, role: AccountRole.WRITABLE_SIGNER }] as OrderedAccounts);\n        expect(accountIndex).toEqual({ [address]: 0 });\n    });\n\n    it('returns a mapping of addresses to their indices for multiple accounts', () => {\n        const address0 = getMockAddress();\n        const address1 = getMockAddress();\n        const address2 = getMockAddress();\n        const address3 = getMockAddress();\n        const accountIndex = getAccountIndex([\n            { address: address0, role: AccountRole.WRITABLE_SIGNER },\n            { address: address1, role: AccountRole.READONLY },\n            { address: address2, role: AccountRole.WRITABLE },\n            { address: address3, role: AccountRole.READONLY_SIGNER },\n        ] as OrderedAccounts);\n        expect(accountIndex).toEqual({\n            [address0]: 0,\n            [address1]: 1,\n            [address2]: 2,\n            [address3]: 3,\n        });\n    });\n\n    it('uses the last occurrence when there are duplicate addresses', () => {\n        const address = getMockAddress();\n        const accountIndex = getAccountIndex([\n            { address, role: AccountRole.READONLY },\n            { address, role: AccountRole.WRITABLE_SIGNER },\n        ] as OrderedAccounts);\n        expect(accountIndex).toEqual({ [address]: 1 });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/__tests__/lifetime-token-test.ts",
    "content": "import type { Blockhash } from '@solana/rpc-types';\n\nimport { Nonce } from '../../../durable-nonce';\nimport { getCompiledLifetimeToken } from '../lifetime-token';\n\ndescribe('getCompiledLifetimeToken', () => {\n    it('compiles a recent blockhash lifetime constraint', () => {\n        const token = getCompiledLifetimeToken({\n            blockhash: 'abc' as Blockhash,\n            lastValidBlockHeight: 100n,\n        });\n        expect(token).toBe('abc');\n    });\n    it('compiles a nonce lifetime constraint', () => {\n        const token = getCompiledLifetimeToken({\n            nonce: 'abc' as Nonce,\n        });\n        expect(token).toBe('abc');\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/__tests__/message-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\n\nimport { TransactionMessageWithBlockhashLifetime } from '../../../blockhash';\nimport { TransactionMessageWithFeePayer } from '../../../fee-payer';\nimport { TransactionMessageWithLifetime } from '../../../lifetime';\nimport { TransactionMessage } from '../../../transaction-message';\nimport { getOrderedAccountsFromAddressMap, OrderedAccounts } from '../accounts';\nimport { getCompiledMessageHeader } from '../header';\nimport { getCompiledInstructions } from '../instructions';\nimport { getCompiledLifetimeToken } from '../lifetime-token';\nimport { compileTransactionMessage } from '../message';\n\njest.mock('../accounts');\njest.mock('../header');\njest.mock('../instructions');\njest.mock('../lifetime-token');\n\nconst MOCK_LIFETIME_CONSTRAINT =\n    'SOME_CONSTRAINT' as unknown as TransactionMessageWithBlockhashLifetime['lifetimeConstraint'];\n\ndescribe('compileTransactionMessage', () => {\n    let baseTx: TransactionMessage &\n        TransactionMessageWithFeePayer &\n        TransactionMessageWithLifetime & { version: 'legacy' };\n    beforeEach(() => {\n        baseTx = {\n            feePayer: { address: 'abc' as Address<'abc'> },\n            instructions: [],\n            lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n            version: 'legacy',\n        };\n        jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue([] as unknown as OrderedAccounts);\n    });\n    describe('message header', () => {\n        const expectedCompiledMessageHeader = {\n            numReadonlyNonSignerAccounts: 0,\n            numReadonlySignerAccounts: 0,\n            numSignerAccounts: 1,\n        } as const;\n        beforeEach(() => {\n            jest.mocked(getCompiledMessageHeader).mockReturnValue(expectedCompiledMessageHeader);\n        });\n        it('sets `header` to the return value of `getCompiledMessageHeader`', () => {\n            const message = compileTransactionMessage(baseTx);\n            expect(getCompiledMessageHeader).toHaveBeenCalled();\n            expect(message.header).toBe(expectedCompiledMessageHeader);\n        });\n    });\n    describe('instructions', () => {\n        const expectedInstructions = [] as ReturnType<typeof getCompiledInstructions>;\n        beforeEach(() => {\n            jest.mocked(getCompiledInstructions).mockReturnValue(expectedInstructions);\n        });\n        it('sets `instructions` to the return value of `getCompiledInstructions`', () => {\n            const message = compileTransactionMessage(baseTx);\n            console.log({ message });\n            expect(getCompiledInstructions).toHaveBeenCalledWith(\n                baseTx.instructions,\n                expect.any(Array) /* orderedAccounts */,\n            );\n            expect(message.instructions).toBe(expectedInstructions);\n        });\n    });\n    describe('lifetime constraints', () => {\n        beforeEach(() => {\n            jest.mocked(getCompiledLifetimeToken).mockReturnValue('abc');\n        });\n        it('sets `lifetimeToken` to the return value of `getCompiledLifetimeToken`', () => {\n            const message = compileTransactionMessage(baseTx);\n            expect(getCompiledLifetimeToken).toHaveBeenCalledWith('SOME_CONSTRAINT');\n            expect(message.lifetimeToken).toBe('abc');\n        });\n    });\n    describe('static accounts', () => {\n        const expectedOrderedAccounts: ReturnType<typeof getOrderedAccountsFromAddressMap> = [\n            {\n                address: 'abc' as Address<'abc'>,\n                role: AccountRole.WRITABLE_SIGNER,\n            },\n            {\n                address: 'def' as Address<'def'>,\n                role: AccountRole.READONLY,\n            },\n        ] as ReturnType<typeof getOrderedAccountsFromAddressMap>;\n        beforeEach(() => {\n            jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(expectedOrderedAccounts);\n        });\n        it('sets `staticAccounts` to the return value of `getCompiledStaticAccounts`', () => {\n            const message = compileTransactionMessage(baseTx);\n            expect(getOrderedAccountsFromAddressMap).toHaveBeenCalled();\n            expect(message.staticAccounts).toStrictEqual(['abc' as Address<'abc'>, 'def' as Address<'def'>]);\n        });\n    });\n    describe('versions', () => {\n        it('compiles the version', () => {\n            const message = compileTransactionMessage(baseTx);\n            expect(message).toHaveProperty('version', 'legacy');\n        });\n    });\n    describe('constraints', () => {\n        describe('too many account addresses', () => {\n            it('throws when there are more than 64 unique accounts', () => {\n                const accounts = Array.from({ length: 65 }, (_, i) => ({\n                    address: `account${i}` as Address,\n                    role: AccountRole.READONLY,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES, {\n                        actualCount: 65,\n                        maxAllowed: 64,\n                    }),\n                );\n            });\n            it('does not throw with exactly 64 unique accounts', () => {\n                const accounts = Array.from({ length: 64 }, (_, i) => ({\n                    address: `account${i}` as Address,\n                    role: AccountRole.READONLY,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                expect(() => compileTransactionMessage(baseTx)).not.toThrow();\n            });\n        });\n        describe('too many signer addresses', () => {\n            it('throws when there are more than 12 unique signers', () => {\n                const accounts = Array.from({ length: 13 }, (_, i) => ({\n                    address: `signer${i}` as Address,\n                    role: AccountRole.WRITABLE_SIGNER,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES, {\n                        actualCount: 13,\n                        maxAllowed: 12,\n                    }),\n                );\n            });\n            it('does not throw with exactly 12 signers', () => {\n                const accounts = Array.from({ length: 12 }, (_, i) => ({\n                    address: `signer${i}` as Address,\n                    role: AccountRole.WRITABLE_SIGNER,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                expect(() => compileTransactionMessage(baseTx)).not.toThrow();\n            });\n        });\n        describe('too many instructions', () => {\n            it('throws when there are more than 64 instructions', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: Array.from({ length: 65 }, () => ({ programAddress: 'prog' as Address })),\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS, {\n                        actualCount: 65,\n                        maxAllowed: 64,\n                    }),\n                );\n            });\n            it('does not throw with exactly 64 instructions', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: Array.from({ length: 64 }, () => ({ programAddress: 'prog' as Address })),\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).not.toThrow();\n            });\n        });\n        describe('too many accounts in an instruction', () => {\n            it('throws when an instruction has more than 255 account references', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: [\n                        {\n                            accounts: Array.from({ length: 256 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                        actualCount: 256,\n                        instructionIndex: 0,\n                        maxAllowed: 255,\n                    }),\n                );\n            });\n            it('does not throw with exactly 255 accounts in an instruction', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: [\n                        {\n                            accounts: Array.from({ length: 255 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).not.toThrow();\n            });\n            it('reports the correct instruction index when a later instruction violates the constraint', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: [\n                        { programAddress: 'prog' as Address },\n                        {\n                            accounts: Array.from({ length: 256 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                        actualCount: 256,\n                        instructionIndex: 1,\n                        maxAllowed: 255,\n                    }),\n                );\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/accounts.ts",
    "content": "import { Address, getAddressComparator } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES,\n    SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,\n    SolanaError,\n} from '@solana/errors';\nimport {\n    AccountMeta,\n    AccountRole,\n    Instruction,\n    isSignerRole,\n    isWritableRole,\n    mergeRoles,\n    ReadonlyAccount,\n    ReadonlySignerAccount,\n    WritableAccount,\n    WritableSignerAccount,\n} from '@solana/instructions';\nimport { Brand } from '@solana/nominal-types';\n\nexport const enum AddressMapEntryType {\n    FEE_PAYER,\n    STATIC,\n}\n\ntype AddressMap = {\n    [address: string]: FeePayerAccountEntry | StaticAccountEntry;\n};\ntype FeePayerAccountEntry = Omit<WritableSignerAccount, 'address'> & {\n    [TYPE]: AddressMapEntryType.FEE_PAYER;\n};\nexport type OrderedAccounts = Brand<AccountMeta[], 'OrderedAccounts'>;\ntype StaticAccountEntry = Omit<\n    ReadonlyAccount | ReadonlySignerAccount | WritableAccount | WritableSignerAccount,\n    'address'\n> & { [TYPE]: AddressMapEntryType.STATIC };\n\nfunction upsert(\n    addressMap: AddressMap,\n    address: Address,\n    update: (entry: FeePayerAccountEntry | Record<never, never> | StaticAccountEntry) => AddressMap[Address],\n) {\n    addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });\n}\n\nconst TYPE = Symbol('AddressMapTypeProperty');\nexport const ADDRESS_MAP_TYPE_PROPERTY: typeof TYPE = TYPE;\n\nexport function getAddressMapFromInstructions(feePayer: Address, instructions: readonly Instruction[]): AddressMap {\n    const addressMap: AddressMap = {\n        [feePayer]: { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER },\n    };\n    const addressesOfInvokedPrograms = new Set<Address>();\n    for (const instruction of instructions) {\n        upsert(addressMap, instruction.programAddress, entry => {\n            addressesOfInvokedPrograms.add(instruction.programAddress);\n            if (TYPE in entry) {\n                if (isWritableRole(entry.role)) {\n                    switch (entry[TYPE]) {\n                        case AddressMapEntryType.FEE_PAYER:\n                            throw new SolanaError(SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES, {\n                                programAddress: instruction.programAddress,\n                            });\n                        default:\n                            throw new SolanaError(SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE, {\n                                programAddress: instruction.programAddress,\n                            });\n                    }\n                }\n                if (entry[TYPE] === AddressMapEntryType.STATIC) {\n                    return entry;\n                }\n            }\n            return { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.READONLY };\n        });\n        if (!instruction.accounts) {\n            continue;\n        }\n        for (const account of instruction.accounts) {\n            upsert(addressMap, account.address, entry => {\n                const {\n                    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n                    address: _,\n                    ...accountMeta\n                } = account;\n                if (TYPE in entry) {\n                    switch (entry[TYPE]) {\n                        case AddressMapEntryType.FEE_PAYER:\n                            // The fee payer already has the highest rank -- it is by definition\n                            // writable-signer. Return it, no matter how `account` is configured\n                            return entry;\n                        case AddressMapEntryType.STATIC: {\n                            const nextRole = mergeRoles(entry.role, accountMeta.role);\n                            if (\n                                // Check to see if this address represents a program that is invoked\n                                // in this transaction.\n                                addressesOfInvokedPrograms.has(account.address)\n                            ) {\n                                if (isWritableRole(accountMeta.role)) {\n                                    throw new SolanaError(\n                                        SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,\n                                        {\n                                            programAddress: account.address,\n                                        },\n                                    );\n                                }\n                                if (entry.role !== nextRole) {\n                                    return {\n                                        ...entry,\n                                        role: nextRole,\n                                    } as StaticAccountEntry;\n                                } else {\n                                    return entry;\n                                }\n                            } else {\n                                if (entry.role !== nextRole) {\n                                    // The account's role ranks higher than the current entry's.\n                                    return {\n                                        ...entry,\n                                        role: nextRole,\n                                    } as StaticAccountEntry;\n                                } else {\n                                    return entry;\n                                }\n                            }\n                        }\n                    }\n                }\n                return {\n                    ...accountMeta,\n                    [TYPE]: AddressMapEntryType.STATIC,\n                };\n            });\n        }\n    }\n    return addressMap;\n}\n\nexport function getOrderedAccountsFromAddressMap(addressMap: AddressMap): OrderedAccounts {\n    let addressComparator: ReturnType<typeof getAddressComparator>;\n    const orderedAccounts: AccountMeta[] = Object.entries(addressMap)\n        .sort(([leftAddress, leftEntry], [rightAddress, rightEntry]) => {\n            // STEP 1: Rapid precedence check. Fee payer, then static addresses\n            if (leftEntry[TYPE] !== rightEntry[TYPE]) {\n                if (leftEntry[TYPE] === AddressMapEntryType.FEE_PAYER) {\n                    return -1;\n                } else if (rightEntry[TYPE] === AddressMapEntryType.FEE_PAYER) {\n                    return 1;\n                } else if (leftEntry[TYPE] === AddressMapEntryType.STATIC) {\n                    return -1;\n                } else if (rightEntry[TYPE] === AddressMapEntryType.STATIC) {\n                    return 1;\n                }\n            }\n            // STEP 2: Sort by signer-writability.\n            const leftIsSigner = isSignerRole(leftEntry.role);\n            if (leftIsSigner !== isSignerRole(rightEntry.role)) {\n                return leftIsSigner ? -1 : 1;\n            }\n            const leftIsWritable = isWritableRole(leftEntry.role);\n            if (leftIsWritable !== isWritableRole(rightEntry.role)) {\n                return leftIsWritable ? -1 : 1;\n            }\n            // STEP 3: Sort by address.\n            addressComparator ||= getAddressComparator();\n            return addressComparator(leftAddress, rightAddress);\n        })\n        .map(([address, addressMeta]) => ({\n            address: address as Address<typeof address>,\n            ...addressMeta,\n        }));\n    return orderedAccounts as unknown as OrderedAccounts;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/header.ts",
    "content": "import { isSignerRole, isWritableRole } from '@solana/instructions';\n\nimport { OrderedAccounts } from '../v0/accounts';\n\ntype MessageHeader = Readonly<{\n    /**\n     * The number of accounts in the static accounts list that are neither writable nor\n     * signers.\n     *\n     * Adding this number to `numSignerAccounts` yields the index of the first read-only non-signer\n     * account in the static accounts list.\n     */\n    numReadonlyNonSignerAccounts: number;\n    /**\n     * The number of read-only accounts in the static accounts list that must sign this\n     * transaction.\n     *\n     * Subtracting this number from `numSignerAccounts` yields the index of the first read-only\n     * signer account in the static accounts list.\n     */\n    numReadonlySignerAccounts: number;\n    /**\n     * The number of accounts in the static accounts list that must sign this transaction.\n     *\n     * Subtracting `numReadonlySignerAccounts` from this number yields the number of\n     * writable signer accounts in the static accounts list. Writable signer accounts always\n     * begin at index zero in the static accounts list.\n     *\n     * This number itself is the index of the first non-signer account in the static\n     * accounts list.\n     */\n    numSignerAccounts: number;\n}>;\n\nexport function getCompiledMessageHeader(orderedAccounts: OrderedAccounts): MessageHeader {\n    let numReadonlyNonSignerAccounts = 0;\n    let numReadonlySignerAccounts = 0;\n    let numSignerAccounts = 0;\n    for (const account of orderedAccounts) {\n        if ('lookupTableAddress' in account) {\n            break;\n        }\n        const accountIsWritable = isWritableRole(account.role);\n        if (isSignerRole(account.role)) {\n            numSignerAccounts++;\n            if (!accountIsWritable) {\n                numReadonlySignerAccounts++;\n            }\n        } else if (!accountIsWritable) {\n            numReadonlyNonSignerAccounts++;\n        }\n    }\n    return {\n        numReadonlyNonSignerAccounts,\n        numReadonlySignerAccounts,\n        numSignerAccounts,\n    };\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/instructions.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { Instruction } from '@solana/instructions';\n\nimport { OrderedAccounts } from './accounts';\n\nexport type CompiledInstruction = Readonly<{\n    /**\n     * An ordered list of indices that indicate which accounts in the transaction message's\n     * accounts list are loaded by this instruction.\n     */\n    accountIndices?: number[];\n    /** The input to the invoked program */\n    data?: ReadonlyUint8Array;\n    /**\n     * The index of the address in the transaction message's accounts list associated with the\n     * program to invoke.\n     */\n    programAddressIndex: number;\n}>;\n\nexport function getAccountIndex(orderedAccounts: OrderedAccounts) {\n    const out: Record<Address, number> = {};\n    for (const [index, account] of orderedAccounts.entries()) {\n        out[account.address] = index;\n    }\n    return out;\n}\n\nexport function getCompiledInstructions(\n    instructions: readonly Instruction[],\n    orderedAccounts: OrderedAccounts,\n): CompiledInstruction[] {\n    const accountIndex = getAccountIndex(orderedAccounts);\n    return instructions.map(({ accounts, data, programAddress }) => {\n        return {\n            programAddressIndex: accountIndex[programAddress],\n            ...(accounts ? { accountIndices: accounts.map(({ address }) => accountIndex[address]) } : null),\n            ...(data ? { data } : null),\n        };\n    });\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/lifetime-token.ts",
    "content": "import { TransactionMessageWithBlockhashLifetime, TransactionMessageWithDurableNonceLifetime } from '../../index';\n\nexport function getCompiledLifetimeToken(\n    lifetimeConstraint: (\n        | TransactionMessageWithBlockhashLifetime\n        | TransactionMessageWithDurableNonceLifetime\n    )['lifetimeConstraint'],\n): string {\n    if ('nonce' in lifetimeConstraint) {\n        return lifetimeConstraint.nonce;\n    }\n    return lifetimeConstraint.blockhash;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/legacy/message.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SolanaError,\n} from '@solana/errors';\nimport { isSignerRole } from '@solana/instructions';\n\nimport { TransactionMessageWithFeePayer, TransactionMessageWithLifetime } from '../..';\nimport { TransactionMessage } from '../../transaction-message';\nimport { ForwardTransactionMessageLifetime } from '../message-types';\nimport { getAddressMapFromInstructions, getOrderedAccountsFromAddressMap } from './accounts';\nimport { getCompiledMessageHeader } from './header';\nimport { getCompiledInstructions } from './instructions';\nimport { getCompiledLifetimeToken } from './lifetime-token';\n\nexport type LegacyCompiledTransactionMessage = Readonly<{\n    /** Information about the role of the accounts loaded. */\n    header: ReturnType<typeof getCompiledMessageHeader>;\n    /** A list of instructions that this transaction will execute */\n    instructions: ReturnType<typeof getCompiledInstructions>;\n    /** A list of addresses indicating which accounts to load */\n    staticAccounts: Address[];\n    version: 'legacy';\n}>;\n\n/**\n * Converts the type of transaction message data structure that you create in your application to\n * the type of transaction message data structure that can be encoded for execution on the network.\n *\n * This is a lossy process; you can not fully reconstruct a source message from a compiled message\n * without extra information. In particular, supporting details about the lifetime constraint will\n * be lost to compilation.\n *\n * @see {@link decompileTransactionMessage}\n */\nexport function compileTransactionMessage<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer & { version: 'legacy' },\n>(\n    transactionMessage: TTransactionMessage,\n): ForwardTransactionMessageLifetime<LegacyCompiledTransactionMessage, TTransactionMessage> {\n    type ReturnType = ForwardTransactionMessageLifetime<LegacyCompiledTransactionMessage, TTransactionMessage>;\n\n    const addressMap = getAddressMapFromInstructions(\n        transactionMessage.feePayer.address,\n        transactionMessage.instructions,\n    );\n    const orderedAccounts = getOrderedAccountsFromAddressMap(addressMap);\n    const numAccounts = orderedAccounts.length;\n    if (numAccounts > 64) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES, {\n            actualCount: numAccounts,\n            maxAllowed: 64,\n        });\n    }\n    const numSigners = orderedAccounts.filter(account => isSignerRole(account.role)).length;\n    if (numSigners > 12) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES, {\n            actualCount: numSigners,\n            maxAllowed: 12,\n        });\n    }\n    const numInstructions = transactionMessage.instructions.length;\n    if (numInstructions > 64) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS, {\n            actualCount: numInstructions,\n            maxAllowed: 64,\n        });\n    }\n    for (let i = 0; i < transactionMessage.instructions.length; i++) {\n        const numAccountsInInstruction = transactionMessage.instructions[i].accounts?.length ?? 0;\n        if (numAccountsInInstruction > 255) {\n            throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                actualCount: numAccountsInInstruction,\n                instructionIndex: i,\n                maxAllowed: 255,\n            });\n        }\n    }\n    const lifetimeConstraint = (transactionMessage as Partial<TransactionMessageWithLifetime>).lifetimeConstraint;\n\n    return {\n        ...(lifetimeConstraint ? { lifetimeToken: getCompiledLifetimeToken(lifetimeConstraint) } : null),\n        header: getCompiledMessageHeader(orderedAccounts),\n        instructions: getCompiledInstructions(transactionMessage.instructions, orderedAccounts),\n        staticAccounts: orderedAccounts.map(account => account.address),\n        version: transactionMessage.version,\n    } as ReturnType;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/message-types.ts",
    "content": "/**\n * This file is for types that are exported for use in multiple places within the compile directory,\n * but that are not intended to be exported from the package as part of the public API.\n */\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '..';\nimport { TransactionMessageWithLifetime } from '../lifetime';\nimport { TransactionMessage } from '../transaction-message';\n\nexport type ForwardTransactionMessageLifetime<\n    TCompiledTransactionMessage extends CompiledTransactionMessage,\n    TTransactionMessage extends TransactionMessage,\n> = TTransactionMessage extends TransactionMessageWithLifetime\n    ? CompiledTransactionMessageWithLifetime & TCompiledTransactionMessage\n    : TCompiledTransactionMessage;\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/message.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport { TransactionMessageWithFeePayer } from '../fee-payer';\nimport { TransactionMessageWithLifetime } from '../lifetime';\nimport { TransactionMessage } from '../transaction-message';\nimport { getCompiledLifetimeToken } from './legacy/lifetime-token';\nimport {\n    compileTransactionMessage as compileLegacyTransactionMessage,\n    LegacyCompiledTransactionMessage,\n} from './legacy/message';\nimport { compileTransactionMessage as compileV0TransactionMessage, V0CompiledTransactionMessage } from './v0/message';\nimport { compileTransactionMessage as compileV1TransactionMessage, V1CompiledTransactionMessage } from './v1/message';\n\n/**\n * A transaction message in a form suitable for encoding for execution on the network.\n *\n * You can not fully reconstruct a source message from a compiled message without extra information.\n * In particular, supporting details about the lifetime constraint and the concrete addresses of\n * accounts sourced from account lookup tables are lost to compilation.\n */\nexport type CompiledTransactionMessage =\n    | LegacyCompiledTransactionMessage\n    | V0CompiledTransactionMessage\n    | V1CompiledTransactionMessage;\n\nexport type { LegacyCompiledTransactionMessage, V0CompiledTransactionMessage, V1CompiledTransactionMessage };\n\nexport type CompiledTransactionMessageWithLifetime = Readonly<{\n    /**\n     * 32 bytes of data observed by the transaction proposed that makes a transaction eligible to\n     * land on the network.\n     *\n     * In the case of a transaction message with a nonce lifetime constraint, this will be the value\n     * of the nonce itself. In all other cases this will be a recent blockhash.\n     */\n    lifetimeToken: ReturnType<typeof getCompiledLifetimeToken>;\n}>;\n\n/**\n * Converts the type of transaction message data structure that you create in your application to\n * the type of transaction message data structure that can be encoded for execution on the network.\n *\n * This is a lossy process; you can not fully reconstruct a source message from a compiled message\n * without extra information. In particular, supporting details about the lifetime constraint and\n * the concrete addresses of accounts sourced from account lookup tables will be lost to\n * compilation.\n *\n * @see {@link decompileTransactionMessage}\n */\nexport function compileTransactionMessage<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer & { version: 'legacy' },\n>(\n    transactionMessage: TTransactionMessage,\n): ForwardTransactionMessageLifetime<LegacyCompiledTransactionMessage, TTransactionMessage>;\nexport function compileTransactionMessage<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer & { version: 0 },\n>(\n    transactionMessage: TTransactionMessage,\n): ForwardTransactionMessageLifetime<V0CompiledTransactionMessage, TTransactionMessage>;\nexport function compileTransactionMessage<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer & { version: 1 },\n>(\n    transactionMessage: TTransactionMessage,\n): ForwardTransactionMessageLifetime<V1CompiledTransactionMessage, TTransactionMessage>;\nexport function compileTransactionMessage<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer,\n>(\n    transactionMessage: TTransactionMessage,\n): ForwardTransactionMessageLifetime<CompiledTransactionMessage, TTransactionMessage>;\nexport function compileTransactionMessage<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer,\n>(\n    transactionMessage: TTransactionMessage,\n): ForwardTransactionMessageLifetime<CompiledTransactionMessage, TTransactionMessage> {\n    type ReturnType = ForwardTransactionMessageLifetime<CompiledTransactionMessage, TTransactionMessage>;\n\n    const version = transactionMessage.version;\n    if (version === 'legacy') {\n        return compileLegacyTransactionMessage(transactionMessage) as ReturnType;\n    } else if (version === 0) {\n        return compileV0TransactionMessage(transactionMessage) as ReturnType;\n    } else if (version === 1) {\n        return compileV1TransactionMessage(transactionMessage) as ReturnType;\n    } else {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n            version,\n        });\n    }\n}\n\ntype ForwardTransactionMessageLifetime<\n    TCompiledTransactionMessage extends CompiledTransactionMessage,\n    TTransactionMessage extends TransactionMessage,\n> = TTransactionMessage extends TransactionMessageWithLifetime\n    ? CompiledTransactionMessageWithLifetime & TCompiledTransactionMessage\n    : TCompiledTransactionMessage;\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/__tests__/accounts-test.ts",
    "content": "import { Address, getAddressComparator } from '@solana/addresses';\nimport { AccountLookupMeta, AccountRole, Instruction } from '@solana/instructions';\n\nimport {\n    ADDRESS_MAP_TYPE_PROPERTY as TYPE,\n    AddressMapEntryType,\n    getAddressMapFromInstructions,\n    getOrderedAccountsFromAddressMap,\n} from '../accounts';\n\ntype AccountRoleEnumName = keyof typeof AccountRole;\ntype TestCase = {\n    aRole: AccountRoleEnumName;\n    bRole: AccountRoleEnumName;\n    expectedEntry:\n        | typeof FEE_PAYER_ENTRY\n        | typeof LUT_ENTRY_READONLY\n        | typeof LUT_ENTRY_WRITABLE\n        | typeof STATIC_ENTRY_READONLY\n        | typeof STATIC_ENTRY_READONLY_SIGNER\n        | typeof STATIC_ENTRY_WRITABLE\n        | typeof STATIC_ENTRY_WRITABLE_SIGNER;\n    instructionOrder: [string, (i: Instruction[]) => Instruction[]];\n    lutRole: AccountRoleEnumName;\n    role: AccountRoleEnumName;\n    staticRole: AccountRoleEnumName;\n};\n\nconst MOCK_ADDRESSES: ReadonlyArray<Address> = [\n    'BRwZRKsvKkG45g59269qZ5e8UaECFim5Qfxex44UKwDG',\n    'AZE3mXbzNp8SfZYBfL4L67ejQ8zmatAKKezUdCarKnUL',\n    'Awft9caFzun5FcVTaXJAkAYDBgbEDF5QALeaqeY3M3Va',\n    'ARc8zz6T14LZQTpjryhBGDuNZb3YmNT9PtEuBSuVM5xo',\n    '6Tu9wk1r9yGwzd3xdrVzDttmkTN98iiffq7L25JKTvwh',\n    '4R6dgeBbwPjnTSN78KGxhB78oFsxaobiwBsCBLAyauqA',\n] as Address[];\n\nlet _nextMockAddress = 0;\nfunction getMockAddress() {\n    return `${_nextMockAddress++}` as Address;\n}\nfunction forwardOrder(i: Instruction[]) {\n    return i;\n}\nfunction reverseOrder(i: Instruction[]) {\n    return i.reverse();\n}\n\nconst FEE_PAYER_ENTRY = { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER } as const;\nconst LUT_ENTRY_READONLY = { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, role: AccountRole.READONLY } as const;\nconst LUT_ENTRY_WRITABLE = { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, role: AccountRole.WRITABLE } as const;\nconst STATIC_ENTRY_READONLY = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.READONLY } as const;\nconst STATIC_ENTRY_READONLY_SIGNER = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.READONLY_SIGNER } as const;\nconst STATIC_ENTRY_WRITABLE = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.WRITABLE } as const;\nconst STATIC_ENTRY_WRITABLE_SIGNER = { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.WRITABLE_SIGNER } as const;\n\ndescribe('getAddressMapFromInstructions', () => {\n    it('creates a fee-payer entry for the fee payer', () => {\n        const feePayerAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(feePayerAddress, []);\n        expect(addressMap).toHaveProperty(feePayerAddress, FEE_PAYER_ENTRY);\n    });\n    it('creates a READONLY static entry for a program address', () => {\n        const programAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [{ programAddress }]);\n        expect(addressMap).toHaveProperty(programAddress, STATIC_ENTRY_READONLY);\n    });\n    it('creates a READONLY static entry for a static account address', () => {\n        const staticAccountAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n            {\n                accounts: [{ address: staticAccountAddress, role: AccountRole.READONLY }],\n                programAddress: getMockAddress(),\n            },\n        ]);\n        expect(addressMap).toHaveProperty(staticAccountAddress, STATIC_ENTRY_READONLY);\n    });\n    it.each`\n        role                 | expectedEntry\n        ${'READONLY'}        | ${STATIC_ENTRY_READONLY}\n        ${'WRITABLE'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n    `('creates a $role static entry for a $role static account address', ({ expectedEntry, role }: TestCase) => {\n        const staticAccountAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n            {\n                accounts: [{ address: staticAccountAddress, role: AccountRole[role] }],\n                programAddress: getMockAddress(),\n            },\n        ]);\n        expect(addressMap).toHaveProperty(staticAccountAddress, expectedEntry);\n    });\n    it.each`\n        role          | expectedEntry\n        ${'READONLY'} | ${LUT_ENTRY_READONLY}\n        ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE}\n    `('creates a $role lut entry for a $role lookup table address', ({ expectedEntry, role }: TestCase) => {\n        const lutAccountAddress = getMockAddress();\n        const lutMeta = {\n            addressIndex: 0,\n            lookupTableAddress: getMockAddress(),\n            role: AccountRole[role],\n        };\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n            {\n                accounts: [{ address: lutAccountAddress, ...lutMeta }],\n                programAddress: getMockAddress(),\n            },\n        ]);\n        expect(addressMap).toHaveProperty(lutAccountAddress, { ...expectedEntry, ...lutMeta });\n    });\n    it('fatals given a matching fee payer and program address', () => {\n        const commonAddress = getMockAddress();\n        expect(() => {\n            getAddressMapFromInstructions(/* fee payer */ commonAddress, [{ programAddress: commonAddress }]);\n        }).toThrow();\n    });\n    it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])(\n        'creates a fee-payer entry given a matching fee payer and %s static account address',\n        role => {\n            const commonAddress = getMockAddress();\n            const addressMap = getAddressMapFromInstructions(/* fee payer */ commonAddress, [\n                {\n                    accounts: [{ address: commonAddress, role: AccountRole[role] }],\n                    programAddress: getMockAddress(),\n                },\n            ]);\n            expect(addressMap).toHaveProperty(commonAddress, FEE_PAYER_ENTRY);\n        },\n    );\n    it.each(['READONLY', 'WRITABLE'] as AccountRoleEnumName[])(\n        'creates a fee-payer entry given a matching fee payer and %s lookup table address',\n        role => {\n            const commonAddress = getMockAddress();\n            const addressMap = getAddressMapFromInstructions(/* fee payer */ commonAddress, [\n                {\n                    accounts: [\n                        {\n                            address: commonAddress,\n                            addressIndex: 0,\n                            lookupTableAddress: getMockAddress(),\n                            role: AccountRole[role],\n                        } as AccountLookupMeta<typeof commonAddress>,\n                    ],\n                    programAddress: getMockAddress(),\n                },\n            ]);\n            expect(addressMap).toHaveProperty(commonAddress, FEE_PAYER_ENTRY);\n        },\n    );\n    it('creates one READONLY static entry given two matching program addresses', () => {\n        const commonAddress = getMockAddress();\n        const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n            { programAddress: commonAddress },\n            { programAddress: commonAddress },\n        ]);\n        expect(addressMap).toHaveProperty(commonAddress, STATIC_ENTRY_READONLY);\n    });\n    it.each`\n        role                 | instructionOrder\n        ${'READONLY'}        | ${['static address comes first', forwardOrder]}\n        ${'READONLY_SIGNER'} | ${['static address comes first', forwardOrder]}\n        ${'READONLY'}        | ${['program address comes first', reverseOrder]}\n        ${'READONLY_SIGNER'} | ${['program address comes first', reverseOrder]}\n    `(\n        'creates a $role static entry given a matching program and $role static account address when the $instructionOrder.0',\n        ({ instructionOrder: [_, orderInstructions], role }: TestCase) => {\n            const commonAddress = getMockAddress();\n            const addressMap = getAddressMapFromInstructions(\n                /* fee payer */ getMockAddress(),\n                orderInstructions([\n                    {\n                        accounts: [{ address: commonAddress, role: AccountRole[role] }],\n                        programAddress: getMockAddress(),\n                    },\n                    {\n                        programAddress: commonAddress,\n                    },\n                ]),\n            );\n            expect(addressMap).toHaveProperty(commonAddress, {\n                [TYPE]: AddressMapEntryType.STATIC,\n                role: AccountRole[role],\n            });\n        },\n    );\n    it.each`\n        role                 | instructionOrder\n        ${'WRITABLE'}        | ${['static address comes first', forwardOrder]}\n        ${'WRITABLE_SIGNER'} | ${['static address comes first', forwardOrder]}\n        ${'WRITABLE'}        | ${['program address comes first', reverseOrder]}\n        ${'WRITABLE_SIGNER'} | ${['program address comes first', reverseOrder]}\n    `(\n        'fatals given a matching program and $role static account address when the $instructionOrder.0',\n        ({ instructionOrder: [_, orderInstructions], role }: TestCase) => {\n            const commonAddress = getMockAddress();\n            expect(() =>\n                getAddressMapFromInstructions(\n                    /* fee payer */ getMockAddress(),\n                    orderInstructions([\n                        {\n                            accounts: [{ address: commonAddress, role: AccountRole[role] }],\n                            programAddress: getMockAddress(),\n                        },\n                        { programAddress: commonAddress },\n                    ]),\n                ),\n            ).toThrow();\n        },\n    );\n    it.each`\n        instructionOrder\n        ${['lut address comes first', forwardOrder]}\n        ${['program address comes first', reverseOrder]}\n    `(\n        'creates a READONLY static entry given a matching program and READONLY lookup table address when the $instructionOrder.0',\n        ({ instructionOrder: [_, orderInstructions] }: TestCase) => {\n            const commonAddress = getMockAddress();\n            const addressMap = getAddressMapFromInstructions(\n                /* fee payer */ getMockAddress(),\n                orderInstructions([\n                    {\n                        accounts: [\n                            {\n                                address: commonAddress,\n                                addressIndex: 0,\n                                lookupTableAddress: getMockAddress(),\n                                role: AccountRole.READONLY,\n                            },\n                        ],\n                        programAddress: getMockAddress(),\n                    },\n                    { programAddress: commonAddress },\n                ]),\n            );\n            expect(addressMap).toHaveProperty(commonAddress, STATIC_ENTRY_READONLY);\n        },\n    );\n    it.each`\n        instructionOrder\n        ${['lut address comes first', forwardOrder]}\n        ${['program address comes first', reverseOrder]}\n    `(\n        'fatals given a matching program and WRITABLE lookup table address when the $instructionOrder.0',\n        ({ instructionOrder: [_, orderInstructions] }: TestCase) => {\n            const commonAddress = getMockAddress();\n            expect(() =>\n                getAddressMapFromInstructions(\n                    /* fee payer */ getMockAddress(),\n                    orderInstructions([\n                        {\n                            accounts: [\n                                {\n                                    address: commonAddress,\n                                    addressIndex: 0,\n                                    lookupTableAddress: getMockAddress(),\n                                    role: AccountRole.WRITABLE,\n                                },\n                            ],\n                            programAddress: getMockAddress(),\n                        },\n                        { programAddress: commonAddress },\n                    ]),\n                ),\n            ).toThrow();\n        },\n    );\n    it.each`\n        aRole                | bRole                | endRole              | expectedEntry\n        ${'READONLY'}        | ${'READONLY'}        | ${'READONLY'}        | ${STATIC_ENTRY_READONLY}\n        ${'READONLY'}        | ${'WRITABLE'}        | ${'WRITABLE'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'READONLY'}        | ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER}\n        ${'READONLY'}        | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE'}        | ${'READONLY'}        | ${'WRITABLE'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'WRITABLE'}        | ${'WRITABLE'}        | ${'WRITABLE'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'WRITABLE'}        | ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE'}        | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'READONLY_SIGNER'} | ${'READONLY'}        | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER}\n        ${'READONLY_SIGNER'} | ${'WRITABLE'}        | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER}\n        ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${'READONLY'}        | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE'}        | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${'READONLY_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER}\n    `(\n        'creates one $endRole static entry given matching $aRole and $bRole static accounts',\n        ({ aRole, bRole, expectedEntry }: TestCase) => {\n            const commonAddress = getMockAddress();\n            const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n                {\n                    accounts: [{ address: commonAddress, role: AccountRole[aRole] }],\n                    programAddress: getMockAddress(),\n                },\n                {\n                    accounts: [{ address: commonAddress, role: AccountRole[bRole] }],\n                    programAddress: getMockAddress(),\n                },\n            ]);\n            expect(addressMap).toHaveProperty(commonAddress, expectedEntry);\n        },\n    );\n    it.each`\n        staticRole    | lutRole       | endRole       | expectedEntry         | instructionOrder\n        ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} | ${['lut address comes first', forwardOrder]}\n        ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['lut address comes first', forwardOrder]}\n        ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['lut address comes first', forwardOrder]}\n        ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['lut address comes first', forwardOrder]}\n        ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} | ${['static address comes first', reverseOrder]}\n        ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['static address comes first', reverseOrder]}\n        ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['static address comes first', reverseOrder]}\n        ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['static address comes first', reverseOrder]}\n    `(\n        'creates a $endRole lut entry given a matching $staticRole static and $lutRole lookup table address when the $instructionOrder.0 because the static address is not a signer',\n        ({ expectedEntry, instructionOrder: [_, orderInstructions], lutRole, staticRole }: TestCase) => {\n            const commonAddress = getMockAddress();\n            const lutMeta = {\n                addressIndex: 0,\n                lookupTableAddress: getMockAddress(),\n            };\n            const addressMap = getAddressMapFromInstructions(\n                /* fee payer */ getMockAddress(),\n                orderInstructions([\n                    {\n                        accounts: [{ address: commonAddress, ...lutMeta, role: AccountRole[lutRole] }],\n                        programAddress: getMockAddress(),\n                    },\n                    {\n                        accounts: [{ address: commonAddress, role: AccountRole[staticRole] }],\n                        programAddress: getMockAddress(),\n                    },\n                ]),\n            );\n            expect(addressMap).toHaveProperty(commonAddress, { ...expectedEntry, ...lutMeta });\n        },\n    );\n    it.each`\n        staticRole           | lutRole       | endRole              | expectedEntry                   | instructionOrder\n        ${'READONLY_SIGNER'} | ${'READONLY'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${['lut address comes first', forwardOrder]}\n        ${'READONLY_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['lut address comes first', forwardOrder]}\n        ${'WRITABLE_SIGNER'} | ${'READONLY'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['lut address comes first', forwardOrder]}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['lut address comes first', forwardOrder]}\n        ${'READONLY_SIGNER'} | ${'READONLY'} | ${'READONLY_SIGNER'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${['static address comes first', reverseOrder]}\n        ${'READONLY_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['static address comes first', reverseOrder]}\n        ${'WRITABLE_SIGNER'} | ${'READONLY'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['static address comes first', reverseOrder]}\n        ${'WRITABLE_SIGNER'} | ${'WRITABLE'} | ${'WRITABLE_SIGNER'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${['static address comes first', reverseOrder]}\n    `(\n        'creates a $endRole static entry given a matching $staticRole static and $lutRole lookup table address when the $instructionOrder.0 because the static address is a signer',\n        ({ expectedEntry, instructionOrder: [_, orderInstructions], lutRole, staticRole }) => {\n            const commonAddress = getMockAddress();\n            const lutMeta = {\n                addressIndex: 0,\n                lookupTableAddress: getMockAddress(),\n            };\n            const addressMap = getAddressMapFromInstructions(\n                /* fee payer */ getMockAddress(),\n                orderInstructions([\n                    {\n                        accounts: [{ address: commonAddress, ...lutMeta, role: AccountRole[lutRole] }],\n                        programAddress: getMockAddress(),\n                    },\n                    {\n                        accounts: [{ address: commonAddress, role: AccountRole[staticRole] }],\n                        programAddress: getMockAddress(),\n                    },\n                ]),\n            );\n            expect(addressMap).toHaveProperty(commonAddress, expectedEntry);\n        },\n    );\n    it.each`\n        aRole         | bRole         | endRole       | expectedEntry\n        ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY}\n        ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE}\n        ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE}\n        ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE}\n    `(\n        'creates one $endRole lut entry given matching $aRole and $bRole lut addresses',\n        ({ aRole, bRole, expectedEntry }: TestCase) => {\n            const commonAddress = getMockAddress();\n            const lutMeta = {\n                addressIndex: 0,\n                lookupTableAddress: getMockAddress(),\n            };\n            const addressMap = getAddressMapFromInstructions(/* fee payer */ getMockAddress(), [\n                {\n                    accounts: [{ address: commonAddress, ...lutMeta, role: AccountRole[aRole] }],\n                    programAddress: getMockAddress(),\n                },\n                {\n                    accounts: [{ address: commonAddress, ...lutMeta, role: AccountRole[bRole] }],\n                    programAddress: getMockAddress(),\n                },\n            ]);\n            expect(addressMap).toHaveProperty(commonAddress, { ...expectedEntry, ...lutMeta });\n        },\n    );\n    it.each`\n        aRole         | bRole         | endRole       | expectedEntry         | instructionOrder\n        ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} | ${['comes first', forwardOrder]}\n        ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes first', forwardOrder]}\n        ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes first', forwardOrder]}\n        ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes first', forwardOrder]}\n        ${'READONLY'} | ${'READONLY'} | ${'READONLY'} | ${LUT_ENTRY_READONLY} | ${['comes last', reverseOrder]}\n        ${'READONLY'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes last', reverseOrder]}\n        ${'WRITABLE'} | ${'READONLY'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes last', reverseOrder]}\n        ${'WRITABLE'} | ${'WRITABLE'} | ${'WRITABLE'} | ${LUT_ENTRY_WRITABLE} | ${['comes last', reverseOrder]}\n    `(\n        'creates one $endRole lut entry given matching $aRole and $bRole lut addresses from different lookup tables, preferring the table with the lower address when it $instructionOrder.0',\n        ({ aRole, bRole, expectedEntry, instructionOrder: [_, orderInstructions] }) => {\n            const commonAddress = getMockAddress();\n            const sortedAddresses = MOCK_ADDRESSES.slice(0, 2).sort(getAddressComparator());\n            const lowerLutMeta = {\n                addressIndex: 9,\n                lookupTableAddress: sortedAddresses[0], // Address which sorts lower.\n            };\n            const higherLutMeta = {\n                addressIndex: 6,\n                lookupTableAddress: sortedAddresses[1], // Address which sorts higher.\n            };\n            const addressMap = getAddressMapFromInstructions(\n                /* fee payer */ getMockAddress(),\n                orderInstructions([\n                    {\n                        accounts: [{ address: commonAddress, role: AccountRole[aRole], ...lowerLutMeta }],\n                        programAddress: getMockAddress(),\n                    },\n                    {\n                        accounts: [{ address: commonAddress, role: AccountRole[bRole], ...higherLutMeta }],\n                        programAddress: getMockAddress(),\n                    },\n                ]),\n            );\n            expect(addressMap).toHaveProperty(commonAddress, { ...expectedEntry, ...lowerLutMeta });\n        },\n    );\n});\n\ndescribe('getOrderedAccountsFromAddressMap', () => {\n    let sortedAddresses: Address[];\n    beforeEach(() => {\n        sortedAddresses = [...MOCK_ADDRESSES].sort(getAddressComparator());\n    });\n    it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])(\n        'puts the fee payer before %s static addresses',\n        role => {\n            const orderedAccounts = getOrderedAccountsFromAddressMap({\n                [sortedAddresses[0]]: { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole[role] },\n                [sortedAddresses[1]]: { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER },\n            });\n            expect(orderedAccounts).toHaveProperty('0', {\n                [TYPE]: AddressMapEntryType.FEE_PAYER,\n                address: sortedAddresses[1],\n                role: AccountRole.WRITABLE_SIGNER,\n            });\n        },\n    );\n    it.each(['READONLY', 'WRITABLE'] as AccountRoleEnumName[])(\n        'puts the fee payer before %s lookup table addresses',\n        role => {\n            const orderedAccounts = getOrderedAccountsFromAddressMap({\n                [sortedAddresses[0]]: {\n                    [TYPE]: AddressMapEntryType.LOOKUP_TABLE,\n                    addressIndex: 0,\n                    lookupTableAddress: getMockAddress(),\n                    role: AccountRole[role] as Exclude<\n                        AccountRole,\n                        AccountRole.READONLY_SIGNER | AccountRole.WRITABLE_SIGNER\n                    >,\n                },\n                [sortedAddresses[1]]: { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER },\n            });\n            expect(orderedAccounts).toHaveProperty('0', {\n                [TYPE]: AddressMapEntryType.FEE_PAYER,\n                address: sortedAddresses[1],\n                role: AccountRole.WRITABLE_SIGNER,\n            });\n        },\n    );\n    it.each(['READONLY', 'WRITABLE', 'READONLY_SIGNER', 'WRITABLE_SIGNER'] as AccountRoleEnumName[])(\n        'orders %s static account addresses in lexical order',\n        role => {\n            const roleMeta = { role: AccountRole[role] };\n            const orderedAccounts = getOrderedAccountsFromAddressMap({\n                [sortedAddresses[1]]: { [TYPE]: AddressMapEntryType.STATIC, ...roleMeta },\n                [sortedAddresses[0]]: { [TYPE]: AddressMapEntryType.STATIC, ...roleMeta },\n            });\n            expect(orderedAccounts).toEqual([\n                { [TYPE]: AddressMapEntryType.STATIC, address: sortedAddresses[0], ...roleMeta },\n                { [TYPE]: AddressMapEntryType.STATIC, address: sortedAddresses[1], ...roleMeta },\n            ]);\n        },\n    );\n    it.each(['READONLY', 'WRITABLE'] as AccountRoleEnumName[])(\n        'orders %s lookup table addresses by the lexical order of the address of their lookup table first, then by the addresses themselves',\n        role => {\n            const firstLutMeta = {\n                addressIndex: 0,\n                lookupTableAddress: sortedAddresses[0],\n            };\n            const secondLutMeta = {\n                addressIndex: 0,\n                lookupTableAddress: sortedAddresses[1],\n            };\n            const roleMeta = {\n                role: AccountRole[role] as Exclude<\n                    AccountRole,\n                    AccountRole.READONLY_SIGNER | AccountRole.WRITABLE_SIGNER\n                >,\n            };\n            const orderedAccounts = getOrderedAccountsFromAddressMap({\n                [sortedAddresses[3]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, ...secondLutMeta, ...roleMeta },\n                [sortedAddresses[2]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, ...secondLutMeta, ...roleMeta },\n                [sortedAddresses[5]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, ...firstLutMeta, ...roleMeta },\n                [sortedAddresses[4]]: { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, ...firstLutMeta, ...roleMeta },\n            });\n            expect(orderedAccounts).toEqual([\n                { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, address: sortedAddresses[4], ...firstLutMeta, ...roleMeta },\n                { [TYPE]: AddressMapEntryType.LOOKUP_TABLE, address: sortedAddresses[5], ...firstLutMeta, ...roleMeta },\n                {\n                    [TYPE]: AddressMapEntryType.LOOKUP_TABLE,\n                    address: sortedAddresses[2],\n                    ...secondLutMeta,\n                    ...roleMeta,\n                },\n                {\n                    [TYPE]: AddressMapEntryType.LOOKUP_TABLE,\n                    address: sortedAddresses[3],\n                    ...secondLutMeta,\n                    ...roleMeta,\n                },\n            ]);\n        },\n    );\n    it.each`\n        beforeKind                  | beforeEntry                     | afterKind                   | afterEntry\n        ${'WRITABLE lookup table'}  | ${LUT_ENTRY_WRITABLE}           | ${'READONLY lookup table'}  | ${LUT_ENTRY_READONLY}\n        ${'READONLY static'}        | ${STATIC_ENTRY_READONLY}        | ${'READONLY lookup table'}  | ${LUT_ENTRY_READONLY}\n        ${'READONLY static'}        | ${STATIC_ENTRY_READONLY}        | ${'WRITABLE lookup table'}  | ${LUT_ENTRY_WRITABLE}\n        ${'WRITABLE static'}        | ${STATIC_ENTRY_WRITABLE}        | ${'READONLY lookup table'}  | ${LUT_ENTRY_READONLY}\n        ${'WRITABLE static'}        | ${STATIC_ENTRY_WRITABLE}        | ${'WRITABLE lookup table'}  | ${LUT_ENTRY_WRITABLE}\n        ${'WRITABLE static'}        | ${STATIC_ENTRY_WRITABLE}        | ${'READONLY static'}        | ${STATIC_ENTRY_READONLY}\n        ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'READONLY lookup table'}  | ${LUT_ENTRY_READONLY}\n        ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'WRITABLE lookup table'}  | ${LUT_ENTRY_WRITABLE}\n        ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'READONLY static'}        | ${STATIC_ENTRY_READONLY}\n        ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER} | ${'WRITABLE static'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'READONLY lookup table'}  | ${LUT_ENTRY_READONLY}\n        ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'WRITABLE lookup table'}  | ${LUT_ENTRY_WRITABLE}\n        ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'READONLY static'}        | ${STATIC_ENTRY_READONLY}\n        ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'WRITABLE static'}        | ${STATIC_ENTRY_WRITABLE}\n        ${'WRITABLE_SIGNER static'} | ${STATIC_ENTRY_WRITABLE_SIGNER} | ${'READONLY_SIGNER static'} | ${STATIC_ENTRY_READONLY_SIGNER}\n    `('orders $beforeKind addresses before $afterKind addresses', ({ afterEntry, beforeEntry }) => {\n        const orderedAccounts = getOrderedAccountsFromAddressMap({\n            [sortedAddresses[0]]: afterEntry,\n            [sortedAddresses[1]]: beforeEntry,\n        });\n        expect(orderedAccounts).toEqual([\n            { address: sortedAddresses[1], ...beforeEntry },\n            { address: sortedAddresses[0], ...afterEntry },\n        ]);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/__tests__/address-table-lookups-test.ts",
    "content": "import { Address, getAddressComparator } from '@solana/addresses';\nimport { AccountRole } from '@solana/instructions';\n\nimport { OrderedAccounts } from '../accounts';\nimport { getCompiledAddressTableLookups } from '../address-table-lookups';\n\nconst MOCK_ADDRESSES: ReadonlyArray<Address> = [\n    'BRwZRKsvKkG45g59269qZ5e8UaECFim5Qfxex44UKwDG',\n    'AZE3mXbzNp8SfZYBfL4L67ejQ8zmatAKKezUdCarKnUL',\n    'Awft9caFzun5FcVTaXJAkAYDBgbEDF5QALeaqeY3M3Va',\n    'ARc8zz6T14LZQTpjryhBGDuNZb3YmNT9PtEuBSuVM5xo',\n    '6Tu9wk1r9yGwzd3xdrVzDttmkTN98iiffq7L25JKTvwh',\n    '4R6dgeBbwPjnTSN78KGxhB78oFsxaobiwBsCBLAyauqA',\n] as Address[];\n\nlet _nextMockAddress = 0;\nfunction getMockAddress() {\n    return `${_nextMockAddress++}` as Address;\n}\n\ndescribe('getCompiledAddressTableLookups', () => {\n    it('returns address table lookups in lexical order', () => {\n        const sortedAddresses = [...MOCK_ADDRESSES].sort(getAddressComparator());\n        const orderedAccounts = [\n            {\n                address: getMockAddress(),\n                addressIndex: 10,\n                lookupTableAddress: sortedAddresses[1],\n                role: AccountRole.WRITABLE,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 20,\n                lookupTableAddress: sortedAddresses[2],\n                role: AccountRole.WRITABLE,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 30,\n                lookupTableAddress: sortedAddresses[0],\n                role: AccountRole.READONLY,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 40,\n                lookupTableAddress: sortedAddresses[3],\n                role: AccountRole.READONLY,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 50,\n                lookupTableAddress: sortedAddresses[2],\n                role: AccountRole.READONLY,\n            },\n        ] as OrderedAccounts;\n        const compiledAddressTableLookups = getCompiledAddressTableLookups(orderedAccounts);\n        expect(compiledAddressTableLookups).toHaveProperty('0.lookupTableAddress', sortedAddresses[0]);\n        expect(compiledAddressTableLookups).toHaveProperty('1.lookupTableAddress', sortedAddresses[1]);\n        expect(compiledAddressTableLookups).toHaveProperty('2.lookupTableAddress', sortedAddresses[2]);\n        expect(compiledAddressTableLookups).toHaveProperty('3.lookupTableAddress', sortedAddresses[3]);\n    });\n    it('populates readable/writable address indices in order', () => {\n        const lookupTableAddress = getMockAddress();\n        const orderedAccounts = [\n            {\n                address: getMockAddress(),\n                addressIndex: 20,\n                lookupTableAddress,\n                role: AccountRole.WRITABLE,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 10,\n                lookupTableAddress,\n                role: AccountRole.WRITABLE,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 30,\n                lookupTableAddress,\n                role: AccountRole.READONLY,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 50,\n                lookupTableAddress,\n                role: AccountRole.READONLY,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 40,\n                lookupTableAddress,\n                role: AccountRole.READONLY,\n            },\n        ] as OrderedAccounts;\n        const compiledAddressTableLookups = getCompiledAddressTableLookups(orderedAccounts);\n        expect(compiledAddressTableLookups).toHaveProperty('0.readonlyIndexes', [30, 50, 40]);\n        expect(compiledAddressTableLookups).toHaveProperty('0.writableIndexes', [20, 10]);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/__tests__/instructions-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountRole, Instruction } from '@solana/instructions';\n\nimport { OrderedAccounts } from '../accounts';\nimport { getCompiledInstructions } from '../instructions';\n\nlet _nextMockAddress = 0;\nfunction getMockAddress() {\n    return `${_nextMockAddress++}` as Address;\n}\n\ndescribe('getCompiledInstructions', () => {\n    it('compiles no account indices when are no accounts', () => {\n        const compiledInstructions = getCompiledInstructions(\n            [{ programAddress: getMockAddress() }],\n            [] as unknown as OrderedAccounts,\n        );\n        expect(compiledInstructions[0]).not.toHaveProperty('accountIndices');\n    });\n    it('compiles no data when there is no data', () => {\n        const compiledInstructions = getCompiledInstructions(\n            [{ programAddress: getMockAddress() }],\n            [] as unknown as OrderedAccounts,\n        );\n        expect(compiledInstructions[0]).not.toHaveProperty('data');\n    });\n    it('compiles account addresses into indices of the account addresses', () => {\n        const addressAtIndex2 = getMockAddress();\n        const addressAtIndex3 = getMockAddress();\n        const addressAtIndex4 = getMockAddress();\n        const lookupTableAddress = getMockAddress();\n        const programAddressAtIndex1 = getMockAddress();\n        const instructions = [\n            {\n                accounts: [\n                    { address: addressAtIndex3, role: AccountRole.READONLY },\n                    { address: addressAtIndex2, role: AccountRole.WRITABLE },\n                ],\n                programAddress: programAddressAtIndex1,\n            },\n            {\n                accounts: [\n                    {\n                        address: addressAtIndex4,\n                        addressIndex: 0,\n                        lookupTableAddress,\n                        role: AccountRole.WRITABLE,\n                    },\n                    { address: addressAtIndex2, role: AccountRole.READONLY },\n                ],\n                programAddress: programAddressAtIndex1,\n            },\n        ] as Instruction[];\n        const compiledInstructions = getCompiledInstructions(instructions, [\n            { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n            { address: programAddressAtIndex1, role: AccountRole.READONLY },\n            { address: addressAtIndex2, role: AccountRole.WRITABLE },\n            { address: addressAtIndex3, role: AccountRole.READONLY },\n            { address: addressAtIndex4, addressIndex: 0, lookupTableAddress, role: AccountRole.WRITABLE },\n        ] as OrderedAccounts);\n        expect(compiledInstructions).toHaveProperty('0.accountIndices', [3, 2]);\n        expect(compiledInstructions).toHaveProperty('1.accountIndices', [4, 2]);\n    });\n    it('copies over the instruction data verbatim', () => {\n        const expectedData = new Uint8Array([1, 2, 3]);\n        const compiledInstructions = getCompiledInstructions(\n            [{ data: expectedData, programAddress: getMockAddress() }],\n            [] as unknown as OrderedAccounts,\n        );\n        expect(compiledInstructions[0]).toHaveProperty('data', expectedData);\n    });\n    it('compiles the program address into a program address index', () => {\n        const programAddress = getMockAddress();\n        const compiledInstructions = getCompiledInstructions([{ programAddress }], [\n            { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n            { address: programAddress, role: AccountRole.READONLY },\n        ] as OrderedAccounts);\n        expect(compiledInstructions[0]).toHaveProperty('programAddressIndex', 1);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/__tests__/message-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\n\nimport { TransactionMessageWithBlockhashLifetime } from '../../../blockhash';\nimport { TransactionMessageWithFeePayer } from '../../../fee-payer';\nimport { TransactionMessageWithLifetime } from '../../../lifetime';\nimport { TransactionMessage } from '../../../transaction-message';\nimport { getCompiledMessageHeader } from '../../legacy/header';\nimport { getCompiledLifetimeToken } from '../../legacy/lifetime-token';\nimport { getCompiledAddressTableLookups } from '../../v0/address-table-lookups';\nimport { getCompiledInstructions } from '../../v0/instructions';\nimport { getCompiledStaticAccounts } from '../../v0/static-accounts';\nimport { getAddressMapFromInstructions, getOrderedAccountsFromAddressMap, OrderedAccounts } from '../accounts';\nimport { compileTransactionMessage } from '../message';\n\njest.mock('../accounts');\njest.mock('../address-table-lookups');\njest.mock('../../legacy/header');\njest.mock('../instructions');\njest.mock('../../legacy/lifetime-token');\njest.mock('../static-accounts');\n\nconst MOCK_LIFETIME_CONSTRAINT =\n    'SOME_CONSTRAINT' as unknown as TransactionMessageWithBlockhashLifetime['lifetimeConstraint'];\n\ndescribe('compileTransactionMessage', () => {\n    let baseTx: TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime;\n    beforeEach(() => {\n        baseTx = {\n            feePayer: { address: 'abc' as Address<'abc'> },\n            instructions: [],\n            lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n            version: 0,\n        };\n        jest.mocked(getAddressMapFromInstructions).mockReturnValue({});\n        jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue([] as unknown as OrderedAccounts);\n    });\n    describe('address table lookups', () => {\n        const expectedAddressTableLookups = [] as ReturnType<typeof getCompiledAddressTableLookups>;\n        beforeEach(() => {\n            jest.mocked(getCompiledAddressTableLookups).mockReturnValue(expectedAddressTableLookups);\n        });\n        it('sets `addressTableLookups` to the return value of `getCompiledAddressTableLookups`', () => {\n            const message = compileTransactionMessage(baseTx as typeof baseTx & { version: 0 });\n            expect(getCompiledAddressTableLookups).toHaveBeenCalled();\n            expect(message.addressTableLookups).toBe(expectedAddressTableLookups);\n        });\n    });\n    describe('message header', () => {\n        const expectedCompiledMessageHeader = {\n            numReadonlyNonSignerAccounts: 0,\n            numReadonlySignerAccounts: 0,\n            numSignerAccounts: 1,\n        } as const;\n        beforeEach(() => {\n            jest.mocked(getCompiledMessageHeader).mockReturnValue(expectedCompiledMessageHeader);\n        });\n        it('sets `header` to the return value of `getCompiledMessageHeader`', () => {\n            const message = compileTransactionMessage(baseTx);\n            expect(getCompiledMessageHeader).toHaveBeenCalled();\n            expect(message.header).toBe(expectedCompiledMessageHeader);\n        });\n    });\n    describe('instructions', () => {\n        const expectedInstructions = [] as ReturnType<typeof getCompiledInstructions>;\n        beforeEach(() => {\n            jest.mocked(getCompiledInstructions).mockReturnValue(expectedInstructions);\n        });\n        it('sets `instructions` to the return value of `getCompiledInstructions`', () => {\n            const message = compileTransactionMessage(baseTx);\n            console.log({ message });\n            expect(getCompiledInstructions).toHaveBeenCalledWith(\n                baseTx.instructions,\n                expect.any(Array) /* orderedAccounts */,\n            );\n            expect(message.instructions).toBe(expectedInstructions);\n        });\n    });\n    describe('lifetime constraints', () => {\n        beforeEach(() => {\n            jest.mocked(getCompiledLifetimeToken).mockReturnValue('abc');\n        });\n        it('sets `lifetimeToken` to the return value of `getCompiledLifetimeToken`', () => {\n            const message = compileTransactionMessage(baseTx);\n            expect(getCompiledLifetimeToken).toHaveBeenCalledWith('SOME_CONSTRAINT');\n            expect(message.lifetimeToken).toBe('abc');\n        });\n    });\n    describe('static accounts', () => {\n        const expectedStaticAccounts = [] as ReturnType<typeof getCompiledStaticAccounts>;\n        beforeEach(() => {\n            jest.mocked(getCompiledStaticAccounts).mockReturnValue(expectedStaticAccounts);\n        });\n        it('sets `staticAccounts` to the return value of `getCompiledStaticAccounts`', () => {\n            const message = compileTransactionMessage(baseTx);\n            expect(getCompiledStaticAccounts).toHaveBeenCalled();\n            expect(message.staticAccounts).toBe(expectedStaticAccounts);\n        });\n    });\n    describe('versions', () => {\n        it('compiles the version', () => {\n            const message = compileTransactionMessage(baseTx);\n            expect(message).toHaveProperty('version', 0);\n        });\n    });\n    describe('constraints', () => {\n        describe('too many account addresses', () => {\n            it('throws when there are more than 64 unique accounts', () => {\n                const accounts = Array.from({ length: 65 }, (_, i) => ({\n                    address: `account${i}` as Address,\n                    role: AccountRole.READONLY,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES, {\n                        actualCount: 65,\n                        maxAllowed: 64,\n                    }),\n                );\n            });\n            it('does not throw with exactly 64 unique accounts', () => {\n                const accounts = Array.from({ length: 64 }, (_, i) => ({\n                    address: `account${i}` as Address,\n                    role: AccountRole.READONLY,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                expect(() => compileTransactionMessage(baseTx)).not.toThrow();\n            });\n        });\n        describe('too many signer addresses', () => {\n            it('throws when there are more than 12 unique signers', () => {\n                const accounts = Array.from({ length: 13 }, (_, i) => ({\n                    address: `signer${i}` as Address,\n                    role: AccountRole.WRITABLE_SIGNER,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES, {\n                        actualCount: 13,\n                        maxAllowed: 12,\n                    }),\n                );\n            });\n            it('does not throw with exactly 12 signers', () => {\n                const accounts = Array.from({ length: 12 }, (_, i) => ({\n                    address: `signer${i}` as Address,\n                    role: AccountRole.WRITABLE_SIGNER,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                expect(() => compileTransactionMessage(baseTx)).not.toThrow();\n            });\n        });\n        describe('too many instructions', () => {\n            it('throws when there are more than 64 instructions', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: Array.from({ length: 65 }, () => ({ programAddress: 'prog' as Address })),\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS, {\n                        actualCount: 65,\n                        maxAllowed: 64,\n                    }),\n                );\n            });\n            it('does not throw with exactly 64 instructions', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: Array.from({ length: 64 }, () => ({ programAddress: 'prog' as Address })),\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).not.toThrow();\n            });\n        });\n        describe('too many accounts in an instruction', () => {\n            it('throws when an instruction has more than 255 account references', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: [\n                        {\n                            accounts: Array.from({ length: 256 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                        actualCount: 256,\n                        instructionIndex: 0,\n                        maxAllowed: 255,\n                    }),\n                );\n            });\n            it('does not throw with exactly 255 accounts in an instruction', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: [\n                        {\n                            accounts: Array.from({ length: 255 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).not.toThrow();\n            });\n            it('reports the correct instruction index when a later instruction violates the constraint', () => {\n                baseTx = {\n                    ...baseTx,\n                    instructions: [\n                        { programAddress: 'prog' as Address },\n                        {\n                            accounts: Array.from({ length: 256 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                    lifetimeConstraint: MOCK_LIFETIME_CONSTRAINT,\n                };\n                expect(() => compileTransactionMessage(baseTx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                        actualCount: 256,\n                        instructionIndex: 1,\n                        maxAllowed: 255,\n                    }),\n                );\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/__tests__/static-accounts-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountRole } from '@solana/instructions';\n\nimport { OrderedAccounts } from '../accounts';\nimport { getCompiledStaticAccounts } from '../static-accounts';\n\nlet _nextMockAddress = 0;\nfunction getMockAddress() {\n    return `${_nextMockAddress++}` as Address;\n}\n\ndescribe('getCompiledStaticAccounts', () => {\n    it('returns an array of addresses of each account in order', () => {\n        const orderedAccounts = [\n            { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n            { address: getMockAddress(), role: AccountRole.READONLY_SIGNER },\n            { address: getMockAddress(), role: AccountRole.WRITABLE },\n            { address: getMockAddress(), role: AccountRole.READONLY },\n        ] as OrderedAccounts;\n        const compiledStaticAccounts = getCompiledStaticAccounts(orderedAccounts);\n        expect(compiledStaticAccounts).toEqual([\n            orderedAccounts[0].address,\n            orderedAccounts[1].address,\n            orderedAccounts[2].address,\n            orderedAccounts[3].address,\n        ]);\n    });\n    it('omits lookup table accounts', () => {\n        const orderedAccounts = [\n            { address: getMockAddress(), role: AccountRole.WRITABLE_SIGNER },\n            { address: getMockAddress(), role: AccountRole.READONLY_SIGNER },\n            { address: getMockAddress(), role: AccountRole.WRITABLE },\n            { address: getMockAddress(), role: AccountRole.READONLY },\n            {\n                address: getMockAddress(),\n                addressIndex: 0,\n                lookupTableAddress: getMockAddress(),\n                role: AccountRole.WRITABLE,\n            },\n            {\n                address: getMockAddress(),\n                addressIndex: 1,\n                lookupTableAddress: getMockAddress(),\n                role: AccountRole.READONLY,\n            },\n        ] as OrderedAccounts;\n        const compiledStaticAccounts = getCompiledStaticAccounts(orderedAccounts);\n        expect(compiledStaticAccounts).not.toContain(orderedAccounts[4].address);\n        expect(compiledStaticAccounts).not.toContain(orderedAccounts[5].address);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/accounts.ts",
    "content": "import { Address, getAddressComparator } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES,\n    SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,\n    SolanaError,\n} from '@solana/errors';\nimport {\n    AccountLookupMeta,\n    AccountMeta,\n    AccountRole,\n    Instruction,\n    isSignerRole,\n    isWritableRole,\n    mergeRoles,\n    ReadonlyAccount,\n    ReadonlyAccountLookup,\n    ReadonlySignerAccount,\n    WritableAccount,\n    WritableAccountLookup,\n    WritableSignerAccount,\n} from '@solana/instructions';\nimport { Brand } from '@solana/nominal-types';\n\nexport const enum AddressMapEntryType {\n    FEE_PAYER,\n    LOOKUP_TABLE,\n    STATIC,\n}\n\ntype AddressMap = {\n    [address: string]: FeePayerAccountEntry | LookupTableAccountEntry | StaticAccountEntry;\n};\ntype FeePayerAccountEntry = Omit<WritableSignerAccount, 'address'> & {\n    [TYPE]: AddressMapEntryType.FEE_PAYER;\n};\ntype LookupTableAccountEntry = Omit<ReadonlyAccountLookup | WritableAccountLookup, 'address'> & {\n    [TYPE]: AddressMapEntryType.LOOKUP_TABLE;\n};\nexport type OrderedAccounts = Brand<(AccountLookupMeta | AccountMeta)[], 'OrderedAccounts'>;\ntype StaticAccountEntry = Omit<\n    ReadonlyAccount | ReadonlySignerAccount | WritableAccount | WritableSignerAccount,\n    'address'\n> & { [TYPE]: AddressMapEntryType.STATIC };\n\nfunction upsert(\n    addressMap: AddressMap,\n    address: Address,\n    update: (\n        entry: FeePayerAccountEntry | LookupTableAccountEntry | Record<never, never> | StaticAccountEntry,\n    ) => AddressMap[Address],\n) {\n    addressMap[address] = update(addressMap[address] ?? { role: AccountRole.READONLY });\n}\n\nconst TYPE = Symbol('AddressMapTypeProperty');\nexport const ADDRESS_MAP_TYPE_PROPERTY: typeof TYPE = TYPE;\n\nexport function getAddressMapFromInstructions(feePayer: Address, instructions: readonly Instruction[]): AddressMap {\n    const addressMap: AddressMap = {\n        [feePayer]: { [TYPE]: AddressMapEntryType.FEE_PAYER, role: AccountRole.WRITABLE_SIGNER },\n    };\n    const addressesOfInvokedPrograms = new Set<Address>();\n    for (const instruction of instructions) {\n        upsert(addressMap, instruction.programAddress, entry => {\n            addressesOfInvokedPrograms.add(instruction.programAddress);\n            if (TYPE in entry) {\n                if (isWritableRole(entry.role)) {\n                    switch (entry[TYPE]) {\n                        case AddressMapEntryType.FEE_PAYER:\n                            throw new SolanaError(SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_CANNOT_PAY_FEES, {\n                                programAddress: instruction.programAddress,\n                            });\n                        default:\n                            throw new SolanaError(SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE, {\n                                programAddress: instruction.programAddress,\n                            });\n                    }\n                }\n                if (entry[TYPE] === AddressMapEntryType.STATIC) {\n                    return entry;\n                }\n            }\n            return { [TYPE]: AddressMapEntryType.STATIC, role: AccountRole.READONLY };\n        });\n        let addressComparator: ReturnType<typeof getAddressComparator>;\n        if (!instruction.accounts) {\n            continue;\n        }\n        for (const account of instruction.accounts) {\n            upsert(addressMap, account.address, entry => {\n                const {\n                    // eslint-disable-next-line @typescript-eslint/no-unused-vars\n                    address: _,\n                    ...accountMeta\n                } = account;\n                if (TYPE in entry) {\n                    switch (entry[TYPE]) {\n                        case AddressMapEntryType.FEE_PAYER:\n                            // The fee payer already has the highest rank -- it is by definition\n                            // writable-signer. Return it, no matter how `account` is configured\n                            return entry;\n                        case AddressMapEntryType.LOOKUP_TABLE: {\n                            const nextRole = mergeRoles(entry.role, accountMeta.role);\n                            if ('lookupTableAddress' in accountMeta) {\n                                const shouldReplaceEntry =\n                                    // Consider using the new LOOKUP_TABLE if its address is different...\n                                    entry.lookupTableAddress !== accountMeta.lookupTableAddress &&\n                                    // ...and sorts before the existing one.\n                                    (addressComparator ||= getAddressComparator())(\n                                        accountMeta.lookupTableAddress,\n                                        entry.lookupTableAddress,\n                                    ) < 0;\n                                if (shouldReplaceEntry) {\n                                    return {\n                                        [TYPE]: AddressMapEntryType.LOOKUP_TABLE,\n                                        ...accountMeta,\n                                        role: nextRole,\n                                    } as LookupTableAccountEntry;\n                                }\n                            } else if (isSignerRole(accountMeta.role)) {\n                                // Upgrade this LOOKUP_TABLE entry to a static entry if it must sign.\n                                return {\n                                    [TYPE]: AddressMapEntryType.STATIC,\n                                    role: nextRole,\n                                } as StaticAccountEntry;\n                            }\n                            if (entry.role !== nextRole) {\n                                return {\n                                    ...entry,\n                                    role: nextRole,\n                                } as LookupTableAccountEntry;\n                            } else {\n                                return entry;\n                            }\n                        }\n                        case AddressMapEntryType.STATIC: {\n                            const nextRole = mergeRoles(entry.role, accountMeta.role);\n                            if (\n                                // Check to see if this address represents a program that is invoked\n                                // in this transaction.\n                                addressesOfInvokedPrograms.has(account.address)\n                            ) {\n                                if (isWritableRole(accountMeta.role)) {\n                                    throw new SolanaError(\n                                        SOLANA_ERROR__TRANSACTION__INVOKED_PROGRAMS_MUST_NOT_BE_WRITABLE,\n                                        {\n                                            programAddress: account.address,\n                                        },\n                                    );\n                                }\n                                if (entry.role !== nextRole) {\n                                    return {\n                                        ...entry,\n                                        role: nextRole,\n                                    } as StaticAccountEntry;\n                                } else {\n                                    return entry;\n                                }\n                            } else if (\n                                'lookupTableAddress' in accountMeta &&\n                                // Static accounts can be 'upgraded' to lookup table accounts as\n                                // long as they are not require to sign the transaction.\n                                !isSignerRole(entry.role)\n                            ) {\n                                return {\n                                    ...accountMeta,\n                                    [TYPE]: AddressMapEntryType.LOOKUP_TABLE,\n                                    role: nextRole,\n                                } as LookupTableAccountEntry;\n                            } else {\n                                if (entry.role !== nextRole) {\n                                    // The account's role ranks higher than the current entry's.\n                                    return {\n                                        ...entry,\n                                        role: nextRole,\n                                    } as StaticAccountEntry;\n                                } else {\n                                    return entry;\n                                }\n                            }\n                        }\n                    }\n                }\n                if ('lookupTableAddress' in accountMeta) {\n                    return {\n                        ...accountMeta,\n                        [TYPE]: AddressMapEntryType.LOOKUP_TABLE,\n                    };\n                } else {\n                    return {\n                        ...accountMeta,\n                        [TYPE]: AddressMapEntryType.STATIC,\n                    };\n                }\n            });\n        }\n    }\n    return addressMap;\n}\n\nexport function getOrderedAccountsFromAddressMap(addressMap: AddressMap): OrderedAccounts {\n    let addressComparator: ReturnType<typeof getAddressComparator>;\n    const orderedAccounts: (AccountLookupMeta | AccountMeta)[] = Object.entries(addressMap)\n        .sort(([leftAddress, leftEntry], [rightAddress, rightEntry]) => {\n            // STEP 1: Rapid precedence check. Fee payer, then static addresses, then lookups.\n            if (leftEntry[TYPE] !== rightEntry[TYPE]) {\n                if (leftEntry[TYPE] === AddressMapEntryType.FEE_PAYER) {\n                    return -1;\n                } else if (rightEntry[TYPE] === AddressMapEntryType.FEE_PAYER) {\n                    return 1;\n                } else if (leftEntry[TYPE] === AddressMapEntryType.STATIC) {\n                    return -1;\n                } else if (rightEntry[TYPE] === AddressMapEntryType.STATIC) {\n                    return 1;\n                }\n            }\n            // STEP 2: Sort by signer-writability.\n            const leftIsSigner = isSignerRole(leftEntry.role);\n            if (leftIsSigner !== isSignerRole(rightEntry.role)) {\n                return leftIsSigner ? -1 : 1;\n            }\n            const leftIsWritable = isWritableRole(leftEntry.role);\n            if (leftIsWritable !== isWritableRole(rightEntry.role)) {\n                return leftIsWritable ? -1 : 1;\n            }\n            // STEP 3: Sort by address.\n            addressComparator ||= getAddressComparator();\n            if (\n                leftEntry[TYPE] === AddressMapEntryType.LOOKUP_TABLE &&\n                rightEntry[TYPE] === AddressMapEntryType.LOOKUP_TABLE &&\n                leftEntry.lookupTableAddress !== rightEntry.lookupTableAddress\n            ) {\n                return addressComparator(leftEntry.lookupTableAddress, rightEntry.lookupTableAddress);\n            } else {\n                return addressComparator(leftAddress, rightAddress);\n            }\n        })\n        .map(([address, addressMeta]) => ({\n            address: address as Address<typeof address>,\n            ...addressMeta,\n        }));\n    return orderedAccounts as unknown as OrderedAccounts;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/address-table-lookups.ts",
    "content": "import { Address, getAddressComparator } from '@solana/addresses';\nimport { AccountRole } from '@solana/instructions';\n\nimport { OrderedAccounts } from './accounts';\n\ntype AddressTableLookup = Readonly<{\n    /** The address of the address lookup table account. */\n    lookupTableAddress: Address;\n    /** Indexes of accounts in a lookup table to load as read-only. */\n    readonlyIndexes: readonly number[];\n    /** Indexes of accounts in a lookup table to load as writable. */\n    writableIndexes: readonly number[];\n}>;\n\nexport function getCompiledAddressTableLookups(orderedAccounts: OrderedAccounts): AddressTableLookup[] {\n    const index: Record<\n        Address,\n        Readonly<{\n            [K in keyof Omit<AddressTableLookup, 'lookupTableAddress'>]: number[];\n        }>\n    > = {};\n    for (const account of orderedAccounts) {\n        if (!('lookupTableAddress' in account)) {\n            continue;\n        }\n        const entry = (index[account.lookupTableAddress] ||= {\n            readonlyIndexes: [],\n            writableIndexes: [],\n        });\n        if (account.role === AccountRole.WRITABLE) {\n            entry.writableIndexes.push(account.addressIndex);\n        } else {\n            entry.readonlyIndexes.push(account.addressIndex);\n        }\n    }\n    return Object.keys(index)\n        .sort(getAddressComparator())\n        .map(lookupTableAddress => ({\n            lookupTableAddress: lookupTableAddress as Address,\n            ...index[lookupTableAddress as unknown as Address],\n        }));\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/instructions.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Instruction } from '@solana/instructions';\n\nimport { CompiledInstruction } from '../legacy/instructions';\nimport { OrderedAccounts } from './accounts';\n\nfunction getAccountIndex(orderedAccounts: OrderedAccounts) {\n    const out: Record<Address, number> = {};\n    for (const [index, account] of orderedAccounts.entries()) {\n        out[account.address] = index;\n    }\n    return out;\n}\n\nexport function getCompiledInstructions(\n    instructions: readonly Instruction[],\n    orderedAccounts: OrderedAccounts,\n): CompiledInstruction[] {\n    const accountIndex = getAccountIndex(orderedAccounts);\n    return instructions.map(({ accounts, data, programAddress }) => {\n        return {\n            programAddressIndex: accountIndex[programAddress],\n            ...(accounts ? { accountIndices: accounts.map(({ address }) => accountIndex[address]) } : null),\n            ...(data ? { data } : null),\n        };\n    });\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/message.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SolanaError,\n} from '@solana/errors';\nimport { isSignerRole } from '@solana/instructions';\n\nimport { TransactionMessageWithFeePayer } from '../../fee-payer';\nimport { TransactionMessageWithLifetime } from '../../lifetime';\nimport { TransactionMessage } from '../../transaction-message';\nimport { getCompiledMessageHeader } from '../legacy/header';\nimport { getCompiledLifetimeToken } from '../legacy/lifetime-token';\nimport { ForwardTransactionMessageLifetime } from '../message-types';\nimport { getAddressMapFromInstructions, getOrderedAccountsFromAddressMap } from './accounts';\nimport { getCompiledAddressTableLookups } from './address-table-lookups';\nimport { getCompiledInstructions } from './instructions';\nimport { getCompiledStaticAccounts } from './static-accounts';\n\nexport type V0CompiledTransactionMessage = Readonly<{\n    /** A list of address tables and the accounts that this transaction loads from them */\n    addressTableLookups?: ReturnType<typeof getCompiledAddressTableLookups>;\n    /** Information about the role of the accounts loaded. */\n    header: ReturnType<typeof getCompiledMessageHeader>;\n    /** A list of instructions that this transaction will execute */\n    instructions: ReturnType<typeof getCompiledInstructions>;\n    /** A list of addresses indicating which accounts to load */\n    staticAccounts: Address[];\n    version: 0;\n}>;\n\nexport function compileTransactionMessage<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer,\n>(\n    transactionMessage: TTransactionMessage,\n): ForwardTransactionMessageLifetime<V0CompiledTransactionMessage, TTransactionMessage> {\n    type ReturnType = ForwardTransactionMessageLifetime<V0CompiledTransactionMessage, TTransactionMessage>;\n\n    const addressMap = getAddressMapFromInstructions(\n        transactionMessage.feePayer.address,\n        transactionMessage.instructions,\n    );\n    const orderedAccounts = getOrderedAccountsFromAddressMap(addressMap);\n    const numAccounts = orderedAccounts.length;\n    if (numAccounts > 64) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES, {\n            actualCount: numAccounts,\n            maxAllowed: 64,\n        });\n    }\n    const numSigners = orderedAccounts.filter(account => isSignerRole(account.role)).length;\n    if (numSigners > 12) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES, {\n            actualCount: numSigners,\n            maxAllowed: 12,\n        });\n    }\n    const numInstructions = transactionMessage.instructions.length;\n    if (numInstructions > 64) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS, {\n            actualCount: numInstructions,\n            maxAllowed: 64,\n        });\n    }\n    for (let i = 0; i < transactionMessage.instructions.length; i++) {\n        const numAccountsInInstruction = transactionMessage.instructions[i].accounts?.length ?? 0;\n        if (numAccountsInInstruction > 255) {\n            throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                actualCount: numAccountsInInstruction,\n                instructionIndex: i,\n                maxAllowed: 255,\n            });\n        }\n    }\n    const lifetimeConstraint = (transactionMessage as Partial<TransactionMessageWithLifetime>).lifetimeConstraint;\n\n    return {\n        addressTableLookups: getCompiledAddressTableLookups(orderedAccounts),\n        ...(lifetimeConstraint ? { lifetimeToken: getCompiledLifetimeToken(lifetimeConstraint) } : null),\n        header: getCompiledMessageHeader(orderedAccounts),\n        instructions: getCompiledInstructions(transactionMessage.instructions, orderedAccounts),\n        staticAccounts: getCompiledStaticAccounts(orderedAccounts),\n        version: transactionMessage.version,\n    } as ReturnType;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v0/static-accounts.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { OrderedAccounts } from './accounts';\n\nexport function getCompiledStaticAccounts(orderedAccounts: OrderedAccounts): Address[] {\n    const firstLookupTableAccountIndex = orderedAccounts.findIndex(account => 'lookupTableAddress' in account);\n    const orderedStaticAccounts =\n        firstLookupTableAccountIndex === -1 ? orderedAccounts : orderedAccounts.slice(0, firstLookupTableAccountIndex);\n    return orderedStaticAccounts.map(({ address }) => address);\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v1/__tests__/config-test.ts",
    "content": "import { V1TransactionConfig } from '../../../v1-transaction-config';\nimport { getTransactionConfigMask, getTransactionConfigValues } from '../config';\n\ndescribe('getTransactionConfigMask', () => {\n    it('should return a mask with all values unset correctly', () => {\n        const config: V1TransactionConfig = {};\n        const mask = getTransactionConfigMask(config);\n\n        // All bits 0\n        expect(mask).toBe(0b00000000);\n    });\n\n    it('should return a mask with all values set correctly', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: 100,\n            heapSize: 100,\n            loadedAccountsDataSizeLimit: 100,\n            priorityFeeLamports: 100n,\n        };\n        const mask = getTransactionConfigMask(config);\n\n        // Lowest 5 bits set to 1, rest are 0\n        expect(mask).toBe(0b00011111);\n    });\n\n    it('should return a mask with just priority fee set correctly', () => {\n        const config: V1TransactionConfig = {\n            priorityFeeLamports: 100n,\n        };\n        const mask = getTransactionConfigMask(config);\n\n        // Lowest two bits set to 1, rest are 0\n        expect(mask).toBe(0b00000011);\n    });\n\n    it('should return a mask with just compute unit limit set correctly', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: 100,\n        };\n        const mask = getTransactionConfigMask(config);\n\n        // Third lowest bit set to 1, rest are 0\n        expect(mask).toBe(0b00000100);\n    });\n\n    it('should return a mask with just loaded accounts data size limit set correctly', () => {\n        const config: V1TransactionConfig = {\n            loadedAccountsDataSizeLimit: 100,\n        };\n        const mask = getTransactionConfigMask(config);\n\n        // Fourth lowest bit set to 1, rest are 0\n        expect(mask).toBe(0b00001000);\n    });\n\n    it('should return a mask with just heap size set correctly', () => {\n        const config: V1TransactionConfig = {\n            heapSize: 100,\n        };\n        const mask = getTransactionConfigMask(config);\n\n        // Fifth lowest bit set to 1, rest are 0\n        expect(mask).toBe(0b00010000);\n    });\n\n    it('should return a mask with multiple values set correctly', () => {\n        const config: V1TransactionConfig = {\n            loadedAccountsDataSizeLimit: 100,\n            priorityFeeLamports: 100n,\n        };\n        const mask = getTransactionConfigMask(config);\n\n        // First, second and fourth lowest bits set to 1, rest are 0\n        expect(mask).toBe(0b00001011);\n    });\n});\n\ndescribe('getTransactionConfigValues', () => {\n    it('should return an empty array when no values are set', () => {\n        const config: V1TransactionConfig = {};\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([]);\n    });\n\n    it('should return all values correctly', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: 20,\n            heapSize: 40,\n            loadedAccountsDataSizeLimit: 30,\n            priorityFeeLamports: 10n,\n        };\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([\n            { kind: 'u64', value: 10n },\n            { kind: 'u32', value: 20 },\n            { kind: 'u32', value: 30 },\n            { kind: 'u32', value: 40 },\n        ]);\n    });\n\n    it('should return just priority fee correctly', () => {\n        const config: V1TransactionConfig = {\n            priorityFeeLamports: 10n,\n        };\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([{ kind: 'u64', value: 10n }]);\n    });\n\n    it('should return a large priority fee value correctly', () => {\n        const config: V1TransactionConfig = {\n            priorityFeeLamports: 2n ** 64n - 1n,\n        };\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([{ kind: 'u64', value: 2n ** 64n - 1n }]);\n    });\n\n    it('should return just compute unit limit correctly', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: 20,\n        };\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([{ kind: 'u32', value: 20 }]);\n    });\n\n    it('should return just loaded accounts data size limit correctly', () => {\n        const config: V1TransactionConfig = {\n            loadedAccountsDataSizeLimit: 30,\n        };\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([{ kind: 'u32', value: 30 }]);\n    });\n\n    it('should return just heap size correctly', () => {\n        const config: V1TransactionConfig = {\n            heapSize: 40,\n        };\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([{ kind: 'u32', value: 40 }]);\n    });\n\n    it('should return multiple values correctly', () => {\n        const config: V1TransactionConfig = {\n            loadedAccountsDataSizeLimit: 30,\n            priorityFeeLamports: 10n,\n        };\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([\n            { kind: 'u64', value: 10n },\n            { kind: 'u32', value: 30 },\n        ]);\n    });\n\n    it('should return a large priority fee value correctly with another value', () => {\n        const config: V1TransactionConfig = {\n            computeUnitLimit: 20,\n            priorityFeeLamports: 2n ** 64n - 1n,\n        };\n        const values = getTransactionConfigValues(config);\n        expect(values).toEqual([\n            { kind: 'u64', value: 2n ** 64n - 1n },\n            { kind: 'u32', value: 20 },\n        ]);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v1/__tests__/instructions-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Instruction } from '@solana/instructions';\n\nimport { getInstructionHeader, getInstructionPayload } from '../instructions';\n\ndescribe('getInstructionHeader', () => {\n    const programAddress = '11111111111111111111111111111111' as Address;\n    const accountAddress1 = '22222222222222222222222222222222' as Address;\n    const accountAddress2 = '33333333333333333333333333333333' as Address;\n\n    it('returns the instruction header when all fields are defined', () => {\n        const instruction: Instruction = {\n            accounts: [\n                { address: accountAddress1, role: 0 },\n                { address: accountAddress2, role: 0 },\n            ],\n            data: Uint8Array.from({ length: 2 ** 16 - 1 }, (_, i) => i),\n            programAddress,\n        };\n        const accountIndex = {\n            [accountAddress1]: 2,\n            [accountAddress2]: 3,\n            [programAddress]: 1,\n        };\n        expect(getInstructionHeader(instruction, accountIndex)).toEqual({\n            numInstructionAccounts: 2,\n            numInstructionDataBytes: 2 ** 16 - 1,\n            programAccountIndex: 1,\n        });\n    });\n\n    it('returns 0 accounts when accounts is missing', () => {\n        const instruction: Instruction = {\n            data: new Uint8Array([1, 2, 3]),\n            programAddress,\n        };\n        const accountIndex = {\n            [programAddress]: 1,\n        };\n        expect(getInstructionHeader(instruction, accountIndex)).toEqual({\n            numInstructionAccounts: 0,\n            numInstructionDataBytes: 3,\n            programAccountIndex: 1,\n        });\n    });\n\n    it('returns 0 data bytes when data is missing', () => {\n        const instruction: Instruction = {\n            accounts: [\n                { address: accountAddress1, role: 0 },\n                { address: accountAddress2, role: 0 },\n            ],\n            programAddress,\n        };\n        const accountIndex = {\n            [accountAddress1]: 2,\n            [accountAddress2]: 3,\n            [programAddress]: 1,\n        };\n        expect(getInstructionHeader(instruction, accountIndex)).toEqual({\n            numInstructionAccounts: 2,\n            numInstructionDataBytes: 0,\n            programAccountIndex: 1,\n        });\n    });\n});\n\ndescribe('getInstructionPayload', () => {\n    const programAddress = '11111111111111111111111111111111' as Address;\n    const accountAddress1 = '22222222222222222222222222222222' as Address;\n    const accountAddress2 = '33333333333333333333333333333333' as Address;\n\n    it('returns the instruction payload when all fields are defined', () => {\n        const instruction: Instruction = {\n            accounts: [\n                { address: accountAddress1, role: 0 },\n                { address: accountAddress2, role: 0 },\n            ],\n            data: new Uint8Array([1, 2, 3]),\n            programAddress,\n        };\n        const accountIndex = {\n            [accountAddress1]: 2,\n            [accountAddress2]: 3,\n            [programAddress]: 1,\n        };\n        expect(getInstructionPayload(instruction, accountIndex)).toEqual({\n            instructionAccountIndices: [2, 3],\n            instructionData: new Uint8Array([1, 2, 3]),\n        });\n    });\n\n    it('returns an empty array when `accounts` is missing', () => {\n        const instruction: Instruction = {\n            data: new Uint8Array([1, 2, 3]),\n            programAddress,\n        };\n        const accountIndex = {\n            [programAddress]: 1,\n        };\n        expect(getInstructionPayload(instruction, accountIndex)).toEqual({\n            instructionAccountIndices: [],\n            instructionData: new Uint8Array([1, 2, 3]),\n        });\n    });\n\n    it('returns an empty Uint8Array when `data` is missing', () => {\n        const instruction: Instruction = {\n            accounts: [\n                { address: accountAddress1, role: 0 },\n                { address: accountAddress2, role: 0 },\n            ],\n            programAddress,\n        };\n        const accountIndex = {\n            [accountAddress1]: 2,\n            [accountAddress2]: 3,\n            [programAddress]: 1,\n        };\n        expect(getInstructionPayload(instruction, accountIndex)).toEqual({\n            instructionAccountIndices: [2, 3],\n            instructionData: new Uint8Array(),\n        });\n    });\n\n    it('returns an empty payload when both `accounts` and `data` are missing', () => {\n        const instruction: Instruction = {\n            programAddress,\n        };\n        const accountIndex = {\n            [programAddress]: 1,\n        };\n        expect(getInstructionPayload(instruction, accountIndex)).toEqual({\n            instructionAccountIndices: [],\n            instructionData: new Uint8Array(),\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v1/__tests__/message-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\n\nimport { TransactionMessageWithBlockhashLifetime } from '../../../blockhash';\nimport { TransactionMessageWithFeePayer } from '../../../fee-payer';\nimport { TransactionMessage } from '../../../transaction-message';\nimport { V1TransactionConfig } from '../../../v1-transaction-config';\nimport {\n    getAddressMapFromInstructions,\n    getOrderedAccountsFromAddressMap,\n    OrderedAccounts,\n} from '../../legacy/accounts';\nimport { getCompiledMessageHeader } from '../../legacy/header';\nimport { getAccountIndex } from '../../legacy/instructions';\nimport { getCompiledLifetimeToken } from '../../legacy/lifetime-token';\nimport { getTransactionConfigMask, getTransactionConfigValues } from '../config';\nimport { getInstructionHeader, getInstructionPayload } from '../instructions';\nimport { compileTransactionMessage } from '../message';\n\njest.mock('../../legacy/accounts');\njest.mock('../../legacy/header');\njest.mock('../../legacy/instructions');\njest.mock('../../legacy/lifetime-token');\njest.mock('../config');\njest.mock('../instructions');\n\ntype V1TransactionMessage = TransactionMessage & TransactionMessageWithFeePayer & { version: 1 };\ntype V1Instruction = V1TransactionMessage['instructions'][number];\n\nfunction makeMockTransactionMessage(overrides?: Partial<V1TransactionMessage>): V1TransactionMessage {\n    return {\n        feePayer: { address: 'abc' as Address },\n        instructions: [] as V1Instruction[],\n        version: 1,\n        ...overrides,\n    };\n}\n\ndescribe('compileTransactionMessage', () => {\n    beforeEach(() => {\n        jest.mocked(getAddressMapFromInstructions).mockReturnValue({});\n        jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue([] as unknown as OrderedAccounts);\n        jest.mocked(getAccountIndex).mockReturnValue({});\n    });\n\n    it('returns with version 1', () => {\n        const tx = makeMockTransactionMessage();\n        const message = compileTransactionMessage(tx);\n        expect(message).toHaveProperty('version', 1);\n    });\n\n    it('sets `header` to the return value of `getCompiledMessageHeader`', () => {\n        const expectedCompiledMessageHeader = {\n            numReadonlyNonSignerAccounts: 0,\n            numReadonlySignerAccounts: 0,\n            numSignerAccounts: 1,\n        } as const;\n        jest.mocked(getCompiledMessageHeader).mockReturnValue(expectedCompiledMessageHeader);\n\n        const tx = makeMockTransactionMessage();\n        const message = compileTransactionMessage(tx);\n        expect(getCompiledMessageHeader).toHaveBeenCalled();\n        expect(message.header).toBe(expectedCompiledMessageHeader);\n    });\n\n    describe('config', () => {\n        const expectedConfigMask = 0b00011111;\n        const expectedConfigValues = [\n            { kind: 'u64' as const, value: 10n },\n            { kind: 'u32' as const, value: 20 },\n        ];\n\n        beforeEach(() => {\n            jest.mocked(getTransactionConfigMask).mockReturnValue(expectedConfigMask);\n            jest.mocked(getTransactionConfigValues).mockReturnValue(expectedConfigValues);\n        });\n\n        it('sets `configMask` to the return value of `getTransactionConfigMask`', () => {\n            const config: V1TransactionConfig = {\n                computeUnitLimit: 10,\n            };\n            const tx = makeMockTransactionMessage({ config });\n            const message = compileTransactionMessage(tx);\n            expect(getTransactionConfigMask).toHaveBeenCalledWith(tx.config);\n            expect(message.configMask).toBe(expectedConfigMask);\n        });\n\n        it('sets `configValues` to the return value of `getTransactionConfigValues`', () => {\n            const config: V1TransactionConfig = {\n                computeUnitLimit: 10,\n            };\n            const tx = makeMockTransactionMessage({ config });\n            const message = compileTransactionMessage(tx);\n            expect(getTransactionConfigValues).toHaveBeenCalledWith(tx.config);\n            expect(message.configValues).toBe(expectedConfigValues);\n        });\n\n        it('passes an empty object to config functions when config is missing', () => {\n            const txWithoutConfig = makeMockTransactionMessage();\n            compileTransactionMessage(txWithoutConfig);\n            expect(getTransactionConfigMask).toHaveBeenCalledWith({});\n            expect(getTransactionConfigValues).toHaveBeenCalledWith({});\n        });\n    });\n\n    describe('lifetime constraints', () => {\n        beforeEach(() => {\n            jest.mocked(getCompiledLifetimeToken).mockReturnValue('abc');\n        });\n        it('sets `lifetimeToken` to the return value of `getCompiledLifetimeToken`', () => {\n            const blockhash = 'myblockhash' as unknown as TransactionMessageWithBlockhashLifetime['lifetimeConstraint'];\n            const tx = {\n                ...makeMockTransactionMessage(),\n                lifetimeConstraint: blockhash,\n            };\n            const message = compileTransactionMessage(tx);\n            expect(getCompiledLifetimeToken).toHaveBeenCalledWith(blockhash);\n            expect(message.lifetimeToken).toBe('abc');\n        });\n        it('does not set `lifetimeToken` when lifetime constraint is missing', () => {\n            const txWithoutLifetime = makeMockTransactionMessage();\n            const message = compileTransactionMessage(txWithoutLifetime);\n            expect(message).not.toHaveProperty('lifetimeToken');\n        });\n    });\n\n    describe('instructions', () => {\n        const expectedInstructionHeader = {\n            numInstructionAccounts: 2,\n            numInstructionDataBytes: 3,\n            programAccountIndex: 1,\n        };\n\n        const expectedInstructionPayload = {\n            instructionAccountIndices: [2, 3],\n            instructionData: new Uint8Array([1, 2, 3]),\n        };\n\n        beforeEach(() => {\n            jest.mocked(getInstructionHeader).mockReturnValue(expectedInstructionHeader);\n            jest.mocked(getInstructionPayload).mockReturnValue(expectedInstructionPayload);\n        });\n\n        it('sets `numInstructions` to the number of instructions', () => {\n            const tx = makeMockTransactionMessage({\n                instructions: [{} as V1Instruction, {} as V1Instruction],\n            });\n            const message = compileTransactionMessage(tx);\n            expect(message.numInstructions).toBe(2);\n        });\n\n        it('sets `instructionHeaders` to the return values of `getInstructionHeader`', () => {\n            const mockInstruction1 = {} as V1Instruction;\n            const mockInstruction2 = {} as V1Instruction;\n            const tx = makeMockTransactionMessage({\n                instructions: [mockInstruction1, mockInstruction2],\n            });\n            const message = compileTransactionMessage(tx);\n            expect(getInstructionHeader).toHaveBeenCalledTimes(2);\n            expect(getInstructionHeader).toHaveBeenNthCalledWith(\n                1,\n                mockInstruction1,\n                expect.anything() /* accountIndex */,\n            );\n            expect(getInstructionHeader).toHaveBeenNthCalledWith(\n                2,\n                mockInstruction2,\n                expect.anything() /* accountIndex */,\n            );\n            expect(message.instructionHeaders).toEqual([expectedInstructionHeader, expectedInstructionHeader]);\n        });\n\n        it('sets `instructionPayloads` to the return values of `getInstructionPayload`', () => {\n            const mockInstruction1 = {} as V1Instruction;\n            const mockInstruction2 = {} as V1Instruction;\n            const tx = makeMockTransactionMessage({\n                instructions: [mockInstruction1, mockInstruction2],\n            });\n            const message = compileTransactionMessage(tx);\n            expect(getInstructionPayload).toHaveBeenCalledTimes(2);\n            expect(getInstructionPayload).toHaveBeenNthCalledWith(\n                1,\n                mockInstruction1,\n                expect.anything() /* accountIndex */,\n            );\n            expect(getInstructionPayload).toHaveBeenNthCalledWith(\n                2,\n                mockInstruction2,\n                expect.anything() /* accountIndex */,\n            );\n            expect(message.instructionPayloads).toEqual([expectedInstructionPayload, expectedInstructionPayload]);\n        });\n    });\n\n    describe('static accounts', () => {\n        const expectedOrderedAccounts: ReturnType<typeof getOrderedAccountsFromAddressMap> = [\n            {\n                address: 'abc' as Address<'abc'>,\n                role: AccountRole.WRITABLE_SIGNER,\n            },\n            {\n                address: 'def' as Address<'def'>,\n                role: AccountRole.READONLY,\n            },\n        ] as ReturnType<typeof getOrderedAccountsFromAddressMap>;\n\n        beforeEach(() => {\n            jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(expectedOrderedAccounts);\n        });\n\n        it('sets `staticAccounts` to the addresses from the ordered accounts', () => {\n            const tx = makeMockTransactionMessage();\n            const message = compileTransactionMessage(tx);\n            expect(getOrderedAccountsFromAddressMap).toHaveBeenCalled();\n            expect(message.staticAccounts).toStrictEqual(['abc' as Address<'abc'>, 'def' as Address<'def'>]);\n        });\n        it('sets `numStaticAccounts` to the number of ordered accounts', () => {\n            const tx = makeMockTransactionMessage();\n            const message = compileTransactionMessage(tx);\n            expect(message.numStaticAccounts).toBe(2);\n        });\n    });\n    describe('constraints', () => {\n        describe('too many account addresses', () => {\n            it('throws when there are more than 64 unique accounts', () => {\n                const accounts = Array.from({ length: 65 }, (_, i) => ({\n                    address: `account${i}` as Address,\n                    role: AccountRole.READONLY,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                const tx = makeMockTransactionMessage();\n                expect(() => compileTransactionMessage(tx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES, {\n                        actualCount: 65,\n                        maxAllowed: 64,\n                    }),\n                );\n            });\n            it('does not throw with exactly 64 unique accounts', () => {\n                const accounts = Array.from({ length: 64 }, (_, i) => ({\n                    address: `account${i}` as Address,\n                    role: AccountRole.READONLY,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                const tx = makeMockTransactionMessage();\n                expect(() => compileTransactionMessage(tx)).not.toThrow();\n            });\n        });\n        describe('too many signer addresses', () => {\n            it('throws when there are more than 12 unique signers', () => {\n                const accounts = Array.from({ length: 13 }, (_, i) => ({\n                    address: `signer${i}` as Address,\n                    role: AccountRole.WRITABLE_SIGNER,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                const tx = makeMockTransactionMessage();\n                expect(() => compileTransactionMessage(tx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES, {\n                        actualCount: 13,\n                        maxAllowed: 12,\n                    }),\n                );\n            });\n            it('does not throw with exactly 12 signers', () => {\n                const accounts = Array.from({ length: 12 }, (_, i) => ({\n                    address: `signer${i}` as Address,\n                    role: AccountRole.WRITABLE_SIGNER,\n                })) as unknown as OrderedAccounts;\n                jest.mocked(getOrderedAccountsFromAddressMap).mockReturnValue(accounts);\n                const tx = makeMockTransactionMessage();\n                expect(() => compileTransactionMessage(tx)).not.toThrow();\n            });\n        });\n        describe('too many instructions', () => {\n            it('throws when there are more than 64 instructions', () => {\n                const tx = makeMockTransactionMessage({\n                    instructions: Array.from({ length: 65 }, () => ({ programAddress: 'prog' as Address })),\n                });\n                expect(() => compileTransactionMessage(tx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS, {\n                        actualCount: 65,\n                        maxAllowed: 64,\n                    }),\n                );\n            });\n            it('does not throw with exactly 64 instructions', () => {\n                const tx = makeMockTransactionMessage({\n                    instructions: Array.from({ length: 64 }, () => ({ programAddress: 'prog' as Address })),\n                });\n                expect(() => compileTransactionMessage(tx)).not.toThrow();\n            });\n        });\n        describe('too many accounts in an instruction', () => {\n            it('throws when an instruction has more than 255 account references', () => {\n                const tx = makeMockTransactionMessage({\n                    instructions: [\n                        {\n                            accounts: Array.from({ length: 256 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                });\n                expect(() => compileTransactionMessage(tx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                        actualCount: 256,\n                        instructionIndex: 0,\n                        maxAllowed: 255,\n                    }),\n                );\n            });\n            it('does not throw with exactly 255 accounts in an instruction', () => {\n                const tx = makeMockTransactionMessage({\n                    instructions: [\n                        {\n                            accounts: Array.from({ length: 255 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                });\n                expect(() => compileTransactionMessage(tx)).not.toThrow();\n            });\n            it('reports the correct instruction index when a later instruction violates the constraint', () => {\n                const tx = makeMockTransactionMessage({\n                    instructions: [\n                        { programAddress: 'prog' as Address },\n                        {\n                            accounts: Array.from({ length: 256 }, () => ({\n                                address: 'acct' as Address,\n                                role: AccountRole.READONLY,\n                            })),\n                            programAddress: 'prog' as Address,\n                        },\n                    ],\n                });\n                expect(() => compileTransactionMessage(tx)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                        actualCount: 256,\n                        instructionIndex: 1,\n                        maxAllowed: 255,\n                    }),\n                );\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v1/config.ts",
    "content": "import {\n    TRANSACTION_CONFIG_COMPUTE_UNIT_LIMIT_BIT_MASK,\n    TRANSACTION_CONFIG_HEAP_SIZE_BIT_MASK,\n    TRANSACTION_CONFIG_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_BIT_MASK,\n    TRANSACTION_CONFIG_PRIORITY_FEE_LAMPORTS_BIT_MASK,\n} from '../../v1-transaction-config';\nimport { V1TransactionConfig } from '../../v1-transaction-config';\n\nexport function getTransactionConfigMask(config: V1TransactionConfig): number {\n    let mask = 0;\n    // Set the lowest 2 bits for priority fee lamports\n    if (config.priorityFeeLamports !== undefined) mask |= TRANSACTION_CONFIG_PRIORITY_FEE_LAMPORTS_BIT_MASK;\n    // Set the 3rd lowest bit for compute unit limit\n    if (config.computeUnitLimit !== undefined) mask |= TRANSACTION_CONFIG_COMPUTE_UNIT_LIMIT_BIT_MASK;\n    // Set the 4th lowest bit for loaded accounts data size limit\n    if (config.loadedAccountsDataSizeLimit !== undefined)\n        mask |= TRANSACTION_CONFIG_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_BIT_MASK;\n    // Set the 5th lowest bit for heap size\n    if (config.heapSize !== undefined) mask |= TRANSACTION_CONFIG_HEAP_SIZE_BIT_MASK;\n    return mask;\n}\n\nexport type CompiledTransactionConfigValue =\n    | {\n          kind: 'u32';\n          value: number;\n      }\n    | {\n          kind: 'u64';\n          value: bigint;\n      };\n\nexport function getTransactionConfigValues(config: V1TransactionConfig): CompiledTransactionConfigValue[] {\n    const values: CompiledTransactionConfigValue[] = [];\n    if (config.priorityFeeLamports !== undefined) {\n        values.push({ kind: 'u64', value: config.priorityFeeLamports });\n    }\n    if (config.computeUnitLimit !== undefined) {\n        values.push({ kind: 'u32', value: config.computeUnitLimit });\n    }\n    if (config.loadedAccountsDataSizeLimit !== undefined) {\n        values.push({ kind: 'u32', value: config.loadedAccountsDataSizeLimit });\n    }\n    if (config.heapSize !== undefined) {\n        values.push({ kind: 'u32', value: config.heapSize });\n    }\n    return values;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v1/instructions.ts",
    "content": "import { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { Instruction } from '@solana/instructions';\n\nimport { getAccountIndex } from '../legacy/instructions';\n\nexport type InstructionHeader = {\n    numInstructionAccounts: number;\n    numInstructionDataBytes: number;\n    programAccountIndex: number;\n};\n\nexport type InstructionPayload = {\n    instructionAccountIndices: number[];\n    instructionData: ReadonlyUint8Array;\n};\n\nexport function getInstructionHeader(\n    instruction: Instruction,\n    accountIndex: ReturnType<typeof getAccountIndex>,\n): InstructionHeader {\n    return {\n        numInstructionAccounts: instruction.accounts?.length ?? 0,\n        numInstructionDataBytes: instruction.data?.byteLength ?? 0,\n        programAccountIndex: accountIndex[instruction.programAddress],\n    };\n}\n\nexport function getInstructionPayload(\n    instruction: Instruction,\n    accountIndex: ReturnType<typeof getAccountIndex>,\n): InstructionPayload {\n    return {\n        instructionAccountIndices: instruction.accounts?.map(({ address }) => accountIndex[address]) ?? [],\n        instructionData: instruction.data ?? new Uint8Array(),\n    };\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compile/v1/message.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS,\n    SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES,\n    SolanaError,\n} from '@solana/errors';\nimport { isSignerRole } from '@solana/instructions';\n\nimport { TransactionMessageWithFeePayer } from '../../fee-payer';\nimport { TransactionMessageWithLifetime } from '../../lifetime';\nimport { TransactionMessage } from '../../transaction-message';\nimport { getAddressMapFromInstructions, getOrderedAccountsFromAddressMap } from '../legacy/accounts';\nimport { getCompiledMessageHeader } from '../legacy/header';\nimport { getAccountIndex } from '../legacy/instructions';\nimport { getCompiledLifetimeToken } from '../legacy/lifetime-token';\nimport { ForwardTransactionMessageLifetime } from '../message-types';\nimport { getTransactionConfigMask, getTransactionConfigValues } from './config';\nimport { getInstructionHeader, getInstructionPayload } from './instructions';\n\nexport type V1CompiledTransactionMessage = Readonly<{\n    /** A mask indicating which transaction config values are present */\n    configMask: number;\n    /** The configuration values for the transaction */\n    configValues: ReturnType<typeof getTransactionConfigValues>;\n    /** Information about the role of the accounts loaded. */\n    header: ReturnType<typeof getCompiledMessageHeader>;\n    /** The headers for each instruction in the transaction */\n    instructionHeaders: ReturnType<typeof getInstructionHeader>[];\n    /** The payload for each instruction in the transaction */\n    instructionPayloads: ReturnType<typeof getInstructionPayload>[];\n    /** The number of instructions in the transaction */\n    numInstructions: number;\n    /** The number of static accounts in the transaction */\n    numStaticAccounts: number;\n    /** A list of addresses indicating which accounts to load */\n    staticAccounts: Address[];\n    version: 1;\n}>;\n\nexport function compileTransactionMessage<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer & { version: 1 },\n>(\n    transactionMessage: TTransactionMessage,\n): ForwardTransactionMessageLifetime<V1CompiledTransactionMessage, TTransactionMessage> {\n    type ReturnType = ForwardTransactionMessageLifetime<V1CompiledTransactionMessage, TTransactionMessage>;\n    const addressMap = getAddressMapFromInstructions(\n        transactionMessage.feePayer.address,\n        transactionMessage.instructions,\n    );\n    const orderedAccounts = getOrderedAccountsFromAddressMap(addressMap);\n    const numAccounts = orderedAccounts.length;\n    if (numAccounts > 64) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNT_ADDRESSES, {\n            actualCount: numAccounts,\n            maxAllowed: 64,\n        });\n    }\n    const numSigners = orderedAccounts.filter(account => isSignerRole(account.role)).length;\n    if (numSigners > 12) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_SIGNER_ADDRESSES, {\n            actualCount: numSigners,\n            maxAllowed: 12,\n        });\n    }\n    const numInstructions = transactionMessage.instructions.length;\n    if (numInstructions > 64) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_INSTRUCTIONS, {\n            actualCount: numInstructions,\n            maxAllowed: 64,\n        });\n    }\n    for (let i = 0; i < transactionMessage.instructions.length; i++) {\n        const numAccountsInInstruction = transactionMessage.instructions[i].accounts?.length ?? 0;\n        if (numAccountsInInstruction > 255) {\n            throw new SolanaError(SOLANA_ERROR__TRANSACTION__TOO_MANY_ACCOUNTS_IN_INSTRUCTION, {\n                actualCount: numAccountsInInstruction,\n                instructionIndex: i,\n                maxAllowed: 255,\n            });\n        }\n    }\n    const accountIndex = getAccountIndex(orderedAccounts);\n    const lifetimeConstraint = (transactionMessage as Partial<TransactionMessageWithLifetime>).lifetimeConstraint;\n\n    return {\n        version: 1,\n        ...(lifetimeConstraint ? { lifetimeToken: getCompiledLifetimeToken(lifetimeConstraint) } : null),\n        configMask: getTransactionConfigMask(transactionMessage.config ?? {}),\n        configValues: getTransactionConfigValues(transactionMessage.config ?? {}),\n        header: getCompiledMessageHeader(orderedAccounts),\n        instructionHeaders: transactionMessage.instructions.map(instruction =>\n            getInstructionHeader(instruction, accountIndex),\n        ),\n        instructionPayloads: transactionMessage.instructions.map(instruction =>\n            getInstructionPayload(instruction, accountIndex),\n        ),\n        numInstructions: transactionMessage.instructions.length,\n        numStaticAccounts: orderedAccounts.length,\n        staticAccounts: orderedAccounts.map(account => account.address),\n    } as ReturnType;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compress-transaction-message.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountLookupMeta, AccountMeta, AccountRole, Instruction, isSignerRole } from '@solana/instructions';\n\nimport { AddressesByLookupTableAddress } from './addresses-by-lookup-table-address';\nimport { TransactionMessage } from './transaction-message';\n\ntype Mutable<T> = {\n    -readonly [P in keyof T]: T[P];\n};\n\n// Look up the address in lookup tables, return a lookup meta if it is found in any of them\nfunction findAddressInLookupTables(\n    address: Address,\n    role: AccountRole.READONLY | AccountRole.WRITABLE,\n    addressesByLookupTableAddress: AddressesByLookupTableAddress,\n): AccountLookupMeta | undefined {\n    for (const [lookupTableAddress, addresses] of Object.entries(addressesByLookupTableAddress)) {\n        for (let i = 0; i < addresses.length; i++) {\n            if (address === addresses[i]) {\n                return {\n                    address,\n                    addressIndex: i,\n                    lookupTableAddress: lookupTableAddress as Address,\n                    role,\n                };\n            }\n        }\n    }\n}\n\ntype TransactionMessageNotLegacy = Exclude<TransactionMessage, { version: 'legacy' }>;\n\n// Each account can be AccountLookupMeta | AccountMeta\ntype WidenInstructionAccounts<TInstruction extends Instruction> =\n    TInstruction extends Instruction<infer TProgramAddress, infer TAccounts>\n        ? Instruction<\n              TProgramAddress,\n              {\n                  [K in keyof TAccounts]: TAccounts[K] extends AccountMeta<infer TAddress>\n                      ? AccountLookupMeta<TAddress> | AccountMeta<TAddress>\n                      : TAccounts[K];\n              }\n          >\n        : TInstruction;\n\ntype WidenTransactionMessageInstructions<TTransactionMessage extends TransactionMessage> = TTransactionMessage extends {\n    readonly instructions: readonly (infer TInstruction extends Instruction)[];\n}\n    ? Omit<TTransactionMessage, 'instructions'> & {\n          readonly instructions: readonly WidenInstructionAccounts<TInstruction>[];\n      }\n    : TTransactionMessage;\n\n/**\n * Given a transaction message and a mapping of lookup tables to the addresses stored in them, this\n * function will return a new transaction message with the same instructions but with all non-signer\n * accounts that are found in the given lookup tables represented by an {@link AccountLookupMeta}\n * instead of an {@link AccountMeta}.\n *\n * This means that these accounts will take up less space in the compiled transaction message. This\n * size reduction is most significant when the transaction includes many accounts from the same\n * lookup table.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n * import {\n *     AddressesByLookupTableAddress,\n *     compressTransactionMessageUsingAddressLookupTables,\n * } from '@solana/transaction-messages';\n * import { fetchAddressLookupTable } from '@solana-program/address-lookup-table';\n *\n * const lookupTableAddress = address('4QwSwNriKPrz8DLW4ju5uxC2TN5cksJx6tPUPj7DGLAW');\n * const {\n *     data: { addresses },\n * } = await fetchAddressLookupTable(rpc, lookupTableAddress);\n * const addressesByAddressLookupTable: AddressesByLookupTableAddress = {\n *     [lookupTableAddress]: addresses,\n * };\n *\n * const compressedTransactionMessage = compressTransactionMessageUsingAddressLookupTables(\n *     transactionMessage,\n *     addressesByAddressLookupTable,\n * );\n * ```\n */\nexport function compressTransactionMessageUsingAddressLookupTables<\n    TTransactionMessage extends TransactionMessageNotLegacy = TransactionMessageNotLegacy,\n>(\n    transactionMessage: TTransactionMessage,\n    addressesByLookupTableAddress: AddressesByLookupTableAddress,\n): TTransactionMessage | WidenTransactionMessageInstructions<TTransactionMessage> {\n    const programAddresses = new Set(transactionMessage.instructions.map(ix => ix.programAddress));\n    const eligibleLookupAddresses = new Set(\n        Object.values(addressesByLookupTableAddress)\n            .flatMap(a => a)\n            .filter(address => !programAddresses.has(address)),\n    );\n    const newInstructions: Instruction[] = [];\n    let updatedAnyInstructions = false;\n    for (const instruction of transactionMessage.instructions) {\n        if (!instruction.accounts) {\n            newInstructions.push(instruction);\n            continue;\n        }\n\n        const newAccounts: Mutable<NonNullable<Instruction['accounts']>> = [];\n        let updatedAnyAccounts = false;\n        for (const account of instruction.accounts) {\n            // If the address is already a lookup, is not in any lookup tables, or is a signer role, return as-is\n            if (\n                'lookupTableAddress' in account ||\n                !eligibleLookupAddresses.has(account.address) ||\n                isSignerRole(account.role)\n            ) {\n                newAccounts.push(account);\n                continue;\n            }\n\n            // We already checked it's in one of the lookup tables\n            const lookupMetaAccount = findAddressInLookupTables(\n                account.address,\n                account.role,\n                addressesByLookupTableAddress,\n            )!;\n            newAccounts.push(Object.freeze(lookupMetaAccount));\n            updatedAnyAccounts = true;\n            updatedAnyInstructions = true;\n        }\n\n        newInstructions.push(\n            Object.freeze(updatedAnyAccounts ? { ...instruction, accounts: newAccounts } : instruction),\n        );\n    }\n\n    return Object.freeze(\n        updatedAnyInstructions ? { ...transactionMessage, instructions: newInstructions } : transactionMessage,\n    );\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compute-budget-instruction.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { getBytesEncoder, getStructEncoder } from '@solana/codecs-data-structures';\nimport { getU8Encoder, getU32Decoder, getU32Encoder, getU64Decoder, getU64Encoder } from '@solana/codecs-numbers';\nimport { Instruction, InstructionWithData } from '@solana/instructions';\n\nimport type { TransactionMessage } from './transaction-message';\n\n/** Address of the Compute Budget program. */\nexport const COMPUTE_BUDGET_PROGRAM_ADDRESS =\n    'ComputeBudget111111111111111111111111111111' as Address<'ComputeBudget111111111111111111111111111111'>;\n\n/** The maximum compute unit limit that can be set for a transaction (1.4M CU). */\nexport const MAX_COMPUTE_UNIT_LIMIT = 1_400_000;\n\nconst REQUEST_HEAP_FRAME_DISCRIMINATOR = 1;\nconst SET_COMPUTE_UNIT_LIMIT_DISCRIMINATOR = 2;\nconst SET_COMPUTE_UNIT_PRICE_DISCRIMINATOR = 3;\nconst SET_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_DISCRIMINATOR = 4;\n\ntype ComputeBudgetInstruction = Instruction<typeof COMPUTE_BUDGET_PROGRAM_ADDRESS> &\n    InstructionWithData<ReadonlyUint8Array>;\n\nfunction getComputeBudgetInstruction(discriminator: number, value: ReadonlyUint8Array): ComputeBudgetInstruction {\n    const data = getStructEncoder([\n        ['discriminator', getU8Encoder()],\n        ['value', getBytesEncoder()],\n    ]).encode({ discriminator, value });\n    return Object.freeze({\n        data,\n        programAddress: COMPUTE_BUDGET_PROGRAM_ADDRESS,\n    }) as ComputeBudgetInstruction;\n}\n\nfunction isComputeBudgetInstruction(\n    instruction: Instruction,\n    discriminator: number,\n    expectedDataLength: number,\n): instruction is ComputeBudgetInstruction {\n    return (\n        instruction.programAddress === COMPUTE_BUDGET_PROGRAM_ADDRESS &&\n        'data' in instruction &&\n        instruction.data != null &&\n        instruction.data.byteLength === expectedDataLength &&\n        instruction.data[0] === discriminator\n    );\n}\n\nexport function getSetComputeUnitLimitInstruction(units: number): ComputeBudgetInstruction {\n    return getComputeBudgetInstruction(SET_COMPUTE_UNIT_LIMIT_DISCRIMINATOR, getU32Encoder().encode(units));\n}\n\nexport function isSetComputeUnitLimitInstruction(instruction: Instruction): instruction is ComputeBudgetInstruction {\n    return isComputeBudgetInstruction(instruction, SET_COMPUTE_UNIT_LIMIT_DISCRIMINATOR, 5);\n}\n\nexport function getComputeUnitLimitFromInstructionData(data: ReadonlyUint8Array): number {\n    return getU32Decoder().decode(data, 1);\n}\n\nexport function getSetComputeUnitPriceInstruction(microLamports: bigint): ComputeBudgetInstruction {\n    return getComputeBudgetInstruction(SET_COMPUTE_UNIT_PRICE_DISCRIMINATOR, getU64Encoder().encode(microLamports));\n}\n\nexport function isSetComputeUnitPriceInstruction(instruction: Instruction): instruction is ComputeBudgetInstruction {\n    return isComputeBudgetInstruction(instruction, SET_COMPUTE_UNIT_PRICE_DISCRIMINATOR, 9);\n}\n\nexport function getPriorityFeeFromInstructionData(data: ReadonlyUint8Array): bigint {\n    return getU64Decoder().decode(data, 1);\n}\n\nexport function getRequestHeapFrameInstruction(bytes: number): ComputeBudgetInstruction {\n    return getComputeBudgetInstruction(REQUEST_HEAP_FRAME_DISCRIMINATOR, getU32Encoder().encode(bytes));\n}\n\nexport function isRequestHeapFrameInstruction(instruction: Instruction): instruction is ComputeBudgetInstruction {\n    return isComputeBudgetInstruction(instruction, REQUEST_HEAP_FRAME_DISCRIMINATOR, 5);\n}\n\nexport function getHeapSizeFromInstructionData(data: ReadonlyUint8Array): number {\n    return getU32Decoder().decode(data, 1);\n}\n\nexport function getSetLoadedAccountsDataSizeLimitInstruction(limit: number): ComputeBudgetInstruction {\n    return getComputeBudgetInstruction(\n        SET_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_DISCRIMINATOR,\n        getU32Encoder().encode(limit),\n    );\n}\n\nexport function isSetLoadedAccountsDataSizeLimitInstruction(\n    instruction: Instruction,\n): instruction is ComputeBudgetInstruction {\n    return isComputeBudgetInstruction(instruction, SET_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_DISCRIMINATOR, 5);\n}\n\nexport function getLoadedAccountsDataSizeLimitFromInstructionData(data: ReadonlyUint8Array): number {\n    return getU32Decoder().decode(data, 1);\n}\n\nexport function replaceTransactionMessageInstruction<TTransactionMessage extends TransactionMessage>(\n    index: number,\n    newInstruction: Instruction,\n    transactionMessage: TTransactionMessage,\n) {\n    const nextInstructions = [...transactionMessage.instructions];\n    nextInstructions[index] = newInstruction;\n    return Object.freeze({\n        ...transactionMessage,\n        instructions: Object.freeze(nextInstructions),\n    }) as TTransactionMessage;\n}\n\nexport function removeTransactionMessageInstruction<TTransactionMessage extends TransactionMessage>(\n    index: number,\n    transactionMessage: TTransactionMessage,\n) {\n    return Object.freeze({\n        ...transactionMessage,\n        instructions: Object.freeze([\n            ...transactionMessage.instructions.slice(0, index),\n            ...transactionMessage.instructions.slice(index + 1),\n        ]),\n    }) as TTransactionMessage;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compute-unit-limit.ts",
    "content": "import type { Instruction } from '@solana/instructions';\n\nimport {\n    getComputeUnitLimitFromInstructionData,\n    getSetComputeUnitLimitInstruction,\n    isSetComputeUnitLimitInstruction,\n    removeTransactionMessageInstruction,\n    replaceTransactionMessageInstruction,\n} from './compute-budget-instruction';\nimport { appendTransactionMessageInstruction } from './instructions';\nimport { TransactionMessage } from './transaction-message';\nimport { areV1ConfigsEqual, isV1ConfigEmpty } from './v1-transaction-config';\n\n/**\n * Returns the compute unit limit currently set on a transaction message, or `undefined` if none is\n * set.\n *\n * This function works with all transaction versions:\n * - **V1**: Reads from the transaction message's `config.computeUnitLimit`.\n * - **Legacy / V0**: Searches the instructions for a `SetComputeUnitLimit` instruction and decodes\n *   its value.\n *\n * @param transactionMessage - The transaction message to inspect.\n * @return The compute unit limit, or `undefined` if none is set.\n *\n * @example\n * ```ts\n * const limit = getTransactionMessageComputeUnitLimit(transactionMessage);\n * if (limit !== undefined) {\n *     console.log(`Compute unit limit: ${limit}`);\n * }\n * ```\n */\nexport function getTransactionMessageComputeUnitLimit(transactionMessage: TransactionMessage): number | undefined {\n    switch (transactionMessage.version) {\n        case 1:\n            return transactionMessage.config?.computeUnitLimit;\n        default:\n            return getTransactionMessageComputeUnitLimitUsingInstruction(transactionMessage);\n    }\n}\n\nfunction getTransactionMessageComputeUnitLimitUsingInstruction(\n    transactionMessage: TransactionMessage,\n): number | undefined {\n    const instructions = transactionMessage.instructions as Instruction[];\n    const existingInstruction = instructions.find(isSetComputeUnitLimitInstruction);\n    return existingInstruction ? getComputeUnitLimitFromInstructionData(existingInstruction.data) : undefined;\n}\n\n/**\n * Sets the compute unit limit for a transaction message.\n *\n * This function works with all transaction versions:\n * - **V1**: Sets the `computeUnitLimit` field in the transaction message's config.\n * - **Legacy / V0**: Appends (or replaces) a `SetComputeUnitLimit` instruction from the Compute\n *   Budget program.\n *\n * @param computeUnitLimit - The maximum compute units (CUs) allowed, or `undefined` to remove the\n *   limit.\n * @param transactionMessage - The transaction message to configure.\n * @typeParam TTransactionMessage - The transaction message type.\n * @return A new transaction message with the compute unit limit set.\n *\n * @example\n * ```ts\n * const txMessage = setTransactionMessageComputeUnitLimit(\n *     400_000,\n *     transactionMessage,\n * );\n * ```\n */\nexport function setTransactionMessageComputeUnitLimit<TTransactionMessage extends TransactionMessage>(\n    computeUnitLimit: number | undefined,\n    transactionMessage: TTransactionMessage,\n): TTransactionMessage {\n    switch (transactionMessage.version) {\n        case 1:\n            return setTransactionMessageComputeUnitLimitUsingConfig(\n                computeUnitLimit,\n                transactionMessage,\n            ) as TTransactionMessage;\n        default:\n            return setTransactionMessageComputeUnitLimitUsingInstruction(computeUnitLimit, transactionMessage);\n    }\n}\n\nfunction setTransactionMessageComputeUnitLimitUsingConfig<\n    TTransactionMessage extends TransactionMessage & { version: 1 },\n>(computeUnitLimit: number | undefined, transactionMessage: TTransactionMessage): TTransactionMessage {\n    const mergedConfig = { ...(transactionMessage.config ?? {}), computeUnitLimit };\n    const nextConfig = isV1ConfigEmpty(mergedConfig) ? undefined : Object.freeze(mergedConfig);\n    if (nextConfig === undefined) {\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        const { config, ...rest } = transactionMessage;\n        return Object.freeze(rest) as TTransactionMessage;\n    }\n\n    if (transactionMessage.config && areV1ConfigsEqual(transactionMessage.config, nextConfig)) {\n        return transactionMessage;\n    }\n\n    return Object.freeze({ ...transactionMessage, config: nextConfig }) as TTransactionMessage;\n}\n\nfunction setTransactionMessageComputeUnitLimitUsingInstruction<TTransactionMessage extends TransactionMessage>(\n    computeUnitLimit: number | undefined,\n    transactionMessage: TTransactionMessage,\n): TTransactionMessage {\n    const existingIndex = transactionMessage.instructions.findIndex(isSetComputeUnitLimitInstruction);\n\n    // Remove the compute unit limit instruction if there is one and the new limit is undefined.\n    if (computeUnitLimit === undefined) {\n        return existingIndex === -1\n            ? transactionMessage\n            : removeTransactionMessageInstruction(existingIndex, transactionMessage);\n    }\n\n    // Ignore if the new compute unit limit is the same as the existing one.\n    if (getTransactionMessageComputeUnitLimit(transactionMessage) === computeUnitLimit) {\n        return transactionMessage;\n    }\n\n    // Add or replace the compute unit limit instruction with the new limit.\n    const newInstruction = getSetComputeUnitLimitInstruction(computeUnitLimit);\n    return existingIndex === -1\n        ? (appendTransactionMessageInstruction(newInstruction, transactionMessage) as TTransactionMessage)\n        : replaceTransactionMessageInstruction(existingIndex, newInstruction, transactionMessage);\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/compute-unit-price.ts",
    "content": "import type { Instruction } from '@solana/instructions';\n\nimport {\n    getPriorityFeeFromInstructionData,\n    getSetComputeUnitPriceInstruction,\n    isSetComputeUnitPriceInstruction,\n    removeTransactionMessageInstruction,\n    replaceTransactionMessageInstruction,\n} from './compute-budget-instruction';\nimport { appendTransactionMessageInstruction } from './instructions';\nimport { TransactionMessage, TransactionVersion } from './transaction-message';\n\ntype SupportedTransactionVersions = Extract<TransactionVersion, 'legacy' | 0>;\n\n/**\n * Returns the compute unit price currently set on a legacy or v0 transaction message, or\n * `undefined` if none is set.\n *\n * This searches the instructions for a `SetComputeUnitPrice` instruction and decodes its value.\n * The value represents the price in **micro-lamports per compute unit**.\n *\n * @param transactionMessage - The legacy or v0 transaction message to inspect.\n * @return The compute unit price in micro-lamports per compute unit, or `undefined` if none is set.\n *\n * @example\n * ```ts\n * const price = getTransactionMessageComputeUnitPrice(transactionMessage);\n * if (price !== undefined) {\n *     console.log(`Compute unit price: ${price} micro-lamports`);\n * }\n * ```\n *\n * @see {@link setTransactionMessageComputeUnitPrice}\n * @see {@link getTransactionMessagePriorityFeeLamports} for v1 transactions.\n */\nexport function getTransactionMessageComputeUnitPrice<\n    TTransactionMessage extends TransactionMessage & { version: SupportedTransactionVersions },\n>(transactionMessage: TTransactionMessage): bigint | undefined {\n    const instructions = transactionMessage.instructions as Instruction[];\n    const existingInstruction = instructions.find(isSetComputeUnitPriceInstruction);\n    return existingInstruction ? getPriorityFeeFromInstructionData(existingInstruction.data) : undefined;\n}\n\n/**\n * Sets the compute unit price for a legacy or v0 transaction message.\n *\n * The value represents the price in **micro-lamports per compute unit**. The actual priority fee\n * paid is `computeUnitPrice × computeUnitLimit`.\n *\n * This appends, replaces, or removes a `SetComputeUnitPrice` instruction from the Compute Budget\n * program. The operation is idempotent: setting the same value returns the same reference, and\n * setting `undefined` removes the instruction.\n *\n * @param computeUnitPrice - The price in micro-lamports per compute unit, or `undefined` to remove\n *   the instruction.\n * @param transactionMessage - The legacy or v0 transaction message to configure.\n * @typeParam TTransactionMessage - The transaction message type.\n * @return A new transaction message with the compute unit price set.\n *\n * @example\n * ```ts\n * const txMessage = setTransactionMessageComputeUnitPrice(\n *     10_000n,\n *     transactionMessage,\n * );\n * ```\n *\n * @see {@link getTransactionMessageComputeUnitPrice}\n * @see {@link setTransactionMessagePriorityFeeLamports} for v1 transactions.\n */\nexport function setTransactionMessageComputeUnitPrice<\n    TTransactionMessage extends TransactionMessage & { version: SupportedTransactionVersions },\n>(computeUnitPrice: bigint | undefined, transactionMessage: TTransactionMessage): TTransactionMessage {\n    const existingIndex = transactionMessage.instructions.findIndex(isSetComputeUnitPriceInstruction);\n\n    // Remove the compute unit price instruction if there is one and the new price is undefined.\n    if (computeUnitPrice === undefined) {\n        return existingIndex === -1\n            ? transactionMessage\n            : removeTransactionMessageInstruction(existingIndex, transactionMessage);\n    }\n\n    // Ignore if the new compute unit price is the same as the existing one.\n    if (getTransactionMessageComputeUnitPrice(transactionMessage) === computeUnitPrice) {\n        return transactionMessage;\n    }\n\n    // Add or replace the compute unit price instruction with the new price.\n    const newInstruction = getSetComputeUnitPriceInstruction(computeUnitPrice);\n    return existingIndex === -1\n        ? (appendTransactionMessageInstruction(newInstruction, transactionMessage) as TTransactionMessage)\n        : replaceTransactionMessageInstruction(existingIndex, newInstruction, transactionMessage);\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/create-transaction-message.ts",
    "content": "import { TransactionMessage, TransactionVersion } from './transaction-message';\nimport { TransactionMessageWithinSizeLimit } from './transaction-message-size';\n\n// Note: v1 transactions are not yet supported by these functions\ntype SupportedTransactionVersion = Exclude<TransactionVersion, 1>;\n\ntype TransactionConfig<TVersion extends SupportedTransactionVersion> = Readonly<{\n    version: TVersion;\n}>;\n\ntype EmptyTransactionMessage<TVersion extends SupportedTransactionVersion> = Omit<\n    Extract<TransactionMessage, { version: TVersion }>,\n    'instructions'\n> &\n    TransactionMessageWithinSizeLimit & { instructions: readonly [] };\n\n/**\n * Given a {@link TransactionVersion} this method will return an empty transaction having the\n * capabilities of that version.\n *\n * @example\n * ```ts\n * import { createTransactionMessage } from '@solana/transaction-messages';\n *\n * const message = createTransactionMessage({ version: 0 });\n * ```\n */\nexport function createTransactionMessage<TVersion extends SupportedTransactionVersion>(\n    config: TransactionConfig<TVersion>,\n): EmptyTransactionMessage<TVersion> {\n    return Object.freeze({\n        instructions: Object.freeze([]),\n        version: config.version,\n    }) as EmptyTransactionMessage<TVersion>;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/__tests__/message-test.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    DecompileTransactionMessageConfig,\n} from '../..';\nimport { decompileTransactionMessage as decompileLegacyTransactionMessage } from '../legacy/message';\nimport { decompileTransactionMessage } from '../message';\nimport { decompileTransactionMessage as decompileV0TransactionMessage } from '../v0/message';\nimport { decompileTransactionMessage as decompileV1TransactionMessage } from '../v1/message';\n\njest.mock('../legacy/message');\njest.mock('../v0/message');\njest.mock('../v1/message');\n\ndescribe('decompileTransactionMessage', () => {\n    it('uses the legacy decompiler for legacy messages', () => {\n        const mockTransactionMessage = { version: 'legacy' } as unknown as ReturnType<\n            typeof decompileLegacyTransactionMessage\n        >;\n        jest.mocked(decompileLegacyTransactionMessage).mockReturnValue(mockTransactionMessage);\n\n        const tx: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            instructions: [],\n            lifetimeToken: '',\n            staticAccounts: [],\n            version: 'legacy',\n        };\n\n        const config: DecompileTransactionMessageConfig = {\n            lastValidBlockHeight: 123n,\n        };\n\n        expect(decompileLegacyTransactionMessage(tx, config)).toBe(mockTransactionMessage);\n        expect(decompileLegacyTransactionMessage).toHaveBeenCalledTimes(1);\n        expect(decompileLegacyTransactionMessage).toHaveBeenCalledWith(tx, config);\n    });\n\n    it('uses the v0 decompiler for v0 messages', () => {\n        const mockTransactionMessage = { version: 0 } as unknown as ReturnType<typeof decompileV0TransactionMessage>;\n        jest.mocked(decompileV0TransactionMessage).mockReturnValue(mockTransactionMessage);\n\n        const tx: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime & { version: 0 } = {\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            instructions: [],\n            lifetimeToken: '',\n            staticAccounts: [],\n            version: 0,\n        };\n\n        const config: DecompileTransactionMessageConfig = {\n            addressesByLookupTableAddress: {},\n            lastValidBlockHeight: 123n,\n        };\n\n        expect(decompileV0TransactionMessage(tx, config)).toBe(mockTransactionMessage);\n        expect(decompileV0TransactionMessage).toHaveBeenCalledTimes(1);\n        expect(decompileV0TransactionMessage).toHaveBeenCalledWith(tx, config);\n    });\n\n    it('uses the v1 decompiler for v1 messages', () => {\n        const mockTransactionMessage = { version: 1 } as unknown as ReturnType<typeof decompileV1TransactionMessage>;\n        jest.mocked(decompileV1TransactionMessage).mockReturnValue(mockTransactionMessage);\n\n        const tx: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime & { version: 1 } = {\n            configMask: 0,\n            configValues: [],\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            instructionHeaders: [],\n            instructionPayloads: [],\n            lifetimeToken: '',\n            numInstructions: 0,\n            numStaticAccounts: 0,\n            staticAccounts: [],\n            version: 1,\n        };\n\n        const config: DecompileTransactionMessageConfig = {\n            addressesByLookupTableAddress: {},\n            lastValidBlockHeight: 123n,\n        };\n\n        expect(decompileV1TransactionMessage(tx, config)).toBe(mockTransactionMessage);\n        expect(decompileV1TransactionMessage).toHaveBeenCalledTimes(1);\n        expect(decompileV1TransactionMessage).toHaveBeenCalledWith(tx, config);\n    });\n\n    it('throws for unsupported v2 transaction', () => {\n        const tx = {\n            version: 2,\n        } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n        expect(() => decompileTransactionMessage(tx)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                version: 2,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/__typetests__/message-typetest.ts",
    "content": "import { isTransactionMessageWithBlockhashLifetime, TransactionMessageWithBlockhashLifetime } from '../../blockhash';\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../../compile/message';\nimport { TransactionMessageWithFeePayer } from '../../fee-payer';\nimport { TransactionMessageWithLifetime } from '../../lifetime';\nimport { TransactionMessage } from '../../transaction-message';\nimport { decompileTransactionMessage } from '../message';\n\n// [DESCRIBE] decompileTransactionMessage\n{\n    // Returns a TransactionMessage\n    {\n        const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n            CompiledTransactionMessageWithLifetime;\n        decompileTransactionMessage(compiledTransactionMessage) satisfies TransactionMessage;\n    }\n\n    // Has a fee payer\n    {\n        const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n            CompiledTransactionMessageWithLifetime;\n        decompileTransactionMessage(compiledTransactionMessage) satisfies TransactionMessageWithFeePayer;\n    }\n\n    // Has a lifetime\n    {\n        const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n            CompiledTransactionMessageWithLifetime;\n        decompileTransactionMessage(compiledTransactionMessage) satisfies TransactionMessageWithLifetime;\n    }\n\n    // Has the correct version\n    {\n        // for legacy\n        {\n            const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' };\n            decompileTransactionMessage(compiledTransactionMessage) satisfies TransactionMessage & {\n                version: 'legacy';\n            };\n        }\n\n        // for v0\n        {\n            const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 };\n            decompileTransactionMessage(compiledTransactionMessage) satisfies TransactionMessage & { version: 0 };\n        }\n\n        // for v1\n        {\n            const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 1 };\n            decompileTransactionMessage(compiledTransactionMessage) satisfies TransactionMessage & { version: 1 };\n        }\n    }\n\n    // Lifetime can be narrowed\n    {\n        {\n            const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime;\n            const transactionMessage = decompileTransactionMessage(compiledTransactionMessage);\n            // @ts-expect-error Lifetime could be different\n            transactionMessage satisfies TransactionMessageWithBlockhashLifetime;\n            if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n                transactionMessage satisfies TransactionMessageWithBlockhashLifetime;\n            }\n        }\n    }\n\n    // Version can be narrowed\n    {\n        const compiledTransactionMessage = null as unknown as CompiledTransactionMessage &\n            CompiledTransactionMessageWithLifetime;\n        const transactionMessage = decompileTransactionMessage(compiledTransactionMessage);\n        // @ts-expect-error Version could be different\n        transactionMessage satisfies TransactionMessage & { version: 'legacy' };\n        if (transactionMessage.version === 'legacy') {\n            transactionMessage satisfies TransactionMessage & { version: 'legacy' };\n        } else if (transactionMessage.version === 0) {\n            transactionMessage satisfies TransactionMessage & { version: 0 };\n        } else if (transactionMessage.version === 1) {\n            transactionMessage satisfies TransactionMessage & { version: 1 };\n        }\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/index.ts",
    "content": "export * from './message';\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/__tests__/account-metas-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountRole } from '@solana/instructions';\n\nimport { CompiledTransactionMessage } from '../../..';\nimport { getAccountMetas } from '../account-metas';\n\ndescribe('getAccountMetas', () => {\n    it('should return account metas with all four types of accounts', () => {\n        const compiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 2,\n                numReadonlySignerAccounts: 1,\n                numSignerAccounts: 3,\n            },\n            staticAccounts: [\n                'writable-signer-1' as Address,\n                'writable-signer-2' as Address,\n                'readonly-signer' as Address,\n                'writable-non-signer-1' as Address,\n                'writable-non-signer-2' as Address,\n                'readonly-non-signer-1' as Address,\n                'readonly-non-signer-2' as Address,\n            ],\n        } as CompiledTransactionMessage;\n\n        const accountMetas = getAccountMetas(compiledTransactionMessage);\n\n        expect(accountMetas).toStrictEqual([\n            { address: 'writable-signer-1', role: AccountRole.WRITABLE_SIGNER },\n            { address: 'writable-signer-2', role: AccountRole.WRITABLE_SIGNER },\n            { address: 'readonly-signer', role: AccountRole.READONLY_SIGNER },\n            { address: 'writable-non-signer-1', role: AccountRole.WRITABLE },\n            { address: 'writable-non-signer-2', role: AccountRole.WRITABLE },\n            { address: 'readonly-non-signer-1', role: AccountRole.READONLY },\n            { address: 'readonly-non-signer-2', role: AccountRole.READONLY },\n        ]);\n    });\n\n    it('should return account metas with only writable signers', () => {\n        const compiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 2,\n            },\n            staticAccounts: ['writable-signer-1' as Address, 'writable-signer-2' as Address],\n        } as CompiledTransactionMessage;\n\n        const accountMetas = getAccountMetas(compiledTransactionMessage);\n\n        expect(accountMetas).toStrictEqual([\n            { address: 'writable-signer-1', role: AccountRole.WRITABLE_SIGNER },\n            { address: 'writable-signer-2', role: AccountRole.WRITABLE_SIGNER },\n        ]);\n    });\n\n    it('should return account metas with only readonly signers', () => {\n        const compiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 2,\n                numSignerAccounts: 2,\n            },\n            staticAccounts: ['readonly-signer-1' as Address, 'readonly-signer-2' as Address],\n        } as CompiledTransactionMessage;\n\n        const accountMetas = getAccountMetas(compiledTransactionMessage);\n\n        expect(accountMetas).toStrictEqual([\n            { address: 'readonly-signer-1', role: AccountRole.READONLY_SIGNER },\n            { address: 'readonly-signer-2', role: AccountRole.READONLY_SIGNER },\n        ]);\n    });\n\n    it('should return account metas with only writable non-signers', () => {\n        const compiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            staticAccounts: ['writable-non-signer-1' as Address, 'writable-non-signer-2' as Address],\n        } as CompiledTransactionMessage;\n\n        const accountMetas = getAccountMetas(compiledTransactionMessage);\n\n        expect(accountMetas).toStrictEqual([\n            { address: 'writable-non-signer-1', role: AccountRole.WRITABLE },\n            { address: 'writable-non-signer-2', role: AccountRole.WRITABLE },\n        ]);\n    });\n\n    it('should return account metas with only readonly non-signers', () => {\n        const compiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 2,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            staticAccounts: ['readonly-non-signer-1' as Address, 'readonly-non-signer-2' as Address],\n        } as CompiledTransactionMessage;\n\n        const accountMetas = getAccountMetas(compiledTransactionMessage);\n\n        expect(accountMetas).toStrictEqual([\n            { address: 'readonly-non-signer-1', role: AccountRole.READONLY },\n            { address: 'readonly-non-signer-2', role: AccountRole.READONLY },\n        ]);\n    });\n\n    it('should return empty array when no accounts are present', () => {\n        const compiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 0,\n            },\n            staticAccounts: [] as Address[],\n        } as CompiledTransactionMessage;\n\n        const accountMetas = getAccountMetas(compiledTransactionMessage);\n\n        expect(accountMetas).toStrictEqual([]);\n    });\n\n    it('should handle a single writable signer (fee payer only)', () => {\n        const compiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 1,\n            },\n            staticAccounts: ['fee-payer' as Address],\n        } as CompiledTransactionMessage;\n\n        const accountMetas = getAccountMetas(compiledTransactionMessage);\n\n        expect(accountMetas).toStrictEqual([{ address: 'fee-payer', role: AccountRole.WRITABLE_SIGNER }]);\n    });\n\n    it('should correctly handle mixed writable signers and readonly non-signers', () => {\n        const compiledTransactionMessage = {\n            header: {\n                numReadonlyNonSignerAccounts: 2,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 2,\n            },\n            staticAccounts: [\n                'writable-signer-1' as Address,\n                'writable-signer-2' as Address,\n                'readonly-non-signer-1' as Address,\n                'readonly-non-signer-2' as Address,\n            ],\n        } as CompiledTransactionMessage;\n\n        const accountMetas = getAccountMetas(compiledTransactionMessage);\n\n        expect(accountMetas).toStrictEqual([\n            { address: 'writable-signer-1', role: AccountRole.WRITABLE_SIGNER },\n            { address: 'writable-signer-2', role: AccountRole.WRITABLE_SIGNER },\n            { address: 'readonly-non-signer-1', role: AccountRole.READONLY },\n            { address: 'readonly-non-signer-2', role: AccountRole.READONLY },\n        ]);\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/__tests__/convert-instruction-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\n\nimport { LegacyCompiledTransactionMessage } from '../../..';\nimport { convertInstructions } from '../convert-instruction';\n\ndescribe('convertInstructions', () => {\n    it('should convert a single instruction with program address, accounts, and data', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                accountIndices: [0, 1],\n                data: new Uint8Array([1, 2, 3]),\n                programAddressIndex: 2,\n            },\n        ];\n\n        const accountMetas = [\n            { address: 'account0' as Address, role: AccountRole.WRITABLE_SIGNER },\n            { address: 'account1' as Address, role: AccountRole.READONLY },\n            { address: 'program' as Address, role: AccountRole.READONLY },\n        ];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([\n            {\n                accounts: [\n                    { address: 'account0', role: AccountRole.WRITABLE_SIGNER },\n                    { address: 'account1', role: AccountRole.READONLY },\n                ],\n                data: new Uint8Array([1, 2, 3]),\n                programAddress: 'program',\n            },\n        ]);\n    });\n\n    it('should convert an instruction with only program address (no accounts or data)', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                programAddressIndex: 0,\n            },\n        ];\n\n        const accountMetas = [{ address: 'program' as Address, role: AccountRole.READONLY }];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([\n            {\n                programAddress: 'program',\n            },\n        ]);\n    });\n\n    it('should convert an instruction with program address and accounts but no data', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                accountIndices: [0],\n                programAddressIndex: 1,\n            },\n        ];\n\n        const accountMetas = [\n            { address: 'account0' as Address, role: AccountRole.WRITABLE },\n            { address: 'program' as Address, role: AccountRole.READONLY },\n        ];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([\n            {\n                accounts: [{ address: 'account0', role: AccountRole.WRITABLE }],\n                programAddress: 'program',\n            },\n        ]);\n    });\n\n    it('should convert an instruction with program address and data but no accounts', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                data: new Uint8Array([4, 5, 6]),\n                programAddressIndex: 0,\n            },\n        ];\n\n        const accountMetas = [{ address: 'program' as Address, role: AccountRole.READONLY }];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([\n            {\n                data: new Uint8Array([4, 5, 6]),\n                programAddress: 'program',\n            },\n        ]);\n    });\n\n    it('should not include accounts field when accountIndices is empty array', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                accountIndices: [],\n                programAddressIndex: 0,\n            },\n        ];\n\n        const accountMetas = [{ address: 'program' as Address, role: AccountRole.READONLY }];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([\n            {\n                programAddress: 'program',\n            },\n        ]);\n        expect(instructions[0]).not.toHaveProperty('accounts');\n    });\n\n    it('should not include data field when data is empty array', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                data: new Uint8Array(),\n                programAddressIndex: 0,\n            },\n        ];\n\n        const accountMetas = [{ address: 'program' as Address, role: AccountRole.READONLY }];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([\n            {\n                programAddress: 'program',\n            },\n        ]);\n        expect(instructions[0]).not.toHaveProperty('data');\n    });\n\n    it('should convert multiple instructions', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                accountIndices: [0],\n                data: new Uint8Array([1]),\n                programAddressIndex: 2,\n            },\n            {\n                accountIndices: [1],\n                data: new Uint8Array([2]),\n                programAddressIndex: 3,\n            },\n            {\n                programAddressIndex: 4,\n            },\n        ];\n\n        const accountMetas = [\n            { address: 'account0' as Address, role: AccountRole.WRITABLE_SIGNER },\n            { address: 'account1' as Address, role: AccountRole.READONLY_SIGNER },\n            { address: 'program1' as Address, role: AccountRole.READONLY },\n            { address: 'program2' as Address, role: AccountRole.READONLY },\n            { address: 'program3' as Address, role: AccountRole.READONLY },\n        ];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([\n            {\n                accounts: [{ address: 'account0', role: AccountRole.WRITABLE_SIGNER }],\n                data: new Uint8Array([1]),\n                programAddress: 'program1',\n            },\n            {\n                accounts: [{ address: 'account1', role: AccountRole.READONLY_SIGNER }],\n                data: new Uint8Array([2]),\n                programAddress: 'program2',\n            },\n            {\n                programAddress: 'program3',\n            },\n        ]);\n    });\n\n    it('should handle instructions with multiple account indices', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                accountIndices: [0, 1, 2, 3],\n                programAddressIndex: 4,\n            },\n        ];\n\n        const accountMetas = [\n            { address: 'account0' as Address, role: AccountRole.WRITABLE_SIGNER },\n            { address: 'account1' as Address, role: AccountRole.READONLY_SIGNER },\n            { address: 'account2' as Address, role: AccountRole.WRITABLE },\n            { address: 'account3' as Address, role: AccountRole.READONLY },\n            { address: 'program' as Address, role: AccountRole.READONLY },\n        ];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([\n            {\n                accounts: [\n                    { address: 'account0', role: AccountRole.WRITABLE_SIGNER },\n                    { address: 'account1', role: AccountRole.READONLY_SIGNER },\n                    { address: 'account2', role: AccountRole.WRITABLE },\n                    { address: 'account3', role: AccountRole.READONLY },\n                ],\n                programAddress: 'program',\n            },\n        ]);\n    });\n\n    it('should throw when program address index is out of bounds', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                programAddressIndex: 5,\n            },\n        ];\n\n        const accountMetas = [{ address: 'account0' as Address, role: AccountRole.WRITABLE_SIGNER }];\n\n        expect(() => convertInstructions(compiledInstructions, accountMetas)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {\n                index: 5,\n            }),\n        );\n    });\n\n    it('should throw when program address index is negative', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                programAddressIndex: -1,\n            },\n        ];\n\n        const accountMetas = [{ address: 'account0' as Address, role: AccountRole.WRITABLE_SIGNER }];\n\n        expect(() => convertInstructions(compiledInstructions, accountMetas)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {\n                index: -1,\n            }),\n        );\n    });\n\n    it('should return empty array when no instructions provided', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [];\n        const accountMetas = [{ address: 'account0' as Address, role: AccountRole.WRITABLE_SIGNER }];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions).toStrictEqual([]);\n    });\n\n    it('should freeze the returned instruction objects', () => {\n        const compiledInstructions: LegacyCompiledTransactionMessage['instructions'] = [\n            {\n                accountIndices: [0],\n                programAddressIndex: 1,\n            },\n        ];\n\n        const accountMetas = [\n            { address: 'account0' as Address, role: AccountRole.WRITABLE },\n            { address: 'program' as Address, role: AccountRole.READONLY },\n        ];\n\n        const instructions = convertInstructions(compiledInstructions, accountMetas);\n\n        expect(instructions[0]).toBeFrozenObject();\n        expect(instructions[0].accounts).toBeFrozenObject();\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/__tests__/fee-payer-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING, SolanaError } from '@solana/errors';\n\nimport { getFeePayer } from '../fee-payer';\n\ndescribe('getFeePayer', () => {\n    it('should return the fee payer from the compiled transaction message', () => {\n        const staticAccounts = ['fee-payer' as Address, 'account1' as Address, 'account2' as Address];\n        const feePayer = getFeePayer(staticAccounts);\n        expect(feePayer).toBe('fee-payer');\n    });\n\n    it('should throw when staticAccounts is empty', () => {\n        const staticAccounts: Address[] = [];\n        expect(() => getFeePayer(staticAccounts)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/__tests__/lifetime-constraint-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { AccountRole, Instruction } from '@solana/instructions';\nimport { Blockhash } from '@solana/rpc-types';\n\nimport { getLifetimeConstraint } from '../lifetime-constraint';\n\ndescribe('getLifetimeConstraint', () => {\n    describe('blockhash lifetime constraint', () => {\n        it('should return blockhash lifetime constraint when no instructions provided', () => {\n            const lifetimeToken = 'blockhash123' as Blockhash;\n            const instructions: Instruction[] = [];\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                blockhash: lifetimeToken,\n                lastValidBlockHeight: 2n ** 64n - 1n,\n            });\n        });\n\n        it('should return blockhash lifetime constraint when first instruction is not advance nonce', () => {\n            const lifetimeToken = 'blockhash456' as Blockhash;\n            const instructions: Instruction[] = [\n                {\n                    accounts: [{ address: 'account1' as Address, role: AccountRole.WRITABLE }],\n                    programAddress: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address,\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                blockhash: lifetimeToken,\n                lastValidBlockHeight: 2n ** 64n - 1n,\n            });\n        });\n\n        it('should use provided lastValidBlockHeight when given', () => {\n            const lifetimeToken = 'blockhash789' as Blockhash;\n            const instructions: Instruction[] = [];\n            const lastValidBlockHeight = 12345n;\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions, lastValidBlockHeight);\n\n            expect(constraint).toStrictEqual({\n                blockhash: lifetimeToken,\n                lastValidBlockHeight: 12345n,\n            });\n        });\n\n        it('should return blockhash when first instruction has wrong program address', () => {\n            const lifetimeToken = 'blockhash000' as Blockhash;\n            const instructions: Instruction[] = [\n                {\n                    accounts: [\n                        { address: 'nonce-account' as Address, role: AccountRole.WRITABLE },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                        { address: 'authority' as Address, role: AccountRole.READONLY_SIGNER },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: 'WrongProgram1111111111111111111111111111' as Address,\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                blockhash: lifetimeToken,\n                lastValidBlockHeight: 2n ** 64n - 1n,\n            });\n        });\n\n        it('should return blockhash when first instruction has wrong data', () => {\n            const lifetimeToken = 'blockhash111' as Blockhash;\n            const instructions = [\n                {\n                    accounts: [\n                        { address: 'nonce-account' as Address, role: AccountRole.WRITABLE },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                        { address: 'authority' as Address, role: AccountRole.READONLY_SIGNER },\n                    ],\n                    data: new Uint8Array([5, 0, 0, 0]),\n                    programAddress: '11111111111111111111111111111111' as Address, // wrong instruction discriminator\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                blockhash: lifetimeToken,\n                lastValidBlockHeight: 2n ** 64n - 1n,\n            });\n        });\n\n        it('should return blockhash when first instruction has wrong number of accounts', () => {\n            const lifetimeToken = 'blockhash222' as Blockhash;\n            const instructions = [\n                {\n                    accounts: [\n                        { address: 'nonce-account' as Address, role: AccountRole.WRITABLE },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: '11111111111111111111111111111111' as Address,\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                blockhash: lifetimeToken,\n                lastValidBlockHeight: 2n ** 64n - 1n,\n            });\n        });\n\n        it('should return blockhash when first instruction has no accounts', () => {\n            const lifetimeToken = 'blockhash-no-accounts' as Blockhash;\n            const instructions: Instruction[] = [\n                {\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: '11111111111111111111111111111111' as Address,\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                blockhash: lifetimeToken,\n                lastValidBlockHeight: 2n ** 64n - 1n,\n            });\n        });\n\n        it('should return blockhash when first instruction has no data', () => {\n            const lifetimeToken = 'blockhash-no-data' as Blockhash;\n            const instructions: Instruction[] = [\n                {\n                    accounts: [\n                        { address: 'nonce-account' as Address, role: AccountRole.WRITABLE },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                        { address: 'authority' as Address, role: AccountRole.READONLY_SIGNER },\n                    ],\n                    programAddress: '11111111111111111111111111111111' as Address,\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                blockhash: lifetimeToken,\n                lastValidBlockHeight: 2n ** 64n - 1n,\n            });\n        });\n    });\n\n    describe('nonce lifetime constraint', () => {\n        it('should return nonce lifetime constraint when first instruction is advance nonce with readonly signer', () => {\n            const lifetimeToken = 'nonce123';\n            const instructions = [\n                {\n                    accounts: [\n                        {\n                            address: '4wBqpZM9xaSheZzJSMawUHDgH36fBXoKrcna28MqTQF1' as Address,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: 'FYZJxv6E1UB1AZReeakjUZgnkYvsHxqPMVkDsjdbWs3L' as Address,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: '11111111111111111111111111111111' as Address,\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                nonce: lifetimeToken,\n                nonceAccountAddress: '4wBqpZM9xaSheZzJSMawUHDgH36fBXoKrcna28MqTQF1',\n                nonceAuthorityAddress: 'FYZJxv6E1UB1AZReeakjUZgnkYvsHxqPMVkDsjdbWs3L',\n            });\n        });\n\n        it('should return nonce lifetime constraint when first instruction is advance nonce with writable signer', () => {\n            const lifetimeToken = 'nonce456';\n            const instructions = [\n                {\n                    accounts: [\n                        {\n                            address: '8vCf5aVJkPzzkW34WFq9tHHVmgYMNzJf2jPKvv7YF5Ah' as Address,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: 'GZz8aVQBfN7wXT8F2vKvK4kZ5J1xYPaM3wQE4pqBv8Qj' as Address,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: '11111111111111111111111111111111' as Address,\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                nonce: lifetimeToken,\n                nonceAccountAddress: '8vCf5aVJkPzzkW34WFq9tHHVmgYMNzJf2jPKvv7YF5Ah',\n                nonceAuthorityAddress: 'GZz8aVQBfN7wXT8F2vKvK4kZ5J1xYPaM3wQE4pqBv8Qj',\n            });\n        });\n\n        it('should return nonce lifetime constraint even when lastValidBlockHeight is provided', () => {\n            const lifetimeToken = 'nonce789';\n            const instructions = [\n                {\n                    accounts: [\n                        {\n                            address: 'CsJmqbHTR5pY8CLH8TnQXh5rL2qp1fS9Y8wSVkv8pPWy' as Address,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: 'DnVsJPvU3iW9rJqbLbGxFdp4xVkLZKRLw8pnhqVkpN3H' as Address,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: '11111111111111111111111111111111' as Address,\n                },\n            ];\n            const lastValidBlockHeight = 99999n;\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions, lastValidBlockHeight);\n\n            expect(constraint).toStrictEqual({\n                nonce: lifetimeToken,\n                nonceAccountAddress: 'CsJmqbHTR5pY8CLH8TnQXh5rL2qp1fS9Y8wSVkv8pPWy',\n                nonceAuthorityAddress: 'DnVsJPvU3iW9rJqbLbGxFdp4xVkLZKRLw8pnhqVkpN3H',\n            });\n        });\n\n        it('should return nonce lifetime constraint when there are multiple instructions', () => {\n            const lifetimeToken = 'nonce000';\n            const instructions = [\n                {\n                    accounts: [\n                        {\n                            address: '2mGq8vz9Z3e3vQWaP9sPfYvYzrh8jrE1VQ4TH2wLFRp6' as Address,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: 'SysvarRecentB1ockHashes11111111111111111111' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: '7hBjZqWmR3JvE4QfxqKjvFZnkxqYpLCz4xJ9Fn8MTy2D' as Address,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: '11111111111111111111111111111111' as Address,\n                },\n                {\n                    accounts: [\n                        {\n                            address: '3pKvN2wV8qhLZjP6YfmR7qWJdkzVxH5RKLnfU9sQ2tY8' as Address,\n                            role: AccountRole.WRITABLE,\n                        },\n                    ],\n                    programAddress: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address,\n                },\n            ];\n\n            const constraint = getLifetimeConstraint(lifetimeToken, instructions);\n\n            expect(constraint).toStrictEqual({\n                nonce: lifetimeToken,\n                nonceAccountAddress: '2mGq8vz9Z3e3vQWaP9sPfYvYzrh8jrE1VQ4TH2wLFRp6',\n                nonceAuthorityAddress: '7hBjZqWmR3JvE4QfxqKjvFZnkxqYpLCz4xJ9Fn8MTy2D',\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/__tests__/message-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { AccountRole } from '@solana/instructions';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../../..';\nimport { Nonce } from '../../../durable-nonce';\nimport { decompileTransactionMessage } from '../message';\n\ndescribe('decompileTransactionMessage (legacy)', () => {\n    const U64_MAX = 2n ** 64n - 1n;\n    const feePayer = '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK' as Address;\n\n    describe('for a transaction with a blockhash lifetime', () => {\n        const blockhash = 'J4yED2jcMAHyQUg61DBmm4njmEydUr2WqrV9cdEcDDgL';\n\n        it('converts a legacy transaction with no instructions', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 0,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructions: [],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n\n            expect(transaction.version).toBe('legacy');\n            expect(transaction.feePayer.address).toBe(feePayer);\n            expect(transaction.lifetimeConstraint).toStrictEqual({\n                blockhash,\n                lastValidBlockHeight: U64_MAX,\n            });\n            expect(transaction.instructions).toStrictEqual([]);\n        });\n\n        it('freezes the blockhash lifetime constraint', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 0,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructions: [],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.lifetimeConstraint).toBeFrozenObject();\n        });\n\n        it('converts a transaction with one instruction with no accounts or data', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    programAddress,\n                },\n            ]);\n        });\n\n        it('converts a transaction with one instruction with accounts and data', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // 1 passed into instruction + 1 program\n                    numReadonlySignerAccounts: 1,\n                    numSignerAccounts: 3, // fee payer + 2 passed into instruction\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 2, 3, 4],\n                        data: new Uint8Array([0, 1, 2, 3, 4]),\n                        programAddressIndex: 5,\n                    },\n                ],\n                lifetimeToken: blockhash,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address,\n                    // read-only signers\n                    'G35QeFd4jpXWfRkuRKwn8g4vYrmn8DWJ5v88Kkpd8z1V' as Address,\n                    // writable non-signers\n                    '3LeBzRE9Yna5zi9R8vdT3MiNQYuEp4gJgVyhhwmqfCtd' as Address,\n                    // read-only non-signers\n                    '8kud9bpNvfemXYdTFjs5cZ8fZinBkx8JAnhVmRwJZk5e' as Address,\n                    programAddress,\n                ],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toHaveLength(1);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: 'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                        {\n                            address: 'G35QeFd4jpXWfRkuRKwn8g4vYrmn8DWJ5v88Kkpd8z1V' as Address,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                        {\n                            address: '3LeBzRE9Yna5zi9R8vdT3MiNQYuEp4gJgVyhhwmqfCtd' as Address,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: '8kud9bpNvfemXYdTFjs5cZ8fZinBkx8JAnhVmRwJZk5e' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    data: new Uint8Array([0, 1, 2, 3, 4]),\n                    programAddress,\n                },\n            ]);\n        });\n\n        it('freezes the instruction accounts', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // 1 passed into instruction + 1 program\n                    numReadonlySignerAccounts: 1,\n                    numSignerAccounts: 3, // fee payer + 2 passed into instruction\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 2, 3, 4],\n                        data: new Uint8Array([0, 1, 2, 3, 4]),\n                        programAddressIndex: 5,\n                    },\n                ],\n                lifetimeToken: blockhash,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address,\n                    // read-only signers\n                    'G35QeFd4jpXWfRkuRKwn8g4vYrmn8DWJ5v88Kkpd8z1V' as Address,\n                    // writable non-signers\n                    '3LeBzRE9Yna5zi9R8vdT3MiNQYuEp4gJgVyhhwmqfCtd' as Address,\n                    // read-only non-signers\n                    '8kud9bpNvfemXYdTFjs5cZ8fZinBkx8JAnhVmRwJZk5e' as Address,\n                    programAddress,\n                ],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0].accounts).toBeFrozenObject();\n        });\n\n        it('converts a transaction with multiple instructions', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 3, // 3 programs\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }, { programAddressIndex: 2 }, { programAddressIndex: 3 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [\n                    feePayer,\n                    '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                    'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                    'GJRYBLa6XpfswT1AN5tpGp8NHtUirwAdTPdSYXsW9L3S' as Address,\n                ],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    programAddress: '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                },\n                {\n                    programAddress: 'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                },\n                {\n                    programAddress: 'GJRYBLa6XpfswT1AN5tpGp8NHtUirwAdTPdSYXsW9L3S' as Address,\n                },\n            ]);\n        });\n\n        it('converts a transaction with a given lastValidBlockHeight', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 0,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructions: [],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction, { lastValidBlockHeight: 100n });\n            expect(transaction.lifetimeConstraint).toStrictEqual({\n                blockhash,\n                lastValidBlockHeight: 100n,\n            });\n        });\n\n        it('freezes the instructions within the transaction', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0]).toBeFrozenObject();\n        });\n    });\n\n    describe('for a transaction with a durable nonce lifetime', () => {\n        const nonce = '27kqzE1RifbyoFtibDRTjbnfZ894jsNpuR77JJkt3vgH' as Nonce;\n\n        // added as writable non-signer in the durable nonce instruction\n        const nonceAccountAddress = 'DhezFECsqmzuDxeuitFChbghTrwKLdsKdVsGArYbFEtm' as Address;\n\n        // added as read-only signer in the durable nonce instruction\n        const nonceAuthorityAddress = '2KntmCrnaf63tpNb8UMFFjFGGnYYAKQdmW9SbuCiRvhM' as Address;\n\n        const systemProgramAddress = '11111111111111111111111111111111' as Address;\n        const recentBlockhashesSysvarAddress = 'SysvarRecentB1ockHashes11111111111111111111' as Address;\n\n        it('converts a transaction with one instruction which is advance nonce (fee payer is nonce authority)', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // recent blockhashes sysvar, system program\n                    numReadonlySignerAccounts: 0, // nonce authority already added as fee payer\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same account\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            1, // nonce account address\n                            3, // recent blockhashes sysvar\n                            0, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 2,\n                    },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // no read-only signers\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: recentBlockhashesSysvarAddress,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: systemProgramAddress,\n                },\n            ]);\n            expect(transaction.feePayer.address).toBe(nonceAuthorityAddress);\n            expect(transaction.lifetimeConstraint).toStrictEqual({ nonce });\n        });\n\n        it('freezes the nonce lifetime constraint', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // recent blockhashes sysvar, system program\n                    numReadonlySignerAccounts: 0, // nonce authority already added as fee payer\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same account\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            1, // nonce account address\n                            3, // recent blockhashes sysvar\n                            0, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 2,\n                    },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // no read-only signers\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.lifetimeConstraint).toBeFrozenObject();\n        });\n\n        it('converts a transaction with one instruction which is advance nonce (fee payer is not nonce authority)', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // recent blockhashes sysvar, system program\n                    numReadonlySignerAccounts: 1, // nonce authority\n                    numSignerAccounts: 2, // fee payer, nonce authority\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            2, // nonce account address\n                            4, // recent blockhashes sysvar\n                            1, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 3,\n                    },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    // read-only signers\n                    nonceAuthorityAddress,\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: recentBlockhashesSysvarAddress,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: systemProgramAddress,\n                },\n            ]);\n            expect(transaction.feePayer.address).toBe(feePayer);\n        });\n\n        it('converts a durable nonce transaction with multiple instructions', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 4, // recent blockhashes sysvar, system program, 2 other program addresses\n                    numReadonlySignerAccounts: 0, // nonce authority already added as fee payer\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same account\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            1, // nonce account address\n                            3, // recent blockhashes sysvar\n                            0, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 2,\n                    },\n                    {\n                        accountIndices: [0, 1],\n                        data: new Uint8Array([1, 2, 3, 4]),\n                        programAddressIndex: 4,\n                    },\n                    { programAddressIndex: 5 },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // no read-only signers\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                    '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                    'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                ],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: recentBlockhashesSysvarAddress,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: systemProgramAddress,\n                },\n                {\n                    accounts: [\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                    ],\n                    data: new Uint8Array([1, 2, 3, 4]),\n                    programAddress: '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                },\n                {\n                    programAddress: 'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                },\n            ]);\n            expect(transaction.lifetimeConstraint).toStrictEqual({ nonce });\n        });\n\n        it('freezes the instructions within the transaction', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 'legacy' } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 4, // recent blockhashes sysvar, system program, 2 other program addresses\n                    numReadonlySignerAccounts: 0, // nonce authority already added as fee payer\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same account\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            1, // nonce account address\n                            3, // recent blockhashes sysvar\n                            0, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 2,\n                    },\n                    {\n                        accountIndices: [0, 1],\n                        data: new Uint8Array([1, 2, 3, 4]),\n                        programAddressIndex: 4,\n                    },\n                    { programAddressIndex: 5 },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // no read-only signers\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                    '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                    'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                ],\n                version: 'legacy',\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0]).toBeFrozenObject();\n            expect(transaction.instructions[1]).toBeFrozenObject();\n            expect(transaction.instructions[2]).toBeFrozenObject();\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/account-metas.ts",
    "content": "import { AccountMeta, AccountRole } from '@solana/instructions';\n\nimport { CompiledTransactionMessage } from '../..';\n\nexport function getAccountMetas(message: CompiledTransactionMessage): AccountMeta[] {\n    const { header } = message;\n    const numWritableSignerAccounts = header.numSignerAccounts - header.numReadonlySignerAccounts;\n    const numWritableNonSignerAccounts =\n        message.staticAccounts.length - header.numSignerAccounts - header.numReadonlyNonSignerAccounts;\n\n    const accountMetas: AccountMeta[] = [];\n\n    let accountIndex = 0;\n    for (let i = 0; i < numWritableSignerAccounts; i++) {\n        accountMetas.push({\n            address: message.staticAccounts[accountIndex],\n            role: AccountRole.WRITABLE_SIGNER,\n        });\n        accountIndex++;\n    }\n\n    for (let i = 0; i < header.numReadonlySignerAccounts; i++) {\n        accountMetas.push({\n            address: message.staticAccounts[accountIndex],\n            role: AccountRole.READONLY_SIGNER,\n        });\n        accountIndex++;\n    }\n\n    for (let i = 0; i < numWritableNonSignerAccounts; i++) {\n        accountMetas.push({\n            address: message.staticAccounts[accountIndex],\n            role: AccountRole.WRITABLE,\n        });\n        accountIndex++;\n    }\n\n    for (let i = 0; i < header.numReadonlyNonSignerAccounts; i++) {\n        accountMetas.push({\n            address: message.staticAccounts[accountIndex],\n            role: AccountRole.READONLY,\n        });\n        accountIndex++;\n    }\n\n    return accountMetas;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/convert-instruction.ts",
    "content": "import {\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountMeta, Instruction } from '@solana/instructions';\n\nimport { LegacyCompiledTransactionMessage } from '../../compile/legacy/message';\n\nfunction convertInstruction(\n    instruction: LegacyCompiledTransactionMessage['instructions'][number],\n    accountMetas: AccountMeta[],\n): Instruction {\n    const programAddress = accountMetas[instruction.programAddressIndex]?.address;\n    if (!programAddress) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {\n            index: instruction.programAddressIndex,\n        });\n    }\n\n    const accounts = instruction.accountIndices?.map(accountIndex => accountMetas[accountIndex]);\n    const { data } = instruction;\n\n    return Object.freeze({\n        programAddress,\n        ...(accounts && accounts.length ? { accounts: Object.freeze(accounts) } : {}),\n        ...(data && data.length ? { data } : {}),\n    });\n}\n\nexport function convertInstructions(\n    instructions: LegacyCompiledTransactionMessage['instructions'],\n    accountMetas: AccountMeta[],\n): Instruction[] {\n    return instructions.map(instruction => convertInstruction(instruction, accountMetas));\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/fee-payer.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING, SolanaError } from '@solana/errors';\n\nimport { CompiledTransactionMessage } from '../..';\n\nexport function getFeePayer(staticAccounts: CompiledTransactionMessage['staticAccounts']) {\n    const feePayer = staticAccounts[0];\n    if (!feePayer) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_FEE_PAYER_MISSING);\n    }\n    return feePayer;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/lifetime-constraint.ts",
    "content": "import { assertIsAddress } from '@solana/addresses';\nimport { Instruction } from '@solana/instructions';\nimport { Blockhash } from '@solana/rpc-types';\n\nimport { BlockhashLifetimeConstraint } from '../../blockhash';\nimport { Nonce, setTransactionMessageLifetimeUsingDurableNonce } from '../../durable-nonce';\nimport { isAdvanceNonceAccountInstruction } from '../../durable-nonce-instruction';\n\ntype LifetimeConstraint =\n    | BlockhashLifetimeConstraint\n    | Parameters<typeof setTransactionMessageLifetimeUsingDurableNonce>[0];\n\nexport function getLifetimeConstraint(\n    messageLifetimeToken: string,\n    instructions: Instruction[],\n    lastValidBlockHeight?: bigint,\n): LifetimeConstraint {\n    const firstInstruction = instructions[0];\n    if (!firstInstruction || !isAdvanceNonceAccountInstruction(firstInstruction)) {\n        // first instruction is not advance durable nonce, so use blockhash lifetime constraint\n        return {\n            blockhash: messageLifetimeToken as Blockhash,\n            lastValidBlockHeight: lastValidBlockHeight ?? 2n ** 64n - 1n, // U64 MAX\n        };\n    } else {\n        // We know these accounts are defined because we checked `isAdvanceNonceAccountInstruction`\n        const nonceAccountAddress = firstInstruction.accounts[0].address;\n        assertIsAddress(nonceAccountAddress);\n\n        const nonceAuthorityAddress = firstInstruction.accounts[2].address;\n        assertIsAddress(nonceAuthorityAddress);\n\n        return {\n            nonce: messageLifetimeToken as Nonce,\n            nonceAccountAddress,\n            nonceAuthorityAddress,\n        };\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/legacy/message.ts",
    "content": "import { pipe } from '@solana/functional';\n\nimport {\n    appendTransactionMessageInstructions,\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    createTransactionMessage,\n    setTransactionMessageLifetimeUsingBlockhash,\n    setTransactionMessageLifetimeUsingDurableNonce,\n} from '../..';\nimport { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../../fee-payer';\nimport { TransactionMessageWithLifetime } from '../../lifetime';\nimport { TransactionMessage } from '../../transaction-message';\nimport { getAccountMetas } from './account-metas';\nimport { convertInstructions } from './convert-instruction';\nimport { getFeePayer } from './fee-payer';\nimport { getLifetimeConstraint } from './lifetime-constraint';\n\nexport function decompileTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage &\n        CompiledTransactionMessageWithLifetime & { version: 'legacy' },\n    config?: {\n        lastValidBlockHeight?: bigint;\n    },\n): TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime & { version: 'legacy' } {\n    const feePayer = getFeePayer(compiledTransactionMessage.staticAccounts);\n    const accountMetas = getAccountMetas(compiledTransactionMessage);\n    const instructions = convertInstructions(compiledTransactionMessage.instructions, accountMetas);\n    const lifetimeConstraint = getLifetimeConstraint(\n        compiledTransactionMessage.lifetimeToken,\n        instructions,\n        config?.lastValidBlockHeight,\n    );\n\n    return pipe(\n        createTransactionMessage({ version: 'legacy' }),\n        m => setTransactionMessageFeePayer(feePayer, m),\n        m => appendTransactionMessageInstructions(instructions, m),\n        m =>\n            'blockhash' in lifetimeConstraint\n                ? setTransactionMessageLifetimeUsingBlockhash(lifetimeConstraint, m)\n                : setTransactionMessageLifetimeUsingDurableNonce(lifetimeConstraint, m),\n    );\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/message.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, SolanaError } from '@solana/errors';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '..';\nimport { AddressesByLookupTableAddress } from '../addresses-by-lookup-table-address';\nimport { TransactionMessageWithFeePayer } from '../fee-payer';\nimport { TransactionMessageWithLifetime } from '../lifetime';\nimport { TransactionMessage } from '../transaction-message';\nimport { decompileTransactionMessage as decompileLegacyTransactionMessage } from './legacy/message';\nimport { decompileTransactionMessage as decompileV0TransactionMessage } from './v0/message';\nimport { decompileTransactionMessage as decompileV1TransactionMessage } from './v1/message';\n\nexport type DecompileTransactionMessageConfig = {\n    /**\n     * Only used for V0 transactions. If the compiled message loads addresses from one or more\n     * address lookup tables, you will have to supply a map of those tables to an array of\n     * the addresses they contained at the time that the transaction message was constructed.\n     *\n     * @see {@link decompileTransactionMessageFetchingLookupTables} if you do not already have this.\n     */\n    addressesByLookupTableAddress?: AddressesByLookupTableAddress;\n    /**\n     * If the compiled message has a blockhash-based lifetime constraint, you will have to supply\n     * the block height after which that blockhash is no longer valid for use as a lifetime\n     * constraint.\n     */\n    lastValidBlockHeight?: bigint;\n};\n\n/**\n * Converts the type of transaction message data structure appropriate for execution on the network\n * to the type of transaction message data structure designed for use in your application.\n *\n * Because compilation is a lossy process, you can not fully reconstruct a source message from a\n * compiled message without extra information. In order to faithfully reconstruct the original\n * source message you will need to supply supporting details about the lifetime constraint and the\n * concrete addresses of any accounts sourced from account lookup tables (for v0 transactions).\n *\n * @see {@link compileTransactionMessage}\n */\nexport function decompileTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage &\n        CompiledTransactionMessageWithLifetime & { version: 'legacy' },\n    config?: DecompileTransactionMessageConfig,\n): TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime & { version: 'legacy' };\nexport function decompileTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime & { version: 0 },\n    config?: DecompileTransactionMessageConfig,\n): TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime & { version: 0 };\nexport function decompileTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime & { version: 1 },\n    config?: DecompileTransactionMessageConfig,\n): TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime & { version: 1 };\nexport function decompileTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime,\n    config?: DecompileTransactionMessageConfig,\n): TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime;\nexport function decompileTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime,\n    config?: DecompileTransactionMessageConfig,\n): TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime {\n    const version = compiledTransactionMessage.version;\n\n    if (version === 'legacy') {\n        return decompileLegacyTransactionMessage(compiledTransactionMessage, config);\n    } else if (version === 0) {\n        return decompileV0TransactionMessage(compiledTransactionMessage, config);\n    } else if (version === 1) {\n        return decompileV1TransactionMessage(compiledTransactionMessage, config);\n    } else {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n            version,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v0/__tests__/address-lookup-metas-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\n\nimport { AddressesByLookupTableAddress } from '../../../addresses-by-lookup-table-address';\nimport { getAddressLookupMetas } from '../address-lookup-metas';\n\ndescribe('getAddressLookupMetas', () => {\n    const lookupTableAddress1 = '9wnrQTq5MKhYfp379pKvpy1PvRyteseQmKv4Bw3uQrUw' as Address;\n    const lookupTableAddress2 = 'GS7Rphk6CZLoCGbTcbRaPZzD3k4ZK8XiA5BAj89Fi2Eg' as Address;\n\n    describe('for a single lookup table', () => {\n        it('should return readonly account lookup metas for a single index', () => {\n            const addressInLookup = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: addressInLookup,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.READONLY,\n                },\n            ]);\n        });\n\n        it('should return readonly account lookup metas for multiple indexes', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const addressInLookup2 = '5g6b4v8ivF7haRWMUXT1aewBGsc8xY7B6efGadNc3xYk' as Address;\n            const addressInLookup3 = 'HAv2PXRjwr4AL1odpoMNfvsw6bWxjDzURy1nPA6QBhDj' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0, 2],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1, addressInLookup3, addressInLookup2],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: addressInLookup1,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.READONLY,\n                },\n                {\n                    address: addressInLookup2,\n                    addressIndex: 2,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.READONLY,\n                },\n            ]);\n        });\n\n        it('should return writable account lookup metas for a single index', () => {\n            const addressInLookup = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [],\n                    writableIndexes: [0],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: addressInLookup,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.WRITABLE,\n                },\n            ]);\n        });\n\n        it('should return writable account lookup metas for multiple indexes', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const addressInLookup2 = '5g6b4v8ivF7haRWMUXT1aewBGsc8xY7B6efGadNc3xYk' as Address;\n            const addressInLookup3 = 'HAv2PXRjwr4AL1odpoMNfvsw6bWxjDzURy1nPA6QBhDj' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [],\n                    writableIndexes: [0, 2],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1, addressInLookup3, addressInLookup2],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: addressInLookup1,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: addressInLookup2,\n                    addressIndex: 2,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.WRITABLE,\n                },\n            ]);\n        });\n\n        it('should return writable metas first, then readonly metas', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const addressInLookup2 = '5g6b4v8ivF7haRWMUXT1aewBGsc8xY7B6efGadNc3xYk' as Address;\n            const addressInLookup3 = 'HAv2PXRjwr4AL1odpoMNfvsw6bWxjDzURy1nPA6QBhDj' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [2],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1, addressInLookup3, addressInLookup2],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: addressInLookup2,\n                    addressIndex: 2,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: addressInLookup1,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.READONLY,\n                },\n            ]);\n        });\n\n        it('should return empty array when no indexes are provided', () => {\n            const addressInLookup = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([]);\n        });\n    });\n\n    describe('for multiple lookup tables', () => {\n        it('should return readonly account lookup metas from multiple tables', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const addressInLookup2 = 'E7p56hzZZEs9vJ1yjxAFjhUP3fN2UJNk2nWvcY7Hz3ee' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n                {\n                    lookupTableAddress: lookupTableAddress2,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1],\n                [lookupTableAddress2]: [addressInLookup2],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: addressInLookup1,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.READONLY,\n                },\n                {\n                    address: addressInLookup2,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress2,\n                    role: AccountRole.READONLY,\n                },\n            ]);\n        });\n\n        it('should return writable account lookup metas from multiple tables', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const addressInLookup2 = 'E7p56hzZZEs9vJ1yjxAFjhUP3fN2UJNk2nWvcY7Hz3ee' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [],\n                    writableIndexes: [0],\n                },\n                {\n                    lookupTableAddress: lookupTableAddress2,\n                    readonlyIndexes: [],\n                    writableIndexes: [0],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1],\n                [lookupTableAddress2]: [addressInLookup2],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: addressInLookup1,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: addressInLookup2,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress2,\n                    role: AccountRole.WRITABLE,\n                },\n            ]);\n        });\n\n        it('should return writable metas first across all lookup tables', () => {\n            const readonlyAddressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const readonlyAddressInLookup2 = 'E7p56hzZZEs9vJ1yjxAFjhUP3fN2UJNk2nWvcY7Hz3ee' as Address;\n            const writableAddressInLookup1 = 'FgNrG1D7AoqNJuLc5eqmsXSHWta6Tfu41mQ9dgc5yaXo' as Address;\n            const writableAddressInLookup2 = '9jEBzMuJfwWH1qcG4g1bj24iSLGCmTsedgisui7SVHes' as Address;\n\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [1],\n                },\n                {\n                    lookupTableAddress: lookupTableAddress2,\n                    readonlyIndexes: [0],\n                    writableIndexes: [1],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [readonlyAddressInLookup1, writableAddressInLookup1],\n                [lookupTableAddress2]: [readonlyAddressInLookup2, writableAddressInLookup2],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: writableAddressInLookup1,\n                    addressIndex: 1,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: writableAddressInLookup2,\n                    addressIndex: 1,\n                    lookupTableAddress: lookupTableAddress2,\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: readonlyAddressInLookup1,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.READONLY,\n                },\n                {\n                    address: readonlyAddressInLookup2,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress2,\n                    role: AccountRole.READONLY,\n                },\n            ]);\n        });\n\n        it('should handle multiple indexes across multiple tables', () => {\n            const readonlyAddress1InLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const readonlyAddress2InLookup1 = 'HAv2PXRjwr4AL1odpoMNfvsw6bWxjDzURy1nPA6QBhDj' as Address;\n            const writableAddress1InLookup1 = 'FgNrG1D7AoqNJuLc5eqmsXSHWta6Tfu41mQ9dgc5yaXo' as Address;\n            const writableAddress2InLookup1 = '8kud9bpNvfemXYdTFjs5cZ8fZinBkx8JAnhVmRwJZk5e' as Address;\n\n            const readonlyAddressInLookup2 = 'E7p56hzZZEs9vJ1yjxAFjhUP3fN2UJNk2nWvcY7Hz3ee' as Address;\n            const writableAddressInLookup2 = '9jEBzMuJfwWH1qcG4g1bj24iSLGCmTsedgisui7SVHes' as Address;\n\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0, 3],\n                    writableIndexes: [1, 2],\n                },\n                {\n                    lookupTableAddress: lookupTableAddress2,\n                    readonlyIndexes: [0],\n                    writableIndexes: [1],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [\n                    readonlyAddress1InLookup1,\n                    writableAddress1InLookup1,\n                    writableAddress2InLookup1,\n                    readonlyAddress2InLookup1,\n                ],\n                [lookupTableAddress2]: [readonlyAddressInLookup2, writableAddressInLookup2],\n            };\n\n            const lookupMetas = getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress);\n\n            expect(lookupMetas).toStrictEqual([\n                {\n                    address: writableAddress1InLookup1,\n                    addressIndex: 1,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: writableAddress2InLookup1,\n                    addressIndex: 2,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: writableAddressInLookup2,\n                    addressIndex: 1,\n                    lookupTableAddress: lookupTableAddress2,\n                    role: AccountRole.WRITABLE,\n                },\n                {\n                    address: readonlyAddress1InLookup1,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.READONLY,\n                },\n                {\n                    address: readonlyAddress2InLookup1,\n                    addressIndex: 3,\n                    lookupTableAddress: lookupTableAddress1,\n                    role: AccountRole.READONLY,\n                },\n                {\n                    address: readonlyAddressInLookup2,\n                    addressIndex: 0,\n                    lookupTableAddress: lookupTableAddress2,\n                    role: AccountRole.READONLY,\n                },\n            ]);\n        });\n    });\n\n    describe('error cases', () => {\n        it('should throw when lookup table is not provided', () => {\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {};\n\n            expect(() => getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {\n                    lookupTableAddresses: [lookupTableAddress1],\n                }),\n            );\n        });\n\n        it('should throw when multiple lookup tables are not provided', () => {\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n                {\n                    lookupTableAddress: lookupTableAddress2,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {};\n\n            expect(() => getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {\n                    lookupTableAddresses: [lookupTableAddress1, lookupTableAddress2],\n                }),\n            );\n        });\n\n        it('should throw when one of multiple lookup tables is not provided', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n                {\n                    lookupTableAddress: lookupTableAddress2,\n                    readonlyIndexes: [0],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1],\n            };\n\n            expect(() => getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {\n                    lookupTableAddresses: [lookupTableAddress2],\n                }),\n            );\n        });\n\n        it('should throw when readonly index is out of range', () => {\n            const addressInLookup = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [1],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup],\n            };\n\n            expect(() => getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress)).toThrow(\n                new SolanaError(\n                    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n                    {\n                        highestKnownIndex: 0,\n                        highestRequestedIndex: 1,\n                        lookupTableAddress: lookupTableAddress1,\n                    },\n                ),\n            );\n        });\n\n        it('should throw when writable index is out of range', () => {\n            const addressInLookup = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [],\n                    writableIndexes: [1],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup],\n            };\n\n            expect(() => getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress)).toThrow(\n                new SolanaError(\n                    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n                    {\n                        highestKnownIndex: 0,\n                        highestRequestedIndex: 1,\n                        lookupTableAddress: lookupTableAddress1,\n                    },\n                ),\n            );\n        });\n\n        it('should throw when highest readonly index is out of range', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const addressInLookup2 = '5g6b4v8ivF7haRWMUXT1aewBGsc8xY7B6efGadNc3xYk' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0, 1, 5],\n                    writableIndexes: [],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1, addressInLookup2],\n            };\n\n            expect(() => getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress)).toThrow(\n                new SolanaError(\n                    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n                    {\n                        highestKnownIndex: 1,\n                        highestRequestedIndex: 5,\n                        lookupTableAddress: lookupTableAddress1,\n                    },\n                ),\n            );\n        });\n\n        it('should throw when highest writable index is out of range', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const addressInLookup2 = '5g6b4v8ivF7haRWMUXT1aewBGsc8xY7B6efGadNc3xYk' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [],\n                    writableIndexes: [0, 1, 5],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1, addressInLookup2],\n            };\n\n            expect(() => getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress)).toThrow(\n                new SolanaError(\n                    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n                    {\n                        highestKnownIndex: 1,\n                        highestRequestedIndex: 5,\n                        lookupTableAddress: lookupTableAddress1,\n                    },\n                ),\n            );\n        });\n\n        it('should throw when index is out of range across mixed readonly and writable', () => {\n            const addressInLookup1 = 'F1Vc6AGoxXLwGB7QV8f4So3C5d8SXEk3KKGHxKGEJ8qn' as Address;\n            const addressInLookup2 = '5g6b4v8ivF7haRWMUXT1aewBGsc8xY7B6efGadNc3xYk' as Address;\n            const compiledAddressTableLookups = [\n                {\n                    lookupTableAddress: lookupTableAddress1,\n                    readonlyIndexes: [0],\n                    writableIndexes: [3],\n                },\n            ];\n            const addressesByLookupTableAddress: AddressesByLookupTableAddress = {\n                [lookupTableAddress1]: [addressInLookup1, addressInLookup2],\n            };\n\n            expect(() => getAddressLookupMetas(compiledAddressTableLookups, addressesByLookupTableAddress)).toThrow(\n                new SolanaError(\n                    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n                    {\n                        highestKnownIndex: 1,\n                        highestRequestedIndex: 3,\n                        lookupTableAddress: lookupTableAddress1,\n                    },\n                ),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v0/__tests__/message-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../../..';\nimport { Nonce } from '../../../durable-nonce';\nimport { decompileTransactionMessage } from '../message';\n\ndescribe('decompileTransactionMessage (v0)', () => {\n    const U64_MAX = 2n ** 64n - 1n;\n    const feePayer = '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK' as Address;\n\n    describe('for a transaction with a blockhash lifetime', () => {\n        const blockhash = 'J4yED2jcMAHyQUg61DBmm4njmEydUr2WqrV9cdEcDDgL';\n\n        it('converts a v0 transaction with no instructions', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 0,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructions: [],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n\n            expect(transaction.version).toBe(0);\n            expect(transaction.feePayer.address).toBe(feePayer);\n            expect(transaction.lifetimeConstraint).toStrictEqual({\n                blockhash,\n                lastValidBlockHeight: U64_MAX,\n            });\n            expect(transaction.instructions).toStrictEqual([]);\n        });\n\n        it('freezes the blockhash lifetime constraint', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 0,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructions: [],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.lifetimeConstraint).toBeFrozenObject();\n        });\n\n        it('converts a transaction with one instruction with no accounts or data', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    programAddress,\n                },\n            ]);\n        });\n\n        it('converts a transaction with one instruction with accounts and data', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // 1 passed into instruction + 1 program\n                    numReadonlySignerAccounts: 1,\n                    numSignerAccounts: 3, // fee payer + 2 passed into instruction\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 2, 3, 4],\n                        data: new Uint8Array([0, 1, 2, 3, 4]),\n                        programAddressIndex: 5,\n                    },\n                ],\n                lifetimeToken: blockhash,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address,\n                    // read-only signers\n                    'G35QeFd4jpXWfRkuRKwn8g4vYrmn8DWJ5v88Kkpd8z1V' as Address,\n                    // writable non-signers\n                    '3LeBzRE9Yna5zi9R8vdT3MiNQYuEp4gJgVyhhwmqfCtd' as Address,\n                    // read-only non-signers\n                    '8kud9bpNvfemXYdTFjs5cZ8fZinBkx8JAnhVmRwJZk5e' as Address,\n                    programAddress,\n                ],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: 'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                        {\n                            address: 'G35QeFd4jpXWfRkuRKwn8g4vYrmn8DWJ5v88Kkpd8z1V' as Address,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                        {\n                            address: '3LeBzRE9Yna5zi9R8vdT3MiNQYuEp4gJgVyhhwmqfCtd' as Address,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: '8kud9bpNvfemXYdTFjs5cZ8fZinBkx8JAnhVmRwJZk5e' as Address,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    data: new Uint8Array([0, 1, 2, 3, 4]),\n                    programAddress,\n                },\n            ]);\n        });\n\n        it('freezes the instruction accounts', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // 1 passed into instruction + 1 program\n                    numReadonlySignerAccounts: 1,\n                    numSignerAccounts: 3, // fee payer + 2 passed into instruction\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 2, 3, 4],\n                        data: new Uint8Array([0, 1, 2, 3, 4]),\n                        programAddressIndex: 5,\n                    },\n                ],\n                lifetimeToken: blockhash,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address,\n                    // read-only signers\n                    'G35QeFd4jpXWfRkuRKwn8g4vYrmn8DWJ5v88Kkpd8z1V' as Address,\n                    // writable non-signers\n                    '3LeBzRE9Yna5zi9R8vdT3MiNQYuEp4gJgVyhhwmqfCtd' as Address,\n                    // read-only non-signers\n                    '8kud9bpNvfemXYdTFjs5cZ8fZinBkx8JAnhVmRwJZk5e' as Address,\n                    programAddress,\n                ],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0].accounts).toBeFrozenObject();\n        });\n\n        it('converts a transaction with multiple instructions', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 3, // 3 programs\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }, { programAddressIndex: 2 }, { programAddressIndex: 3 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [\n                    feePayer,\n                    '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                    'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                    'GJRYBLa6XpfswT1AN5tpGp8NHtUirwAdTPdSYXsW9L3S' as Address,\n                ],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    programAddress: '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                },\n                {\n                    programAddress: 'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                },\n                {\n                    programAddress: 'GJRYBLa6XpfswT1AN5tpGp8NHtUirwAdTPdSYXsW9L3S' as Address,\n                },\n            ]);\n        });\n\n        it('converts a transaction with a given lastValidBlockHeight', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 0,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructions: [],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction, { lastValidBlockHeight: 100n });\n            expect(transaction.lifetimeConstraint).toStrictEqual({\n                blockhash,\n                lastValidBlockHeight: 100n,\n            });\n        });\n\n        it('freezes the instructions within the transaction', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0]).toBeFrozenObject();\n        });\n    });\n\n    describe('for a transaction with a durable nonce lifetime', () => {\n        const nonce = '27kqzE1RifbyoFtibDRTjbnfZ894jsNpuR77JJkt3vgH' as Nonce;\n\n        // added as writable non-signer in the durable nonce instruction\n        const nonceAccountAddress = 'DhezFECsqmzuDxeuitFChbghTrwKLdsKdVsGArYbFEtm' as Address;\n\n        // added as read-only signer in the durable nonce instruction\n        const nonceAuthorityAddress = '2KntmCrnaf63tpNb8UMFFjFGGnYYAKQdmW9SbuCiRvhM' as Address;\n\n        const systemProgramAddress = '11111111111111111111111111111111' as Address;\n        const recentBlockhashesSysvarAddress = 'SysvarRecentB1ockHashes11111111111111111111' as Address;\n\n        it('converts a transaction with one instruction which is advance nonce (fee payer is nonce authority)', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // recent blockhashes sysvar, system program\n                    numReadonlySignerAccounts: 0, // nonce authority already added as fee payer\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same account\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            1, // nonce account address\n                            3, // recent blockhashes sysvar\n                            0, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 2,\n                    },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // no read-only signers\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: recentBlockhashesSysvarAddress,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: systemProgramAddress,\n                },\n            ]);\n            expect(transaction.feePayer.address).toBe(nonceAuthorityAddress);\n            expect(transaction.lifetimeConstraint).toStrictEqual({ nonce });\n        });\n\n        it('freezes the nonce lifetime constraint', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // recent blockhashes sysvar, system program\n                    numReadonlySignerAccounts: 0, // nonce authority already added as fee payer\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same account\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            1, // nonce account address\n                            3, // recent blockhashes sysvar\n                            0, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 2,\n                    },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // no read-only signers\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.lifetimeConstraint).toBeFrozenObject();\n        });\n\n        it('converts a transaction with one instruction which is advance nonce (fee payer is not nonce authority)', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // recent blockhashes sysvar, system program\n                    numReadonlySignerAccounts: 1, // nonce authority\n                    numSignerAccounts: 2, // fee payer, nonce authority\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            2, // nonce account address\n                            4, // recent blockhashes sysvar\n                            1, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 3,\n                    },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    // read-only signers\n                    nonceAuthorityAddress,\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: recentBlockhashesSysvarAddress,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: systemProgramAddress,\n                },\n            ]);\n            expect(transaction.feePayer.address).toBe(feePayer);\n        });\n\n        it('converts a durable nonce transaction with multiple instructions', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 4, // recent blockhashes sysvar, system program, 2 other program addresses\n                    numReadonlySignerAccounts: 0, // nonce authority already added as fee payer\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same account\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            1, // nonce account address\n                            3, // recent blockhashes sysvar\n                            0, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 2,\n                    },\n                    {\n                        accountIndices: [0, 1],\n                        data: new Uint8Array([1, 2, 3, 4]),\n                        programAddressIndex: 4,\n                    },\n                    { programAddressIndex: 5 },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // no read-only signers\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                    '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                    'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                ],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: recentBlockhashesSysvarAddress,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: systemProgramAddress,\n                },\n                {\n                    accounts: [\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                    ],\n                    data: new Uint8Array([1, 2, 3, 4]),\n                    programAddress: '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                },\n                {\n                    programAddress: 'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                },\n            ]);\n            expect(transaction.lifetimeConstraint).toStrictEqual({ nonce });\n        });\n\n        it('freezes the instructions within the transaction', () => {\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & { version: 0 } = {\n                header: {\n                    numReadonlyNonSignerAccounts: 4, // recent blockhashes sysvar, system program, 2 other program addresses\n                    numReadonlySignerAccounts: 0, // nonce authority already added as fee payer\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same account\n                },\n                instructions: [\n                    {\n                        accountIndices: [\n                            1, // nonce account address\n                            3, // recent blockhashes sysvar\n                            0, // nonce authority address\n                        ],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 2,\n                    },\n                    {\n                        accountIndices: [0, 1],\n                        data: new Uint8Array([1, 2, 3, 4]),\n                        programAddressIndex: 4,\n                    },\n                    { programAddressIndex: 5 },\n                ],\n                lifetimeToken: nonce,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // no read-only signers\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // read-only non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                    '3hpECiFPtnyxoWqWqcVyfBUDhPKSZXWDduNXFywo8ncP' as Address,\n                    'Cmqw16pVQvmW1b7Ek1ioQ5Ggf1PaoXi5XxsK9iVSbRKC' as Address,\n                ],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0]).toBeFrozenObject();\n            expect(transaction.instructions[1]).toBeFrozenObject();\n            expect(transaction.instructions[2]).toBeFrozenObject();\n        });\n    });\n\n    describe('for a transaction with address lookup tables', () => {\n        const blockhash = 'J4yED2jcMAHyQUg61DBmm4njmEydUr2WqrV9cdEcDDgL';\n        const lookupTableAddress = 'FwR5Cu5b5zXHa5KHuGQkN7UhSNebc756N1EhR2aHHLHq' as Address;\n\n        it('converts a transaction with accounts from a lookup table', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n            const lookupAccount1 = '9fhzQgdY7y7TpYHvH4sVBjJRzgq2LbqNq7hPvWvKAzWz' as Address;\n            const lookupAccount2 = 'BqN3g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & {\n                    addressTableLookups: readonly {\n                        lookupTableAddress: Address;\n                        readonlyIndexes: readonly number[];\n                        writableIndexes: readonly number[];\n                    }[];\n                    version: 0;\n                } = {\n                addressTableLookups: [\n                    {\n                        lookupTableAddress,\n                        readonlyIndexes: [1],\n                        writableIndexes: [0],\n                    },\n                ],\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [\n                    {\n                        accountIndices: [2, 3], // indexes 2 and 3 reference lookup table accounts\n                        programAddressIndex: 1,\n                    },\n                ],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction, {\n                addressesByLookupTableAddress: {\n                    [lookupTableAddress]: [lookupAccount1, lookupAccount2],\n                },\n            });\n\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: lookupAccount1,\n                            addressIndex: 0,\n                            lookupTableAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: lookupAccount2,\n                            addressIndex: 1,\n                            lookupTableAddress,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    programAddress,\n                },\n            ]);\n        });\n\n        it('converts a transaction with both static and lookup table accounts', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n            const staticAccount = 'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address;\n            const lookupAccount = '9fhzQgdY7y7TpYHvH4sVBjJRzgq2LbqNq7hPvWvKAzWz' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & {\n                    addressTableLookups: readonly {\n                        lookupTableAddress: Address;\n                        readonlyIndexes: readonly number[];\n                        writableIndexes: readonly number[];\n                    }[];\n                    version: 0;\n                } = {\n                addressTableLookups: [\n                    {\n                        lookupTableAddress,\n                        readonlyIndexes: [0],\n                        writableIndexes: [],\n                    },\n                ],\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 2, // fee payer + static account\n                },\n                instructions: [\n                    {\n                        accountIndices: [1, 3], // index 1 is static, index 3 is from lookup table\n                        programAddressIndex: 2,\n                    },\n                ],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, staticAccount, programAddress],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction, {\n                addressesByLookupTableAddress: {\n                    [lookupTableAddress]: [lookupAccount],\n                },\n            });\n\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: staticAccount,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                        {\n                            address: lookupAccount,\n                            addressIndex: 0,\n                            lookupTableAddress,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    programAddress,\n                },\n            ]);\n        });\n\n        it('converts a transaction with multiple lookup tables', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n            const lookupTableAddress2 = '8qN8g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7' as Address;\n            const lookupAccount1 = '9fhzQgdY7y7TpYHvH4sVBjJRzgq2LbqNq7hPvWvKAzWz' as Address;\n            const lookupAccount2 = 'BqN3g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7g7' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & {\n                    addressTableLookups: readonly {\n                        lookupTableAddress: Address;\n                        readonlyIndexes: readonly number[];\n                        writableIndexes: readonly number[];\n                    }[];\n                    version: 0;\n                } = {\n                addressTableLookups: [\n                    {\n                        lookupTableAddress,\n                        readonlyIndexes: [0],\n                        writableIndexes: [],\n                    },\n                    {\n                        lookupTableAddress: lookupTableAddress2,\n                        readonlyIndexes: [],\n                        writableIndexes: [0],\n                    },\n                ],\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [\n                    {\n                        accountIndices: [2, 3], // indexes from two different lookup tables\n                        programAddressIndex: 1,\n                    },\n                ],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction, {\n                addressesByLookupTableAddress: {\n                    [lookupTableAddress]: [lookupAccount1],\n                    [lookupTableAddress2]: [lookupAccount2],\n                },\n            });\n\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: lookupAccount2,\n                            addressIndex: 0,\n                            lookupTableAddress: lookupTableAddress2,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: lookupAccount1,\n                            addressIndex: 0,\n                            lookupTableAddress,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    programAddress,\n                },\n            ]);\n        });\n\n        it('converts a transaction with empty address table lookups array', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & {\n                    addressTableLookups: readonly {\n                        lookupTableAddress: Address;\n                        readonlyIndexes: readonly number[];\n                        writableIndexes: readonly number[];\n                    }[];\n                    version: 0;\n                } = {\n                addressTableLookups: [],\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 0,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    programAddress,\n                },\n            ]);\n        });\n\n        it('throws when address lookup table content is missing', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & {\n                    addressTableLookups: readonly {\n                        lookupTableAddress: Address;\n                        readonlyIndexes: readonly number[];\n                        writableIndexes: readonly number[];\n                    }[];\n                    version: 0;\n                } = {\n                addressTableLookups: [\n                    {\n                        lookupTableAddress,\n                        readonlyIndexes: [0],\n                        writableIndexes: [],\n                    },\n                ],\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 0,\n            };\n\n            expect(() => {\n                decompileTransactionMessage(compiledTransaction);\n            }).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {\n                    lookupTableAddresses: [lookupTableAddress],\n                }),\n            );\n        });\n\n        it('throws when address lookup table index is out of range', () => {\n            const programAddress = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n            const lookupAccount = '9fhzQgdY7y7TpYHvH4sVBjJRzgq2LbqNq7hPvWvKAzWz' as Address;\n\n            const compiledTransaction: CompiledTransactionMessage &\n                CompiledTransactionMessageWithLifetime & {\n                    addressTableLookups: readonly {\n                        lookupTableAddress: Address;\n                        readonlyIndexes: readonly number[];\n                        writableIndexes: readonly number[];\n                    }[];\n                    version: 0;\n                } = {\n                addressTableLookups: [\n                    {\n                        lookupTableAddress,\n                        readonlyIndexes: [5], // index 5 is out of range (only 1 account in lookup table)\n                        writableIndexes: [],\n                    },\n                ],\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructions: [{ programAddressIndex: 1 }],\n                lifetimeToken: blockhash,\n                staticAccounts: [feePayer, programAddress],\n                version: 0,\n            };\n\n            expect(() => {\n                decompileTransactionMessage(compiledTransaction, {\n                    addressesByLookupTableAddress: {\n                        [lookupTableAddress]: [lookupAccount],\n                    },\n                });\n            }).toThrow(\n                new SolanaError(\n                    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n                    {\n                        highestKnownIndex: 0,\n                        highestRequestedIndex: 5,\n                        lookupTableAddress,\n                    },\n                ),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v0/address-lookup-metas.ts",
    "content": "import {\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING,\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountLookupMeta, AccountRole } from '@solana/instructions';\n\nimport { AddressesByLookupTableAddress } from '../../addresses-by-lookup-table-address';\nimport { getCompiledAddressTableLookups } from '../../compile/v0/address-table-lookups';\n\nexport function getAddressLookupMetas(\n    compiledAddressTableLookups: ReturnType<typeof getCompiledAddressTableLookups>,\n    addressesByLookupTableAddress: AddressesByLookupTableAddress,\n): AccountLookupMeta[] {\n    // check that all message lookups are known\n    const compiledAddressTableLookupAddresses = compiledAddressTableLookups.map(l => l.lookupTableAddress);\n    const missing = compiledAddressTableLookupAddresses.filter(a => addressesByLookupTableAddress[a] === undefined);\n    if (missing.length > 0) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_CONTENTS_MISSING, {\n            lookupTableAddresses: missing,\n        });\n    }\n\n    const readOnlyMetas: AccountLookupMeta[] = [];\n    const writableMetas: AccountLookupMeta[] = [];\n\n    // we know that for each lookup, knownLookups[lookup.lookupTableAddress] is defined\n    for (const lookup of compiledAddressTableLookups) {\n        const addresses = addressesByLookupTableAddress[lookup.lookupTableAddress];\n        const readonlyIndexes = lookup.readonlyIndexes;\n        const writableIndexes = lookup.writableIndexes;\n\n        const highestIndex = Math.max(...readonlyIndexes, ...writableIndexes);\n        if (highestIndex >= addresses.length) {\n            throw new SolanaError(\n                SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_ADDRESS_LOOKUP_TABLE_INDEX_OUT_OF_RANGE,\n                {\n                    highestKnownIndex: addresses.length - 1,\n                    highestRequestedIndex: highestIndex,\n                    lookupTableAddress: lookup.lookupTableAddress,\n                },\n            );\n        }\n\n        const readOnlyForLookup: AccountLookupMeta[] = readonlyIndexes.map(r => ({\n            address: addresses[r],\n            addressIndex: r,\n            lookupTableAddress: lookup.lookupTableAddress,\n            role: AccountRole.READONLY,\n        }));\n        readOnlyMetas.push(...readOnlyForLookup);\n\n        const writableForLookup: AccountLookupMeta[] = writableIndexes.map(w => ({\n            address: addresses[w],\n            addressIndex: w,\n            lookupTableAddress: lookup.lookupTableAddress,\n            role: AccountRole.WRITABLE,\n        }));\n        writableMetas.push(...writableForLookup);\n    }\n\n    return [...writableMetas, ...readOnlyMetas];\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v0/message.ts",
    "content": "import { pipe } from '@solana/functional';\n\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../..';\nimport { AddressesByLookupTableAddress } from '../../addresses-by-lookup-table-address';\nimport { setTransactionMessageLifetimeUsingBlockhash } from '../../blockhash';\nimport { createTransactionMessage } from '../../create-transaction-message';\nimport { setTransactionMessageLifetimeUsingDurableNonce } from '../../durable-nonce';\nimport { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../../fee-payer';\nimport { appendTransactionMessageInstructions } from '../../instructions';\nimport { TransactionMessageWithLifetime } from '../../lifetime';\nimport { TransactionMessage } from '../../transaction-message';\nimport { getAccountMetas } from '../legacy/account-metas';\nimport { convertInstructions } from '../legacy/convert-instruction';\nimport { getFeePayer } from '../legacy/fee-payer';\nimport { getLifetimeConstraint } from '../legacy/lifetime-constraint';\nimport { getAddressLookupMetas } from './address-lookup-metas';\n\nexport type DecompileTransactionMessageConfig = {\n    addressesByLookupTableAddress?: AddressesByLookupTableAddress;\n    lastValidBlockHeight?: bigint;\n};\n\nexport function decompileTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime & { version: 0 },\n    config?: DecompileTransactionMessageConfig,\n): TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime {\n    const feePayer = getFeePayer(compiledTransactionMessage.staticAccounts);\n\n    const accountMetas = getAccountMetas(compiledTransactionMessage);\n    const accountLookupMetas =\n        'addressTableLookups' in compiledTransactionMessage &&\n        compiledTransactionMessage.addressTableLookups !== undefined &&\n        compiledTransactionMessage.addressTableLookups.length > 0\n            ? getAddressLookupMetas(\n                  compiledTransactionMessage.addressTableLookups,\n                  config?.addressesByLookupTableAddress ?? {},\n              )\n            : [];\n    const transactionMetas = [...accountMetas, ...accountLookupMetas];\n    const instructions = convertInstructions(compiledTransactionMessage.instructions, transactionMetas);\n\n    const lifetimeConstraint = getLifetimeConstraint(\n        compiledTransactionMessage.lifetimeToken,\n        instructions,\n        config?.lastValidBlockHeight,\n    );\n\n    return pipe(\n        createTransactionMessage({ version: 0 }),\n        m => setTransactionMessageFeePayer(feePayer, m),\n        m => appendTransactionMessageInstructions(instructions, m),\n        m =>\n            'blockhash' in lifetimeConstraint\n                ? setTransactionMessageLifetimeUsingBlockhash(lifetimeConstraint, m)\n                : setTransactionMessageLifetimeUsingDurableNonce(lifetimeConstraint, m),\n    ) as TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v1/__tests__/config-test.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND, SolanaError } from '@solana/errors';\n\nimport { CompiledTransactionConfigValue } from '../../../compile/v1/config';\nimport { decompileTransactionConfig } from '../config';\n\ndescribe('decompileTransactionConfig', () => {\n    const U64_MAX = 2n ** 64n - 1n;\n    const U32_MAX = 2 ** 32 - 1;\n\n    describe('individual config values', () => {\n        it('decompiles priority fee lamports only', () => {\n            const configMask = 0b11;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u64', value: 5_000n }];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                priorityFeeLamports: 5_000n,\n            });\n        });\n\n        it('decompiles compute unit limit only', () => {\n            const configMask = 0b100;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u32', value: 300_000 }];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                computeUnitLimit: 300000,\n            });\n        });\n\n        it('decompiles loaded accounts data size limit only', () => {\n            const configMask = 0b1000;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u32', value: 64_000 }];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                loadedAccountsDataSizeLimit: 64000,\n            });\n        });\n\n        it('decompiles heap size only', () => {\n            const configMask = 0b10000;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u32', value: 256_000 }];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                heapSize: 256000,\n            });\n        });\n    });\n\n    describe('multiple config values', () => {\n        it('decompiles priority fee and compute unit limit', () => {\n            const configMask = 0b111;\n            const configValues: CompiledTransactionConfigValue[] = [\n                { kind: 'u64', value: 5_000n },\n                { kind: 'u32', value: 300_000 },\n            ];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                computeUnitLimit: 300000,\n                priorityFeeLamports: 5_000n,\n            });\n        });\n\n        it('decompiles all u32 values without priority fee', () => {\n            const configMask = 0b11100;\n            const configValues: CompiledTransactionConfigValue[] = [\n                { kind: 'u32', value: 300_000 },\n                { kind: 'u32', value: 64_000 },\n                { kind: 'u32', value: 256_000 },\n            ];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                computeUnitLimit: 300000,\n                heapSize: 256000,\n                loadedAccountsDataSizeLimit: 64000,\n            });\n        });\n\n        it('decompiles non-contiguous config values', () => {\n            const configMask = 0b10011;\n            const configValues: CompiledTransactionConfigValue[] = [\n                { kind: 'u64', value: 5_000n },\n                { kind: 'u32', value: 256_000 },\n            ];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                heapSize: 256000,\n                priorityFeeLamports: 5_000n,\n            });\n        });\n    });\n\n    describe('all config values', () => {\n        it('decompiles all config values', () => {\n            const configMask = 0b11111;\n            const configValues: CompiledTransactionConfigValue[] = [\n                { kind: 'u64', value: 10_000n },\n                { kind: 'u32', value: 400_000 },\n                { kind: 'u32', value: 80_000 },\n                { kind: 'u32', value: 512_000 },\n            ];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                computeUnitLimit: 400_000,\n                heapSize: 512_000,\n                loadedAccountsDataSizeLimit: 80_000,\n                priorityFeeLamports: 10_000n,\n            });\n        });\n    });\n\n    describe('empty config', () => {\n        it('returns empty config object when mask is 0', () => {\n            const configMask = 0;\n            const configValues: CompiledTransactionConfigValue[] = [];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({});\n        });\n    });\n\n    describe('boundary values', () => {\n        it('handles maximum u64 priority fee', () => {\n            const configMask = 0b11;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u64', value: U64_MAX }];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                priorityFeeLamports: U64_MAX,\n            });\n        });\n\n        it('handles maximum u32 compute unit limit', () => {\n            const configMask = 0b100;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u32', value: U32_MAX }];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                computeUnitLimit: U32_MAX,\n            });\n        });\n\n        it('handles zero values', () => {\n            const configMask = 0b11111;\n            const configValues: CompiledTransactionConfigValue[] = [\n                { kind: 'u64', value: 0n },\n                { kind: 'u32', value: 0 },\n                { kind: 'u32', value: 0 },\n                { kind: 'u32', value: 0 },\n            ];\n\n            const config = decompileTransactionConfig(configMask, configValues);\n            expect(config).toStrictEqual({\n                computeUnitLimit: 0,\n                heapSize: 0,\n                loadedAccountsDataSizeLimit: 0,\n                priorityFeeLamports: 0n,\n            });\n        });\n    });\n\n    describe('type mismatch errors', () => {\n        it('throws when priority fee has u32 instead of u64', () => {\n            const configMask = 0b11;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u32', value: 5_000 }];\n\n            expect(() => decompileTransactionConfig(configMask, configValues)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND, {\n                    actualKind: 'u32',\n                    configName: 'priorityFeeLamports',\n                    expectedKind: 'u64',\n                }),\n            );\n        });\n\n        it('throws when compute unit limit has u64 instead of u32', () => {\n            const configMask = 0b100;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u64', value: 300_000n }];\n\n            expect(() => decompileTransactionConfig(configMask, configValues)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND, {\n                    actualKind: 'u64',\n                    configName: 'computeUnitLimit',\n                    expectedKind: 'u32',\n                }),\n            );\n        });\n\n        it('throws when loaded accounts data size limit has u64 instead of u32', () => {\n            const configMask = 0b1000;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u64', value: 64_000n }];\n\n            expect(() => decompileTransactionConfig(configMask, configValues)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND, {\n                    actualKind: 'u64',\n                    configName: 'loadedAccountsDataSizeLimit',\n                    expectedKind: 'u32',\n                }),\n            );\n        });\n\n        it('throws when heap size has u64 instead of u32', () => {\n            const configMask = 0b10000;\n            const configValues: CompiledTransactionConfigValue[] = [{ kind: 'u64', value: 256_000n }];\n\n            expect(() => decompileTransactionConfig(configMask, configValues)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND, {\n                    actualKind: 'u64',\n                    configName: 'heapSize',\n                    expectedKind: 'u32',\n                }),\n            );\n        });\n\n        it('throws on first type mismatch when multiple values present', () => {\n            const configMask = 0b111;\n            const configValues: CompiledTransactionConfigValue[] = [\n                { kind: 'u32', value: 5_000 },\n                { kind: 'u32', value: 300_000 },\n            ];\n\n            expect(() => decompileTransactionConfig(configMask, configValues)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND, {\n                    actualKind: 'u32',\n                    configName: 'priorityFeeLamports',\n                    expectedKind: 'u64',\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v1/__tests__/instructions-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountRole } from '@solana/instructions';\n\nimport { InstructionHeader, InstructionPayload } from '../../../compile/v1/instructions';\nimport { decompileInstructions } from '../instructions';\n\ndescribe('decompileInstructions', () => {\n    const account1 = '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK' as Address;\n    const account2 = 'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address;\n    const account3 = 'BPFLoaderUpgradeab1e11111111111111111111111' as Address;\n    const program1 = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n    const program2 = '11111111111111111111111111111111' as Address;\n    const program3 = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address;\n    const program4 = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL' as Address;\n\n    describe('single instruction', () => {\n        it('decompiles instruction with program address only', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 0,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [{ address: program1, role: AccountRole.READONLY }];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions).toStrictEqual([\n                {\n                    programAddress: program1,\n                },\n            ]);\n        });\n\n        it('decompiles instruction with program address and accounts', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 2,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 2,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [0, 1],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [\n                { address: account1, role: AccountRole.WRITABLE_SIGNER },\n                { address: account2, role: AccountRole.READONLY },\n                { address: program1, role: AccountRole.READONLY },\n            ];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions).toStrictEqual([\n                {\n                    accounts: [\n                        { address: account1, role: AccountRole.WRITABLE_SIGNER },\n                        { address: account2, role: AccountRole.READONLY },\n                    ],\n                    programAddress: program1,\n                },\n            ]);\n        });\n\n        it('decompiles instruction with program address and data', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 5,\n                    programAccountIndex: 0,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array([1, 2, 3, 4, 5]),\n                },\n            ];\n            const accountMetas = [{ address: program1, role: AccountRole.READONLY }];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions).toStrictEqual([\n                {\n                    data: new Uint8Array([1, 2, 3, 4, 5]),\n                    programAddress: program1,\n                },\n            ]);\n        });\n\n        it('decompiles instruction with all fields', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 3,\n                    numInstructionDataBytes: 4,\n                    programAccountIndex: 3,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [0, 1, 2],\n                    instructionData: new Uint8Array([0, 1, 2, 3]),\n                },\n            ];\n            const accountMetas = [\n                { address: account1, role: AccountRole.WRITABLE_SIGNER },\n                { address: account2, role: AccountRole.READONLY_SIGNER },\n                { address: account3, role: AccountRole.WRITABLE },\n                { address: program1, role: AccountRole.READONLY },\n            ];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions).toStrictEqual([\n                {\n                    accounts: [\n                        { address: account1, role: AccountRole.WRITABLE_SIGNER },\n                        { address: account2, role: AccountRole.READONLY_SIGNER },\n                        { address: account3, role: AccountRole.WRITABLE },\n                    ],\n                    data: new Uint8Array([0, 1, 2, 3]),\n                    programAddress: program1,\n                },\n            ]);\n        });\n\n        it('does not include accounts field when instructionAccountIndices is empty', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 0,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [{ address: program1, role: AccountRole.READONLY }];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions[0]).not.toHaveProperty('accounts');\n        });\n\n        it('does not include data field when instructionData is empty', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 0,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [{ address: program1, role: AccountRole.READONLY }];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions[0]).not.toHaveProperty('data');\n        });\n    });\n\n    describe('multiple instructions', () => {\n        it('decompiles multiple instructions with different patterns', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 1,\n                    programAccountIndex: 2,\n                },\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 1,\n                    programAccountIndex: 3,\n                },\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 4,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array([1]),\n                },\n                {\n                    instructionAccountIndices: [1],\n                    instructionData: new Uint8Array([2]),\n                },\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [\n                { address: account1, role: AccountRole.WRITABLE_SIGNER },\n                { address: account2, role: AccountRole.READONLY_SIGNER },\n                { address: program2, role: AccountRole.READONLY },\n                { address: program3, role: AccountRole.READONLY },\n                { address: program4, role: AccountRole.READONLY },\n            ];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions).toStrictEqual([\n                {\n                    accounts: [{ address: account1, role: AccountRole.WRITABLE_SIGNER }],\n                    data: new Uint8Array([1]),\n                    programAddress: program2,\n                },\n                {\n                    accounts: [{ address: account2, role: AccountRole.READONLY_SIGNER }],\n                    data: new Uint8Array([2]),\n                    programAddress: program3,\n                },\n                {\n                    programAddress: program4,\n                },\n            ]);\n        });\n\n        it('reuses account metas across instructions', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 1,\n                },\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 1,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array(),\n                },\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [\n                { address: account1, role: AccountRole.WRITABLE_SIGNER },\n                { address: program1, role: AccountRole.READONLY },\n            ];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n\n            expect(instructions[0].programAddress).toBe(instructions[1].programAddress);\n            expect(instructions[0].accounts?.[0]).toStrictEqual(instructions[1].accounts?.[0]);\n        });\n    });\n\n    describe('empty arrays', () => {\n        it('returns empty array when no instructions provided', () => {\n            const instructionHeaders: InstructionHeader[] = [];\n            const instructionPayloads: InstructionPayload[] = [];\n            const accountMetas = [{ address: account1, role: AccountRole.WRITABLE_SIGNER }];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions).toStrictEqual([]);\n        });\n    });\n\n    describe('immutability', () => {\n        it('freezes the returned instruction objects', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 1,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [\n                { address: account1, role: AccountRole.WRITABLE },\n                { address: program1, role: AccountRole.READONLY },\n            ];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions[0]).toBeFrozenObject();\n        });\n\n        it('freezes the accounts array within instructions', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 1,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 1,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [0],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [\n                { address: account1, role: AccountRole.WRITABLE },\n                { address: program1, role: AccountRole.READONLY },\n            ];\n\n            const instructions = decompileInstructions(instructionHeaders, instructionPayloads, accountMetas);\n            expect(instructions[0].accounts).toBeFrozenObject();\n        });\n    });\n\n    describe('error cases', () => {\n        it('throws when headers and payloads length mismatch with more headers', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 0,\n                },\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 0,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [{ address: program1, role: AccountRole.READONLY }];\n\n            expect(() => decompileInstructions(instructionHeaders, instructionPayloads, accountMetas)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH, {\n                    numInstructionHeaders: 2,\n                    numInstructionPayloads: 1,\n                }),\n            );\n        });\n\n        it('throws when headers and payloads length mismatch with more payloads', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 0,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [{ address: program1, role: AccountRole.READONLY }];\n\n            expect(() => decompileInstructions(instructionHeaders, instructionPayloads, accountMetas)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH, {\n                    numInstructionHeaders: 1,\n                    numInstructionPayloads: 2,\n                }),\n            );\n        });\n\n        it('throws when program address index is out of bounds', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: 5,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [{ address: account1, role: AccountRole.WRITABLE_SIGNER }];\n\n            expect(() => decompileInstructions(instructionHeaders, instructionPayloads, accountMetas)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {\n                    index: 5,\n                }),\n            );\n        });\n\n        it('throws when program address index is negative', () => {\n            const instructionHeaders: InstructionHeader[] = [\n                {\n                    numInstructionAccounts: 0,\n                    numInstructionDataBytes: 0,\n                    programAccountIndex: -1,\n                },\n            ];\n            const instructionPayloads: InstructionPayload[] = [\n                {\n                    instructionAccountIndices: [],\n                    instructionData: new Uint8Array(),\n                },\n            ];\n            const accountMetas = [{ address: account1, role: AccountRole.WRITABLE_SIGNER }];\n\n            expect(() => decompileInstructions(instructionHeaders, instructionPayloads, accountMetas)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {\n                    index: -1,\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v1/__tests__/message-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { AccountRole } from '@solana/instructions';\nimport { Blockhash } from '@solana/rpc-types';\n\nimport { CompiledTransactionMessageWithLifetime, V1CompiledTransactionMessage } from '../../../compile/message';\nimport { CompiledTransactionConfigValue } from '../../../compile/v1/config';\nimport { Nonce } from '../../../durable-nonce';\nimport { decompileTransactionMessage } from '../message';\n\ndescribe('decompileTransactionMessage (v1)', () => {\n    const U64_MAX = 2n ** 64n - 1n;\n\n    const feePayer = '7EqQdEULxWcraVx3mXKFjc84LhCkMGZCkRuDpvcMwJeK' as Address;\n    const account1 = 'H4RdPRWYk3pKw2CkNznxQK6J6herjgQke2pzFJW4GC6x' as Address;\n    const account2 = 'BPFLoaderUpgradeab1e11111111111111111111111' as Address;\n    const account3 = 'B5Fz4ToKPTzVXHwrAjorBLxwjoDp2ReeZbKXbq38AKgj' as Address;\n    const account4 = 'D56dcHE1GALkcjJ7dAFGtus48iev7A8deHNY9dHLXrnq' as Address;\n    const program1 = 'HZMKVnRrWLyQLwPLTTLKtY7ET4Cf7pQugrTr9eTBrpsf' as Address;\n    const program2 = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address;\n    const program3 = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL' as Address;\n    const blockhash = 'J4yED2jcMAHyQUg61DBmm4njmEydUr2WqrV9cdEcDDgL' as Blockhash;\n\n    function getMockV1CompiledTransactionMessage({\n        lifetimeToken,\n    }: {\n        lifetimeToken?: Blockhash | Nonce;\n    } = {}): CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage {\n        return {\n            configMask: 0,\n            configValues: [],\n            header: {\n                numReadonlyNonSignerAccounts: 0,\n                numReadonlySignerAccounts: 0,\n                numSignerAccounts: 1,\n            },\n            instructionHeaders: [],\n            instructionPayloads: [],\n            lifetimeToken: lifetimeToken ?? blockhash,\n            numInstructions: 0,\n            numStaticAccounts: 1,\n            staticAccounts: [feePayer],\n            version: 1,\n        };\n    }\n\n    describe('for a transaction with a blockhash lifetime', () => {\n        it('decompiles a v1 transaction with no instructions and no config', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage({ lifetimeToken: blockhash }),\n                instructionHeaders: [],\n                instructionPayloads: [],\n                version: 1,\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n\n            expect(transaction.version).toBe(1);\n            expect(transaction.feePayer.address).toBe(feePayer);\n            expect(transaction.lifetimeConstraint).toStrictEqual({\n                blockhash,\n                lastValidBlockHeight: U64_MAX,\n            });\n            expect(transaction.instructions).toStrictEqual([]);\n            expect(transaction).not.toHaveProperty('config');\n        });\n\n        it('freezes the blockhash lifetime constraint', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage =\n                getMockV1CompiledTransactionMessage({ lifetimeToken: blockhash });\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.lifetimeConstraint).toBeFrozenObject();\n        });\n\n        it('decompiles a transaction with one instruction with no accounts or data', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                header: {\n                    numReadonlyNonSignerAccounts: 1, // program address\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 0,\n                        numInstructionDataBytes: 0,\n                        programAccountIndex: 1,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [],\n                        instructionData: new Uint8Array(),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 2,\n                staticAccounts: [feePayer, program1],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    programAddress: program1,\n                },\n            ]);\n        });\n\n        it('decompiles a transaction with one instruction with accounts and data', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // 1 passed into instruction + 1 program\n                    numReadonlySignerAccounts: 1,\n                    numSignerAccounts: 3, // fee payer + 2 passed into instruction\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 4,\n                        numInstructionDataBytes: 5,\n                        programAccountIndex: 5,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [1, 2, 3, 4],\n                        instructionData: new Uint8Array([0, 1, 2, 3, 4]),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 6,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    account1,\n                    // readonly signers\n                    account2,\n                    // writable non-signers\n                    account3,\n                    // readonly non-signers\n                    account4,\n                    program1,\n                ],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toHaveLength(1);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: account1,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                        {\n                            address: account2,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                        {\n                            address: account3,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: account4,\n                            role: AccountRole.READONLY,\n                        },\n                    ],\n                    data: new Uint8Array([0, 1, 2, 3, 4]),\n                    programAddress: program1,\n                },\n            ]);\n        });\n\n        it('freezes the instruction accounts', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                header: {\n                    numReadonlyNonSignerAccounts: 2,\n                    numReadonlySignerAccounts: 1,\n                    numSignerAccounts: 3,\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 4,\n                        numInstructionDataBytes: 5,\n                        programAccountIndex: 5,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [1, 2, 3, 4],\n                        instructionData: new Uint8Array([0, 1, 2, 3, 4]),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 6,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    // read-only signers\n                    account1,\n                    account2,\n                    // writable non-signers\n                    account3,\n                    // readonly non-signers\n                    account4,\n                    program1,\n                ],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0].accounts).toBeFrozenObject();\n        });\n\n        it('decompiles a transaction with multiple instructions', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                header: {\n                    numReadonlyNonSignerAccounts: 3, // 3 programs\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 0,\n                        numInstructionDataBytes: 0,\n                        programAccountIndex: 1,\n                    },\n                    {\n                        numInstructionAccounts: 0,\n                        numInstructionDataBytes: 0,\n                        programAccountIndex: 2,\n                    },\n                    {\n                        numInstructionAccounts: 0,\n                        numInstructionDataBytes: 0,\n                        programAccountIndex: 3,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [],\n                        instructionData: new Uint8Array(),\n                    },\n                    {\n                        instructionAccountIndices: [],\n                        instructionData: new Uint8Array(),\n                    },\n                    {\n                        instructionAccountIndices: [],\n                        instructionData: new Uint8Array(),\n                    },\n                ],\n                numInstructions: 3,\n                numStaticAccounts: 4,\n                staticAccounts: [\n                    feePayer,\n                    // read-only non-signers\n                    program1,\n                    program2,\n                    program3,\n                ],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    programAddress: program1,\n                },\n                {\n                    programAddress: program2,\n                },\n                {\n                    programAddress: program3,\n                },\n            ]);\n        });\n\n        it('decompiles a transaction with a given lastValidBlockHeight', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage =\n                getMockV1CompiledTransactionMessage({ lifetimeToken: blockhash });\n\n            const transaction = decompileTransactionMessage(compiledTransaction, { lastValidBlockHeight: 100n });\n            expect(transaction.lifetimeConstraint).toStrictEqual({\n                blockhash,\n                lastValidBlockHeight: 100n,\n            });\n        });\n\n        it('freezes the instructions within the transaction', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 0,\n                        numInstructionDataBytes: 0,\n                        programAccountIndex: 1,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [],\n                        instructionData: new Uint8Array(),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 2,\n                staticAccounts: [feePayer, program1],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0]).toBeFrozenObject();\n        });\n    });\n\n    describe('for a transaction with a durable nonce lifetime', () => {\n        const nonce = '27kqzE1RifbyoFtibDRTjbnfZ894jsNpuR77JJkt3vgH' as Nonce;\n        const nonceAccountAddress = 'DhezFECsqmzuDxeuitFChbghTrwKLdsKdVsGArYbFEtm' as Address;\n        const nonceAuthorityAddress = '2KntmCrnaf63tpNb8UMFFjFGGnYYAKQdmW9SbuCiRvhM' as Address;\n        const systemProgramAddress = '11111111111111111111111111111111' as Address;\n        const recentBlockhashesSysvarAddress = 'SysvarRecentB1ockHashes11111111111111111111' as Address;\n\n        it('decompiles a transaction with advance nonce instruction where fee payer is nonce authority', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage({ lifetimeToken: nonce }),\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // recent blockhashes sysvar, system program\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1, // fee payer and nonce authority are the same\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 3,\n                        numInstructionDataBytes: 4,\n                        programAccountIndex: 2,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [1, 3, 0],\n                        instructionData: new Uint8Array([4, 0, 0, 0]),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 4,\n                staticAccounts: [\n                    // writable signers\n                    nonceAuthorityAddress,\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // readonly non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: recentBlockhashesSysvarAddress,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: systemProgramAddress,\n                },\n            ]);\n            expect(transaction.feePayer.address).toBe(nonceAuthorityAddress);\n            expect(transaction.lifetimeConstraint).toStrictEqual({ nonce });\n        });\n\n        it('freezes the nonce lifetime constraint', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage({ lifetimeToken: nonce }),\n                header: {\n                    numReadonlyNonSignerAccounts: 2,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 3,\n                        numInstructionDataBytes: 4,\n                        programAccountIndex: 2,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [1, 3, 0],\n                        instructionData: new Uint8Array([4, 0, 0, 0]),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 4,\n                staticAccounts: [\n                    nonceAuthorityAddress,\n                    nonceAccountAddress,\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.lifetimeConstraint).toBeFrozenObject();\n        });\n\n        it('decompiles a transaction with advance nonce instruction where fee payer is not nonce authority', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage({ lifetimeToken: nonce }),\n                header: {\n                    numReadonlyNonSignerAccounts: 2, // recent blockhashes sysvar, system program\n                    numReadonlySignerAccounts: 1, // nonce authority\n                    numSignerAccounts: 2, // fee payer, nonce authority\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 3,\n                        numInstructionDataBytes: 4,\n                        programAccountIndex: 3,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [2, 4, 1],\n                        instructionData: new Uint8Array([4, 0, 0, 0]),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 5,\n                staticAccounts: [\n                    // writable signers\n                    feePayer,\n                    // readonly signers\n                    nonceAuthorityAddress,\n                    // writable non-signers\n                    nonceAccountAddress,\n                    // readonly non-signers\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: nonceAccountAddress,\n                            role: AccountRole.WRITABLE,\n                        },\n                        {\n                            address: recentBlockhashesSysvarAddress,\n                            role: AccountRole.READONLY,\n                        },\n                        {\n                            address: nonceAuthorityAddress,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([4, 0, 0, 0]),\n                    programAddress: systemProgramAddress,\n                },\n            ]);\n            expect(transaction.feePayer.address).toBe(feePayer);\n            expect(transaction.lifetimeConstraint).toStrictEqual({ nonce });\n        });\n\n        it('decompiles a durable nonce transaction with multiple instructions', () => {\n            const programAddress1 = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA' as Address;\n            const programAddress2 = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL' as Address;\n\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage({ lifetimeToken: nonce }),\n                header: {\n                    numReadonlyNonSignerAccounts: 4, // recent blockhashes, system program, 2 other programs\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 3,\n                        numInstructionDataBytes: 4,\n                        programAccountIndex: 2,\n                    },\n                    {\n                        numInstructionAccounts: 0,\n                        numInstructionDataBytes: 0,\n                        programAccountIndex: 4,\n                    },\n                    {\n                        numInstructionAccounts: 0,\n                        numInstructionDataBytes: 0,\n                        programAccountIndex: 5,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [1, 3, 0],\n                        instructionData: new Uint8Array([4, 0, 0, 0]),\n                    },\n                    {\n                        instructionAccountIndices: [],\n                        instructionData: new Uint8Array(),\n                    },\n                    {\n                        instructionAccountIndices: [],\n                        instructionData: new Uint8Array(),\n                    },\n                ],\n                numInstructions: 3,\n                numStaticAccounts: 6,\n                staticAccounts: [\n                    nonceAuthorityAddress,\n                    nonceAccountAddress,\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                    programAddress1,\n                    programAddress2,\n                ],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions).toHaveLength(3);\n            expect(transaction.instructions[0].programAddress).toBe(systemProgramAddress);\n            expect(transaction.instructions[1].programAddress).toBe(programAddress1);\n            expect(transaction.instructions[2].programAddress).toBe(programAddress2);\n            expect(transaction.lifetimeConstraint).toStrictEqual({ nonce });\n        });\n\n        it('freezes all instructions in nonce transaction', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage({ lifetimeToken: nonce }),\n                header: {\n                    numReadonlyNonSignerAccounts: 2,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 3,\n                        numInstructionDataBytes: 4,\n                        programAccountIndex: 2,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [1, 3, 0],\n                        instructionData: new Uint8Array([4, 0, 0, 0]),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 4,\n                staticAccounts: [\n                    nonceAuthorityAddress,\n                    nonceAccountAddress,\n                    systemProgramAddress,\n                    recentBlockhashesSysvarAddress,\n                ],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.instructions[0]).toBeFrozenObject();\n        });\n    });\n\n    describe('for a transaction with config values', () => {\n        const blockhash = 'J4yED2jcMAHyQUg61DBmm4njmEydUr2WqrV9cdEcDDgL' as Blockhash;\n\n        it('converts a transaction with priority fee config', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                configMask: 0b11,\n                configValues: [{ kind: 'u64', value: 5_000n }] as CompiledTransactionConfigValue[],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.config).toStrictEqual({\n                priorityFeeLamports: 5_000n,\n            });\n        });\n\n        it('converts a transaction with all config values', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                configMask: 0b11111,\n                configValues: [\n                    { kind: 'u64', value: 10_000n },\n                    { kind: 'u32', value: 400_000 },\n                    { kind: 'u32', value: 80_000 },\n                    { kind: 'u32', value: 512_000 },\n                ] as CompiledTransactionConfigValue[],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.config).toStrictEqual({\n                computeUnitLimit: 400_000,\n                heapSize: 512_000,\n                loadedAccountsDataSizeLimit: 80_000,\n                priorityFeeLamports: 10_000n,\n            });\n        });\n\n        it('does not include config field when configMask is 0', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                configMask: 0,\n                configValues: [],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction).not.toHaveProperty('config');\n        });\n\n        it('converts a transaction with config and instructions', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                configMask: 0b100,\n                configValues: [{ kind: 'u32', value: 300_000 }] as CompiledTransactionConfigValue[],\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 1,\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 0,\n                        numInstructionDataBytes: 2,\n                        programAccountIndex: 1,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [],\n                        instructionData: new Uint8Array([7, 8]),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 2,\n                staticAccounts: [feePayer, program1],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.config).toStrictEqual({\n                computeUnitLimit: 300_000,\n            });\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    data: new Uint8Array([7, 8]),\n                    programAddress: program1,\n                },\n            ]);\n        });\n\n        it('freezes the config object', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                configMask: 0b11,\n                configValues: [{ kind: 'u64', value: 5_000n }] as CompiledTransactionConfigValue[],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction);\n            expect(transaction.config).toBeFrozenObject();\n        });\n\n        it('converts a complex transaction with all features', () => {\n            const compiledTransaction: CompiledTransactionMessageWithLifetime & V1CompiledTransactionMessage = {\n                ...getMockV1CompiledTransactionMessage(),\n                configMask: 0b11111,\n                configValues: [\n                    { kind: 'u64', value: 10_000n },\n                    { kind: 'u32', value: 400_000 },\n                    { kind: 'u32', value: 80_000 },\n                    { kind: 'u32', value: 512_000 },\n                ] as CompiledTransactionConfigValue[],\n                header: {\n                    numReadonlyNonSignerAccounts: 1,\n                    numReadonlySignerAccounts: 0,\n                    numSignerAccounts: 2,\n                },\n                instructionHeaders: [\n                    {\n                        numInstructionAccounts: 1,\n                        numInstructionDataBytes: 3,\n                        programAccountIndex: 2,\n                    },\n                ],\n                instructionPayloads: [\n                    {\n                        instructionAccountIndices: [1],\n                        instructionData: new Uint8Array([1, 2, 3]),\n                    },\n                ],\n                numInstructions: 1,\n                numStaticAccounts: 3,\n                staticAccounts: [feePayer, account1, program1],\n            };\n\n            const transaction = decompileTransactionMessage(compiledTransaction, { lastValidBlockHeight: 100n });\n\n            expect(transaction.version).toBe(1);\n            expect(transaction.feePayer.address).toBe(feePayer);\n            expect(transaction.config).toStrictEqual({\n                computeUnitLimit: 400_000,\n                heapSize: 512_000,\n                loadedAccountsDataSizeLimit: 80_000,\n                priorityFeeLamports: 10_000n,\n            });\n            expect(transaction.instructions).toStrictEqual([\n                {\n                    accounts: [\n                        {\n                            address: account1,\n                            role: AccountRole.WRITABLE_SIGNER,\n                        },\n                    ],\n                    data: new Uint8Array([1, 2, 3]),\n                    programAddress: program1,\n                },\n            ]);\n            expect(transaction.lifetimeConstraint).toStrictEqual({\n                blockhash,\n                lastValidBlockHeight: 100n,\n            });\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v1/config.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND, SolanaError } from '@solana/errors';\n\nimport { CompiledTransactionConfigValue } from '../../compile/v1/config';\nimport {\n    transactionConfigMaskHasComputeUnitLimit,\n    transactionConfigMaskHasHeapSize,\n    transactionConfigMaskHasLoadedAccountsDataSizeLimit,\n    transactionConfigMaskHasPriorityFee,\n    V1TransactionConfig,\n} from '../../v1-transaction-config';\n\ntype SupportedConfig = [keyof V1TransactionConfig, 'u32' | 'u64', (mask: number) => boolean];\n\nexport function decompileTransactionConfig(\n    configMask: number,\n    configValues: CompiledTransactionConfigValue[],\n): V1TransactionConfig {\n    const supportedConfigs: SupportedConfig[] = [\n        ['priorityFeeLamports', 'u64', transactionConfigMaskHasPriorityFee],\n        ['computeUnitLimit', 'u32', transactionConfigMaskHasComputeUnitLimit],\n        ['loadedAccountsDataSizeLimit', 'u32', transactionConfigMaskHasLoadedAccountsDataSizeLimit],\n        ['heapSize', 'u32', transactionConfigMaskHasHeapSize],\n    ];\n\n    const [config] = supportedConfigs.reduce(\n        ([acc, index], [name, kind, predicate]) => {\n            if (!predicate(configMask)) return [acc, index];\n            const configValue = configValues[index];\n            if (configValue.kind !== kind) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_VALUE_KIND, {\n                    actualKind: configValue.kind,\n                    configName: name,\n                    expectedKind: kind,\n                });\n            }\n            return [{ ...acc, [name]: configValue.value }, index + 1];\n        },\n        [{}, 0] as [V1TransactionConfig, number],\n    );\n\n    return config;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v1/instructions.ts",
    "content": "import {\n    SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND,\n    SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH,\n    SolanaError,\n} from '@solana/errors';\nimport { AccountMeta, Instruction } from '@solana/instructions';\n\nimport { InstructionHeader, InstructionPayload } from '../../compile/v1/instructions';\n\nfunction decompileInstruction(\n    instructionHeader: InstructionHeader,\n    instructionPayload: InstructionPayload,\n    accountMetas: AccountMeta[],\n): Instruction {\n    const programAddress = accountMetas[instructionHeader.programAccountIndex]?.address;\n    if (!programAddress) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__FAILED_TO_DECOMPILE_INSTRUCTION_PROGRAM_ADDRESS_NOT_FOUND, {\n            index: instructionHeader.programAccountIndex,\n        });\n    }\n\n    const accounts = instructionPayload.instructionAccountIndices.map(accountIndex => accountMetas[accountIndex]);\n    const data = instructionPayload.instructionData;\n\n    return Object.freeze({\n        programAddress,\n        ...(accounts && accounts.length ? { accounts: Object.freeze(accounts) } : {}),\n        ...(data && data.length ? { data } : {}),\n    });\n}\n\nexport function decompileInstructions(\n    instructionHeaders: InstructionHeader[],\n    instructionPayloads: InstructionPayload[],\n    accountMetas: AccountMeta[],\n): Instruction[] {\n    if (instructionHeaders.length !== instructionPayloads.length) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__INSTRUCTION_HEADERS_PAYLOADS_MISMATCH, {\n            numInstructionHeaders: instructionHeaders.length,\n            numInstructionPayloads: instructionPayloads.length,\n        });\n    }\n\n    return instructionHeaders.map((instructionHeader, index) =>\n        decompileInstruction(instructionHeader, instructionPayloads[index], accountMetas),\n    );\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/decompile/v1/message.ts",
    "content": "import { pipe } from '@solana/functional';\n\nimport { setTransactionMessageLifetimeUsingBlockhash } from '../../blockhash';\nimport { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime } from '../../compile';\nimport { createTransactionMessage } from '../../create-transaction-message';\nimport { setTransactionMessageLifetimeUsingDurableNonce } from '../../durable-nonce';\nimport { setTransactionMessageFeePayer, TransactionMessageWithFeePayer } from '../../fee-payer';\nimport { appendTransactionMessageInstructions } from '../../instructions';\nimport { TransactionMessageWithLifetime } from '../../lifetime';\nimport { TransactionMessage } from '../../transaction-message';\nimport { setTransactionMessageConfig } from '../../v1-transaction-config';\nimport { getAccountMetas } from '../legacy/account-metas';\nimport { getFeePayer } from '../legacy/fee-payer';\nimport { getLifetimeConstraint } from '../legacy/lifetime-constraint';\nimport { decompileTransactionConfig } from './config';\nimport { decompileInstructions } from './instructions';\n\nexport function decompileTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime & { version: 1 },\n    config?: {\n        lastValidBlockHeight?: bigint;\n    },\n): TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithLifetime & { version: 1 } {\n    const feePayer = getFeePayer(compiledTransactionMessage.staticAccounts);\n    const accountMetas = getAccountMetas(compiledTransactionMessage);\n    const transactionConfig = decompileTransactionConfig(\n        compiledTransactionMessage.configMask,\n        compiledTransactionMessage.configValues,\n    );\n    const instructions = decompileInstructions(\n        compiledTransactionMessage.instructionHeaders,\n        compiledTransactionMessage.instructionPayloads,\n        accountMetas,\n    );\n    const lifetimeConstraint = getLifetimeConstraint(\n        compiledTransactionMessage.lifetimeToken,\n        instructions,\n        config?.lastValidBlockHeight,\n    );\n\n    return pipe(\n        // @ts-expect-error We don't expose v1 on `createTransactionMessage` yet\n        createTransactionMessage({ version: 1 }),\n        // Won't need this cast after we support v1 on `createTransactionMessage`\n        m => setTransactionMessageConfig(transactionConfig, m as unknown as TransactionMessage & { version: 1 }),\n        m => setTransactionMessageFeePayer(feePayer, m),\n        m => appendTransactionMessageInstructions(instructions, m),\n        m =>\n            'blockhash' in lifetimeConstraint\n                ? setTransactionMessageLifetimeUsingBlockhash(lifetimeConstraint, m)\n                : setTransactionMessageLifetimeUsingDurableNonce(lifetimeConstraint, m),\n    );\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/durable-nonce-instruction.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    AccountRole,\n    Instruction,\n    InstructionWithAccounts,\n    InstructionWithData,\n    isSignerRole,\n    ReadonlyAccount,\n    ReadonlySignerAccount,\n    WritableAccount,\n    WritableSignerAccount,\n} from '@solana/instructions';\nimport { Brand } from '@solana/nominal-types';\n\nexport type AdvanceNonceAccountInstruction<\n    TNonceAccountAddress extends string = string,\n    TNonceAuthorityAddress extends string = string,\n> = Instruction<'11111111111111111111111111111111'> &\n    InstructionWithAccounts<\n        readonly [\n            WritableAccount<TNonceAccountAddress>,\n            ReadonlyAccount<'SysvarRecentB1ockHashes11111111111111111111'>,\n            ReadonlySignerAccount<TNonceAuthorityAddress> | WritableSignerAccount<TNonceAuthorityAddress>,\n        ]\n    > &\n    InstructionWithData<AdvanceNonceAccountInstructionData>;\n\ntype AdvanceNonceAccountInstructionData = Brand<Uint8Array, 'AdvanceNonceAccountInstructionData'>;\n\nconst RECENT_BLOCKHASHES_SYSVAR_ADDRESS =\n    'SysvarRecentB1ockHashes11111111111111111111' as Address<'SysvarRecentB1ockHashes11111111111111111111'>;\nconst SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;\n\n/**\n * Creates an instruction for the System program to advance a nonce.\n *\n * This instruction is a prerequisite for a transaction with a nonce-based lifetime to be landed on\n * the network. In order to be considered valid, the transaction must meet all of these criteria.\n *\n * 1. Its lifetime constraint must be a {@link NonceLifetimeConstraint}.\n * 2. The value contained in the on-chain account at the address `nonceAccountAddress` must be equal\n *    to {@link NonceLifetimeConstraint.nonce} at the time the transaction is landed.\n * 3. The first instruction in that transaction message must be the one returned by this function.\n *\n * You could also use the `getAdvanceNonceAccountInstruction` method of `@solana-program/system`.\n */\nexport function createAdvanceNonceAccountInstruction<\n    TNonceAccountAddress extends string = string,\n    TNonceAuthorityAddress extends string = string,\n>(\n    nonceAccountAddress: Address<TNonceAccountAddress>,\n    nonceAuthorityAddress: Address<TNonceAuthorityAddress>,\n): AdvanceNonceAccountInstruction<TNonceAccountAddress, TNonceAuthorityAddress> {\n    return {\n        accounts: [\n            { address: nonceAccountAddress, role: AccountRole.WRITABLE },\n            {\n                address: RECENT_BLOCKHASHES_SYSVAR_ADDRESS,\n                role: AccountRole.READONLY,\n            },\n            { address: nonceAuthorityAddress, role: AccountRole.READONLY_SIGNER },\n        ],\n        data: new Uint8Array([4, 0, 0, 0]) as AdvanceNonceAccountInstructionData,\n        programAddress: SYSTEM_PROGRAM_ADDRESS,\n    };\n}\n\n/**\n * A type guard that returns `true` if the instruction conforms to the\n * {@link AdvanceNonceAccountInstruction} type, and refines its type for use in your program.\n *\n * @example\n * ```ts\n * import { isAdvanceNonceAccountInstruction } from '@solana/transaction-messages';\n *\n * if (isAdvanceNonceAccountInstruction(message.instructions[0])) {\n *     // At this point, the first instruction in the message has been refined to a\n *     // `AdvanceNonceAccountInstruction`.\n *     setNonceAccountAddress(message.instructions[0].accounts[0].address);\n * } else {\n *     setError('The first instruction is not an `AdvanceNonce` instruction');\n * }\n * ```\n */\nexport function isAdvanceNonceAccountInstruction(\n    instruction: Instruction,\n): instruction is AdvanceNonceAccountInstruction {\n    return (\n        instruction.programAddress === SYSTEM_PROGRAM_ADDRESS &&\n        // Test for `AdvanceNonceAccount` instruction data\n        instruction.data != null &&\n        isAdvanceNonceAccountInstructionData(instruction.data) &&\n        // Test for exactly 3 accounts\n        instruction.accounts?.length === 3 &&\n        // First account is nonce account address\n        instruction.accounts[0].address != null &&\n        instruction.accounts[0].role === AccountRole.WRITABLE &&\n        // Second account is recent blockhashes sysvar\n        instruction.accounts[1].address === RECENT_BLOCKHASHES_SYSVAR_ADDRESS &&\n        instruction.accounts[1].role === AccountRole.READONLY &&\n        // Third account is nonce authority account\n        instruction.accounts[2].address != null &&\n        isSignerRole(instruction.accounts[2].role)\n    );\n}\n\nfunction isAdvanceNonceAccountInstructionData(data: ReadonlyUint8Array): data is AdvanceNonceAccountInstructionData {\n    // AdvanceNonceAccount is the fifth instruction in the System Program (index 4)\n    return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/durable-nonce.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME, SolanaError } from '@solana/errors';\nimport { Instruction } from '@solana/instructions';\nimport { Brand } from '@solana/nominal-types';\n\nimport {\n    AdvanceNonceAccountInstruction,\n    createAdvanceNonceAccountInstruction,\n    isAdvanceNonceAccountInstruction,\n} from './durable-nonce-instruction';\nimport { ExcludeTransactionMessageLifetime } from './lifetime';\nimport { TransactionMessage } from './transaction-message';\nimport { ExcludeTransactionMessageWithinSizeLimit } from './transaction-message-size';\n\ntype DurableNonceConfig<\n    TNonceAccountAddress extends string = string,\n    TNonceAuthorityAddress extends string = string,\n    TNonceValue extends string = string,\n> = Readonly<{\n    readonly nonce: Nonce<TNonceValue>;\n    readonly nonceAccountAddress: Address<TNonceAccountAddress>;\n    readonly nonceAuthorityAddress: Address<TNonceAuthorityAddress>;\n}>;\n\n/** Represents a string that is particularly known to be the base58-encoded value of a nonce. */\nexport type Nonce<TNonceValue extends string = string> = Brand<TNonceValue, 'Nonce'>;\n\n/**\n * A constraint which, when applied to a transaction message, makes that transaction message\n * eligible to land on the network.\n *\n * The transaction message will continue to be eligible to land until the network considers the\n * `nonce` to have advanced. This can happen when the nonce account in which this nonce is found is\n * destroyed, or the nonce value within changes.\n */\nexport type NonceLifetimeConstraint<TNonceValue extends string = string> = Readonly<{\n    /**\n     * A value contained in the related nonce account at the time the transaction was prepared.\n     *\n     * The transaction will be considered eligible to land until the nonce account ceases to exist\n     * or contain this value.\n     */\n    nonce: Nonce<TNonceValue>;\n}>;\n\n/**\n * Represents a transaction message whose lifetime is defined by the value of a nonce it includes.\n *\n * Such a transaction can only be landed on the network if the nonce is known to the network and has\n * not already been used to land a different transaction.\n */\nexport interface TransactionMessageWithDurableNonceLifetime<\n    TNonceAccountAddress extends string = string,\n    TNonceAuthorityAddress extends string = string,\n    TNonceValue extends string = string,\n> {\n    readonly instructions: readonly [\n        // The first instruction *must* be the system program's `AdvanceNonceAccount` instruction.\n        AdvanceNonceAccountInstruction<TNonceAccountAddress, TNonceAuthorityAddress>,\n        ...Instruction[],\n    ];\n    readonly lifetimeConstraint: NonceLifetimeConstraint<TNonceValue>;\n}\n\n/**\n * A helper type to exclude the durable nonce lifetime constraint from a transaction message.\n */\nexport type ExcludeTransactionMessageDurableNonceLifetime<TTransactionMessage extends TransactionMessage> =\n    TTransactionMessage extends TransactionMessageWithDurableNonceLifetime\n        ? ExcludeTransactionMessageLifetime<TTransactionMessage>\n        : TTransactionMessage;\n\n/**\n * A type guard that returns `true` if the transaction message conforms to the\n * {@link TransactionMessageWithDurableNonceLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionMessageWithDurableNonceLifetime } from '@solana/transaction-messages';\n * import { fetchNonce } from \"@solana-program/system\";\n *\n * if (isTransactionMessageWithDurableNonceLifetime(message)) {\n *     // At this point, `message` has been refined to a\n *     // `TransactionMessageWithDurableNonceLifetime`.\n *     const { nonce, nonceAccountAddress } = message.lifetimeConstraint;\n *     const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n *     setNonceIsValid(nonce === actualNonce);\n * } else {\n *     setError(\n *         `${getSignatureFromTransaction(transaction)} does not have a nonce-based lifetime`,\n *     );\n * }\n * ```\n */\nexport function isTransactionMessageWithDurableNonceLifetime(\n    transactionMessage: TransactionMessage | (TransactionMessage & TransactionMessageWithDurableNonceLifetime),\n): transactionMessage is TransactionMessage & TransactionMessageWithDurableNonceLifetime {\n    return (\n        'lifetimeConstraint' in transactionMessage &&\n        typeof transactionMessage.lifetimeConstraint.nonce === 'string' &&\n        transactionMessage.instructions[0] != null &&\n        isAdvanceNonceAccountInstruction(transactionMessage.instructions[0])\n    );\n}\n\n/**\n * From time to time you might acquire a transaction message, that you expect to have a\n * nonce-based lifetime, from an untrusted network API or user input. Use this function to assert\n * that such a transaction message actually has a nonce-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionMessageWithDurableNonceLifetime } from '@solana/transaction-messages';\n *\n * try {\n *     // If this type assertion function doesn't throw, then\n *     // Typescript will upcast `message` to `TransactionMessageWithDurableNonceLifetime`.\n *     assertIsTransactionMessageWithDurableNonceLifetime(message);\n *     // At this point, `message` is a `TransactionMessageWithDurableNonceLifetime` that can be used\n *     // with the RPC.\n *     const { nonce, nonceAccountAddress } = message.lifetimeConstraint;\n *     const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * } catch (e) {\n *     // `message` turned out not to have a nonce-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionMessageWithDurableNonceLifetime(\n    transactionMessage: TransactionMessage | (TransactionMessage & TransactionMessageWithDurableNonceLifetime),\n): asserts transactionMessage is TransactionMessage & TransactionMessageWithDurableNonceLifetime {\n    if (!isTransactionMessageWithDurableNonceLifetime(transactionMessage)) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME);\n    }\n}\n\nfunction isAdvanceNonceAccountInstructionForNonce<\n    TNonceAccountAddress extends Address = Address,\n    TNonceAuthorityAddress extends Address = Address,\n>(\n    instruction: AdvanceNonceAccountInstruction,\n    nonceAccountAddress: TNonceAccountAddress,\n    nonceAuthorityAddress: TNonceAuthorityAddress,\n): instruction is AdvanceNonceAccountInstruction<TNonceAccountAddress, TNonceAuthorityAddress> {\n    return (\n        instruction.accounts[0].address === nonceAccountAddress &&\n        instruction.accounts[2].address === nonceAuthorityAddress\n    );\n}\n\n/**\n * Given a nonce, the account where the value of the nonce is stored, and the address of the account\n * authorized to consume that nonce, this method will return a new transaction having the same type\n * as the one supplied plus the {@link TransactionMessageWithDurableNonceLifetime} type.\n *\n * In particular, this method _prepends_ an instruction to the transaction message designed to\n * consume (or 'advance') the nonce in the same transaction whose lifetime is defined by it.\n *\n * @param config\n *\n * @example\n * ```ts\n * import { Nonce, setTransactionMessageLifetimeUsingDurableNonce } from '@solana/transaction-messages';\n * import { fetchNonce } from '@solana-program/system';\n *\n * const nonceAccountAddress = address('EGtMh4yvXswwHhwVhyPxGrVV2TkLTgUqGodbATEPvojZ');\n * const nonceAuthorityAddress = address('4KD1Rdrd89NG7XbzW3xsX9Aqnx2EExJvExiNme6g9iAT');\n *\n * const {\n *     data: { blockhash },\n * } = await fetchNonce(rpc, nonceAccountAddress);\n * const nonce = blockhash as string as Nonce;\n *\n * const durableNonceTransactionMessage = setTransactionMessageLifetimeUsingDurableNonce(\n *     { nonce, nonceAccountAddress, nonceAuthorityAddress },\n *     tx,\n * );\n * ```\n */\nexport function setTransactionMessageLifetimeUsingDurableNonce<\n    TTransactionMessage extends TransactionMessage,\n    TNonceAccountAddress extends string = string,\n    TNonceAuthorityAddress extends string = string,\n    TNonceValue extends string = string,\n>(\n    {\n        nonce,\n        nonceAccountAddress,\n        nonceAuthorityAddress,\n    }: DurableNonceConfig<TNonceAccountAddress, TNonceAuthorityAddress, TNonceValue>,\n    transactionMessage: TTransactionMessage,\n): SetTransactionMessageWithDurableNonceLifetime<\n    TTransactionMessage,\n    TNonceAccountAddress,\n    TNonceAuthorityAddress,\n    TNonceValue\n> {\n    type ReturnType = SetTransactionMessageWithDurableNonceLifetime<\n        TTransactionMessage,\n        TNonceAccountAddress,\n        TNonceAuthorityAddress,\n        TNonceValue\n    >;\n\n    let newInstructions: [\n        AdvanceNonceAccountInstruction<TNonceAccountAddress, TNonceAuthorityAddress>,\n        ...Instruction[],\n    ];\n\n    const firstInstruction = transactionMessage.instructions[0];\n    if (firstInstruction && isAdvanceNonceAccountInstruction(firstInstruction)) {\n        if (isAdvanceNonceAccountInstructionForNonce(firstInstruction, nonceAccountAddress, nonceAuthorityAddress)) {\n            if (\n                isTransactionMessageWithDurableNonceLifetime(transactionMessage) &&\n                transactionMessage.lifetimeConstraint.nonce === nonce\n            ) {\n                return transactionMessage as unknown as ReturnType;\n            } else {\n                // we already have the right first instruction, leave it as-is\n                newInstructions = [firstInstruction, ...transactionMessage.instructions.slice(1)];\n            }\n        } else {\n            // we have a different advance nonce instruction as the first instruction, replace it\n            newInstructions = [\n                Object.freeze(createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress)),\n                ...transactionMessage.instructions.slice(1),\n            ];\n        }\n    } else {\n        // we don't have an existing advance nonce instruction as the first instruction, prepend one\n        newInstructions = [\n            Object.freeze(createAdvanceNonceAccountInstruction(nonceAccountAddress, nonceAuthorityAddress)),\n            ...transactionMessage.instructions,\n        ];\n    }\n\n    return Object.freeze({\n        ...transactionMessage,\n        instructions: Object.freeze(newInstructions),\n        lifetimeConstraint: Object.freeze({ nonce }),\n    }) as unknown as ReturnType;\n}\n\n/**\n * Helper type that transforms a given transaction message type into a new one that has the\n * `AdvanceNonceAccount` instruction as the first instruction and a lifetime constraint\n * representing the nonce value.\n */\ntype SetTransactionMessageWithDurableNonceLifetime<\n    TTransactionMessage extends TransactionMessage,\n    TNonceAccountAddress extends string = string,\n    TNonceAuthorityAddress extends string = string,\n    TNonceValue extends string = string,\n> = TTransactionMessage extends unknown\n    ? Omit<\n          // 1. The transaction message only grows in size if it currently has a different (or no) lifetime.\n          TTransactionMessage extends TransactionMessageWithDurableNonceLifetime\n              ? TTransactionMessage\n              : ExcludeTransactionMessageWithinSizeLimit<TTransactionMessage>,\n          // 2. Remove the instructions array as we are going to replace it with a new one.\n          | 'instructions'\n          // 3. Remove the existing lifetime constraint as we are going to replace it with a new one.\n          | 'lifetimeConstraint'\n      > & {\n          // 4. Replace or prepend the first instruction with the advance nonce account instruction.\n          readonly instructions: TTransactionMessage['instructions'] extends readonly [\n              AdvanceNonceAccountInstruction,\n              ...infer TTail extends readonly Instruction[],\n          ]\n              ? readonly [AdvanceNonceAccountInstruction<TNonceAccountAddress, TNonceAuthorityAddress>, ...TTail]\n              : readonly [\n                    AdvanceNonceAccountInstruction<TNonceAccountAddress, TNonceAuthorityAddress>,\n                    ...TTransactionMessage['instructions'],\n                ];\n          // 5. Set the lifetime constraint to the nonce value.\n          readonly lifetimeConstraint: NonceLifetimeConstraint<TNonceValue>;\n      }\n    : never;\n"
  },
  {
    "path": "packages/transaction-messages/src/fee-payer.ts",
    "content": "import { Address } from '@solana/addresses';\n\nimport { TransactionMessage } from './transaction-message';\n\n/**\n * Represents a transaction message for which a fee payer has been declared. A transaction must\n * conform to this type to be compiled and landed on the network.\n */\nexport interface TransactionMessageWithFeePayer<TAddress extends string = string> {\n    readonly feePayer: Readonly<{ address: Address<TAddress> }>;\n}\n\n/**\n * A helper type to exclude the fee payer from a transaction message.\n */\ntype ExcludeTransactionMessageFeePayer<TTransactionMessage extends TransactionMessage> =\n    TTransactionMessage extends unknown ? Omit<TTransactionMessage, 'feePayer'> : never;\n\n/**\n * Given a base58-encoded address of a system account, this method will return a new transaction\n * message having the same type as the one supplied plus the {@link TransactionMessageWithFeePayer}\n * type.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n * import { setTransactionMessageFeePayer } from '@solana/transaction-messages';\n *\n * const myAddress = address('mpngsFd4tmbUfzDYJayjKZwZcaR7aWb2793J6grLsGu');\n * const txPaidByMe = setTransactionMessageFeePayer(myAddress, tx);\n * ```\n */\nexport function setTransactionMessageFeePayer<\n    TFeePayerAddress extends string,\n    TTransactionMessage extends Partial<TransactionMessageWithFeePayer> & TransactionMessage,\n>(\n    feePayer: Address<TFeePayerAddress>,\n    transactionMessage: TTransactionMessage,\n): ExcludeTransactionMessageFeePayer<TTransactionMessage> & TransactionMessageWithFeePayer<TFeePayerAddress> {\n    if (\n        'feePayer' in transactionMessage &&\n        feePayer === transactionMessage.feePayer?.address &&\n        isAddressOnlyFeePayer(transactionMessage.feePayer)\n    ) {\n        return transactionMessage as ExcludeTransactionMessageFeePayer<TTransactionMessage> &\n            TransactionMessageWithFeePayer<TFeePayerAddress>;\n    }\n    const out = {\n        ...transactionMessage,\n        feePayer: Object.freeze({ address: feePayer }),\n    };\n    Object.freeze(out);\n    return out as ExcludeTransactionMessageFeePayer<TTransactionMessage> &\n        TransactionMessageWithFeePayer<TFeePayerAddress>;\n}\n\nfunction isAddressOnlyFeePayer(\n    feePayer: Partial<TransactionMessageWithFeePayer>['feePayer'],\n): feePayer is { address: Address } {\n    return (\n        !!feePayer &&\n        'address' in feePayer &&\n        typeof feePayer.address === 'string' &&\n        Object.keys(feePayer).length === 1\n    );\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/heap-size.ts",
    "content": "import type { Instruction } from '@solana/instructions';\n\nimport {\n    getHeapSizeFromInstructionData,\n    getRequestHeapFrameInstruction,\n    isRequestHeapFrameInstruction,\n    removeTransactionMessageInstruction,\n    replaceTransactionMessageInstruction,\n} from './compute-budget-instruction';\nimport { appendTransactionMessageInstruction } from './instructions';\nimport { TransactionMessage } from './transaction-message';\nimport { areV1ConfigsEqual, isV1ConfigEmpty } from './v1-transaction-config';\n\n/**\n * Returns the heap size currently set on a transaction message, or `undefined` if none is set.\n *\n * This function works with all transaction versions:\n * - **V1**: Reads from the transaction message's `config.heapSize`.\n * - **Legacy / V0**: Searches the instructions for a `RequestHeapFrame` instruction and decodes its\n *   value.\n *\n * @param transactionMessage - The transaction message to inspect.\n * @return The heap size in bytes, or `undefined` if none is set.\n *\n * @example\n * ```ts\n * const heapSize = getTransactionMessageHeapSize(transactionMessage);\n * if (heapSize !== undefined) {\n *     console.log(`Heap size: ${heapSize}`);\n * }\n * ```\n */\nexport function getTransactionMessageHeapSize(transactionMessage: TransactionMessage): number | undefined {\n    switch (transactionMessage.version) {\n        case 1:\n            return transactionMessage.config?.heapSize;\n        default:\n            return getTransactionMessageHeapSizeUsingInstruction(transactionMessage);\n    }\n}\n\nfunction getTransactionMessageHeapSizeUsingInstruction(transactionMessage: TransactionMessage): number | undefined {\n    const instructions = transactionMessage.instructions as Instruction[];\n    const existingInstruction = instructions.find(isRequestHeapFrameInstruction);\n    return existingInstruction ? getHeapSizeFromInstructionData(existingInstruction.data) : undefined;\n}\n\n/**\n * Sets the heap frame size for a transaction message.\n *\n * This function works with all transaction versions:\n * - **V1**: Sets the `heapSize` field in the transaction message's config.\n * - **Legacy / V0**: Appends (or replaces) a `RequestHeapFrame` instruction from the Compute\n *   Budget program.\n *\n * @param heapSize - The requested heap frame size in bytes, or `undefined` to remove the setting.\n * @param transactionMessage - The transaction message to configure.\n * @typeParam TTransactionMessage - The transaction message type.\n * @return A new transaction message with the heap size set.\n *\n * @example\n * ```ts\n * const txMessage = setTransactionMessageHeapSize(\n *     256_000,\n *     transactionMessage,\n * );\n * ```\n */\nexport function setTransactionMessageHeapSize<TTransactionMessage extends TransactionMessage>(\n    heapSize: number | undefined,\n    transactionMessage: TTransactionMessage,\n): TTransactionMessage {\n    switch (transactionMessage.version) {\n        case 1:\n            return setTransactionMessageHeapSizeUsingConfig(heapSize, transactionMessage) as TTransactionMessage;\n        default:\n            return setTransactionMessageHeapSizeUsingInstruction(heapSize, transactionMessage);\n    }\n}\n\nfunction setTransactionMessageHeapSizeUsingConfig<TTransactionMessage extends TransactionMessage & { version: 1 }>(\n    heapSize: number | undefined,\n    transactionMessage: TTransactionMessage,\n): TTransactionMessage {\n    const mergedConfig = { ...(transactionMessage.config ?? {}), heapSize };\n    const nextConfig = isV1ConfigEmpty(mergedConfig) ? undefined : Object.freeze(mergedConfig);\n    if (nextConfig === undefined) {\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        const { config, ...rest } = transactionMessage;\n        return Object.freeze(rest) as TTransactionMessage;\n    }\n\n    if (transactionMessage.config && areV1ConfigsEqual(transactionMessage.config, nextConfig)) {\n        return transactionMessage;\n    }\n\n    return Object.freeze({ ...transactionMessage, config: nextConfig }) as TTransactionMessage;\n}\n\nfunction setTransactionMessageHeapSizeUsingInstruction<TTransactionMessage extends TransactionMessage>(\n    heapSize: number | undefined,\n    transactionMessage: TTransactionMessage,\n): TTransactionMessage {\n    const existingIndex = transactionMessage.instructions.findIndex(isRequestHeapFrameInstruction);\n\n    // Remove the heap size instruction if there is one and the new size is undefined.\n    if (heapSize === undefined) {\n        return existingIndex === -1\n            ? transactionMessage\n            : removeTransactionMessageInstruction(existingIndex, transactionMessage);\n    }\n\n    // Ignore if the new heap size is the same as the existing one.\n    if (getTransactionMessageHeapSize(transactionMessage) === heapSize) {\n        return transactionMessage;\n    }\n\n    // Add or replace the heap size instruction with the new size.\n    const newInstruction = getRequestHeapFrameInstruction(heapSize);\n    return existingIndex === -1\n        ? (appendTransactionMessageInstruction(newInstruction, transactionMessage) as TTransactionMessage)\n        : replaceTransactionMessageInstruction(existingIndex, newInstruction, transactionMessage);\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/index.ts",
    "content": "/**\n * This package contains types and functions for creating transaction messages.\n * It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * @example\n * Transaction messages are built one step at a time using the transform functions offered by this\n * package. To make it more ergonomic to apply consecutive transforms to your transaction messages,\n * consider using a pipelining helper like the one in `@solana/functional`.\n *\n * ```ts\n * import { pipe } from '@solana/functional';\n * import {\n *     appendTransactionMessageInstruction,\n *     createTransactionMessage,\n *     setTransactionMessageFeePayer,\n *     setTransactionMessageLifetimeUsingBlockhash,\n * } from '@solana/transaction-messages';\n *\n * const transferTransactionMessage = pipe(\n *     createTransactionMessage({ version: 0 }),\n *     m => setTransactionMessageFeePayer(myAddress, m),\n *     m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),\n *     m => appendTransactionMessageInstruction(getTransferSolInstruction({ source, destination, amount }), m),\n * );\n * ```\n *\n * @packageDocumentation\n */\nexport * from './addresses-by-lookup-table-address';\nexport * from './blockhash';\nexport * from './codecs';\nexport * from './compile';\nexport * from './compress-transaction-message';\nexport * from './compute-unit-limit';\nexport * from './compute-unit-price';\nexport * from './create-transaction-message';\nexport * from './decompile';\nexport * from './durable-nonce';\nexport { isAdvanceNonceAccountInstruction } from './durable-nonce-instruction';\nexport * from './fee-payer';\nexport * from './heap-size';\nexport * from './instructions';\nexport * from './lifetime';\nexport * from './loaded-accounts-data-size-limit';\nexport * from './priority-fee-lamports';\nexport * from './transaction-message-size';\nexport * from './transaction-message';\n"
  },
  {
    "path": "packages/transaction-messages/src/instructions.ts",
    "content": "import { Instruction } from '@solana/instructions';\n\nimport { ExcludeTransactionMessageDurableNonceLifetime } from './durable-nonce';\nimport { TransactionMessage } from './transaction-message';\nimport { ExcludeTransactionMessageWithinSizeLimit } from './transaction-message-size';\n\n/**\n * A helper type to append instructions to a transaction message\n * without losing type information about the current instructions.\n */\ntype AppendTransactionMessageInstructions<\n    TTransactionMessage extends TransactionMessage,\n    TInstructions extends readonly Instruction[],\n> = TTransactionMessage extends TransactionMessage\n    ? Omit<ExcludeTransactionMessageWithinSizeLimit<TTransactionMessage>, 'instructions'> & {\n          readonly instructions: readonly [...TTransactionMessage['instructions'], ...TInstructions];\n      }\n    : never;\n\n/**\n * A helper type to prepend instructions to a transaction message\n * without losing type information about the current instructions.\n */\ntype PrependTransactionMessageInstructions<\n    TTransactionMessage extends TransactionMessage,\n    TInstructions extends readonly Instruction[],\n> = TTransactionMessage extends TransactionMessage\n    ? Omit<\n          ExcludeTransactionMessageWithinSizeLimit<ExcludeTransactionMessageDurableNonceLifetime<TTransactionMessage>>,\n          'instructions'\n      > & {\n          readonly instructions: readonly [...TInstructions, ...TTransactionMessage['instructions']];\n      }\n    : never;\n\n/**\n * Given an instruction, this method will return a new transaction message with that instruction\n * having been added to the end of the list of existing instructions.\n *\n * @see {@link appendTransactionInstructions} if you need to append multiple instructions to a\n * transaction message.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n * import { getUtf8Encoder } from '@solana/codecs-strings';\n * import { appendTransactionMessageInstruction } from '@solana/transaction-messages';\n *\n * const memoTransactionMessage = appendTransactionMessageInstruction(\n *     {\n *         data: getUtf8Encoder().encode('Hello world!'),\n *         programAddress: address('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),\n *     },\n *     transactionMessage,\n * );\n * ```\n */\nexport function appendTransactionMessageInstruction<\n    TTransactionMessage extends TransactionMessage,\n    TInstruction extends Instruction,\n>(\n    instruction: TInstruction,\n    transactionMessage: TTransactionMessage,\n): AppendTransactionMessageInstructions<TTransactionMessage, [TInstruction]> {\n    return appendTransactionMessageInstructions([instruction], transactionMessage);\n}\n\n/**\n * Given an array of instructions, this method will return a new transaction message with those\n * instructions having been added to the end of the list of existing instructions.\n *\n * @see {@link appendTransactionInstruction} if you only need to append one instruction to a\n * transaction message.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n * import { appendTransactionMessageInstructions } from '@solana/transaction-messages';\n *\n * const memoTransaction = appendTransactionMessageInstructions(\n *     [\n *         {\n *             data: new TextEncoder().encode('Hello world!'),\n *             programAddress: address('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),\n *         },\n *         {\n *             data: new TextEncoder().encode('How are you?'),\n *             programAddress: address('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),\n *         },\n *     ],\n *     tx,\n * );\n * ```\n */\nexport function appendTransactionMessageInstructions<\n    TTransactionMessage extends TransactionMessage,\n    const TInstructions extends readonly Instruction[],\n>(\n    instructions: TInstructions,\n    transactionMessage: TTransactionMessage,\n): AppendTransactionMessageInstructions<TTransactionMessage, TInstructions> {\n    return Object.freeze({\n        ...transactionMessage,\n        instructions: Object.freeze([\n            ...(transactionMessage.instructions as TTransactionMessage['instructions']),\n            ...instructions,\n        ] as readonly [...TTransactionMessage['instructions'], ...TInstructions]),\n    }) as AppendTransactionMessageInstructions<TTransactionMessage, TInstructions>;\n}\n\n/**\n * Given an instruction, this method will return a new transaction message with that instruction\n * having been added to the beginning of the list of existing instructions.\n *\n * @see {@link prependTransactionInstructions} if you need to prepend multiple instructions to a\n * transaction message.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n * import { prependTransactionMessageInstruction } from '@solana/transaction-messages';\n *\n * const memoTransaction = prependTransactionMessageInstruction(\n *     {\n *         data: new TextEncoder().encode('Hello world!'),\n *         programAddress: address('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),\n *     },\n *     tx,\n * );\n * ```\n */\nexport function prependTransactionMessageInstruction<\n    TTransactionMessage extends TransactionMessage,\n    TInstruction extends Instruction,\n>(\n    instruction: TInstruction,\n    transactionMessage: TTransactionMessage,\n): PrependTransactionMessageInstructions<TTransactionMessage, [TInstruction]> {\n    return prependTransactionMessageInstructions([instruction], transactionMessage);\n}\n\n/**\n * Given an array of instructions, this method will return a new transaction message with those\n * instructions having been added to the beginning of the list of existing instructions.\n *\n * @see {@link prependTransactionInstruction} if you only need to prepend one instruction to a\n * transaction message.\n *\n * @example\n * ```ts\n * import { address } from '@solana/addresses';\n * import { prependTransactionMessageInstructions } from '@solana/transaction-messages';\n *\n * const memoTransaction = prependTransactionMessageInstructions(\n *     [\n *         {\n *             data: new TextEncoder().encode('Hello world!'),\n *             programAddress: address('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),\n *         },\n *         {\n *             data: new TextEncoder().encode('How are you?'),\n *             programAddress: address('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),\n *         },\n *     ],\n *     tx,\n * );\n * ```\n */\nexport function prependTransactionMessageInstructions<\n    TTransactionMessage extends TransactionMessage,\n    const TInstructions extends readonly Instruction[],\n>(\n    instructions: TInstructions,\n    transactionMessage: TTransactionMessage,\n): PrependTransactionMessageInstructions<TTransactionMessage, TInstructions> {\n    return Object.freeze({\n        ...(transactionMessage as ExcludeTransactionMessageDurableNonceLifetime<TTransactionMessage>),\n        instructions: Object.freeze([\n            ...instructions,\n            ...(transactionMessage.instructions as TTransactionMessage['instructions']),\n        ] as readonly [...TInstructions, ...TTransactionMessage['instructions']]),\n    }) as unknown as PrependTransactionMessageInstructions<TTransactionMessage, TInstructions>;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/lifetime.ts",
    "content": "import { TransactionMessageWithBlockhashLifetime } from './blockhash';\nimport { TransactionMessageWithDurableNonceLifetime } from './durable-nonce';\nimport { TransactionMessage } from './transaction-message';\n\n/**\n * A transaction message with any valid lifetime constraint.\n */\nexport type TransactionMessageWithLifetime =\n    | TransactionMessageWithBlockhashLifetime\n    | TransactionMessageWithDurableNonceLifetime;\n\n/**\n * A helper type to exclude any lifetime constraint from a transaction message.\n */\nexport type ExcludeTransactionMessageLifetime<TTransactionMessage extends TransactionMessage> =\n    TTransactionMessage extends unknown ? Omit<TTransactionMessage, 'lifetimeConstraint'> : never;\n"
  },
  {
    "path": "packages/transaction-messages/src/loaded-accounts-data-size-limit.ts",
    "content": "import type { Instruction } from '@solana/instructions';\n\nimport {\n    getLoadedAccountsDataSizeLimitFromInstructionData,\n    getSetLoadedAccountsDataSizeLimitInstruction,\n    isSetLoadedAccountsDataSizeLimitInstruction,\n    removeTransactionMessageInstruction,\n    replaceTransactionMessageInstruction,\n} from './compute-budget-instruction';\nimport { appendTransactionMessageInstruction } from './instructions';\nimport { TransactionMessage } from './transaction-message';\nimport { areV1ConfigsEqual, isV1ConfigEmpty } from './v1-transaction-config';\n\n/**\n * Returns the loaded accounts data size limit currently set on a transaction message, or\n * `undefined` if none is set.\n *\n * This function works with all transaction versions:\n * - **V1**: Reads from the transaction message's `config.loadedAccountsDataSizeLimit`.\n * - **Legacy / V0**: Searches the instructions for a `SetLoadedAccountsDataSizeLimit` instruction\n *   and decodes its value.\n *\n * @param transactionMessage - The transaction message to inspect.\n * @return The loaded accounts data size limit in bytes, or `undefined` if none is set.\n *\n * @example\n * ```ts\n * const limit = getTransactionMessageLoadedAccountsDataSizeLimit(transactionMessage);\n * if (limit !== undefined) {\n *     console.log(`Loaded accounts data size limit: ${limit}`);\n * }\n * ```\n */\nexport function getTransactionMessageLoadedAccountsDataSizeLimit(\n    transactionMessage: TransactionMessage,\n): number | undefined {\n    switch (transactionMessage.version) {\n        case 1:\n            return transactionMessage.config?.loadedAccountsDataSizeLimit;\n        default:\n            return getTransactionMessageLoadedAccountsDataSizeLimitUsingInstruction(transactionMessage);\n    }\n}\n\nfunction getTransactionMessageLoadedAccountsDataSizeLimitUsingInstruction(\n    transactionMessage: TransactionMessage,\n): number | undefined {\n    const instructions = transactionMessage.instructions as Instruction[];\n    const existingInstruction = instructions.find(isSetLoadedAccountsDataSizeLimitInstruction);\n    return existingInstruction\n        ? getLoadedAccountsDataSizeLimitFromInstructionData(existingInstruction.data)\n        : undefined;\n}\n\n/**\n * Sets the loaded accounts data size limit for a transaction message.\n *\n * This function works with all transaction versions:\n * - **V1**: Sets the `loadedAccountsDataSizeLimit` field in the transaction message's config.\n * - **Legacy / V0**: Appends (or replaces) a `SetLoadedAccountsDataSizeLimit` instruction from\n *   the Compute Budget program.\n *\n * @param loadedAccountsDataSizeLimit - The maximum size in bytes for loaded account data, or\n *   `undefined` to remove the limit.\n * @param transactionMessage - The transaction message to configure.\n * @typeParam TTransactionMessage - The transaction message type.\n * @return A new transaction message with the loaded accounts data size limit set.\n *\n * @example\n * ```ts\n * const txMessage = setTransactionMessageLoadedAccountsDataSizeLimit(\n *     64_000,\n *     transactionMessage,\n * );\n * ```\n */\nexport function setTransactionMessageLoadedAccountsDataSizeLimit<TTransactionMessage extends TransactionMessage>(\n    loadedAccountsDataSizeLimit: number | undefined,\n    transactionMessage: TTransactionMessage,\n): TTransactionMessage {\n    switch (transactionMessage.version) {\n        case 1:\n            return setTransactionMessageLoadedAccountsDataSizeLimitUsingConfig(\n                loadedAccountsDataSizeLimit,\n                transactionMessage,\n            ) as TTransactionMessage;\n        default:\n            return setTransactionMessageLoadedAccountsDataSizeLimitUsingInstruction(\n                loadedAccountsDataSizeLimit,\n                transactionMessage,\n            );\n    }\n}\n\nfunction setTransactionMessageLoadedAccountsDataSizeLimitUsingConfig<\n    TTransactionMessage extends TransactionMessage & { version: 1 },\n>(loadedAccountsDataSizeLimit: number | undefined, transactionMessage: TTransactionMessage): TTransactionMessage {\n    const mergedConfig = { ...(transactionMessage.config ?? {}), loadedAccountsDataSizeLimit };\n    const nextConfig = isV1ConfigEmpty(mergedConfig) ? undefined : Object.freeze(mergedConfig);\n    if (nextConfig === undefined) {\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        const { config, ...rest } = transactionMessage;\n        return Object.freeze(rest) as TTransactionMessage;\n    }\n\n    if (transactionMessage.config && areV1ConfigsEqual(transactionMessage.config, nextConfig)) {\n        return transactionMessage;\n    }\n\n    return Object.freeze({ ...transactionMessage, config: nextConfig }) as TTransactionMessage;\n}\n\nfunction setTransactionMessageLoadedAccountsDataSizeLimitUsingInstruction<\n    TTransactionMessage extends TransactionMessage,\n>(loadedAccountsDataSizeLimit: number | undefined, transactionMessage: TTransactionMessage): TTransactionMessage {\n    const existingIndex = transactionMessage.instructions.findIndex(isSetLoadedAccountsDataSizeLimitInstruction);\n\n    // Remove the loaded accounts data size limit instruction if there is one and the new limit is undefined.\n    if (loadedAccountsDataSizeLimit === undefined) {\n        return existingIndex === -1\n            ? transactionMessage\n            : removeTransactionMessageInstruction(existingIndex, transactionMessage);\n    }\n\n    // Ignore if the new loaded accounts data size limit is the same as the existing one.\n    if (getTransactionMessageLoadedAccountsDataSizeLimit(transactionMessage) === loadedAccountsDataSizeLimit) {\n        return transactionMessage;\n    }\n\n    // Add or replace the loaded accounts data size limit instruction with the new limit.\n    const newInstruction = getSetLoadedAccountsDataSizeLimitInstruction(loadedAccountsDataSizeLimit);\n    return existingIndex === -1\n        ? (appendTransactionMessageInstruction(newInstruction, transactionMessage) as TTransactionMessage)\n        : replaceTransactionMessageInstruction(existingIndex, newInstruction, transactionMessage);\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/priority-fee-lamports.ts",
    "content": "import { TransactionMessage, TransactionVersion } from './transaction-message';\nimport { areV1ConfigsEqual, isV1ConfigEmpty } from './v1-transaction-config';\n\ntype SupportedTransactionVersions = Extract<TransactionVersion, 1>;\n\n/**\n * Returns the priority fee in lamports currently set on a v1 transaction message, or `undefined`\n * if none is set.\n *\n * This reads from the transaction message's `config.priorityFeeLamports`.\n *\n * @param transactionMessage - The v1 transaction message to inspect.\n * @return The priority fee in lamports, or `undefined` if none is set.\n *\n * @example\n * ```ts\n * const fee = getTransactionMessagePriorityFeeLamports(transactionMessage);\n * if (fee !== undefined) {\n *     console.log(`Priority fee: ${fee}`);\n * }\n * ```\n *\n * @see {@link setTransactionMessagePriorityFeeLamports}\n * @see {@link setTransactionMessageComputeUnitPrice} for legacy/v0 transactions.\n */\nexport function getTransactionMessagePriorityFeeLamports<\n    TTransactionMessage extends TransactionMessage & { version: SupportedTransactionVersions },\n>(transactionMessage: TTransactionMessage): bigint | undefined {\n    return transactionMessage.config?.priorityFeeLamports;\n}\n\n/**\n * Sets the total priority fee for a v1 transaction message.\n *\n * In v1 transactions, the priority fee is expressed as a total amount in lamports — what you set is\n * what you pay, regardless of the compute unit limit.\n *\n * @param priorityFeeLamports - The priority fee amount in lamports, or `undefined` to remove the\n *   fee.\n * @param transactionMessage - The v1 transaction message to configure.\n * @typeParam TTransactionMessage - The transaction message type.\n * @return A new transaction message with the priority fee set.\n *\n * @example\n * ```ts\n * const txMessage = setTransactionMessagePriorityFeeLamports(\n *     10_000n,\n *     transactionMessage,\n * );\n * ```\n *\n * @see {@link getTransactionMessagePriorityFeeLamports}\n * @see {@link setTransactionMessageComputeUnitPrice} for legacy/v0 transactions.\n */\nexport function setTransactionMessagePriorityFeeLamports<\n    TTransactionMessage extends TransactionMessage & { version: SupportedTransactionVersions },\n>(priorityFeeLamports: bigint | undefined, transactionMessage: TTransactionMessage): TTransactionMessage {\n    const mergedConfig = { ...(transactionMessage.config ?? {}), priorityFeeLamports };\n    const nextConfig = isV1ConfigEmpty(mergedConfig) ? undefined : Object.freeze(mergedConfig);\n    if (nextConfig === undefined) {\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        const { config, ...rest } = transactionMessage;\n        return Object.freeze(rest) as TTransactionMessage;\n    }\n\n    if (transactionMessage.config && areV1ConfigsEqual(transactionMessage.config, nextConfig)) {\n        return transactionMessage;\n    }\n\n    return Object.freeze({ ...transactionMessage, config: nextConfig }) as TTransactionMessage;\n}\n"
  },
  {
    "path": "packages/transaction-messages/src/transaction-message-size.ts",
    "content": "import type { NominalType } from '@solana/nominal-types';\n\nimport type { TransactionMessage } from './transaction-message';\n\n/**\n * A type guard that checks if a transaction message is within the size limit\n * when compiled into a transaction.\n */\nexport type TransactionMessageWithinSizeLimit = NominalType<'transactionSize', 'withinLimit'>;\n\n/**\n * Helper type that removes the `TransactionMessageWithinSizeLimit` flag\n * from a transaction message.\n */\nexport type ExcludeTransactionMessageWithinSizeLimit<TTransactionMessage extends TransactionMessage> = Omit<\n    TTransactionMessage,\n    '__transactionSize:@solana/kit'\n>;\n"
  },
  {
    "path": "packages/transaction-messages/src/transaction-message.ts",
    "content": "import { AccountMeta, Instruction } from '@solana/instructions';\n\nimport { V1TransactionConfig } from './v1-transaction-config';\n\ntype BaseTransactionMessage<\n    TVersion extends TransactionVersion = TransactionVersion,\n    TInstruction extends Instruction = Instruction,\n> = Readonly<{\n    instructions: readonly TInstruction[];\n    version: TVersion;\n}>;\n\nexport const MAX_SUPPORTED_TRANSACTION_VERSION = 1;\n\ntype InstructionWithoutLookupTables<TProgramAddress extends string = string> = Instruction<\n    TProgramAddress,\n    readonly AccountMeta[]\n>;\ntype LegacyTransactionMessage = BaseTransactionMessage<'legacy', InstructionWithoutLookupTables>;\ntype V0TransactionMessage = BaseTransactionMessage<0, Instruction>;\ntype V1TransactionMessage = BaseTransactionMessage<1, InstructionWithoutLookupTables> &\n    Readonly<{\n        /** A set of optional configuration values for the transaction */\n        config?: V1TransactionConfig;\n    }>;\nexport type TransactionMessage = LegacyTransactionMessage | V0TransactionMessage | V1TransactionMessage;\nexport type TransactionVersion = 'legacy' | 0 | 1;\n"
  },
  {
    "path": "packages/transaction-messages/src/v1-transaction-config.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS, SolanaError } from '@solana/errors';\n\nimport { TransactionMessage, TransactionVersion } from './transaction-message';\n\n/**\n * Configuration options for transaction messages.\n *\n * These options allow fine-grained control over transaction resource usage and\n * prioritization. All fields are optional and will be encoded into the transaction\n * when present.\n */\nexport type V1TransactionConfig = {\n    /**\n     * Maximum number of compute units the transaction may consume.\n     *\n     * If not specified, defaults to 200,000 CUs per instruction. The maximum\n     * allowed value is 1,400,000 CUs.\n     */\n    computeUnitLimit?: number;\n    /**\n     * Requested heap frame size in bytes for the transaction's execution.\n     */\n    heapSize?: number;\n    /**\n     * Maximum size in bytes for loaded account data.\n     */\n    loadedAccountsDataSizeLimit?: number;\n    /**\n     * Total priority fee in lamports to pay for transaction prioritization.\n     */\n    priorityFeeLamports?: bigint;\n};\n\nexport function isV1ConfigEmpty(config: V1TransactionConfig): boolean {\n    return (\n        config.computeUnitLimit === undefined &&\n        config.heapSize === undefined &&\n        config.loadedAccountsDataSizeLimit === undefined &&\n        config.priorityFeeLamports === undefined\n    );\n}\n\nexport function areV1ConfigsEqual(config1: V1TransactionConfig, config2: V1TransactionConfig) {\n    return (\n        config1.computeUnitLimit === config2.computeUnitLimit &&\n        config1.heapSize === config2.heapSize &&\n        config1.loadedAccountsDataSizeLimit === config2.loadedAccountsDataSizeLimit &&\n        config1.priorityFeeLamports === config2.priorityFeeLamports\n    );\n}\n\ntype SupportedTransactionVersions = Extract<TransactionVersion, 1>;\n\n/**\n * Sets configuration options on a transaction message.\n *\n * This function merges the provided configuration with any existing configuration\n * on the transaction message. Configuration values control resource limits and\n * transaction prioritization.\n *\n * @param config - The configuration options to apply.\n * @param transactionMessage - The transaction message to configure.\n * @typeParam TTransactionMessage - The transaction message type.\n * @return A new transaction message with the merged configuration.\n *\n * @example\n * ```ts\n * const configuredTx = setTransactionMessageConfig(\n *     {\n *         computeUnitLimit: 300_000,\n *         priorityFeeLamports: 50_000n,\n *     },\n *     transactionMessage,\n * );\n * ```\n *\n * @example\n * Incrementally adding configuration values.\n * ```ts\n * const txMessage = pipe(\n *     baseTransaction,\n *     tx => setTransactionMessageConfig({ computeUnitLimit: 300_000 }, tx),\n *     tx => setTransactionMessageConfig({ priorityFeeLamports: 50_000n }, tx),\n * );\n * ```\n *\n * @example\n * Removing a configuration value.\n * ```ts\n * const txMessage = setTransactionMessageConfig({ computeUnitLimit: undefined }, tx);\n * ```\n *\n * @see {@link setTransactionMessageComputeUnitLimit}\n * @see {@link setTransactionMessagePriorityFeeLamports}\n */\nexport function setTransactionMessageConfig<\n    TTransactionMessage extends TransactionMessage & { version: SupportedTransactionVersions },\n>(config: V1TransactionConfig, transactionMessage: TTransactionMessage): TTransactionMessage {\n    const mergedConfig = {\n        ...transactionMessage.config,\n        ...config,\n    };\n\n    if (isV1ConfigEmpty(mergedConfig)) {\n        // If config has no defined values, remove it entirely\n        if (!transactionMessage.config) {\n            // No config before, no config after - return same reference\n            return transactionMessage;\n        }\n        // eslint-disable-next-line @typescript-eslint/no-unused-vars\n        const { config, ...rest } = transactionMessage;\n        return Object.freeze(rest) as TTransactionMessage;\n    }\n\n    // Check if config is identical for idempotency\n    if (transactionMessage.config && areV1ConfigsEqual(transactionMessage.config, mergedConfig)) {\n        return transactionMessage;\n    }\n\n    return Object.freeze({\n        ...transactionMessage,\n        config: Object.freeze(mergedConfig),\n    }) as TTransactionMessage;\n}\n\nexport const TRANSACTION_CONFIG_PRIORITY_FEE_LAMPORTS_BIT_MASK = 0b11;\nexport const TRANSACTION_CONFIG_COMPUTE_UNIT_LIMIT_BIT_MASK = 0b100;\nexport const TRANSACTION_CONFIG_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_BIT_MASK = 0b1000;\nexport const TRANSACTION_CONFIG_HEAP_SIZE_BIT_MASK = 0b10000;\n\n/**\n * Checks whether the transaction config mask indicates a priority fee is present.\n *\n * The priority fee uses bits 0 and 1 of the mask. Both bits must be set or\n * both must be unset — having only one bit set is invalid and will throw an error.\n *\n * @param mask - The transaction config mask to check.\n * @return `true` if the mask indicates a priority fee is present, `false` otherwise.\n *\n * @throws {SolanaError} Throws `SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS`\n * if only one of the two priority fee bits is set.\n *\n * @example\n * Check if a mask has a priority fee.\n * ```ts\n * const hasPriorityFee = transactionConfigMaskHasPriorityFee(0b11);\n * // true (both bits 0 and 1 are set)\n * ```\n */\nexport function transactionConfigMaskHasPriorityFee(mask: number): boolean {\n    // bits 0 and 1 must both be set or both be unset\n    const priorityFeeBits = mask & TRANSACTION_CONFIG_PRIORITY_FEE_LAMPORTS_BIT_MASK;\n    if (priorityFeeBits === 0b01 || priorityFeeBits === 0b10) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_CONFIG_MASK_PRIORITY_FEE_BITS, { mask });\n    }\n    return priorityFeeBits === TRANSACTION_CONFIG_PRIORITY_FEE_LAMPORTS_BIT_MASK;\n}\n\n/**\n * Checks whether the transaction config mask indicates a compute unit limit is present.\n *\n * The compute unit limit uses bit 2 of the mask.\n *\n * @param mask - The transaction config mask to check.\n * @return `true` if the mask indicates a compute unit limit is present, `false` otherwise.\n *\n * @example\n * ```ts\n * const hasComputeUnitLimit = transactionConfigMaskHasComputeUnitLimit(0b100);\n * // true (bit 2 is set)\n * ```\n */\nexport function transactionConfigMaskHasComputeUnitLimit(mask: number): boolean {\n    return (mask & TRANSACTION_CONFIG_COMPUTE_UNIT_LIMIT_BIT_MASK) !== 0;\n}\n\n/**\n * Checks whether the transaction config mask indicates a loaded accounts data size limit is present.\n *\n * The loaded accounts data size limit uses bit 3 of the mask.\n *\n * @param mask - The transaction config mask to check.\n * @return `true` if the mask indicates a loaded accounts data size limit is present, `false` otherwise.\n *\n * @example\n * ```ts\n * const hasLimit = transactionConfigMaskHasLoadedAccountsDataSizeLimit(0b1000);\n * // true (bit 3 is set)\n * ```\n */\nexport function transactionConfigMaskHasLoadedAccountsDataSizeLimit(mask: number): boolean {\n    return (mask & TRANSACTION_CONFIG_LOADED_ACCOUNTS_DATA_SIZE_LIMIT_BIT_MASK) !== 0;\n}\n\n/**\n * Checks whether the transaction config mask indicates a heap size is present.\n *\n * The heap size uses bit 4 of the mask.\n *\n * @param mask - The transaction config mask to check.\n * @return `true` if the mask indicates a heap size is present, `false` otherwise.\n *\n * @example\n * ```ts\n * const hasHeapSize = transactionConfigMaskHasHeapSize(0b10000);\n * // true (bit 4 is set)\n * ```\n */\nexport function transactionConfigMaskHasHeapSize(mask: number): boolean {\n    return (mask & TRANSACTION_CONFIG_HEAP_SIZE_BIT_MASK) !== 0;\n}\n"
  },
  {
    "path": "packages/transaction-messages/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/transaction-messages/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": []\n    },\n    \"display\": \"@solana/transaction-messages\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/transaction-messages/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/transactions/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/transactions/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/transactions/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/transactions/CHANGELOG.md",
    "content": "# @solana/transactions\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- Updated dependencies [[`92126f4`](https://github.com/anza-xyz/kit/commit/92126f438afff8b7521f827cf0e92b1d2cd69c55), [`a5ef97b`](https://github.com/anza-xyz/kit/commit/a5ef97b17fe747de1e2bee0189ed44e20c0f6c40), [`e82e03e`](https://github.com/anza-xyz/kit/commit/e82e03eb0e982db74f96d11b9aa8fefb4f0038c3), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7), [`0e8fd3f`](https://github.com/anza-xyz/kit/commit/0e8fd3f62b2cdb8e5082700096ce011883a60578)]:\n    - @solana/errors@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/codecs-data-structures@6.9.0\n    - @solana/codecs-numbers@6.9.0\n    - @solana/codecs-strings@6.9.0\n    - @solana/functional@6.9.0\n    - @solana/instructions@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/nominal-types@6.9.0\n    - @solana/rpc-types@6.9.0\n    - @solana/transaction-messages@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439), [`ffb7665`](https://github.com/anza-xyz/kit/commit/ffb76652f6b887eb5020c3584f1d827a1098dccc)]:\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/codecs-data-structures@6.8.0\n    - @solana/codecs-numbers@6.8.0\n    - @solana/codecs-strings@6.8.0\n    - @solana/errors@6.8.0\n    - @solana/functional@6.8.0\n    - @solana/instructions@6.8.0\n    - @solana/nominal-types@6.8.0\n    - @solana/rpc-types@6.8.0\n    - @solana/transaction-messages@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/codecs-data-structures@6.7.0\n    - @solana/codecs-numbers@6.7.0\n    - @solana/codecs-strings@6.7.0\n    - @solana/errors@6.7.0\n    - @solana/functional@6.7.0\n    - @solana/instructions@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/nominal-types@6.7.0\n    - @solana/rpc-types@6.7.0\n    - @solana/transaction-messages@6.7.0\n\n## 6.6.0\n\n### Minor Changes\n\n- [#1499](https://github.com/anza-xyz/kit/pull/1499) [`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add version-aware transaction size limits. Version 1 transactions now allow up to 4096 bytes, while legacy and v0 transactions continue to use the existing 1232-byte limit. Two new helper functions are exported from `@solana/transactions`: `getTransactionSizeLimit` for compiled `Transaction` objects, and `getTransactionMessageSizeLimit` for `TransactionMessage` objects.\n\n    The existing `TRANSACTION_SIZE_LIMIT`, `TRANSACTION_PACKET_SIZE`, and `TRANSACTION_PACKET_HEADER` constants are now deprecated in favour of `getTransactionSizeLimit` and will be removed in a future major version.\n\n### Patch Changes\n\n- Updated dependencies [[`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad)]:\n    - @solana/errors@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/codecs-data-structures@6.6.0\n    - @solana/codecs-numbers@6.6.0\n    - @solana/codecs-strings@6.6.0\n    - @solana/instructions@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/rpc-types@6.6.0\n    - @solana/functional@6.6.0\n    - @solana/nominal-types@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/codecs-data-structures@6.5.0\n    - @solana/codecs-numbers@6.5.0\n    - @solana/codecs-strings@6.5.0\n    - @solana/errors@6.5.0\n    - @solana/functional@6.5.0\n    - @solana/instructions@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/nominal-types@6.5.0\n    - @solana/rpc-types@6.5.0\n    - @solana/transaction-messages@6.5.0\n\n## 6.4.0\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c), [`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/codecs-strings@6.4.0\n    - @solana/transaction-messages@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/codecs-data-structures@6.4.0\n    - @solana/codecs-numbers@6.4.0\n    - @solana/instructions@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/rpc-types@6.4.0\n    - @solana/errors@6.4.0\n    - @solana/functional@6.4.0\n    - @solana/nominal-types@6.4.0\n\n## 6.3.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.3.1\n    - @solana/codecs-core@6.3.1\n    - @solana/codecs-data-structures@6.3.1\n    - @solana/codecs-numbers@6.3.1\n    - @solana/codecs-strings@6.3.1\n    - @solana/errors@6.3.1\n    - @solana/functional@6.3.1\n    - @solana/instructions@6.3.1\n    - @solana/keys@6.3.1\n    - @solana/nominal-types@6.3.1\n    - @solana/rpc-types@6.3.1\n    - @solana/transaction-messages@6.3.1\n\n## 6.3.0\n\n### Patch Changes\n\n- Updated dependencies [[`f47d5cf`](https://github.com/anza-xyz/kit/commit/f47d5cf30512bbae3233f0ddccae45462af7f309)]:\n    - @solana/errors@6.3.0\n    - @solana/addresses@6.3.0\n    - @solana/codecs-core@6.3.0\n    - @solana/codecs-data-structures@6.3.0\n    - @solana/codecs-numbers@6.3.0\n    - @solana/codecs-strings@6.3.0\n    - @solana/instructions@6.3.0\n    - @solana/keys@6.3.0\n    - @solana/rpc-types@6.3.0\n    - @solana/transaction-messages@6.3.0\n    - @solana/functional@6.3.0\n    - @solana/nominal-types@6.3.0\n\n## 6.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`0d0be3e`](https://github.com/anza-xyz/kit/commit/0d0be3e18bfbb053b92c4b2d338c5bb0ed414bcc), [`7568a12`](https://github.com/anza-xyz/kit/commit/7568a127e1d1197d2362be464117bc41c82b01ad), [`e33a65f`](https://github.com/anza-xyz/kit/commit/e33a65fd18d52bd2d7a0018ff9a152ff6f43a3b3), [`5390602`](https://github.com/anza-xyz/kit/commit/53906024cffc3facb7259ab65ab974b6b1038f56), [`3f4c5f0`](https://github.com/anza-xyz/kit/commit/3f4c5f003e343c21a785e8f339f84c8d6bd3a3b1), [`49c1195`](https://github.com/anza-xyz/kit/commit/49c1195637a8d550b864918e96d9f9681f658bfe)]:\n    - @solana/errors@6.2.0\n    - @solana/codecs-data-structures@6.2.0\n    - @solana/addresses@6.2.0\n    - @solana/codecs-core@6.2.0\n    - @solana/codecs-numbers@6.2.0\n    - @solana/codecs-strings@6.2.0\n    - @solana/instructions@6.2.0\n    - @solana/keys@6.2.0\n    - @solana/rpc-types@6.2.0\n    - @solana/transaction-messages@6.2.0\n    - @solana/functional@6.2.0\n    - @solana/nominal-types@6.2.0\n\n## 6.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`70b1ed8`](https://github.com/anza-xyz/kit/commit/70b1ed83be4c5445f81c600a8ca70127dbdf3463), [`3f711e1`](https://github.com/anza-xyz/kit/commit/3f711e16bc38657d5d1ff71cf98e73897ff19ea5), [`215027c`](https://github.com/anza-xyz/kit/commit/215027c49845bd5cbd86d3da396f0c3895283d75), [`7ce7545`](https://github.com/anza-xyz/kit/commit/7ce75455659ace9776042def6774678a81c43a4a)]:\n    - @solana/codecs-data-structures@6.1.0\n    - @solana/errors@6.1.0\n    - @solana/transaction-messages@6.1.0\n    - @solana/addresses@6.1.0\n    - @solana/codecs-core@6.1.0\n    - @solana/codecs-numbers@6.1.0\n    - @solana/codecs-strings@6.1.0\n    - @solana/instructions@6.1.0\n    - @solana/keys@6.1.0\n    - @solana/rpc-types@6.1.0\n    - @solana/functional@6.1.0\n    - @solana/nominal-types@6.1.0\n\n## 6.0.1\n\n### Patch Changes\n\n- Updated dependencies [[`2d3296f`](https://github.com/anza-xyz/kit/commit/2d3296f1ea03184455197d0284be73ada999b492), [`a8a57ce`](https://github.com/anza-xyz/kit/commit/a8a57cebc47caa24f6d105c346427baa244fa462)]:\n    - @solana/transaction-messages@6.0.1\n    - @solana/addresses@6.0.1\n    - @solana/codecs-core@6.0.1\n    - @solana/codecs-data-structures@6.0.1\n    - @solana/codecs-numbers@6.0.1\n    - @solana/codecs-strings@6.0.1\n    - @solana/errors@6.0.1\n    - @solana/functional@6.0.1\n    - @solana/instructions@6.0.1\n    - @solana/keys@6.0.1\n    - @solana/nominal-types@6.0.1\n    - @solana/rpc-types@6.0.1\n\n## 6.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`f80b6de`](https://github.com/anza-xyz/kit/commit/f80b6de0649ed2df3aa64fdd01215322bb8cc926), [`b82df4c`](https://github.com/anza-xyz/kit/commit/b82df4c98a9f157c030f62735f4427ba095bee6a), [`986a09c`](https://github.com/anza-xyz/kit/commit/986a09c56c38c2a91752972ec258fe790f8620db)]:\n    - @solana/transaction-messages@6.0.0\n    - @solana/addresses@6.0.0\n    - @solana/codecs-core@6.0.0\n    - @solana/codecs-data-structures@6.0.0\n    - @solana/codecs-numbers@6.0.0\n    - @solana/codecs-strings@6.0.0\n    - @solana/errors@6.0.0\n    - @solana/functional@6.0.0\n    - @solana/instructions@6.0.0\n    - @solana/keys@6.0.0\n    - @solana/nominal-types@6.0.0\n    - @solana/rpc-types@6.0.0\n\n## 5.5.1\n\n### Patch Changes\n\n- Updated dependencies [[`d957526`](https://github.com/anza-xyz/kit/commit/d9575263c3e563c6951cd35bbc6e65e70a0e6a10)]:\n    - @solana/errors@5.5.1\n    - @solana/addresses@5.5.1\n    - @solana/codecs-core@5.5.1\n    - @solana/codecs-data-structures@5.5.1\n    - @solana/codecs-numbers@5.5.1\n    - @solana/codecs-strings@5.5.1\n    - @solana/instructions@5.5.1\n    - @solana/keys@5.5.1\n    - @solana/rpc-types@5.5.1\n    - @solana/transaction-messages@5.5.1\n    - @solana/functional@5.5.1\n    - @solana/nominal-types@5.5.1\n\n## 5.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`b4f5897`](https://github.com/anza-xyz/kit/commit/b4f5897cab50a92f50b6b390ae76d743173c26dd), [`08c9062`](https://github.com/anza-xyz/kit/commit/08c906299409e82a5941e1044fc6d47d633df784), [`ba3f186`](https://github.com/anza-xyz/kit/commit/ba3f1861a9cb53b4c0e7c6d1b92791d8983e001b), [`1cc0a31`](https://github.com/anza-xyz/kit/commit/1cc0a3163cf884a715aef5ba336adfd980dabfa6), [`6af7c15`](https://github.com/anza-xyz/kit/commit/6af7c156a9cd196d0d5ecb374fe696ec659756bf)]:\n    - @solana/errors@5.5.0\n    - @solana/addresses@5.5.0\n    - @solana/codecs-core@5.5.0\n    - @solana/codecs-data-structures@5.5.0\n    - @solana/codecs-numbers@5.5.0\n    - @solana/codecs-strings@5.5.0\n    - @solana/instructions@5.5.0\n    - @solana/keys@5.5.0\n    - @solana/rpc-types@5.5.0\n    - @solana/transaction-messages@5.5.0\n    - @solana/functional@5.5.0\n    - @solana/nominal-types@5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n- Updated dependencies [[`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09), [`189de37`](https://github.com/anza-xyz/kit/commit/189de37f76bcb273986d750fd6ed6541f711103b)]:\n    - @solana/codecs-data-structures@5.4.0\n    - @solana/transaction-messages@5.4.0\n    - @solana/codecs-numbers@5.4.0\n    - @solana/codecs-strings@5.4.0\n    - @solana/nominal-types@5.4.0\n    - @solana/instructions@5.4.0\n    - @solana/codecs-core@5.4.0\n    - @solana/functional@5.4.0\n    - @solana/addresses@5.4.0\n    - @solana/rpc-types@5.4.0\n    - @solana/errors@5.4.0\n    - @solana/keys@5.4.0\n\n## 5.3.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@5.3.0\n    - @solana/codecs-core@5.3.0\n    - @solana/codecs-data-structures@5.3.0\n    - @solana/codecs-numbers@5.3.0\n    - @solana/codecs-strings@5.3.0\n    - @solana/errors@5.3.0\n    - @solana/functional@5.3.0\n    - @solana/instructions@5.3.0\n    - @solana/keys@5.3.0\n    - @solana/nominal-types@5.3.0\n    - @solana/rpc-types@5.3.0\n    - @solana/transaction-messages@5.3.0\n\n## 5.2.0\n\n### Minor Changes\n\n- [#1139](https://github.com/anza-xyz/kit/pull/1139) [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Return more precise types from transaction message functions\n\n    Deprecate `BaseTransactionMessage` in favour of `TransactionMessage`\n\n### Patch Changes\n\n- Updated dependencies [[`b80b092`](https://github.com/anza-xyz/kit/commit/b80b09239762262116cb70b43271ad98a2f716b5), [`c391a44`](https://github.com/anza-xyz/kit/commit/c391a44eebd26707165991f8837f4d40fa988288), [`109c78e`](https://github.com/anza-xyz/kit/commit/109c78e8972857323558ca913706a95cdb70c549), [`6dbaf66`](https://github.com/anza-xyz/kit/commit/6dbaf66015198bd912ec0800c1db1fd63b68e7a2)]:\n    - @solana/errors@5.2.0\n    - @solana/codecs-core@5.2.0\n    - @solana/codecs-numbers@5.2.0\n    - @solana/codecs-strings@5.2.0\n    - @solana/keys@5.2.0\n    - @solana/transaction-messages@5.2.0\n    - @solana/addresses@5.2.0\n    - @solana/codecs-data-structures@5.2.0\n    - @solana/instructions@5.2.0\n    - @solana/rpc-types@5.2.0\n    - @solana/functional@5.2.0\n    - @solana/nominal-types@5.2.0\n\n## 5.1.0\n\n### Patch Changes\n\n- [#1040](https://github.com/anza-xyz/kit/pull/1040) [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c) Thanks [@OrmEmbaar](https://github.com/OrmEmbaar)! - Add a function called bytesEqual to codecs-core that you can use to compare two byte arrays for equality.\n\n- [#1058](https://github.com/anza-xyz/kit/pull/1058) [`2f7bda8`](https://github.com/anza-xyz/kit/commit/2f7bda81ca8248797957bdf693e812abc90b1951) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Remove `TransactionWithLifetime` from required input type for `signTransaction` and `partiallySignTransaction`\n\n- Updated dependencies [[`becf5f6`](https://github.com/anza-xyz/kit/commit/becf5f63f1b97d43109b2488c7cd0806ce6329f4), [`d7f5a0c`](https://github.com/anza-xyz/kit/commit/d7f5a0c046f0a2f2836554fa671364de0b512e97), [`32214f5`](https://github.com/anza-xyz/kit/commit/32214f57cfb79fb2566e773acec71635bac641df), [`32b13a8`](https://github.com/anza-xyz/kit/commit/32b13a8973fe0645af1f87f0068c289730b4062c), [`81a0eec`](https://github.com/anza-xyz/kit/commit/81a0eec57d196d4ce6b86897640dcab85c5deafd)]:\n    - @solana/errors@5.1.0\n    - @solana/codecs-strings@5.1.0\n    - @solana/addresses@5.1.0\n    - @solana/codecs-core@5.1.0\n    - @solana/transaction-messages@5.1.0\n    - @solana/codecs-data-structures@5.1.0\n    - @solana/codecs-numbers@5.1.0\n    - @solana/instructions@5.1.0\n    - @solana/keys@5.1.0\n    - @solana/rpc-types@5.1.0\n    - @solana/functional@5.1.0\n    - @solana/nominal-types@5.1.0\n\n## 5.0.0\n\n### Patch Changes\n\n- Updated dependencies [[`0fed638`](https://github.com/anza-xyz/kit/commit/0fed6389886639a48b44a09e129ac1b264c44389)]:\n    - @solana/rpc-types@5.0.0\n    - @solana/errors@5.0.0\n    - @solana/transaction-messages@5.0.0\n    - @solana/addresses@5.0.0\n    - @solana/codecs-core@5.0.0\n    - @solana/codecs-data-structures@5.0.0\n    - @solana/codecs-numbers@5.0.0\n    - @solana/codecs-strings@5.0.0\n    - @solana/instructions@5.0.0\n    - @solana/keys@5.0.0\n    - @solana/functional@5.0.0\n    - @solana/nominal-types@5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#918](https://github.com/anza-xyz/kit/pull/918) [`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add a function to extract the lifetime from a CompiledTransactionMessage\n\n- [#871](https://github.com/anza-xyz/kit/pull/871) [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Do not allow decoding transactions with an unsupported version\n\n- [#925](https://github.com/anza-xyz/kit/pull/925) [`af01f27`](https://github.com/anza-xyz/kit/commit/af01f2770e4b3a94f3ef3360677b27aa08175c1b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add functions to narrow a TransactionWithLifetime to a specific lifetime\n\n- Updated dependencies [[`5408f52`](https://github.com/anza-xyz/kit/commit/5408f524ae22293cb7b497310440019be5a98c55), [`f591dea`](https://github.com/anza-xyz/kit/commit/f591dead4a3d5871fd02460f6301bb4bdf6b508e), [`cb11699`](https://github.com/anza-xyz/kit/commit/cb11699d77536e5901c62d32e43c671b044e4aa1), [`9fa8465`](https://github.com/anza-xyz/kit/commit/9fa8465bf0f264f5a9181c805a0d85cb1ecc2768), [`ce7f91c`](https://github.com/anza-xyz/kit/commit/ce7f91c522118bd929f69f581d2d48e90d18c99a), [`22f18d0`](https://github.com/anza-xyz/kit/commit/22f18d0ce8950b26eaa897b146bfe8c1a025b3bb), [`c87cada`](https://github.com/anza-xyz/kit/commit/c87cada3ddf0a8c5fa27ed7122b901b17392c2df), [`54d8445`](https://github.com/anza-xyz/kit/commit/54d8445bbef207b6d84da0ea91a1c091251ee013)]:\n    - @solana/errors@4.0.0\n    - @solana/keys@4.0.0\n    - @solana/transaction-messages@4.0.0\n    - @solana/rpc-types@4.0.0\n    - @solana/codecs-core@4.0.0\n    - @solana/addresses@4.0.0\n    - @solana/codecs-data-structures@4.0.0\n    - @solana/codecs-numbers@4.0.0\n    - @solana/codecs-strings@4.0.0\n    - @solana/instructions@4.0.0\n    - @solana/functional@4.0.0\n    - @solana/nominal-types@4.0.0\n\n## 3.0.0\n\n### Major Changes\n\n- [#691](https://github.com/anza-xyz/kit/pull/691) [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: Removes the `assertTransactionIsFullySigned` deprecated function.\n\n- [#482](https://github.com/anza-xyz/kit/pull/482) [`00d66fb`](https://github.com/anza-xyz/kit/commit/00d66fbec15288bb531f7459b6baa48aead1cdc6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: Transactions must now satisfy the `SendableTransaction` type before being provided to helper functions that send transactions to the network. On top of ensuring the transaction is fully signed, this type also ensures the transaction is within size limit.\n\n- [#574](https://github.com/anza-xyz/kit/pull/574) [`0bd053b`](https://github.com/anza-xyz/kit/commit/0bd053bfa40b095d37bea7b7cd695259ba5a9cdc) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add the `TransactionWithLifetime` requirement when signing transactions. This is because, whilst a lifetime may not always be required before compile a transaction message, it is always required when signing a transaction. Otherwise, the transaction signatures will be invalid when one is added later.\n\n- [#581](https://github.com/anza-xyz/kit/pull/581) [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Allow transaction messages with no lifetime constraints to be compiled. Renames `TransactionFromCompilableTransactionMessage` and `SetTransactionLifetimeFromCompilableTransactionMessage` type helpers to `TransactionFromTransactionMessage` and `SetTransactionLifetimeFromTransactionMessage` respectively, to reflect that they can now be used with transaction messages that do not have a lifetime constraint.\n\n- [#462](https://github.com/anza-xyz/kit/pull/462) [`a74ea02`](https://github.com/anza-xyz/kit/commit/a74ea0267bf589fba50bb2ebe72dc4f73da9adcf) Thanks [@lorisleiva](https://github.com/lorisleiva)! - BREAKING CHANGE: The `FullySignedTransaction` no longer extends the `Transaction` type so it can be composed with other flags that also narrow transaction types. This means, whenever `FullySignedTransaction` is used on its own, it will need to be replaced with `FullySignedTransaction & Transaction`.\n\n### Minor Changes\n\n- [#583](https://github.com/anza-xyz/kit/pull/583) [`a894d53`](https://github.com/anza-xyz/kit/commit/a894d53192d50b5d2217ada2cb715d71ef4f8f02) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Allow transaction messages with no lifetime constraints in transaction size helpers — i.e. `getTransactionMessageSize`, `isTransactionMessageWithinSizeLimit` and `assertIsTransactionMessageWithinSizeLimit`.\n\n### Patch Changes\n\n- Updated dependencies [[`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`6a183bf`](https://github.com/anza-xyz/kit/commit/6a183bf9e9d672e2d42f3aecc589a9e54d01cb1a), [`760fb83`](https://github.com/anza-xyz/kit/commit/760fb8319f6b53fa1baf05f9aa1246cb6c2caceb), [`23d2fa1`](https://github.com/anza-xyz/kit/commit/23d2fa14cbd5197473eca94a1ac6c5abf221b052), [`771f8ae`](https://github.com/anza-xyz/kit/commit/771f8aef1f8c096450c6e4ac05b8611150201485), [`9feba85`](https://github.com/anza-xyz/kit/commit/9feba8557b64dd3199cd88af2c17b7ccd5d18fec), [`9205484`](https://github.com/anza-xyz/kit/commit/9205484d33af9426fc9de9594bab204b8f954faf), [`733605d`](https://github.com/anza-xyz/kit/commit/733605df84ce5f5ffea1e83eea8df74e08789642), [`01f159a`](https://github.com/anza-xyz/kit/commit/01f159a436d7a29479aa1a1877c9b4c77da1170f), [`98eabac`](https://github.com/anza-xyz/kit/commit/98eabac905759fc6809eaabb412a5846e3a773f0), [`55d6b04`](https://github.com/anza-xyz/kit/commit/55d6b040764f5e32de9c94d1844529855233d845)]:\n    - @solana/transaction-messages@3.0.0\n    - @solana/instructions@3.0.0\n    - @solana/errors@3.0.0\n    - @solana/codecs-data-structures@3.0.0\n    - @solana/codecs-core@3.0.0\n    - @solana/addresses@3.0.0\n    - @solana/codecs-numbers@3.0.0\n    - @solana/codecs-strings@3.0.0\n    - @solana/keys@3.0.0\n    - @solana/rpc-types@3.0.0\n    - @solana/functional@3.0.0\n    - @solana/nominal-types@3.0.0\n\n## 2.3.0\n\n### Minor Changes\n\n- [#468](https://github.com/anza-xyz/kit/pull/468) [`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add, remove and forward the `TransactionMessageWithinSizeLimit` and `TransactionWithinSizeLimit` types in all helpers that may affect the size of a transaction or transaction message.\n\n- [#479](https://github.com/anza-xyz/kit/pull/479) [`bbcb913`](https://github.com/anza-xyz/kit/commit/bbcb913839d33abc746f38d6e65e7bfd30cd2ac6) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Adds `isFullySignedTransaction` helper and renames `assertTransactionIsFullySigned` to `assertIsFullySignedTransaction`. The old name was kept as an alias but marked as deprecated.\n\n- [#426](https://github.com/anza-xyz/kit/pull/426) [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Deprecate the `I` prefix of four transaction message types to stay consistent with the rest of them. Namely, the following types are renamed and their old names are marked as deprecated:\n    - `ITransactionMessageWithFeePayer` -> `TransactionMessageWithFeePayer`\n    - `ITransactionMessageWithFeePayerSigner` -> `TransactionMessageWithFeePayerSigner`\n    - `ITransactionMessageWithSigners` -> `TransactionMessageWithSigners`\n    - `ITransactionMessageWithSingleSendingSigner` -> `TransactionMessageWithSingleSendingSigner`\n\n### Patch Changes\n\n- [#425](https://github.com/anza-xyz/kit/pull/425) [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add a variety of types, constants and functions to help with transaction sizes and their limits\n\n- Updated dependencies [[`6ccbf01`](https://github.com/anza-xyz/kit/commit/6ccbf012703fce1cb40388b0f4e1ffaeffea838a), [`53e1336`](https://github.com/anza-xyz/kit/commit/53e1336149878c84048e0fde5c7e7ace6cc1e97f), [`363e3cc`](https://github.com/anza-xyz/kit/commit/363e3cc45db77a731bab1435b925fe0ad0af01df), [`eb61d94`](https://github.com/anza-xyz/kit/commit/eb61d94786e212fc23778d445a94b86d2b1b024f), [`eeac21d`](https://github.com/anza-xyz/kit/commit/eeac21d5fe4d8fb3ed3addee87872679ee37b4c4), [`93609aa`](https://github.com/anza-xyz/kit/commit/93609aa31dbd83086d0debd41aa2f8e9a0809761), [`b7dfe03`](https://github.com/anza-xyz/kit/commit/b7dfe033a8e929d7a598d8bfea546e9ef4207639), [`e6c0568`](https://github.com/anza-xyz/kit/commit/e6c0568ef34fdc04075af27eb102851123a02be0), [`810d6ab`](https://github.com/anza-xyz/kit/commit/810d6abafe1b7ea46ed63c491db1f5d6c16397ab)]:\n    - @solana/transaction-messages@2.3.0\n    - @solana/errors@2.3.0\n    - @solana/instructions@2.3.0\n    - @solana/addresses@2.3.0\n    - @solana/codecs-core@2.3.0\n    - @solana/codecs-data-structures@2.3.0\n    - @solana/codecs-numbers@2.3.0\n    - @solana/codecs-strings@2.3.0\n    - @solana/keys@2.3.0\n    - @solana/rpc-types@2.3.0\n    - @solana/functional@2.3.0\n    - @solana/nominal-types@2.3.0\n\n## 2.2.1\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.2.1\n    - @solana/codecs-core@2.2.1\n    - @solana/codecs-data-structures@2.2.1\n    - @solana/codecs-numbers@2.2.1\n    - @solana/codecs-strings@2.2.1\n    - @solana/errors@2.2.1\n    - @solana/functional@2.2.1\n    - @solana/instructions@2.2.1\n    - @solana/keys@2.2.1\n    - @solana/nominal-types@2.2.1\n    - @solana/rpc-types@2.2.1\n    - @solana/transaction-messages@2.2.1\n\n## 2.2.0\n\n### Patch Changes\n\n- Updated dependencies [[`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893), [`85925d6`](https://github.com/anza-xyz/kit/commit/85925d64308e91b59fb748c75e4b414012eb4893)]:\n    - @solana/nominal-types@2.2.0\n    - @solana/addresses@2.2.0\n    - @solana/keys@2.2.0\n    - @solana/rpc-types@2.2.0\n    - @solana/transaction-messages@2.2.0\n    - @solana/instructions@2.2.0\n    - @solana/codecs-core@2.2.0\n    - @solana/codecs-data-structures@2.2.0\n    - @solana/codecs-numbers@2.2.0\n    - @solana/codecs-strings@2.2.0\n    - @solana/errors@2.2.0\n    - @solana/functional@2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n- Updated dependencies [[`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`41b679c`](https://github.com/anza-xyz/kit/commit/41b679c2646029c9c7f005de55fba687e3c89e8a), [`776e18d`](https://github.com/anza-xyz/kit/commit/776e18d75c759a839608069c61da3f70b775540b), [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2)]:\n    - @solana/codecs-data-structures@2.1.1\n    - @solana/transaction-messages@2.1.1\n    - @solana/codecs-numbers@2.1.1\n    - @solana/codecs-strings@2.1.1\n    - @solana/nominal-types@2.1.1\n    - @solana/instructions@2.1.1\n    - @solana/codecs-core@2.1.1\n    - @solana/functional@2.1.1\n    - @solana/addresses@2.1.1\n    - @solana/rpc-types@2.1.1\n    - @solana/errors@2.1.1\n    - @solana/keys@2.1.1\n\n## 2.1.0\n\n### Patch Changes\n\n- Updated dependencies [[`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d), [`d1c787c`](https://github.com/anza-xyz/kit/commit/d1c787c447bd134e6a6da8be059c8353f92b2f9a), [`0c577eb`](https://github.com/anza-xyz/kit/commit/0c577eb03fa5db8b817f209d52a19a36976c7c12), [`cfe6910`](https://github.com/anza-xyz/kit/commit/cfe691010a493d06983a8a2728cda9751135906d), [`c7b7dd9`](https://github.com/anza-xyz/kit/commit/c7b7dd99aca878d2450760c214dbea593ddbadc0), [`9b179dc`](https://github.com/anza-xyz/kit/commit/9b179dc6b7c7e6e4d51481a396567f17665abbc3), [`400f4d5`](https://github.com/anza-xyz/kit/commit/400f4d5673286a197561033bba63bac9a433cc6a), [`5af7f20`](https://github.com/anza-xyz/kit/commit/5af7f2013135a79893a0f190a905c6dd077ac38c), [`704d8a2`](https://github.com/anza-xyz/kit/commit/704d8a220592a5a472bd7726013814b50c991f5b)]:\n    - @solana/addresses@2.1.0\n    - @solana/codecs-core@2.1.0\n    - @solana/codecs-data-structures@2.1.0\n    - @solana/codecs-numbers@2.1.0\n    - @solana/codecs-strings@2.1.0\n    - @solana/errors@2.1.0\n    - @solana/keys@2.1.0\n    - @solana/rpc-types@2.1.0\n    - @solana/transaction-messages@2.1.0\n    - @solana/instructions@2.1.0\n    - @solana/functional@2.1.0\n\n## 2.0.0\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#2412](https://github.com/solana-labs/solana-web3.js/pull/2412) [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed the size option of `getBytesCodec`\n\n    The `getBytesCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode byte arrays. In order to fix or prefix the size of a `getBytesCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getBytesCodec(); // Variable.\n    getBytesCodec({ size: 5 }); // Fixed.\n    getBytesCodec({ size: getU16Codec() }); // Prefixed.\n\n    // After.\n    getBytesCodec(); // Variable.\n    fixCodecSize(getBytesCodec(), 5); // Fixed.\n    addCodecSizePrefix(getBytesCodec(), getU16Codec()); // Prefixed.\n    ```\n\n- [#2550](https://github.com/solana-labs/solana-web3.js/pull/2550) [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor transactions, to separate constructing transaction messages from signing/sending compiled transactions\n\n    A transaction message contains a transaction version and an array of transaction instructions. It may also have a fee payer and a lifetime. Transaction messages can be built up incrementally, for example by adding instructions or a fee payer.\n\n    Transactions represent a compiled transaction message (serialized to an immutable byte array) and a map of signatures for each required signer of the transaction message. These signatures are only valid for the byte array stored in the transaction. Transactions can be signed by updating this map of signatures, and when they have a valid signature for all required signers they can be landed on the network.\n\n    Note that this change essentially splits the previous `@solana/transactions` API in two, with functionality for creating/modifying transaction messages moved to `@solana/transaction-messages`.\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6), [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac), [`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0\n    - @solana/codecs-data-structures@2.0.0\n    - @solana/codecs-strings@2.0.0\n    - @solana/codecs-core@2.0.0\n    - @solana/addresses@2.0.0\n    - @solana/rpc-types@2.0.0\n    - @solana/keys@2.0.0\n    - @solana/codecs-numbers@2.0.0\n    - @solana/transaction-messages@2.0.0\n    - @solana/instructions@2.0.0\n    - @solana/functional@2.0.0\n\n## 2.0.0-rc.4\n\n### Patch Changes\n\n- Updated dependencies [[`2798061`](https://github.com/solana-labs/solana-web3.js/commit/27980617e4f8d34dbc7b6da4507e4bca68a68090)]:\n    - @solana/errors@2.0.0-rc.4\n    - @solana/addresses@2.0.0-rc.4\n    - @solana/codecs-core@2.0.0-rc.4\n    - @solana/codecs-data-structures@2.0.0-rc.4\n    - @solana/codecs-numbers@2.0.0-rc.4\n    - @solana/codecs-strings@2.0.0-rc.4\n    - @solana/instructions@2.0.0-rc.4\n    - @solana/keys@2.0.0-rc.4\n    - @solana/rpc-types@2.0.0-rc.4\n    - @solana/transaction-messages@2.0.0-rc.4\n    - @solana/functional@2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@2.0.0-rc.3\n    - @solana/codecs-core@2.0.0-rc.3\n    - @solana/codecs-data-structures@2.0.0-rc.3\n    - @solana/codecs-numbers@2.0.0-rc.3\n    - @solana/codecs-strings@2.0.0-rc.3\n    - @solana/errors@2.0.0-rc.3\n    - @solana/functional@2.0.0-rc.3\n    - @solana/instructions@2.0.0-rc.3\n    - @solana/keys@2.0.0-rc.3\n    - @solana/rpc-types@2.0.0-rc.3\n    - @solana/transaction-messages@2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n- Updated dependencies [[`292487d`](https://github.com/solana-labs/solana-web3.js/commit/292487da00ee57350e8faf49ccf961203aed6403), [`3834d82`](https://github.com/solana-labs/solana-web3.js/commit/3834d82eb1dd150f261612d742c3105194689c13), [`0245265`](https://github.com/solana-labs/solana-web3.js/commit/024526554fa0145e31e62a0d47f1eea556a30e71), [`231a030`](https://github.com/solana-labs/solana-web3.js/commit/231a0303ae5960e783719a8ff1d17a50ff26ad78), [`38faba0`](https://github.com/solana-labs/solana-web3.js/commit/38faba05fab479ddbd95d0e211744d203f8aa823), [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a), [`0158b31`](https://github.com/solana-labs/solana-web3.js/commit/0158b3181ed96996f269f3bff689f76411e460b3)]:\n    - @solana/addresses@2.0.0-rc.2\n    - @solana/rpc-types@2.0.0-rc.2\n    - @solana/transaction-messages@2.0.0-rc.2\n    - @solana/errors@2.0.0-rc.2\n    - @solana/codecs-data-structures@2.0.0-rc.2\n    - @solana/codecs-numbers@2.0.0-rc.2\n    - @solana/codecs-strings@2.0.0-rc.2\n    - @solana/instructions@2.0.0-rc.2\n    - @solana/codecs-core@2.0.0-rc.2\n    - @solana/functional@2.0.0-rc.2\n    - @solana/keys@2.0.0-rc.2\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- Updated dependencies [[`7d310f6`](https://github.com/solana-labs/solana-web3.js/commit/7d310f6f9cd7d02fca4d6f8e311b857c9dd84e61), [`f9a8446`](https://github.com/solana-labs/solana-web3.js/commit/f9a84460670a97d4ab6514b28fe0d29c6fac3302)]:\n    - @solana/keys@2.0.0-rc.1\n    - @solana/addresses@2.0.0-rc.1\n    - @solana/codecs-core@2.0.0-rc.1\n    - @solana/codecs-data-structures@2.0.0-rc.1\n    - @solana/codecs-numbers@2.0.0-rc.1\n    - @solana/codecs-strings@2.0.0-rc.1\n    - @solana/errors@2.0.0-rc.1\n    - @solana/functional@2.0.0-rc.1\n    - @solana/instructions@2.0.0-rc.1\n    - @solana/rpc-types@2.0.0-rc.1\n    - @solana/transaction-messages@2.0.0-rc.1\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- Updated dependencies [[`419c12e`](https://github.com/solana-labs/solana-web3.js/commit/419c12e617435570d0cded6ca6d35370d0060da7), [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4)]:\n    - @solana/transaction-messages@2.0.0-rc.0\n    - @solana/errors@2.0.0-rc.0\n    - @solana/addresses@2.0.0-rc.0\n    - @solana/codecs-core@2.0.0-rc.0\n    - @solana/codecs-data-structures@2.0.0-rc.0\n    - @solana/codecs-numbers@2.0.0-rc.0\n    - @solana/codecs-strings@2.0.0-rc.0\n    - @solana/instructions@2.0.0-rc.0\n    - @solana/keys@2.0.0-rc.0\n    - @solana/rpc-types@2.0.0-rc.0\n    - @solana/functional@2.0.0-rc.0\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- Updated dependencies [[`3bf31e7`](https://github.com/solana-labs/solana-web3.js/commit/3bf31e7b7918cb60cd9f5f4476909d81257cdfd7), [`26dae19`](https://github.com/solana-labs/solana-web3.js/commit/26dae190c2ec835fbdaa7b7d66ca33d6ba0727b8), [`4f19842`](https://github.com/solana-labs/solana-web3.js/commit/4f198423997d28d927f982333d268e19940656df), [`73bd5a9`](https://github.com/solana-labs/solana-web3.js/commit/73bd5a9e0b32846cd5d76f2d2d1b21661eab0677), [`be36bab`](https://github.com/solana-labs/solana-web3.js/commit/be36babd752b1c987a2f53b4ff83ac8c045a3418), [`cb49bfa`](https://github.com/solana-labs/solana-web3.js/commit/cb49bfa28f412376a41e758eeda59e7e90983147), [`3d90241`](https://github.com/solana-labs/solana-web3.js/commit/3d902419c1b232fa7145757b9c95976de69790c7), [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b)]:\n    - @solana/codecs-strings@2.0.0-preview.4\n    - @solana/codecs-data-structures@2.0.0-preview.4\n    - @solana/errors@2.0.0-preview.4\n    - @solana/rpc-types@2.0.0-preview.4\n    - @solana/keys@2.0.0-preview.4\n    - @solana/transaction-messages@2.0.0-preview.4\n    - @solana/codecs-numbers@2.0.0-preview.4\n    - @solana/instructions@2.0.0-preview.4\n    - @solana/codecs-core@2.0.0-preview.4\n    - @solana/functional@2.0.0-preview.4\n    - @solana/addresses@2.0.0-preview.4\n\n## 2.0.0-preview.3\n\n### Patch Changes\n\n- [#2434](https://github.com/solana-labs/solana-web3.js/pull/2434) [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Renamed `mapCodec` to `transformCodec`\n\n- [#2413](https://github.com/solana-labs/solana-web3.js/pull/2413) [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed `getStringCodec` in favour of `fixCodecSize` and `addCodecSizePrefix`\n\n    The `getStringCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode strings. In order to fix or prefix the size of a `getStringCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getStringCodec({ size: 'variable' }); // Variable.\n    getStringCodec({ encoding: getUtf8Codec(), size: 'variable' }); // Variable (equivalent).\n    getStringCodec({ size: 5 }); // Fixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: 5 }); // Fixed (equivalent).\n    getStringCodec(); // Prefixed.\n    getStringCodec({ encoding: getUtf8Codec(), size: getU32Codec() }); // Prefixed (equivalent).\n\n    // After.\n    getUtf8Codec(); // Variable.\n    fixCodecSize(getUtf8Codec(), 5); // Fixed.\n    addCodecSizePrefix(getUtf8Codec(), getU32Codec()); // Prefixed.\n    ```\n\n- [#2412](https://github.com/solana-labs/solana-web3.js/pull/2412) [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Removed the size option of `getBytesCodec`\n\n    The `getBytesCodec` function now always returns a `VariableSizeCodec` that uses as many bytes as necessary to encode and/or decode byte arrays. In order to fix or prefix the size of a `getBytesCodec`, you may now use the `fixCodecSize` or `prefixCodecSide` accordingly. Here are some examples:\n\n    ```ts\n    // Before.\n    getBytesCodec(); // Variable.\n    getBytesCodec({ size: 5 }); // Fixed.\n    getBytesCodec({ size: getU16Codec() }); // Prefixed.\n\n    // After.\n    getBytesCodec(); // Variable.\n    fixCodecSize(getBytesCodec(), 5); // Fixed.\n    addCodecSizePrefix(getBytesCodec(), getU16Codec()); // Prefixed.\n    ```\n\n- [#2550](https://github.com/solana-labs/solana-web3.js/pull/2550) [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Refactor transactions, to separate constructing transaction messages from signing/sending compiled transactions\n\n    A transaction message contains a transaction version and an array of transaction instructions. It may also have a fee payer and a lifetime. Transaction messages can be built up incrementally, for example by adding instructions or a fee payer.\n\n    Transactions represent a compiled transaction message (serialized to an immutable byte array) and a map of signatures for each required signer of the transaction message. These signatures are only valid for the byte array stored in the transaction. Transactions can be signed by updating this map of signatures, and when they have a valid signature for all required signers they can be landed on the network.\n\n    Note that this change essentially splits the previous `@solana/transactions` API in two, with functionality for creating/modifying transaction messages moved to `@solana/transaction-messages`.\n\n- Updated dependencies [[`9370133`](https://github.com/solana-labs/solana-web3.js/commit/9370133e414bfa863517248d97905449e9a867eb), [`31916ae`](https://github.com/solana-labs/solana-web3.js/commit/31916ae5d4fb29f239c63252a59745e33a6979ea), [`a548de2`](https://github.com/solana-labs/solana-web3.js/commit/a548de2ebe3cf7289fd126933c4c395c885c3224), [`ff4aff6`](https://github.com/solana-labs/solana-web3.js/commit/ff4aff61c05c0ae5bfb62d35353d9527588b39b6), [`89f399d`](https://github.com/solana-labs/solana-web3.js/commit/89f399d474abac463b1daaa864c88305d7b8c21f), [`deb7b80`](https://github.com/solana-labs/solana-web3.js/commit/deb7b806b4cbe620b1714be1765c981d88c3a2f6), [`6dcf548`](https://github.com/solana-labs/solana-web3.js/commit/6dcf5483bb6bbb8d343db28dedb258c8da91ffac), [`ebb03cd`](https://github.com/solana-labs/solana-web3.js/commit/ebb03cd8270027db957d4cecc7d2374d468d4ccb), [`49a764c`](https://github.com/solana-labs/solana-web3.js/commit/49a764c6d481886501540f8dbfe8be75d754355b), [`002cc38`](https://github.com/solana-labs/solana-web3.js/commit/002cc38a99cd4c91c7ce9023e1b4fb28f7e10832), [`ce1be3f`](https://github.com/solana-labs/solana-web3.js/commit/ce1be3fe37ea9b744fd836f3d6c2c8e5e31efd77), [`82cf07f`](https://github.com/solana-labs/solana-web3.js/commit/82cf07f4e905f6b056e70a0463a94222c3e7cadd), [`2d54650`](https://github.com/solana-labs/solana-web3.js/commit/2d5465018d8060eceb00efbf4f718df26d145199), [`bef9604`](https://github.com/solana-labs/solana-web3.js/commit/bef960435eb2303395bfa76e44f84d3348c5722d), [`7e86583`](https://github.com/solana-labs/solana-web3.js/commit/7e86583da68695076ec62033f3fe078b3890f026), [`919c736`](https://github.com/solana-labs/solana-web3.js/commit/919c7367dec8e142746295128cc6c2cc6752e636), [`2e5af9f`](https://github.com/solana-labs/solana-web3.js/commit/2e5af9f1a9410f15108863342b48225fdf9a0c83), [`2d48c09`](https://github.com/solana-labs/solana-web3.js/commit/2d48c0954a3823b937a9b4e572a8d63cd7e4631c), [`e3e82d9`](https://github.com/solana-labs/solana-web3.js/commit/e3e82d909825e958ae234ed18500335a621773bd), [`54d68c4`](https://github.com/solana-labs/solana-web3.js/commit/54d68c482feebf4e62a9896b3badd77dab615941), [`288029a`](https://github.com/solana-labs/solana-web3.js/commit/288029a55a5eeb863b6df960027a59214ffc37f1), [`4ae78f5`](https://github.com/solana-labs/solana-web3.js/commit/4ae78f5cdddd6772b25351beb813483d4e52cea6), [`478443f`](https://github.com/solana-labs/solana-web3.js/commit/478443fedac06678f12e8ac285aa7c7fcf503ee8), [`bf029dd`](https://github.com/solana-labs/solana-web3.js/commit/bf029dd90230405b3d59f70aedd57fc0117b926e), [`125fc15`](https://github.com/solana-labs/solana-web3.js/commit/125fc1540cfbc0a4afdba5aabac0884c750e58c1)]:\n    - @solana/errors@2.0.0-preview.3\n    - @solana/codecs-data-structures@2.0.0-preview.3\n    - @solana/codecs-strings@2.0.0-preview.3\n    - @solana/codecs-core@2.0.0-preview.3\n    - @solana/addresses@2.0.0-preview.3\n    - @solana/rpc-types@2.0.0-preview.3\n    - @solana/codecs-numbers@2.0.0-preview.3\n    - @solana/transaction-messages@2.0.0-preview.3\n    - @solana/keys@2.0.0-preview.3\n    - @solana/instructions@2.0.0-preview.3\n    - @solana/functional@2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n\n- Updated dependencies [[`0546a8c`](https://github.com/solana-labs/solana-web3.js/commit/0546a8ce95b6852324d58bb32ac31480506193a7)]:\n    - @solana/addresses@2.0.0-preview.2\n    - @solana/codecs-core@2.0.0-preview.2\n    - @solana/codecs-data-structures@2.0.0-preview.2\n    - @solana/codecs-numbers@2.0.0-preview.2\n    - @solana/codecs-strings@2.0.0-preview.2\n    - @solana/errors@2.0.0-preview.2\n    - @solana/functional@2.0.0-preview.2\n    - @solana/keys@2.0.0-preview.2\n"
  },
  {
    "path": "packages/transactions/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/transactions/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/transactions?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/transactions?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/transactions\n\n# @solana/transactions\n\nThis package contains types and functions for compiling, signing and sending transactions. It can be used standalone, but it is also exported as part of Kit [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n\nTransactions are created by compiling a transaction message. They must then be signed before being submitted to the network.\n\n## Compiling a transaction\n\n### Functions\n\n#### `compileTransaction()`\n\nGiven a `TransactionMessage`, this function returns a `Transaction` object. This includes the compiled bytes of the transaction message, and a map of signatures. This map will have a key for each address that is required to sign the transaction. The transaction will not yet have signatures for any of these addresses.\n\nWhether a transaction message is ready to be compiled or not is enforced for you at the type level. In order to be signable, a transaction message must:\n\n- have a version and a list of zero or more instructions (ie. conform to `TransactionMessage`)\n- have a fee payer set (ie. conform to `TransactionMessageWithFeePayer`)\n- have a lifetime specified (ie. conform to `TransactionMessageWithBlockhashLifetime | TransactionMessageWithDurableNonceLifetime`)\n\n## Signing transactions\n\nIn order to be landed on the network, a transaction must be signed by all of the private keys belonging to accounts that are required signers of the transaction.\n\n### Types\n\n#### `FullySignedTransaction`\n\nThis type represents a transaction that is signed by all of its required signers.\n\n#### `TransactionWithSizeLimit`\n\nThis type represents a transaction that is under or equal to the maximum size limit for transactions on the Solana network.\n\n#### `SendableTransaction`\n\nThis type represents a transaction that has all the required conditions to be sent to the network. Namely:\n\n- It must be fully signed (ie. conform to `FullySignedTransaction`)\n- It must be within size limit (ie. conform to `TransactionWithSizeLimit`)\n\nThe `SendableTransaction` type is a prerequisite of functions designed to land transactions on the network.\n\n### Functions\n\n#### `getSignatureFromTransaction()`\n\nGiven a transaction signed by its fee payer, this method will return the `Signature` that uniquely identifies it. This string can be used to look up transactions at a later date, for example on a Solana block explorer.\n\n```ts\nimport { getSignatureFromTransaction } from '@solana/transactions';\n\nconst signature = getSignatureFromTransaction(tx);\nconsole.debug(`Inspect this transaction at https://explorer.solana.com/tx/${signature}`);\n```\n\n### `signTransaction()`\n\nGiven an array of `CryptoKey` objects which are private keys pertaining to addresses that are required to sign a transaction, this method will return a new signed transaction of type `FullySignedTransaction`. This function will throw unless the resulting transaction is fully signed.\n\n```ts\nimport { generateKeyPair } from '@solana/keys';\nimport { signTransaction } from '@solana/transactions';\n\nconst signedTransaction = await signTransaction([myPrivateKey], tx);\n```\n\n### `partiallySignTransaction()`\n\nThis function is the same as `signTransaction()` but does not require the transaction to be signed by all signers. A partially signed transaction cannot be landed on the network, but can be serialized and deserialized.\n\n## Serializing transactions\n\nBefore sending a transaction to be landed on the network, you must serialize it in a particular way. You can use these types and functions to serialize a signed transaction into a binary format suitable for transit over the wire.\n\n### Types\n\n#### `Base64EncodedWireTransaction`\n\nThis type represents the wire format of a transaction as a base64-encoded string.\n\n### Functions\n\n#### `getBase64EncodedWireTransaction()`\n\nGiven a signed transaction, this method returns the transaction as a string that conforms to the `Base64EncodedWireTransaction` type.\n\n```ts\nimport { getBase64EncodedWireTransaction, signTransaction } from '@solana/transactions';\n\nconst serializedTransaction = getBase64EncodedWireTransaction(signedTransaction);\nconst signature = await rpc.sendTransaction(serializedTransaction, { encoding: 'base64' }).send();\n```\n"
  },
  {
    "path": "packages/transactions/package.json",
    "content": "{\n    \"name\": \"@solana/transactions\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Helpers for creating and serializing transactions\",\n    \"homepage\": \"https://www.solanakit.com/api#solanatransactions\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/codecs-data-structures\": \"workspace:*\",\n        \"@solana/codecs-numbers\": \"workspace:*\",\n        \"@solana/codecs-strings\": \"workspace:*\",\n        \"@solana/errors\": \"workspace:*\",\n        \"@solana/functional\": \"workspace:*\",\n        \"@solana/instructions\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/nominal-types\": \"workspace:*\",\n        \"@solana/rpc-types\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/transactions/src/__tests__/compile-transaction-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { Blockhash } from '@solana/rpc-types';\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    compileTransactionMessage,\n    getCompiledTransactionMessageEncoder,\n    Nonce,\n    setTransactionMessageLifetimeUsingDurableNonce,\n    TransactionMessageWithBlockhashLifetime,\n} from '@solana/transaction-messages';\n\nimport { compileTransaction } from '../compile-transaction';\n\njest.mock('@solana/transaction-messages', () => ({\n    ...jest.requireActual('@solana/transaction-messages'),\n    compileTransactionMessage: jest.fn(),\n    getCompiledTransactionMessageEncoder: jest.fn(),\n}));\n\ntype TransactionMessage = Parameters<typeof compileTransaction>[0];\n\ndescribe('compileTransactionMessage', () => {\n    const mockAddressA = '2aaa' as Address;\n    const mockAddressB = '1aaa' as Address;\n    const mockCompiledMessage = {\n        header: {\n            numReadonlyNonSignerAccounts: 0,\n            numReadonlySignerAccounts: 0,\n            numSignerAccounts: 2,\n        },\n        instructions: [],\n        lifetimeToken: 'a',\n        staticAccounts: [mockAddressA, mockAddressB],\n        version: 0,\n    } as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n    const mockCompiledMessageBytes = new Uint8Array(Array(100)).fill(1);\n    beforeEach(() => {\n        (compileTransactionMessage as jest.Mock).mockReturnValue(mockCompiledMessage);\n        (getCompiledTransactionMessageEncoder as jest.Mock).mockReturnValue({\n            encode: jest.fn().mockReturnValue(mockCompiledMessageBytes),\n        });\n    });\n\n    const emptyMockTransactionMessage = { instructions: [] } as unknown as TransactionMessage;\n\n    it('compiles the supplied `TransactionMessage` and sets the `messageBytes` property to the result', () => {\n        const transaction = compileTransaction(emptyMockTransactionMessage);\n        expect(transaction).toHaveProperty('messageBytes', mockCompiledMessageBytes);\n    });\n    it('compiles an array of signatures the length of the number of signers', () => {\n        const transaction = compileTransaction(emptyMockTransactionMessage);\n        expect(Object.keys(transaction.signatures)).toHaveLength(mockCompiledMessage.header.numSignerAccounts);\n    });\n    it(\"inserts signers into the correct position in the signatures' array\", () => {\n        const transaction = compileTransaction(emptyMockTransactionMessage);\n        expect(Object.keys(transaction.signatures)).toStrictEqual([\n            // Two signers, in the order they're found in `mockCompiledMessage.staticAccounts`\n            mockAddressA,\n            mockAddressB,\n        ]);\n    });\n    it('inserts a null signature into the map for each signer', () => {\n        const transaction = compileTransaction(emptyMockTransactionMessage);\n        expect(Object.values(transaction.signatures)).toStrictEqual([null, null]);\n    });\n    it('freezes the returned transaction', () => {\n        const transaction = compileTransaction(emptyMockTransactionMessage);\n        expect(transaction).toBeFrozenObject();\n    });\n\n    it('returns a blockhash lifetime constraint when the transaction message has a blockhash constraint', () => {\n        const transactionMessage = {\n            lifetimeConstraint: {\n                blockhash: 'D5vmAVFNZFaBBZNJ17tMaVrcsQ9DZViL9bAZn1n1Kxer' as Blockhash,\n                lastValidBlockHeight: 1n,\n            },\n        } as TransactionMessage & TransactionMessageWithBlockhashLifetime;\n        const transaction = compileTransaction(transactionMessage);\n        expect(transaction.lifetimeConstraint).toStrictEqual({\n            blockhash: 'D5vmAVFNZFaBBZNJ17tMaVrcsQ9DZViL9bAZn1n1Kxer' as Blockhash,\n            lastValidBlockHeight: 1n,\n        });\n    });\n\n    it('returns a durable nonce lifetime constraint when the transaction message has a nonce constraint', () => {\n        const transactionMessage = setTransactionMessageLifetimeUsingDurableNonce(\n            {\n                nonce: 'b' as Nonce,\n                nonceAccountAddress: 'nonceAddress' as Address,\n                nonceAuthorityAddress: 'nonceAuthorityAddress' as Address,\n            },\n            emptyMockTransactionMessage,\n        );\n        const transaction = compileTransaction(transactionMessage);\n        expect(transaction.lifetimeConstraint).toStrictEqual({\n            nonce: 'b' as Nonce,\n            nonceAccountAddress: 'nonceAddress',\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transactions/src/__tests__/lifetime-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX,\n    SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED,\n    SolanaError,\n} from '@solana/errors';\nimport { Blockhash } from '@solana/rpc-types';\nimport {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    Nonce,\n} from '@solana/transaction-messages';\n\nimport {\n    assertIsTransactionWithBlockhashLifetime,\n    assertIsTransactionWithDurableNonceLifetime,\n    getTransactionLifetimeConstraintFromCompiledTransactionMessage,\n} from '../lifetime';\nimport { Transaction, TransactionMessageBytes } from '../transaction';\n\nconst SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111' as Address;\nconst U64_MAX = 2n ** 64n - 1n;\n\ndescribe('getTransactionLifetimeConstraintFromCompiledTransactionMessage', () => {\n    describe.each(['legacy', 0] as const)('for a %s transaction message', version => {\n        it('returns a blockhash transaction lifetime when there are no instructions', async () => {\n            expect.assertions(1);\n            const compiledTransactionMessage = {\n                instructions: [],\n                lifetimeToken: 'abc',\n                version,\n            } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n            await expect(\n                getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n            ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n        });\n\n        describe('returns a blockhash transaction lifetime when the first instruction is not an AdvanceNonceAccount instruction', () => {\n            it('because the program is not the System Program', async () => {\n                expect.assertions(1);\n                const compiledTransactionMessage = {\n                    instructions: [\n                        {\n                            accountIndices: [1, 2, 3],\n                            data: new Uint8Array([4, 0, 0, 0]),\n                            programAddressIndex: 0,\n                        },\n                    ],\n                    lifetimeToken: 'abc',\n                    staticAccounts: ['otherProgramAddress'],\n                    version,\n                } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n                await expect(\n                    getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n                ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n            });\n\n            it('because the instruction data is not for AdvanceNonceAccount', async () => {\n                expect.assertions(1);\n                const compiledTransactionMessage = {\n                    instructions: [\n                        {\n                            accountIndices: [1, 2, 3],\n                            data: new Uint8Array([1, 0, 0, 0]),\n                            programAddressIndex: 0,\n                        },\n                    ],\n                    lifetimeToken: 'abc',\n                    staticAccounts: [SYSTEM_PROGRAM_ADDRESS],\n                    version,\n                } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n                await expect(\n                    getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n                ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n            });\n\n            it('because the instruction does not have exactly 3 accounts', async () => {\n                expect.assertions(1);\n                const compiledTransactionMessage = {\n                    instructions: [\n                        {\n                            accountIndices: [1, 2],\n                            data: new Uint8Array([4, 0, 0, 0]),\n                            programAddressIndex: 0,\n                        },\n                    ],\n                    lifetimeToken: 'abc',\n                    staticAccounts: [SYSTEM_PROGRAM_ADDRESS],\n                    version,\n                } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n                await expect(\n                    getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n                ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n            });\n\n            it('because it has no account indices', async () => {\n                expect.assertions(1);\n                const compiledTransactionMessage = {\n                    instructions: [\n                        {\n                            data: new Uint8Array([4, 0, 0, 0]),\n                            programAddressIndex: 0,\n                        },\n                    ],\n                    lifetimeToken: 'abc',\n                    staticAccounts: [SYSTEM_PROGRAM_ADDRESS],\n                    version,\n                } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n                await expect(\n                    getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n                ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n            });\n        });\n\n        it('returns a durable nonce transaction lifetime when the first instruction is an AdvanceNonceAccount instruction', async () => {\n            expect.assertions(1);\n            const compiledTransactionMessage = {\n                instructions: [\n                    {\n                        accountIndices: [1, 2, 3],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 0,\n                    },\n                ],\n                lifetimeToken: 'abc',\n                staticAccounts: [\n                    '11111111111111111111111111111111',\n                    'nonceAccountAddress',\n                    'recentBlockhashesSysvarAddress',\n                    'nonceAuthorityAddress',\n                ],\n                version,\n            } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n            await expect(\n                getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n            ).resolves.toEqual({ nonce: 'abc' as Nonce, nonceAccountAddress: 'nonceAccountAddress' });\n        });\n\n        it('fatals if the nonce account address is not in static accounts', async () => {\n            expect.assertions(1);\n            const compiledTransactionMessage = {\n                instructions: [\n                    {\n                        accountIndices: [1, 2, 3],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 0,\n                    },\n                ],\n                lifetimeToken: 'abc',\n                staticAccounts: ['11111111111111111111111111111111'],\n                version,\n            } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n            await expect(() =>\n                getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n            ).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n                    nonce: 'abc',\n                }),\n            );\n        });\n    });\n\n    describe('for a v1 transaction message', () => {\n        it('returns a blockhash transaction lifetime when there are no instructions', async () => {\n            expect.assertions(1);\n            const compiledTransactionMessage = {\n                instructionHeaders: [],\n                instructionPayloads: [],\n                lifetimeToken: 'abc',\n                version: 1,\n            } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n            await expect(\n                getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n            ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n        });\n\n        describe('returns a blockhash transaction lifetime when the first instruction is not an AdvanceNonceAccount instruction', () => {\n            it('because the program is not the System Program', async () => {\n                expect.assertions(1);\n                const compiledTransactionMessage = {\n                    instructionHeaders: [\n                        { numInstructionAccounts: 3, numInstructionDataBytes: 4, programAccountIndex: 0 },\n                    ],\n                    instructionPayloads: [\n                        { instructionAccountIndices: [1, 2, 3], instructionData: new Uint8Array([4, 0, 0, 0]) },\n                    ],\n                    lifetimeToken: 'abc',\n                    staticAccounts: ['otherProgramAddress', 'abc', 'def', 'ghi'],\n                    version: 1,\n                } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n                await expect(\n                    getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n                ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n            });\n\n            it('because the instruction data is not for AdvanceNonceAccount', async () => {\n                expect.assertions(1);\n                const compiledTransactionMessage = {\n                    instructionHeaders: [\n                        { numInstructionAccounts: 3, numInstructionDataBytes: 4, programAccountIndex: 0 },\n                    ],\n                    instructionPayloads: [\n                        { instructionAccountIndices: [1, 2, 3], instructionData: new Uint8Array([1, 0, 0, 0]) },\n                    ],\n                    lifetimeToken: 'abc',\n                    staticAccounts: [SYSTEM_PROGRAM_ADDRESS, 'abc', 'def', 'ghi'],\n                    version: 1,\n                } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n                await expect(\n                    getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n                ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n            });\n\n            it('because the instruction does not have exactly 3 accounts', async () => {\n                expect.assertions(1);\n                const compiledTransactionMessage = {\n                    instructionHeaders: [\n                        { numInstructionAccounts: 2, numInstructionDataBytes: 4, programAccountIndex: 0 },\n                    ],\n                    instructionPayloads: [\n                        { instructionAccountIndices: [1, 2], instructionData: new Uint8Array([4, 0, 0, 0]) },\n                    ],\n                    instructions: [\n                        {\n                            accountIndices: [1, 2],\n                            data: new Uint8Array([4, 0, 0, 0]),\n                            programAddressIndex: 0,\n                        },\n                    ],\n                    lifetimeToken: 'abc',\n                    staticAccounts: [SYSTEM_PROGRAM_ADDRESS, 'abc', 'def', 'ghi'],\n                    version: 1,\n                } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n                await expect(\n                    getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n                ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n            });\n\n            it('because it has no account indices', async () => {\n                expect.assertions(1);\n                const compiledTransactionMessage = {\n                    instructionHeaders: [\n                        { numInstructionAccounts: 0, numInstructionDataBytes: 4, programAccountIndex: 0 },\n                    ],\n                    instructionPayloads: [\n                        { instructionAccountIndices: [], instructionData: new Uint8Array([4, 0, 0, 0]) },\n                    ],\n                    instructions: [\n                        {\n                            data: new Uint8Array([4, 0, 0, 0]),\n                            programAddressIndex: 0,\n                        },\n                    ],\n                    lifetimeToken: 'abc',\n                    staticAccounts: [SYSTEM_PROGRAM_ADDRESS],\n                    version: 1,\n                } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n                await expect(\n                    getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n                ).resolves.toEqual({ blockhash: 'abc' as Blockhash, lastValidBlockHeight: U64_MAX });\n            });\n        });\n\n        it('returns a durable nonce transaction lifetime when the first instruction is an AdvanceNonceAccount instruction', async () => {\n            expect.assertions(1);\n            const compiledTransactionMessage = {\n                instructionHeaders: [{ numInstructionAccounts: 3, numInstructionDataBytes: 4, programAccountIndex: 0 }],\n                instructionPayloads: [\n                    { instructionAccountIndices: [1, 2, 3], instructionData: new Uint8Array([4, 0, 0, 0]) },\n                ],\n                instructions: [\n                    {\n                        accountIndices: [1, 2, 3],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 0,\n                    },\n                ],\n                lifetimeToken: 'abc',\n                staticAccounts: [\n                    SYSTEM_PROGRAM_ADDRESS,\n                    'nonceAccountAddress',\n                    'recentBlockhashesSysvarAddress',\n                    'nonceAuthorityAddress',\n                ],\n                version: 1,\n            } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n            await expect(\n                getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n            ).resolves.toEqual({ nonce: 'abc' as Nonce, nonceAccountAddress: 'nonceAccountAddress' });\n        });\n\n        it('fatals if the nonce account address is not in static accounts', async () => {\n            expect.assertions(1);\n            const compiledTransactionMessage = {\n                instructionHeaders: [{ numInstructionAccounts: 3, numInstructionDataBytes: 4, programAccountIndex: 0 }],\n                instructionPayloads: [\n                    { instructionAccountIndices: [1, 2, 3], instructionData: new Uint8Array([4, 0, 0, 0]) },\n                ],\n                instructions: [\n                    {\n                        accountIndices: [1, 2, 3],\n                        data: new Uint8Array([4, 0, 0, 0]),\n                        programAddressIndex: 0,\n                    },\n                ],\n                lifetimeToken: 'abc',\n                staticAccounts: ['11111111111111111111111111111111'],\n                version: 1,\n            } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n            await expect(() =>\n                getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n            ).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX, {\n                    nonce: 'abc',\n                    nonceAccountIndex: 1,\n                    numberOfStaticAccounts: 1,\n                }),\n            );\n        });\n    });\n\n    describe('for unsupported transaction message version v2', () => {\n        it('throws an error', async () => {\n            expect.assertions(1);\n            const compiledTransactionMessage = {\n                instructions: [],\n                lifetimeToken: 'abc',\n                version: 2,\n            } as unknown as CompiledTransactionMessage & CompiledTransactionMessageWithLifetime;\n\n            await expect(() =>\n                getTransactionLifetimeConstraintFromCompiledTransactionMessage(compiledTransactionMessage),\n            ).rejects.toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, { unsupportedVersion: 2 }),\n            );\n        });\n    });\n});\n\ndescribe('assertIsTransactionWithBlockhashLifetime', () => {\n    it('throws for a transaction with no lifetime constraint', () => {\n        const transaction: Transaction = {\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        };\n        expect(() => assertIsTransactionWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a durable nonce constraint', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                nonce: 'abcd' as Nonce,\n                nonceAccountAddress: 'nonceAccountAddress' as Address,\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a blockhash but no lastValidBlockHeight in lifetimeConstraint', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                blockhash: '11111111111111111111111111111111',\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a lastValidBlockHeight but no blockhash in lifetimeConstraint', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                lastValidBlockHeight: 1234n,\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a blockhash lifetime but an invalid blockhash value', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                blockhash: 'not a valid blockhash value',\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithBlockhashLifetime(transaction)).toThrow();\n    });\n    it('does not throw for a transaction with a valid blockhash lifetime constraint', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                blockhash: '11111111111111111111111111111111',\n                lastValidBlockHeight: 1234n,\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithBlockhashLifetime(transaction)).not.toThrow();\n    });\n});\n\ndescribe('assertIsTransactionWithDurableNonceLifetime()', () => {\n    const validAddress = '2B7hCrBozp5hPV31mw1qUh5XhXYs9f6p1GsRdHNjF4xS' as Address;\n    it('throws for a transaction with no lifetime constraint', () => {\n        const transaction: Transaction = {\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        };\n        expect(() => assertIsTransactionWithDurableNonceLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a blockhash constraint', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                blockhash: '11111111111111111111111111111111',\n                lastValidBlockHeight: 1234n,\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithDurableNonceLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a nonce but no nonceAccountAddress in lifetimeConstraint', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                nonce: 'abcd' as Nonce,\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithDurableNonceLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a nonceAccountAddress but no nonce in lifetimeConstraint', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                nonceAccountAddress: validAddress,\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithDurableNonceLifetime(transaction)).toThrow();\n    });\n    it('throws for a transaction with a durable nonce lifetime but an invalid nonceAccountAddress value', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                nonce: 'abcd' as Nonce,\n                nonceAccountAddress: 'not a valid address' as Address,\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithDurableNonceLifetime(transaction)).toThrow();\n    });\n    it('does not throw for a transaction with a valid durable nonce lifetime constraint', () => {\n        const transaction = {\n            lifetimeConstraint: {\n                nonce: 'abcd' as Nonce,\n                nonceAccountAddress: validAddress,\n            },\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        } as Transaction;\n        expect(() => assertIsTransactionWithDurableNonceLifetime(transaction)).not.toThrow();\n    });\n});\n"
  },
  {
    "path": "packages/transactions/src/__tests__/signatures-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,\n    SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes, signBytes } from '@solana/keys';\nimport { TransactionMessageWithBlockhashLifetime } from '@solana/transaction-messages';\n\nimport { TransactionWithLifetime } from '../lifetime';\nimport {\n    assertIsFullySignedTransaction,\n    getSignatureFromTransaction,\n    isFullySignedTransaction,\n    partiallySignTransaction,\n    signTransaction,\n} from '../signatures';\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\n\njest.mock('@solana/addresses');\njest.mock('@solana/keys');\n\nconst MOCK_BLOCKHASH_LIFETIME = {\n    blockhash: '11111111111111111111111111111111',\n    lastValidBlockHeight: 0n,\n} as TransactionMessageWithBlockhashLifetime['lifetimeConstraint'];\n\ndescribe('getSignatureFromTransaction', () => {\n    it(\"returns the signature associated with a transaction's fee payer\", () => {\n        const signatures: SignaturesMap = {};\n        signatures['123' as Address] = new Uint8Array(new Array(64).fill(9)) as SignatureBytes;\n        const transactionWithFeePayerSignature: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n        expect(getSignatureFromTransaction(transactionWithFeePayerSignature)).toBe(\n            'BUguQsv2ZuHus54HAFzjdJHzZBkygAjKhEeYwSG19tUfUyvvz3worsdQCdAXDNjakJHioSiyxhFiDJrm8XpSXRA',\n        );\n    });\n    it('throws when supplied a transaction that has not been signed by the fee payer', () => {\n        const transactionWithoutFeePayerSignature: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {},\n        };\n        expect(() => {\n            getSignatureFromTransaction(transactionWithoutFeePayerSignature);\n        }).toThrow(new SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING));\n    });\n});\n\ndescribe('partiallySignTransaction', () => {\n    const MOCK_SIGNATURE_A = new Uint8Array(Array(64).fill(1)) as SignatureBytes;\n    const MOCK_SIGNATURE_B = new Uint8Array(Array(64).fill(2)) as SignatureBytes;\n    const MOCK_SIGNATURE_C = new Uint8Array(Array(64).fill(3)) as SignatureBytes;\n    const mockKeyPairA = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairB = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairC = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockPublicKeyAddressA = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address<'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'>;\n    const mockPublicKeyAddressB = 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address<'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'>;\n    const mockPublicKeyAddressC = 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC' as Address<'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'>;\n    beforeEach(() => {\n        (getAddressFromPublicKey as jest.Mock).mockImplementation(publicKey => {\n            switch (publicKey) {\n                case mockKeyPairA.publicKey:\n                    return mockPublicKeyAddressA;\n                case mockKeyPairB.publicKey:\n                    return mockPublicKeyAddressB;\n                case mockKeyPairC.publicKey:\n                    return mockPublicKeyAddressC;\n                default:\n                    return '99999999999999999999999999999999' as Address<'99999999999999999999999999999999'>;\n            }\n        });\n        (signBytes as jest.Mock).mockImplementation(secretKey => {\n            switch (secretKey) {\n                case mockKeyPairA.privateKey:\n                    return MOCK_SIGNATURE_A;\n                case mockKeyPairB.privateKey:\n                    return MOCK_SIGNATURE_B;\n                case mockKeyPairC.privateKey:\n                    return MOCK_SIGNATURE_C;\n                default:\n                    return new Uint8Array(Array(64).fill(0xff));\n            }\n        });\n        (signBytes as jest.Mock).mockClear();\n    });\n    it(\"returns a signed transaction object having the first signer's signature\", async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n\n        const partiallySignedTransactionPromise = partiallySignTransaction([mockKeyPairA], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            }),\n        );\n    });\n    it('returns unchanged compiled message bytes', async () => {\n        expect.assertions(1);\n        const messageBytes = new Uint8Array([1, 2, 3]) as ReadonlyUint8Array as TransactionMessageBytes;\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: messageBytes as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        const partiallySignedTransactionPromise = partiallySignTransaction([mockKeyPairA], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty('messageBytes', messageBytes);\n    });\n    it('returns a signed transaction object having null for the missing signers', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n                [mockPublicKeyAddressC]: null,\n            },\n        };\n        const partiallySignedTransactionPromise = partiallySignTransaction([mockKeyPairA], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressB]: null,\n                [mockPublicKeyAddressC]: null,\n            }),\n        );\n    });\n    it(\"returns a transaction object having the second signer's signature\", async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedTransactionPromise = partiallySignTransaction([mockKeyPairB], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressB]: MOCK_SIGNATURE_B,\n            }),\n        );\n    });\n    it('returns a transaction object having multiple signatures', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n                [mockPublicKeyAddressC]: null,\n            },\n        };\n        const partiallySignedTransactionPromise = partiallySignTransaction(\n            [mockKeyPairA, mockKeyPairB, mockKeyPairC],\n            transaction,\n        );\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n                [mockPublicKeyAddressB]: MOCK_SIGNATURE_B,\n                [mockPublicKeyAddressC]: MOCK_SIGNATURE_C,\n            }),\n        );\n    });\n    it('stores the signatures in the order specified on the compiled message', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n                [mockPublicKeyAddressC]: null,\n            },\n        };\n        const { signatures } = await partiallySignTransaction([mockKeyPairC, mockKeyPairB, mockKeyPairA], transaction);\n        const orderedAddresses = Object.keys(signatures);\n        expect(orderedAddresses).toEqual([mockPublicKeyAddressA, mockPublicKeyAddressB, mockPublicKeyAddressC]);\n    });\n    it('does not modify an existing signature when the signature is the same', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedTransactionPromise = partiallySignTransaction([mockKeyPairB], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            }),\n        );\n    });\n    it('produces a new signature for an existing signer', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            },\n        };\n        await partiallySignTransaction([mockKeyPairA], transaction);\n        expect(signBytes as jest.Mock).toHaveBeenCalledTimes(1);\n    });\n    it('modifies the existing signature when the signature is different', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: new Uint8Array([1, 2, 3, 4]) as ReadonlyUint8Array as SignatureBytes,\n            },\n        };\n        const partiallySignedTransactionPromise = partiallySignTransaction([mockKeyPairA], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            }),\n        );\n    });\n    it('produces a signature for a new signer when there is an existing one', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedTransactionPromise = partiallySignTransaction([mockKeyPairB], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressB]: MOCK_SIGNATURE_B,\n            }),\n        );\n    });\n    it('freezes the object', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        await expect(partiallySignTransaction([mockKeyPairA], transaction)).resolves.toBeFrozenObject();\n    });\n    it('returns the input transaction object if no signatures changed', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n            },\n        };\n        await expect(partiallySignTransaction([mockKeyPairA], transaction)).resolves.toBe(transaction);\n    });\n    it('throws if a keypair is for an address that is not in the signatures of the transaction', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        await expect(partiallySignTransaction([mockKeyPairB], transaction)).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, {\n                expectedAddresses: [mockPublicKeyAddressA],\n                unexpectedAddresses: [mockPublicKeyAddressB],\n            }),\n        );\n    });\n    it('throws with multiple addresses if there are multiple keypairs that are not in the signatures', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n            },\n        };\n        await expect(partiallySignTransaction([mockKeyPairB, mockKeyPairC], transaction)).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, {\n                expectedAddresses: [mockPublicKeyAddressA],\n                unexpectedAddresses: [mockPublicKeyAddressB, mockPublicKeyAddressC],\n            }),\n        );\n    });\n});\n\ndescribe('signTransaction', () => {\n    const mockPublicKeyAddressA = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as Address<'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'>;\n    const mockPublicKeyAddressB = 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB' as Address<'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'>;\n    const MOCK_SIGNATURE_A = new Uint8Array(Array(64).fill(1)) as SignatureBytes;\n    const MOCK_SIGNATURE_B = new Uint8Array(Array(64).fill(2)) as SignatureBytes;\n    const mockKeyPairA = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    const mockKeyPairB = { privateKey: {} as CryptoKey, publicKey: {} as CryptoKey } as CryptoKeyPair;\n    beforeEach(() => {\n        (getAddressFromPublicKey as jest.Mock).mockImplementation(publicKey => {\n            switch (publicKey) {\n                case mockKeyPairA.publicKey:\n                    return mockPublicKeyAddressA;\n                case mockKeyPairB.publicKey:\n                    return mockPublicKeyAddressB;\n                default:\n                    return '99999999999999999999999999999999' as Address<'99999999999999999999999999999999'>;\n            }\n        });\n        (signBytes as jest.Mock).mockImplementation(secretKey => {\n            switch (secretKey) {\n                case mockKeyPairA.privateKey:\n                    return MOCK_SIGNATURE_A;\n                case mockKeyPairB.privateKey:\n                    return MOCK_SIGNATURE_B;\n                default:\n                    return new Uint8Array(Array(64).fill(0xff));\n            }\n        });\n    });\n    it('fatals when missing a signer', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const signedTransactionPromise = signTransaction([mockKeyPairA], transaction);\n        await expect(signedTransactionPromise).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n                addresses: [mockPublicKeyAddressB],\n            }),\n        );\n    });\n    it('returns a signed transaction object with multiple signatures', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedTransactionPromise = signTransaction([mockKeyPairA, mockKeyPairB], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty(\n            'signatures',\n            expect.objectContaining({\n                [mockPublicKeyAddressA]: MOCK_SIGNATURE_A,\n                [mockPublicKeyAddressB]: MOCK_SIGNATURE_B,\n            }),\n        );\n    });\n    it('returns a signed transaction object with the compiled message bytes', async () => {\n        expect.assertions(1);\n        const messageBytes = new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes;\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const partiallySignedTransactionPromise = signTransaction([mockKeyPairA, mockKeyPairB], transaction);\n        await expect(partiallySignedTransactionPromise).resolves.toHaveProperty('messageBytes', messageBytes);\n    });\n    it('stores the signatures in the order specified on the compiled message', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        const { signatures } = await signTransaction([mockKeyPairB, mockKeyPairA], transaction);\n        const orderedAddresses = Object.keys(signatures);\n        expect(orderedAddresses).toEqual([mockPublicKeyAddressA, mockPublicKeyAddressB]);\n    });\n    it('freezes the object', async () => {\n        expect.assertions(1);\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                [mockPublicKeyAddressA]: null,\n                [mockPublicKeyAddressB]: null,\n            },\n        };\n        await expect(signTransaction([mockKeyPairA, mockKeyPairB], transaction)).resolves.toBeFrozenObject();\n    });\n});\n\ndescribe('isFullySignedTransaction', () => {\n    const mockPublicKeyAddressA = 'A' as Address;\n    const mockSignatureA = new Uint8Array(0) as SignatureBytes;\n    const mockPublicKeyAddressB = 'B' as Address;\n    const mockSignatureB = new Uint8Array(1) as SignatureBytes;\n\n    it('returns false if the transaction has missing signatures', () => {\n        const signatures: SignaturesMap = {};\n        signatures[mockPublicKeyAddressA] = null;\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n\n        expect(isFullySignedTransaction(transaction)).toBe(false);\n    });\n\n    it('returns true if the transaction is signed by all its signers', () => {\n        const signatures: SignaturesMap = {};\n        signatures[mockPublicKeyAddressA] = mockSignatureA;\n        signatures[mockPublicKeyAddressB] = mockSignatureB;\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n\n        expect(isFullySignedTransaction(transaction)).toBe(true);\n    });\n\n    it('return true if the transaction has no signatures', () => {\n        const signatures: SignaturesMap = {};\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n\n        expect(isFullySignedTransaction(transaction)).toBe(true);\n    });\n});\n\ndescribe('assertIsFullySignedTransaction', () => {\n    const mockPublicKeyAddressA = 'A' as Address;\n    const mockSignatureA = new Uint8Array(0) as SignatureBytes;\n    const mockPublicKeyAddressB = 'B' as Address;\n    const mockSignatureB = new Uint8Array(1) as SignatureBytes;\n\n    it('throws if the transaction has no signature for the fee payer', () => {\n        const signatures: SignaturesMap = {};\n        signatures[mockPublicKeyAddressA] = null;\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n\n        expect(() => assertIsFullySignedTransaction(transaction)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n                addresses: [mockPublicKeyAddressA],\n            }),\n        );\n    });\n\n    it('throws all missing signers if the transaction has no signature for multiple signers', () => {\n        const signatures: SignaturesMap = {};\n        signatures[mockPublicKeyAddressA] = null;\n        signatures[mockPublicKeyAddressB] = null;\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n\n        expect(() => assertIsFullySignedTransaction(transaction)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n                addresses: [mockPublicKeyAddressA, mockPublicKeyAddressB],\n            }),\n        );\n    });\n\n    it('does not throw if the transaction is signed by its only signer', () => {\n        const signatures: SignaturesMap = {};\n        signatures[mockPublicKeyAddressA] = mockSignatureA;\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n\n        expect(() => assertIsFullySignedTransaction(transaction)).not.toThrow();\n    });\n\n    it('does not throw if the transaction is signed by all its signers', () => {\n        const signatures: SignaturesMap = {};\n        signatures[mockPublicKeyAddressA] = mockSignatureA;\n        signatures[mockPublicKeyAddressB] = mockSignatureB;\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n\n        expect(() => assertIsFullySignedTransaction(transaction)).not.toThrow();\n    });\n\n    it('does not throw if the transaction has no signatures', () => {\n        const signatures: SignaturesMap = {};\n        const transaction: Transaction & TransactionWithLifetime = {\n            lifetimeConstraint: MOCK_BLOCKHASH_LIFETIME,\n            messageBytes: new Uint8Array() as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures,\n        };\n        expect(() => assertIsFullySignedTransaction(transaction)).not.toThrow();\n    });\n});\n"
  },
  {
    "path": "packages/transactions/src/__tests__/transaction-message-size-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport type { Blockhash } from '@solana/rpc-types';\nimport {\n    appendTransactionMessageInstruction,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n} from '@solana/transaction-messages';\n\nimport {\n    assertIsTransactionMessageWithinSizeLimit,\n    getTransactionMessageSize,\n    getTransactionMessageSizeLimit,\n    isTransactionMessageWithinSizeLimit,\n} from '../transaction-message-size';\nimport { LEGACY_TRANSACTION_SIZE_LIMIT, V1_TRANSACTION_SIZE_LIMIT } from '../transaction-size-limits';\n\nconst MOCK_BLOCKHASH = {\n    blockhash: '11111111111111111111111111111111' as Blockhash,\n    lastValidBlockHeight: 0n,\n};\n\nconst SMALL_TRANSACTION_MESSAGE = pipe(\n    createTransactionMessage({ version: 0 }),\n    m => setTransactionMessageLifetimeUsingBlockhash(MOCK_BLOCKHASH, m),\n    m => setTransactionMessageFeePayer(address('22222222222222222222222222222222222222222222'), m),\n);\n\nconst OVERSIZED_TRANSACTION_MESSAGE = pipe(SMALL_TRANSACTION_MESSAGE, m =>\n    appendTransactionMessageInstruction(\n        {\n            data: new Uint8Array(LEGACY_TRANSACTION_SIZE_LIMIT + 1),\n            programAddress: address('33333333333333333333333333333333333333333333'),\n        },\n        m,\n    ),\n);\n\nconst SMALL_V1_TRANSACTION_MESSAGE = pipe(\n    // @ts-expect-error v1 not yet included in type for `createTransactionMessage`\n    createTransactionMessage({ version: 1 }),\n    m => setTransactionMessageLifetimeUsingBlockhash(MOCK_BLOCKHASH, m),\n    m => setTransactionMessageFeePayer(address('22222222222222222222222222222222222222222222'), m),\n);\n\ndescribe('getTransactionMessageSizeLimit', () => {\n    it('returns LEGACY_TRANSACTION_SIZE_LIMIT for a legacy transaction message', () => {\n        const legacyMessage = pipe(createTransactionMessage({ version: 'legacy' }), m =>\n            setTransactionMessageFeePayer(address('22222222222222222222222222222222222222222222'), m),\n        );\n        expect(getTransactionMessageSizeLimit(legacyMessage)).toBe(LEGACY_TRANSACTION_SIZE_LIMIT);\n    });\n\n    it('returns LEGACY_TRANSACTION_SIZE_LIMIT for a v0 transaction message', () => {\n        expect(getTransactionMessageSizeLimit(SMALL_TRANSACTION_MESSAGE)).toBe(LEGACY_TRANSACTION_SIZE_LIMIT);\n    });\n\n    it('returns V1_TRANSACTION_SIZE_LIMIT for a v1 transaction message', () => {\n        expect(getTransactionMessageSizeLimit(SMALL_V1_TRANSACTION_MESSAGE)).toBe(V1_TRANSACTION_SIZE_LIMIT);\n    });\n});\n\ndescribe('getTransactionMessageSize', () => {\n    it('gets the size of a compilable transaction message', () => {\n        expect(getTransactionMessageSize(SMALL_TRANSACTION_MESSAGE)).toBe(136);\n    });\n\n    it('gets the size of an oversized compilable transaction message', () => {\n        expect(getTransactionMessageSize(OVERSIZED_TRANSACTION_MESSAGE)).toBe(1405);\n    });\n});\n\ndescribe('isTransactionMessageWithinSizeLimit', () => {\n    it('returns true when the compiled size is under the transaction size limit', () => {\n        expect(isTransactionMessageWithinSizeLimit(SMALL_TRANSACTION_MESSAGE)).toBe(true);\n    });\n\n    it('returns false when the compiled size is above the transaction size limit', () => {\n        expect(isTransactionMessageWithinSizeLimit(OVERSIZED_TRANSACTION_MESSAGE)).toBe(false);\n    });\n\n    it('returns true for a v1 message whose size exceeds the legacy limit but is within the v1 limit', () => {\n        const v1MessageOverLegacyLimit = pipe(SMALL_V1_TRANSACTION_MESSAGE, m =>\n            appendTransactionMessageInstruction(\n                {\n                    data: new Uint8Array(LEGACY_TRANSACTION_SIZE_LIMIT + 1),\n                    programAddress: address('33333333333333333333333333333333333333333333'),\n                },\n                m,\n            ),\n        );\n        expect(isTransactionMessageWithinSizeLimit(v1MessageOverLegacyLimit)).toBe(true);\n    });\n\n    it('returns false for a v1 message whose size exceeds the v1 limit', () => {\n        const v1MessageOverV1Limit = pipe(SMALL_V1_TRANSACTION_MESSAGE, m =>\n            appendTransactionMessageInstruction(\n                {\n                    data: new Uint8Array(V1_TRANSACTION_SIZE_LIMIT + 1),\n                    programAddress: address('33333333333333333333333333333333333333333333'),\n                },\n                m,\n            ),\n        );\n        expect(isTransactionMessageWithinSizeLimit(v1MessageOverV1Limit)).toBe(false);\n    });\n});\n\ndescribe('assertIsTransactionMessageWithinSizeLimit', () => {\n    it('does not throw when the compiled size is under the transaction size limit', () => {\n        expect(() => assertIsTransactionMessageWithinSizeLimit(SMALL_TRANSACTION_MESSAGE)).not.toThrow();\n    });\n\n    it('throws when the compiled size is above the transaction size limit', () => {\n        expect(() => assertIsTransactionMessageWithinSizeLimit(OVERSIZED_TRANSACTION_MESSAGE)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n                transactionSize: 1405,\n                transactionSizeLimit: LEGACY_TRANSACTION_SIZE_LIMIT,\n            }),\n        );\n    });\n\n    it('does not throw for a v1 message whose size exceeds the legacy limit but is within the v1 limit', () => {\n        const v1MessageOverLegacyLimit = pipe(SMALL_V1_TRANSACTION_MESSAGE, m =>\n            appendTransactionMessageInstruction(\n                {\n                    data: new Uint8Array(LEGACY_TRANSACTION_SIZE_LIMIT + 1),\n                    programAddress: address('33333333333333333333333333333333333333333333'),\n                },\n                m,\n            ),\n        );\n        expect(() => assertIsTransactionMessageWithinSizeLimit(v1MessageOverLegacyLimit)).not.toThrow();\n    });\n\n    it('throws for a v1 message whose size exceeds the v1 limit', () => {\n        const v1MessageOverV1Limit = pipe(SMALL_V1_TRANSACTION_MESSAGE, m =>\n            appendTransactionMessageInstruction(\n                {\n                    data: new Uint8Array(V1_TRANSACTION_SIZE_LIMIT + 1),\n                    programAddress: address('33333333333333333333333333333333333333333333'),\n                },\n                m,\n            ),\n        );\n        expect(() => assertIsTransactionMessageWithinSizeLimit(v1MessageOverV1Limit)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n                transactionSize: 4271,\n                transactionSizeLimit: V1_TRANSACTION_SIZE_LIMIT,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/transactions/src/__tests__/transaction-size-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport { pipe } from '@solana/functional';\nimport type { Blockhash } from '@solana/rpc-types';\nimport {\n    appendTransactionMessageInstruction,\n    createTransactionMessage,\n    setTransactionMessageFeePayer,\n    setTransactionMessageLifetimeUsingBlockhash,\n} from '@solana/transaction-messages';\n\nimport { compileTransaction } from '../compile-transaction';\nimport {\n    assertIsTransactionWithinSizeLimit,\n    getTransactionSize,\n    isTransactionWithinSizeLimit,\n} from '../transaction-size';\nimport { LEGACY_TRANSACTION_SIZE_LIMIT, V1_TRANSACTION_SIZE_LIMIT } from '../transaction-size-limits';\n\nconst MOCK_BLOCKHASH = {\n    blockhash: '11111111111111111111111111111111' as Blockhash,\n    lastValidBlockHeight: 0n,\n};\n\nconst SMALL_TRANSACTION_MESSAGE = pipe(\n    createTransactionMessage({ version: 0 }),\n    m => setTransactionMessageLifetimeUsingBlockhash(MOCK_BLOCKHASH, m),\n    m => setTransactionMessageFeePayer(address('22222222222222222222222222222222222222222222'), m),\n);\n\nconst SMALL_TRANSACTION = compileTransaction(SMALL_TRANSACTION_MESSAGE);\n\nconst OVERSIZED_TRANSACTION = compileTransaction(\n    pipe(SMALL_TRANSACTION_MESSAGE, m =>\n        appendTransactionMessageInstruction(\n            {\n                data: new Uint8Array(LEGACY_TRANSACTION_SIZE_LIMIT + 1),\n                programAddress: address('33333333333333333333333333333333333333333333'),\n            },\n            m,\n        ),\n    ),\n);\n\nconst SMALL_V1_TRANSACTION_MESSAGE = pipe(\n    // @ts-expect-error v1 not yet included in type for `createTransactionMessage`\n    createTransactionMessage({ version: 1 }),\n    m => setTransactionMessageLifetimeUsingBlockhash(MOCK_BLOCKHASH, m),\n    m => setTransactionMessageFeePayer(address('22222222222222222222222222222222222222222222'), m),\n);\n\n// A v1 transaction whose size exceeds the legacy limit but is within the v1 limit.\nconst V1_TRANSACTION_OVER_LEGACY_LIMIT = compileTransaction(\n    pipe(SMALL_V1_TRANSACTION_MESSAGE, m =>\n        appendTransactionMessageInstruction(\n            {\n                data: new Uint8Array(LEGACY_TRANSACTION_SIZE_LIMIT + 1),\n                programAddress: address('33333333333333333333333333333333333333333333'),\n            },\n            m,\n        ),\n    ),\n);\n\n// A v1 transaction whose size exceeds the v1 limit.\nconst V1_TRANSACTION_OVER_V1_LIMIT = compileTransaction(\n    pipe(SMALL_V1_TRANSACTION_MESSAGE, m =>\n        appendTransactionMessageInstruction(\n            {\n                data: new Uint8Array(V1_TRANSACTION_SIZE_LIMIT + 1),\n                programAddress: address('33333333333333333333333333333333333333333333'),\n            },\n            m,\n        ),\n    ),\n);\n\ndescribe('getTransactionSize', () => {\n    it('gets the size of a transaction', () => {\n        expect(getTransactionSize(SMALL_TRANSACTION)).toBe(136);\n    });\n\n    it('gets the size of an oversized transaction', () => {\n        expect(getTransactionSize(OVERSIZED_TRANSACTION)).toBe(1405);\n    });\n});\n\ndescribe('isTransactionWithinSizeLimit', () => {\n    it('returns true when the transaction size is under the transaction size limit', () => {\n        expect(isTransactionWithinSizeLimit(SMALL_TRANSACTION)).toBe(true);\n    });\n\n    it('returns false when the transaction size is above the transaction size limit', () => {\n        expect(isTransactionWithinSizeLimit(OVERSIZED_TRANSACTION)).toBe(false);\n    });\n\n    it('returns true for a v1 transaction whose size exceeds the legacy limit but is within the v1 limit', () => {\n        expect(isTransactionWithinSizeLimit(V1_TRANSACTION_OVER_LEGACY_LIMIT)).toBe(true);\n    });\n\n    it('returns false for a v1 transaction whose size exceeds the v1 limit', () => {\n        expect(isTransactionWithinSizeLimit(V1_TRANSACTION_OVER_V1_LIMIT)).toBe(false);\n    });\n});\n\ndescribe('assertIsTransactionWithinSizeLimit', () => {\n    it('does not throw when the transaction size is under the transaction size limit', () => {\n        expect(() => assertIsTransactionWithinSizeLimit(SMALL_TRANSACTION)).not.toThrow();\n    });\n\n    it('throws when the transaction size is above the transaction size limit', () => {\n        expect(() => assertIsTransactionWithinSizeLimit(OVERSIZED_TRANSACTION)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n                transactionSize: 1405,\n                transactionSizeLimit: LEGACY_TRANSACTION_SIZE_LIMIT,\n            }),\n        );\n    });\n\n    it('does not throw for a v1 transaction whose size exceeds the legacy limit but is within the v1 limit', () => {\n        expect(() => assertIsTransactionWithinSizeLimit(V1_TRANSACTION_OVER_LEGACY_LIMIT)).not.toThrow();\n    });\n\n    it('throws for a v1 transaction whose size exceeds the v1 limit', () => {\n        expect(() => assertIsTransactionWithinSizeLimit(V1_TRANSACTION_OVER_V1_LIMIT)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n                transactionSize: 4271,\n                transactionSizeLimit: V1_TRANSACTION_SIZE_LIMIT,\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/transactions/src/__tests__/wire-transaction-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { Transaction, TransactionMessageBytes } from '../transaction';\nimport { getBase64EncodedWireTransaction } from '../wire-transaction';\n\ndescribe('getBase64EncodedWireTransaction', () => {\n    it('serializes a transaction to wire format', () => {\n        // Based on the following transaction message:\n        /*\n        {\n            feePayer: '22222222222222222222222222222222222222222222' as Address,\n            instructions: [\n                {\n                    accounts: [\n                        {\n                            address: '44444444444444444444444444444444444444444444' as Address,\n                            role: AccountRole.READONLY_SIGNER,\n                        },\n                    ],\n                    programAddress: '55555555555555555555555555555555555555555555' as Address,\n                },\n            ],\n            lifetimeConstraint: {\n                blockhash: '33333333333333333333333333333333333333333333' as Blockhash,\n                lastValidBlockHeight: 123n,\n            },\n            signatures: {\n                // No signature for fee payer\n                ['44444444444444444444444444444444444444444444' as Address]:\n                    // Base58 encoded signature: `3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333`\n                    new Uint8Array([\n                        0x65, 0xc9, 0xfa, 0x89, 0xe6, 0xab, 0xdb, 0x8b, 0x62, 0x79, 0xaf, 0x58, 0x43, 0x82, 0x48, 0xa6,\n                        0x7f, 0xbc, 0x40, 0xb2, 0x37, 0x06, 0x76, 0xe0, 0xed, 0xa6, 0xef, 0x73, 0x7d, 0x39, 0xfc, 0x30,\n                        0x6c, 0x80, 0x80, 0xc0, 0x66, 0x2d, 0x32, 0x7a, 0x56, 0xb5, 0xb9, 0xd3, 0xc1, 0x20, 0xd7, 0x15,\n                        0xa4, 0x34, 0x3f, 0x93, 0x8a, 0x23, 0xee, 0x08, 0xfb, 0x82, 0x3e, 0xe0, 0x8f, 0xb8, 0x23, 0xee,\n                    ]) as SignatureBytes,\n            },\n            version: 0,\n        }\n        */\n\n        const transaction: Transaction = {\n            messageBytes: new Uint8Array([\n                128, 2, 1, 1, 3, 15, 30, 107, 20, 33, 192, 74, 7, 4, 49, 38, 92, 25, 197, 187, 238, 25, 146, 186, 232,\n                175, 209, 205, 7, 142, 248, 175, 112, 71, 220, 17, 247, 45, 91, 65, 60, 101, 64, 222, 21, 12, 147, 115,\n                20, 77, 81, 51, 202, 76, 184, 48, 186, 15, 117, 103, 22, 172, 234, 14, 80, 215, 148, 53, 229, 60, 121,\n                172, 80, 135, 1, 40, 28, 16, 196, 153, 112, 103, 22, 239, 184, 102, 74, 235, 162, 191, 71, 52, 30, 59,\n                226, 189, 193, 31, 112, 71, 220, 30, 60, 214, 40, 67, 128, 148, 14, 8, 98, 76, 184, 51, 139, 119, 220,\n                51, 37, 117, 209, 95, 163, 154, 15, 29, 241, 94, 224, 143, 184, 35, 238, 1, 2, 1, 1, 0, 0,\n            ]) as ReadonlyUint8Array as TransactionMessageBytes,\n            signatures: {\n                ['22222222222222222222222222222222222222222222' as Address]: null,\n                // Base58 encoded signature: `3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333`\n                ['44444444444444444444444444444444444444444444' as Address]: new Uint8Array([\n                    0x65, 0xc9, 0xfa, 0x89, 0xe6, 0xab, 0xdb, 0x8b, 0x62, 0x79, 0xaf, 0x58, 0x43, 0x82, 0x48, 0xa6,\n                    0x7f, 0xbc, 0x40, 0xb2, 0x37, 0x06, 0x76, 0xe0, 0xed, 0xa6, 0xef, 0x73, 0x7d, 0x39, 0xfc, 0x30,\n                    0x6c, 0x80, 0x80, 0xc0, 0x66, 0x2d, 0x32, 0x7a, 0x56, 0xb5, 0xb9, 0xd3, 0xc1, 0x20, 0xd7, 0x15,\n                    0xa4, 0x34, 0x3f, 0x93, 0x8a, 0x23, 0xee, 0x08, 0xfb, 0x82, 0x3e, 0xe0, 0x8f, 0xb8, 0x23, 0xee,\n                ]) as SignatureBytes,\n            },\n        };\n\n        expect(getBase64EncodedWireTransaction(transaction))\n            // Copy and paste this string into the Solana Explorer at https://explorer.solana.com/tx/inspector\n            .toBe(\n                'AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlyfqJ5qvbi2J5r1hDgkimf7xAsjcGduDtpu9zfTn8MGyAgMBmLTJ6VrW508Eg1xWkND+TiiPuCPuCPuCPuCPugAIBAQMPHmsUIcBKBwQxJlwZxbvuGZK66K/RzQeO+K9wR9wR9y1bQTxlQN4VDJNzFE1RM8pMuDC6D3VnFqzqDlDXlDXlPHmsUIcBKBwQxJlwZxbvuGZK66K/RzQeO+K9wR9wR9wePNYoQ4CUDghiTLgzi3fcMyV10V+jmg8d8V7gj7gj7gECAQEAAA==',\n            );\n    });\n});\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/compile-transaction-typetest.ts",
    "content": "import { Blockhash } from '@solana/rpc-types';\nimport {\n    Nonce,\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithDurableNonceLifetime,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithinSizeLimit,\n    TransactionMessageWithLifetime,\n} from '@solana/transaction-messages';\n\nimport { compileTransaction } from '../compile-transaction';\nimport {\n    TransactionBlockhashLifetime,\n    TransactionDurableNonceLifetime,\n    TransactionWithBlockhashLifetime,\n    TransactionWithDurableNonceLifetime,\n    TransactionWithLifetime,\n} from '../lifetime';\nimport { Transaction } from '../transaction';\nimport { TransactionWithinSizeLimit } from '../transaction-size';\n\n// [DESCRIBE] compileTransaction.\n{\n    // It returns a transaction with no lifetime if the compiled message has no lifetime.\n    {\n        const transaction = compileTransaction(null as unknown as TransactionMessage & TransactionMessageWithFeePayer);\n\n        transaction satisfies Readonly<Transaction>;\n        // @ts-expect-error Expects no lifetime constraint\n        transaction satisfies Readonly<Transaction & TransactionWithLifetime>;\n    }\n\n    // It forwards the blockhash lifetime constraint from the transaction message to the transaction.\n    {\n        const transaction = compileTransaction(\n            null as unknown as TransactionMessage &\n                TransactionMessageWithBlockhashLifetime &\n                TransactionMessageWithFeePayer,\n        );\n\n        transaction satisfies Readonly<Transaction & TransactionWithLifetime>;\n        transaction satisfies Readonly<Transaction & TransactionWithBlockhashLifetime>;\n        transaction.lifetimeConstraint.blockhash satisfies Blockhash;\n    }\n\n    // It forwards the durable nonce lifetime constraint from the transaction message to the transaction.\n    {\n        const transaction = compileTransaction(\n            null as unknown as TransactionMessage &\n                TransactionMessageWithDurableNonceLifetime &\n                TransactionMessageWithFeePayer,\n        );\n\n        transaction satisfies Readonly<Transaction & TransactionWithLifetime>;\n        transaction satisfies Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n        transaction.lifetimeConstraint.nonce satisfies Nonce;\n    }\n\n    // It returns a transaction with a lifetime constraint even if we don't know which one it is.\n    {\n        const transaction = compileTransaction(\n            null as unknown as null as unknown as TransactionMessage &\n                TransactionMessageWithFeePayer &\n                TransactionMessageWithLifetime,\n        );\n\n        transaction satisfies Readonly<Transaction & TransactionWithLifetime>;\n        // @ts-expect-error not known to have blockhash lifetime\n        transaction satisfies Readonly<Transaction & TransactionBlockhashLifetime>;\n        // @ts-expect-error not known to have durable nonce lifetime\n        transaction satisfies Readonly<Transaction & TransactionDurableNonceLifetime>;\n\n        transaction.lifetimeConstraint satisfies { blockhash: Blockhash } | { nonce: Nonce };\n        // @ts-expect-error not known to have blockhash lifetime\n        transaction.lifetimeConstraint satisfies { blockhash: Blockhash };\n        // @ts-expect-error not known to have durable nonce lifetime\n        transaction.lifetimeConstraint satisfies { nonce: Nonce };\n    }\n\n    // It forwards the within size limit flag from the transaction message to the transaction.\n    {\n        const transaction = compileTransaction(\n            null as unknown as TransactionMessage & TransactionMessageWithFeePayer & TransactionMessageWithinSizeLimit,\n        );\n\n        transaction satisfies Readonly<Transaction & TransactionWithinSizeLimit>;\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/lifetime-typetest.ts",
    "content": "import { Address } from '@solana/addresses';\nimport { Blockhash } from '@solana/rpc-types';\nimport type {\n    Nonce,\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithDurableNonceLifetime,\n    TransactionMessageWithLifetime,\n} from '@solana/transaction-messages';\n\nimport {\n    assertIsTransactionWithBlockhashLifetime,\n    assertIsTransactionWithDurableNonceLifetime,\n    isTransactionWithBlockhashLifetime,\n    isTransactionWithDurableNonceLifetime,\n    type SetTransactionLifetimeFromTransactionMessage,\n    type TransactionWithBlockhashLifetime,\n    type TransactionWithDurableNonceLifetime,\n    type TransactionWithLifetime,\n} from '../lifetime';\nimport { Transaction } from '../transaction';\n\n// [DESCRIBE] SetTransactionLifetimeFromTransactionMessage.\n{\n    // It returns the transaction unchanged if the transaction message has no lifetime constraint.\n    {\n        type Result = SetTransactionLifetimeFromTransactionMessage<Transaction, TransactionMessage>;\n        null as unknown as Result satisfies Readonly<Transaction>;\n        // @ts-expect-error Expects no lifetime constraint.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithLifetime>;\n    }\n\n    // It augments the provided transaction with a lifetime constraint if the transaction message has a lifetime constraint.\n    {\n        type Result = SetTransactionLifetimeFromTransactionMessage<\n            Transaction,\n            TransactionMessage & TransactionMessageWithLifetime\n        >;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithLifetime>;\n        // @ts-expect-error Cannot know that the lifetime constraint is a blockhash lifetime.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithBlockhashLifetime>;\n        // @ts-expect-error Cannot know that the lifetime constraint is a durable nonce lifetime.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n    }\n\n    // It keeps extra properties from the transaction but not from the transaction message.\n    {\n        type Result = SetTransactionLifetimeFromTransactionMessage<\n            Transaction & { _from_transaction: 1 },\n            TransactionMessage & { _from_transaction_message: 1 }\n        >;\n        null as unknown as Result satisfies Readonly<{ _from_transaction: 1 }>;\n        // @ts-expect-error Does not keep extra properties from transaction messages.\n        null as unknown as Result satisfies Readonly<{ _from_transaction_message: 1 }>;\n    }\n\n    // It forwards the blockhash lifetime constraint from the transaction message to the transaction.\n    {\n        type Result = SetTransactionLifetimeFromTransactionMessage<\n            Transaction,\n            TransactionMessage & TransactionMessageWithBlockhashLifetime\n        >;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithBlockhashLifetime>;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithLifetime>;\n        // @ts-expect-error Cannot be a durable nonce lifetime.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n    }\n\n    // It forwards the durable nonce lifetime constraint from the transaction message to the transaction.\n    {\n        type Result = SetTransactionLifetimeFromTransactionMessage<\n            Transaction,\n            TransactionMessage & TransactionMessageWithDurableNonceLifetime\n        >;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithLifetime>;\n        // @ts-expect-error Cannot be a blockhash lifetime.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithBlockhashLifetime>;\n    }\n}\n\n// [DESCRIBE] isTransactionWithBlockhashLifetime\n{\n    // It narrows the transaction type to one with a blockhash-based lifetime.\n    {\n        const transaction = null as unknown as Transaction & { some: 1 };\n        if (isTransactionWithBlockhashLifetime(transaction)) {\n            transaction satisfies Transaction & TransactionWithBlockhashLifetime & { some: 1 };\n        } else {\n            transaction satisfies Transaction & { some: 1 };\n            // @ts-expect-error It does not have a blockhash-based lifetime.\n            transaction satisfies TransactionWithBlockhashLifetime;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsTransactionWithBlockhashLifetime\n{\n    // It narrows the transaction type to one with a blockhash-based lifetime.\n    {\n        const transaction = null as unknown as Transaction & { some: 1 };\n        // @ts-expect-error Should not be blockhash lifetime\n        transaction satisfies TransactionWithBlockhashLifetime;\n        // @ts-expect-error Should not satisfy has blockhash\n        transaction satisfies { lifetimeConstraint: { blockhash: Blockhash } };\n        // @ts-expect-error Should not satisfy has lastValidBlockHeight\n        transaction satisfies { lifetimeConstraint: { lastValidBlockHeight: bigint } };\n        assertIsTransactionWithBlockhashLifetime(transaction);\n        transaction satisfies Transaction & TransactionWithBlockhashLifetime & { some: 1 };\n        transaction satisfies TransactionWithBlockhashLifetime;\n        transaction satisfies { lifetimeConstraint: { blockhash: Blockhash } };\n        transaction satisfies { lifetimeConstraint: { lastValidBlockHeight: bigint } };\n    }\n}\n\n// [DESCRIBE] isTransactionWithDurableNonceLifetime\n{\n    // It narrows the transaction type to one with a nonce-based lifetime.\n    {\n        const transaction = null as unknown as Transaction & { some: 1 };\n        if (isTransactionWithDurableNonceLifetime(transaction)) {\n            transaction satisfies Transaction & TransactionWithDurableNonceLifetime & { some: 1 };\n        } else {\n            transaction satisfies Transaction & { some: 1 };\n            // @ts-expect-error It does not have a nonce-based lifetime.\n            transaction satisfies TransactionWithDurableNonceLifetime;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsTransactionWithDurableNonceLifetime\n{\n    // It narrows the transaction type to one with a nonce-based lifetime.\n    {\n        const transaction = null as unknown as Transaction & { some: 1 };\n        // @ts-expect-error Should not be durable nonce lifetime\n        transaction satisfies TransactionWithDurableNonceLifetime;\n        // @ts-expect-error Should not have a nonce-based lifetime\n        transaction satisfies { lifetimeConstraint: { nonce: Nonce } };\n        // @ts-expect-error Should not have a nonce account address\n        transaction satisfies { lifetimeConstraint: { nonceAccountAddress: Address } };\n        assertIsTransactionWithDurableNonceLifetime(transaction);\n        transaction satisfies Transaction & TransactionWithDurableNonceLifetime & { some: 1 };\n        transaction satisfies TransactionWithDurableNonceLifetime;\n        transaction satisfies { lifetimeConstraint: { nonce: Nonce } };\n        transaction satisfies { lifetimeConstraint: { nonceAccountAddress: Address } };\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/sendable-transaction-typetest.ts",
    "content": "import { assertIsSendableTransaction, isSendableTransaction, SendableTransaction } from '../sendable-transaction';\nimport { FullySignedTransaction } from '../signatures';\nimport { Transaction } from '../transaction';\nimport { TransactionWithinSizeLimit } from '../transaction-size';\n\n// [DESCRIBE] SendableTransaction.\n{\n    // It must have all the required conditions.\n    {\n        null as unknown as FullySignedTransaction &\n            Transaction &\n            TransactionWithinSizeLimit satisfies SendableTransaction;\n    }\n\n    // It is not satisfied by Transaction alone.\n    {\n        // @ts-expect-error No required conditions.\n        null as unknown as Transaction satisfies SendableTransaction;\n    }\n\n    // It is not satisfied by Transaction with missing required conditions.\n    {\n        // @ts-expect-error Not enough required conditions.\n        null as unknown as FullySignedTransaction & Transaction satisfies SendableTransaction;\n        // @ts-expect-error Not enough required conditions.\n        null as unknown as Transaction & TransactionWithinSizeLimit satisfies SendableTransaction;\n    }\n}\n\n// [DESCRIBE] isSendableTransaction.\n{\n    // It narrows the type to a SendableTransaction.\n    {\n        const transaction = null as unknown as Transaction;\n        if (isSendableTransaction(transaction)) {\n            transaction satisfies SendableTransaction;\n            transaction satisfies FullySignedTransaction;\n            transaction satisfies TransactionWithinSizeLimit;\n        } else {\n            // @ts-expect-error Not sendable.\n            transaction satisfies SendableTransaction;\n            // @ts-expect-error Not fully signed.\n            transaction satisfies FullySignedTransaction;\n            // @ts-expect-error Not within size limit.\n            transaction satisfies TransactionWithinSizeLimit;\n        }\n    }\n}\n\n// [DESCRIBE] assertIsSendableTransaction.\n{\n    // It narrows the type to a SendableTransaction.\n    {\n        const transaction = null as unknown as Transaction;\n        assertIsSendableTransaction(transaction);\n        transaction satisfies SendableTransaction;\n        transaction satisfies FullySignedTransaction;\n        transaction satisfies TransactionWithinSizeLimit;\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/signatures-typetest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-floating-promises */\nimport { Signature } from '@solana/keys';\n\nimport {\n    assertIsFullySignedTransaction,\n    FullySignedTransaction,\n    getSignatureFromTransaction,\n    isFullySignedTransaction,\n    partiallySignTransaction,\n    signTransaction,\n} from '..';\nimport { Transaction } from '../transaction';\n\n// getSignatureFromTransaction\n{\n    const transaction = null as unknown as Transaction & { some: 1 };\n    getSignatureFromTransaction(transaction) satisfies Signature;\n}\n\n// partiallySignTransaction\n{\n    const transaction = null as unknown as Transaction & { some: 1 };\n    partiallySignTransaction([], transaction) satisfies Promise<Transaction & { some: 1 }>;\n}\n\n// signTransaction\n{\n    const transaction = null as unknown as Transaction & { some: 1 };\n    signTransaction([], transaction) satisfies Promise<FullySignedTransaction & Transaction & { some: 1 }>;\n}\n\n// isFullySignedTransaction\n{\n    const transaction = null as unknown as Transaction & { some: 1 };\n    if (isFullySignedTransaction(transaction)) {\n        transaction satisfies FullySignedTransaction & Transaction & { some: 1 };\n    }\n}\n\n// assertIsFullySignedTransaction\n{\n    const transaction = null as unknown as Transaction & { some: 1 };\n    assertIsFullySignedTransaction(transaction);\n    transaction satisfies FullySignedTransaction & Transaction & { some: 1 };\n}\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/transaction-message-size-typetest.ts",
    "content": "import {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithinSizeLimit,\n} from '@solana/transaction-messages';\n\nimport {\n    assertIsTransactionMessageWithinSizeLimit,\n    isTransactionMessageWithinSizeLimit,\n} from '../transaction-message-size';\n\n// [DESCRIBE] isTransactionMessageWithinSizeLimit.\n{\n    // It narrows the type of the transaction message to include the `TransactionMessageWithinSizeLimit` flag.\n    {\n        const transactionMessage = null as unknown as TransactionMessage & TransactionMessageWithFeePayer;\n        if (isTransactionMessageWithinSizeLimit(transactionMessage)) {\n            transactionMessage satisfies TransactionMessage &\n                TransactionMessageWithFeePayer &\n                TransactionMessageWithinSizeLimit;\n        }\n    }\n\n    // It keeps any extra properties from the transaction message.\n    {\n        const transactionMessage = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { some: 1 };\n        if (isTransactionMessageWithinSizeLimit(transactionMessage)) {\n            transactionMessage satisfies TransactionMessage & TransactionMessageWithFeePayer & { some: 1 };\n        }\n    }\n}\n\n// [DESCRIBE] assertIsTransactionMessageWithinSizeLimit.\n{\n    // It narrows the type of the transaction message to include the `TransactionMessageWithinSizeLimit` flag.\n    {\n        const transactionMessage = null as unknown as TransactionMessage & TransactionMessageWithFeePayer;\n        assertIsTransactionMessageWithinSizeLimit(transactionMessage);\n        transactionMessage satisfies TransactionMessage &\n            TransactionMessageWithFeePayer &\n            TransactionMessageWithinSizeLimit;\n    }\n\n    // It keeps any extra properties from the transaction message.\n    {\n        const transactionMessage = null as unknown as TransactionMessage & TransactionMessageWithFeePayer & { some: 1 };\n        assertIsTransactionMessageWithinSizeLimit(transactionMessage);\n        transactionMessage satisfies TransactionMessage & TransactionMessageWithFeePayer & { some: 1 };\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/transaction-size-typetest.ts",
    "content": "import type { TransactionMessage, TransactionMessageWithinSizeLimit } from '@solana/transaction-messages';\n\nimport { Transaction } from '../transaction';\nimport {\n    assertIsTransactionWithinSizeLimit,\n    isTransactionWithinSizeLimit,\n    SetTransactionWithinSizeLimitFromTransactionMessage,\n    TransactionWithinSizeLimit,\n} from '../transaction-size';\n\n// [DESCRIBE] isTransactionWithinSizeLimit.\n{\n    // It narrows the type of the transaction to include the `TransactionWithinSizeLimit` flag.\n    {\n        const transaction = null as unknown as Transaction;\n        if (isTransactionWithinSizeLimit(transaction)) {\n            transaction satisfies Transaction & TransactionWithinSizeLimit;\n        }\n    }\n\n    // It keeps any extra properties from the transaction.\n    {\n        const transaction = null as unknown as Transaction & { some: 1 };\n        if (isTransactionWithinSizeLimit(transaction)) {\n            transaction satisfies Transaction & { some: 1 };\n        }\n    }\n}\n\n// [DESCRIBE] assertIsTransactionWithinSizeLimit.\n{\n    // It narrows the type of the transaction to include the `TransactionWithinSizeLimit` flag.\n    {\n        const transaction = null as unknown as Transaction;\n        assertIsTransactionWithinSizeLimit(transaction);\n        transaction satisfies Transaction & TransactionWithinSizeLimit;\n    }\n\n    // It keeps any extra properties from the transaction.\n    {\n        const transaction = null as unknown as Transaction & { some: 1 };\n        assertIsTransactionWithinSizeLimit(transaction);\n        transaction satisfies Transaction & { some: 1 };\n    }\n}\n\n// [DESCRIBE] SetTransactionWithinSizeLimitFromTransactionMessage.\n{\n    // It augments the provided transaction with the `TransactionWithinSizeLimit` flag.\n    {\n        type Result = SetTransactionWithinSizeLimitFromTransactionMessage<\n            Transaction,\n            TransactionMessage & TransactionMessageWithinSizeLimit\n        >;\n        null as unknown as Result satisfies Transaction & TransactionWithinSizeLimit;\n    }\n\n    // It keeps any extra properties from the transaction but not from the transaction message.\n    {\n        type Result = SetTransactionWithinSizeLimitFromTransactionMessage<\n            Transaction & { _from_transaction: 1 },\n            TransactionMessage & TransactionMessageWithinSizeLimit & { _from_transaction_message: 1 }\n        >;\n        null as unknown as Result satisfies { _from_transaction: 1 };\n        // @ts-expect-error Does not keep extra properties from transaction messages.\n        null as unknown as Result satisfies { _from_transaction_message: 1 };\n    }\n\n    // It returns the transaction as-is if the transaction message is not within size limit.\n    {\n        type Result = SetTransactionWithinSizeLimitFromTransactionMessage<\n            Transaction & { some: 1 },\n            TransactionMessage\n        >;\n        null as unknown as Result satisfies Transaction & { some: 1 };\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/transaction-typetest.ts",
    "content": "import type {\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithDurableNonceLifetime,\n    TransactionMessageWithinSizeLimit,\n} from '@solana/transaction-messages';\n\nimport type {\n    TransactionWithBlockhashLifetime,\n    TransactionWithDurableNonceLifetime,\n    TransactionWithLifetime,\n} from '../lifetime';\nimport type { Transaction, TransactionFromTransactionMessage } from '../transaction';\nimport { TransactionWithinSizeLimit } from '../transaction-size';\n\n// [DESCRIBE] TransactionFromTransactionMessage.\n{\n    // It returns a transaction with no lifetime constraint if the message has no lifetime constraint.\n    {\n        type Result = TransactionFromTransactionMessage<TransactionMessage>;\n        null as unknown as Result satisfies Readonly<Transaction>;\n        // @ts-expect-error Expects no lifetime constraint.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithLifetime>;\n    }\n\n    // It returns a transaction with an unknown lifetime constraint when the message lifetime constraint exists but is unknown.\n    {\n        type Result = TransactionFromTransactionMessage<TransactionMessage & TransactionWithLifetime>;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithLifetime>;\n        // @ts-expect-error Cannot know that the lifetime constraint is a blockhash lifetime.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithBlockhashLifetime>;\n        // @ts-expect-error Cannot know that the lifetime constraint is a durable nonce lifetime.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n    }\n\n    // It does not keep extra properties from the transaction message.\n    {\n        type Result = TransactionFromTransactionMessage<TransactionMessage & { some: 1 }>;\n        null as unknown as Result satisfies Readonly<Transaction>;\n        // @ts-expect-error Does not keep extra properties from transaction messages.\n        null as unknown as Result satisfies Readonly<{ some: 1 }>;\n    }\n\n    // It forwards the blockhash lifetime constraint from the transaction message to the transaction.\n    {\n        type Result = TransactionFromTransactionMessage<TransactionMessage & TransactionMessageWithBlockhashLifetime>;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithBlockhashLifetime>;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithLifetime>;\n        // @ts-expect-error Cannot be a durable nonce lifetime.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n    }\n\n    // It forwards the durable nonce lifetime constraint from the transaction message to the transaction.\n    {\n        type Result = TransactionFromTransactionMessage<\n            TransactionMessage & TransactionMessageWithDurableNonceLifetime\n        >;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithDurableNonceLifetime>;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithLifetime>;\n        // @ts-expect-error Cannot be a blockhash lifetime.\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithBlockhashLifetime>;\n    }\n\n    // It forwards the within size limit flag from the transaction message to the transaction.\n    {\n        type Result = TransactionFromTransactionMessage<TransactionMessage & TransactionMessageWithinSizeLimit>;\n        null as unknown as Result satisfies Readonly<Transaction & TransactionWithinSizeLimit>;\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/transaction-typetests.ts",
    "content": "import { EncodedString } from '@solana/nominal-types';\n\nimport { TransactionMessageBytesBase64 } from '../transaction';\n\n// [DESCRIBE] TransactionMessageBytesBase64\n{\n    // It satisfies the base64 encoded string brand\n    {\n        const encodedBytes = null as unknown as TransactionMessageBytesBase64;\n        encodedBytes satisfies EncodedString<string, 'base64'>;\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/__typetests__/wire-transaction-typetests.ts",
    "content": "import { EncodedString } from '@solana/nominal-types';\n\nimport { Transaction } from '../transaction';\nimport { getBase64EncodedWireTransaction } from '../wire-transaction';\n\nconst transaction = null as unknown as Transaction;\n\n// [DESCRIBE] getBase64EncodedWireTransaction\n{\n    // The return value satisfies the base64 encoded string brand\n    {\n        getBase64EncodedWireTransaction(transaction) satisfies EncodedString<string, 'base64'>;\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/codecs/__tests__/signatures-encoder-test.ts",
    "content": "import { Address } from '@solana/addresses';\nimport {\n    SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS,\n    SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../../transaction';\nimport { getSignaturesEncoderWithLength, getSignaturesEncoderWithSizePrefix } from '../signatures-encoder';\n\ndescribe('getSignaturesEncoderWithSizePrefix', () => {\n    const encoder = getSignaturesEncoderWithSizePrefix();\n\n    it('should throw if the signatures map is empty', () => {\n        const signatures: SignaturesMap = {};\n        expect(() => encoder.encode(signatures)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES),\n        );\n    });\n\n    describe('when the signatures map contains one entry', () => {\n        const address = 'abc' as Address;\n\n        it('should return the bytes of a single signature if it is defined', () => {\n            const signature = new Uint8Array(64).fill(1) as SignatureBytes;\n            const signatures: SignaturesMap = { [address]: signature };\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* length of signatures */\n                    1,\n                    /* signature */\n                    ...signature,\n                ]),\n            );\n        });\n\n        it('should return all 0 bytes for the signature if it is not defined', () => {\n            const signatures: SignaturesMap = { [address]: null };\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* length of signatures */\n                    1,\n                    /* null signature */\n                    ...new Uint8Array(64).fill(0),\n                ]),\n            );\n        });\n    });\n\n    describe('when the signatures map contains multiple entries', () => {\n        // intentionally out of order\n        const address1 = 'fff' as Address;\n        const address2 = 'eee' as Address;\n        const address3 = 'ddd' as Address;\n\n        const signature1 = new Uint8Array(64).fill(1) as SignatureBytes;\n        const signature2 = new Uint8Array(64).fill(2) as SignatureBytes;\n        const signature3 = new Uint8Array(64).fill(3) as SignatureBytes;\n\n        it('should return the bytes of multiple signatures if all are defined', () => {\n            const signatures: SignaturesMap = {\n                [address1]: signature1,\n                [address2]: signature2,\n                [address3]: signature3,\n            };\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* length of signatures */\n                    3,\n                    /* signatures */\n                    ...signature1,\n                    ...signature2,\n                    ...signature3,\n                ]),\n            );\n        });\n\n        it('should return multiple all 0 byte signatures if all are not defined', () => {\n            const signatures: SignaturesMap = {\n                [address1]: null,\n                [address2]: null,\n                [address3]: null,\n            };\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* length of signatures */\n                    3,\n                    /* signatures */\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n                ]),\n            );\n        });\n\n        it('should return a mixture of defined and not defined signatures', () => {\n            const signatures: SignaturesMap = {\n                [address1]: signature1,\n                [address2]: null,\n                [address3]: signature3,\n            };\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* length of signatures */\n                    3,\n                    /* signatures */\n                    ...signature1,\n                    ...new Uint8Array(64).fill(0),\n                    ...signature3,\n                ]),\n            );\n        });\n    });\n});\n\ndescribe('getSignaturesEncoderWithLength', () => {\n    it('should throw if the signatures map is empty', () => {\n        const signatures: SignaturesMap = {};\n        const encoder = getSignaturesEncoderWithLength(1);\n        expect(() => encoder.encode(signatures)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES),\n        );\n    });\n\n    describe('when the signatures map contains one entry', () => {\n        const address = 'abc' as Address;\n\n        it('should return the bytes of a single signature if it is defined', () => {\n            const signature = new Uint8Array(64).fill(1) as SignatureBytes;\n            const signatures: SignaturesMap = { [address]: signature };\n            const encoder = getSignaturesEncoderWithLength(1);\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* no size prefix */\n                    /* signature */\n                    ...signature,\n                ]),\n            );\n        });\n\n        it('should return all 0 bytes for the signature if it is not defined', () => {\n            const signatures: SignaturesMap = { [address]: null };\n            const encoder = getSignaturesEncoderWithLength(1);\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* no size prefix */\n                    /* null signature */\n                    ...new Uint8Array(64).fill(0),\n                ]),\n            );\n        });\n    });\n\n    describe('when the signatures map contains multiple entries', () => {\n        // intentionally out of order\n        const address1 = 'fff' as Address;\n        const address2 = 'eee' as Address;\n        const address3 = 'ddd' as Address;\n\n        const signature1 = new Uint8Array(64).fill(1) as SignatureBytes;\n        const signature2 = new Uint8Array(64).fill(2) as SignatureBytes;\n        const signature3 = new Uint8Array(64).fill(3) as SignatureBytes;\n\n        it('should return the bytes of multiple signatures if all are defined', () => {\n            const signatures: SignaturesMap = {\n                [address1]: signature1,\n                [address2]: signature2,\n                [address3]: signature3,\n            };\n            const encoder = getSignaturesEncoderWithLength(3);\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* no size prefix */\n                    /* signatures */\n                    ...signature1,\n                    ...signature2,\n                    ...signature3,\n                ]),\n            );\n        });\n\n        it('should return multiple all 0 byte signatures if all are not defined', () => {\n            const signatures: SignaturesMap = {\n                [address1]: null,\n                [address2]: null,\n                [address3]: null,\n            };\n            const encoder = getSignaturesEncoderWithLength(3);\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* no size prefix */\n                    /* signatures */\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n                ]),\n            );\n        });\n\n        it('should return a mixture of defined and not defined signatures', () => {\n            const signatures: SignaturesMap = {\n                [address1]: signature1,\n                [address2]: null,\n                [address3]: signature3,\n            };\n            const encoder = getSignaturesEncoderWithLength(3);\n            const encoded = encoder.encode(signatures);\n\n            expect(encoded).toStrictEqual(\n                new Uint8Array([\n                    /* no size prefix */\n                    /* signatures */\n                    ...signature1,\n                    ...new Uint8Array(64).fill(0),\n                    ...signature3,\n                ]),\n            );\n        });\n\n        it('should throw if the number of signatures is more than the expected size', () => {\n            const signatures: SignaturesMap = {\n                [address1]: signature1,\n                [address2]: signature2,\n                [address3]: signature3,\n            };\n            const encoder = getSignaturesEncoderWithLength(2);\n            expect(() => encoder.encode(signatures)).toThrow(\n                new SolanaError(SOLANA_ERROR__CODECS__INVALID_NUMBER_OF_ITEMS, {\n                    actual: 3,\n                    codecDescription: 'signatures',\n                    expected: 2,\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transactions/src/codecs/__tests__/transaction-codec-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\n\nimport { Address } from '@solana/addresses';\nimport { Encoder, ReadonlyUint8Array, VariableSizeDecoder } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES,\n    SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { Transaction, TransactionMessageBytes } from '../../transaction';\nimport { getSignaturesEncoderWithLength, getSignaturesEncoderWithSizePrefix } from '../signatures-encoder';\nimport { getTransactionCodec, getTransactionDecoder, getTransactionEncoder } from '../transaction-codec';\n\njest.mock('../signatures-encoder');\n\ndescribe.each([getTransactionEncoder, getTransactionCodec])('Transaction encoder %p', encoderFactory => {\n    const mockEncodedSignatures = new Uint8Array([1, 2, 3]);\n    let encoder: Encoder<Transaction>;\n    beforeEach(() => {\n        (getSignaturesEncoderWithSizePrefix as jest.Mock).mockReturnValue({\n            getSizeFromValue: jest.fn().mockReturnValue(mockEncodedSignatures.length),\n            write: jest.fn().mockImplementation((_value, bytes: Uint8Array, offset: number) => {\n                bytes.set(mockEncodedSignatures, offset);\n                return offset + mockEncodedSignatures.length;\n            }),\n        });\n\n        encoder = encoderFactory();\n    });\n\n    it('should encode a legacy transaction correctly', () => {\n        // Legacy transactions have signature number as the first byte of the message\n        const messageBytes = new Uint8Array([4, 5, 6]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n        const transaction: Transaction = {\n            messageBytes,\n            signatures: {},\n        };\n\n        expect(encoder.encode(transaction)).toStrictEqual(\n            new Uint8Array([\n                /* signatures */\n                ...mockEncodedSignatures,\n                /* message bytes */\n                ...messageBytes,\n            ]),\n        );\n    });\n\n    it('should encode a v0 transaction correctly', () => {\n        // v0 transactions have the first byte with the version bit set to 128\n        const messageBytes = new Uint8Array([128, 4, 5, 6]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n        const transaction: Transaction = {\n            messageBytes,\n            signatures: {},\n        };\n\n        expect(encoder.encode(transaction)).toStrictEqual(\n            new Uint8Array([\n                /* signatures */\n                ...mockEncodedSignatures,\n                /* message bytes */\n                ...messageBytes,\n            ]),\n        );\n    });\n\n    it('should encode a v1 transaction correctly', () => {\n        // v1 transactions have the first byte with the version bit set to 129\n        const messageBytes = new Uint8Array([129, 1, 5, 6]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n        const mockSignature = new Uint8Array(64).fill(1);\n\n        // In this case we have a VariableSizEncoder with size messageBytes + (signatures * 64)\n        // So we will mock the signature encoder with the size of a real signature\n        // The second byte of `messageBytes` is 1, so we encode to 1 signature\n        (getSignaturesEncoderWithLength as jest.Mock).mockReturnValue({\n            fixedSize: 64,\n            write: jest.fn().mockImplementation((_value, bytes: Uint8Array, offset: number) => {\n                bytes.set(mockSignature, offset);\n                return offset + mockSignature.length;\n            }),\n        });\n\n        const transaction: Transaction = {\n            messageBytes,\n            signatures: {},\n        };\n\n        expect(encoder.encode(transaction)).toStrictEqual(\n            new Uint8Array([\n                /* message bytes */\n                ...messageBytes,\n                /* signatures */\n                ...mockSignature,\n            ]),\n        );\n\n        expect(getSignaturesEncoderWithLength).toHaveBeenCalledTimes(1);\n        expect(getSignaturesEncoderWithLength).toHaveBeenCalledWith(1);\n    });\n\n    it('should throw for a v1 transaction if there are no other message bytes', () => {\n        // v1 transactions have the first byte with the version bit set to 129\n        // the following byte is signature count, but here the message bytes is malformed\n        const messageBytes = new Uint8Array([129]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n        const transaction: Transaction = {\n            messageBytes,\n            signatures: {},\n        };\n\n        expect(() => encoder.encode(transaction)).toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES, {\n                messageBytes,\n            }),\n        );\n    });\n});\n\ndescribe.each([getTransactionDecoder, getTransactionCodec])('Transaction decoder %p', decoderFactory => {\n    let decoder: VariableSizeDecoder<Transaction>;\n    beforeEach(() => {\n        (getSignaturesEncoderWithSizePrefix as jest.Mock).mockReturnValue({\n            getSizeFromValue: jest.fn().mockReturnValue(0),\n            write: jest.fn(),\n        });\n        decoder = decoderFactory();\n    });\n\n    describe('for a legacy transaction', () => {\n        describe('for a transaction with a single signature', () => {\n            const addressBytes = new Uint8Array(64).fill(11);\n            const address = 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address;\n\n            it('should decode the transaction correctly when the signature is defined', () => {\n                const signature = new Uint8Array(64).fill(1) as ReadonlyUint8Array as SignatureBytes;\n                const messageBytes = new Uint8Array([\n                    /** NO VERSION BYTE */\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    2, // Number of static accounts\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    1, // num signatures\n                    ...signature,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address]: signature,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when the signature is not defined', () => {\n                const signature = new Uint8Array(64).fill(0) as ReadonlyUint8Array as SignatureBytes;\n                const messageBytes = new Uint8Array([\n                    /** NO VERSION BYTE */\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    2, // Number of static accounts\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    1, // num signatures\n                    ...signature,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const address = 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address;\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address]: null,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should freeze the signatures map', () => {\n                const signature = new Uint8Array(64).fill(0) as ReadonlyUint8Array as SignatureBytes;\n                const messageBytes = new Uint8Array([\n                    /** NO VERSION BYTE */\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    2, // Number of static accounts\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    1, // num signatures\n                    ...signature,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const decoded = decoder.decode(encodedTransaction);\n                expect(decoded.signatures).toBeFrozenObject();\n            });\n        });\n\n        describe('for a transaction with multiple signatures', () => {\n            const address1Bytes = new Uint8Array(32).fill(11);\n            const address1 = 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address;\n\n            const address2Bytes = new Uint8Array(32).fill(12);\n            const address2 = 'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address;\n\n            const address3Bytes = new Uint8Array(32).fill(13);\n            const address3 = 'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address;\n\n            const signature1 = new Uint8Array(64).fill(1) as ReadonlyUint8Array as SignatureBytes;\n            const signature2 = new Uint8Array(64).fill(2) as ReadonlyUint8Array as SignatureBytes;\n            const signature3 = new Uint8Array(64).fill(3) as ReadonlyUint8Array as SignatureBytes;\n\n            it('should decode the transaction correctly when all the signatures are defined', () => {\n                const messageBytes = new Uint8Array([\n                    /** NO VERSION BYTE */\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    4, // Number of static accounts\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(21),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    3, // num signatures\n                    ...signature1,\n                    ...signature2,\n                    ...signature3,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: signature1,\n                        [address2]: signature2,\n                        [address3]: signature3,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when none of the signatures are defined', () => {\n                const messageBytes = new Uint8Array([\n                    /** NO VERSION BYTE */\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    4, // Number of static accounts\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(21),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    3, // num signatures\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: null,\n                        [address2]: null,\n                        [address3]: null,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when some of the signatures are defined', () => {\n                const messageBytes = new Uint8Array([\n                    /** NO VERSION BYTE */\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    4, // Number of static accounts\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(21),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    3, // num signatures\n                    ...signature1,\n                    ...new Uint8Array(64).fill(0),\n                    ...signature3,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: signature1,\n                        [address2]: null,\n                        [address3]: signature3,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should throw when the number of signers in the header does not match the number of signatures', () => {\n                const messageBytes = new Uint8Array([\n                    /** NO VERSION BYTE */\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    4, // Number of static accounts\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(21),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    2, // num signatures\n                    ...signature1,\n                    ...signature2,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                expect(() => decoder.decode(encodedTransaction)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n                        numRequiredSignatures: 3,\n                        signaturesLength: 2,\n                        signerAddresses: [address1, address2, address3],\n                    }),\n                );\n            });\n        });\n    });\n\n    describe('for a v0 transaction', () => {\n        describe('for a transaction with a single signature', () => {\n            const addressBytes = new Uint8Array(64).fill(11);\n            const address = 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address;\n\n            it('should decode the transaction correctly when the signature is defined', () => {\n                const signature = new Uint8Array(64).fill(1) as ReadonlyUint8Array as SignatureBytes;\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    2, // Number of static accounts\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    1, // num signatures\n                    ...signature,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address]: signature,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when the signature is not defined', () => {\n                const signature = new Uint8Array(64).fill(0) as ReadonlyUint8Array as SignatureBytes;\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    2, // Number of static accounts\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    1, // num signatures\n                    ...signature,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const address = 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address;\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address]: null,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should freeze the signatures map', () => {\n                const signature = new Uint8Array(64).fill(0) as ReadonlyUint8Array as SignatureBytes;\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    2, // Number of static accounts\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    1, // num signatures\n                    ...signature,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const decoded = decoder.decode(encodedTransaction);\n                expect(decoded.signatures).toBeFrozenObject();\n            });\n        });\n\n        describe('for a transaction with multiple signatures', () => {\n            const address1Bytes = new Uint8Array(32).fill(11);\n            const address1 = 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address;\n\n            const address2Bytes = new Uint8Array(32).fill(12);\n            const address2 = 'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address;\n\n            const address3Bytes = new Uint8Array(32).fill(13);\n            const address3 = 'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address;\n\n            const signature1 = new Uint8Array(64).fill(1) as ReadonlyUint8Array as SignatureBytes;\n            const signature2 = new Uint8Array(64).fill(2) as ReadonlyUint8Array as SignatureBytes;\n            const signature3 = new Uint8Array(64).fill(3) as ReadonlyUint8Array as SignatureBytes;\n\n            it('should decode the transaction correctly when all the signatures are defined', () => {\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    4, // Number of static accounts\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(21),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    3, // num signatures\n                    ...signature1,\n                    ...signature2,\n                    ...signature3,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: signature1,\n                        [address2]: signature2,\n                        [address3]: signature3,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when none of the signatures are defined', () => {\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    4, // Number of static accounts\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(21),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    3, // num signatures\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: null,\n                        [address2]: null,\n                        [address3]: null,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when some of the signatures are defined', () => {\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    4, // Number of static accounts\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(21),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    3, // num signatures\n                    ...signature1,\n                    ...new Uint8Array(64).fill(0),\n                    ...signature3,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: signature1,\n                        [address2]: null,\n                        [address3]: signature3,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should throw when the number of signers in the header does not match the number of signatures', () => {\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    128, // 0 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** STATIC ADDRESSES */\n                    4, // Number of static accounts\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(21),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** SIGNATURES */\n                    2, // num signatures\n                    ...signature1,\n                    ...signature2,\n\n                    /** MESSAGE */\n                    ...messageBytes,\n                ]);\n\n                expect(() => decoder.decode(encodedTransaction)).toThrow(\n                    new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n                        numRequiredSignatures: 3,\n                        signaturesLength: 2,\n                        signerAddresses: [address1, address2, address3],\n                    }),\n                );\n            });\n        });\n    });\n\n    describe('for a v1 transaction', () => {\n        describe('for a transaction with a single signature', () => {\n            const addressBytes = new Uint8Array(64).fill(11);\n            const address = 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address;\n\n            it('should decode the transaction correctly when the signature is defined', () => {\n                const signature = new Uint8Array(64).fill(1) as ReadonlyUint8Array as SignatureBytes;\n                // prettier-ignore\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    129, // 1 + version mask\n\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** TRANSACTION CONFIG MASK */\n                    0, 0, 0, 0, // arbitrary, 4 bytes\n\n                    /** LIFETIME SPECIFIER */\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0, // arbitrary, 32 bytes\n\n                    /** NUM INSTRUCTIONS */\n                    1, // arbitrary\n\n                    /** NUM ACCOUNTS */\n                    2,\n\n                    /** STATIC ADDRESSES */\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** MESSAGE */\n                    ...messageBytes,\n\n                    /** SIGNATURES */\n                    ...signature,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address]: signature,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when the signature is not defined', () => {\n                const signature = new Uint8Array(64).fill(0) as ReadonlyUint8Array as SignatureBytes;\n                // prettier-ignore\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    129, // 1 + version mask\n\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** TRANSACTION CONFIG MASK */\n                    0,\n                    0,\n                    0,\n                    0, // arbitrary\n\n                    /** LIFETIME SPECIFIER */\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0, // arbitrary, 32 bytes\n\n                    /** NUM INSTRUCTIONS */\n                    1, // arbitrary\n\n                    /** NUM ACCOUNTS */\n                    2,\n\n                    /** STATIC ADDRESSES */\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** MESSAGE */\n                    ...messageBytes,\n\n                    /** SIGNATURES */\n                    ...signature,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address]: null,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should freeze the signatures map', () => {\n                const signature = new Uint8Array(64).fill(0) as ReadonlyUint8Array as SignatureBytes;\n                // prettier-ignore\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    129, // 1 + version mask\n\n                    /** MESSAGE HEADER */\n                    1, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** TRANSACTION CONFIG MASK */\n                    0,\n                    0,\n                    0,\n                    0, // arbitrary\n\n                    /** LIFETIME SPECIFIER */\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0, // arbitrary, 32 bytes\n\n                    /** NUM INSTRUCTIONS */\n                    1, // arbitrary\n\n                    /** NUM ACCOUNTS */\n                    2,\n\n                    /** STATIC ADDRESSES */\n                    ...addressBytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** MESSAGE */\n                    ...messageBytes,\n\n                    /** SIGNATURES */\n                    ...signature,\n                ]);\n\n                const decoded = decoder.decode(encodedTransaction);\n                expect(decoded.signatures).toBeFrozenObject();\n            });\n        });\n\n        describe('for a transaction with multiple signatures', () => {\n            const address1Bytes = new Uint8Array(32).fill(11);\n            const address1 = 'k7FaK87WHGVXzkaoHb7CdVPgkKDQhZ29VLDeBVbDfYn' as Address;\n\n            const address2Bytes = new Uint8Array(32).fill(12);\n            const address2 = 'p2Yicb86aZig616Eav2VWG9vuXR5mEqhtzshZYBxzsV' as Address;\n\n            const address3Bytes = new Uint8Array(32).fill(13);\n            const address3 = 'swqrv48gsrwpBFbftEwnP2vB4jckpvfGJfXkwaniLCC' as Address;\n\n            const signature1 = new Uint8Array(64).fill(1) as ReadonlyUint8Array as SignatureBytes;\n            const signature2 = new Uint8Array(64).fill(2) as ReadonlyUint8Array as SignatureBytes;\n            const signature3 = new Uint8Array(64).fill(3) as ReadonlyUint8Array as SignatureBytes;\n\n            it('should decode the transaction correctly when all the signatures are defined', () => {\n                // prettier-ignore\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    129, // 1 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** TRANSACTION CONFIG MASK */\n                    0,\n                    0,\n                    0,\n                    0, // arbitrary\n\n                    /** LIFETIME SPECIFIER */\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0, // arbitrary, 32 bytes\n\n                    /** NUM INSTRUCTIONS */\n                    1, // arbitrary\n\n                    /** NUM ACCOUNTS */\n                    4,\n\n                    /** STATIC ADDRESSES */\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** MESSAGE */\n                    ...messageBytes,\n\n                    /** SIGNATURES */\n                    ...signature1,\n                    ...signature2,\n                    ...signature3,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: signature1,\n                        [address2]: signature2,\n                        [address3]: signature3,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when none of the signatures are defined', () => {\n                // prettier-ignore\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    129, // 1 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** TRANSACTION CONFIG MASK */\n                    0,\n                    0,\n                    0,\n                    0, // arbitrary\n\n                    /** LIFETIME SPECIFIER */\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0, // arbitrary, 32 bytes\n\n                    /** NUM INSTRUCTIONS */\n                    1, // arbitrary\n\n                    /** NUM ACCOUNTS */\n                    4,\n\n                    /** STATIC ADDRESSES */\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** MESSAGE */\n                    ...messageBytes,\n\n                    /** SIGNATURES */\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n                    ...new Uint8Array(64).fill(0),\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: null,\n                        [address2]: null,\n                        [address3]: null,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n\n            it('should decode the transaction correctly when some of the signatures are defined', () => {\n                // prettier-ignore\n                const messageBytes = new Uint8Array([\n                    /** VERSION HEADER */\n                    129, // 1 + version mask\n\n                    /** MESSAGE HEADER */\n                    3, // numSignerAccounts\n                    0, // numReadonlySignerAccount\n                    1, // numReadonlyNonSignerAccounts\n\n                    /** TRANSACTION CONFIG MASK */\n                    0,\n                    0,\n                    0,\n                    0, // arbitrary\n\n                    /** LIFETIME SPECIFIER */\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 0, 0, 0, 0, // arbitrary, 32 bytes\n\n                    /** NUM INSTRUCTIONS */\n                    1, // arbitrary\n\n                    /** NUM ACCOUNTS */\n                    4,\n\n                    /** STATIC ADDRESSES */\n                    ...address1Bytes,\n                    ...address2Bytes,\n                    ...address3Bytes,\n                    ...new Uint8Array(64).fill(12),\n\n                    /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                    ...new Uint8Array(100).fill(1),\n                ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n                const encodedTransaction = new Uint8Array([\n                    /** MESSAGE */\n                    ...messageBytes,\n\n                    /** SIGNATURES */\n                    ...signature1,\n                    ...new Uint8Array(64).fill(0),\n                    ...signature3,\n                ]);\n\n                const expectedTransaction: Transaction = {\n                    messageBytes: messageBytes,\n                    signatures: {\n                        [address1]: signature1,\n                        [address2]: null,\n                        [address3]: signature3,\n                    },\n                };\n                expect(decoder.decode(encodedTransaction)).toStrictEqual(expectedTransaction);\n            });\n        });\n    });\n\n    describe('unsupported transaction versions', () => {\n        it('should throw for a v0-shaped transaction with a v2 version byte', () => {\n            const messageBytes = new Uint8Array([\n                /** VERSION HEADER */\n                130, // 2 + version mask\n\n                /** MESSAGE HEADER */\n                1, // numSignerAccounts\n                0, // numReadonlySignerAccount\n                0, // numReadonlyNonSignerAccounts\n\n                /** STATIC ADDRESSES */\n                1, // Number of static accounts\n                ...new Uint8Array(64).fill(12),\n\n                /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                ...new Uint8Array(100).fill(1),\n            ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n            const encodedTransaction = new Uint8Array([\n                /** SIGNATURES */\n                1, // num signatures\n                ...(new Uint8Array(64).fill(1) as ReadonlyUint8Array as SignatureBytes),\n\n                /** MESSAGE */\n                ...messageBytes,\n            ]);\n\n            expect(() => decoder.decode(encodedTransaction)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                    unsupportedVersion: 2,\n                }),\n            );\n        });\n\n        it('should throw for a v1-shaped transaction with a v2 version byte', () => {\n            // prettier-ignore\n            const messageBytes = new Uint8Array([\n                /** VERSION HEADER */\n                130, // 2 + version mask\n\n                /** MESSAGE HEADER */\n                1, // numSignerAccounts\n                0, // numReadonlySignerAccount\n                0, // numReadonlyNonSignerAccounts\n\n                /** TRANSACTION CONFIG MASK */\n                0,\n                0,\n                0,\n                0, // arbitrary\n\n                /** LIFETIME SPECIFIER */\n                0, 0, 0, 0, 0, 0, 0, 0,\n                0, 0, 0, 0, 0, 0, 0, 0,\n                0, 0, 0, 0, 0, 0, 0, 0,\n                0, 0, 0, 0, 0, 0, 0, 0, // arbitrary, 32 bytes\n\n                /** NUM INSTRUCTIONS */\n                1, // arbitrary\n\n                /** NUM ACCOUNTS */\n                1,\n\n                /** STATIC ADDRESSES */\n                ...new Uint8Array(64).fill(12),\n\n                /** REST OF TRANSACTION MESSAGE (arbitrary) */\n                ...new Uint8Array(100).fill(1),\n            ]) as ReadonlyUint8Array as TransactionMessageBytes;\n\n            const encodedTransaction = new Uint8Array([\n                /** MESSAGE */\n                ...messageBytes,\n\n                /** SIGNATURES */\n                ...(new Uint8Array(64).fill(0) as ReadonlyUint8Array as SignatureBytes),\n            ]);\n\n            expect(() => decoder.decode(encodedTransaction)).toThrow(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n                    unsupportedVersion: 2,\n                }),\n            );\n        });\n    });\n});\n"
  },
  {
    "path": "packages/transactions/src/codecs/index.ts",
    "content": "export * from './transaction-codec';\n"
  },
  {
    "path": "packages/transactions/src/codecs/signatures-encoder.ts",
    "content": "import { FixedSizeEncoder, fixEncoderSize, transformEncoder, VariableSizeEncoder } from '@solana/codecs-core';\nimport { getArrayEncoder, getBytesEncoder } from '@solana/codecs-data-structures';\nimport { getShortU16Encoder } from '@solana/codecs-numbers';\nimport { SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES, SolanaError } from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\n\nimport { SignaturesMap } from '../transaction';\n\nfunction getSignaturesToEncode(signaturesMap: SignaturesMap): SignatureBytes[] {\n    const signatures = Object.values(signaturesMap);\n    if (signatures.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_SIGNATURES);\n    }\n\n    return signatures.map(signature => {\n        if (!signature) {\n            return new Uint8Array(64).fill(0) as SignatureBytes;\n        }\n        return signature;\n    });\n}\n\n/**\n * Signatures encoder used for legacy and v0 transactions, which encode signatures\n * as an array with a u16-short size prefix\n *\n * @internal\n */\nexport function getSignaturesEncoderWithSizePrefix(): VariableSizeEncoder<SignaturesMap> {\n    return transformEncoder(\n        getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { size: getShortU16Encoder() }),\n        getSignaturesToEncode,\n    );\n}\n\n/**\n * Signatures encoder used for v1 transactions, which encode signatures\n * as a known-size array\n *\n * @param size Known number of signatures for the transaction\n *\n * @internal\n */\nexport function getSignaturesEncoderWithLength(size: number): FixedSizeEncoder<SignaturesMap> {\n    return transformEncoder(\n        getArrayEncoder(fixEncoderSize(getBytesEncoder(), 64), { description: 'signatures', size }),\n        getSignaturesToEncode,\n    );\n}\n"
  },
  {
    "path": "packages/transactions/src/codecs/transaction-codec.ts",
    "content": "import { Address, getAddressDecoder } from '@solana/addresses';\nimport {\n    combineCodec,\n    createDecoder,\n    createEncoder,\n    fixDecoderSize,\n    padRightDecoder,\n    ReadonlyUint8Array,\n    transformDecoder,\n    VariableSizeCodec,\n    VariableSizeDecoder,\n    VariableSizeEncoder,\n} from '@solana/codecs-core';\nimport {\n    getArrayDecoder,\n    getBytesDecoder,\n    getBytesEncoder,\n    getPredicateDecoder,\n    getPredicateEncoder,\n    getStructDecoder,\n    getStructEncoder,\n    getTupleDecoder,\n} from '@solana/codecs-data-structures';\nimport { getShortU16Decoder, getU8Decoder } from '@solana/codecs-numbers';\nimport {\n    SOLANA_ERROR__TRANSACTION__CANNOT_DECODE_EMPTY_TRANSACTION_BYTES,\n    SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_MESSAGE_BYTES,\n    SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES,\n    SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH,\n    SOLANA_ERROR__TRANSACTION__SIGNATURE_COUNT_TOO_HIGH_FOR_TRANSACTION_BYTES,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED,\n    SOLANA_ERROR__TRANSACTION__VERSION_ZERO_MUST_BE_ENCODED_WITH_SIGNATURES_FIRST,\n    SolanaError,\n} from '@solana/errors';\nimport { SignatureBytes } from '@solana/keys';\nimport { getTransactionVersionDecoder } from '@solana/transaction-messages';\n\nimport { SignaturesMap, Transaction, TransactionMessageBytes } from '../transaction';\nimport { getSignaturesEncoderWithLength, getSignaturesEncoderWithSizePrefix } from './signatures-encoder';\n\ntype EnvelopeShape = 'messageFirst' | 'signaturesFirst';\n\nconst SIGNATURE_COUNT_FLAG_MASK = 0b10000000;\nconst VERSION_FLAG_MASK = 0b01111111;\n\nfunction getEnvelopeShapeFromMessageBytes(messageBytes: ReadonlyUint8Array): EnvelopeShape {\n    if (messageBytes.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_ENCODE_WITH_EMPTY_MESSAGE_BYTES);\n    }\n\n    const version = getTransactionVersionDecoder().decode(messageBytes);\n    return version === 1 ? 'messageFirst' : 'signaturesFirst';\n}\n\nfunction getEnvelopeShapeFromTransactionBytes(transactionBytes: ReadonlyUint8Array): EnvelopeShape {\n    if (transactionBytes.length === 0) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__CANNOT_DECODE_EMPTY_TRANSACTION_BYTES);\n    }\n    const firstByte = transactionBytes[0];\n    if ((firstByte & SIGNATURE_COUNT_FLAG_MASK) === 0) {\n        // First byte is a signature count, so signatures come first\n        return 'signaturesFirst';\n    }\n    // If the first byte is not a signature count, then we must have message bytes first,\n    // and the first byte of the message must be the version byte\n    const version = firstByte & VERSION_FLAG_MASK;\n    if (version === 0) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_ZERO_MUST_BE_ENCODED_WITH_SIGNATURES_FIRST, {\n            firstByte,\n            transactionBytes,\n        });\n    }\n    if (version === 1) {\n        return 'messageFirst';\n    }\n    throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n        unsupportedVersion: version,\n    });\n}\n\n/**\n * Returns an encoder that you can use to encode a {@link Transaction} to a byte array in a wire\n * format appropriate for sending to the Solana network for execution.\n */\nexport function getTransactionEncoder(): VariableSizeEncoder<Transaction> {\n    return getPredicateEncoder(\n        (transaction: Transaction) => getEnvelopeShapeFromMessageBytes(transaction.messageBytes) === 'signaturesFirst',\n        getTransactionEncoderWithSignaturesFirst(),\n        getTransactionEncoderWithMessageFirst(),\n    );\n}\n\nfunction getTransactionEncoderWithSignaturesFirst(): VariableSizeEncoder<Transaction> {\n    return getStructEncoder([\n        ['signatures', getSignaturesEncoderWithSizePrefix()],\n        ['messageBytes', getBytesEncoder()],\n    ]);\n}\n\nfunction getSignatureCountForVersionedOrThrow(messageBytes: ReadonlyUint8Array, offset: number): number {\n    if (messageBytes.length < offset + 2) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__MALFORMED_MESSAGE_BYTES, {\n            messageBytes,\n        });\n    }\n    return messageBytes[offset + 1]; // second byte\n}\n\nfunction getTransactionEncoderWithMessageFirst(): VariableSizeEncoder<Transaction> {\n    const bytesEncoder = getBytesEncoder();\n\n    return createEncoder({\n        getSizeFromValue: (transaction: Transaction) => {\n            const signatureCount = getSignatureCountForVersionedOrThrow(transaction.messageBytes, 0);\n            return transaction.messageBytes.length + signatureCount * 64;\n        },\n        write: (transaction: Transaction, bytes: Uint8Array, offset: number) => {\n            // 1. Encode messageBytes first\n            offset = bytesEncoder.write(transaction.messageBytes, bytes, offset);\n\n            // 2. Extract signature count from second byte\n            const signatureCount = getSignatureCountForVersionedOrThrow(transaction.messageBytes, 0);\n\n            // 3. Encode signatures with the extracted length\n            const signaturesEncoder = getSignaturesEncoderWithLength(signatureCount);\n            offset = signaturesEncoder.write(transaction.signatures, bytes, offset);\n\n            return offset;\n        },\n    });\n}\n\n/**\n * Returns a decoder that you can use to convert a byte array in the Solana transaction wire format\n * to a {@link Transaction} object.\n *\n * @example\n * ```ts\n * import { getTransactionDecoder } from '@solana/transactions';\n *\n * const transactionDecoder = getTransactionDecoder();\n * const transaction = transactionDecoder.decode(wireTransactionBytes);\n * for (const [address, signature] in Object.entries(transaction.signatures)) {\n *     console.log(`Signature by ${address}`, signature);\n * }\n * ```\n */\n\nexport function getTransactionDecoder(): VariableSizeDecoder<Transaction> {\n    return getPredicateDecoder(\n        (transactionBytes: ReadonlyUint8Array) =>\n            getEnvelopeShapeFromTransactionBytes(transactionBytes) === 'signaturesFirst',\n        getTransactionDecoderWithSignaturesFirst(),\n        getTransactionDecoderWithMessageFirst(),\n    );\n}\n\nfunction getTransactionDecoderWithSignaturesFirst(): VariableSizeDecoder<Transaction> {\n    return transformDecoder(\n        getStructDecoder([\n            ['signatures', getArrayDecoder(fixDecoderSize(getBytesDecoder(), 64), { size: getShortU16Decoder() })],\n            ['messageBytes', getBytesDecoder()],\n        ]),\n        decodePartiallyDecodedLegacyOrV0Transaction,\n    );\n}\n\nfunction getTransactionDecoderWithMessageFirst(): VariableSizeDecoder<Transaction> {\n    return transformDecoder(\n        getPartiallyDecodedTransactionDecoderWithMessageFirst(),\n        decodePartiallyDecodedV1Transaction,\n    );\n}\n\nfunction getPartiallyDecodedTransactionDecoderWithMessageFirst(): VariableSizeDecoder<PartiallyDecodedTransaction> {\n    return createDecoder({\n        read(bytes, offset) {\n            // 1. Message comes first, so read signature count from message bytes\n            const signatureCount = getSignatureCountForVersionedOrThrow(bytes, offset);\n            const signatureByteLength = signatureCount * 64;\n\n            // 2. Read the message, which is all bytes except the last {signatureByteLength} bytes\n            // Note that this is based on an assumption that we want to read the rest of the input bytes\n            // as a transaction, which allows us to avoid decoding the entire message bytes to read each field\n            // This is the same logic as using `getBytesDecoder` to read the message bytes when they are trailing\n            const messageBytesLength = bytes.length - offset - signatureByteLength;\n            if (messageBytesLength < 0) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURE_COUNT_TOO_HIGH_FOR_TRANSACTION_BYTES, {\n                    numExpectedSignatures: signatureCount,\n                    transactionBytes: bytes.subarray(offset),\n                    transactionBytesLength: bytes.length - offset,\n                });\n            }\n            const messageBytes = bytes.subarray(offset, offset + messageBytesLength);\n\n            // 3. Read the signature bytes, which are the remaining bytes\n            const [signatures, finalOffset] = getArrayDecoder(fixDecoderSize(getBytesDecoder(), 64), {\n                size: signatureCount,\n            }).read(bytes, offset + messageBytesLength);\n\n            return [\n                {\n                    messageBytes: messageBytes as unknown as TransactionMessageBytes,\n                    signatures,\n                },\n                finalOffset,\n            ];\n        },\n    });\n}\n\n/**\n * Returns a codec that you can use to encode from or decode to a {@link Transaction}\n *\n * @see {@link getTransactionDecoder}\n * @see {@link getTransactionEncoder}\n */\nexport function getTransactionCodec(): VariableSizeCodec<Transaction> {\n    return combineCodec(getTransactionEncoder(), getTransactionDecoder());\n}\n\ntype PartiallyDecodedTransaction = {\n    messageBytes: ReadonlyUint8Array;\n    signatures: ReadonlyUint8Array[];\n};\n\nfunction decodePartiallyDecodedLegacyOrV0Transaction(transaction: PartiallyDecodedTransaction): Transaction {\n    const { messageBytes, signatures } = transaction;\n\n    /*\n    Relevant message structure is at the start:\n    - transaction version (0 bytes for legacy transactions, 1 byte for versioned transactions)\n    - `numRequiredSignatures` (1 byte, we verify this matches the length of signatures)\n    - `numReadOnlySignedAccounts` (1 byte, not used here)\n    - `numReadOnlyUnsignedAccounts` (1 byte, not used here)\n    - static addresses, with signers first. This is an array of addresses, prefixed with a short-u16 length\n    */\n\n    const signerAddressesDecoder = getTupleDecoder([\n        // read transaction version\n        getTransactionVersionDecoder(),\n        // read first byte of header, `numSignerAccounts`\n        // padRight to skip the next 2 bytes, `numReadOnlySignedAccounts` and `numReadOnlyUnsignedAccounts` which we don't need\n        padRightDecoder(getU8Decoder(), 2),\n        // read static addresses\n        getArrayDecoder(getAddressDecoder(), { size: getShortU16Decoder() }),\n    ]);\n    const [_txVersion, numRequiredSignatures, staticAddresses] = signerAddressesDecoder.decode(messageBytes);\n\n    const signerAddresses = staticAddresses.slice(0, numRequiredSignatures);\n\n    // signer addresses and signatures must be the same length\n    // we encode an all-zero signature when the signature is missing\n    if (signerAddresses.length !== signatures.length) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n            numRequiredSignatures,\n            signaturesLength: signatures.length,\n            signerAddresses,\n        });\n    }\n\n    // combine the signer addresses + signatures into the signatures map\n    const signaturesMap = makeSignaturesMap(signerAddresses, signatures);\n\n    return {\n        messageBytes: messageBytes as TransactionMessageBytes,\n        signatures: Object.freeze(signaturesMap),\n    };\n}\n\nfunction decodePartiallyDecodedV1Transaction(transaction: PartiallyDecodedTransaction): Transaction {\n    const { messageBytes, signatures } = transaction;\n\n    /*\n    Relevant message structure is at the start:\n    - transaction version (1 byte for versioned transactions)\n    - `numRequiredSignatures` (1 byte, we verify this matches the length of signatures)\n    - `numReadOnlySignedAccounts` (1 byte, not used here)\n    - `numReadOnlyUnsignedAccounts` (1 byte, not used here)\n    - transaction config mask (4 bytes, not used here)\n    - lifetime specifier (4 bytes, not used here)\n    - num instructions (1 byte, not used here)\n    - num addresses (1 byte, not used here because we only need to read `numRequiredSignatures` addresses)\n    - static addresses, with signers first. This is an array of addresses, with no prefix\n    */\n\n    const numRequiredSignatures = messageBytes[1]; // second byte\n\n    /**\n     * Static addresses start after:\n     * - 1 byte transaction version\n     * - 3 bytes for the header (`numRequiredSignatures`, `numReadOnlySignedAccounts`, and `numReadOnlyUnsignedAccounts`)\n     * - 4 bytes for transaction config mask\n     * - 32 bytes for lifetime specifier (a base58-encoded 32-byte blockhash or nonce)\n     * - 1 byte for num instructions\n     * - 1 byte for num addresses\n     */\n    const staticAddressOffset = 1 + 3 + 4 + 32 + 1 + 1;\n\n    const signerAddresses = getArrayDecoder(getAddressDecoder(), { size: numRequiredSignatures }).decode(\n        messageBytes,\n        staticAddressOffset,\n    );\n\n    if (signerAddresses.length !== signatures.length) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__MESSAGE_SIGNATURES_MISMATCH, {\n            numRequiredSignatures,\n            signaturesLength: signatures.length,\n            signerAddresses,\n        });\n    }\n\n    const signaturesMap = makeSignaturesMap(signerAddresses, signatures);\n\n    return {\n        messageBytes: messageBytes as TransactionMessageBytes,\n        signatures: signaturesMap,\n    };\n}\n\nfunction makeSignaturesMap(signerAddresses: Address[], signatures: ReadonlyUint8Array[]): SignaturesMap {\n    // combine the signer addresses + signatures into the signatures map\n    const signaturesMap: SignaturesMap = {};\n    signerAddresses.forEach((address, index) => {\n        const signatureForAddress = signatures[index];\n        if (signatureForAddress.every(b => b === 0)) {\n            signaturesMap[address] = null;\n        } else {\n            signaturesMap[address] = signatureForAddress as SignatureBytes;\n        }\n    });\n\n    return Object.freeze(signaturesMap);\n}\n"
  },
  {
    "path": "packages/transactions/src/compile-transaction.ts",
    "content": "import {\n    compileTransactionMessage,\n    getCompiledTransactionMessageEncoder,\n    isTransactionMessageWithBlockhashLifetime,\n    isTransactionMessageWithDurableNonceLifetime,\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n} from '@solana/transaction-messages';\n\nimport type { TransactionWithLifetime } from './lifetime';\nimport type { SignaturesMap, TransactionFromTransactionMessage, TransactionMessageBytes } from './transaction';\n\n/**\n * Returns a {@link Transaction} object for a given {@link TransactionMessage}.\n *\n * This includes the compiled bytes of the transaction message, and a map of signatures. This map\n * will have a key for each address that is required to sign the transaction. The transaction will\n * not yet have signatures for any of these addresses.\n *\n * Whether a transaction message is ready to be compiled or not is enforced for you at the type\n * level. In order to be signable, a transaction message must:\n *\n * - have a version and a list of zero or more instructions (ie. conform to\n *   {@link TransactionMessage})\n * - have a fee payer set (ie. conform to {@link TransactionMessageWithFeePayer})\n * - have a lifetime specified (ie. conform to {@link TransactionMessageWithBlockhashLifetime} or\n *   {@link TransactionMessageWithDurableNonceLifetime})\n */\nexport function compileTransaction<TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer>(\n    transactionMessage: TTransactionMessage,\n): Readonly<TransactionFromTransactionMessage<TTransactionMessage>> {\n    type ReturnType = Readonly<TransactionFromTransactionMessage<TTransactionMessage>>;\n\n    const compiledMessage = compileTransactionMessage(transactionMessage);\n    const messageBytes = getCompiledTransactionMessageEncoder().encode(compiledMessage) as TransactionMessageBytes;\n\n    const transactionSigners = compiledMessage.staticAccounts.slice(0, compiledMessage.header.numSignerAccounts);\n    const signatures: SignaturesMap = {};\n    for (const signerAddress of transactionSigners) {\n        signatures[signerAddress] = null;\n    }\n\n    let lifetimeConstraint: TransactionWithLifetime['lifetimeConstraint'] | undefined;\n    if (isTransactionMessageWithBlockhashLifetime(transactionMessage)) {\n        lifetimeConstraint = {\n            blockhash: transactionMessage.lifetimeConstraint.blockhash,\n            lastValidBlockHeight: transactionMessage.lifetimeConstraint.lastValidBlockHeight,\n        };\n    } else if (isTransactionMessageWithDurableNonceLifetime(transactionMessage)) {\n        lifetimeConstraint = {\n            nonce: transactionMessage.lifetimeConstraint.nonce,\n            nonceAccountAddress: transactionMessage.instructions[0].accounts[0].address,\n        };\n    }\n\n    return Object.freeze({\n        ...(lifetimeConstraint ? { lifetimeConstraint } : undefined),\n        messageBytes: messageBytes,\n        signatures: Object.freeze(signatures),\n    }) as ReturnType;\n}\n"
  },
  {
    "path": "packages/transactions/src/index.ts",
    "content": "/**\n * This package contains types and functions for compiling, signing and sending transactions.\n * It can be used standalone, but it is also exported as part of Kit\n * [`@solana/kit`](https://github.com/anza-xyz/kit/tree/main/packages/kit).\n *\n * Transactions are created by compiling a transaction message. They must then be signed before\n * being submitted to the network.\n *\n * @packageDocumentation\n */\nexport * from './codecs';\nexport * from './lifetime';\nexport * from './compile-transaction';\nexport * from './signatures';\nexport * from './wire-transaction';\nexport * from './sendable-transaction';\nexport * from './transaction-message-size';\nexport * from './transaction-size';\nexport * from './transaction';\n"
  },
  {
    "path": "packages/transactions/src/lifetime.ts",
    "content": "import { type Address, isAddress } from '@solana/addresses';\nimport { ReadonlyUint8Array } from '@solana/codecs-core';\nimport {\n    SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME,\n    SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME,\n    SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX,\n    SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE,\n    SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED,\n    SolanaError,\n} from '@solana/errors';\nimport { type Blockhash, isBlockhash, type Slot } from '@solana/rpc-types';\nimport type {\n    CompiledTransactionMessage,\n    CompiledTransactionMessageWithLifetime,\n    LegacyCompiledTransactionMessage,\n    Nonce,\n    TransactionMessage,\n    TransactionMessageWithBlockhashLifetime,\n    TransactionMessageWithDurableNonceLifetime,\n    V1CompiledTransactionMessage,\n} from '@solana/transaction-messages';\n\nimport type { Transaction } from './transaction';\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network. The transaction will continue to be eligible to land until the network considers the\n * `blockhash` to be expired.\n *\n * This can happen when the network proceeds past the `lastValidBlockHeight` for which the blockhash\n * is considered valid, or when the network switches to a fork where that blockhash is not present.\n */\nexport type TransactionBlockhashLifetime = {\n    /**\n     * A recent blockhash observed by the transaction proposer.\n     *\n     * The transaction will be considered eligible to land until the network determines this\n     * blockhash to be too old, or has switched to a fork where it is not present.\n     */\n    blockhash: Blockhash;\n    /**\n     * This is the block height beyond which the network will consider the blockhash to be too old\n     * to make a transaction eligible to land.\n     */\n    lastValidBlockHeight: Slot;\n};\n\n/**\n * A constraint which, when applied to a transaction, makes that transaction eligible to land on the\n * network.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionDurableNonceLifetime = {\n    /**\n     * A value contained in the account with address `nonceAccountAddress` at the time the\n     * transaction was prepared.\n     *\n     * The transaction will be considered eligible to land until the nonce account ceases to exist\n     * or contain this value.\n     */\n    nonce: Nonce;\n    /** The account that contains the `nonce` value */\n    nonceAccountAddress: Address;\n};\n\n/**\n * A transaction whose ability to land on the network is determined by some evanescent criteria.\n *\n * This describes a window of time after which a transaction is constructed and before which it will\n * no longer be accepted by the network.\n *\n * No transaction can land on Solana without having a `lifetimeConstraint` set.\n */\nexport type TransactionWithLifetime = {\n    readonly lifetimeConstraint: TransactionBlockhashLifetime | TransactionDurableNonceLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by the age of a blockhash observed on the network.\n *\n * The transaction will continue to be eligible to land until the network considers the `blockhash`\n * to be expired.\n */\nexport type TransactionWithBlockhashLifetime = {\n    readonly lifetimeConstraint: TransactionBlockhashLifetime;\n};\n\n/**\n * A transaction whose lifetime is determined by a nonce.\n *\n * The transaction will continue to be eligible to land until the network considers the `nonce` to\n * have advanced. This can happen when the nonce account in which this nonce is found is destroyed,\n * or the nonce value within changes.\n */\nexport type TransactionWithDurableNonceLifetime = {\n    readonly lifetimeConstraint: TransactionDurableNonceLifetime;\n};\n\n/**\n * Helper type that sets the lifetime constraint of a transaction to be the same as the\n * lifetime constraint of the provided transaction message.\n *\n * If the transaction message has no explicit lifetime constraint, neither will the transaction.\n */\nexport type SetTransactionLifetimeFromTransactionMessage<\n    TTransaction extends Transaction,\n    TTransactionMessage extends TransactionMessage,\n> = TTransactionMessage extends { lifetimeConstraint: unknown }\n    ? TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithBlockhashLifetime['lifetimeConstraint']\n        ? TransactionWithBlockhashLifetime & TTransaction\n        : TTransactionMessage['lifetimeConstraint'] extends TransactionMessageWithDurableNonceLifetime['lifetimeConstraint']\n          ? TransactionWithDurableNonceLifetime & TTransaction\n          : TransactionWithLifetime & TTransaction\n    : TTransaction;\n\nconst SYSTEM_PROGRAM_ADDRESS = '11111111111111111111111111111111' as Address;\n\nfunction compiledV1InstructionIsAdvanceNonceInstruction(\n    instructionHeader: V1CompiledTransactionMessage['instructionHeaders'][number],\n    instructionPayload: V1CompiledTransactionMessage['instructionPayloads'][number],\n    staticAddresses: Address[],\n): instructionHeader is typeof instructionHeader & { programAccountIndex: number } {\n    return (\n        staticAddresses[instructionHeader.programAccountIndex] === SYSTEM_PROGRAM_ADDRESS &&\n        // Test for `AdvanceNonceAccount` instruction data\n        isAdvanceNonceAccountInstructionData(instructionPayload.instructionData) &&\n        // Test for exactly 3 accounts\n        instructionHeader.numInstructionAccounts === 3\n    );\n}\n\nfunction compiledLegacyInstructionIsAdvanceNonceInstruction(\n    instruction: LegacyCompiledTransactionMessage['instructions'][number],\n    staticAddresses: Address[],\n): instruction is typeof instruction & { accountIndices: [number, number, number] } {\n    return (\n        staticAddresses[instruction.programAddressIndex] === SYSTEM_PROGRAM_ADDRESS &&\n        // Test for `AdvanceNonceAccount` instruction data\n        instruction.data != null &&\n        isAdvanceNonceAccountInstructionData(instruction.data) &&\n        // Test for exactly 3 accounts\n        instruction.accountIndices?.length === 3\n    );\n}\n\nfunction isAdvanceNonceAccountInstructionData(data: ReadonlyUint8Array): boolean {\n    // AdvanceNonceAccount is the fifth instruction in the System Program (index 4)\n    return data.byteLength === 4 && data[0] === 4 && data[1] === 0 && data[2] === 0 && data[3] === 0;\n}\n\n/**\n * Get the lifetime constraint for a transaction from a compiled transaction message that includes a lifetime token.\n * @param compiledTransactionMessage A compiled transaction message that includes a lifetime token\n * @returns A lifetime constraint for the transaction\n * Note that this is less precise than checking a decompiled instruction, as we can't inspect\n * the address or role of input accounts (which may be in lookup tables). However, this is\n * sufficient for all valid advance durable nonce instructions.\n * Note that the program address must not be in a lookup table, see [this answer on StackExchange](https://solana.stackexchange.com/a/16224/289)\n * @see {@link isAdvanceNonceAccountInstruction}\n * Note that this function is async to allow for future implementations that may fetch `lastValidBlockHeight` using an RPC\n */\n// eslint-disable-next-line @typescript-eslint/require-await\nexport async function getTransactionLifetimeConstraintFromCompiledTransactionMessage(\n    compiledTransactionMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime,\n): Promise<TransactionBlockhashLifetime | TransactionDurableNonceLifetime> {\n    // We need to check if the first instruction is an AdvanceNonceAccount instruction\n    const { version } = compiledTransactionMessage;\n\n    if (version === 'legacy' || version === 0) {\n        const firstInstruction = compiledTransactionMessage.instructions[0];\n        const { staticAccounts } = compiledTransactionMessage;\n\n        if (firstInstruction && compiledLegacyInstructionIsAdvanceNonceInstruction(firstInstruction, staticAccounts)) {\n            const nonceAccountAddress = staticAccounts[firstInstruction.accountIndices[0]];\n            if (!nonceAccountAddress) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n                    nonce: compiledTransactionMessage.lifetimeToken,\n                });\n            }\n            return {\n                nonce: compiledTransactionMessage.lifetimeToken as Nonce,\n                nonceAccountAddress,\n            };\n        } else {\n            return {\n                blockhash: compiledTransactionMessage.lifetimeToken as Blockhash,\n                // This is not known from the compiled message, so we set it to the maximum possible value\n                lastValidBlockHeight: 0xffffffffffffffffn,\n            };\n        }\n    }\n\n    if (version === 1) {\n        const firstInstructionHeader = compiledTransactionMessage.instructionHeaders[0];\n        const firstInstructionPayload = compiledTransactionMessage.instructionPayloads[0];\n        const { staticAccounts } = compiledTransactionMessage;\n\n        if (\n            firstInstructionHeader &&\n            firstInstructionPayload &&\n            compiledV1InstructionIsAdvanceNonceInstruction(\n                firstInstructionHeader,\n                firstInstructionPayload,\n                staticAccounts,\n            )\n        ) {\n            const nonceAccountAddress = staticAccounts[firstInstructionPayload.instructionAccountIndices[0]];\n            if (!nonceAccountAddress) {\n                throw new SolanaError(SOLANA_ERROR__TRANSACTION__INVALID_NONCE_ACCOUNT_INDEX, {\n                    nonce: compiledTransactionMessage.lifetimeToken,\n                    nonceAccountIndex: firstInstructionPayload.instructionAccountIndices[0],\n                    numberOfStaticAccounts: staticAccounts.length,\n                });\n            }\n            return {\n                nonce: compiledTransactionMessage.lifetimeToken as Nonce,\n                nonceAccountAddress,\n            };\n        } else {\n            return {\n                blockhash: compiledTransactionMessage.lifetimeToken as Blockhash,\n                // This is not known from the compiled message, so we set it to the maximum possible value\n                lastValidBlockHeight: 0xffffffffffffffffn,\n            };\n        }\n    }\n\n    throw new SolanaError(SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED, {\n        unsupportedVersion: version,\n    });\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithBlockhashLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * if (isTransactionWithBlockhashLifetime(transaction)) {\n *     // At this point, `transaction` has been refined to a `TransactionWithBlockhashLifetime`.\n *     const { blockhash } = transaction.lifetimeConstraint;\n *     const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n *     setBlockhashIsValid(blockhashIsValid);\n * } else {\n *     setError(\n *         `${getSignatureFromTransaction(transaction)} does not have a blockhash-based lifetime`,\n *     );\n * }\n * ```\n */\nexport function isTransactionWithBlockhashLifetime(\n    transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithBlockhashLifetime {\n    return (\n        'lifetimeConstraint' in transaction &&\n        'blockhash' in transaction.lifetimeConstraint &&\n        typeof transaction.lifetimeConstraint.blockhash === 'string' &&\n        typeof transaction.lifetimeConstraint.lastValidBlockHeight === 'bigint' &&\n        isBlockhash(transaction.lifetimeConstraint.blockhash)\n    );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * blockhash-based lifetime, from for example a wallet. Use this function to\n * assert that such a transaction actually has a blockhash-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithBlockhashLifetime } from '@solana/transactions';\n *\n * try {\n *     // If this type assertion function doesn't throw, then\n *     // Typescript will upcast `transaction` to `TransactionWithBlockhashLifetime`.\n *     assertIsTransactionWithBlockhashLifetime(transaction);\n *     // At this point, `transaction` is a `TransactionWithBlockhashLifetime` that can be used\n *     // with the RPC.\n *     const { blockhash } = transaction.lifetimeConstraint;\n *     const { value: blockhashIsValid } = await rpc.isBlockhashValid(blockhash).send();\n * } catch (e) {\n *     // `transaction` turned out not to have a blockhash-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithBlockhashLifetime(\n    transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithBlockhashLifetime {\n    if (!isTransactionWithBlockhashLifetime(transaction)) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_BLOCKHASH_LIFETIME);\n    }\n}\n\n/**\n * A type guard that returns `true` if the transaction conforms to the\n * {@link TransactionWithDurableNonceLifetime} type, and refines its type for use in your\n * program.\n *\n * @example\n * ```ts\n * import { isTransactionWithDurableNonceLifetime } from '@solana/transactions';\n * import { fetchNonce } from \"@solana-program/system\";\n *\n * if (isTransactionWithDurableNonceLifetime(transaction)) {\n *     // At this point, `transaction` has been refined to a\n *     // `TransactionWithDurableNonceLifetime`.\n *     const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n *     const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n *     setNonceIsValid(nonce === actualNonce);\n * } else {\n *     setError(\n *         `${getSignatureFromTransaction(transaction)} does not have a nonce-based lifetime`,\n *     );\n * }\n * ```\n */\nexport function isTransactionWithDurableNonceLifetime(\n    transaction: Transaction | (Transaction & TransactionWithLifetime),\n): transaction is Transaction & TransactionWithDurableNonceLifetime {\n    return (\n        'lifetimeConstraint' in transaction &&\n        'nonce' in transaction.lifetimeConstraint &&\n        typeof transaction.lifetimeConstraint.nonce === 'string' &&\n        typeof transaction.lifetimeConstraint.nonceAccountAddress === 'string' &&\n        isAddress(transaction.lifetimeConstraint.nonceAccountAddress)\n    );\n}\n\n/**\n * From time to time you might acquire a transaction, that you expect to have a\n * nonce-based lifetime, from for example a wallet. Use this function to assert\n * that such a transaction actually has a nonce-based lifetime.\n *\n * @example\n * ```ts\n * import { assertIsTransactionWithDurableNonceLifetime } from '@solana/transactions';\n *\n * try {\n *     // If this type assertion function doesn't throw, then\n *     // Typescript will upcast `transaction` to `TransactionWithDurableNonceLifetime`.\n *     assertIsTransactionWithDurableNonceLifetime(transaction);\n *     // At this point, `transaction` is a `TransactionWithDurableNonceLifetime` that can be used\n *     // with the RPC.\n *     const { nonce, nonceAccountAddress } = transaction.lifetimeConstraint;\n *     const { data: { blockhash: actualNonce } } = await fetchNonce(nonceAccountAddress);\n * } catch (e) {\n *     // `transaction` turned out not to have a nonce-based lifetime\n * }\n * ```\n */\nexport function assertIsTransactionWithDurableNonceLifetime(\n    transaction: Transaction | (Transaction & TransactionWithLifetime),\n): asserts transaction is Transaction & TransactionWithDurableNonceLifetime {\n    if (!isTransactionWithDurableNonceLifetime(transaction)) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXPECTED_NONCE_LIFETIME);\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/sendable-transaction.ts",
    "content": "import { assertIsFullySignedTransaction, FullySignedTransaction, isFullySignedTransaction } from './signatures';\nimport { Transaction } from './transaction';\nimport {\n    assertIsTransactionWithinSizeLimit,\n    isTransactionWithinSizeLimit,\n    TransactionWithinSizeLimit,\n} from './transaction-size';\n\n/**\n * Helper type that includes all transaction types required\n * for the transaction to be sent to the network.\n *\n * @see {@link isSendableTransaction}\n * @see {@link assertIsSendableTransaction}\n */\nexport type SendableTransaction = FullySignedTransaction & TransactionWithinSizeLimit;\n\n/**\n * Checks if a transaction has all the required\n * conditions to be sent to the network.\n *\n * @example\n * ```ts\n * import { isSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isSendableTransaction(transaction)) {\n *   // At this point we know that the transaction can be sent to the network.\n * }\n * ```\n *\n * @see {@link assertIsSendableTransaction}\n */\nexport function isSendableTransaction<TTransaction extends Transaction>(\n    transaction: TTransaction,\n): transaction is SendableTransaction & TTransaction {\n    return isFullySignedTransaction(transaction) && isTransactionWithinSizeLimit(transaction);\n}\n\n/**\n * Asserts that a given transaction has all the\n * required conditions to be sent to the network.\n *\n * From time to time you might acquire a {@link Transaction}\n * from an untrusted network API or user input and you are not sure\n * that it has all the required conditions to be sent to the network\n * — such as being fully signed and within the size limit.\n * This function can be used to assert that such a transaction\n * is in fact sendable.\n *\n * @example\n * ```ts\n * import { assertIsSendableTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n *     // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n *     // to `SendableTransaction`.\n *     assertIsSendableTransaction(transaction);\n *     // At this point we know that the transaction can be sent to the network.\n *     await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n *     if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n *         setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n *     } else if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT)) {\n *         setError(`Transaction exceeds size limit of ${e.context.transactionSizeLimit} bytes`);\n *     }\n *     throw;\n * }\n * ```\n */\nexport function assertIsSendableTransaction<TTransaction extends Transaction>(\n    transaction: TTransaction,\n): asserts transaction is SendableTransaction & TTransaction {\n    assertIsFullySignedTransaction(transaction);\n    assertIsTransactionWithinSizeLimit(transaction);\n}\n"
  },
  {
    "path": "packages/transactions/src/signatures.ts",
    "content": "import { Address, getAddressFromPublicKey } from '@solana/addresses';\nimport { bytesEqual, Decoder } from '@solana/codecs-core';\nimport { getBase58Decoder } from '@solana/codecs-strings';\nimport {\n    SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION,\n    SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING,\n    SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING,\n    SolanaError,\n} from '@solana/errors';\nimport { Signature, SignatureBytes, signBytes } from '@solana/keys';\nimport { NominalType } from '@solana/nominal-types';\n\nimport { Transaction } from './transaction';\n\n/**\n * Represents a transaction that is signed by all of its required signers. Being fully signed is a\n * prerequisite of functions designed to land transactions on the network.\n */\nexport type FullySignedTransaction = NominalType<'transactionSignedness', 'fullySigned'>;\n\nlet base58Decoder: Decoder<string> | undefined;\n\n/**\n * Given a transaction signed by its fee payer, this method will return the {@link Signature} that\n * uniquely identifies it. This string can be used to look up transactions at a later date, for\n * example on a Solana block explorer.\n *\n * @example\n * ```ts\n * import { getSignatureFromTransaction } from '@solana/transactions';\n *\n * const signature = getSignatureFromTransaction(tx);\n * console.debug(`Inspect this transaction at https://explorer.solana.com/tx/${signature}`);\n * ```\n */\nexport function getSignatureFromTransaction(transaction: Transaction): Signature {\n    if (!base58Decoder) base58Decoder = getBase58Decoder();\n\n    // We have ordered signatures from the compiled message accounts\n    // first signature is the fee payer\n    const signatureBytes = Object.values(transaction.signatures)[0];\n    if (!signatureBytes) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__FEE_PAYER_SIGNATURE_MISSING);\n    }\n    const transactionSignature = base58Decoder.decode(signatureBytes);\n    return transactionSignature as Signature;\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link Transaction}.\n *\n * Though the resulting transaction might have every signature it needs to land on the network, this\n * function will not assert that it does. A partially signed transaction cannot be landed on the\n * network, but can be serialized and deserialized.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { partiallySignTransaction } from '@solana/transactions';\n *\n * const partiallySignedTransaction = await partiallySignTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link signTransaction} if you want to assert that the transaction has all of its required\n * signatures after signing.\n */\nexport async function partiallySignTransaction<TTransaction extends Transaction>(\n    keyPairs: CryptoKeyPair[],\n    transaction: TTransaction,\n): Promise<TTransaction> {\n    let newSignatures: Record<Address, SignatureBytes> | undefined;\n    let unexpectedSigners: Set<Address> | undefined;\n\n    await Promise.all(\n        keyPairs.map(async keyPair => {\n            const address = await getAddressFromPublicKey(keyPair.publicKey);\n            const existingSignature = transaction.signatures[address];\n\n            // Check if the address is expected to sign the transaction\n            if (existingSignature === undefined) {\n                // address is not an expected signer for this transaction\n                unexpectedSigners ||= new Set();\n                unexpectedSigners.add(address);\n                return;\n            }\n\n            // Return if there are any unexpected signers already since we won't be using signatures\n            if (unexpectedSigners) {\n                return;\n            }\n\n            const newSignature = await signBytes(keyPair.privateKey, transaction.messageBytes);\n\n            if (existingSignature !== null && bytesEqual(newSignature, existingSignature)) {\n                // already have the same signature set\n                return;\n            }\n\n            newSignatures ||= {};\n            newSignatures[address] = newSignature;\n        }),\n    );\n\n    if (unexpectedSigners && unexpectedSigners.size > 0) {\n        const expectedSigners = Object.keys(transaction.signatures);\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__ADDRESSES_CANNOT_SIGN_TRANSACTION, {\n            expectedAddresses: expectedSigners,\n            unexpectedAddresses: [...unexpectedSigners],\n        });\n    }\n\n    if (!newSignatures) {\n        return transaction;\n    }\n\n    return Object.freeze({\n        ...transaction,\n        signatures: Object.freeze({\n            ...transaction.signatures,\n            ...newSignatures,\n        }),\n    });\n}\n\n/**\n * Given an array of `CryptoKey` objects which are private keys pertaining to addresses that are\n * required to sign a transaction, this method will return a new signed transaction of type\n * {@link FullySignedTransaction}.\n *\n * This function will throw unless the resulting transaction is fully signed.\n *\n * @example\n * ```ts\n * import { generateKeyPair } from '@solana/keys';\n * import { signTransaction } from '@solana/transactions';\n *\n * const signedTransaction = await signTransaction([myPrivateKey], tx);\n * ```\n *\n * @see {@link partiallySignTransaction} if you want to sign the transaction without asserting that\n * the resulting transaction is fully signed.\n */\nexport async function signTransaction<TTransaction extends Transaction>(\n    keyPairs: CryptoKeyPair[],\n    transaction: TTransaction,\n): Promise<FullySignedTransaction & TTransaction> {\n    const out = await partiallySignTransaction(keyPairs, transaction);\n    assertIsFullySignedTransaction(out);\n    Object.freeze(out);\n    return out;\n}\n\n/**\n * Checks whether a given {@link Transaction} is fully signed.\n *\n * @example\n * ```ts\n * import { isFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * if (isFullySignedTransaction(transaction)) {\n *   // At this point we know that the transaction is signed and can be sent to the network.\n * }\n * ```\n */\nexport function isFullySignedTransaction<TTransaction extends Transaction>(\n    transaction: TTransaction,\n): transaction is FullySignedTransaction & TTransaction {\n    return Object.entries(transaction.signatures).every(([_, signatureBytes]) => !!signatureBytes);\n}\n\n/**\n * From time to time you might acquire a {@link Transaction}, that you expect to be fully signed,\n * from an untrusted network API or user input. Use this function to assert that such a transaction\n * is fully signed.\n *\n * @example\n * ```ts\n * import { assertIsFullySignedTransaction } from '@solana/transactions';\n *\n * const transaction = getTransactionDecoder().decode(transactionBytes);\n * try {\n *     // If this type assertion function doesn't throw, then Typescript will upcast `transaction`\n *     // to `FullySignedTransaction`.\n *     assertIsFullySignedTransaction(transaction);\n *     // At this point we know that the transaction is signed and can be sent to the network.\n *     await sendAndConfirmTransaction(transaction, { commitment: 'confirmed' });\n * } catch(e) {\n *     if (isSolanaError(e, SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING)) {\n *         setError(`Missing signatures for ${e.context.addresses.join(', ')}`);\n *     }\n *     throw;\n * }\n * ```\n */\nexport function assertIsFullySignedTransaction<TTransaction extends Transaction>(\n    transaction: TTransaction,\n): asserts transaction is FullySignedTransaction & TTransaction {\n    const missingSigs: Address[] = [];\n    Object.entries(transaction.signatures).forEach(([address, signatureBytes]) => {\n        if (!signatureBytes) {\n            missingSigs.push(address as Address);\n        }\n    });\n\n    if (missingSigs.length > 0) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__SIGNATURES_MISSING, {\n            addresses: missingSigs,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/transaction-message-size.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type {\n    TransactionMessage,\n    TransactionMessageWithFeePayer,\n    TransactionMessageWithinSizeLimit,\n} from '@solana/transaction-messages';\n\nimport { compileTransaction } from './compile-transaction';\nimport { getTransactionSize } from './transaction-size';\nimport { LEGACY_TRANSACTION_SIZE_LIMIT, V1_TRANSACTION_SIZE_LIMIT } from './transaction-size-limits';\n\n/**\n * Gets the compiled transaction size of a given transaction message in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionMessageSize(transactionMessage);\n * ```\n */\nexport function getTransactionMessageSize(\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer,\n): number {\n    return getTransactionSize(compileTransaction(transactionMessage));\n}\n\n/**\n * Returns the maximum allowed compiled size in bytes for a given transaction message.\n *\n * This depends on the version of the transaction message.\n *\n * @example\n * ```ts\n * const sizeLimit = getTransactionMessageSizeLimit(transactionMessage);\n * ```\n */\nexport function getTransactionMessageSizeLimit(\n    transactionMessage: TransactionMessage & TransactionMessageWithFeePayer,\n): number {\n    return transactionMessage.version === 1 ? V1_TRANSACTION_SIZE_LIMIT : LEGACY_TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Checks if a transaction message is within the size limit\n * when compiled into a transaction.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * if (isTransactionMessageWithinSizeLimit(transactionMessage)) {\n *    transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionMessageWithinSizeLimit<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer,\n>(\n    transactionMessage: TTransactionMessage,\n): transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n    return getTransactionMessageSize(transactionMessage) <= getTransactionMessageSizeLimit(transactionMessage);\n}\n\n/**\n * Asserts that a given transaction message is within the size limit\n * when compiled into a transaction.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction message exceeds the size limit.\n *\n * @typeParam TTransactionMessage - The type of the given transaction message.\n *\n * @example\n * ```ts\n * assertIsTransactionMessageWithinSizeLimit(transactionMessage);\n * transactionMessage satisfies TransactionMessageWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionMessageWithinSizeLimit<\n    TTransactionMessage extends TransactionMessage & TransactionMessageWithFeePayer,\n>(\n    transactionMessage: TTransactionMessage,\n): asserts transactionMessage is TransactionMessageWithinSizeLimit & TTransactionMessage {\n    const transactionSize = getTransactionMessageSize(transactionMessage);\n    const transactionSizeLimit = getTransactionMessageSizeLimit(transactionMessage);\n    if (transactionSize > transactionSizeLimit) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n            transactionSize,\n            transactionSizeLimit,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/transaction-size-limits.ts",
    "content": "/**\n * This file defines the size limits for transactions\n * It is used by both transaction-size and transaction-message-size\n * But intentionally not exported from the package\n */\n\n/**\n * The maximum size of a legacy (and v0) transaction in bytes.\n */\nexport const LEGACY_TRANSACTION_SIZE_LIMIT = 1232;\n\n/**\n * The maximum size of a version 1 transaction in bytes.\n */\nexport const V1_TRANSACTION_SIZE_LIMIT = 4096;\n"
  },
  {
    "path": "packages/transactions/src/transaction-size.ts",
    "content": "import { SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, SolanaError } from '@solana/errors';\nimport type { NominalType } from '@solana/nominal-types';\nimport type { TransactionMessage, TransactionMessageWithinSizeLimit } from '@solana/transaction-messages';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\nimport { LEGACY_TRANSACTION_SIZE_LIMIT, V1_TRANSACTION_SIZE_LIMIT } from './transaction-size-limits';\n\n/**\n * The maximum size of a transaction packet in bytes.\n *\n * @deprecated Transaction size is no longer constant as v1 transactions have a larger size limit. Use `getTransactionSizeLimit` instead to get the size limit for a specific transaction based on its version.\n */\nexport const TRANSACTION_PACKET_SIZE = 1280;\n\n/**\n * The size of the transaction packet header in bytes.\n * This includes the IPv6 header and the fragment header.\n *\n * @deprecated Transaction size is no longer constant as v1 transactions have a larger size limit. Use `getTransactionSizeLimit` instead to get the size limit for a specific transaction based on its version.\n */\nexport const TRANSACTION_PACKET_HEADER =\n    40 /* 40 bytes is the size of the IPv6 header. */ + 8; /* 8 bytes is the size of the fragment header. */\n\n/**\n * The maximum size of a transaction in bytes.\n *\n * Note that this excludes the transaction packet header.\n * In other words, this is how much content we can fit in a transaction packet.\n *\n * @deprecated Transaction size is no longer constant as v1 transactions have a larger size limit. Use `getTransactionSizeLimit` instead to get the size limit for a specific transaction based on its version.\n */\nexport const TRANSACTION_SIZE_LIMIT = TRANSACTION_PACKET_SIZE - TRANSACTION_PACKET_HEADER;\n\n/**\n * Gets the size of a given transaction in bytes.\n *\n * @example\n * ```ts\n * const transactionSize = getTransactionSize(transaction);\n * ```\n */\nexport function getTransactionSize(transaction: Transaction): number {\n    return getTransactionEncoder().getSizeFromValue(transaction);\n}\n\n/**\n * A type guard that checks if a transaction is within the size limit.\n */\nexport type TransactionWithinSizeLimit = NominalType<'transactionSize', 'withinLimit'>;\n\n/**\n * Helper type that adds the `TransactionWithinSizeLimit` flag to\n * a transaction if and only if the provided transaction message\n * is also within the size limit.\n */\nexport type SetTransactionWithinSizeLimitFromTransactionMessage<\n    TTransaction extends Transaction,\n    TTransactionMessage extends TransactionMessage,\n> = TTransactionMessage extends TransactionMessageWithinSizeLimit\n    ? TransactionWithinSizeLimit & TTransaction\n    : TTransaction;\n\n/**\n * Returns the maximum size in bytes allowed for the given transaction.\n *\n * The size limit depends on the transaction version: version 1 transactions\n * allow up to {@link V1_TRANSACTION_SIZE_LIMIT} bytes, while legacy and v0\n * transactions are capped at {@link LEGACY_TRANSACTION_SIZE_LIMIT} bytes.\n *\n * @param transaction - The transaction whose size limit to retrieve.\n * @return The maximum number of bytes the transaction may occupy.\n *\n * @example\n * ```ts\n * const sizeLimit = getTransactionSizeLimit(transaction);\n * ```\n *\n * @see {@link isTransactionWithinSizeLimit}\n * @see {@link assertIsTransactionWithinSizeLimit}\n */\nexport function getTransactionSizeLimit(transaction: Transaction): number {\n    const VERSION_FLAG_MASK = 0b01111111;\n    const firstByte = transaction.messageBytes[0];\n    return (firstByte & VERSION_FLAG_MASK) === 1 ? V1_TRANSACTION_SIZE_LIMIT : LEGACY_TRANSACTION_SIZE_LIMIT;\n}\n\n/**\n * Checks if a transaction is within the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * if (isTransactionWithinSizeLimit(transaction)) {\n *    transaction satisfies TransactionWithinSizeLimit;\n * }\n * ```\n */\nexport function isTransactionWithinSizeLimit<TTransaction extends Transaction>(\n    transaction: TTransaction,\n): transaction is TransactionWithinSizeLimit & TTransaction {\n    if (transaction.messageBytes.length === 0) {\n        // If there are no message bytes, then the transaction is empty and thus within the size limit.\n        return true;\n    }\n\n    const sizeLimit = getTransactionSizeLimit(transaction);\n    return getTransactionSize(transaction) <= sizeLimit;\n}\n\n/**\n * Asserts that a given transaction is within the size limit.\n *\n * Throws a {@link SolanaError} of code {@link SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT}\n * if the transaction exceeds the size limit.\n *\n * @typeParam TTransaction - The type of the given transaction.\n *\n * @example\n * ```ts\n * assertIsTransactionWithinSizeLimit(transaction);\n * transaction satisfies TransactionWithinSizeLimit;\n * ```\n */\nexport function assertIsTransactionWithinSizeLimit<TTransaction extends Transaction>(\n    transaction: TTransaction,\n): asserts transaction is TransactionWithinSizeLimit & TTransaction {\n    if (transaction.messageBytes.length === 0) {\n        // If there are no message bytes, then the transaction is empty and thus within the size limit.\n        return;\n    }\n\n    const sizeLimit = getTransactionSizeLimit(transaction);\n    const transactionSize = getTransactionSize(transaction);\n\n    if (transactionSize > sizeLimit) {\n        throw new SolanaError(SOLANA_ERROR__TRANSACTION__EXCEEDS_SIZE_LIMIT, {\n            transactionSize,\n            transactionSizeLimit: sizeLimit,\n        });\n    }\n}\n"
  },
  {
    "path": "packages/transactions/src/transaction.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport type { ReadonlyUint8Array } from '@solana/codecs-core';\nimport type { SignatureBytes } from '@solana/keys';\nimport type { Brand, EncodedString } from '@solana/nominal-types';\nimport type { TransactionMessage } from '@solana/transaction-messages';\n\nimport type { SetTransactionLifetimeFromTransactionMessage } from './lifetime';\nimport type { SetTransactionWithinSizeLimitFromTransactionMessage } from './transaction-size';\n\nexport type TransactionMessageBytes = Brand<ReadonlyUint8Array, 'TransactionMessageBytes'>;\nexport type TransactionMessageBytesBase64 = Brand<EncodedString<string, 'base64'>, 'TransactionMessageBytesBase64'>;\n\ntype OrderedMap<K extends string, V> = Record<K, V>;\nexport type SignaturesMap = OrderedMap<Address, SignatureBytes | null>;\n\nexport type Transaction = Readonly<{\n    /** The bytes of a compiled transaction message, encoded in wire format */\n    messageBytes: TransactionMessageBytes;\n    /**\n     * A map between the addresses of a transaction message's signers, and the 64-byte Ed25519\n     * signature of the transaction's `messageBytes` by the private key associated with each.\n     */\n    signatures: SignaturesMap;\n}>;\n\n/**\n * Helper type that creates a `Transaction` type as narrow as possible\n * from the provided `TransactionMessage` type.\n */\nexport type TransactionFromTransactionMessage<TTransactionMessage extends TransactionMessage> =\n    SetTransactionWithinSizeLimitFromTransactionMessage<\n        SetTransactionLifetimeFromTransactionMessage<Transaction, TTransactionMessage>,\n        TTransactionMessage\n    >;\n"
  },
  {
    "path": "packages/transactions/src/wire-transaction.ts",
    "content": "import { getBase64Decoder } from '@solana/codecs-strings';\nimport { Brand, EncodedString } from '@solana/nominal-types';\n\nimport { getTransactionEncoder } from './codecs';\nimport { Transaction } from './transaction';\n\n/** Represents the wire format of a transaction as a base64-encoded string. */\nexport type Base64EncodedWireTransaction = Brand<EncodedString<string, 'base64'>, 'Base64EncodedWireTransaction'>;\n\n/**\n * Given a signed transaction, this method returns the transaction as a string that conforms to the\n * {@link Base64EncodedWireTransaction} type.\n *\n * @example\n * ```ts\n * import { getBase64EncodedWireTransaction, signTransaction } from '@solana/transactions';\n *\n * const serializedTransaction = getBase64EncodedWireTransaction(signedTransaction);\n * const signature = await rpc.sendTransaction(serializedTransaction, { encoding: 'base64' }).send();\n * ```\n */\nexport function getBase64EncodedWireTransaction(transaction: Transaction): Base64EncodedWireTransaction {\n    const wireTransactionBytes = getTransactionEncoder().encode(transaction);\n    return getBase64Decoder().decode(wireTransactionBytes) as Base64EncodedWireTransaction;\n}\n"
  },
  {
    "path": "packages/transactions/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/transactions/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2017\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/transactions\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/transactions/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/tsconfig/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/tsconfig/README.md",
    "content": "# `tsconfig`\n\nThese are base shared `tsconfig.json`s from which all other `tsconfig.json`'s inherit from.\n"
  },
  {
    "path": "packages/tsconfig/base.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"display\": \"Default\",\n    \"compilerOptions\": {\n        \"composite\": false,\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"esModuleInterop\": true,\n        \"forceConsistentCasingInFileNames\": true,\n        \"inlineSources\": false,\n        \"isolatedModules\": true,\n        \"moduleResolution\": \"node\",\n        \"noFallthroughCasesInSwitch\": true,\n        \"noUnusedLocals\": true,\n        \"noUnusedParameters\": true,\n        \"preserveWatchOutput\": true,\n        \"skipLibCheck\": true,\n        \"strict\": true,\n        \"target\": \"ESNext\",\n        \"useDefineForClassFields\": true\n    },\n    \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "packages/tsconfig/package.json",
    "content": "{\n    \"name\": \"@solana/tsconfig\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"files\": [\n        \"base.json\"\n    ],\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/.gitignore",
    "content": ".docs/\ndist/"
  },
  {
    "path": "packages/wallet-account-signer/.npmrc",
    "content": "engine-strict=true"
  },
  {
    "path": "packages/wallet-account-signer/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/"
  },
  {
    "path": "packages/wallet-account-signer/CHANGELOG.md",
    "content": "# @solana/wallet-account-signer\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n### Patch Changes\n\n- [#1548](https://github.com/anza-xyz/kit/pull/1548) [`f9bf4ef`](https://github.com/anza-xyz/kit/commit/f9bf4ef8cfaeff5be0d792c0d7245904cb838361) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Widen the `chain` parameter on `createSignerFromWalletAccount`, `createTransactionSignerFromWalletAccount`, and `createTransactionSendingSignerFromWalletAccount` from `SolanaChain` to `SolanaChain | (IdentifierString & {})`. The known Solana chain identifiers continue to autocomplete, but any Wallet Standard `${namespace}:${reference}` value is now also accepted, matching the underlying `solana:signTransaction` and `solana:signAndSendTransaction` feature inputs.\n\n- Updated dependencies [[`8d73de5`](https://github.com/anza-xyz/kit/commit/8d73de5241d709946431f2fdda74f2a0df5e9529), [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7)]:\n    - @solana/promises@6.9.0\n    - @solana/addresses@6.9.0\n    - @solana/codecs-core@6.9.0\n    - @solana/keys@6.9.0\n    - @solana/signers@6.9.0\n    - @solana/transaction-messages@6.9.0\n    - @solana/transactions@6.9.0\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n- Updated dependencies [[`d79f8d1`](https://github.com/anza-xyz/kit/commit/d79f8d115065557194db9604f3a0bfef7d37a2b6), [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b), [`fdfcb6c`](https://github.com/anza-xyz/kit/commit/fdfcb6cbf439eb55e07ad7d59372347bd816d6d3), [`43bc570`](https://github.com/anza-xyz/kit/commit/43bc570a5b51a9fda75abc1f0f818728ca3cd439)]:\n    - @solana/signers@6.8.0\n    - @solana/keys@6.8.0\n    - @solana/addresses@6.8.0\n    - @solana/codecs-core@6.8.0\n    - @solana/promises@6.8.0\n    - @solana/transaction-messages@6.8.0\n    - @solana/transactions@6.8.0\n\n## 6.7.0\n\n### Patch Changes\n\n- Updated dependencies []:\n    - @solana/addresses@6.7.0\n    - @solana/codecs-core@6.7.0\n    - @solana/keys@6.7.0\n    - @solana/promises@6.7.0\n    - @solana/signers@6.7.0\n    - @solana/transaction-messages@6.7.0\n    - @solana/transactions@6.7.0\n\n## 6.6.0\n\n### Patch Changes\n\n- Updated dependencies [[`742ffca`](https://github.com/anza-xyz/kit/commit/742ffcaf5304f702334e1f0b2a14cf208ae0ee5f), [`7f02d23`](https://github.com/anza-xyz/kit/commit/7f02d23948cc09e3f0bc70931d845569f1cb38ad), [`0fa54a4`](https://github.com/anza-xyz/kit/commit/0fa54a469937db3989f42afc4248882736f719f5)]:\n    - @solana/transactions@6.6.0\n    - @solana/transaction-messages@6.6.0\n    - @solana/signers@6.6.0\n    - @solana/addresses@6.6.0\n    - @solana/codecs-core@6.6.0\n    - @solana/keys@6.6.0\n    - @solana/promises@6.6.0\n\n## 6.5.0\n\n### Patch Changes\n\n- Updated dependencies [[`9e05736`](https://github.com/anza-xyz/kit/commit/9e057365a1a4e350f8a0ccc233b262e09b0134fa)]:\n    - @solana/signers@6.5.0\n    - @solana/addresses@6.5.0\n    - @solana/codecs-core@6.5.0\n    - @solana/keys@6.5.0\n    - @solana/promises@6.5.0\n    - @solana/transaction-messages@6.5.0\n    - @solana/transactions@6.5.0\n\n## 6.4.0\n\n### Minor Changes\n\n- [#1368](https://github.com/anza-xyz/kit/pull/1368) [`938ca94`](https://github.com/anza-xyz/kit/commit/938ca9442db414ee6fe736b89288c6d14c97cf5a) Thanks [@dpsi9](https://github.com/dpsi9)! - Add functions to create Kit signers from [Wallet Standard](https://github.com/wallet-standard/wallet-standard) `UiWalletAccount` objects.\n\n    `createSignerFromWalletAccount` returns a `TransactionSigner` that can sign transactions using the `solana:signTransaction` and the `solana:signAndSendTransaction` features. At least one of these must be present in the wallet account. If the `solana:signMessage` feature is available, then this signer is also a `MessageSigner`.\n\n    There are also more specific helpers:\n    - `createTransactionSignerFromWalletAccount(account, chain)` returns a `TransactionModifyingSigner` that uses the wallet's `solana:signTransaction` feature.\n    - `createTransactionSendingSignerFromWalletAccount(account, chain)` returns a `TransactionSendingSigner` that uses the wallet's `solana:signAndSendTransaction` feature.\n    - `createMessageSignerFromWalletAccount(account)` returns a `MessageModifyingSigner` that uses the wallet's `solana:signMessage` feature.\n\n    These enable any wallet-standard wallet to be used as a Kit signer.\n\n### Patch Changes\n\n- Updated dependencies [[`27c3975`](https://github.com/anza-xyz/kit/commit/27c39755f5185e09a194c0b22eac4286f14c552c), [`084e92e`](https://github.com/anza-xyz/kit/commit/084e92e668d41041c6424d616441557560873888)]:\n    - @solana/codecs-core@6.4.0\n    - @solana/transaction-messages@6.4.0\n    - @solana/addresses@6.4.0\n    - @solana/keys@6.4.0\n    - @solana/signers@6.4.0\n    - @solana/transactions@6.4.0\n    - @solana/promises@6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n### Minor Changes\n\n- [#1415](https://github.com/anza-xyz/kit/pull/1415) [`587ede3`](https://github.com/anza-xyz/kit/commit/587ede3915eea9b14a1150c71e509b7d0d4b4a6c) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Add new `@solana/wallet-account-signer` package that will contain functions for converting from [Wallet Standard](https://github.com/wallet-standard/wallet-standard) accounts on Solana chains, to Kit Signer objects.\n"
  },
  {
    "path": "packages/wallet-account-signer/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/wallet-account-signer/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/wallet-account-signer?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/wallet-account-signer?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/wallet-account-signer\n\n# @solana/wallet-account-signer\n\nThis package bridges [Wallet Standard](https://github.com/wallet-standard/wallet-standard) accounts to Kit [`@solana/signers`](https://github.com/anza-xyz/kit/tree/main/packages/signers) interfaces. It converts a `UiWalletAccount` into the appropriate Kit signer depending on which Wallet Standard features the wallet supports.\n\n## Installation\n\n```shell\npnpm add @solana/wallet-account-signer\n```\n\n## Chains\n\nSeveral functions in this package require a `chain` parameter. The known Solana chains from `@solana/wallet-standard-chains` are autocompleted:\n\n- `'solana:mainnet'`\n- `'solana:devnet'`\n- `'solana:testnet'`\n- `'solana:localnet'`\n\nAny other Wallet Standard `IdentifierString` (i.e. any `${namespace}:${reference}` value) is also accepted to support wallets that advertise non-standard chains.\n\n## Usage\n\n### `createSignerFromWalletAccount(uiWalletAccount, chain)`\n\nCreates a signer that exposes every signing capability the wallet account supports. Inspects the account's features at call time and returns a frozen object with the applicable methods:\n\n- `modifyAndSignTransactions` — when `solana:signTransaction` is available.\n- `signAndSendTransactions` — when `solana:signAndSendTransaction` is available.\n- `modifyAndSignMessages` — when `solana:signMessage` is available.\n\nAt least one transaction-signing feature must be present or an error is thrown.\n\n```ts\nimport { createSignerFromWalletAccount } from '@solana/wallet-account-signer';\n\nconst signer = createSignerFromWalletAccount(walletAccount, 'solana:mainnet');\n```\n\n### `createTransactionSignerFromWalletAccount(uiWalletAccount, chain)`\n\nCreates a `TransactionModifyingSigner` from a wallet account that supports the `solana:signTransaction` feature.\n\n```ts\nimport { createTransactionSignerFromWalletAccount } from '@solana/wallet-account-signer';\n\nconst signer = createTransactionSignerFromWalletAccount(walletAccount, 'solana:devnet');\nconst [signedTransaction] = await signer.modifyAndSignTransactions([transaction]);\n```\n\n### `createTransactionSendingSignerFromWalletAccount(uiWalletAccount, chain)`\n\nCreates a `TransactionSendingSigner` from a wallet account that supports the `solana:signAndSendTransaction` feature.\n\n```ts\nimport { createTransactionSendingSignerFromWalletAccount } from '@solana/wallet-account-signer';\n\nconst signer = createTransactionSendingSignerFromWalletAccount(walletAccount, 'solana:devnet');\nconst [signature] = await signer.signAndSendTransactions([transaction]);\n```\n\n### `createMessageSignerFromWalletAccount(uiWalletAccount)`\n\nCreates a `MessageModifyingSigner` from a wallet account that supports the `solana:signMessage` feature. Unlike the transaction signers, this function does not require a `chain` parameter.\n\n```ts\nimport { createMessageSignerFromWalletAccount } from '@solana/wallet-account-signer';\nimport { createSignableMessage } from '@solana/signers';\n\nconst signer = createMessageSignerFromWalletAccount(walletAccount);\nconst message = createSignableMessage('Hello, world!');\nconst [signedMessage] = await signer.modifyAndSignMessages([message]);\n```\n\nTo learn more about the different signer types, see the [Signers](https://www.solanakit.com/docs/concepts/signers) documentation.\n"
  },
  {
    "path": "packages/wallet-account-signer/package.json",
    "content": "{\n    \"name\": \"@solana/wallet-account-signer\",\n    \"version\": \"6.9.0\",\n    \"description\": \"Utilities for converting from Wallet Standard accounts to Kit Signer objects\",\n    \"homepage\": \"https://www.solanakit.com/api#solanawallet-account-signer\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": false,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:native\": \"agadoo dist/index.native.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@solana/addresses\": \"workspace:*\",\n        \"@solana/codecs-core\": \"workspace:*\",\n        \"@solana/keys\": \"workspace:*\",\n        \"@solana/promises\": \"workspace:*\",\n        \"@solana/signers\": \"workspace:*\",\n        \"@solana/transaction-messages\": \"workspace:*\",\n        \"@solana/transactions\": \"workspace:*\",\n        \"@solana/wallet-standard-chains\": \"^1.1.1\",\n        \"@solana/wallet-standard-features\": \"^1.3.0\",\n        \"@wallet-standard/base\": \"^1.1.0\",\n        \"@wallet-standard/errors\": \"^0.1.1\",\n        \"@wallet-standard/ui\": \"^1.0.1\",\n        \"@wallet-standard/ui-registry\": \"^1.0.1\"\n    },\n    \"devDependencies\": {\n        \"@solana/errors\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/wallet-account-signer/src/__tests__/wallet-account-message-signer-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { address } from '@solana/addresses';\nimport { bytesEqual } from '@solana/codecs-core';\nimport type { SignatureBytes } from '@solana/keys';\nimport type { SignableMessage } from '@solana/signers';\nimport { SolanaSignMessage, SolanaSignMessageFeature } from '@solana/wallet-standard-features';\nimport { getWalletAccountFeature, UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\n\nimport { createMessageSignerFromWalletAccount } from '../wallet-account-message-signer';\n\njest.mock('@solana/addresses');\njest.mock('@wallet-standard/ui');\njest.mock('@wallet-standard/ui-registry');\njest.mock('@solana/codecs-core');\n\ndescribe('createMessageSignerFromWalletAccount', () => {\n    const mockAddress = 'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy' as Address;\n\n    function createMockAccount(overrides: Partial<UiWalletAccount> = {}): UiWalletAccount {\n        return {\n            address: mockAddress,\n            chains: ['solana:devnet'],\n            features: [SolanaSignMessage],\n            ...overrides,\n        } as unknown as UiWalletAccount;\n    }\n\n    beforeEach(() => {\n        jest.clearAllMocks();\n        jest.mocked(address).mockImplementation(addr => addr as Address);\n    });\n\n    it('exposes the correct address', () => {\n        // Given a wallet account with a known address.\n        const account = createMockAccount({ address: mockAddress });\n\n        // And a mock wallet feature.\n        const mockFeature: SolanaSignMessageFeature['solana:signMessage'] = {\n            signMessage: jest.fn().mockResolvedValue([]),\n        } as unknown as SolanaSignMessageFeature['solana:signMessage'];\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer from the account.\n        const signer = createMessageSignerFromWalletAccount(account);\n\n        // Then the signer exposes the same address.\n        expect(signer.address).toBe(mockAddress);\n    });\n\n    it('returns empty array when no messages are provided', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signMessage: jest.fn().mockResolvedValue([]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignMessages with an empty array.\n        const signer = createMessageSignerFromWalletAccount(account);\n\n        // Then it returns an empty array.\n        await expect(signer.modifyAndSignMessages([])).resolves.toEqual([]);\n    });\n\n    it('forwards messages to wallet feature', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature that returns a signed message.\n        const mockFeature = {\n            signMessage: jest\n                .fn()\n                .mockResolvedValue([\n                    { signature: new Uint8Array(64).fill(1), signedMessage: new Uint8Array([1, 2, 3]) },\n                ]),\n        };\n\n        const mockWalletAccount = { mockWalletAccount: 1 } as unknown as ReturnType<\n            typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n        >;\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            mockWalletAccount,\n        );\n\n        // When we create a signer and call modifyAndSignMessages.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const message = {\n            content: new Uint8Array([1, 2, 3]),\n            signatures: {},\n        } as SignableMessage;\n        await signer.modifyAndSignMessages([message]);\n\n        // Then the wallet feature's signMessage method is called.\n        expect(mockFeature.signMessage).toHaveBeenCalledWith({ account: mockWalletAccount, message: message.content });\n    });\n\n    it('propagates wallet errors', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature that rejects with an error.\n        const mockFeature = {\n            signMessage: jest.fn().mockRejectedValue(new Error('fail')),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignMessages.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const message = {\n            content: new Uint8Array([1, 2, 3]),\n            signatures: {},\n        } as SignableMessage;\n\n        // Then the wallet error is propagated.\n        await expect(signer.modifyAndSignMessages([message])).rejects.toThrow('fail');\n    });\n\n    it('handles multiple messages in a single call', async () => {\n        expect.assertions(2);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature that returns signed messages.\n        const mockFeature = {\n            signMessage: jest.fn().mockResolvedValue([\n                { signature: new Uint8Array(64).fill(1), signedMessage: new Uint8Array([1, 2, 3]) },\n                { signature: new Uint8Array(64).fill(2), signedMessage: new Uint8Array([4, 5, 6]) },\n            ]),\n        };\n\n        const mockWalletAccount = { mockWalletAccount: 1 } as unknown as ReturnType<\n            typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n        >;\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            mockWalletAccount,\n        );\n\n        // When we create a signer and call modifyAndSignMessages with multiple messages.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const messages = [\n            { content: new Uint8Array([1, 2, 3]), signatures: {} },\n            { content: new Uint8Array([4, 5, 6]), signatures: {} },\n        ] as SignableMessage[];\n\n        const results = await signer.modifyAndSignMessages(messages);\n\n        // Then the wallet feature is called once.\n        expect(mockFeature.signMessage).toHaveBeenCalledWith(\n            { account: mockWalletAccount, message: messages[0].content },\n            { account: mockWalletAccount, message: messages[1].content },\n        );\n\n        // And we get the correct number of results.\n        expect(results).toHaveLength(2);\n    });\n\n    it('returns same message object when signature and content are unchanged', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature that returns the same message and signature.\n        const mockFeature = {\n            signMessage: jest\n                .fn()\n                .mockResolvedValue([\n                    { signature: new Uint8Array(64).fill(9), signedMessage: new Uint8Array([1, 2, 3]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n        jest.mocked(bytesEqual).mockReturnValue(true);\n\n        // When we create a signer and sign a message that already has the same signature.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const inputMessage = {\n            content: new Uint8Array([1, 2, 3]),\n            signatures: {\n                [mockAddress]: new Uint8Array(64).fill(9) as SignatureBytes,\n            },\n        } as SignableMessage;\n\n        const [result] = await signer.modifyAndSignMessages([inputMessage]);\n\n        // Then the result is the same object.\n        expect(result).toBe(inputMessage);\n    });\n\n    it('returns new object when signature changes', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature that returns a different signature.\n        const mockFeature = {\n            signMessage: jest\n                .fn()\n                .mockResolvedValue([\n                    { signature: new Uint8Array(64).fill(8), signedMessage: new Uint8Array([1, 2, 3]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n        jest.mocked(bytesEqual).mockReturnValue(false);\n\n        // When we create a signer and sign a message.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const inputMessage = {\n            content: new Uint8Array([1, 2, 3]),\n            signatures: {\n                [mockAddress]: new Uint8Array(64).fill(9) as SignatureBytes,\n            },\n        } as SignableMessage;\n\n        const [result] = await signer.modifyAndSignMessages([inputMessage]);\n\n        // Then the result is a different object.\n        expect(result).not.toBe(inputMessage);\n    });\n\n    it('returns new object when content changes', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature that returns a modified message.\n        const mockFeature = {\n            signMessage: jest\n                .fn()\n                .mockResolvedValue([\n                    { signature: new Uint8Array(64).fill(9), signedMessage: new Uint8Array([2, 3, 4]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and sign a message.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const inputMessage = {\n            content: new Uint8Array([1, 2, 3]),\n            signatures: {\n                [mockAddress]: new Uint8Array(64).fill(9) as SignatureBytes,\n            },\n        } as SignableMessage;\n\n        const [result] = await signer.modifyAndSignMessages([inputMessage]);\n\n        // Then the result is a different object.\n        expect(result).not.toBe(inputMessage);\n    });\n\n    it('preserves existing signatures when message is not modified', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature that returns the same message.\n        const mockFeature = {\n            signMessage: jest\n                .fn()\n                .mockResolvedValue([\n                    { signature: new Uint8Array(64).fill(127), signedMessage: new Uint8Array([1, 2, 3]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and sign a message that has other signatures.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const inputMessage = {\n            content: new Uint8Array([1, 2, 3]),\n            signatures: {\n                '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n            },\n        } as SignableMessage;\n\n        const [result] = await signer.modifyAndSignMessages([inputMessage]);\n\n        // Then the result preserves the existing signature.\n        expect(result.signatures).toEqual({\n            '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n            [mockAddress]: new Uint8Array(64).fill(127) as SignatureBytes,\n        });\n    });\n\n    it('clears existing signatures when message is modified', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature that returns a modified message.\n        const mockFeature = {\n            signMessage: jest\n                .fn()\n                .mockResolvedValue([\n                    { signature: new Uint8Array(64).fill(127), signedMessage: new Uint8Array([2, 3, 4]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and sign a message that has other signatures.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const inputMessage = {\n            content: new Uint8Array([1, 2, 3]),\n            signatures: {\n                '11111111111111111111111111111114': new Uint8Array(64).fill(2) as SignatureBytes,\n            },\n        } as SignableMessage;\n\n        const [result] = await signer.modifyAndSignMessages([inputMessage]);\n\n        // Then the result only has the new signature.\n        expect(result.signatures).toEqual({\n            [mockAddress]: new Uint8Array(64).fill(127) as SignatureBytes,\n        });\n    });\n\n    it('rejects when aborted', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signMessage: jest\n                .fn()\n                .mockResolvedValue([\n                    { signature: new Uint8Array(64).fill(1), signedMessage: new Uint8Array([1, 2, 3]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer.\n        const signer = createMessageSignerFromWalletAccount(account);\n        const message = {\n            content: new Uint8Array([1, 2, 3]),\n            signatures: {},\n        } as SignableMessage;\n\n        // And we call modifyAndSignMessages with an already aborted signal.\n        const abortController = new AbortController();\n        abortController.abort(new Error('o no'));\n        const alreadyAbortedSignal = abortController.signal;\n\n        // Then it rejects with the abort error.\n        await expect(signer.modifyAndSignMessages([message], { abortSignal: alreadyAbortedSignal })).rejects.toThrow(\n            new Error('o no'),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/wallet-account-signer/src/__tests__/wallet-account-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION, SolanaError } from '@solana/errors';\nimport {\n    SolanaSignAndSendTransaction,\n    SolanaSignMessage,\n    SolanaSignTransaction,\n} from '@solana/wallet-standard-features';\nimport { WalletStandardError } from '@wallet-standard/errors';\nimport { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { createMessageSignerFromWalletAccount } from '../wallet-account-message-signer';\nimport { createSignerFromWalletAccount } from '../wallet-account-signer';\nimport { createTransactionSendingSignerFromWalletAccount } from '../wallet-account-transaction-sending-signer';\nimport { createTransactionSignerFromWalletAccount } from '../wallet-account-transaction-signer';\n\njest.mock('../wallet-account-transaction-signer');\njest.mock('../wallet-account-transaction-sending-signer');\njest.mock('../wallet-account-message-signer');\n\ndescribe('createSignerFromWalletAccount', () => {\n    const mockAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n\n    function createMockAccount(overrides: Partial<UiWalletAccount> = {}): UiWalletAccount {\n        return {\n            address: mockAddress,\n            chains: ['solana:devnet'],\n            features: [SolanaSignTransaction],\n            ...overrides,\n        } as unknown as UiWalletAccount;\n    }\n\n    const mockModifyAndSignTransactions = jest.fn();\n    const mockSignAndSendTransactions = jest.fn();\n    const mockModifyAndSignMessages = jest.fn();\n\n    beforeEach(() => {\n        jest.clearAllMocks();\n\n        jest.mocked(createTransactionSignerFromWalletAccount).mockReturnValue({\n            address: mockAddress,\n            modifyAndSignTransactions: mockModifyAndSignTransactions,\n        });\n\n        jest.mocked(createTransactionSendingSignerFromWalletAccount).mockReturnValue({\n            address: mockAddress,\n            signAndSendTransactions: mockSignAndSendTransactions,\n        });\n\n        jest.mocked(createMessageSignerFromWalletAccount).mockReturnValue({\n            address: mockAddress,\n            modifyAndSignMessages: mockModifyAndSignMessages,\n        });\n    });\n\n    it('throws if chain is unsupported', () => {\n        // Given a wallet account that only supports devnet.\n        const account = createMockAccount({ chains: ['solana:devnet'] });\n\n        // When we try to create a signer for mainnet.\n        const fn = () => createSignerFromWalletAccount(account, 'solana:mainnet');\n\n        // Then we expect an error to be thrown.\n        expect(fn).toThrow(WalletStandardError);\n    });\n\n    it('throws if neither signTransaction nor signAndSendTransaction feature is available', () => {\n        // Given a wallet account that only supports message signing.\n        const account = createMockAccount({ features: [SolanaSignMessage] });\n\n        // When we try to create a signer.\n        const fn = () => createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then we expect a SolanaError to be thrown (not a wallet-standard error).\n        expect(fn).toThrow(\n            new SolanaError(SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION, {\n                address: account.address,\n                supportedFeatures: account.features as string[],\n            }),\n        );\n    });\n\n    it('exposes the correct address', () => {\n        // Given a wallet account with a known address.\n        const account = createMockAccount();\n\n        // When we create a signer from the account.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer exposes the same address.\n        expect(signer.address).toBe(mockAddress);\n    });\n\n    it('includes modifyAndSignTransactions when signTransaction feature is available', () => {\n        // Given a wallet account with the signTransaction feature.\n        const account = createMockAccount({ features: [SolanaSignTransaction] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer has modifyAndSignTransactions.\n        expect('modifyAndSignTransactions' in signer).toBe(true);\n    });\n\n    it('does not include modifyAndSignTransactions when signTransaction feature is absent', () => {\n        // Given a wallet account without the signTransaction feature.\n        const account = createMockAccount({ features: [SolanaSignAndSendTransaction] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer does not have modifyAndSignTransactions.\n        expect('modifyAndSignTransactions' in signer).toBe(false);\n    });\n\n    it('includes signAndSendTransactions when signAndSendTransaction feature is available', () => {\n        // Given a wallet account with the signAndSendTransaction feature.\n        const account = createMockAccount({ features: [SolanaSignAndSendTransaction] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer has signAndSendTransactions.\n        expect('signAndSendTransactions' in signer).toBe(true);\n    });\n\n    it('does not include signAndSendTransactions when signAndSendTransaction feature is absent', () => {\n        // Given a wallet account without the signAndSendTransaction feature.\n        const account = createMockAccount({ features: [SolanaSignTransaction] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer does not have signAndSendTransactions.\n        expect('signAndSendTransactions' in signer).toBe(false);\n    });\n\n    it('includes modifyAndSignMessages when signMessage feature is available', () => {\n        // Given a wallet account with the signMessage feature in addition to a tx feature.\n        const account = createMockAccount({ features: [SolanaSignTransaction, SolanaSignMessage] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer has modifyAndSignMessages.\n        expect('modifyAndSignMessages' in signer).toBe(true);\n    });\n\n    it('does not include modifyAndSignMessages when signMessage feature is absent', () => {\n        // Given a wallet account without the signMessage feature.\n        const account = createMockAccount({ features: [SolanaSignTransaction] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer does not have modifyAndSignMessages.\n        expect('modifyAndSignMessages' in signer).toBe(false);\n    });\n\n    it('includes all three methods when all features are available', () => {\n        // Given a wallet account with all three features.\n        const account = createMockAccount({\n            features: [SolanaSignTransaction, SolanaSignAndSendTransaction, SolanaSignMessage],\n        });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer has all three methods.\n        expect('modifyAndSignTransactions' in signer).toBe(true);\n        expect('signAndSendTransactions' in signer).toBe(true);\n        expect('modifyAndSignMessages' in signer).toBe(true);\n    });\n\n    it('uses the method from createTransactionSignerFromWalletAccount', () => {\n        // Given a wallet account with the signTransaction feature.\n        const account = createMockAccount({ features: [SolanaSignTransaction] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the modifyAndSignTransactions method is the one from the delegate.\n        expect((signer as { modifyAndSignTransactions: unknown }).modifyAndSignTransactions).toBe(\n            mockModifyAndSignTransactions,\n        );\n    });\n\n    it('uses the method from createTransactionSendingSignerFromWalletAccount', () => {\n        // Given a wallet account with the signAndSendTransaction feature.\n        const account = createMockAccount({ features: [SolanaSignAndSendTransaction] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signAndSendTransactions method is the one from the delegate.\n        expect((signer as { signAndSendTransactions: unknown }).signAndSendTransactions).toBe(\n            mockSignAndSendTransactions,\n        );\n    });\n\n    it('uses the method from createMessageSignerFromWalletAccount', () => {\n        // Given a wallet account with the signMessage feature.\n        const account = createMockAccount({ features: [SolanaSignTransaction, SolanaSignMessage] });\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the modifyAndSignMessages method is the one from the delegate.\n        expect((signer as { modifyAndSignMessages: unknown }).modifyAndSignMessages).toBe(mockModifyAndSignMessages);\n    });\n\n    it('returns a frozen object', () => {\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // When we create a signer.\n        const signer = createSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer is frozen.\n        expect(Object.isFrozen(signer)).toBe(true);\n    });\n\n    it('passes the chain to createTransactionSignerFromWalletAccount', () => {\n        // Given a wallet account on mainnet.\n        const account = createMockAccount({ chains: ['solana:mainnet'], features: [SolanaSignTransaction] });\n\n        // When we create a signer for mainnet.\n        createSignerFromWalletAccount(account, 'solana:mainnet');\n\n        // Then the chain is forwarded to the delegate.\n        expect(createTransactionSignerFromWalletAccount).toHaveBeenCalledWith(account, 'solana:mainnet');\n    });\n\n    it('passes the chain to createTransactionSendingSignerFromWalletAccount', () => {\n        // Given a wallet account on mainnet.\n        const account = createMockAccount({ chains: ['solana:mainnet'], features: [SolanaSignAndSendTransaction] });\n\n        // When we create a signer for mainnet.\n        createSignerFromWalletAccount(account, 'solana:mainnet');\n\n        // Then the chain is forwarded to the delegate.\n        expect(createTransactionSendingSignerFromWalletAccount).toHaveBeenCalledWith(account, 'solana:mainnet');\n    });\n});\n"
  },
  {
    "path": "packages/wallet-account-signer/src/__tests__/wallet-account-transaction-sending-signer-test.ts",
    "content": "import { address } from '@solana/addresses';\nimport { TransactionSendingSigner } from '@solana/signers';\nimport { getTransactionEncoder } from '@solana/transactions';\nimport { SolanaSignAndSendTransaction } from '@solana/wallet-standard-features';\nimport { WalletStandardError } from '@wallet-standard/errors';\nimport { getWalletAccountFeature, UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\n\nimport { createTransactionSendingSignerFromWalletAccount } from '../wallet-account-transaction-sending-signer';\n\njest.mock('@wallet-standard/ui');\njest.mock('@wallet-standard/ui-registry');\njest.mock('@solana/transactions');\n\ntype InputTransaction = Parameters<TransactionSendingSigner['signAndSendTransactions']>[0][number];\n\ndescribe('createSendingSignerFromWalletAccount', () => {\n    const mockAddress = address('Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy');\n\n    function createMockAccount(overrides: Partial<UiWalletAccount> = {}): UiWalletAccount {\n        return {\n            address: mockAddress,\n            chains: ['solana:devnet'],\n            features: [SolanaSignAndSendTransaction],\n            ...overrides,\n        } as unknown as UiWalletAccount;\n    }\n\n    beforeEach(() => {\n        jest.clearAllMocks();\n    });\n\n    it('throws if chain is unsupported', () => {\n        // Given a wallet account that only supports devnet.\n        const account = createMockAccount({ chains: ['solana:devnet'] });\n\n        // When we try to create a sending signer for mainnet.\n        const fn = () => createTransactionSendingSignerFromWalletAccount(account, 'solana:mainnet');\n\n        // Then we expect an error to be thrown.\n        expect(fn).toThrow(WalletStandardError);\n    });\n\n    it('exposes the correct address', () => {\n        // Given a wallet account with a known address.\n        const account = createMockAccount();\n\n        // When we create a sending signer from the account.\n        const signer = createTransactionSendingSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer exposes the same address.\n        expect(signer.address).toBe(mockAddress);\n    });\n\n    it('returns empty array when no transactions provided', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // When we create a sending signer and call signAndSendTransactions with an empty array.\n        const signer = createTransactionSendingSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then it returns an empty array.\n        await expect(signer.signAndSendTransactions([])).resolves.toEqual([]);\n    });\n\n    it('handles multiple transactions', async () => {\n        expect.assertions(2);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction encoder.\n        const mockEncodedTransaction1 = new Uint8Array([1, 2, 3]);\n        const mockEncodedTransaction2 = new Uint8Array([4, 5, 6]);\n        const mockEncode = jest\n            .fn()\n            .mockReturnValueOnce(mockEncodedTransaction1)\n            .mockReturnValueOnce(mockEncodedTransaction2);\n\n        jest.mocked(getTransactionEncoder).mockReturnValue({\n            encode: mockEncode,\n        } as unknown as ReturnType<typeof getTransactionEncoder>);\n\n        // And a mock wallet feature that returns signatures for all transactions at once.\n        const mockFeature = {\n            signAndSendTransaction: jest\n                .fn()\n                .mockResolvedValue([{ signature: new Uint8Array([9]) }, { signature: new Uint8Array([10]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n\n        const mockWalletAccount = { mockWallet: 1 } as unknown as ReturnType<\n            typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\n        >;\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            mockWalletAccount,\n        );\n\n        // When we create a sending signer and call signAndSendTransactions with multiple transactions.\n        const signer = createTransactionSendingSignerFromWalletAccount(account, 'solana:devnet');\n\n        const tx1 = {} as InputTransaction;\n        const tx2 = {} as InputTransaction;\n\n        const result = await signer.signAndSendTransactions([tx1, tx2]);\n\n        // Then the wallet feature is called once with all transactions.\n        expect(mockFeature.signAndSendTransaction).toHaveBeenCalledWith(\n            { account: mockWalletAccount, chain: 'solana:devnet', transaction: mockEncodedTransaction1 },\n            { account: mockWalletAccount, chain: 'solana:devnet', transaction: mockEncodedTransaction2 },\n        );\n\n        // And the result contains both signatures.\n        expect(result).toHaveLength(2);\n    });\n\n    it('encodes transaction and forwards to wallet feature', async () => {\n        expect.assertions(2);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction encoder.\n        const mockEncode = jest.fn().mockReturnValue(new Uint8Array([1, 2, 3]));\n\n        jest.mocked(getTransactionEncoder).mockReturnValue({\n            encode: mockEncode,\n        } as unknown as ReturnType<typeof getTransactionEncoder>);\n\n        // And a mock wallet feature that returns a signed transaction.\n        const mockFeature = {\n            signAndSendTransaction: jest.fn().mockResolvedValue([{ signature: new Uint8Array([9]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a sending signer and call signAndSendTransactions.\n        const signer = createTransactionSendingSignerFromWalletAccount(account, 'solana:devnet');\n\n        const tx = {} as InputTransaction;\n\n        await signer.signAndSendTransactions([tx]);\n\n        // Then the transaction is encoded and forwarded to the wallet feature.\n        expect(mockEncode).toHaveBeenCalledWith(tx);\n        expect(mockFeature.signAndSendTransaction).toHaveBeenCalled();\n    });\n\n    it('returns the correct signatures from wallet', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction encoder.\n        jest.mocked(getTransactionEncoder).mockReturnValue({\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionEncoder>);\n\n        // And a mock wallet feature that returns specific signatures.\n        const expectedSignature = new Uint8Array([1, 2, 3, 4, 5]);\n        const mockFeature = {\n            signAndSendTransaction: jest.fn().mockResolvedValue([{ signature: expectedSignature }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a sending signer and call signAndSendTransactions.\n        const signer = createTransactionSendingSignerFromWalletAccount(account, 'solana:devnet');\n        const tx = {} as InputTransaction;\n\n        const result = await signer.signAndSendTransactions([tx]);\n\n        // Then the returned signature matches what the wallet returned.\n        expect(result).toEqual([expectedSignature]);\n    });\n\n    it('propagates wallet errors', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction encoder.\n        jest.mocked(getTransactionEncoder).mockReturnValue({\n            encode: jest.fn().mockReturnValue(new Uint8Array([1])),\n        } as unknown as ReturnType<typeof getTransactionEncoder>);\n\n        // And a mock wallet feature that rejects with an error.\n        const mockFeature = {\n            signAndSendTransaction: jest.fn().mockRejectedValue(new Error('fail')),\n        };\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a sending signer and call signAndSendTransactions.\n        const signer = createTransactionSendingSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the wallet error is propagated.\n        await expect(signer.signAndSendTransactions([{} as InputTransaction])).rejects.toThrow('fail');\n    });\n\n    it('passes minContextSlot option to wallet feature', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction encoder.\n        jest.mocked(getTransactionEncoder).mockReturnValue({\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionEncoder>);\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signAndSendTransaction: jest.fn().mockResolvedValue([{ signature: new Uint8Array([9]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a sending signer and call signAndSendTransactions with options.\n        const signer = createTransactionSendingSignerFromWalletAccount(account, 'solana:devnet');\n        const tx = {} as InputTransaction;\n\n        await signer.signAndSendTransactions([tx], {\n            abortSignal: AbortSignal.timeout(1_000_000),\n            minContextSlot: 123n,\n        });\n\n        // Then the minContextSlot is passed to the wallet feature (converted to number).\n        expect(mockFeature.signAndSendTransaction).toHaveBeenCalledWith(\n            expect.objectContaining({\n                options: { minContextSlot: 123 },\n            }),\n        );\n    });\n\n    it('rejects when aborted', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction encoder.\n        jest.mocked(getTransactionEncoder).mockReturnValue({\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionEncoder>);\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signAndSendTransaction: jest.fn().mockResolvedValue([{ signature: new Uint8Array([9]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a sending signer.\n        const signer = createTransactionSendingSignerFromWalletAccount(account, 'solana:devnet');\n        const tx = {} as InputTransaction;\n\n        // And we call signAndSendTransactions with an already aborted signal.\n        const abortController = new AbortController();\n        abortController.abort(new Error('o no'));\n        const alreadyAbortedSignal = abortController.signal;\n\n        // Then it rejects with the abort error.\n        await expect(signer.signAndSendTransactions([tx], { abortSignal: alreadyAbortedSignal })).rejects.toThrow(\n            new Error('o no'),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/wallet-account-signer/src/__tests__/wallet-account-transaction-signer-test.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { address } from '@solana/addresses';\nimport { bytesEqual } from '@solana/codecs-core';\nimport { SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, SolanaError } from '@solana/errors';\nimport { TransactionModifyingSigner } from '@solana/signers';\nimport { getCompiledTransactionMessageDecoder } from '@solana/transaction-messages';\nimport {\n    assertIsTransactionWithinSizeLimit,\n    getTransactionCodec,\n    getTransactionLifetimeConstraintFromCompiledTransactionMessage,\n    TransactionBlockhashLifetime,\n    TransactionDurableNonceLifetime,\n    TransactionMessageBytes,\n} from '@solana/transactions';\nimport { SolanaSignTransaction, SolanaSignTransactionFeature } from '@solana/wallet-standard-features';\nimport { WalletStandardError } from '@wallet-standard/errors';\nimport { getWalletAccountFeature, UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\n\nimport { Blockhash } from '../../../rpc-types/dist/types';\nimport { createTransactionSignerFromWalletAccount } from '../wallet-account-transaction-signer';\n\njest.mock('@solana/addresses');\njest.mock('@wallet-standard/ui');\njest.mock('@wallet-standard/ui-registry');\njest.mock('@solana/transactions');\njest.mock('@solana/transaction-messages');\njest.mock('@solana/codecs-core');\n\ntype InputTransaction = Parameters<TransactionModifyingSigner['modifyAndSignTransactions']>[0][number];\n\ndescribe('createSignerFromWalletAccount', () => {\n    const mockAddress = 'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy' as Address;\n\n    function createMockAccount(overrides: Partial<UiWalletAccount> = {}): UiWalletAccount {\n        return {\n            address: mockAddress,\n            chains: ['solana:devnet'],\n            features: [SolanaSignTransaction],\n            ...overrides,\n        } as unknown as UiWalletAccount;\n    }\n\n    beforeEach(() => {\n        jest.clearAllMocks();\n        jest.mocked(address).mockImplementation(addr => addr as Address);\n    });\n\n    it('throws if chain is unsupported', () => {\n        // Given a wallet account that only supports devnet.\n        const account = createMockAccount({ chains: ['solana:devnet'] });\n\n        // When we try to create a signer for mainnet.\n        const fn = () => createTransactionSignerFromWalletAccount(account, 'solana:mainnet');\n\n        // Then we expect an error to be thrown.\n        expect(fn).toThrow(WalletStandardError);\n    });\n\n    it('exposes the correct address', () => {\n        // Given a wallet account with a known address.\n        const account = createMockAccount({ address: mockAddress });\n\n        // When we create a signer from the account.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the signer exposes the same address.\n        expect(signer.address).toBe(mockAddress);\n    });\n\n    it('returns empty array when no transactions are provided', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock wallet feature.\n        const mockFeature: SolanaSignTransactionFeature['solana:signTransaction'] = {\n            signTransaction: jest.fn().mockResolvedValue([]),\n        } as unknown as SolanaSignTransactionFeature['solana:signTransaction'];\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with an empty array.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then it returns an empty array.\n        await expect(signer.modifyAndSignTransactions([])).resolves.toEqual([]);\n    });\n\n    it('forwards transactions to wallet feature', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockEncodedTransaction = new Uint8Array([1, 2, 3]);\n        const mockEncode = jest.fn().mockReturnValue(mockEncodedTransaction);\n        const mockDecode = jest.fn().mockReturnValue({\n            messageBytes: new Uint8Array([4, 5, 6]),\n            signatures: {},\n        });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: mockEncode,\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest.fn().mockReturnValue({ lifetimeToken: 'test-blockhash' }),\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage).mockResolvedValue({\n            blockhash: 'test-blockhash',\n            lastValidBlockHeight: 100n,\n        } as TransactionBlockhashLifetime);\n\n        // And a mock wallet feature that returns a signed transaction.\n        const mockFeature = {\n            signTransaction: jest.fn().mockResolvedValue([{ signedTransaction: new Uint8Array([1, 2, 3]) }]),\n        };\n\n        const mockWalletAccount: ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED> =\n            {\n                mockAccount: 1,\n            } as unknown as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>;\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            mockWalletAccount,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n        const tx = {} as unknown as InputTransaction;\n        await signer.modifyAndSignTransactions([tx]);\n\n        // Then the wallet feature's signTransaction method is called.\n        expect(mockFeature.signTransaction).toHaveBeenCalledWith({\n            account: mockWalletAccount,\n            chain: 'solana:devnet',\n            transaction: mockEncodedTransaction,\n        });\n    });\n\n    it('propagates wallet errors', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: jest.fn(),\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        // And a mock wallet feature that rejects with an error.\n        const mockFeature = {\n            signTransaction: jest.fn().mockRejectedValue(new Error('fail')),\n        };\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n\n        // Then the wallet error is propagated.\n        await expect(signer.modifyAndSignTransactions([{} as InputTransaction])).rejects.toThrow('fail');\n    });\n\n    it('returns unchanged lifetime constraint if the signed transaction has identical bytes', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const messageBytes = new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes;\n        const mockDecode = jest.fn().mockReturnValue({\n            messageBytes,\n            signatures: {},\n        });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n        jest.mocked(bytesEqual).mockReturnValue(true);\n\n        // And a mock wallet feature that returns a signed transaction.\n        const mockFeature = {\n            signTransaction: jest.fn().mockResolvedValue([{ signedTransaction: new Uint8Array([1, 2, 3]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with a lifetime constraint.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n        const lifetimeConstraint = { blockhash: 'abc', lastValidBlockHeight: 123n } as TransactionBlockhashLifetime;\n        const tx = {\n            lifetimeConstraint,\n            messageBytes,\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        const result = await signer.modifyAndSignTransactions([tx]);\n\n        // Then the result has the original lifetime constraint.\n        expect(result[0].lifetimeConstraint).toBe(lifetimeConstraint);\n    });\n\n    it('returns unchanged lifetime constraint if the signed transaction has the same lifetime token', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec that returns different message bytes.\n        const inputMessageBytes = new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes;\n        const outputMessageBytes = new Uint8Array([4, 5, 6]) as unknown as TransactionMessageBytes;\n        const mockDecode = jest.fn().mockReturnValue({\n            messageBytes: outputMessageBytes,\n            signatures: {},\n        });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n        jest.mocked(bytesEqual).mockReturnValue(false);\n\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest.fn().mockReturnValue({ lifetimeToken: 'abc' }),\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        // And a mock wallet feature that returns a signed transaction.\n        const mockFeature = {\n            signTransaction: jest.fn().mockResolvedValue([{ signedTransaction: new Uint8Array([4, 5, 6]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with a lifetime constraint.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n        const lifetimeConstraint = { blockhash: 'abc', lastValidBlockHeight: 123n } as TransactionBlockhashLifetime;\n        const tx = {\n            lifetimeConstraint,\n            messageBytes: inputMessageBytes,\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        const result = await signer.modifyAndSignTransactions([tx]);\n\n        // Then the result has the original lifetime constraint.\n        expect(result[0].lifetimeConstraint).toBe(lifetimeConstraint);\n    });\n\n    it('returns a new lifetime constraint if the input transaction does not have one', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockDecode = jest.fn().mockReturnValue({\n            messageBytes: new Uint8Array([4, 5, 6]),\n            signatures: {},\n        });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest.fn().mockReturnValue({}),\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        const newLifetimeConstraint = { blockhash: 'def', lastValidBlockHeight: 456n } as TransactionBlockhashLifetime;\n        jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage).mockResolvedValue(\n            newLifetimeConstraint,\n        );\n\n        // And a mock wallet feature that returns a signed transaction.\n        const mockFeature = {\n            signTransaction: jest.fn().mockResolvedValue([{ signedTransaction: new Uint8Array([4, 5, 6]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions without a lifetime constraint.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n        const tx = {\n            messageBytes: new Uint8Array([1, 2, 3]),\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        const result = await signer.modifyAndSignTransactions([tx]);\n\n        // Then the result has the new lifetime constraint.\n        expect(result[0].lifetimeConstraint).toEqual(newLifetimeConstraint);\n    });\n\n    it('returns a new lifetime constraint if the signed transaction has a different lifetime token', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockDecode = jest.fn().mockReturnValue({\n            messageBytes: new Uint8Array([4, 5, 6]),\n            signatures: {},\n        });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n        jest.mocked(bytesEqual).mockReturnValue(false);\n\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest.fn().mockReturnValue({ lifetimeToken: 'def' }),\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        const newLifetimeConstraint = { blockhash: 'def', lastValidBlockHeight: 456n } as TransactionBlockhashLifetime;\n        jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage).mockResolvedValue(\n            newLifetimeConstraint,\n        );\n\n        // And a mock wallet feature that returns a signed transaction.\n        const mockFeature = {\n            signTransaction: jest.fn().mockResolvedValue([{ signedTransaction: new Uint8Array([4, 5, 6]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with a different lifetime token.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n        const inputLifetimeConstraint = {\n            blockhash: 'abc',\n            lastValidBlockHeight: 123n,\n        } as TransactionBlockhashLifetime;\n        const tx = {\n            lifetimeConstraint: inputLifetimeConstraint,\n            messageBytes: new Uint8Array([1, 2, 3]),\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        const result = await signer.modifyAndSignTransactions([tx]);\n\n        // Then the result has the new lifetime constraint.\n        expect(result[0].lifetimeConstraint).toEqual(newLifetimeConstraint);\n    });\n\n    it('throws when the signed transaction has a nonce lifetime but the nonce account is in a lookup table', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockDecode = jest.fn().mockReturnValue({\n            messageBytes: new Uint8Array([4, 5, 6]),\n            signatures: {},\n        });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest.fn().mockReturnValue({}),\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage).mockRejectedValue(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n                nonce: 'abc',\n            }),\n        );\n\n        // And a mock wallet feature that returns a signed transaction.\n        const mockFeature = {\n            signTransaction: jest.fn().mockResolvedValue([{ signedTransaction: new Uint8Array([4, 5, 6]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n        const tx = {\n            messageBytes: new Uint8Array([1, 2, 3]),\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        // Then the error is propagated.\n        await expect(signer.modifyAndSignTransactions([tx])).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n                nonce: 'abc',\n            }),\n        );\n    });\n\n    it('passes minContextSlot option to wallet feature', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockDecode = jest.fn().mockReturnValue({\n            messageBytes: new Uint8Array([1, 2, 3]),\n            signatures: {},\n        });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n        jest.mocked(bytesEqual).mockReturnValue(true);\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signTransaction: jest.fn().mockResolvedValue([{ signedTransaction: new Uint8Array([1, 2, 3]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with options.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n        const lifetimeConstraint = { blockhash: 'abc', lastValidBlockHeight: 123n };\n        const tx = {\n            lifetimeConstraint,\n            messageBytes: new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes,\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        await signer.modifyAndSignTransactions([tx], {\n            abortSignal: AbortSignal.timeout(1_000_000),\n            minContextSlot: 456n,\n        });\n\n        // Then the minContextSlot is passed to the wallet feature (converted to number).\n        expect(mockFeature.signTransaction).toHaveBeenCalledWith(\n            expect.objectContaining({\n                options: { minContextSlot: 456 },\n            }),\n        );\n    });\n\n    it('rejects when aborted', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: jest.fn(),\n            encode: jest.fn().mockReturnValue(new Uint8Array([1, 2, 3])),\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signTransaction: jest.fn().mockResolvedValue([{ signedTransaction: new Uint8Array([1, 2, 3]) }]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n        const tx = {\n            messageBytes: new Uint8Array([1, 2, 3]),\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        // And we call modifyAndSignTransactions with an already aborted signal.\n        const abortController = new AbortController();\n        abortController.abort(new Error('o no'));\n        const alreadyAbortedSignal = abortController.signal;\n\n        // Then it rejects with the abort error.\n        await expect(signer.modifyAndSignTransactions([tx], { abortSignal: alreadyAbortedSignal })).rejects.toThrow(\n            new Error('o no'),\n        );\n    });\n\n    it('processes multiple transactions with different lifetime constraint scenarios independently', async () => {\n        expect.assertions(5);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const tx1MessageBytes = new Uint8Array([1, 2, 3]) as unknown as TransactionMessageBytes;\n        const tx2MessageBytes = new Uint8Array([4, 5, 6]) as unknown as TransactionMessageBytes;\n        const tx3MessageBytes = new Uint8Array([7, 8, 9]) as unknown as TransactionMessageBytes;\n\n        const mockEncode = jest.fn().mockReturnValue(new Uint8Array([1, 2, 3]));\n        const mockDecode = jest\n            .fn()\n            .mockReturnValueOnce({\n                messageBytes: tx1MessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: tx2MessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: tx3MessageBytes,\n                signatures: {},\n            });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: mockEncode,\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n\n        const tx1Lifetime: TransactionBlockhashLifetime = { blockhash: 'abc' as Blockhash, lastValidBlockHeight: 100n };\n        const tx2Lifetime: TransactionBlockhashLifetime = { blockhash: 'xyz' as Blockhash, lastValidBlockHeight: 200n };\n\n        // Mock bytesEqual to return true for tx1 (identical bytes), false for tx2\n        jest.mocked(bytesEqual)\n            .mockReturnValueOnce(true) // tx1 comparison\n            .mockReturnValueOnce(false); // tx2 comparison\n\n        // Mock decoder for tx2 to return matching lifetime token\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest\n                .fn()\n                .mockReturnValueOnce({ lifetimeToken: 'xyz' }) // tx2 token check\n                .mockReturnValueOnce({}), // tx3 needs new lifetime\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        // Mock new lifetime for tx3\n        const newLifetime = {\n            blockhash: 'new-hash' as Blockhash,\n            lastValidBlockHeight: 999n,\n        } as TransactionBlockhashLifetime;\n        jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage).mockResolvedValue(newLifetime);\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signTransaction: jest\n                .fn()\n                .mockResolvedValue([\n                    { signedTransaction: new Uint8Array([1, 2, 3]) },\n                    { signedTransaction: new Uint8Array([4, 5, 6]) },\n                    { signedTransaction: new Uint8Array([7, 8, 9]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with 3 transactions.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n\n        const tx1 = {\n            lifetimeConstraint: tx1Lifetime,\n            messageBytes: tx1MessageBytes,\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        const tx2 = {\n            lifetimeConstraint: tx2Lifetime,\n            messageBytes: tx2MessageBytes,\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        const tx3 = {\n            messageBytes: tx3MessageBytes,\n            signatures: {},\n        } as unknown as InputTransaction;\n\n        const result = await signer.modifyAndSignTransactions([tx1, tx2, tx3]);\n\n        // Then bytesEqual is called twice (for tx1 and tx2, tx3 does not have an input lifetime).\n        expect(bytesEqual).toHaveBeenCalledTimes(2);\n\n        // And the result has 3 transactions.\n        expect(result).toHaveLength(3);\n\n        // And tx1 reuses its lifetime (identical bytes path).\n        expect(result[0].lifetimeConstraint).toBe(tx1Lifetime);\n\n        // And tx2 reuses its lifetime (same token path).\n        expect(result[1].lifetimeConstraint).toBe(tx2Lifetime);\n\n        // And tx3 has the new lifetime.\n        expect(result[2].lifetimeConstraint).toEqual(newLifetime);\n    });\n\n    it('calls assertIsTransactionWithinSizeLimit for each transaction in the batch', async () => {\n        expect.assertions(2);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockEncode = jest.fn().mockReturnValue(new Uint8Array([1, 2, 3]));\n        const mockDecode = jest\n            .fn()\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([1]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([2]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([3]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([4]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: mockEncode,\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        const assertMock = jest.fn();\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(assertMock);\n\n        // Mock bytesEqual to return true for all to simplify the test.\n        jest.mocked(bytesEqual).mockReturnValue(true);\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signTransaction: jest\n                .fn()\n                .mockResolvedValue([\n                    { signedTransaction: new Uint8Array([1]) },\n                    { signedTransaction: new Uint8Array([2]) },\n                    { signedTransaction: new Uint8Array([3]) },\n                    { signedTransaction: new Uint8Array([4]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with 4 transactions.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n\n        const transactions = [\n            {\n                lifetimeConstraint: { blockhash: 'a', lastValidBlockHeight: 100n },\n                messageBytes: new Uint8Array([1]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            },\n            {\n                lifetimeConstraint: { blockhash: 'b', lastValidBlockHeight: 200n },\n                messageBytes: new Uint8Array([2]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            },\n            {\n                lifetimeConstraint: { blockhash: 'c', lastValidBlockHeight: 300n },\n                messageBytes: new Uint8Array([3]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            },\n            {\n                lifetimeConstraint: { blockhash: 'd', lastValidBlockHeight: 400n },\n                messageBytes: new Uint8Array([4]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            },\n        ] as unknown as InputTransaction[];\n\n        const result = await signer.modifyAndSignTransactions(transactions);\n\n        // Then assertIsTransactionWithinSizeLimit is called exactly 4 times.\n        expect(assertMock).toHaveBeenCalledTimes(4);\n\n        // And the result has 4 transactions.\n        expect(result).toHaveLength(4);\n    });\n\n    it('fetches new lifetime constraints for multiple transactions without existing lifetimes', async () => {\n        expect.assertions(4);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockEncode = jest.fn().mockReturnValue(new Uint8Array([1, 2, 3]));\n        const mockDecode = jest\n            .fn()\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([10, 11, 12]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([20, 21, 22]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([30, 31, 32]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: mockEncode,\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n\n        // Mock decoder to return empty objects (no lifetime token).\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest.fn().mockReturnValue({}),\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        // Mock getTransactionLifetimeConstraintFromCompiledTransactionMessage to return different lifetimes.\n        const lifetime1 = { blockhash: 'new-hash-1', lastValidBlockHeight: 1000n } as TransactionBlockhashLifetime;\n        const lifetime2 = { blockhash: 'new-hash-2', lastValidBlockHeight: 2000n } as TransactionBlockhashLifetime;\n        const lifetime3 = { blockhash: 'new-hash-3', lastValidBlockHeight: 3000n } as TransactionBlockhashLifetime;\n\n        jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage)\n            .mockResolvedValueOnce(lifetime1)\n            .mockResolvedValueOnce(lifetime2)\n            .mockResolvedValueOnce(lifetime3);\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signTransaction: jest\n                .fn()\n                .mockResolvedValue([\n                    { signedTransaction: new Uint8Array([10, 11, 12]) },\n                    { signedTransaction: new Uint8Array([20, 21, 22]) },\n                    { signedTransaction: new Uint8Array([30, 31, 32]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with 3 transactions without lifetimes.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n\n        const transactions = [\n            { messageBytes: new Uint8Array([10, 11, 12]) as unknown as TransactionMessageBytes, signatures: {} },\n            { messageBytes: new Uint8Array([20, 21, 22]) as unknown as TransactionMessageBytes, signatures: {} },\n            { messageBytes: new Uint8Array([30, 31, 32]) as unknown as TransactionMessageBytes, signatures: {} },\n        ] as unknown as InputTransaction[];\n\n        const result = await signer.modifyAndSignTransactions(transactions);\n\n        // Then getTransactionLifetimeConstraintFromCompiledTransactionMessage is called exactly 3 times.\n        expect(getTransactionLifetimeConstraintFromCompiledTransactionMessage).toHaveBeenCalledTimes(3);\n\n        // And each transaction has the correct new lifetime.\n        expect(result[0].lifetimeConstraint).toEqual(lifetime1);\n        expect(result[1].lifetimeConstraint).toEqual(lifetime2);\n        expect(result[2].lifetimeConstraint).toEqual(lifetime3);\n    });\n\n    it('fetches new lifetime constraints when multiple transactions have different lifetime tokens', async () => {\n        expect.assertions(4);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockEncode = jest.fn().mockReturnValue(new Uint8Array([1, 2, 3]));\n        const mockDecode = jest\n            .fn()\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([50, 51]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([60, 61]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: mockEncode,\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n\n        // Mock bytesEqual to return false for both transactions.\n        jest.mocked(bytesEqual).mockReturnValue(false);\n\n        // Mock decoder to return different lifetime tokens.\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest\n                .fn()\n                .mockReturnValueOnce({ lifetimeToken: 'changed-1' }) // tx1 decode lifetime\n                .mockReturnValueOnce({ lifetimeToken: 'changed-2' }), // tx2 decode lifetime\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        // Mock new lifetimes.\n        const newLifetime1 = { blockhash: 'changed-1', lastValidBlockHeight: 5000n } as TransactionBlockhashLifetime;\n        const newLifetime2 = {\n            nonce: 'changed-2',\n            nonceAccountAddress: address('11111111111111111111111111111111'),\n        } as TransactionDurableNonceLifetime;\n\n        jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage)\n            .mockResolvedValueOnce(newLifetime1)\n            .mockResolvedValueOnce(newLifetime2);\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signTransaction: jest\n                .fn()\n                .mockResolvedValue([\n                    { signedTransaction: new Uint8Array([50, 51]) },\n                    { signedTransaction: new Uint8Array([60, 61]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with 2 transactions with existing but changed lifetimes.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n\n        const transactions = [\n            {\n                lifetimeConstraint: { blockhash: 'original-1', lastValidBlockHeight: 100n },\n                messageBytes: new Uint8Array([50, 51]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            },\n            {\n                lifetimeConstraint: {\n                    nonce: 'original-2',\n                    nonceAccountAddress: address('11111111111111111111111111111111'),\n                },\n                messageBytes: new Uint8Array([60, 61]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            },\n        ] as unknown as InputTransaction[];\n\n        const result = await signer.modifyAndSignTransactions(transactions);\n\n        // Then bytesEqual is called twice.\n        expect(bytesEqual).toHaveBeenCalledTimes(2);\n\n        // And the decoder is called 2 times (once per transaction.\n        expect(getCompiledTransactionMessageDecoder().decode).toHaveBeenCalledTimes(2);\n\n        // And each transaction has the new lifetime.\n        expect(result[0].lifetimeConstraint).toEqual(newLifetime1);\n        expect(result[1].lifetimeConstraint).toEqual(newLifetime2);\n    });\n\n    it('propagates error when lifetime constraint fetch fails for one transaction in a batch', async () => {\n        expect.assertions(1);\n\n        // Given a wallet account.\n        const account = createMockAccount();\n\n        // And a mock transaction codec.\n        const mockEncode = jest.fn().mockReturnValue(new Uint8Array([1, 2, 3]));\n        const mockDecode = jest\n            .fn()\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([70, 71]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([80, 81]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            })\n            .mockReturnValueOnce({\n                messageBytes: new Uint8Array([90, 91]) as unknown as TransactionMessageBytes,\n                signatures: {},\n            });\n\n        jest.mocked(getTransactionCodec).mockReturnValue({\n            decode: mockDecode,\n            encode: mockEncode,\n        } as unknown as ReturnType<typeof getTransactionCodec>);\n\n        jest.mocked(assertIsTransactionWithinSizeLimit).mockImplementation(() => {});\n\n        // Mock decoder to return empty objects.\n        jest.mocked(getCompiledTransactionMessageDecoder).mockReturnValue({\n            decode: jest.fn().mockReturnValue({}),\n        } as unknown as ReturnType<typeof getCompiledTransactionMessageDecoder>);\n\n        // Mock getTransactionLifetimeConstraintFromCompiledTransactionMessage to succeed for first, fail for second.\n        jest.mocked(getTransactionLifetimeConstraintFromCompiledTransactionMessage)\n            .mockResolvedValueOnce({ blockhash: 'ok-hash', lastValidBlockHeight: 100n } as TransactionBlockhashLifetime)\n            .mockRejectedValueOnce(\n                new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n                    nonce: 'bad-nonce',\n                }),\n            );\n\n        // And a mock wallet feature.\n        const mockFeature = {\n            signTransaction: jest\n                .fn()\n                .mockResolvedValue([\n                    { signedTransaction: new Uint8Array([70, 71]) },\n                    { signedTransaction: new Uint8Array([80, 81]) },\n                    { signedTransaction: new Uint8Array([90, 91]) },\n                ]),\n        };\n\n        jest.mocked(getWalletAccountFeature).mockReturnValue(mockFeature);\n        jest.mocked(getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED).mockReturnValue(\n            {} as ReturnType<typeof getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED>,\n        );\n\n        // When we create a signer and call modifyAndSignTransactions with 3 transactions.\n        const signer = createTransactionSignerFromWalletAccount(account, 'solana:devnet');\n\n        const transactions = [\n            { messageBytes: new Uint8Array([70, 71]) as unknown as TransactionMessageBytes, signatures: {} },\n            { messageBytes: new Uint8Array([80, 81]) as unknown as TransactionMessageBytes, signatures: {} },\n            { messageBytes: new Uint8Array([90, 91]) as unknown as TransactionMessageBytes, signatures: {} },\n        ] as unknown as InputTransaction[];\n\n        // Then it rejects with the nonce error.\n        await expect(signer.modifyAndSignTransactions(transactions)).rejects.toThrow(\n            new SolanaError(SOLANA_ERROR__TRANSACTION__NONCE_ACCOUNT_CANNOT_BE_IN_LOOKUP_TABLE, {\n                nonce: 'bad-nonce',\n            }),\n        );\n    });\n});\n"
  },
  {
    "path": "packages/wallet-account-signer/src/__typetests__/wallet-account-message-signer-typetest.ts",
    "content": "import { MessageModifyingSigner } from '@solana/signers';\nimport { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { createMessageSignerFromWalletAccount } from '../wallet-account-message-signer';\n\nconst mockAccount = {\n    address: 'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy',\n    chains: ['solana:devnet'],\n    features: ['solana:signMessage'],\n} as unknown as UiWalletAccount;\n\n{\n    // [createMessageSignerFromWalletAccount]: It returns a MessageModifyingSigner with the correct address type.\n    const signer = createMessageSignerFromWalletAccount(mockAccount);\n    signer satisfies MessageModifyingSigner<typeof mockAccount.address>;\n}\n\n{\n    // [createMessageSignerFromWalletAccount]: It exposes a modifyAndSignMessages method.\n    const signer = createMessageSignerFromWalletAccount(mockAccount);\n    signer.modifyAndSignMessages satisfies MessageModifyingSigner['modifyAndSignMessages'];\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/src/__typetests__/wallet-account-transaction-sending-signer-typetest.ts",
    "content": "import { TransactionSendingSigner } from '@solana/signers';\nimport { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { createTransactionSendingSignerFromWalletAccount } from '../wallet-account-transaction-sending-signer';\n\nconst mockAccount = {\n    address: 'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy',\n    chains: ['solana:devnet'],\n    features: ['solana:signAndSendTransaction'],\n} as unknown as UiWalletAccount;\n\n{\n    // [createSendingSignerFromWalletAccount]: It returns a TransactionSendingSigner with the correct address type.\n    const signer = createTransactionSendingSignerFromWalletAccount(mockAccount, 'solana:devnet');\n    signer satisfies TransactionSendingSigner<typeof mockAccount.address>;\n}\n\n{\n    // [createSendingSignerFromWalletAccount]: It exposes a signAndSendTransactions method.\n    const signer = createTransactionSendingSignerFromWalletAccount(mockAccount, 'solana:devnet');\n    signer.signAndSendTransactions satisfies TransactionSendingSigner['signAndSendTransactions'];\n}\n\n{\n    // [createSendingSignerFromWalletAccount]: It accepts any solana chain identifier.\n    createTransactionSendingSignerFromWalletAccount(mockAccount, 'solana:mainnet');\n    createTransactionSendingSignerFromWalletAccount(mockAccount, 'solana:devnet');\n    createTransactionSendingSignerFromWalletAccount(mockAccount, 'solana:testnet');\n}\n\n{\n    // [createSendingSignerFromWalletAccount]: It accepts any non-Solana chain identifier.\n    createTransactionSendingSignerFromWalletAccount(mockAccount, 'l2:mainnet');\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/src/__typetests__/wallet-account-transaction-signer-typetest.ts",
    "content": "import { TransactionModifyingSigner } from '@solana/signers';\nimport { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { createTransactionSignerFromWalletAccount } from '../wallet-account-transaction-signer';\n\nconst mockAccount = {\n    address: 'Gp7YgHcJciP4px5FdFnywUiMG4UcfMZV9UagSAZzDxdy',\n    chains: ['solana:devnet'],\n    features: ['solana:signTransaction'],\n} as unknown as UiWalletAccount;\n\n{\n    // [createSignerFromWalletAccount]: It returns a TransactionModifyingSigner with the correct address type.\n    const signer = createTransactionSignerFromWalletAccount(mockAccount, 'solana:devnet');\n    signer satisfies TransactionModifyingSigner<typeof mockAccount.address>;\n}\n\n{\n    // [createSignerFromWalletAccount]: It exposes a modifyAndSignTransactions method.\n    const signer = createTransactionSignerFromWalletAccount(mockAccount, 'solana:devnet');\n    signer.modifyAndSignTransactions satisfies TransactionModifyingSigner['modifyAndSignTransactions'];\n}\n\n{\n    // [createSignerFromWalletAccount]: It accepts any solana chain identifier.\n    createTransactionSignerFromWalletAccount(mockAccount, 'solana:mainnet');\n    createTransactionSignerFromWalletAccount(mockAccount, 'solana:devnet');\n    createTransactionSignerFromWalletAccount(mockAccount, 'solana:testnet');\n}\n\n{\n    // [createSignerFromWalletAccount]: It accepts any non-Solana chain identifier.\n    createTransactionSignerFromWalletAccount(mockAccount, 'l2:mainnet');\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/src/index.ts",
    "content": "/**\n * This package contains functions for converting from [Wallet Standard](https://github.com/wallet-standard/wallet-standard)\n * accounts on Solana chains, to Kit Signer objects.\n * Note that this package has dependencies on Wallet Standard packages.\n *\n * @packageDocumentation\n */\nexport * from './wallet-account-message-signer';\nexport * from './wallet-account-signer';\nexport * from './wallet-account-transaction-sending-signer';\nexport * from './wallet-account-transaction-signer';\n"
  },
  {
    "path": "packages/wallet-account-signer/src/wallet-account-message-signer.ts",
    "content": "import type { Address } from '@solana/addresses';\nimport { address } from '@solana/addresses';\nimport { bytesEqual } from '@solana/codecs-core';\nimport type { SignatureBytes } from '@solana/keys';\nimport { getAbortablePromise } from '@solana/promises';\nimport type { MessageModifyingSigner, SignableMessage } from '@solana/signers';\nimport { SolanaSignMessage, SolanaSignMessageFeature } from '@solana/wallet-standard-features';\nimport { getWalletAccountFeature, UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\n\n/**\n * Creates a {@link MessageModifyingSigner} from a {@link UiWalletAccount}.\n *\n * This function provides a bridge between wallet-standard {@link UiWalletAccount} and the\n * {@link MessageModifyingSigner} interface, allowing any wallet that implements the\n * `solana:signMessage` feature to be used as a message signer.\n *\n * @param uiWalletAccount - The wallet account to create a signer from.\n * @returns A {@link MessageModifyingSigner} that signs messages using the wallet.\n *\n * @example\n * ```ts\n * import { createMessageSignerFromWalletAccount } from '@solana/wallet-account-signer';\n * import { createSignableMessage } from '@solana/signers';\n *\n * const signer = createMessageSignerFromWalletAccount(walletAccount);\n * const message = createSignableMessage(new Uint8Array([1, 2, 3]));\n * const [signedMessage] = await signer.modifyAndSignMessages([message]);\n * const signature = signedMessage.signatures[signer.address];\n * ```\n *\n * @see {@link MessageModifyingSigner}\n * @see {@link SignableMessage}\n */\nexport function createMessageSignerFromWalletAccount<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n): MessageModifyingSigner<TWalletAccount['address']> {\n    const signMessageFeature = getWalletAccountFeature(\n        uiWalletAccount,\n        SolanaSignMessage,\n    ) as SolanaSignMessageFeature[typeof SolanaSignMessage];\n\n    const account = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);\n\n    return {\n        address: address(uiWalletAccount.address),\n        async modifyAndSignMessages(messages, config = {}) {\n            const { abortSignal } = config;\n            abortSignal?.throwIfAborted();\n\n            if (messages.length === 0) {\n                return messages;\n            }\n\n            const inputs = messages.map(message => ({\n                account,\n                message: message.content,\n            }));\n\n            const outputs = await getAbortablePromise(signMessageFeature.signMessage(...inputs), abortSignal);\n\n            const results = outputs.map((output, index) => {\n                const originalMessage = messages[index];\n                const { signedMessage, signature } = output;\n\n                // Check if message was modified\n                const messageWasModified =\n                    originalMessage.content.length !== signedMessage.length ||\n                    originalMessage.content.some((originalByte, ii) => originalByte !== signedMessage[ii]);\n\n                // Check if signature is new\n                const originalSignature = originalMessage.signatures[uiWalletAccount.address as Address<string>] as\n                    | SignatureBytes\n                    | undefined;\n                const signatureIsNew = originalSignature === undefined || !bytesEqual(originalSignature, signature);\n\n                // Identity preservation: no changes at all\n                if (!signatureIsNew && !messageWasModified) {\n                    return originalMessage;\n                }\n\n                // Signature dictionary logic\n                const nextSignatureMap = messageWasModified\n                    ? { [uiWalletAccount.address]: signature }\n                    : { ...originalMessage.signatures, [uiWalletAccount.address]: signature };\n\n                return Object.freeze({\n                    content: signedMessage,\n                    signatures: Object.freeze(nextSignatureMap),\n                }) as SignableMessage;\n            });\n\n            return results;\n        },\n    };\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/src/wallet-account-signer.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION, SolanaError } from '@solana/errors';\nimport type { MessageSigner, TransactionSigner } from '@solana/signers';\nimport { SolanaChain } from '@solana/wallet-standard-chains';\nimport {\n    SolanaSignAndSendTransaction,\n    SolanaSignMessage,\n    SolanaSignTransaction,\n} from '@solana/wallet-standard-features';\nimport { IdentifierString } from '@wallet-standard/base';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport { UiWalletAccount } from '@wallet-standard/ui';\n\nimport { createMessageSignerFromWalletAccount } from './wallet-account-message-signer';\nimport { createTransactionSendingSignerFromWalletAccount } from './wallet-account-transaction-sending-signer';\nimport { createTransactionSignerFromWalletAccount } from './wallet-account-transaction-signer';\n\n/**\n * Creates a combined signer from a {@link UiWalletAccount} that exposes all signing capabilities\n * the wallet account supports.\n *\n * Unlike the more specific helpers ({@link createTransactionSignerFromWalletAccount},\n * {@link createTransactionSendingSignerFromWalletAccount},\n * {@link createMessageSignerFromWalletAccount}), this function inspects the wallet account's\n * features at call time and returns a single signer object with whichever of the following methods\n * are available:\n *\n * - `modifyAndSignTransactions` — present when the `solana:signTransaction` feature is available.\n * - `signAndSendTransactions` — present when the `solana:signAndSendTransaction` feature is available.\n * - `modifyAndSignMessages` — present when the `solana:signMessage` feature is available.\n *\n * At least one of `solana:signTransaction` or `solana:signAndSendTransaction` must be present,\n * otherwise an error is thrown. `solana:signMessage` is optional.\n *\n * @param uiWalletAccount - The wallet account to create a signer from.\n * @param chain - The Solana chain identifier (e.g., `'solana:devnet'`, `'solana:mainnet'`).\n * @returns A {@link TransactionSigner}, optionally combined with a {@link MessageSigner}, depending\n * on the features available on the wallet account.\n *\n * @throws {WalletStandardError} If the wallet account does not support the specified chain.\n * @throws {WalletStandardError} If the wallet account supports neither `solana:signTransaction`\n * nor `solana:signAndSendTransaction`.\n *\n * @example\n * ```ts\n * import { createSignerFromWalletAccount } from '@solana/wallet-account-signer';\n * import { isMessageSigner } from '@solana/signers';\n *\n * const signer = createSignerFromWalletAccount(walletAccount, 'solana:devnet');\n *\n * // Sign a transaction (always available — at least one tx feature must exist)\n * if ('modifyAndSignTransactions' in signer) {\n *     const [signedTransaction] = await signer.modifyAndSignTransactions([transaction]);\n * }\n *\n * // Also sign messages if the wallet supports it\n * if (isMessageSigner(signer)) {\n *     const [signedMessage] = await signer.modifyAndSignMessages([message]);\n * }\n * ```\n *\n * @see {@link createTransactionSignerFromWalletAccount}\n * @see {@link createTransactionSendingSignerFromWalletAccount}\n * @see {@link createMessageSignerFromWalletAccount}\n */\nexport function createSignerFromWalletAccount<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: SolanaChain | (IdentifierString & {}),\n):\n    | TransactionSigner<TWalletAccount['address']>\n    | (MessageSigner<TWalletAccount['address']> & TransactionSigner<TWalletAccount['address']>) {\n    if (!uiWalletAccount.chains.includes(chain)) {\n        throw new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n            address: uiWalletAccount.address,\n            chain,\n            featureName: SolanaSignTransaction,\n            supportedChains: uiWalletAccount.chains as string[],\n            supportedFeatures: uiWalletAccount.features as string[],\n        });\n    }\n\n    const features = uiWalletAccount.features;\n    const hasSignTransaction = features.includes(SolanaSignTransaction);\n    const hasSignAndSendTransaction = features.includes(SolanaSignAndSendTransaction);\n    const hasSignMessage = features.includes(SolanaSignMessage);\n\n    if (!hasSignTransaction && !hasSignAndSendTransaction) {\n        throw new SolanaError(SOLANA_ERROR__SIGNER__WALLET_ACCOUNT_CANNOT_SIGN_TRANSACTION, {\n            address: uiWalletAccount.address,\n            supportedFeatures: features as string[],\n        });\n    }\n\n    const signer: Record<string, unknown> = {\n        address: address(uiWalletAccount.address),\n    };\n\n    if (hasSignTransaction) {\n        const { modifyAndSignTransactions } = createTransactionSignerFromWalletAccount(uiWalletAccount, chain);\n        signer['modifyAndSignTransactions'] = modifyAndSignTransactions;\n    }\n\n    if (hasSignAndSendTransaction) {\n        const { signAndSendTransactions } = createTransactionSendingSignerFromWalletAccount(uiWalletAccount, chain);\n        signer['signAndSendTransactions'] = signAndSendTransactions;\n    }\n\n    if (hasSignMessage) {\n        const { modifyAndSignMessages } = createMessageSignerFromWalletAccount(uiWalletAccount);\n        signer['modifyAndSignMessages'] = modifyAndSignMessages;\n    }\n\n    return Object.freeze(signer) as\n        | TransactionSigner<TWalletAccount['address']>\n        | (MessageSigner<TWalletAccount['address']> & TransactionSigner<TWalletAccount['address']>);\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/src/wallet-account-transaction-sending-signer.ts",
    "content": "import { address } from '@solana/addresses';\nimport { SignatureBytes } from '@solana/keys';\nimport { getAbortablePromise } from '@solana/promises';\nimport { TransactionSendingSigner } from '@solana/signers';\nimport { getTransactionEncoder } from '@solana/transactions';\nimport { SolanaChain } from '@solana/wallet-standard-chains';\nimport { SolanaSignAndSendTransaction, SolanaSignAndSendTransactionFeature } from '@solana/wallet-standard-features';\nimport { IdentifierString } from '@wallet-standard/base';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport { getWalletAccountFeature, UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\n\n/**\n * Creates a {@link TransactionSendingSigner} from a {@link UiWalletAccount}.\n *\n * This function provides a bridge between wallet-standard {@link UiWalletAccount} and the\n * {@link TransactionSendingSigner} interface, allowing any wallet that implements the\n * `solana:signAndSendTransaction` feature to sign and send transactions.\n *\n * @param uiWalletAccount - The wallet account to create a signer from.\n * @param chain - The Solana chain identifier (e.g., 'solana:devnet', 'solana:mainnet').\n * @returns A {@link TransactionSendingSigner} that signs and sends transactions using the wallet.\n *\n * @throws {WalletStandardError} If the wallet account does not support the specified chain.\n *\n * @example\n * ```ts\n * import { createTransactionSendingSignerFromWalletAccount } from '@solana/wallet-account-signer';\n *\n * const signer = createTransactionSendingSignerFromWalletAccount(walletAccount, 'solana:devnet');\n * const [signature] = await signer.signAndSendTransactions([transaction]);\n * ```\n *\n * @see {@link TransactionSendingSigner}\n * @see {@link createTransactionSignerFromWalletAccount}\n */\nexport function createTransactionSendingSignerFromWalletAccount<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: SolanaChain | (IdentifierString & {}),\n): TransactionSendingSigner<TWalletAccount['address']> {\n    if (!uiWalletAccount.chains.includes(chain)) {\n        throw new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n            address: uiWalletAccount.address,\n            chain,\n            featureName: SolanaSignAndSendTransaction,\n            supportedChains: uiWalletAccount.chains as string[],\n            supportedFeatures: uiWalletAccount.features as string[],\n        });\n    }\n\n    const feature = getWalletAccountFeature(\n        uiWalletAccount,\n        SolanaSignAndSendTransaction,\n    ) as SolanaSignAndSendTransactionFeature[typeof SolanaSignAndSendTransaction];\n\n    const walletAccount = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);\n\n    const transactionEncoder = getTransactionEncoder();\n\n    return {\n        address: address(uiWalletAccount.address),\n\n        async signAndSendTransactions(transactions, config = {}) {\n            const { abortSignal, ...options } = config;\n            abortSignal?.throwIfAborted();\n            if (transactions.length === 0) {\n                return [];\n            }\n\n            const inputs = transactions.map(transaction => {\n                const wiredTransactionBytes = transactionEncoder.encode(transaction);\n\n                return {\n                    account: walletAccount,\n                    chain,\n                    transaction: wiredTransactionBytes as Uint8Array,\n                    ...(options?.minContextSlot != null\n                        ? {\n                              options: {\n                                  minContextSlot: Number(options.minContextSlot),\n                              },\n                          }\n                        : null),\n                };\n            });\n\n            const outputs = await getAbortablePromise(feature.signAndSendTransaction(...inputs), abortSignal);\n\n            return outputs.map(o => o.signature as SignatureBytes);\n        },\n    };\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/src/wallet-account-transaction-signer.ts",
    "content": "import { address } from '@solana/addresses';\nimport { bytesEqual } from '@solana/codecs-core';\nimport { getAbortablePromise } from '@solana/promises';\nimport { TransactionModifyingSigner } from '@solana/signers';\nimport { getCompiledTransactionMessageDecoder } from '@solana/transaction-messages';\nimport {\n    assertIsTransactionWithinSizeLimit,\n    getTransactionCodec,\n    getTransactionLifetimeConstraintFromCompiledTransactionMessage,\n    Transaction,\n    TransactionWithinSizeLimit,\n    TransactionWithLifetime,\n} from '@solana/transactions';\nimport { SolanaChain } from '@solana/wallet-standard-chains';\nimport { SolanaSignTransaction, SolanaSignTransactionFeature } from '@solana/wallet-standard-features';\nimport { IdentifierString } from '@wallet-standard/base';\nimport {\n    WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED,\n    WalletStandardError,\n} from '@wallet-standard/errors';\nimport { getWalletAccountFeature, UiWalletAccount } from '@wallet-standard/ui';\nimport { getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED } from '@wallet-standard/ui-registry';\n\n/**\n * Creates a {@link TransactionModifyingSigner} from a {@link UiWalletAccount}.\n *\n * This function provides a bridge between wallet-standard {@link UiWalletAccount} and the\n * {@link TransactionModifyingSigner} interface, allowing any wallet that implements the\n * `solana:signTransaction` feature to be used as a transaction signer.\n *\n * @param uiWalletAccount - The wallet account to create a signer from.\n * @param chain - The Solana chain identifier (e.g., 'solana:devnet', 'solana:mainnet').\n * @returns A {@link TransactionModifyingSigner} that signs transactions using the wallet.\n *\n * @throws {WalletStandardError} If the wallet account does not support the specified chain.\n *\n * @example\n * ```ts\n * import { createTransactionSignerFromWalletAccount } from '@solana/wallet-account-signer';\n *\n * const signer = createTransactionSignerFromWalletAccount(walletAccount, 'solana:devnet');\n * const [signedTransaction] = await signer.modifyAndSignTransactions([transaction]);\n * ```\n *\n * @see {@link TransactionModifyingSigner}\n * @see {@link createTransactionSendingSignerFromWalletAccount}\n */\nexport function createTransactionSignerFromWalletAccount<TWalletAccount extends UiWalletAccount>(\n    uiWalletAccount: TWalletAccount,\n    chain: SolanaChain | (IdentifierString & {}),\n): TransactionModifyingSigner<TWalletAccount['address']> {\n    if (!uiWalletAccount.chains.includes(chain)) {\n        throw new WalletStandardError(WALLET_STANDARD_ERROR__FEATURES__WALLET_ACCOUNT_CHAIN_UNSUPPORTED, {\n            address: uiWalletAccount.address,\n            chain,\n            featureName: SolanaSignTransaction,\n            supportedChains: uiWalletAccount.chains as string[],\n            supportedFeatures: uiWalletAccount.features as string[],\n        });\n    }\n    const signTransactionFeature = getWalletAccountFeature(\n        uiWalletAccount,\n        SolanaSignTransaction,\n    ) as SolanaSignTransactionFeature[typeof SolanaSignTransaction];\n    const account = getWalletAccountForUiWalletAccount_DO_NOT_USE_OR_YOU_WILL_BE_FIRED(uiWalletAccount);\n\n    const transactionCodec = getTransactionCodec();\n\n    return {\n        address: address(uiWalletAccount.address),\n        async modifyAndSignTransactions(transactions, config = {}) {\n            const { abortSignal, ...options } = config;\n            abortSignal?.throwIfAborted();\n            if (transactions.length === 0) {\n                return transactions as readonly (Transaction & TransactionWithinSizeLimit & TransactionWithLifetime)[];\n            }\n\n            const inputs = transactions.map(transaction => ({\n                account: account,\n                chain,\n                transaction: transactionCodec.encode(transaction) as Uint8Array,\n                ...(options?.minContextSlot != null\n                    ? {\n                          options: {\n                              minContextSlot: Number(options.minContextSlot),\n                          },\n                      }\n                    : null),\n            }));\n\n            const outputs = await getAbortablePromise(signTransactionFeature.signTransaction(...inputs), abortSignal);\n\n            const results = await getAbortablePromise(\n                Promise.all(\n                    outputs.map(async ({ signedTransaction }, index) => {\n                        const decodedSignedTransaction = transactionCodec.decode(\n                            signedTransaction,\n                        ) as (typeof transactions)[number];\n\n                        assertIsTransactionWithinSizeLimit(decodedSignedTransaction);\n\n                        const inputTransaction = transactions[index];\n                        const existingLifetime =\n                            inputTransaction && 'lifetimeConstraint' in inputTransaction\n                                ? (inputTransaction as TransactionWithLifetime).lifetimeConstraint\n                                : undefined;\n\n                        // Fast path: identical bytes means the lifetime hasn't changed\n                        if (\n                            existingLifetime &&\n                            bytesEqual(decodedSignedTransaction.messageBytes, inputTransaction.messageBytes)\n                        ) {\n                            return Object.freeze({\n                                ...decodedSignedTransaction,\n                                lifetimeConstraint: existingLifetime,\n                            });\n                        }\n\n                        // Decode once to inspect the lifetime token\n                        const compiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(\n                            decodedSignedTransaction.messageBytes,\n                        );\n\n                        // If the token matches the existing lifetime, reuse it\n                        if (existingLifetime) {\n                            const currentToken =\n                                'blockhash' in existingLifetime ? existingLifetime.blockhash : existingLifetime.nonce;\n                            if (compiledTransactionMessage.lifetimeToken === currentToken) {\n                                return Object.freeze({\n                                    ...decodedSignedTransaction,\n                                    lifetimeConstraint: existingLifetime,\n                                });\n                            }\n                        }\n\n                        // No existing lifetime or it has changed — fetch a new one\n                        const lifetimeConstraint =\n                            await getTransactionLifetimeConstraintFromCompiledTransactionMessage(\n                                compiledTransactionMessage,\n                            );\n                        return Object.freeze({\n                            ...decodedSignedTransaction,\n                            lifetimeConstraint,\n                        });\n                    }),\n                ),\n                abortSignal,\n            );\n\n            return results;\n        },\n    };\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2019.Array\", \"ES2020.BigInt\", \"ES2022.Error\"]\n    },\n    \"display\": \"@solana/wallet-account-signer\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/wallet-account-signer/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/.gitignore",
    "content": ".docs/\ndist/\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/CHANGELOG.md",
    "content": "# @solana/webcrypto-ed25519-polyfill\n\n## 6.9.0\n\n### Minor Changes\n\n- [#1562](https://github.com/anza-xyz/kit/pull/1562) [`096c48e`](https://github.com/anza-xyz/kit/commit/096c48e6771ad7ea833cb4ca51206b7cc827a3d7) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Bump the TypeScript peer dependency floor from `>=5.0.0` to `>=5.4.0`.\n\n## 6.8.0\n\n### Patch Changes\n\n- [#1532](https://github.com/anza-xyz/kit/pull/1532) [`667a0f0`](https://github.com/anza-xyz/kit/commit/667a0f059f5432244ab2cf8a23a22f53c7a36b4b) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Update the TypeScript peer dependency from `^5.0.0` to `>=5.0.0` to allow TypeScript 6 and above.\n\n## 6.7.0\n\n## 6.6.0\n\n## 6.5.0\n\n## 6.4.0\n\n## 6.3.1\n\n## 6.3.0\n\n## 6.2.0\n\n## 6.1.0\n\n## 6.0.1\n\n## 6.0.0\n\n## 5.5.1\n\n## 5.5.0\n\n## 5.4.0\n\n### Patch Changes\n\n- [#1187](https://github.com/anza-xyz/kit/pull/1187) [`f5f89eb`](https://github.com/anza-xyz/kit/commit/f5f89eb8e769d5b6056b2f686d51a7ef4a0d1d09) Thanks [@mcintyre94](https://github.com/mcintyre94)! - Make Typescript peer dependency optional + reduce required version to ^5\n\n## 5.3.0\n\n## 5.2.0\n\n## 5.1.0\n\n## 5.0.0\n\n## 4.0.0\n\n### Patch Changes\n\n- [#806](https://github.com/anza-xyz/kit/pull/806) [`f254415`](https://github.com/anza-xyz/kit/commit/f2544155f410019b63eb2cb7d02b2a3d22580516) Thanks [@steveluscher](https://github.com/steveluscher)! - The Ed25519 polyfill now correctly returns `ArrayBuffer` from `exportKey()` and `sign()` rather than `Uint8Array`\n\n## 3.0.0\n\n## 2.3.0\n\n## 2.2.1\n\n## 2.2.0\n\n## 2.1.1\n\n### Patch Changes\n\n- [#473](https://github.com/anza-xyz/kit/pull/473) [`36a9dee`](https://github.com/anza-xyz/kit/commit/36a9dee4e6cbd72020dc74777fe394130b9a5f46) Thanks [@steveluscher](https://github.com/steveluscher)! - The identity of all branded types has changed in such a way that the types from v2.1.1 will be compatible with any other version going forward, which is not the case for versions v2.1.0 and before.\n\n    If you end up with a mix of versions in your project prior to v2.1.1 (eg. `@solana/addresses@2.0.0` and `@solana/addresses@2.1.0`) you may discover that branded types like `Address` raise a type error, even though they are runtime compatible. Your options are:\n    1. Always make sure that you have exactly one instance of each `@solana/*` dependency in your project at any given time\n    2. Upgrade all of your `@solana/*` dependencies to v2.1.1 at minimum, even if their minor or patch versions differ.\n    3. Suppress the type errors using a comment like the following:\n        ```ts\n        const myAddress = address('1234..5678'); // from @solana/addresses@2.0.0\n        const myAccount = await fetchEncodedAccount(\n            // imports @solana/addresses@2.1.0\n            rpc,\n            // @ts-expect-error Address types mismatch between installed versions of @solana/addresses\n            myAddress,\n        );\n        ```\n\n- [#236](https://github.com/anza-xyz/kit/pull/236) [`ca1d4ec`](https://github.com/anza-xyz/kit/commit/ca1d4ec7ddd641ca813f79f8ca06d225f29419e2) Thanks [@steveluscher](https://github.com/steveluscher)! - The minimum TypeScript version is now 5.3.3\n\n## 2.1.0\n\n### Patch Changes\n\n- [`1adf435`](https://github.com/anza-xyz/kit/commit/1adf435cfc724303f64e509a6fda144ec8f5019d) Thanks [@leantOnSol](https://github.com/leantOnSol)! - A two-versions-old version of Node LTS is now specified everywhere via the `engines` field, including the one in the root of the `pnpm` workspace, and engine-strictness is delegated to the `.npmrc` files.\n\n- [#59](https://github.com/anza-xyz/kit/pull/59) [`710e571`](https://github.com/anza-xyz/kit/commit/710e5719195b95e0ad3ebdd7c6c005c7a8e5d306) Thanks [@steveluscher](https://github.com/steveluscher)! - Fixed a bug where specifying `Ed25519` in a different case, or as an object `{ name: 'Ed25519' }` would cause key operations to be delegated to the underlying runtime instead of the polyfill\n\n## 2.0.0\n\n### Patch Changes\n\n- [#3063](https://github.com/solana-labs/solana-web3.js/pull/3063) [`ae9e8d3`](https://github.com/solana-labs/solana-web3.js/commit/ae9e8d342740598d2dfc90e11c19aa9af520c1c4) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add support for exporting keys as JWK\n\n- [#3541](https://github.com/solana-labs/solana-web3.js/pull/3541) [`135dc5a`](https://github.com/solana-labs/solana-web3.js/commit/135dc5ad43f286380a4c3a689668016f0d7945f4) Thanks [@steveluscher](https://github.com/steveluscher)! - Drop the Release Candidate label and publish `@solana/web3.js` at version 2.0.0\n\n- [#3064](https://github.com/solana-labs/solana-web3.js/pull/3064) [`2370096`](https://github.com/solana-labs/solana-web3.js/commit/237009609fbc0ae32eb9628d08a41f06229ac6d2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add support for importing JWK keys\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.4\n\n## 2.0.0-rc.3\n\n## 2.0.0-rc.2\n\n### Patch Changes\n\n- [#3137](https://github.com/solana-labs/solana-web3.js/pull/3137) [`fd72c2e`](https://github.com/solana-labs/solana-web3.js/commit/fd72c2ed1edad488318fa5d3e285f04852f4210a) Thanks [@mcintyre94](https://github.com/mcintyre94)! - The build is now compatible with the Vercel Edge runtime and Cloudflare Workers through the addition of `edge-light` and `workerd` to the package exports.\n\n## 2.0.0-rc.1\n\n### Patch Changes\n\n- [#3063](https://github.com/solana-labs/solana-web3.js/pull/3063) [`ae9e8d3`](https://github.com/solana-labs/solana-web3.js/commit/ae9e8d342740598d2dfc90e11c19aa9af520c1c4) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add support for exporting keys as JWK\n\n- [#3064](https://github.com/solana-labs/solana-web3.js/pull/3064) [`2370096`](https://github.com/solana-labs/solana-web3.js/commit/237009609fbc0ae32eb9628d08a41f06229ac6d2) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Add support for importing JWK keys\n\n## 2.0.0-rc.0\n\n### Patch Changes\n\n- [#2907](https://github.com/solana-labs/solana-web3.js/pull/2907) [`677a9c4`](https://github.com/solana-labs/solana-web3.js/commit/677a9c4eb88a8ac6a9ede8d82f367c5ac8d69ff4) Thanks [@steveluscher](https://github.com/steveluscher)! - `__DEV__` mode will now be the default if you don't set `process.env.NODE_ENV` at all. This means fewer people ‘accidentally’ finding themselves in production mode with minified error messages.\n\n## 2.0.0-preview.4\n\n### Patch Changes\n\n- [#2606](https://github.com/solana-labs/solana-web3.js/pull/2606) [`367b8ad`](https://github.com/solana-labs/solana-web3.js/commit/367b8ad0cce55a916abfb0125f36b6e844333b2b) Thanks [@lorisleiva](https://github.com/lorisleiva)! - Use commonjs package type\n\n## 2.0.0-preview.3\n\n## 2.0.0-preview.2\n\n### Patch Changes\n\n- The first Technology Preview of `@solana/web3.js` 2.0 was [released at the Breakpoint conference](https://www.youtube.com/watch?v=JUJtAPhES5g) in November 2023. Based on your feedback, we want to get a second version of it into your hands now with some changes, bug fixes, and new features.\n\n    To install the second Technology Preview:\n\n    ```shell\n    npm install --save @solana/web3.js@tp2\n    ```\n\n    Most notably, this release integrates with the new JavaScript client generator for on-chain programs. Instruction creators and account decoders can now be autogenerated for any program, including your own! Read more [here](https://github.com/solana-program/create-solana-program), and check out the growing list of autogenerated core programs [here](https://www.npmjs.com/search?q=%40solana-program).\n\n    Try a demo of Technology Preview 2 in your browser at https://sola.na/web3tp2demo.\n    - Renamed `Base58EncodedAddress` to `Address` (#1814) [63683a4bc](https://github.com/solana-labs/solana-web3.js/commit/63683a4bc)\n    - Renamed `Ed25519Signature` and `TransactionSignature` to `SignatureBytes` and `Signature` (#1815) [205c09268](https://github.com/solana-labs/solana-web3.js/commit/205c09268)\n    - Fixed return type of `getSignaturesForAddress` (#1821) [36c7263bd](https://github.com/solana-labs/solana-web3.js/commit/36c7263bd)\n    - `signTransaction` now asserts that the transaction is fully signed; added `partiallySignTransaction` that does not (#1820) [7d54c2dad](https://github.com/solana-labs/solana-web3.js/commit/7d54c2dad)\n    - The `@solana/webcrypto-ed25519-polyfill` now sets the `crypto` global in Node [17a54d24a](https://github.com/solana-labs/solana-web3.js/commit/17a54d24a)\n    - Added `assertIsBlockhashLifetimeTransaction` that asserts transaction has a blockhash lifetime (#1908) [ae94ca38d](https://github.com/solana-labs/solana-web3.js/commit/ae94ca38d)\n    - Added a `createPrivateKeyFromBytes` helper (#1913) [85b7dfe13](https://github.com/solana-labs/solana-web3.js/commit/85b7dfe13)\n    - Added `@solana/accounts`; types and helper methods for representing, fetching and decoding Solana accounts (#1855) [e1ca3966e](https://github.com/solana-labs/solana-web3.js/commit/e1ca3966e)\n    - Export the TransactionError type (#1964) [4c009bf5b](https://github.com/solana-labs/solana-web3.js/commit/4c009bf5b)\n    - Export all RPC method XApi types from `@solana/rpc-core` (#1965) [ed98b3d9c](https://github.com/solana-labs/solana-web3.js/commit/ed98b3d9c)\n    - Added a generic `createJsonRpcApi` function for custom APIs [1e2106f21](https://github.com/solana-labs/solana-web3.js/commit/1e2106f21)\n    - Added a generic `createJsonRpcSubscriptionsApi` function for custom APIs [ae3f1f087](https://github.com/solana-labs/solana-web3.js/commit/ae3f1f087)\n    - RPC commitment now defaults to `confirmed` when not explicitly specified [cb7702ca5](https://github.com/solana-labs/solana-web3.js/commit/cb7702ca5)\n    - Added `ClusterUrl` types and handlers (#2084) [61f7ba0](https://github.com/solana-labs/solana-web3.js/commit/61f7ba0)\n    - RPC transports can now be cluster-specific, ie. `RpcDevnet<TRpcMethods>` & `RpcSubscriptionsDevnet<TRpcMethods>` (#2053) [e58bb22](https://github.com/solana-labs/solana-web3.js/commit/e58bb22), (#2056) [cbf8f38](https://github.com/solana-labs/solana-web3.js/commit/cbf8f38)\n    - RPC APIs can now be cluster-specific, ie. `SolanaRpcMethodsDevnet` (#2054) [5175d8a](https://github.com/solana-labs/solana-web3.js/commit/5175d8a)\n    - Added cluster-level RPC support for `@solana/web3.js` (#2055) [5a6335d](https://github.com/solana-labs/solana-web3.js/commit/5a6335d), (#2058) [0e03ca9](https://github.com/solana-labs/solana-web3.js/commit/0e03ca9)\n    - Added `@solana/signers`; an abstraction layer over signing messages and transactions in Solana (#1710) [7c29a1e](https://github.com/solana-labs/solana-web3.js/commit/7c29a1e)\n    - Updated codec such that only one instance of `Uint8Array` is created when encoding data. This allows `Encoders` to set data at different offsets and therefore enables non-linear serialization (#1865) [7800e3b](https://github.com/solana-labs/solana-web3.js/commit/7800e3b)\n    - Added `FixedSize*` and `VariableSize*` type variants for `Codecs`, `Encoders` and `Decoders` (#1883) [5e58d5c](https://github.com/solana-labs/solana-web3.js/commit/5e58d5c)\n    - Repaired some inaccurate RPC method signatures (#2137) [bb65ba9](https://github.com/solana-labs/solana-web3.js/commit/bb65ba9)\n    - Renamed transaction/airdrop sender factories with the ‘Factory’ suffix (#2130) [2d1d49c](https://github.com/solana-labs/solana-web3.js/commit/2d1d49c5467e5cb13871067c3dc0f9c87f007b9f)\n    - All code now throws coded exceptions defined in `@solana/errors` which can be refined using `isSolanaError()` and decoded in production using `npx @solana/errors decode` (#2160) [3524f2c](https://github.com/solana-labs/solana-web3.js/commit/3524f2c583dbc663cf6dcb73a01b0beed6cfd136), (#2161) [94944b](https://github.com/solana-labs/solana-web3.js/commit/94944b65b9d957ca95653d66dc1f4805f1a36740), (#2213) [8541c2e](https://github.com/solana-labs/solana-web3.js/commit/8541c2ef860535514fa39c4b9a6a75276417ffaa), (#2220) [c9b2705](https://github.com/solana-labs/solana-web3.js/commit/c9b2705318724bbccb05efdb1ddc088dd82921b2), (#2207) [75a18e3](https://github.com/solana-labs/solana-web3.js/commit/75a18e30524078ea1e8c07133fd6c75fad357db3), (#2224) [613053d](https://github.com/solana-labs/solana-web3.js/commit/613053deab85e5a8703e241ab138ec51cc54885a), (#2226) [94fee67](https://github.com/solana-labs/solana-web3.js/commit/94fee67560faae1f41aeddb2e7c3d0d9078ab851), (#2228) [483c674](https://github.com/solana-labs/solana-web3.js/commit/483c674a8b19f146c7dba5f1eb64182f01fdcdc4), (#2235) [803b2d8](https://github.com/solana-labs/solana-web3.js/commit/803b2d88e9e39cecf18f03b2130507dea7230423), (#2236) [cf9c20c](https://github.com/solana-labs/solana-web3.js/commit/cf9c20ceed7186f5af704ee646344c42d4ec0084), (#2242) [9084fdd](https://github.com/solana-labs/solana-web3.js/commit/9084fddec79eebb9c00c70738e43b4bfb01bf352), (#2245) [e374ac6](https://github.com/solana-labs/solana-web3.js/commit/e374ac67ad48a121470d125a1d08485b8b529b2b), (#2186) [546263e](https://github.com/solana-labs/solana-web3.js/commit/546263e251c8a7b08949b01d0d51fa2398dc7fff), (#2187) [bea19d2](https://github.com/solana-labs/solana-web3.js/commit/bea19d209ea6b02351c21a878200f87da1e9b4be), (#2188) [2e0ae95](https://github.com/solana-labs/solana-web3.js/commit/2e0ae95ffc2738ae047249c7f64c46a95e9573d1), (#2189) [7712fc3](https://github.com/solana-labs/solana-web3.js/commit/7712fc32ef33bfe7f235d85d3ba2308ba6884143), (#2190) [7d67615](https://github.com/solana-labs/solana-web3.js/commit/7d67615ac1ae771810dfc544ecc17d664a0fc11d), (#2191) [0ba8f21](https://github.com/solana-labs/solana-web3.js/commit/0ba8f216d962d61e0f653404c4a9289e59712cc2), (#2192) [91a360d](https://github.com/solana-labs/solana-web3.js/commit/91a360daf5c66ac0f1bae7347298f25ae89329b2), (#2202) [a71a2db](https://github.com/solana-labs/solana-web3.js/commit/a71a2db4c35136c8650b56985bbd33c5413e1bbd), (#2286) [52a5d3d](https://github.com/solana-labs/solana-web3.js/commit/52a5d3db60e702ccf77b4d17b8a3fd388e6e8584), and more\n    - You can now supply a custom Undici dispatcher for use with the `fetch` API when creating an RPC transport in Node (#2178) [a2fc5a3](https://github.com/solana-labs/solana-web3.js/commit/a2fc5a3fda252cccc6ee62f2f7163d1578a20113)\n    - Added functions to assert a value is an `IInstructionWithAccounts` and IInstructionWithData` (#2212) [07c30c1](https://github.com/solana-labs/solana-web3.js/commit/07c30c14c7d5efd6121290db62fa40371f108778)\n    - Added a function to assert an instruction is for a given program (#2234) [fb655dd](https://github.com/solana-labs/solana-web3.js/commit/fb655ddd217e4c4f55c5c8a81a08177e20ef5431)\n    - You can now create an RPC using only a URL (#2238) [cd0b6c6](https://github.com/solana-labs/solana-web3.js/commit/cd0b6c616ded7d1fdee33e33d3e44ce9bce48cef), (#2239) [fc11993](https://github.com/solana-labs/solana-web3.js/commit/fc119937ade7e46f487c99f254ff5a874e524c2c)\n    - You can now resize codec with the `resizeCodec` helper (#2293) [606de63](https://github.com/solana-labs/solana-web3.js/commit/606de638e21eebd0535806dee445e6d046cfb074)\n    - You can now skip bytes while writing byte buffers using the `offsetCodec` helper (#2294) [09d8cc8](https://github.com/solana-labs/solana-web3.js/commit/09d8cc815d133d70da0db93c9a0c0092e0d9a929)\n    - You can now now pad the beginning or end of byte buffers using the `padLeftCodec` and `padRightCodec` helpers (#2314) [f9509c7](https://github.com/solana-labs/solana-web3.js/commit/f9509c77dd6ec92357edbbe18acbb76c5a33e4b2)\n    - Added a new `@solana/sysvars` package for fetching, decoding, and building transactions with sysvar accounts (#2041)\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/README.md",
    "content": "[![npm][npm-image]][npm-url]\n[![npm-downloads][npm-downloads-image]][npm-url]\n<br />\n[![code-style-prettier][code-style-prettier-image]][code-style-prettier-url]\n\n[code-style-prettier-image]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square\n[code-style-prettier-url]: https://github.com/prettier/prettier\n[npm-downloads-image]: https://img.shields.io/npm/dm/@solana/webcrypto-ed25519-polyfill?style=flat\n[npm-image]: https://img.shields.io/npm/v/@solana/webcrypto-ed25519-polyfill?style=flat\n[npm-url]: https://www.npmjs.com/package/@solana/webcrypto-ed25519-polyfill\n\n# @solana/webcrypto-ed25519-polyfill\n\nThis package contains a polyfill that enables Ed25519 key manipulation in environments where it is not yet implemented. It does so by proxying calls to `SubtleCrypto` instance methods to an Ed25519 implementation in userspace.\n\n> [!WARNING]\n> Because this package's implementation of Ed25519 key generation exists in userspace, it can't guarantee that the keys you generate with it are non-exportable. Untrusted code running in your JavaScript context may still be able to gain access to and/or exfiltrate secret key material.\n\n> [!NOTE]\n> Native `CryptoKeys` can be stored in IndexedDB but the keys created by this polyfill can not. This is because, unlike native `CryptoKeys`, our polyfilled key objects can not implement the [structured clone algorithm](https://www.w3.org/TR/WebCryptoAPI/#cryptokey-interface-clone).\n\n## Usage\n\nEnvironments that support Ed25519 (see https://github.com/WICG/webcrypto-secure-curves/issues/20) do not require this polyfill.\n\nFor all others, simply import this polyfill before use.\n\n```ts\nimport { install } from '@solana/webcrypto-ed25519-polyfill';\n\n// Calling this will shim methods on `SubtleCrypto`, adding Ed25519 support.\ninstall();\n\n// Now you can do this, in environments that do not otherwise support Ed25519.\nconst keyPair = await crypto.subtle.generateKey({ name: 'Ed25519' }, false, ['sign']);\nconst publicKeyBytes = await crypto.subtle.exportKey('raw', keyPair.publicKey);\nconst data = new Uint8Array([1, 2, 3]);\nconst signature = await crypto.subtle.sign({ name: 'Ed25519' }, keyPair.privateKey, data);\nif (await crypto.subtle.verify({ name: 'Ed25519' }, keyPair.publicKey, signature, data)) {\n    console.log('Data was signed using the private key associated with this public key');\n} else {\n    throw new Error('Signature verification error');\n}\n```\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/package.json",
    "content": "{\n    \"name\": \"@solana/webcrypto-ed25519-polyfill\",\n    \"version\": \"6.9.0\",\n    \"description\": \"A polyfill that adds Ed25519 key manipulation capabilities to `SubtleCrypto` in environments where it is not yet supported\",\n    \"homepage\": \"https://www.solanakit.com/api#solanawebcrypto-ed25519-polyfill\",\n    \"exports\": {\n        \"edge-light\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"react-native\": \"./dist/index.native.mjs\",\n        \"types\": \"./dist/types/index.d.ts\"\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"react-native\": \"./dist/index.native.mjs\",\n    \"types\": \"./dist/types/index.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\",\n        \"./src/\"\n    ],\n    \"sideEffects\": true,\n    \"keywords\": [\n        \"blockchain\",\n        \"solana\",\n        \"web3\"\n    ],\n    \"scripts\": {\n        \"compile:docs\": \"typedoc\",\n        \"compile:js\": \"tsup --config build-scripts/tsup.config.package.ts\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"prepublishOnly\": \"pnpm pkg delete devDependencies\",\n        \"publish-impl\": \"npm view $npm_package_name@$npm_package_version > /dev/null 2>&1 || (pnpm publish --tag ${PUBLISH_TAG:-canary} --access public --no-git-checks && (([ -n \\\"${GITHUB_OUTPUT:-}\\\" ] && echo 'published=true' >> \\\"$GITHUB_OUTPUT\\\") || true) && (([ \\\"$PUBLISH_TAG\\\" != \\\"canary\\\" ] && ../build-scripts/maybe-tag-latest.ts --token \\\"$GITHUB_TOKEN\\\" $npm_package_name@$npm_package_version) || true))\",\n        \"publish-packages\": \"pnpm prepublishOnly && pnpm publish-impl\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:typecheck\": \"tsc --noEmit\",\n        \"test:unit:browser\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.browser.js --rootDir . --silent\",\n        \"test:unit:node\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-unit.config.node.js --rootDir . --silent\"\n    },\n    \"author\": \"Solana Labs Maintainers <maintainers@solanalabs.com>\",\n    \"license\": \"MIT\",\n    \"repository\": {\n        \"type\": \"git\",\n        \"url\": \"https://github.com/anza-xyz/kit\"\n    },\n    \"bugs\": {\n        \"url\": \"https://github.com/anza-xyz/kit/issues\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"@noble/ed25519\": \"^3.1.0\"\n    },\n    \"devDependencies\": {\n        \"@solana/crypto-impl\": \"workspace:*\"\n    },\n    \"peerDependencies\": {\n        \"typescript\": \">=5.4.0\"\n    },\n    \"peerDependenciesMeta\": {\n        \"typescript\": {\n            \"optional\": true\n        }\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/src/.npmignore",
    "content": "__benchmarks__/\n__mocks__/\n__tests__/\n__typetests__/\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/src/__tests__/install-test.ts",
    "content": "import { install } from '../install';\nimport {\n    exportKeyPolyfill,\n    generateKeyPolyfill,\n    importKeyPolyfill,\n    isPolyfilledKey,\n    signPolyfill,\n    verifyPolyfill,\n} from '../secrets';\n\njest.mock('../secrets');\n\nconst ED25519_ALGORITHM_IDENTIFIERS = [\n    'ed25519',\n    'Ed25519',\n    'ED25519',\n    'eD25519',\n    { name: 'ed25519' },\n    { name: 'Ed25519' },\n    { name: 'ED25519' },\n    { name: 'eD25519' },\n];\n\nfunction isAlgorithmEd25519(putativeEd25519Algorithm: unknown) {\n    const candidate = JSON.stringify(putativeEd25519Algorithm);\n    return ED25519_ALGORITHM_IDENTIFIERS.some(a => JSON.stringify(a) === candidate);\n}\n\ndescribe('exportKey() polyfill', () => {\n    let originalExportKey: SubtleCrypto['exportKey'];\n    beforeEach(() => {\n        jest.spyOn(globalThis.crypto?.subtle, 'exportKey');\n        originalExportKey = globalThis.crypto?.subtle?.exportKey;\n    });\n    afterEach(() => {\n        globalThis.crypto.subtle.exportKey = originalExportKey;\n    });\n    describe('when installed', () => {\n        beforeEach(() => {\n            install();\n        });\n        it('delegates `exportKey` calls to the polyfill when supplied a polyfill-generated key', async () => {\n            expect.assertions(1);\n            (isPolyfilledKey as jest.Mock).mockReturnValue(true);\n            const mockPublicKey = {} as CryptoKey;\n            await globalThis.crypto.subtle.exportKey('raw', mockPublicKey);\n            expect(exportKeyPolyfill).toHaveBeenCalledWith('raw', mockPublicKey);\n        });\n        it('delegates `exportKey` calls to the original implementation when supplied a native-generated key', async () => {\n            expect.assertions(1);\n            (isPolyfilledKey as jest.Mock).mockReturnValue(false);\n            const mockPublicKey = {} as CryptoKey;\n            try {\n                // This will fail because the key is a mock. We are only interested in whether the\n                // native implementation was *called* so this is OK.\n                await globalThis.crypto.subtle.exportKey('raw', mockPublicKey);\n            } catch {\n                /* empty */\n            }\n            expect(originalExportKey).toHaveBeenCalledWith('raw', mockPublicKey);\n        });\n        it('overrides `exportKey`', () => {\n            expect(globalThis.crypto.subtle.exportKey).not.toBe(originalExportKey);\n        });\n    });\n    describe('when installed with no `exportKey` function', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.exportKey = undefined;\n            install();\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.exportKey = originalExportKey;\n        });\n        it('delegates `exportKey` calls to the polyfill when supplied a polyfill-generated key', async () => {\n            expect.assertions(1);\n            (isPolyfilledKey as jest.Mock).mockReturnValue(true);\n            const mockPublicKey = {} as CryptoKey;\n            await globalThis.crypto.subtle.exportKey('raw', mockPublicKey);\n            expect(exportKeyPolyfill).toHaveBeenCalledWith('raw', mockPublicKey);\n        });\n        it('fatals when supplied a native-generated key', async () => {\n            expect.assertions(1);\n            (isPolyfilledKey as jest.Mock).mockReturnValue(false);\n            const mockPublicKey = {} as CryptoKey;\n            await expect(() => globalThis.crypto.subtle.exportKey('raw', mockPublicKey)).rejects.toThrow();\n        });\n    });\n    describe('when installed in an insecure context', () => {\n        beforeEach(() => {\n            globalThis.isSecureContext = false;\n            install();\n        });\n        if (__BROWSER__) {\n            it('does not override `exportKey`', () => {\n                expect(globalThis.crypto.subtle.exportKey).toBe(originalExportKey);\n            });\n        } else {\n            it('overrides `exportKey`', () => {\n                expect(globalThis.crypto.subtle.exportKey).not.toBe(originalExportKey);\n            });\n        }\n    });\n});\n\ndescribe('generateKey() polyfill', () => {\n    let originalGenerateKey: SubtleCrypto['generateKey'];\n    beforeEach(() => {\n        jest.spyOn(globalThis.crypto?.subtle, 'generateKey');\n        originalGenerateKey = globalThis.crypto?.subtle?.generateKey;\n    });\n    afterEach(() => {\n        globalThis.crypto.subtle.generateKey = originalGenerateKey;\n    });\n    describe('when installed in an environment with no `generateKey` function', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.generateKey = undefined;\n            install();\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.generateKey = originalGenerateKey;\n        });\n        it.each([\n            { __variant: 'P256', name: 'ECDSA', namedCurve: 'P-256' },\n            { __variant: 'P384', name: 'ECDSA', namedCurve: 'P-384' } as EcKeyGenParams,\n            { __variant: 'P521', name: 'ECDSA', namedCurve: 'P-521' } as EcKeyGenParams,\n            ...['RSASSA-PKCS1-v1_5', 'RSA-PSS'].flatMap(rsaAlgoName =>\n                ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'].map(\n                    hashName =>\n                        ({\n                            __variant: hashName,\n                            hash: { name: hashName },\n                            modulusLength: 2048,\n                            name: rsaAlgoName,\n                            publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n                        }) as RsaHashedKeyGenParams,\n                ),\n            ),\n        ])('fatals when the algorithm identifier is $name/$__variant', async algorithm => {\n            expect.assertions(1);\n            await expect(() =>\n                globalThis.crypto.subtle.generateKey(algorithm, /* extractable */ false, ['sign', 'verify']),\n            ).rejects.toThrow();\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `generateKey` calls to the polyfill when the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                const mockKeyPair = {};\n                (generateKeyPolyfill as jest.Mock).mockReturnValue(mockKeyPair);\n                await expect(\n                    globalThis.crypto.subtle.generateKey(algorithm, /* extractable */ false, ['sign', 'verify']),\n                ).resolves.toBe(mockKeyPair);\n            },\n        );\n    });\n    describe('when installed in an environment that does not support Ed25519', () => {\n        beforeEach(() => {\n            const originalGenerateKeyImpl = originalGenerateKey;\n            (\n                originalGenerateKey as jest.Mock<\n                    ReturnType<typeof originalGenerateKey>,\n                    Parameters<typeof originalGenerateKey>\n                >\n            ).mockImplementation(async (...args) => {\n                const [algorithm] = args;\n                if (isAlgorithmEd25519(algorithm)) {\n                    throw new Error('Ed25519 not supported');\n                }\n                return await originalGenerateKeyImpl.apply(globalThis.crypto.subtle, args);\n            });\n            install();\n        });\n        it('calls the original `generateKey` once as a test when the algorithm identifier is \"Ed25519\" but never again (parallel version)', async () => {\n            expect.assertions(1);\n            await Promise.all([\n                globalThis.crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']),\n                globalThis.crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']),\n            ]);\n            expect(originalGenerateKey).toHaveBeenCalledTimes(1);\n        });\n        it('calls the original `generateKey` once as a test when the algorithm identifier is \"Ed25519\" but never again (serial version)', async () => {\n            expect.assertions(1);\n            await globalThis.crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']);\n            await globalThis.crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']);\n            expect(originalGenerateKey).toHaveBeenCalledTimes(1);\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `generateKey` calls to the polyfill when the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                const mockKeyPair = {};\n                (generateKeyPolyfill as jest.Mock).mockReturnValue(mockKeyPair);\n                await expect(\n                    globalThis.crypto.subtle.generateKey(algorithm, /* extractable */ false, ['sign', 'verify']),\n                ).resolves.toBe(mockKeyPair);\n            },\n        );\n    });\n    describe('when installed in an environment that supports Ed25519', () => {\n        beforeEach(() => {\n            install();\n        });\n        it('overrides `generateKey`', () => {\n            expect(globalThis.crypto.subtle.generateKey).not.toBe(originalGenerateKey);\n        });\n        it.each([\n            { __variant: 'P256', name: 'ECDSA', namedCurve: 'P-256' },\n            { __variant: 'P384', name: 'ECDSA', namedCurve: 'P-384' } as EcKeyGenParams,\n            { __variant: 'P521', name: 'ECDSA', namedCurve: 'P-521' } as EcKeyGenParams,\n            ...['RSASSA-PKCS1-v1_5', 'RSA-PSS'].flatMap(rsaAlgoName =>\n                ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'].map(\n                    hashName =>\n                        ({\n                            __variant: hashName,\n                            hash: { name: hashName },\n                            modulusLength: 2048,\n                            name: rsaAlgoName,\n                            publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n                        }) as RsaHashedKeyGenParams,\n                ),\n            ),\n        ])('calls the original `generateKey` when the algorithm identifier is $name/$__variant', async algorithm => {\n            expect.assertions(1);\n            await globalThis.crypto.subtle.generateKey(algorithm, /* extractable */ false, ['sign', 'verify']);\n            expect(originalGenerateKey).toHaveBeenCalled();\n        });\n        it('calls the original `generateKey` once per call to `generateKey` when the algorithm identifier is \"Ed25519\" (parallel version)', async () => {\n            expect.assertions(1);\n            await Promise.all([\n                globalThis.crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']),\n                globalThis.crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']),\n            ]);\n            expect(originalGenerateKey).toHaveBeenCalledTimes(2);\n        });\n        it('calls the original `generateKey` once per call to `generateKey` when the algorithm identifier is \"Ed25519\" (serial version)', async () => {\n            expect.assertions(1);\n            await globalThis.crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']);\n            await globalThis.crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']);\n            expect(originalGenerateKey).toHaveBeenCalledTimes(2);\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates the call to the original `generateKey` when the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                const mockKeyPair = {};\n                (originalGenerateKey as jest.Mock).mockResolvedValue(mockKeyPair);\n                await expect(\n                    globalThis.crypto.subtle.generateKey(algorithm, /* extractable */ false, ['sign', 'verify']),\n                ).resolves.toBe(mockKeyPair);\n            },\n        );\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'does not delegate `generateKey` calls to the polyfill when the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                await globalThis.crypto.subtle.generateKey(algorithm, /* extractable */ false, ['sign', 'verify']);\n                expect(generateKeyPolyfill).not.toHaveBeenCalled();\n            },\n        );\n    });\n    describe('when installed in an insecure context', () => {\n        beforeEach(() => {\n            globalThis.isSecureContext = false;\n            install();\n        });\n        if (__BROWSER__) {\n            it('does not override `generateKey`', () => {\n                expect(globalThis.crypto.subtle.generateKey).toBe(originalGenerateKey);\n            });\n        } else {\n            it('overrides `generateKey`', () => {\n                expect(globalThis.crypto.subtle.generateKey).not.toBe(originalGenerateKey);\n            });\n        }\n    });\n});\n\ndescribe('sign() polyfill', () => {\n    let originalSign: SubtleCrypto['sign'];\n    beforeEach(() => {\n        jest.spyOn(globalThis.crypto?.subtle, 'sign');\n        originalSign = globalThis.crypto?.subtle?.sign;\n    });\n    afterEach(() => {\n        globalThis.crypto.subtle.sign = originalSign;\n    });\n    describe('when installed', () => {\n        beforeEach(() => {\n            install();\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `sign` calls to the polyfill when supplied a polyfill-generated key and the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                (isPolyfilledKey as jest.Mock).mockReturnValue(true);\n                const mockPrivateKey = {} as CryptoKey;\n                const mockData = new Uint8Array([1, 2, 3]);\n                await globalThis.crypto.subtle.sign(algorithm, mockPrivateKey, mockData);\n                expect(signPolyfill).toHaveBeenCalledWith(mockPrivateKey, mockData);\n            },\n        );\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `sign` calls to the original implementation when supplied a native-generated key and the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                (isPolyfilledKey as jest.Mock).mockReturnValue(false);\n                const mockPrivateKey = {} as CryptoKey;\n                const mockData = new Uint8Array([1, 2, 3]);\n                try {\n                    // This will fail because the key is a mock. We are only interested in whether the\n                    // native implementation was *called* so this is OK.\n                    await globalThis.crypto.subtle.sign(algorithm, mockPrivateKey, mockData);\n                } catch {\n                    /* empty */\n                }\n                expect(originalSign).toHaveBeenCalledWith(algorithm, mockPrivateKey, mockData);\n            },\n        );\n        it('overrides `sign`', () => {\n            expect(globalThis.crypto.subtle.sign).not.toBe(originalSign);\n        });\n    });\n    describe('when installed with no `sign` function', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.sign = undefined;\n            install();\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.sign = originalSign;\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `sign` calls to the polyfill when supplied a polyfill-generated key and the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                (isPolyfilledKey as jest.Mock).mockReturnValue(true);\n                const mockPrivateKey = {} as CryptoKey;\n                const mockData = new Uint8Array([1, 2, 3]);\n                await globalThis.crypto.subtle.sign(algorithm, mockPrivateKey, mockData);\n                expect(signPolyfill).toHaveBeenCalledWith(mockPrivateKey, mockData);\n            },\n        );\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'fatals when supplied a native-generated key and the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                (isPolyfilledKey as jest.Mock).mockReturnValue(false);\n                const mockPrivateKey = {} as CryptoKey;\n                const mockData = new Uint8Array([1, 2, 3]);\n                await expect(() =>\n                    globalThis.crypto.subtle.sign(algorithm, mockPrivateKey, mockData),\n                ).rejects.toThrow();\n            },\n        );\n    });\n    describe('when installed in an insecure context', () => {\n        beforeEach(() => {\n            globalThis.isSecureContext = false;\n            install();\n        });\n        if (__BROWSER__) {\n            it('does not override `exportKey`', () => {\n                expect(globalThis.crypto.subtle.sign).toBe(originalSign);\n            });\n        } else {\n            it('overrides `exportKey`', () => {\n                expect(globalThis.crypto.subtle.sign).not.toBe(originalSign);\n            });\n        }\n    });\n});\n\ndescribe('verify() polyfill', () => {\n    let originalVerify: SubtleCrypto['verify'];\n    beforeEach(() => {\n        jest.spyOn(globalThis.crypto?.subtle, 'verify');\n        originalVerify = globalThis.crypto?.subtle?.verify;\n    });\n    afterEach(() => {\n        globalThis.crypto.subtle.verify = originalVerify;\n    });\n    describe('when installed', () => {\n        beforeEach(() => {\n            install();\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `verify` calls to the polyfill when supplied a polyfill-generated key and the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                (isPolyfilledKey as jest.Mock).mockReturnValue(true);\n                const mockPrivateKey = {} as CryptoKey;\n                const mockData = new Uint8Array([1, 2, 3]);\n                const mockSignature = new Uint8Array(Array(64).fill(1));\n                await globalThis.crypto.subtle.verify(algorithm, mockPrivateKey, mockSignature, mockData);\n                expect(verifyPolyfill).toHaveBeenCalledWith(mockPrivateKey, mockSignature, mockData);\n            },\n        );\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `verify` calls to the original implementation when supplied a native-generated key and the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                (isPolyfilledKey as jest.Mock).mockReturnValue(false);\n                const mockPrivateKey = {} as CryptoKey;\n                const mockData = new Uint8Array([1, 2, 3]);\n                const mockSignature = new Uint8Array(Array(64).fill(1));\n                try {\n                    // This will fail because the key is a mock. We are only interested in whether the\n                    // native implementation was *called* so this is OK.\n                    await globalThis.crypto.subtle.verify(algorithm, mockPrivateKey, mockSignature, mockData);\n                } catch {\n                    /* empty */\n                }\n                expect(originalVerify).toHaveBeenCalledWith(algorithm, mockPrivateKey, mockSignature, mockData);\n            },\n        );\n        it('overrides `verify`', () => {\n            expect(globalThis.crypto.subtle.verify).not.toBe(originalVerify);\n        });\n    });\n    describe('when imported with no `verify` function', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.verify = undefined;\n            install();\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.verify = originalVerify;\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `verify` calls to the polyfill when supplied a polyfill-generated key and the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                (isPolyfilledKey as jest.Mock).mockReturnValue(true);\n                const mockPrivateKey = {} as CryptoKey;\n                const mockData = new Uint8Array([1, 2, 3]);\n                const mockSignature = new Uint8Array(Array(64).fill(1));\n                await globalThis.crypto.subtle.verify(algorithm, mockPrivateKey, mockSignature, mockData);\n                expect(verifyPolyfill).toHaveBeenCalledWith(mockPrivateKey, mockSignature, mockData);\n            },\n        );\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'fatals when supplied a native-generated key and the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                (isPolyfilledKey as jest.Mock).mockReturnValue(false);\n                const mockPrivateKey = {} as CryptoKey;\n                const mockData = new Uint8Array([1, 2, 3]);\n                const mockSignature = new Uint8Array(Array(64).fill(1));\n                await expect(() =>\n                    globalThis.crypto.subtle.verify(algorithm, mockPrivateKey, mockSignature, mockData),\n                ).rejects.toThrow();\n            },\n        );\n    });\n    describe('when imported in an insecure context', () => {\n        beforeEach(() => {\n            globalThis.isSecureContext = false;\n            install();\n        });\n        if (__BROWSER__) {\n            it('does not override `exportKey`', () => {\n                expect(globalThis.crypto.subtle.verify).toBe(originalVerify);\n            });\n        } else {\n            it('overrides `exportKey`', () => {\n                expect(globalThis.crypto.subtle.verify).not.toBe(originalVerify);\n            });\n        }\n    });\n});\n\ndescribe('importKey() polyfill', () => {\n    let originalImportKey: SubtleCrypto['importKey'];\n\n    const MOCK_PUBLIC_KEY_BYTES = new Uint8Array([\n        0x1d, 0x0e, 0x93, 0x86, 0x4d, 0xcc, 0x81, 0x5f, 0xc3, 0xf2, 0x86, 0x18, 0x09, 0x11, 0xd0, 0x0a, 0x3f, 0xd2,\n        0x06, 0xde, 0x31, 0xa1, 0xc9, 0x42, 0x87, 0xcb, 0x43, 0xf0, 0x5f, 0xc9, 0xf2, 0xb5,\n    ]);\n\n    beforeEach(() => {\n        jest.spyOn(globalThis.crypto?.subtle, 'importKey');\n        originalImportKey = globalThis.crypto?.subtle?.importKey;\n    });\n    afterEach(() => {\n        globalThis.crypto.subtle.importKey = originalImportKey;\n    });\n    describe('when imported in an environment with no `importKey` function', () => {\n        beforeEach(() => {\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.subtle.importKey = undefined;\n            install();\n        });\n        afterEach(() => {\n            globalThis.crypto.subtle.importKey = originalImportKey;\n        });\n        it.each([\n            { __variant: 'P256', name: 'ECDSA', namedCurve: 'P-256' },\n            { __variant: 'P384', name: 'ECDSA', namedCurve: 'P-384' } as EcKeyGenParams,\n            { __variant: 'P521', name: 'ECDSA', namedCurve: 'P-521' } as EcKeyGenParams,\n            ...['RSASSA-PKCS1-v1_5', 'RSA-PSS'].flatMap(rsaAlgoName =>\n                ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'].map(\n                    hashName =>\n                        ({\n                            __variant: hashName,\n                            hash: { name: hashName },\n                            modulusLength: 2048,\n                            name: rsaAlgoName,\n                            publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n                        }) as RsaHashedKeyGenParams,\n                ),\n            ),\n        ])('fatals when the algorithm identifier is $name/$__variant', async algorithm => {\n            expect.assertions(1);\n            await expect(() =>\n                globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, algorithm, /* extractable */ false, [\n                    'verify',\n                ]),\n            ).rejects.toThrow();\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `importKey` calls to the polyfill when the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                const mockKey = {};\n                (importKeyPolyfill as jest.Mock).mockReturnValue(mockKey);\n                await expect(\n                    globalThis.crypto.subtle.importKey(\n                        'raw',\n                        MOCK_PUBLIC_KEY_BYTES,\n                        algorithm,\n                        /* extractable */ false,\n                        ['verify'],\n                    ),\n                ).resolves.toBe(mockKey);\n            },\n        );\n    });\n    describe('when imported in an environment that does not support Ed25519', () => {\n        beforeEach(() => {\n            const originalImportKeyImpl = originalImportKey;\n            (\n                originalImportKey as unknown as jest.Mock<\n                    ReturnType<typeof originalImportKey>,\n                    Parameters<typeof originalImportKey>\n                >\n            ).mockImplementation(async (...args) => {\n                const [_format, _keyData, algorithm] = args;\n                if (isAlgorithmEd25519(algorithm)) {\n                    throw new Error('Ed25519 not supported');\n                }\n                return await originalImportKeyImpl.apply(globalThis.crypto.subtle, args);\n            });\n            install();\n        });\n        it('calls the original `importKey` once as a test when the algorithm identifier is \"Ed25519\" but never again (parallel version)', async () => {\n            expect.assertions(1);\n            await Promise.all([\n                globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', /* extractable */ false, [\n                    'verify',\n                ]),\n                globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', /* extractable */ false, [\n                    'verify',\n                ]),\n            ]);\n            expect(originalImportKey).toHaveBeenCalledTimes(1);\n        });\n        it('calls the original `importKey` once as a test when the algorithm identifier is \"Ed25519\" but never again (serial version)', async () => {\n            expect.assertions(1);\n            await globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', /* extractable */ false, [\n                'verify',\n            ]);\n            await globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', /* extractable */ false, [\n                'verify',\n            ]);\n            expect(originalImportKey).toHaveBeenCalledTimes(1);\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates `generateKey` calls to the polyfill when the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                const mockKey = {};\n                (importKeyPolyfill as jest.Mock).mockReturnValue(mockKey);\n                const key = await globalThis.crypto.subtle.importKey(\n                    'raw',\n                    MOCK_PUBLIC_KEY_BYTES,\n                    algorithm,\n                    /* extractable */ false,\n                    ['verify'],\n                );\n                expect(key).toBe(mockKey);\n            },\n        );\n    });\n    describe('when imported in an environment that supports Ed25519', () => {\n        beforeEach(() => {\n            install();\n        });\n        it('overrides `importKey`', () => {\n            expect(globalThis.crypto.subtle.importKey).not.toBe(originalImportKey);\n        });\n        it.each([\n            { __variant: 'P256', name: 'ECDSA', namedCurve: 'P-256' },\n            { __variant: 'P384', name: 'ECDSA', namedCurve: 'P-384' } as EcKeyGenParams,\n            { __variant: 'P521', name: 'ECDSA', namedCurve: 'P-521' } as EcKeyGenParams,\n            ...['RSASSA-PKCS1-v1_5', 'RSA-PSS'].flatMap(rsaAlgoName =>\n                ['SHA-1', 'SHA-256', 'SHA-384', 'SHA-512'].map(\n                    hashName =>\n                        ({\n                            __variant: hashName,\n                            hash: { name: hashName },\n                            modulusLength: 2048,\n                            name: rsaAlgoName,\n                            publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n                        }) as RsaHashedKeyGenParams,\n                ),\n            ),\n        ])('calls the original `importKey` when the algorithm identifier is $name/$__variant', async algorithm => {\n            expect.assertions(1);\n            try {\n                await globalThis.crypto.subtle.importKey(\n                    'raw',\n                    MOCK_PUBLIC_KEY_BYTES,\n                    algorithm,\n                    /* extractable */ false,\n                    ['verify'],\n                );\n            } catch {\n                // some of these won't work with our mock key data, we just want to make sure they're called\n            }\n            expect(originalImportKey).toHaveBeenCalled();\n        });\n        it('calls the original `importKey` once per call to `importKey` when the algorithm identifier is \"Ed25519\" (parallel version)', async () => {\n            expect.assertions(1);\n            await Promise.all([\n                globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', /* extractable */ false, [\n                    'verify',\n                ]),\n                globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', /* extractable */ false, [\n                    'verify',\n                ]),\n            ]);\n            expect(originalImportKey).toHaveBeenCalledTimes(2);\n        });\n        it('calls the original `importKey` once per call to `importKey` when the algorithm identifier is \"Ed25519\" (serial version)', async () => {\n            expect.assertions(1);\n            await globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', /* extractable */ false, [\n                'verify',\n            ]);\n            await globalThis.crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', /* extractable */ false, [\n                'verify',\n            ]);\n            expect(originalImportKey).toHaveBeenCalledTimes(2);\n        });\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'delegates the call to the original `importKey` when the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                const mockKey = {};\n                (originalImportKey as jest.Mock).mockResolvedValue(mockKey);\n                await expect(\n                    globalThis.crypto.subtle.importKey(\n                        'raw',\n                        MOCK_PUBLIC_KEY_BYTES,\n                        algorithm,\n                        /* extractable */ false,\n                        ['verify'],\n                    ),\n                ).resolves.toBe(mockKey);\n            },\n        );\n        it.each(ED25519_ALGORITHM_IDENTIFIERS)(\n            'does not delegate `importKey` calls to the polyfill when the algorithm identifier is %s',\n            async algorithm => {\n                expect.assertions(1);\n                await globalThis.crypto.subtle.importKey(\n                    'raw',\n                    MOCK_PUBLIC_KEY_BYTES,\n                    algorithm,\n                    /* extractable */ false,\n                    ['verify'],\n                );\n                expect(importKeyPolyfill).not.toHaveBeenCalled();\n            },\n        );\n    });\n    describe('when imported in an insecure context', () => {\n        beforeEach(() => {\n            globalThis.isSecureContext = false;\n            install();\n        });\n        if (__BROWSER__) {\n            it('does not override `importKey`', () => {\n                expect(globalThis.crypto.subtle.importKey).toBe(originalImportKey);\n            });\n        } else {\n            it('overrides `importKey`', () => {\n                expect(globalThis.crypto.subtle.importKey).not.toBe(originalImportKey);\n            });\n        }\n    });\n});\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/src/__tests__/secrets-test.ts",
    "content": "import '@solana/test-matchers/toBeFrozenObject';\nimport '@solana/test-matchers/toEqualArrayBuffer';\n\nimport {\n    exportKeyPolyfill,\n    generateKeyPolyfill,\n    importKeyPolyfill,\n    isPolyfilledKey,\n    signPolyfill,\n    verifyPolyfill,\n} from '../secrets';\n\nconst MOCK_DATA = new Uint8Array([1, 2, 3]);\nconst MOCK_DATA_SIGNATURE = new Uint8Array([\n    239, 105, 216, 141, 51, 239, 0, 205, 191, 77, 181, 210, 95, 178, 175, 34, 226, 220, 252, 118, 255, 132, 101, 63, 35,\n    245, 181, 165, 19, 73, 242, 201, 84, 233, 251, 88, 27, 10, 18, 59, 1, 101, 228, 9, 14, 200, 66, 233, 195, 13, 79,\n    72, 48, 6, 161, 22, 137, 127, 73, 135, 139, 150, 125, 11,\n]);\nconst MOCK_SECRET_KEY_BYTES = new Uint8Array([\n    83, 147, 250, 112, 140, 37, 29, 73, 156, 38, 185, 76, 163, 8, 178, 225, 172, 53, 120, 108, 127, 191, 103, 8, 160,\n    170, 183, 186, 246, 1, 227, 158,\n]);\nconst MOCK_SECRET_KEY_BASE_64_URL = 'U5P6cIwlHUmcJrlMowiy4aw1eGx_v2cIoKq3uvYB454';\nconst MOCK_PUBLIC_KEY_BYTES = new Uint8Array([\n    166, 132, 114, 186, 49, 163, 23, 12, 11, 14, 119, 219, 102, 96, 26, 226, 91, 97, 238, 217, 236, 84, 232, 204, 62,\n    212, 179, 252, 20, 37, 179, 52,\n]);\nconst MOCK_PUBLIC_KEY_BASE_64_URL = 'poRyujGjFwwLDnfbZmAa4lth7tnsVOjMPtSz_BQlszQ';\nconst ED25519_PKCS8_HEADER =\n    // prettier-ignore\n    [\n        /**\n         * PKCS#8 header\n         */\n        0x30, // ASN.1 sequence tag\n        0x2e, // Length of sequence (46 more bytes)\n\n            0x02, // ASN.1 integer tag\n            0x01, // Length of integer\n                0x00, // Version number\n\n            0x30, // ASN.1 sequence tag\n            0x05, // Length of sequence\n                0x06, // ASN.1 object identifier tag\n                0x03, // Length of object identifier\n                    // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n                        0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n                        0x65, // thawte(101)\n                    // Ed25519 identifier\n                        0x70, // id-Ed25519(112)\n\n        /**\n         * Private key payload\n         */\n        0x04, // ASN.1 octet string tag\n        0x22, // String length (34 more bytes)\n\n            // Private key bytes as octet string\n            0x04, // ASN.1 octet string tag\n            0x20, // String length (32 bytes)\n    ];\n\ndescribe('exportKeyPolyfill', () => {\n    it.each(['spki'] as const)('throws an unimplemented error when the format is %s', async format => {\n        expect.assertions(1);\n        const mockKey = { format } as unknown as CryptoKey;\n        await expect(exportKeyPolyfill(format, mockKey)).rejects.toThrow(/unimplemented/);\n    });\n    describe('when format is `raw`', () => {\n        it('throws when the key supplied is non-extractable', async () => {\n            expect.assertions(1);\n            const mockKey = { extractable: false, type: 'public' } as unknown as CryptoKey;\n            await expect(exportKeyPolyfill('raw', mockKey)).rejects.toThrow('key is not extractable');\n        });\n        it.each(['private', 'secret'] as KeyType[])('throws when a %s key is supplied', async type => {\n            expect.assertions(1);\n            const mockKey = { extractable: true, type } as unknown as CryptoKey;\n            await expect(exportKeyPolyfill('raw', mockKey)).rejects.toThrow(\n                `Unable to export a raw Ed25519 ${type} key`,\n            );\n        });\n        it('throws when supplied a public key that was not generated with the polyfill', async () => {\n            expect.assertions(1);\n            const { publicKey } = await crypto.subtle.generateKey('Ed25519', /* extractable */ false, [\n                'sign',\n                'verify',\n            ]);\n            await expect(exportKeyPolyfill('raw', publicKey)).rejects.toThrow();\n        });\n        it('returns the public key bytes associated with a secret key generated by the polyfill', async () => {\n            expect.assertions(1);\n            jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(MOCK_SECRET_KEY_BYTES);\n            const { publicKey } = generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']);\n            await expect(exportKeyPolyfill('raw', publicKey)).resolves.toEqualArrayBuffer(MOCK_PUBLIC_KEY_BYTES.buffer);\n        });\n    });\n    describe('when format is `pkcs8`', () => {\n        it('throws when the key supplied is non-extractable', async () => {\n            expect.assertions(1);\n            const mockKey = { extractable: false, type: 'private' } as unknown as CryptoKey;\n            await expect(exportKeyPolyfill('pkcs8', mockKey)).rejects.toThrow('key is not extractable');\n        });\n        it.each(['public', 'secret'] as KeyType[])('throws when a %s key is supplied', async type => {\n            expect.assertions(1);\n            const mockKey = { extractable: true, type } as unknown as CryptoKey;\n            await expect(exportKeyPolyfill('pkcs8', mockKey)).rejects.toThrow(\n                `Unable to export a pkcs8 Ed25519 ${type} key`,\n            );\n        });\n        it('throws when supplied a private key that was not generated with the polyfill', async () => {\n            expect.assertions(1);\n            const { privateKey } = await crypto.subtle.generateKey('Ed25519', /* extractable */ false, [\n                'sign',\n                'verify',\n            ]);\n            await expect(exportKeyPolyfill('pkcs8', privateKey)).rejects.toThrow();\n        });\n        it('returns the private key bytes associated with a secret key generated by the polyfill with pkcs8 header prepended', async () => {\n            expect.assertions(1);\n            jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(MOCK_SECRET_KEY_BYTES);\n            const { privateKey } = generateKeyPolyfill(/* extractable */ true, ['sign', 'verify']);\n            // prettier-ignore\n            const expectedBytes = new Uint8Array([\n                /**\n                 * PKCS#8 header\n                 */\n                0x30, // ASN.1 sequence tag\n                0x2e, // Length of sequence (46 more bytes)\n\n                    0x02, // ASN.1 integer tag\n                    0x01, // Length of integer\n                        0x00, // Version number\n\n                    0x30, // ASN.1 sequence tag\n                    0x05, // Length of sequence\n                        0x06, // ASN.1 object identifier tag\n                        0x03, // Length of object identifier\n                            // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n                                0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n                                0x65, // thawte(101)\n                            // Ed25519 identifier\n                                0x70, // id-Ed25519(112)\n\n                /**\n                 * Private key payload\n                 */\n                0x04, // ASN.1 octet string tag\n                0x22, // String length (34 more bytes)\n\n                    // Private key bytes as octet string\n                    0x04, // ASN.1 octet string tag\n                    0x20, // String length (32 bytes)\n                        83, 147, 250, 112, 140, 37, 29, 73,\n                        156, 38, 185, 76, 163, 8, 178, 225,\n                        172, 53, 120, 108, 127, 191, 103, 8,\n                        160, 170, 183, 186, 246, 1, 227, 158,\n            ]);\n            await expect(exportKeyPolyfill('pkcs8', privateKey)).resolves.toEqualArrayBuffer(expectedBytes.buffer);\n        });\n    });\n    describe('when format is `jwk`', () => {\n        it('exports public keys', async () => {\n            expect.assertions(1);\n            jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(MOCK_SECRET_KEY_BYTES);\n            const { publicKey } = generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']);\n            const jwk = await exportKeyPolyfill('jwk', publicKey);\n            expect(jwk).toEqual({\n                crv /* curve */: 'Ed25519',\n                ext /* extractable */: true,\n                key_ops /* key operations */: ['verify'],\n                kty /* key type */: 'OKP' /* octet key pair */,\n                x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n            });\n        });\n        it('exports private keys', async () => {\n            expect.assertions(1);\n            jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(MOCK_SECRET_KEY_BYTES);\n            const { privateKey } = generateKeyPolyfill(/* extractable */ true, ['sign', 'verify']);\n            const jwk = await exportKeyPolyfill('jwk', privateKey);\n            expect(jwk).toEqual({\n                crv /* curve */: 'Ed25519',\n                d /* private key (base64-URL encoded) */: MOCK_SECRET_KEY_BASE_64_URL,\n                ext /* extractable */: true,\n                key_ops /* key operations */: ['sign'],\n                kty /* key type */: 'OKP' /* octet key pair */,\n                x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n            });\n        });\n        it('freezes the exported public key', async () => {\n            expect.assertions(1);\n            jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(MOCK_SECRET_KEY_BYTES);\n            const { publicKey } = generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']);\n            const jwk = await exportKeyPolyfill('jwk', publicKey);\n            expect(jwk).toBeFrozenObject();\n        });\n        it('freezes the exported private key', async () => {\n            expect.assertions(1);\n            jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(MOCK_SECRET_KEY_BYTES);\n            const { privateKey } = generateKeyPolyfill(/* extractable */ true, ['sign', 'verify']);\n            const jwk = await exportKeyPolyfill('jwk', privateKey);\n            expect(jwk).toBeFrozenObject();\n        });\n        it('throws when the public key supplied is non-extractable', async () => {\n            expect.assertions(1);\n            const mockKey = { extractable: false, type: 'public' } as unknown as CryptoKey;\n            await expect(exportKeyPolyfill('jwk', mockKey)).rejects.toThrow('key is not extractable');\n        });\n        it('throws when the private key supplied is non-extractable', async () => {\n            expect.assertions(1);\n            const mockKey = { extractable: false, type: 'private' } as unknown as CryptoKey;\n            await expect(exportKeyPolyfill('jwk', mockKey)).rejects.toThrow('key is not extractable');\n        });\n    });\n});\n\ndescribe('importKeyPolyfill', () => {\n    describe('when format is `raw`', () => {\n        it('allows importing valid public key bytes', () => {\n            expect(() => importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify'])).not.toThrow();\n        });\n        it('allows importing with empty keyUsages', () => {\n            expect(() => importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, [])).not.toThrow();\n        });\n        it.each(['sign', 'decrypt', 'deriveBits', 'deriveKey', 'encrypt', 'unwrapKey', 'wrapKey'] as KeyUsage[])(\n            'fatals when the usage `%s` is specified',\n            usage => {\n                expect(() => importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, [usage])).toThrow(\n                    'Unsupported key usage for a Ed25519 key',\n                );\n            },\n        );\n        it.each([0, 1, 30, 31, 33, 34, 48])('fatals when bytes is length `%d`', bytesLength => {\n            const keyData = new Uint8Array(Array(bytesLength).fill(0));\n            expect(() => importKeyPolyfill('raw', keyData, false, ['verify'])).toThrow(\n                'Ed25519 raw keys must be exactly 32-bytes',\n            );\n        });\n        it('has the string tag \"CryptoKey\"', () => {\n            const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify']);\n            expect(key).toHaveProperty([Symbol.toStringTag], 'CryptoKey');\n        });\n        it('has the type \"public\"', () => {\n            const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify']);\n            expect(key).toHaveProperty('type', 'public');\n        });\n        it.each([true, false])(\n            'has extractable `%s` when importing a key with the extractability `%s`',\n            extractability => {\n                const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, extractability, ['verify']);\n                expect(key).toHaveProperty('extractable', extractability);\n            },\n        );\n        it('has the algorithm \"Ed25519\"', () => {\n            const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify']);\n            expect(key).toHaveProperty(['algorithm', 'name'], 'Ed25519');\n        });\n        it('has usages `[\"verify\"]`', () => {\n            const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify']);\n            expect(key).toHaveProperty('usages', ['verify']);\n        });\n        it('stores public key bytes in an internal cache', () => {\n            const weakMapSetSpy = jest.spyOn(WeakMap.prototype, 'set');\n            importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify']);\n            expect(weakMapSetSpy).toHaveBeenCalledWith(expect.anything(), MOCK_PUBLIC_KEY_BYTES);\n        });\n        it('imported key can be used to verify a signature', async () => {\n            expect.assertions(1);\n            const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify']);\n            await expect(verifyPolyfill(key, MOCK_DATA_SIGNATURE, MOCK_DATA)).resolves.toBe(true);\n        });\n        it('imported key correctly does not verify a bad signature', async () => {\n            expect.assertions(1);\n            const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify']);\n            const badSignature = new Uint8Array(Array(64).fill(0));\n            await expect(verifyPolyfill(key, badSignature, MOCK_DATA)).resolves.toBe(false);\n        });\n        it('imported key can be exported to return the same bytes', async () => {\n            expect.assertions(1);\n            const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, /*extractable */ true, ['verify']);\n            await expect(exportKeyPolyfill('raw', key)).resolves.toEqualArrayBuffer(MOCK_PUBLIC_KEY_BYTES.buffer);\n        });\n        it('can import a public key that was exported from a native generated key', async () => {\n            expect.assertions(1);\n            const keyPair = await crypto.subtle.generateKey('Ed25519', /* extractable */ true, ['verify', 'sign']);\n            const publicKeyBytes = await crypto.subtle.exportKey('raw', keyPair.publicKey);\n            expect(() => importKeyPolyfill('raw', publicKeyBytes, false, ['verify'])).not.toThrow();\n        });\n        it('can import a public key that was exported from a polyfill generated key', async () => {\n            expect.assertions(1);\n            const keyPair = generateKeyPolyfill(/* extractable */ true, ['verify', 'sign']);\n            const publicKeyBytes = await exportKeyPolyfill('raw', keyPair.publicKey);\n            expect(() => importKeyPolyfill('raw', publicKeyBytes, false, ['verify'])).not.toThrow();\n        });\n    });\n\n    describe('when format is `pkcs8`', () => {\n        const mockSecretKeyWithHeader = new Uint8Array([...ED25519_PKCS8_HEADER, ...MOCK_SECRET_KEY_BYTES]);\n\n        it('allows importing valid private key bytes', () => {\n            expect(() => importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, ['sign'])).not.toThrow();\n        });\n        it('allows importing with empty keyUsages', () => {\n            expect(() => importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, [])).not.toThrow();\n        });\n        it.each(['verify', 'decrypt', 'deriveBits', 'deriveKey', 'encrypt', 'unwrapKey', 'wrapKey'] as KeyUsage[])(\n            'fatals when the usage `%s` is specified',\n            usage => {\n                expect(() => importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, [usage])).toThrow(\n                    'Unsupported key usage for a Ed25519 key',\n                );\n            },\n        );\n        it.each([0, 1, 32, 46, 47, 49, 50])('fatals when bytes is length `%d`', bytesLength => {\n            const keyData = new Uint8Array(Array(bytesLength).fill(0));\n            expect(() => importKeyPolyfill('pkcs8', keyData, false, ['sign'])).toThrow('Invalid keyData');\n        });\n        it('fatals when the first 16 bytes are not the expected header', () => {\n            const keyData = new Uint8Array([...Array(16).fill(0), ...MOCK_SECRET_KEY_BYTES]);\n            expect(() => importKeyPolyfill('pkcs8', keyData, false, ['sign'])).toThrow('Invalid keyData');\n        });\n        it('has the string tag \"CryptoKey\"', () => {\n            const key = importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, ['sign']);\n            expect(key).toHaveProperty([Symbol.toStringTag], 'CryptoKey');\n        });\n        it('has the type \"private\"', () => {\n            const key = importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, ['sign']);\n            expect(key).toHaveProperty('type', 'private');\n        });\n        it.each([true, false])(\n            'has extractable `%s` when importing a key with the extractability `%s`',\n            extractability => {\n                const key = importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, extractability, ['sign']);\n                expect(key).toHaveProperty('extractable', extractability);\n            },\n        );\n        it('has the algorithm \"Ed25519\"', () => {\n            const key = importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, ['sign']);\n            expect(key).toHaveProperty(['algorithm', 'name'], 'Ed25519');\n        });\n        it('has usages `[\"sign\"]`', () => {\n            const key = importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, ['sign']);\n            expect(key).toHaveProperty('usages', ['sign']);\n        });\n        it('stores private key bytes in an internal cache', () => {\n            const weakMapSetSpy = jest.spyOn(WeakMap.prototype, 'set');\n            importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, ['sign']);\n            expect(weakMapSetSpy).toHaveBeenCalledWith(expect.anything(), MOCK_SECRET_KEY_BYTES);\n        });\n        it('imported key can be used to sign data', async () => {\n            expect.assertions(1);\n            const key = importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, ['sign']);\n            await expect(signPolyfill(key, MOCK_DATA)).resolves.toEqualArrayBuffer(MOCK_DATA_SIGNATURE.buffer);\n        });\n        // we don't have export pkcs8 keys yet\n        it('imported key can be exported to return the same bytes', async () => {\n            expect.assertions(1);\n            const key = importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, /*extractable */ true, ['sign']);\n            await expect(exportKeyPolyfill('pkcs8', key)).resolves.toEqualArrayBuffer(mockSecretKeyWithHeader.buffer);\n        });\n        it('can import a private key that was exported from a native generated key', async () => {\n            expect.assertions(1);\n            const { privateKey } = await crypto.subtle.generateKey('Ed25519', /* extractable */ true, [\n                'verify',\n                'sign',\n            ]);\n            const privateKeyPkcs8Bytes = await crypto.subtle.exportKey('pkcs8', privateKey);\n            expect(() => importKeyPolyfill('pkcs8', privateKeyPkcs8Bytes, false, ['sign'])).not.toThrow();\n        });\n        it('can import a private key that was exported from a polyfill generated key', async () => {\n            expect.assertions(1);\n            const { privateKey } = generateKeyPolyfill(/* extractable */ true, ['verify', 'sign']);\n            const privateKeyPkcs8Bytes = await exportKeyPolyfill('pkcs8', privateKey);\n            expect(() => importKeyPolyfill('pkcs8', privateKeyPkcs8Bytes, false, ['sign'])).not.toThrow();\n        });\n    });\n\n    describe('when format is `jwk`', () => {\n        it('creates public key CryptoKey instances', () => {\n            const key = importKeyPolyfill(\n                'jwk',\n                {\n                    crv /* curve */: 'Ed25519',\n                    ext /* extractable */: false,\n                    key_ops /* key operations */: ['verify'],\n                    kty /* key type */: 'OKP' /* octet key pair */,\n                    x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                },\n                false,\n                ['verify'],\n            );\n            expect(key).toEqual({\n                [Symbol.toStringTag]: 'CryptoKey',\n                algorithm: { name: 'Ed25519' },\n                extractable: false,\n                type: 'public',\n                usages: ['verify'],\n            });\n        });\n        it('creates private key CryptoKey instances', () => {\n            const key = importKeyPolyfill(\n                'jwk',\n                {\n                    crv /* curve */: 'Ed25519',\n                    d /* private key (base64-URL encoded) */: MOCK_SECRET_KEY_BASE_64_URL,\n                    ext /* extractable */: false,\n                    key_ops /* key operations */: ['sign'],\n                    kty /* key type */: 'OKP' /* octet key pair */,\n                    x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                },\n                false,\n                ['sign'],\n            );\n            expect(key).toEqual({\n                [Symbol.toStringTag]: 'CryptoKey',\n                algorithm: { name: 'Ed25519' },\n                extractable: false,\n                type: 'private',\n                usages: ['sign'],\n            });\n        });\n        it('freezes the CryptoKey public key', () => {\n            const key = importKeyPolyfill(\n                'jwk',\n                {\n                    crv /* curve */: 'Ed25519',\n                    ext /* extractable */: false,\n                    key_ops /* key operations */: ['verify'],\n                    kty /* key type */: 'OKP' /* octet key pair */,\n                    x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                },\n                false,\n                ['verify'],\n            );\n            expect(key).toBeFrozenObject();\n        });\n        it('freezes the CryptoKey private key', () => {\n            const key = importKeyPolyfill(\n                'jwk',\n                {\n                    crv /* curve */: 'Ed25519',\n                    d /* private key (base64-URL encoded) */: MOCK_SECRET_KEY_BASE_64_URL,\n                    ext /* extractable */: false,\n                    key_ops /* key operations */: ['sign'],\n                    kty /* key type */: 'OKP' /* octet key pair */,\n                    x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                },\n                false,\n                ['sign'],\n            );\n            expect(key).toBeFrozenObject();\n        });\n        it('can verify a correct signature using the imported public key', async () => {\n            expect.assertions(1);\n            const key = importKeyPolyfill(\n                'jwk',\n                {\n                    crv /* curve */: 'Ed25519',\n                    ext /* extractable */: false,\n                    key_ops /* key operations */: ['verify'],\n                    kty /* key type */: 'OKP' /* octet key pair */,\n                    x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                },\n                false,\n                ['verify'],\n            );\n            await expect(verifyPolyfill(key, MOCK_DATA_SIGNATURE, MOCK_DATA)).resolves.toBe(true);\n        });\n        it('can identify a bad signature using the imported public key', async () => {\n            expect.assertions(1);\n            const key = importKeyPolyfill(\n                'jwk',\n                {\n                    crv /* curve */: 'Ed25519',\n                    ext /* extractable */: false,\n                    key_ops /* key operations */: ['verify'],\n                    kty /* key type */: 'OKP' /* octet key pair */,\n                    x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                },\n                false,\n                ['verify'],\n            );\n            const badSignature = new Uint8Array(Array(64).fill(0));\n            await expect(verifyPolyfill(key, badSignature, MOCK_DATA)).resolves.toBe(false);\n        });\n        it('can sign using the imported private key', async () => {\n            expect.assertions(1);\n            const key = importKeyPolyfill(\n                'jwk',\n                {\n                    crv /* curve */: 'Ed25519',\n                    d /* private key (base64-URL encoded) */: MOCK_SECRET_KEY_BASE_64_URL,\n                    ext /* extractable */: false,\n                    key_ops /* key operations */: ['sign'],\n                    kty /* key type */: 'OKP' /* octet key pair */,\n                    x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                },\n                false,\n                ['sign'],\n            );\n            await expect(signPolyfill(key, MOCK_DATA)).resolves.toEqualArrayBuffer(MOCK_DATA_SIGNATURE.buffer);\n        });\n        it('can import and re-export the same public key', async () => {\n            expect.assertions(1);\n            const originalJwk = {\n                crv /* curve */: 'Ed25519',\n                d /* private key (base64-URL encoded) */: MOCK_SECRET_KEY_BASE_64_URL,\n                ext /* extractable */: true,\n                key_ops /* key operations */: ['sign'],\n                kty /* key type */: 'OKP' /* octet key pair */,\n                x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n            };\n            const key = importKeyPolyfill('jwk', originalJwk, true, ['sign']);\n            const exportedJwk = await exportKeyPolyfill('jwk', key);\n            expect(exportedJwk).toEqual(originalJwk);\n        });\n        it('can import and re-export the same private key', async () => {\n            expect.assertions(1);\n            const originalJwk = {\n                crv /* curve */: 'Ed25519',\n                ext /* extractable */: true,\n                key_ops /* key operations */: ['verify'],\n                kty /* key type */: 'OKP' /* octet key pair */,\n                x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n            };\n            const key = importKeyPolyfill('jwk', originalJwk, true, ['verify']);\n            const exportedJwk = await exportKeyPolyfill('jwk', key);\n            expect(exportedJwk).toEqual(originalJwk);\n        });\n        it('can import a public key that was exported from a native generated key', async () => {\n            expect.assertions(1);\n            const { publicKey } = await crypto.subtle.generateKey('Ed25519', /* extractable */ false, [\n                'verify',\n                'sign',\n            ]);\n            const jwk = await crypto.subtle.exportKey('jwk', publicKey);\n            expect(() => importKeyPolyfill('jwk', jwk, true, ['verify'])).not.toThrow();\n        });\n        it('can import a private key that was exported from a native generated key', async () => {\n            expect.assertions(1);\n            const { privateKey } = await crypto.subtle.generateKey('Ed25519', /* extractable */ true, [\n                'verify',\n                'sign',\n            ]);\n            const jwk = await crypto.subtle.exportKey('jwk', privateKey);\n            expect(() => importKeyPolyfill('jwk', jwk, true, ['sign'])).not.toThrow();\n        });\n        it('can import a public key that was exported from a polyfill generated key', async () => {\n            expect.assertions(1);\n            const { publicKey } = generateKeyPolyfill(/* extractable */ false, ['verify', 'sign']);\n            const jwk = await exportKeyPolyfill('jwk', publicKey);\n            expect(() => importKeyPolyfill('jwk', jwk, true, ['verify'])).not.toThrow();\n        });\n        it('can import a private key that was exported from a polyfill generated key', async () => {\n            expect.assertions(1);\n            const { privateKey } = generateKeyPolyfill(/* extractable */ true, ['verify', 'sign']);\n            const jwk = await exportKeyPolyfill('jwk', privateKey);\n            expect(() => importKeyPolyfill('jwk', jwk, true, ['sign'])).not.toThrow();\n        });\n        it('throws when the JWK curve is not Ed25519', () => {\n            expect(() =>\n                importKeyPolyfill(\n                    'jwk',\n                    {\n                        crv /* curve */: 'Ed448',\n                        ext /* extractable */: false,\n                        key_ops /* key operations */: ['verify'],\n                        kty /* key type */: 'OKP' /* octet key pair */,\n                        x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                    },\n                    false,\n                    ['verify'],\n                ),\n            ).toThrow(/Invalid Ed25519 JWK/);\n        });\n        it('throws when the JWK key type is not OKP', () => {\n            expect(() =>\n                importKeyPolyfill(\n                    'jwk',\n                    {\n                        crv /* curve */: 'Ed25519',\n                        ext /* extractable */: false,\n                        key_ops /* key operations */: ['verify'],\n                        kty /* key type */: 'EC',\n                        x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                    },\n                    false,\n                    ['verify'],\n                ),\n            ).toThrow(/Invalid Ed25519 JWK/);\n        });\n        it('throws when the JWK key_ops do not match the key usages', () => {\n            expect(() =>\n                importKeyPolyfill(\n                    'jwk',\n                    {\n                        crv /* curve */: 'Ed25519',\n                        ext /* extractable */: false,\n                        key_ops /* key operations */: ['verify', 'sign'],\n                        kty /* key type */: 'OKP' /* octet key pair */,\n                        x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                    },\n                    false,\n                    ['verify'],\n                ),\n            ).toThrow(/Invalid Ed25519 JWK/);\n        });\n        it('throws when the JWK ext boolean do not match the extractable argument', () => {\n            expect(() =>\n                importKeyPolyfill(\n                    'jwk',\n                    {\n                        crv /* curve */: 'Ed25519',\n                        ext /* extractable */: false,\n                        key_ops /* key operations */: ['verify'],\n                        kty /* key type */: 'OKP' /* octet key pair */,\n                        x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                    },\n                    true,\n                    ['verify'],\n                ),\n            ).toThrow(/Invalid Ed25519 JWK/);\n        });\n        it.each(['sign', 'decrypt', 'deriveBits', 'deriveKey', 'encrypt', 'unwrapKey', 'wrapKey'] as KeyUsage[])(\n            'throws when a public key is trying to use the `%s` usage',\n            usage => {\n                expect(() =>\n                    importKeyPolyfill(\n                        'jwk',\n                        {\n                            crv /* curve */: 'Ed25519',\n                            ext /* extractable */: false,\n                            key_ops /* key operations */: [usage],\n                            kty /* key type */: 'OKP' /* octet key pair */,\n                            x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                        },\n                        false,\n                        [usage],\n                    ),\n                ).toThrow('Unsupported key usage for a Ed25519 key');\n            },\n        );\n        it.each(['verify', 'decrypt', 'deriveBits', 'deriveKey', 'encrypt', 'unwrapKey', 'wrapKey'] as KeyUsage[])(\n            'throws when a private key is trying to use the `%s` usage',\n            usage => {\n                expect(() =>\n                    importKeyPolyfill(\n                        'jwk',\n                        {\n                            crv /* curve */: 'Ed25519',\n                            d /* private key (base64-URL encoded) */: MOCK_SECRET_KEY_BASE_64_URL,\n                            ext /* extractable */: false,\n                            key_ops /* key operations */: [usage],\n                            kty /* key type */: 'OKP' /* octet key pair */,\n                            x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                        },\n                        false,\n                        [usage],\n                    ),\n                ).toThrow('Unsupported key usage for a Ed25519 key');\n            },\n        );\n        it('throws when a public key is missing the `x` property', () => {\n            expect(() =>\n                importKeyPolyfill(\n                    'jwk',\n                    {\n                        crv /* curve */: 'Ed25519',\n                        ext /* extractable */: false,\n                        key_ops /* key operations */: ['verify'],\n                        kty /* key type */: 'OKP' /* octet key pair */,\n                    },\n                    false,\n                    ['verify'],\n                ),\n            ).toThrow(/Ed25519 JWK is missing public key coordinates/);\n        });\n        it('throws when a private key is missing the `d` property', () => {\n            expect(() =>\n                importKeyPolyfill(\n                    'jwk',\n                    {\n                        crv /* curve */: 'Ed25519',\n                        d: /* private key (base64-URL encoded) */ undefined,\n                        ext /* extractable */: false,\n                        key_ops /* key operations */: ['sign'],\n                        kty /* key type */: 'OKP' /* octet key pair */,\n                        x /* public key x-coordinate (base64-URL encoded) */: MOCK_PUBLIC_KEY_BASE_64_URL,\n                    },\n                    false,\n                    ['sign'],\n                ),\n            ).toThrow(/Ed25519 JWK is missing private key coordinates/);\n        });\n    });\n\n    it('fatals when format is spki', () => {\n        expect(() => importKeyPolyfill('spki', new Uint8Array(), false, ['sign'])).toThrow(/format is unimplemented/);\n    });\n});\n\ndescribe('generateKeyPolyfill', () => {\n    it('stores secret key bytes in an internal cache', () => {\n        const weakMapSetSpy = jest.spyOn(WeakMap.prototype, 'set');\n        const expectedSecretKey = new Uint8Array(Array(32).fill(1));\n        jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(expectedSecretKey);\n        generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']);\n        expect(weakMapSetSpy).toHaveBeenCalledWith(expect.anything(), expectedSecretKey);\n    });\n    describe.each(['public', 'private'])('when generating a %s key', type => {\n        let keyPair: CryptoKeyPair;\n        beforeEach(() => {\n            keyPair = generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']);\n        });\n        it(`has the algorithm \"Ed25519\"`, () => {\n            expect(keyPair).toHaveProperty([`${type}Key`, 'algorithm', 'name'], 'Ed25519');\n        });\n        it('has the string tag \"CryptoKey\"', () => {\n            expect(keyPair).toHaveProperty([`${type}Key`, Symbol.toStringTag], 'CryptoKey');\n        });\n        it(`has the type \"${type}\"`, () => {\n            expect(keyPair).toHaveProperty([`${type}Key`, 'type'], type);\n        });\n    });\n    it.each([true, false])(\n        \"sets the private key's `extractable` accordingly when generating a key pair with the extractability `%s`\",\n        extractable => {\n            const { privateKey } = generateKeyPolyfill(extractable, ['sign', 'verify']);\n            expect(privateKey).toHaveProperty('extractable', extractable);\n        },\n    );\n    it.each([true, false])(\n        \"sets the public key's `extractable` to `true` when generating a key pair with the extractability `%s`\",\n        extractable => {\n            const { publicKey } = generateKeyPolyfill(extractable, ['sign', 'verify']);\n            expect(publicKey).toHaveProperty('extractable', true);\n        },\n    );\n    it.each(['decrypt', 'deriveBits', 'deriveKey', 'encrypt', 'unwrapKey', 'wrapKey'] as KeyUsage[])(\n        'fatals when the usage `%s` is specified',\n        usage => {\n            expect(() => generateKeyPolyfill(/* extractable */ false, [usage])).toThrow();\n        },\n    );\n    it(\"includes `sign` among the private key's usages when the `sign` usage is specified\", () => {\n        const { privateKey } = generateKeyPolyfill(/* extractable */ false, ['sign']);\n        expect(privateKey).toHaveProperty('usages', expect.arrayContaining(['sign']));\n    });\n    it(\"sets the private key's usages to an empty array when the `sign` usage is not specified\", () => {\n        const { privateKey } = generateKeyPolyfill(/* extractable */ false, ['verify']);\n        expect(privateKey).toHaveProperty('usages', []);\n    });\n    it(\"does not include `verify` among the private key's usages when the `verify` usage is specified\", () => {\n        const { privateKey } = generateKeyPolyfill(/* extractable */ false, ['verify']);\n        expect(privateKey).toHaveProperty('usages', []);\n    });\n    it(\"does not include `sign` among the public key's usages when the `sign` usage is specified\", () => {\n        const { publicKey } = generateKeyPolyfill(/* extractable */ false, ['sign']);\n        expect(publicKey).toHaveProperty('usages', []);\n    });\n    it(\"sets the public key's usages to an empty array when the `verify` usage is not specified\", () => {\n        const { publicKey } = generateKeyPolyfill(/* extractable */ false, ['sign']);\n        expect(publicKey).toHaveProperty('usages', []);\n    });\n    it(\"includes `verify` among the public key's usages when the `verify` usage is specified\", () => {\n        const { publicKey } = generateKeyPolyfill(/* extractable */ false, ['verify']);\n        expect(publicKey).toHaveProperty('usages', expect.arrayContaining(['verify']));\n    });\n    it('fatals when no key usages are specified', () => {\n        expect(() => generateKeyPolyfill(/* extractable */ false, [])).toThrow();\n    });\n    describe('when no CSPRNG can be found', () => {\n        let oldGetRandomValues: Crypto['getRandomValues'];\n        beforeEach(() => {\n            oldGetRandomValues = globalThis.crypto.getRandomValues;\n            // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n            // @ts-ignore\n            globalThis.crypto.getRandomValues = undefined;\n        });\n        afterEach(() => {\n            globalThis.crypto.getRandomValues = oldGetRandomValues;\n        });\n        it('fatals', () => {\n            expect(() => {\n                generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']);\n            }).toThrow();\n        });\n    });\n});\n\ndescribe('isPolyfilledKey', () => {\n    it('returns true when given a public key produced with generateKeyPolyfill()', () => {\n        const key = generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']);\n        expect(isPolyfilledKey(key.publicKey)).toBe(true);\n    });\n    it('returns true when given a private key produced with generateKeyPolyfill()', () => {\n        const key = generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']);\n        expect(isPolyfilledKey(key.privateKey)).toBe(true);\n    });\n    it('returns false when given a public key produced with the native keygen', async () => {\n        expect.assertions(1);\n        const key = await crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']);\n        expect(isPolyfilledKey(key.publicKey)).toBe(false);\n    });\n    it('returns false when given a private key produced with the native keygen', async () => {\n        expect.assertions(1);\n        const key = await crypto.subtle.generateKey('Ed25519', /* extractable */ false, ['sign', 'verify']);\n        expect(isPolyfilledKey(key.privateKey)).toBe(false);\n    });\n    it('returns true when given a public key produced with importKeyPolyfill', () => {\n        const key = importKeyPolyfill('raw', MOCK_PUBLIC_KEY_BYTES, false, ['verify']);\n        expect(isPolyfilledKey(key)).toBe(true);\n    });\n    it('returns false when given a public key produced with the native importKey', async () => {\n        expect.assertions(1);\n        const key = await crypto.subtle.importKey('raw', MOCK_PUBLIC_KEY_BYTES, 'Ed25519', false, ['verify']);\n        expect(isPolyfilledKey(key)).toBe(false);\n    });\n    it('returns true when given a private key produced with importKeyPolyfill', () => {\n        const mockSecretKeyWithHeader = new Uint8Array([...ED25519_PKCS8_HEADER, ...MOCK_SECRET_KEY_BYTES]);\n        const key = importKeyPolyfill('pkcs8', mockSecretKeyWithHeader, false, ['sign']);\n        expect(isPolyfilledKey(key)).toBe(true);\n    });\n    it('returns false when given a private key produced with the native importKey', async () => {\n        expect.assertions(1);\n        const mockSecretKeyWithHeader = new Uint8Array([...ED25519_PKCS8_HEADER, ...MOCK_SECRET_KEY_BYTES]);\n        const key = await crypto.subtle.importKey('pkcs8', mockSecretKeyWithHeader, 'Ed25519', false, ['sign']);\n        expect(isPolyfilledKey(key)).toBe(false);\n    });\n});\n\ndescribe('signPolyfill', () => {\n    let privateKey: CryptoKey;\n    beforeEach(() => {\n        jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(MOCK_SECRET_KEY_BYTES);\n        privateKey = generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']).privateKey;\n    });\n    it('throws when the key supplied has no \"sign\" usage', async () => {\n        expect.assertions(1);\n        const mockKey = { type: 'private', usages: ['verify'] } as unknown as CryptoKey;\n        await expect(signPolyfill(mockKey, MOCK_DATA)).rejects.toThrow(/Unable to use this key to sign/);\n    });\n    it.each(['public', 'secret'] as KeyType[])('throws when a %s key is supplied', async type => {\n        expect.assertions(1);\n        const mockKey = { type, usages: ['sign'] } as unknown as CryptoKey;\n        await expect(signPolyfill(mockKey, MOCK_DATA)).rejects.toThrow(/Unable to use this key to sign/);\n    });\n    it('produces the expected signature given a private key', async () => {\n        expect.assertions(1);\n        await expect(signPolyfill(privateKey, MOCK_DATA)).resolves.toEqualArrayBuffer(MOCK_DATA_SIGNATURE.buffer);\n    });\n    it('produces signatures 64 bytes in length', async () => {\n        expect.assertions(1);\n        await expect(signPolyfill(privateKey, MOCK_DATA)).resolves.toHaveProperty('byteLength', 64);\n    });\n});\n\ndescribe('verifyPolyfill', () => {\n    let publicKey: CryptoKey;\n    beforeEach(() => {\n        jest.spyOn(globalThis.crypto, 'getRandomValues').mockReturnValue(MOCK_SECRET_KEY_BYTES);\n        publicKey = generateKeyPolyfill(/* extractable */ false, ['sign', 'verify']).publicKey;\n    });\n    it('throws when the key supplied has no \"verify\" usage', async () => {\n        expect.assertions(1);\n        const mockKey = { type: 'public', usages: ['sign'] } as unknown as CryptoKey;\n        const mockSignature = new Uint8Array(Array(64).fill(1));\n        await expect(verifyPolyfill(mockKey, mockSignature, MOCK_DATA)).rejects.toThrow(\n            /Unable to use this key to verify/,\n        );\n    });\n    it.each(['private', 'secret'] as KeyType[])('throws when a %s key is supplied', async type => {\n        expect.assertions(1);\n        const mockKey = { type, usages: ['verify'] } as unknown as CryptoKey;\n        const mockSignature = new Uint8Array(Array(64).fill(1));\n        await expect(verifyPolyfill(mockKey, mockSignature, MOCK_DATA)).rejects.toThrow(\n            /Unable to use this key to verify/,\n        );\n    });\n    it('returns `true` when the correct signature is supplied for a given payload', async () => {\n        expect.assertions(1);\n        await expect(verifyPolyfill(publicKey, MOCK_DATA_SIGNATURE, MOCK_DATA)).resolves.toBe(true);\n    });\n    it('returns `false` when a bad signature is supplied for a given payload', async () => {\n        expect.assertions(1);\n        const badSignature = new Uint8Array(Array(64).fill(1));\n        await expect(verifyPolyfill(publicKey, badSignature, MOCK_DATA)).resolves.toBe(false);\n    });\n    it('returns `false` when the signature 65 bytes long', async () => {\n        expect.assertions(1);\n        const badSignature = new Uint8Array([...MOCK_DATA_SIGNATURE, 1]);\n        await expect(verifyPolyfill(publicKey, badSignature, MOCK_DATA)).resolves.toBe(false);\n    });\n    it('returns `false` when the signature 63 bytes long', async () => {\n        expect.assertions(1);\n        const badSignature = MOCK_DATA_SIGNATURE.slice(0, 63);\n        await expect(verifyPolyfill(publicKey, badSignature, MOCK_DATA)).resolves.toBe(false);\n    });\n});\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/src/index.ts",
    "content": "/**\n * This package contains a polyfill that enables Ed25519 key manipulation in environments where it\n * is not yet implemented. It does so by proxying calls to `SubtleCrypto` instance methods to an\n * Ed25519 implementation in userspace.\n *\n * > [!WARNING]\n * > Because this package's implementation of Ed25519 key generation exists in userspace, it can't\n * > guarantee that the keys you generate with it are non-exportable. Untrusted code running in your\n * > JavaScript context may still be able to gain access to and/or exfiltrate secret key material.\n *\n * > [!NOTE]\n * > Native `CryptoKeys` can be stored in IndexedDB but the keys created by this polyfill can not.\n * > This is because, unlike native `CryptoKeys`, our polyfilled key objects can not implement the\n * > [structured clone algorithm](https://www.w3.org/TR/WebCryptoAPI/#cryptokey-interface-clone).\n *\n * ## Usage\n *\n * Environments that support Ed25519 (see https://github.com/WICG/webcrypto-secure-curves/issues/20)\n * do not require this polyfill.\n *\n * For all others, simply import this polyfill before use.\n *\n * ```ts\n * import { install } from '@solana/webcrypto-ed25519-polyfill';\n *\n * // Calling this will shim methods on `SubtleCrypto`, adding Ed25519 support.\n * install();\n *\n * // Now you can do this, in environments that do not otherwise support Ed25519.\n * const keyPair = await crypto.subtle.generateKey({ name: 'Ed25519' }, false, ['sign']);\n * const publicKeyBytes = await crypto.subtle.exportKey('raw', keyPair.publicKey);\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await crypto.subtle.sign({ name: 'Ed25519' }, keyPair.privateKey, data);\n * if (await crypto.subtle.verify({ name: 'Ed25519' }, keyPair.publicKey, signature, data)) {\n *     console.log('Data was signed using the private key associated with this public key');\n * } else {\n *     throw new Error('Signature verification error');\n * }\n * ```\n *\n * @packageDocumentation\n */\nexport * from './install';\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/src/install.ts",
    "content": "import cryptoImpl from '@solana/crypto-impl';\n\nimport {\n    exportKeyPolyfill,\n    generateKeyPolyfill,\n    importKeyPolyfill,\n    isPolyfilledKey,\n    signPolyfill,\n    verifyPolyfill,\n} from './secrets';\n\nfunction isAlgorithmEd25519(putativeEd25519Algorithm: AlgorithmIdentifier): boolean {\n    const name =\n        typeof putativeEd25519Algorithm === 'string' ? putativeEd25519Algorithm : putativeEd25519Algorithm.name;\n    return name.localeCompare('Ed25519', 'en-US', { sensitivity: 'base' }) === 0;\n}\n\n/**\n * Polyfills methods on `globalThis.SubtleCrypto` to add support for the Ed25519 algorithm.\n *\n * @example\n * ```ts\n * import { install } from '@solana/webcrypto-ed25519-polyfill';\n *\n * // Calling this will shim methods on `SubtleCrypto`, adding Ed25519 support.\n * install();\n *\n * // Now you can do this, in environments that do not otherwise support Ed25519.\n * const keyPair = await crypto.subtle.generateKey({ name: 'Ed25519' }, false, ['sign']);\n * const publicKeyBytes = await crypto.subtle.exportKey('raw', keyPair.publicKey);\n * const data = new Uint8Array([1, 2, 3]);\n * const signature = await crypto.subtle.sign({ name: 'Ed25519' }, keyPair.privateKey, data);\n * if (await crypto.subtle.verify({ name: 'Ed25519' }, keyPair.publicKey, signature, data)) {\n *     console.log('Data was signed using the private key associated with this public key');\n * } else {\n *     throw new Error('Signature verification error');\n * }\n * ```\n */\nexport function install() {\n    if (__NODEJS__) {\n        /**\n         * Node only sets the `crypto` global variable when run with `--experimental-global-webcrypto`.\n         * Let's set it unconditionally here.\n         */\n        globalThis.crypto ||= cryptoImpl;\n    }\n\n    if (!__BROWSER__ || globalThis.isSecureContext) {\n        /**\n         * Create `crypto.subtle` if it doesn't exist.\n         */\n        const originalCryptoObject = (globalThis.crypto ||= {} as Crypto);\n        const originalSubtleCrypto = ((originalCryptoObject as Crypto & { subtle: SubtleCrypto }).subtle ||=\n            {} as SubtleCrypto);\n\n        /**\n         * Override `SubtleCrypto#exportKey`\n         */\n        const originalExportKey = originalSubtleCrypto.exportKey as SubtleCrypto['exportKey'] | undefined;\n        originalSubtleCrypto.exportKey = (async (...args: Parameters<SubtleCrypto['exportKey']>) => {\n            const [_, key] = args;\n            if (isPolyfilledKey(key)) {\n                return await exportKeyPolyfill(...args);\n            } else if (originalExportKey) {\n                return await originalExportKey.apply(originalSubtleCrypto, args);\n            } else {\n                throw new TypeError('No native `exportKey` function exists to handle this call');\n            }\n        }) as SubtleCrypto['exportKey'];\n\n        /**\n         * Override `SubtleCrypto#generateKey`\n         */\n        const originalGenerateKey = originalSubtleCrypto.generateKey as SubtleCrypto['generateKey'] | undefined;\n        let originalGenerateKeySupportsEd25519: Promise<boolean> | boolean | undefined;\n        originalSubtleCrypto.generateKey = (async (...args: Parameters<SubtleCrypto['generateKey']>) => {\n            const [algorithm] = args;\n            if (!isAlgorithmEd25519(algorithm)) {\n                if (originalGenerateKey) {\n                    return await originalGenerateKey.apply(originalSubtleCrypto, args);\n                } else {\n                    throw new TypeError('No native `generateKey` function exists to handle this call');\n                }\n            }\n            let optimisticallyGeneratedKeyPair;\n            if (originalGenerateKeySupportsEd25519 === undefined) {\n                originalGenerateKeySupportsEd25519 = new Promise(resolve => {\n                    if (!originalGenerateKey) {\n                        resolve((originalGenerateKeySupportsEd25519 = false));\n                        return;\n                    }\n                    originalGenerateKey\n                        .apply(originalSubtleCrypto, args)\n                        .then(keyPair => {\n                            if (__DEV__) {\n                                console.warn(\n                                    '`@solana/webcrypto-ed25519-polyfill` was installed in an ' +\n                                        'environment that supports Ed25519 key manipulation ' +\n                                        'natively. Falling back to the native implementation. ' +\n                                        'Consider installing this polyfill only in environments where ' +\n                                        'Ed25519 is not supported.',\n                                );\n                            }\n                            if (originalSubtleCrypto.generateKey !== originalGenerateKey) {\n                                originalSubtleCrypto.generateKey = originalGenerateKey;\n                            }\n                            optimisticallyGeneratedKeyPair = keyPair;\n                            resolve((originalGenerateKeySupportsEd25519 = true));\n                        })\n                        .catch(() => {\n                            resolve((originalGenerateKeySupportsEd25519 = false));\n                        });\n                });\n            }\n            if (\n                typeof originalGenerateKeySupportsEd25519 === 'boolean'\n                    ? originalGenerateKeySupportsEd25519\n                    : await originalGenerateKeySupportsEd25519\n            ) {\n                if (optimisticallyGeneratedKeyPair) {\n                    return optimisticallyGeneratedKeyPair;\n                } else if (originalGenerateKey) {\n                    return await originalGenerateKey.apply(originalSubtleCrypto, args);\n                } else {\n                    throw new TypeError('No native `generateKey` function exists to handle this call');\n                }\n            } else {\n                const [_, extractable, keyUsages] = args;\n                return generateKeyPolyfill(extractable, keyUsages);\n            }\n        }) as SubtleCrypto['generateKey'];\n\n        /**\n         * Override `SubtleCrypto#sign`\n         */\n        const originalSign = originalSubtleCrypto.sign as SubtleCrypto['sign'] | undefined;\n        originalSubtleCrypto.sign = (async (...args: Parameters<SubtleCrypto['sign']>) => {\n            const [_, key] = args;\n            if (isPolyfilledKey(key)) {\n                const [_, ...rest] = args;\n                return await signPolyfill(...rest);\n            } else if (originalSign) {\n                return await originalSign.apply(originalSubtleCrypto, args);\n            } else {\n                throw new TypeError('No native `sign` function exists to handle this call');\n            }\n        }) as SubtleCrypto['sign'];\n\n        /**\n         * Override `SubtleCrypto#verify`\n         */\n        const originalVerify = originalSubtleCrypto.verify as SubtleCrypto['verify'] | undefined;\n        originalSubtleCrypto.verify = (async (...args: Parameters<SubtleCrypto['verify']>) => {\n            const [_, key] = args;\n            if (isPolyfilledKey(key)) {\n                const [_, ...rest] = args;\n                return await verifyPolyfill(...rest);\n            } else if (originalVerify) {\n                return await originalVerify.apply(originalSubtleCrypto, args);\n            } else {\n                throw new TypeError('No native `verify` function exists to handle this call');\n            }\n        }) as SubtleCrypto['verify'];\n\n        /**\n         * Override `SubtleCrypto#importKey`\n         */\n        const originalImportKey = originalSubtleCrypto.importKey as SubtleCrypto['importKey'] | undefined;\n        let originalImportKeySupportsEd25519: Promise<boolean> | boolean | undefined;\n        originalSubtleCrypto.importKey = (async (...args: Parameters<SubtleCrypto['importKey']>) => {\n            const [format, keyData, algorithm] = args;\n            if (!isAlgorithmEd25519(algorithm)) {\n                if (originalImportKey) {\n                    return await originalImportKey.apply(originalSubtleCrypto, args);\n                } else {\n                    throw new TypeError('No native `importKey` function exists to handle this call');\n                }\n            }\n            let optimisticallyImportedKey;\n            if (originalImportKeySupportsEd25519 === undefined) {\n                originalImportKeySupportsEd25519 = new Promise(resolve => {\n                    if (!originalImportKey) {\n                        resolve((originalImportKeySupportsEd25519 = false));\n                        return;\n                    }\n                    originalImportKey\n                        .apply(originalSubtleCrypto, args)\n                        .then(key => {\n                            if (__DEV__) {\n                                console.warn(\n                                    '`@solana/webcrypto-ed25519-polyfill` was included in an ' +\n                                        'environment that supports Ed25519 key manipulation ' +\n                                        'natively. Falling back to the native implementation. ' +\n                                        'Consider including this polyfill only in environments where ' +\n                                        'Ed25519 is not supported.',\n                                );\n                            }\n                            if (originalSubtleCrypto.importKey !== originalImportKey) {\n                                originalSubtleCrypto.importKey = originalImportKey;\n                            }\n                            optimisticallyImportedKey = key;\n                            resolve((originalImportKeySupportsEd25519 = true));\n                        })\n                        .catch(() => {\n                            resolve((originalImportKeySupportsEd25519 = false));\n                        });\n                });\n            }\n            if (\n                typeof originalImportKey === 'boolean'\n                    ? originalImportKeySupportsEd25519\n                    : await originalImportKeySupportsEd25519\n            ) {\n                if (optimisticallyImportedKey) {\n                    return optimisticallyImportedKey;\n                } else if (originalImportKey) {\n                    return await originalImportKey.apply(originalSubtleCrypto, args);\n                } else {\n                    throw new TypeError('No native `importKey` function exists to handle this call');\n                }\n            } else {\n                const [_format, _keyData, _algorithm, extractable, keyUsages] = args;\n                return importKeyPolyfill(format, keyData, extractable, keyUsages);\n            }\n        }) as SubtleCrypto['importKey'];\n    }\n}\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/src/secrets.ts",
    "content": "/**\n *      HEY!   <== SECRET KEY KOALA\n *      |/     <== WOULD LIKE YOUR\n *   ʕ·͡ᴥ·ʔ     <== ATTENTION PLEASE\n *\n * Key material generated in this module must stay in this module. So long as the secrets cache and\n * the methods that interact with it are not exported from `@solana/webcrypto-ed25519-polyfill`,\n * accidental logging of the actual bytes of a secret key (eg. to the console, or to a remote\n * server) should not be possible.\n *\n * WARNING: This does not imply that the secrets cache is secure against supply-chain attacks.\n * Untrusted code in your JavaScript context can easily override `WeakMap.prototype.set` to steal\n * private keys as they are written to the cache, without alerting you to its presence or affecting\n * the regular operation of the cache.\n */\nimport { getPublicKeyAsync, signAsync, utils, verifyAsync } from '@noble/ed25519';\n\nconst PROHIBITED_KEY_USAGES = new Set<KeyUsage>([\n    'decrypt',\n    'deriveBits',\n    'deriveKey',\n    'encrypt',\n    'unwrapKey',\n    'wrapKey',\n]);\n\nconst ED25519_PKCS8_HEADER =\n    // prettier-ignore\n    [\n        /**\n         * PKCS#8 header\n         */\n        0x30, // ASN.1 sequence tag\n        0x2e, // Length of sequence (46 more bytes)\n\n            0x02, // ASN.1 integer tag\n            0x01, // Length of integer\n                0x00, // Version number\n\n            0x30, // ASN.1 sequence tag\n            0x05, // Length of sequence\n                0x06, // ASN.1 object identifier tag\n                0x03, // Length of object identifier\n                    // Edwards curve algorithms identifier https://oid-rep.orange-labs.fr/get/1.3.101.112\n                        0x2b, // iso(1) / identified-organization(3) (The first node is multiplied by the decimal 40 and the result is added to the value of the second node)\n                        0x65, // thawte(101)\n                    // Ed25519 identifier\n                        0x70, // id-Ed25519(112)\n\n        /**\n         * Private key payload\n         */\n        0x04, // ASN.1 octet string tag\n        0x22, // String length (34 more bytes)\n\n            // Private key bytes as octet string\n            0x04, // ASN.1 octet string tag\n            0x20, // String length (32 bytes)\n    ];\n\nfunction bufferSourceToUint8Array(data: BufferSource): Uint8Array {\n    return data instanceof Uint8Array ? data : new Uint8Array(ArrayBuffer.isView(data) ? data.buffer : data);\n}\n\nlet storageKeyBySecretKey_INTERNAL_ONLY_DO_NOT_EXPORT: WeakMap<CryptoKey, Uint8Array> | undefined;\n\n// Map of public key bytes. These are the result of calling `getPublicKey`\nlet publicKeyBytesStore: WeakMap<CryptoKey, Uint8Array> | undefined;\n\nfunction createKeyPairFromBytes(\n    bytes: Uint8Array,\n    extractable: boolean,\n    keyUsages: readonly KeyUsage[],\n): CryptoKeyPair {\n    const keyPair = createKeyPair_INTERNAL_ONLY_DO_NOT_EXPORT(extractable, keyUsages);\n    const cache = (storageKeyBySecretKey_INTERNAL_ONLY_DO_NOT_EXPORT ||= new WeakMap());\n    cache.set(keyPair.privateKey, bytes);\n    cache.set(keyPair.publicKey, bytes);\n    return keyPair;\n}\n\nfunction createKeyPair_INTERNAL_ONLY_DO_NOT_EXPORT(\n    extractable: boolean,\n    keyUsages: readonly KeyUsage[],\n): CryptoKeyPair {\n    if (keyUsages.length === 0) {\n        throw new DOMException('Usages cannot be empty when creating a key.', 'SyntaxError');\n    }\n    if (keyUsages.some(usage => PROHIBITED_KEY_USAGES.has(usage))) {\n        throw new DOMException('Unsupported key usage for an Ed25519 key.', 'SyntaxError');\n    }\n    const base = {\n        [Symbol.toStringTag]: 'CryptoKey',\n        algorithm: Object.freeze({ name: 'Ed25519' }),\n    };\n    const privateKey = {\n        ...base,\n        extractable,\n        type: 'private',\n        usages: Object.freeze(keyUsages.filter(usage => usage === 'sign')) as KeyUsage[],\n    } as CryptoKey;\n    const publicKey = {\n        ...base,\n        extractable: true,\n        type: 'public',\n        usages: Object.freeze(keyUsages.filter(usage => usage === 'verify')) as KeyUsage[],\n    } as CryptoKey;\n    return Object.freeze({\n        privateKey: Object.freeze(privateKey),\n        publicKey: Object.freeze(publicKey),\n    });\n}\n\nfunction getSecretKeyBytes_INTERNAL_ONLY_DO_NOT_EXPORT(key: CryptoKey): Uint8Array {\n    const secretKeyBytes = storageKeyBySecretKey_INTERNAL_ONLY_DO_NOT_EXPORT?.get(key);\n    if (secretKeyBytes === undefined) {\n        throw new Error('Could not find secret key material associated with this `CryptoKey`');\n    }\n    return secretKeyBytes;\n}\n\nasync function getPublicKeyBytes(key: CryptoKey): Promise<Uint8Array> {\n    // Try to find the key in the public key store first\n    const publicKeyStore = (publicKeyBytesStore ||= new WeakMap());\n    const fromPublicStore = publicKeyStore.get(key);\n    if (fromPublicStore) return fromPublicStore;\n\n    // If not available, get the key from the secrets store instead\n    const publicKeyBytes = await getPublicKeyAsync(getSecretKeyBytes_INTERNAL_ONLY_DO_NOT_EXPORT(key));\n\n    // Store the public key bytes in the public key store for next time\n    publicKeyStore.set(key, publicKeyBytes);\n    return publicKeyBytes;\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n    return btoa(Array.from(bytes, b => String.fromCharCode(b)).join(''))\n        .replace(/\\+/g, '-')\n        .replace(/\\//g, '_')\n        .replace(/=+$/, '');\n}\n\nfunction base64UrlDecode(value: string): Uint8Array {\n    const m = value.length % 4;\n    const base64Value = value\n        .replace(/-/g, '+')\n        .replace(/_/g, '/')\n        .padEnd(value.length + (m === 0 ? 0 : 4 - m), '=');\n    return Uint8Array.from(atob(base64Value), c => c.charCodeAt(0));\n}\n\nexport async function exportKeyPolyfill(format: 'jwk', key: CryptoKey): Promise<JsonWebKey>;\nexport async function exportKeyPolyfill(format: KeyFormat, key: CryptoKey): Promise<ArrayBuffer>;\nexport async function exportKeyPolyfill(format: KeyFormat, key: CryptoKey): Promise<ArrayBuffer | JsonWebKey> {\n    if (key.extractable === false) {\n        throw new DOMException('key is not extractable', 'InvalidAccessException');\n    }\n    switch (format) {\n        case 'raw': {\n            if (key.type !== 'public') {\n                throw new DOMException(`Unable to export a raw Ed25519 ${key.type} key`, 'InvalidAccessError');\n            }\n            const publicKeyBytes = await getPublicKeyBytes(key);\n            return publicKeyBytes.buffer as ArrayBuffer;\n        }\n        case 'pkcs8': {\n            if (key.type !== 'private') {\n                throw new DOMException(`Unable to export a pkcs8 Ed25519 ${key.type} key`, 'InvalidAccessError');\n            }\n            const secretKeyBytes = getSecretKeyBytes_INTERNAL_ONLY_DO_NOT_EXPORT(key);\n            const result = new Uint8Array(ED25519_PKCS8_HEADER.length + secretKeyBytes.length);\n            result.set(ED25519_PKCS8_HEADER, 0);\n            result.set(secretKeyBytes, ED25519_PKCS8_HEADER.length);\n            return result.buffer;\n        }\n        case 'jwk': {\n            const publicKeyBytes = await getPublicKeyBytes(key);\n            const base = {\n                crv /* curve */: 'Ed25519',\n                ext /* extractable */: key.extractable,\n                key_ops /* key operations */: key.usages,\n                kty /* key type */: 'OKP' /* octet key pair */,\n                x /* public key x-coordinate (base64-URL encoded) */: base64UrlEncode(publicKeyBytes),\n            };\n            if (key.type === 'private') {\n                const secretKeyBytes = getSecretKeyBytes_INTERNAL_ONLY_DO_NOT_EXPORT(key);\n                return Object.freeze({\n                    ...base,\n                    d /* private key (base64-URL encoded) */: base64UrlEncode(secretKeyBytes),\n                });\n            }\n            return Object.freeze({ ...base });\n        }\n        default:\n            throw new Error(`Exporting polyfilled Ed25519 keys in the \"${format}\" format is unimplemented`);\n    }\n}\n\n/**\n * This function generates a key pair and stores the secret bytes associated with it in a\n * module-private cache. Instead of vending the actual secret bytes, it returns a `CryptoKeyPair`\n * that you can use with other methods in this package to produce signatures and derive public keys\n * associated with the secret.\n */\nexport function generateKeyPolyfill(extractable: boolean, keyUsages: readonly KeyUsage[]): CryptoKeyPair {\n    const privateKeyBytes = utils.randomSecretKey();\n    const keyPair = createKeyPairFromBytes(privateKeyBytes, extractable, keyUsages);\n    return keyPair;\n}\n\nexport function isPolyfilledKey(key: CryptoKey): boolean {\n    return !!storageKeyBySecretKey_INTERNAL_ONLY_DO_NOT_EXPORT?.has(key) || !!publicKeyBytesStore?.has(key);\n}\n\nexport async function signPolyfill(key: CryptoKey, data: BufferSource): Promise<ArrayBuffer> {\n    if (key.type !== 'private' || !key.usages.includes('sign')) {\n        throw new DOMException('Unable to use this key to sign', 'InvalidAccessError');\n    }\n    const privateKeyBytes = getSecretKeyBytes_INTERNAL_ONLY_DO_NOT_EXPORT(key);\n    const payload = bufferSourceToUint8Array(data);\n    const signature = await signAsync(payload, privateKeyBytes);\n    return signature.buffer as ArrayBuffer;\n}\n\nexport async function verifyPolyfill(key: CryptoKey, signature: BufferSource, data: BufferSource): Promise<boolean> {\n    if (key.type !== 'public' || !key.usages.includes('verify')) {\n        throw new DOMException('Unable to use this key to verify', 'InvalidAccessError');\n    }\n    const publicKeyBytes = await getPublicKeyBytes(key);\n    try {\n        return await verifyAsync(bufferSourceToUint8Array(signature), bufferSourceToUint8Array(data), publicKeyBytes);\n    } catch {\n        return false;\n    }\n}\n\nfunction assertValidKeyUsages(keyUsages: readonly KeyUsage[], type: 'private' | 'public') {\n    const prohibitedKeyUses = new Set<KeyUsage>([\n        ...((type === 'private' ? ['verify'] : ['sign']) as KeyUsage[]),\n        ...PROHIBITED_KEY_USAGES,\n    ]);\n    if (keyUsages.some(usage => prohibitedKeyUses.has(usage))) {\n        throw new DOMException('Unsupported key usage for a Ed25519 key', 'SyntaxError');\n    }\n}\n\nexport function importKeyPolyfill(\n    format: 'jwk',\n    keyData: JsonWebKey,\n    extractable: boolean,\n    keyUsages: readonly KeyUsage[],\n): CryptoKey;\nexport function importKeyPolyfill(\n    format: Exclude<KeyFormat, 'jwk'>,\n    keyData: BufferSource,\n    extractable: boolean,\n    keyUsages: readonly KeyUsage[],\n): CryptoKey;\nexport function importKeyPolyfill(\n    format: KeyFormat,\n    keyData: BufferSource | JsonWebKey,\n    extractable: boolean,\n    keyUsages: readonly KeyUsage[],\n): CryptoKey {\n    if (format === 'raw') {\n        const bytes = bufferSourceToUint8Array(keyData as BufferSource);\n        assertValidKeyUsages(keyUsages, 'public');\n        if (bytes.length !== 32) {\n            throw new DOMException('Ed25519 raw keys must be exactly 32-bytes', 'DataError');\n        }\n        const publicKey = {\n            [Symbol.toStringTag]: 'CryptoKey',\n            algorithm: Object.freeze({ name: 'Ed25519' }),\n            extractable,\n            type: 'public',\n            usages: Object.freeze(keyUsages.filter(usage => usage === 'verify')) as KeyUsage[],\n        } as CryptoKey;\n\n        const cache = (publicKeyBytesStore ||= new WeakMap());\n        cache.set(publicKey, bytes);\n\n        return publicKey;\n    }\n\n    if (format === 'pkcs8') {\n        const bytes = bufferSourceToUint8Array(keyData as BufferSource);\n        assertValidKeyUsages(keyUsages, 'private');\n        // 48 bytes: 16-byte PKCS8 header + 32 byte secret key\n        if (bytes.length !== 48) {\n            throw new DOMException('Invalid keyData', 'DataError');\n        }\n        // Must start with exactly the Ed25519 pkcs8 header\n        const header = bytes.slice(0, 16);\n        if (!header.every((val, i) => val === ED25519_PKCS8_HEADER[i])) {\n            throw new DOMException('Invalid keyData', 'DataError');\n        }\n        const secretKeyBytes = bytes.slice(16);\n\n        const privateKey = {\n            [Symbol.toStringTag]: 'CryptoKey',\n            algorithm: Object.freeze({ name: 'Ed25519' }),\n            extractable,\n            type: 'private',\n            usages: Object.freeze(keyUsages.filter(usage => usage === 'sign')) as KeyUsage[],\n        } as CryptoKey;\n\n        const cache = (storageKeyBySecretKey_INTERNAL_ONLY_DO_NOT_EXPORT ||= new WeakMap());\n        cache.set(privateKey, secretKeyBytes);\n\n        return privateKey;\n    }\n\n    if (format === 'jwk') {\n        const jwk = keyData as JsonWebKey;\n        const type = 'd' in jwk ? 'private' : 'public';\n        assertValidKeyUsages(keyUsages, type);\n        const keyOps = new Set(jwk.key_ops ?? []);\n        const sameKeyUsages = keyUsages.length === keyOps.size && [...keyUsages].every(x => keyOps.has(x));\n        if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519' || jwk.ext !== extractable || !sameKeyUsages) {\n            throw new DOMException('Invalid Ed25519 JWK', 'DataError');\n        }\n        if (type === 'public' && !jwk.x) {\n            throw new DOMException('Ed25519 JWK is missing public key coordinates', 'DataError');\n        }\n        if (type === 'private' && !jwk.d) {\n            throw new DOMException('Ed25519 JWK is missing private key coordinates', 'DataError');\n        }\n        const usageToKeep = type === 'public' ? 'verify' : 'sign';\n        const key = Object.freeze({\n            [Symbol.toStringTag]: 'CryptoKey',\n            algorithm: Object.freeze({ name: 'Ed25519' }),\n            extractable,\n            type,\n            usages: Object.freeze(keyUsages.filter(usage => usage === usageToKeep)) as KeyUsage[],\n        }) as CryptoKey;\n\n        if (type === 'public') {\n            const cache = (publicKeyBytesStore ||= new WeakMap());\n            cache.set(key, base64UrlDecode(jwk.x!));\n        } else {\n            const cache = (storageKeyBySecretKey_INTERNAL_ONLY_DO_NOT_EXPORT ||= new WeakMap());\n            cache.set(key, base64UrlDecode(jwk.d!));\n        }\n\n        return key;\n    }\n\n    throw new Error(`Importing Ed25519 keys in the \"${format}\" format is unimplemented`);\n}\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.ts\"]\n}\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\", \"ES2015\", \"ES2022.Error\", \"ES2022\"]\n    },\n    \"display\": \"@solana/webcrypto-ed25519-polyfill\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/webcrypto-ed25519-polyfill/typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"extends\": [\"../../typedoc.json\"],\n    \"entryPoints\": [\"src/index.ts\"],\n    \"readme\": \"none\",\n    \"out\": \"./.docs\"\n}\n"
  },
  {
    "path": "packages/ws-impl/.gitignore",
    "content": "dist/\n"
  },
  {
    "path": "packages/ws-impl/.npmrc",
    "content": "engine-strict=true\n"
  },
  {
    "path": "packages/ws-impl/.prettierignore",
    "content": "# Changelogs are autogenerated, so leave them alone\nCHANGELOG.md\n\ndist/\n"
  },
  {
    "path": "packages/ws-impl/LICENSE",
    "content": "Copyright (c) 2023 Solana Labs, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "packages/ws-impl/package.json",
    "content": "{\n    \"name\": \"@solana/ws-impl\",\n    \"version\": \"0.0.0\",\n    \"private\": true,\n    \"exports\": {\n        \"edge-light\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"workerd\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        },\n        \"browser\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.browser.mjs\",\n            \"require\": \"./dist/index.browser.cjs\"\n        },\n        \"node\": {\n            \"types\": \"./dist/types/index.browser.d.ts\",\n            \"import\": \"./dist/index.node.mjs\",\n            \"require\": \"./dist/index.node.cjs\"\n        }\n    },\n    \"browser\": {\n        \"./dist/index.node.cjs\": \"./dist/index.browser.cjs\",\n        \"./dist/index.node.mjs\": \"./dist/index.browser.mjs\"\n    },\n    \"main\": \"./dist/index.node.cjs\",\n    \"module\": \"./dist/index.node.mjs\",\n    \"types\": \"./dist/types/index.browser.d.ts\",\n    \"type\": \"commonjs\",\n    \"files\": [\n        \"./dist/\"\n    ],\n    \"sideEffects\": false,\n    \"scripts\": {\n        \"compile:js\": \"tsup\",\n        \"compile:typedefs\": \"tsc -p ./tsconfig.declarations.json\",\n        \"dev\": \"NODE_OPTIONS=\\\"--no-experimental-webstorage\\\" jest -c ../../node_modules/@solana/test-config/jest-dev.config.js --rootDir . --watch\",\n        \"style:fix\": \"pnpm eslint --fix src && pnpm prettier --log-level warn --ignore-unknown --write ./*\",\n        \"test:lint\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-lint.config.js --rootDir . --silent\",\n        \"test:prettier\": \"TERM_OVERRIDE=\\\"${TURBO_HASH:+dumb}\\\" TERM=${TERM_OVERRIDE:-$TERM} jest -c ../../node_modules/@solana/test-config/jest-prettier.config.js --rootDir . --silent\",\n        \"test:treeshakability:browser\": \"agadoo dist/index.browser.mjs\",\n        \"test:treeshakability:node\": \"agadoo dist/index.node.mjs\",\n        \"test:typecheck\": \"tsc --noEmit\"\n    },\n    \"browserslist\": [\n        \"supports bigint and not dead\",\n        \"maintained node versions\"\n    ],\n    \"dependencies\": {\n        \"ws\": \"^8.19.0\"\n    },\n    \"devDependencies\": {\n        \"@types/ws\": \"^8.18.1\"\n    },\n    \"engines\": {\n        \"node\": \">=20.18.0\"\n    }\n}\n"
  },
  {
    "path": "packages/ws-impl/src/index.browser.ts",
    "content": "export default globalThis.WebSocket;\n"
  },
  {
    "path": "packages/ws-impl/src/index.node.ts",
    "content": "// When building the browser bundle, this import gets replaced by `globalThis.WebSocket`.\nimport WebSocketImpl from 'ws';\n\nexport default globalThis.WebSocket\n    ? globalThis.WebSocket // Use native `WebSocket` in runtimes that support it (eg. Deno)\n    : WebSocketImpl;\n"
  },
  {
    "path": "packages/ws-impl/tsconfig.declarations.json",
    "content": "{\n    \"compilerOptions\": {\n        \"declaration\": true,\n        \"declarationMap\": true,\n        \"emitDeclarationOnly\": true,\n        \"isolatedModules\": false,\n        \"outDir\": \"./dist/types\"\n    },\n    \"extends\": \"./tsconfig.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src/index.browser.ts\"]\n}\n"
  },
  {
    "path": "packages/ws-impl/tsconfig.json",
    "content": "{\n    \"$schema\": \"https://json.schemastore.org/tsconfig\",\n    \"compilerOptions\": {\n        \"lib\": [\"DOM\"]\n    },\n    \"display\": \"WebSocket Implementation\",\n    \"extends\": \"../tsconfig/base.json\",\n    \"include\": [\"../build-scripts/build-time-constants.d.ts\", \"src\"]\n}\n"
  },
  {
    "path": "packages/ws-impl/tsup.config.ts",
    "content": "import { defineConfig } from 'tsup';\n\nexport default defineConfig(_options =>\n    (['browser', 'node'] as const).map(platform => ({\n        entry: [`./src/index.${platform}.ts`],\n        format: ['cjs', 'esm'],\n        minify: true,\n        name: platform,\n        outExtension({ format }) {\n            return { js: `.${format === 'cjs' ? 'cjs' : 'mjs'}` };\n        },\n        platform,\n        sourcemap: true,\n        treeshake: true,\n    })),\n);\n"
  },
  {
    "path": "patches/jest-runner-prettier@1.0.0.patch",
    "content": "diff --git a/dist/run.js b/dist/run.js\nindex fdee17d2377dd013d55de1d54bee9d241894e800..7139e496da63da74b3e7966f4a3f5a613a7f3b3b 100644\n--- a/dist/run.js\n+++ b/dist/run.js\n@@ -11,7 +11,7 @@ export default async ({ testPath }) => {\n         ...config,\n         filepath: testPath,\n     };\n-    const isPretty = prettier.check(contents, prettierConfig);\n+    const isPretty = await prettier.check(contents, prettierConfig);\n     if (isPretty) {\n         return pass({\n             start,\n@@ -19,7 +19,7 @@ export default async ({ testPath }) => {\n             test: { path: testPath },\n         });\n     }\n-    const formatted = prettier.format(contents, prettierConfig);\n+    const formatted = await prettier.format(contents, prettierConfig);\n     return fail({\n         start,\n         end: Date.now(),\ndiff --git a/src/run.ts b/src/run.ts\nindex 1775851defdca87b753f1f9bae1cb663332eb640..b6c72e13f82d9e9ed3aef5095f8b8d82e2b4391b 100644\n--- a/src/run.ts\n+++ b/src/run.ts\n@@ -19,7 +19,7 @@ export default async ({ testPath }: Parameters): Promise<TestResult> => {\n     filepath: testPath,\n   };\n \n-  const isPretty = prettier.check(contents, prettierConfig);\n+  const isPretty = await prettier.check(contents, prettierConfig);\n   if (isPretty) {\n     return pass({\n       start,\n@@ -28,7 +28,7 @@ export default async ({ testPath }: Parameters): Promise<TestResult> => {\n     });\n   }\n \n-  const formatted = prettier.format(contents, prettierConfig);\n+  const formatted = await prettier.format(contents, prettierConfig);\n \n   return fail({\n     start,\n"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "packages:\n  - \"examples/*\"\n  - \"packages/*\"\n  - \"!docs\""
  },
  {
    "path": "scripts/fixtures/4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc.json",
    "content": "{\n    \"pubkey\": \"4nTLDQiSTRHbngKZWPMfYnZdWTbKiNeuuPcX7yFUpSAc\",\n    \"account\": {\n        \"lamports\": 5000000,\n        \"data\": [\"\", \"base64\"],\n        \"owner\": \"11111111111111111111111111111111\",\n        \"executable\": false,\n        \"rentEpoch\": 18446744073709551615\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G.json",
    "content": "{\n    \"pubkey\": \"GQE2yjns7SKKuMc89tveBDpzYHwXfeuB2PGAbGaPWc6G\",\n    \"account\": {\n        \"lamports\": 5000000,\n        \"data\": [\"dGVzdCBkYXRh\", \"base64\"],\n        \"owner\": \"11111111111111111111111111111111\",\n        \"executable\": false,\n        \"rentEpoch\": 18446744073709551615\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/address-lookup-table-account.json",
    "content": "{\n    \"pubkey\": \"2JPQuT3dHtPjrdcbUQyrrT4XYRYaWpWfmAJ54SUapg6n\",\n    \"account\": {\n        \"data\": [\n            \"AQAAAI12MwwAAAAAYnYzDAAAAAAUATgR6v4LOu4wviGfQe1lBum2+/H1IeKpRkDeMhkqm9y6AADQI/XyGH3om7/5pHAJhrki5tcJTW4kX6mS4fAEzWYR4deqsPLLGciqj8EhloYHITRrPiTT72gY6QNBB/zr0PhqUCHJVotOxkRT57H7oTFRwoYfMYDs9nwZAheSiiL1FA57PNt4RvigKv1twuk55Ogzn+tfgeGhNtBfTARv0jN/Wg/yrp327qpocC+QiduJ0LzkqZ19ewOZciM1Va04jesjqfvt/pip3Qj+DgLampIbdUe0fynrAmXV4YJSuANxClyp++3+mKndCP4OAtqakht1R7R/KesCZdXhglK4A3EKXDgR6v4LOu4wviGfQe1lBum2+/H1IeKpRkDeMhkqm9y6VfrUKEZJIndlDLeAPGvwE06WKFfv7t9Fy7HedodmOyeFrktorQae58nninoqRZtaA1565Zv6DMM3iR89Gw5D6SlwKdZOEU17NxWVjwkFZLWDjH6FN9VzIuqhUvxAGssVxg/Iw8Rta6jup+RZOAxdYHPjxqDs24Gwyvjn3HINC5DIx/w/0Yc9cIkPXv+5ihlU2rv5BhdeZm925f6RWhatYThqp2K6JIlseB98TpwPq/uji77FJxndRwKlP+Y68ntPxXGNw9qbMKsbFnm/gDKRQxd6drl5Nqfz989KkQA8Q3DryDyNX6631uM+XLrSuAGPBHbW1Ey8VAtO6lA8KGdMVns823hG+KAq/W3C6Tnk6DOf61+B4aE20F9MBG/SM39a2+UDE1OmQUZJDqEfeOyAJd/SE//RClEwKvoq/p3xC8vSZABSlqi9ucEVFcmqMYMjnv5amp+KiWa13q7jr+tfZwbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpjJclj04kifG7PRApFI4NgwtaE5na/xCEBI572Nvp+FnSZABSlqi9ucEVFcmqMYMjnv5amp+KiWa13q7jr+tfZ6vgTkVK7OAFB4Bv63on6VwF4ybipHoDxzwsGujqQdHoFMB871n4679QeH5hCDzOFK6ihcxiboeLDkmlc/HVKTkGp9UXGHvRZjXa1ARV/cLAwSTGjyFWdaXbustfCAAAAAiv+JTD+mfAFjow8jSjPTRn8DqhZBcxXrS4FCe9m6btAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAAtwZbHj0XxFOJ1Sf2sEw81YuGxzGqD9tUm20bwD+ClGYTeQN+NM7gwaeQrcppgZrKYuOillXb36JmSpcEIt2V84Qibyy69UXVjAvVfUF9+nsFI/ppZVEmg4ElC2lXE9T9hZc7jryuUVnb0tlrPh4Ur1r9Q9ywb9rcVrMbTBElctp9b1nVOC3hf4/+JTnfI6kNi60wOw0XpL8xUzNC7ChKx+ZVNejgZuTagI8xvWcygqVTnvoZLdbpz9acnb9nkNVUWS2lXKKEcPWkGgmLfaJBf7dq2ZSPT6viXJ4j4FUxHdC3d0s7uRvQfA3p9rRCiKWGK8wSZRNyzKqBDMuatd7mQ1s1iOZhy+22+GKrxZ3NEabXmaCH/7csdXhgd4fMoyYI8ENirft9mPimlbINM43DRmWOu/vInn9zi9VGROCbki2+UDE1OmQUZJDqEfeOyAJd/SE//RClEwKvoq/p3xC8s=\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"AddressLookupTab1e1111111111111111111111111\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/bpf-upgradeable-loader-program-account.json",
    "content": "{\n    \"pubkey\": \"AfFRmCFz8yUWzug2jiRc13xEEzBwyxxYSRGVE5uQMpHk\",\n    \"account\": {\n        \"data\": [\"AgAAACt+ktmovAPSjvOk0jD6edVhyWXMcbWPzaLOt45/0mJA\", \"base64\"],\n        \"executable\": true,\n        \"lamports\": 10290815,\n        \"owner\": \"BPFLoaderUpgradeab1e11111111111111111111111\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/config-stake-account.json",
    "content": "{\n    \"pubkey\": \"StakeConfig11111111111111111111111111111111\",\n    \"account\": {\n        \"data\": [\"AAAAAAAAANA/DA==\", \"base64\"],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"Config1111111111111111111111111111111111111\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/config-validator-account.json",
    "content": "{\n    \"pubkey\": \"FtLZBmDW4Y6WNTYYZv9AcC2nQupDMDzX5Q5mp5MLpmdY\",\n    \"account\": {\n        \"data\": [\n            \"AgdRlwF0SPKsXcI8nrx6x4wKJyV6xhRFjeCk8W+AAAAAAEXqPSOJPmUB67o0lPJCaryYTiR2ynAOH8K4R+ND6rPxAToAAAAAAAAAeyJuYW1lIjoiSG9sZFRoZU5vZGUiLCJ3ZWJzaXRlIjoiaHR0cHM6Ly9ob2xkdGhlbm9kZS5jb20ifQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"Config1111111111111111111111111111111111111\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/example-deserialize-transaction-address-lookup-table.json",
    "content": "{\n    \"pubkey\": \"DUbh3qSh4Vvxa52LGtCBCcuvAEMh62FLNkupnsBjhrCc\",\n    \"account\": {\n        \"data\": [\n            \"AQAAAI12MwwAAAAAYnYzDAAAAAAUATgR6v4LOu4wviGfQe1lBum2+/H1IeKpRkDeMhkqm9y6AADQI/XyGH3om7/5pHAJhrki5tcJTW4kX6mS4fAEzWYR4deqsPLLGciqj8EhloYHITRrPiTT72gY6QNBB/zr0PhqUCHJVotOxkRT57H7oTFRwoYfMYDs9nwZAheSiiL1FA57PNt4RvigKv1twuk55Ogzn+tfgeGhNtBfTARv0jN/Wg/yrp327qpocC+QiduJ0LzkqZ19ewOZciM1Va04jesjqfvt/pip3Qj+DgLampIbdUe0fynrAmXV4YJSuANxClyp++3+mKndCP4OAtqakht1R7R/KesCZdXhglK4A3EKXDgR6v4LOu4wviGfQe1lBum2+/H1IeKpRkDeMhkqm9y6VfrUKEZJIndlDLeAPGvwE06WKFfv7t9Fy7HedodmOyeFrktorQae58nninoqRZtaA1565Zv6DMM3iR89Gw5D6SlwKdZOEU17NxWVjwkFZLWDjH6FN9VzIuqhUvxAGssVxg/Iw8Rta6jup+RZOAxdYHPjxqDs24Gwyvjn3HINC5DIx/w/0Yc9cIkPXv+5ihlU2rv5BhdeZm925f6RWhatYThqp2K6JIlseB98TpwPq/uji77FJxndRwKlP+Y68ntPxXGNw9qbMKsbFnm/gDKRQxd6drl5Nqfz989KkQA8Q3DryDyNX6631uM+XLrSuAGPBHbW1Ey8VAtO6lA8KGdMVns823hG+KAq/W3C6Tnk6DOf61+B4aE20F9MBG/SM39a2+UDE1OmQUZJDqEfeOyAJd/SE//RClEwKvoq/p3xC8vSZABSlqi9ucEVFcmqMYMjnv5amp+KiWa13q7jr+tfZwbd9uHXZaGT2cvhRs7reawctIXtX1s3kTqM9YV+/wCpjJclj04kifG7PRApFI4NgwtaE5na/xCEBI572Nvp+FnSZABSlqi9ucEVFcmqMYMjnv5amp+KiWa13q7jr+tfZ6vgTkVK7OAFB4Bv63on6VwF4ybipHoDxzwsGujqQdHoFMB871n4679QeH5hCDzOFK6ihcxiboeLDkmlc/HVKTkGp9UXGHvRZjXa1ARV/cLAwSTGjyFWdaXbustfCAAAAAiv+JTD+mfAFjow8jSjPTRn8DqhZBcxXrS4FCe9m6btAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGp9UXGSxcUSGMyUw9SvF/WNruCJuh/UTj29mKAAAAAAtwZbHj0XxFOJ1Sf2sEw81YuGxzGqD9tUm20bwD+ClGYTeQN+NM7gwaeQrcppgZrKYuOillXb36JmSpcEIt2V84Qibyy69UXVjAvVfUF9+nsFI/ppZVEmg4ElC2lXE9T9hZc7jryuUVnb0tlrPh4Ur1r9Q9ywb9rcVrMbTBElctp9b1nVOC3hf4/+JTnfI6kNi60wOw0XpL8xUzNC7ChKx+ZVNejgZuTagI8xvWcygqVTnvoZLdbpz9acnb9nkNVUWS2lXKKEcPWkGgmLfaJBf7dq2ZSPT6viXJ4j4FUxHdC3d0s7uRvQfA3p9rRCiKWGK8wSZRNyzKqBDMuatd7mQ1s1iOZhy+22+GKrxZ3NEabXmaCH/7csdXhgd4fMoyYI8ENirft9mPimlbINM43DRmWOu/vInn9zi9VGROCbki2+UDE1OmQUZJDqEfeOyAJd/SE//RClEwKvoq/p3xC8s=\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"AddressLookupTab1e1111111111111111111111111\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/example-transfer-lamports-source-account.json",
    "content": "{\n    \"pubkey\": \"ED1WqT2hWJLSZtj4TtTdoovmpMrr7zpkUdbfxmcJR1Fq\",\n    \"account\": {\n        \"lamports\": 1000000000,\n        \"data\": [\"\", \"base64\"],\n        \"owner\": \"11111111111111111111111111111111\",\n        \"executable\": false,\n        \"rentEpoch\": 18446744073709551615\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/gpa1.json",
    "content": "{\n    \"pubkey\": \"CcYNb7WqpjaMrNr7B1mapaNfWctZRH7LyAjWRLBGt1Fk\",\n    \"account\": {\n        \"lamports\": 5000000,\n        \"data\": [\"dGVzdCBkYXRh\", \"base64\"],\n        \"owner\": \"DXngmJfjurhnAwbMPgpUGPH6qNvetCKRJ6PiD4ag4PTj\",\n        \"executable\": false,\n        \"rentEpoch\": 18446744073709551615\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/gpa2-1.json",
    "content": "{\n    \"pubkey\": \"C5q1p5UiCVrt6vcLJDGcS4AZ98fahKyb9XkDRdqATK17\",\n    \"account\": {\n        \"lamports\": 5000000,\n        \"data\": [\"dGVzdCBkYXRh\", \"base64\"],\n        \"owner\": \"AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6\",\n        \"executable\": false,\n        \"rentEpoch\": 18446744073709551615\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/gpa2-2.json",
    "content": "{\n    \"pubkey\": \"Hhsoev7Apk5dMbktzLUrsTHuMq9e9GSYBaLcnN2PfdKS\",\n    \"account\": {\n        \"lamports\": 5000000,\n        \"data\": [\"dGVzdCBkYXRh\", \"base64\"],\n        \"owner\": \"AmtpVzo6H6qQCP9dH9wfu5hfa8kKaAFpTJ4aamPYR6V6\",\n        \"executable\": false,\n        \"rentEpoch\": 18446744073709551615\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/nonce-account.json",
    "content": "{\n    \"pubkey\": \"AiZExP8mK4RxDozh4r57knvqSZgkz86HrzPAMx61XMqU\",\n    \"account\": {\n        \"data\": [\n            \"AQAAAAEAAAAsDL6z1hknAtbDjgZSI7IFX/T4ppGnUviTNyfH5/mUSwbRPYfE4oAzOpbdz1sCN+7Dq+r1RfDq7o9TkuvfGbTBiBMAAAAAAAA=\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"11111111111111111111111111111111\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/send-transaction-fee-payer-insufficient-funds.json",
    "content": "{\n    \"pubkey\": \"6Zs91PMyhqyMgNVuT8EnM6f3YjVAVabvVWLjpFSC288q\",\n    \"account\": {\n        \"lamports\": 1,\n        \"data\": [\"\", \"base64\"],\n        \"owner\": \"11111111111111111111111111111111\",\n        \"executable\": false,\n        \"rentEpoch\": 18446744073709551615\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/send-transaction-fee-payer.json",
    "content": "{\n    \"pubkey\": \"DRtXHDgC312wpNdNCSb8vCoXDcofCJcPHdAw4VkJ8L9i\",\n    \"account\": {\n        \"lamports\": 1000000000,\n        \"data\": [\"\", \"base64\"],\n        \"owner\": \"11111111111111111111111111111111\",\n        \"executable\": false,\n        \"rentEpoch\": 18446744073709551615\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-22-account-mega-token.json",
    "content": "{\n    \"pubkey\": \"aUg6iJ3p43hTJsxHrQ1KfqMQYStoFvqcSJRcc51cYzK\",\n    \"account\": {\n        \"data\": [\n            \"RYm8iq8LbcyTLQKCP6wVDptQOvkKvx/PFJtKgrZAeG7ZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGscwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgcAAAANAAAAAgAIAAAAAAAAAAAADwABAAAIAAEAAQsAAQABBQAnAQHGmf+ACSBnwGhPwFsNLGf0R68ypIqgyJhY8PGmjul0JwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC1Oy+19D9M/Ln1h7jIkAZ9g7WaCs4m0zPkPZy7ew5I1hYEN5AEBAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAARAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 4844160,\n        \"owner\": \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\",\n        \"rentEpoch\": 18446744073709551615,\n        \"space\": 568\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-22-mint-account.json",
    "content": "{\n    \"pubkey\": \"CKfatsPMUf8SkiURsDXs7eK6GWb4Jsd6UDbs7twMCWxo\",\n    \"account\": {\n        \"data\": [\n            \"AQAAAF6FlBDp84quKJTnIC3eZq7d8SbOoKlPCfCAsA30E9mWzPZ50PJaAAAFAQEAAABehZQQ6fOKriiU5yAt3mau3fEmzqCpTwnwgLAN9BPZlgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAbABehZQQ6fOKriiU5yAt3mau3fEmzqCpTwnwgLAN9BPZll6FlBDp84quKJTnIC3eZq7d8SbOoKlPCfCAsA30E9mWAAAAAAAAAADHAQAAAAAAAACg3sWtyTU2AADJAQAAAAAAAACg3sWtyTU2sgI=\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-22-mint-mega-token-member.json",
    "content": "{\n    \"pubkey\": \"CXZDzjSrQ5jPaBgk6ckTQrLPTnUURiY2GnAgVCS9Fggz\",\n    \"account\": {\n        \"data\": [\n            \"AQAAANl0oyyj5Em8hjtu2ZP7yo0ugblRsz6hhVJdNo+gAaxzAAAAAAAAAAAJAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARYAQADZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGsc6tEapQBxRcNxhdsw+PGzNq9jCJwADNc6F8reAKgBFSbFwBEAKtEapQBxRcNxhdsw+PGzNq9jCJwADNc6F8reAKgBFSbRYm8iq8LbcyTLQKCP6wVDptQOvkKvx/PFJtKgrZAeG4BAAAA\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 3020640,\n        \"owner\": \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\",\n        \"rentEpoch\": 18446744073709551615,\n        \"space\": 306\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-22-mint-mega-token.json",
    "content": "{\n    \"pubkey\": \"5gSwsLGzyCwgwPJSnxjsQCaFeE19ZFaibHMLky9TDFim\",\n    \"account\": {\n        \"data\": [\n            \"AQAAANl0oyyj5Em8hjtu2ZP7yo0ugblRsz6hhVJdNo+gAaxzAAAAAAAAAAAJAQEAAADZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGscwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQMAIADZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGscwwAIADZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGscwoANADZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGsc1DcOGYAAAAABQBQ3DhmAAAAAAUACQAAAAYAAQABAQBsANl0oyyj5Em8hjtu2ZP7yo0ugblRsz6hhVJdNo+gAaxz2XSjLKPkSbyGO27Zk/vKjS6BuVGzPqGFUl02j6ABrHMAAAAAAAAAAAAAAAAAAAAACwAAAAAAAAAKAAAAAAAAAAAACwAAAAAAAAAKAAQAQQDZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGscwEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAgQDZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGsc8aZ/4AJIGfAaE/AWw0sZ/RHrzKkiqDImFjw8aaO6XQnAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAEAA2XSjLKPkSbyGO27Zk/vKjS6BuVGzPqGFUl02j6ABrHNFibyKrwttzJMtAoI/rBUOm1A6+Qq/H88Um0qCtkB4bhIAQADZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGsc0WJvIqvC23Mky0Cgj+sFQ6bUDr5Cr8fzxSbSoK2QHhuFABAANl0oyyj5Em8hjtu2ZP7yo0ugblRsz6hhVJdNo+gAaxzRYm8iq8LbcyTLQKCP6wVDptQOvkKvx/PFJtKgrZAeG4WAEAA2XSjLKPkSbyGO27Zk/vKjS6BuVGzPqGFUl02j6ABrHNFibyKrwttzJMtAoI/rBUOm1A6+Qq/H88Um0qCtkB4bhMAjQDZdKMso+RJvIY7btmT+8qNLoG5UbM+oYVSXTaPoAGsc0WJvIqvC23Mky0Cgj+sFQ6bUDr5Cr8fzxSbSoK2QHhuCQAAAE1lZ2FUb2tlbgIAAABNVCEAAABodHRwczovL3NwbC5zb2xhbmEuY29tL3Rva2VuLTIwMjIBAAAABAAAAE1lZ2EFAAAAVG9rZW4VAEgA2XSjLKPkSbyGO27Zk/vKjS6BuVGzPqGFUl02j6ABrHNFibyKrwttzJMtAoI/rBUOm1A6+Qq/H88Um0qCtkB4bgAAAADoAwAA\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 8616480,\n        \"owner\": \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\",\n        \"rentEpoch\": 18446744073709551615,\n        \"space\": 1110\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-22-mint-with-token-group-account.json",
    "content": "{\n  \"pubkey\": \"6sN6TS566ttRqmQzSTKxuHBtb8rPNZoqZeiERggev7zW\",\n  \"account\": {\n    \"lamports\": 3104160,\n    \"data\": [\n      \"AQAAAAuARfLVnUapnMQcRvLwNbc6rpo1oEc6fnEXDuKKarLTAAAAAAAAAAAJAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARQAQAALgEXy1Z1GqZzEHEby8DW3Oq6aNaBHOn5xFw7iimqy01cxU4MoCkIxL/2zRHyrRFK8sMA6IKSfkTJUMXZ968+XFQBQAFcxU4MoCkIxL/2zRHyrRFK8sMA6IKSfkTJUMXZ968+XVzFTgygKQjEv/bNEfKtEUrywwDogpJ+RMlQxdn3rz5cAAAAAAAAAAGQAAAAAAAAA\",\n      \"base64\"\n    ],\n    \"owner\": \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\",\n    \"executable\": false,\n    \"rentEpoch\": 18446744073709551615,\n    \"space\": 318\n  }\n}"
  },
  {
    "path": "scripts/fixtures/spl-token-22-mint-with-token-group-member-account.json",
    "content": "{\n  \"pubkey\": \"A2ka2DEVUy1Jm8iuPbXETSKFZQ2wDTq5HW8SrJqMiCi3\",\n  \"account\": {\n    \"lamports\": 3048480,\n    \"data\": [\n      \"AQAAAAuARfLVnUapnMQcRvLwNbc6rpo1oEc6fnEXDuKKarLTAAAAAAAAAAAJAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARYAQAALgEXy1Z1GqZzEHEby8DW3Oq6aNaBHOn5xFw7iimqy04YsBvKfRVpcX/UzDP6iXi06ZN+9eK3UkpkPDdFyT01AFwBIAIYsBvKfRVpcX/UzDP6iXi06ZN+9eK3UkpkPDdFyT01AWnm/p1VNzSsTkvkEEe7qm37RuOWrCeUnPdRnhRCAi0wBAAAAAAAAAA==\",\n      \"base64\"\n    ],\n    \"owner\": \"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb\",\n    \"executable\": false,\n    \"rentEpoch\": 18446744073709551615,\n    \"space\": 310\n  }\n}"
  },
  {
    "path": "scripts/fixtures/spl-token-mint-account-with-delegated.json",
    "content": "{\n    \"pubkey\": \"4SspA9vWmizwcvngHTapwQtpnRrPf8V483giCSaCmy6M\",\n    \"account\": {\n        \"data\": [\n            \"AQAAACwMvrPWGScC1sOOBlIjsgVf9PimkadS+JM3J8fn+ZRLABCl1OgAAAAJAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n        \"rentEpoch\": 0,\n        \"space\": 82\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-mint-account-with-owner.json",
    "content": "{\n    \"pubkey\": \"2nBoNW5B9SdpJYEg9neii7ecCJFwh6UrbXS6HFxkK7Gf\",\n    \"account\": {\n        \"data\": [\n            \"AQAAACwMvrPWGScC1sOOBlIjsgVf9PimkadS+JM3J8fn+ZRLAAAAAAAAAAAJAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n        \"rentEpoch\": 0,\n        \"space\": 82\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-mint-account.json",
    "content": "{\n    \"pubkey\": \"Gh9ZwEmdLJ8DscKNTkTqPbNwLNNBjuSzaG9Vp2KGtKJr\",\n    \"account\": {\n        \"data\": [\n            \"AQAAAOkoOVUJZf/U1krKr0bUXfcxjltPV8kMSH1gYl2Cm4N78eLlNFwmdhcGAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-mint-no-token-accounts.json",
    "content": "{\n    \"pubkey\": \"HWHfrWotTpaNArteqeYDziV1ZX9Lm7WV684NeUCwPPzj\",\n    \"account\": {\n        \"data\": [\n            \"AQAAACwMvrPWGScC1sOOBlIjsgVf9PimkadS+JM3J8fn+ZRLAAAAAAAAAAAJAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 1461600,\n        \"owner\": \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n        \"rentEpoch\": 0,\n        \"space\": 82\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-multisig-account.json",
    "content": "{\n    \"pubkey\": \"4Uh9vK5nnxfskc73asy7AeRYDfZocrv1th9DEjtdCn88\",\n    \"account\": {\n        \"data\": [\n            \"AgIB2y86zXzeWGYwGouJt6FEbb8nLg5UPMEz6t2CJWVD0PRIZd2RCPr4a64lOvhn/t943Vd4CBFnGfFwB41NC1idFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-token-account-delegated.json",
    "content": "{\n    \"pubkey\": \"6uGCrvzPAta1nc6wP9oHvM6sRDu1kXTMuJSJvro4R4xS\",\n    \"account\": {\n        \"data\": [\n            \"MzQJGAUaL2fumioXGww9PVOXgMEaYSUPr/X0cUZdeAYsDL6z1hknAtbDjgZSI7IFX/T4ppGnUviTNyfH5/mUSwAQpdToAAAAAQAAAN++YxbNiIWM+zxxHYuV2FyrImZH2l93yTIUPo7gDw6JAQAAAAAAAAAAAAAAAADodkgXAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n        \"rentEpoch\": 0,\n        \"space\": 165\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-token-account-owner.json",
    "content": "{\n    \"pubkey\": \"GoJdqNkvpf26BAX8cYsV3bb52kbBYt7vT5rqpPGGgK5F\",\n    \"account\": {\n        \"data\": [\n            \"Gm8Iy/4ID/afCSL46M6y025/coiwRHJeND8W2XNpBsTfvmMWzYiFjPs8cR2LldhcqyJmR9pfd8kyFD6O4A8OiQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 2039280,\n        \"owner\": \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n        \"rentEpoch\": 0,\n        \"space\": 165\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/spl-token-token-account.json",
    "content": "{\n    \"pubkey\": \"AyGCwnwxQMCqaU4ixReHt8h5W4dwmxU7eM3BEQBdWVca\",\n    \"account\": {\n        \"data\": [\n            \"6Sg5VQll/9TWSsqvRtRd9zGOW09XyQxIfWBiXYKbg3tRbfSo3iE5g7lQFUZzej7dXNBFemsx9mHsHQF64UlEQ+BvnGLyhiMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/stake-account.json",
    "content": "{\n    \"pubkey\": \"CSg2vQGbnwWdSyJpwK4i3qGfB6FebaV3xQTx4U1MbixN\",\n    \"account\": {\n        \"data\": [\n            \"AgAAAIDVIgAAAAAAIew4IOYWg0ai5I48s8YkuID9Nop6WgtwTQd+Nt/0ybAh7Dgg5haDRqLkjjyzxiS4gP02inpaC3BNB3423/TJsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK0jdm2qTzCVek6Qzfgmj2H4Hw8A6DnJrW76AJ9E7J+m/zB6AAAAAACCAQAAAAAAANcBAAAAAAAAAAAAAAAA0D+ReCEKAAAAAAAAAAA=\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"Stake11111111111111111111111111111111111111\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/fixtures/vote-account.json",
    "content": "{\n    \"pubkey\": \"4QUZQ4c7bZuJ4o4L8tYAEGnePFV27SUFEVmC7BYfsXRp\",\n    \"account\": {\n        \"data\": [\n            \"AgAAAAQwb3iuiTghscLHA7D/Ajwk8VuM/wutYIB4ONKF5GmxBDBveK6JOCGxwscDsP8CPCTxW4z/C61ggHg40oXkabEyHwAAAAAAAAAAULDnEAAAAAAfAAAAAFGw5xAAAAAAHgAAAABSsOcQAAAAAB0AAAAAU7DnEAAAAAAcAAAAAFSw5xAAAAAAGwAAAABVsOcQAAAAABoAAAAAVrDnEAAAAAAZAAAAAFew5xAAAAAAGAAAAABYsOcQAAAAABcAAAAAWbDnEAAAAAAWAAAAAFqw5xAAAAAAFQAAAABbsOcQAAAAABQAAAAAXLDnEAAAAAATAAAAAF2w5xAAAAAAEgAAAABesOcQAAAAABEAAAAAX7DnEAAAAAAQAAAAAGCw5xAAAAAADwAAAABhsOcQAAAAAA4AAAAAYrDnEAAAAAANAAAAAGOw5xAAAAAADAAAAABksOcQAAAAAAsAAAAAZbDnEAAAAAAKAAAAAGaw5xAAAAAACQAAAABnsOcQAAAAAAgAAAAAaLDnEAAAAAAHAAAAAGmw5xAAAAAABgAAAABqsOcQAAAAAAUAAAAAa7DnEAAAAAAEAAAAAGyw5xAAAAAAAwAAAABtsOcQAAAAAAIAAAAAbrDnEAAAAAABAAAAAU+w5xAAAAAAAQAAAAAAAACQAgAAAAAAAAQwb3iuiTghscLHA7D/Ajwk8VuM/wutYIB4ONKF5GmxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAAAAAAAABQAAAAAAAAABRAgAAAAAAAMLyBAcAAAAA9uoEBwAAAABSAgAAAAAAADoCCwcAAAAAwvIEBwAAAABTAgAAAAAAAJ+ZEQcAAAAAOgILBwAAAABUAgAAAAAAAAgxGAcAAAAAn5kRBwAAAABVAgAAAAAAAFzEHgcAAAAACDEYBwAAAABWAgAAAAAAAHWOIwcAAAAAXMQeBwAAAABXAgAAAAAAACuaIwcAAAAAdY4jBwAAAABYAgAAAAAAANGnIwcAAAAAK5ojBwAAAABZAgAAAAAAANWyIwcAAAAA0acjBwAAAABaAgAAAAAAAHS/IwcAAAAA1bIjBwAAAABbAgAAAAAAAJ/LIwcAAAAAdL8jBwAAAABcAgAAAAAAAIbTIwcAAAAAn8sjBwAAAABdAgAAAAAAAEHeIwcAAAAAhtMjBwAAAABeAgAAAAAAAJPmIwcAAAAAQd4jBwAAAABfAgAAAAAAAObyIwcAAAAAk+YjBwAAAABgAgAAAAAAAIf/IwcAAAAA5vIjBwAAAABhAgAAAAAAAO0LJAcAAAAAh/8jBwAAAABiAgAAAAAAAAcTJAcAAAAA7QskBwAAAABjAgAAAAAAANAfJAcAAAAABxMkBwAAAABkAgAAAAAAAEoqJAcAAAAA0B8kBwAAAABlAgAAAAAAAPw0JAcAAAAASiokBwAAAABmAgAAAAAAADdBJAcAAAAA/DQkBwAAAABnAgAAAAAAAEpOJAcAAAAAN0EkBwAAAABoAgAAAAAAAC5cJAcAAAAASk4kBwAAAABpAgAAAAAAAFhlJAcAAAAALlwkBwAAAABqAgAAAAAAAOpvJAcAAAAAWGUkBwAAAABrAgAAAAAAAH93JAcAAAAA6m8kBwAAAABsAgAAAAAAAHaCJAcAAAAAf3ckBwAAAABtAgAAAAAAAK2OJAcAAAAAdoIkBwAAAABuAgAAAAAAAMqbJAcAAAAArY4kBwAAAABvAgAAAAAAAHCnJAcAAAAAypskBwAAAABwAgAAAAAAAGmzJAcAAAAAcKckBwAAAABxAgAAAAAAACe9JAcAAAAAabMkBwAAAAByAgAAAAAAALDIJAcAAAAAJ70kBwAAAABzAgAAAAAAABnWJAcAAAAAsMgkBwAAAAB0AgAAAAAAANTeJAcAAAAAGdYkBwAAAAB1AgAAAAAAAIrsJAcAAAAA1N4kBwAAAAB2AgAAAAAAABr5JAcAAAAAiuwkBwAAAAB3AgAAAAAAAMgHJQcAAAAAGvkkBwAAAAB4AgAAAAAAAJYXJQcAAAAAyAclBwAAAAB5AgAAAAAAAKUkJQcAAAAAlhclBwAAAAB6AgAAAAAAAHoxJQcAAAAApSQlBwAAAAB7AgAAAAAAADs9JQcAAAAAejElBwAAAAB8AgAAAAAAAPVKJQcAAAAAOz0lBwAAAAB9AgAAAAAAAHpWJQcAAAAA9UolBwAAAAB+AgAAAAAAAOVjJQcAAAAAelYlBwAAAAB/AgAAAAAAAH9mJQcAAAAA5WMlBwAAAACAAgAAAAAAAMBzJQcAAAAAf2YlBwAAAACBAgAAAAAAAIF8JQcAAAAAwHMlBwAAAACCAgAAAAAAAMKDJQcAAAAAgXwlBwAAAACDAgAAAAAAAK2SJQcAAAAAwoMlBwAAAACEAgAAAAAAALCeJQcAAAAArZIlBwAAAACFAgAAAAAAAC6rJQcAAAAAsJ4lBwAAAACGAgAAAAAAAI+3JQcAAAAALqslBwAAAACHAgAAAAAAAL7HJQcAAAAAj7clBwAAAACIAgAAAAAAAC7VJQcAAAAAvsclBwAAAACJAgAAAAAAALphKwcAAAAALtUlBwAAAACKAgAAAAAAAGcELAcAAAAAumErBwAAAACLAgAAAAAAACgVLAcAAAAAZwQsBwAAAACMAgAAAAAAABQmLAcAAAAAKBUsBwAAAACNAgAAAAAAAOM0LAcAAAAAFCYsBwAAAACOAgAAAAAAACpCLAcAAAAA4zQsBwAAAACPAgAAAAAAAGhSLAcAAAAAKkIsBwAAAACQAgAAAAAAAAJaLAcAAAAAaFIsBwAAAABusOcQAAAAANXp6WUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\n            \"base64\"\n        ],\n        \"executable\": false,\n        \"lamports\": 10290815,\n        \"owner\": \"Vote111111111111111111111111111111111111111\",\n        \"rentEpoch\": 0\n    }\n}\n"
  },
  {
    "path": "scripts/get-latest-validator-release-version.sh",
    "content": "#!/usr/bin/env bash\n(\n    set -e\n    version=$(node -e \\\n      'fetch(\"https://api.github.com/repos/anza-xyz/agave/releases\").then(res => res.json()).then(rs => { const r = rs.find(r => !r.prerelease && !/alpha|beta|rc/.test(r.tag_name)); if (r) console.log(r.tag_name); });'\n    )\n    if [ -z $version ]; then\n      exit 3\n    fi\n    echo $version\n)\nerrorCode=$?\nif [ $errorCode -ne 0 ]; then\n  # Bust the cache with a timestamp if no version could be found.\n  echo $(date +%s)\nfi"
  },
  {
    "path": "scripts/setup-test-validator.sh",
    "content": "#!/usr/bin/env bash\n\nset -ex\n\nSCRIPTS_DIR=$(dirname \"${BASH_SOURCE[0]}\")\nTARGET_DIR=$( cd \"$SCRIPTS_DIR/..\" ; pwd -P )/.agave\n\n# setup environment\nversion=$(bash $SCRIPTS_DIR/get-latest-validator-release-version.sh)\nsh -c \"$(curl -sSfL https://release.anza.xyz/$version/install)\" init $version --data-dir $TARGET_DIR --no-modify-path\n$TARGET_DIR/active_release/bin/solana --version\n"
  },
  {
    "path": "scripts/start-shared-test-validator.sh",
    "content": "#!/bin/bash\n\n# Run this script when you want to start a test validator.\n# Multiple callers can invoke this script.\n# Only the first caller will start the test validator.\n# Only the last caller to release the lock will shut the validator down.\nLOCK_DIR=\"/tmp/lock\"\nEXCLUSIVE_LOCK_FILE=\"$LOCK_DIR/.agavetestvalidator.exclusivelock\"\nSHARED_LOCK_FILE=\"$LOCK_DIR/.agavetestvalidator.sharedlock\"\nTEST_VALIDATOR=$( cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" ; pwd -P )/.agave/active_release/bin/solana-test-validator\nTEST_VALIDATOR_LEDGER=\"$( cd \"$(dirname \"${BASH_SOURCE[0]}\")/..\" ; pwd -P )/test-ledger\"\nFIXTURE_ACCOUNTS_DIR=\"$( cd \"$(dirname \"${BASH_SOURCE[0]}\")/fixtures\" ; pwd -P)\"\n\nif [ ! -x \"$TEST_VALIDATOR\" ]; then\n    echo \"ERROR: No test validator is installed. Install one using the following command: pnpm test:setup\" >&2\n    exit 1\nfi\n\nmkdir -p $LOCK_DIR\n\n(\n  trap : INT # Resume execution any time we receive SIGINT\n  # Obtain lock on $SHARED_LOCK_FILE (fd 200)\n  flock -s 200 || exit 1\n  (\n    if flock -nx 200; then\n      $TEST_VALIDATOR --ledger $TEST_VALIDATOR_LEDGER --reset --quiet --account-dir $FIXTURE_ACCOUNTS_DIR --rpc-pubsub-enable-vote-subscription >/dev/null &\n      validator_pid=$!\n      echo \"Started test validator (PID $validator_pid)\"\n      wait\n    else\n      echo \"Sharing lock on already running test validator (PID $(pidof $TEST_VALIDATOR))\"\n      sleep 86400000; # 1000 days\n    fi\n  ) 200>$EXCLUSIVE_LOCK_FILE\n  validator_pid=$(pidof $TEST_VALIDATOR)\n  if (exit $?) && ! lsof -p ^$BASHPID -p ^$validator_pid $SHARED_LOCK_FILE >/dev/null; then\n    # We are the last caller with a lock. Kill the validator now.\n    echo \"Terminating test validator (PID $validator_pid)\"\n    kill -n 15 $validator_pid\n    # Wait until we are the last caller with the lock. This way when we exit, we know the lock dies.\n    (flock -x 200) 200>$EXCLUSIVE_LOCK_FILE\n  else\n    echo \"Leaving test validator (PID $validator_pid) running for other lock participants\"\n  fi\n) 200>$SHARED_LOCK_FILE\n"
  },
  {
    "path": "skills-lock.json",
    "content": "{\n  \"version\": 1,\n  \"skills\": {\n    \"changesets\": {\n      \"source\": \"lorisleiva/skills\",\n      \"sourceType\": \"github\",\n      \"computedHash\": \"d3cf32b97909632ddafd1af39de1b66f9b013990e13e78a83ab97abb50094364\"\n    },\n    \"shipping-git\": {\n      \"source\": \"lorisleiva/skills\",\n      \"sourceType\": \"github\",\n      \"computedHash\": \"1e730a4eadb36e5dccae01d0609fc9cfe634349961aa0e45f1b718dd31c2327f\"\n    },\n    \"shipping-graphite\": {\n      \"source\": \"lorisleiva/skills\",\n      \"sourceType\": \"github\",\n      \"computedHash\": \"bd7eebc15668ad09a6dac4c56f981c423a37b17b5fcce869ac93d5c6de36e26e\"\n    },\n    \"ts-docblocks\": {\n      \"source\": \"lorisleiva/skills\",\n      \"sourceType\": \"github\",\n      \"computedHash\": \"5aff2666b4cee7cd31cd21ff71a6951c7874b9df3ad3e8ca29367e11877d7824\"\n    },\n    \"ts-readme\": {\n      \"source\": \"lorisleiva/skills\",\n      \"sourceType\": \"github\",\n      \"computedHash\": \"e693e5a3f3c8a63786ecf52a8c4f8cb0f3870476c7266340ab950c705df08b9f\"\n    }\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n    \"include\": [\"eslint.config.mjs\"],\n    \"references\": [{ \"path\": \"packages/**\" }]\n}\n"
  },
  {
    "path": "turbo.json",
    "content": "{\n    \"$schema\": \"https://turbo.build/schema.json\",\n    \"remoteCache\": {\n        \"signature\": true\n    },\n    \"tasks\": {\n        \"build\": {\n            \"dependsOn\": [\n                \"compile:js\",\n                \"compile:typedefs\",\n                \"test:lint\",\n                \"test:prettier\",\n                \"test:typecheck\",\n                \"test:unit:browser\",\n                \"test:unit:node\",\n                \"test:treeshakability:browser\",\n                \"test:treeshakability:native\",\n                \"test:treeshakability:node\"\n            ],\n            \"outputs\": [\"dist/**\"]\n        },\n        \"compile:docs\": {\n            \"dependsOn\": [\"^compile:typedefs\"],\n            \"inputs\": [\n                \"$TURBO_DEFAULT$\",\n                \"tsconfig.*\",\n                \"$TURBO_ROOT$/typedoc.json\",\n                \"$TURBO_ROOT$/typedoc.plugin.mjs\",\n                \"src/**\"\n            ],\n            \"outputs\": [\".docs/**\"]\n        },\n        \"compile:js\": {\n            \"dependsOn\": [\"^compile:js\"],\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"tsconfig.*\", \"src/**\", \"../build-scripts/*.ts\"],\n            \"outputs\": [\"dist/**\"]\n        },\n        \"compile:typedefs\": {\n            \"dependsOn\": [\"^compile:typedefs\"],\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"tsconfig.*\", \"src/**\"],\n            \"outputs\": [\"dist/**/*.d.ts\"]\n        },\n        \"publish-packages\": {\n            \"dependsOn\": [\n                \"compile:js\",\n                \"compile:typedefs\",\n                \"test:lint\",\n                \"test:prettier\",\n                \"test:typecheck\",\n                \"test:unit:browser\",\n                \"test:unit:node\",\n                \"test:treeshakability:browser\",\n                \"test:treeshakability:native\",\n                \"test:treeshakability:node\"\n            ],\n            \"passThroughEnv\": [\n                \"ACTIONS_ID_TOKEN_REQUEST_TOKEN\",\n                \"ACTIONS_ID_TOKEN_REQUEST_URL\",\n                \"GH_TOKEN\",\n                \"GITHUB_*\",\n                \"NODE_AUTH_TOKEN\",\n                \"NPM_CONFIG_USERCONFIG\",\n                \"PUBLISH_TAG\"\n            ]\n        },\n        \"style:fix\": {\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"*\"],\n            \"outputs\": [\"*\"]\n        },\n        \"test:lint\": {\n            \"dependsOn\": [\"^compile:typedefs\"],\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"src/**\", \"test/**\"],\n            \"outputs\": []\n        },\n        \"test:prettier\": {\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"*\"],\n            \"outputs\": []\n        },\n        \"test:typecheck\": {\n            \"dependsOn\": [\"^compile:typedefs\"],\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"tsconfig.*\", \"src/**\"],\n            \"outputs\": []\n        },\n        \"test:unit:browser\": {\n            \"dependsOn\": [\"compile:js\"],\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"../../.agave/**/version.yml\", \"src/**\"],\n            \"outputs\": []\n        },\n        \"test:unit:node\": {\n            \"dependsOn\": [\"compile:js\"],\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"../../.agave/**/version.yml\", \"src/**\"],\n            \"outputs\": []\n        },\n        \"test:treeshakability:browser\": {\n            \"dependsOn\": [\"compile:js\"]\n        },\n        \"test:treeshakability:native\": {\n            \"dependsOn\": [\"compile:js\"]\n        },\n        \"test:treeshakability:node\": {\n            \"dependsOn\": [\"compile:js\"]\n        },\n        \"@solana/example-react-app#compile:js\": {\n            \"dependsOn\": [\"^compile:js\", \"^compile:typedefs\"],\n            \"env\": [\"REACT_EXAMPLE_APP_BASE_PATH\", \"REACT_EXAMPLE_APP_ENABLE_MAINNET\"],\n            \"inputs\": [\"$TURBO_DEFAULT$\", \"index.html\", \"tsconfig.*\", \"vite.config.ts\", \"public/**\", \"src/**\"],\n            \"outputs\": [\"dist/**\"]\n        }\n    },\n    \"ui\": \"stream\"\n}\n"
  },
  {
    "path": "typedoc.json",
    "content": "{\n    \"$schema\": \"https://typedoc.org/schema.json\",\n    \"out\": \"docs/content/api\",\n    \"plugin\": [\n        \"typedoc-plugin-mdn-links\",\n        \"typedoc-plugin-markdown\",\n        \"typedoc-plugin-frontmatter\",\n        \"./typedoc.plugin.mjs\"\n    ],\n    \"disableSources\": true,\n    \"readme\": \"none\",\n    \"hidePageHeader\": true,\n    \"hideBreadcrumbs\": true,\n    \"hideGroupHeadings\": true,\n    \"hidePageTitle\": true,\n    \"indexFormat\": \"table\",\n    \"parametersFormat\": \"table\",\n    \"classPropertiesFormat\": \"table\",\n    \"enumMembersFormat\": \"table\",\n    \"typeDeclarationFormat\": \"table\",\n    \"propertyMembersFormat\": \"table\",\n    \"interfacePropertiesFormat\": \"table\",\n    \"fileExtension\": \".mdx\",\n    \"entryFileName\": \"index\",\n    \"theme\": \"kit-docs-theme\",\n    \"useCodeBlocks\": true\n}\n"
  },
  {
    "path": "typedoc.plugin.mjs",
    "content": "// @ts-check\nimport prettier from '@prettier/sync';\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport * as td from 'typedoc-plugin-markdown';\n\n// Fits on a 13\" MBP screen (1280px width) given the current design\nconst METHOD_SIGNATURE_COLUMN_WIDTH = 72;\n\n/** @type {import(\"prettier\").Options | null | undefined} */\nlet prettierConfig;\nfunction getPrettierConfig() {\n    if (prettierConfig === undefined) {\n        const PATH = join(import.meta.dirname, 'docs', 'content', '.prettierrc');\n        if (existsSync(PATH)) {\n            prettierConfig = prettier.resolveConfig(PATH);\n        } else {\n            prettierConfig = null;\n            console.warn(\n                `No Pretter config file exists at ${PATH}; Method signatures in generated API ` +\n                    'documentation may not be formatted according to the same options as the ' +\n                    'rest of the docs',\n            );\n        }\n    }\n    return prettierConfig;\n}\n\nclass KitDocsMarkdownTheme extends td.MarkdownTheme {\n    /** @param {td.MarkdownPageEvent<import('typedoc').Reflection>} page */\n    getRenderContext(page) {\n        return new KitDocsThemeRenderContext(this, page, this.application.options);\n    }\n}\n\nclass KitDocsThemeRenderContext extends td.MarkdownThemeContext {\n    /** @param {ConstructorParameters<typeof td.MarkdownThemeContext>} args */\n    constructor(...args) {\n        super(...args);\n        const oldSignatureTitle = this.partials.signatureTitle;\n        this.partials = {\n            ...this.partials,\n            signatureTitle(model, options) {\n                const titleMarkdown = oldSignatureTitle(model, options);\n                const prettierConfig = getPrettierConfig();\n                const prettyTitleMarkdown = prettier.format(titleMarkdown, {\n                    ...prettierConfig,\n                    printWidth: Math.min(\n                        prettierConfig?.printWidth ?? METHOD_SIGNATURE_COLUMN_WIDTH,\n                        METHOD_SIGNATURE_COLUMN_WIDTH,\n                    ),\n                    parser: 'markdown',\n                });\n                return prettyTitleMarkdown;\n            },\n        };\n    }\n}\n\n/** @param {td.MarkdownApplication} app */\nexport function load(app) {\n    // Use this theme name in typedoc.json or when using the CLI\n    app.renderer.defineTheme('kit-docs-theme', KitDocsMarkdownTheme);\n\n    // Set Markdown frontmatter for each page\n    app.renderer.on(td.MarkdownPageEvent.BEGIN, page => {\n        page.frontmatter = {\n            title: page.model.name,\n        };\n    });\n\n    // Rewrite all of the internal links\n    // - root relative for compatibility with Next.js\n    // - strip the .mdx extension\n    app.renderer.on(td.MarkdownPageEvent.END, page => {\n        if (!page.contents) return;\n        page.contents = page.contents.replace(/]\\(((?:[^\\/\\)]+\\/)*[^\\/\\)]+)\\.mdx([^)]*)?\\)/gm, (_, path, suffix) => {\n            const rootRelativeUrl = resolve('/api', dirname(page.url), path);\n            return `](${rootRelativeUrl}${suffix ?? ''})`;\n        });\n    });\n}\n"
  }
]